// The hotspots. private List Hotspots = new List(); ... // Prepare the map for first viewing. private void Form1_Load(object sender, EventArgs e) { // Initialize the hotspots. Hotspots.Add(new Rectangle(88, 509, 22, 22)); Hotspots.Add(new Rectangle(140, 577, 20, 20)); Hotspots.Add(new Rectangle(161, 609, 20, 20)); ... Hotspots.Add(new Rectangle(1234, 1076, 16, 18)); ... }
So how do you come up with the definitions for the hotspots? One way would be to measure the map image and figure out where the hotspots should be, but this program provides an easier way.
If you open the Data menu and select Make Hotspot, you can then click and drag to define a hotspot. The program displays the code needed to define that hotspot in the Output window as shown in the picture here. You can copy that code and paste it into the code window to create the new hotspot.
To make using the program in "normal" mode easier, I set the Data menu's Visible property to False at design time so you normally won't see that menu and you cannot create hotspots. This is the way I would ship the program to a user. To create hotspots, simply make the menu visible and run the program.
The following code executes when you select the Data menu's Make Hotspot command.
// Display a hotspot definition in the Output window. private void mnuMakeHotspot_Click(object sender, EventArgs e) { picMap.MouseMove -= picMap_MouseMove; picMap.MouseClick -= picMap_MouseClick; picMap.MouseDown += makeHotspot_MouseDown; picMap.Cursor = Cursors.Cross; }
This code prepares the program to create a hotspot. First it removes the MouseMove and MouseClick event handlers that normally deal with the user moving over and clicking a hotspot. It then installs a new MouseDown event handler to start creating a hotspot. It also changes the PictureBox's cursor to a crosshair.
The following code shows the new event handler that executes when the user presses the mouse down.
// Get ready to draw a selection rectangle. HotspotBm = (Bitmap)Map.Clone(); HotspotGr = Graphics.FromImage(HotspotBm); picMap.Image = HotspotBm; }
This code saves the initial mouse location in the variable HotspotStart. It removes the MouseDown event handler and installs MouseMove and MouseUp event handlers. It finishes by creating a temporary copy of the original image, making a Graphics object associated with the image, and displaying the image.
When the user moves the mouse, the following code executes.
// Draw a selection rectangle. private void makeHotspot_MouseMove(object sender, MouseEventArgs e) { // Save the new point. HotspotEnd = e.Location;
// Draw the selection rectangle. HotspotGr.DrawImage(Map, 0, 0); float x = Math.Min(HotspotStart.X, HotspotEnd.X) * MapScale; float y = Math.Min(HotspotStart.Y, HotspotEnd.Y) * MapScale; float wid = Math.Abs(HotspotStart.X - HotspotEnd.X) * MapScale; float hgt = Math.Abs(HotspotStart.Y - HotspotEnd.Y) * MapScale; using (Pen thin_pen = new Pen(Color.Red, 1 * MapScale)) { thin_pen.DashStyle = DashStyle.Dash; HotspotGr.DrawRectangle(thin_pen, x, y, wid, hgt); }
picMap.Refresh(); }
This code saves the mouse's new location in the variable HotspotEnd. It then copies the original map onto the temporary image and drawing a rectangle to show the area currently selected.
The following code executes when the user releases the mouse.
This code uninstalls the hotspot MouseMove and MouseUp event handlers and reinstalls the original MouseMove and MouseClick event handlers. It resets the map image and the cursor and redisplays the map.
The code finishes by displaying the code needed to create this hotspot in the Output window.
One modification you might want to make would be to store hotspot data in objects other than Rectangles. For example, you could create a Hotspot class that holds a hotspot's location plus a name, description, or other information. In that case, you could modify the makeHotspot_MouseUp method so it prompts you for that other information and then uses it to generate the code needed to create a new Hotspot object.
Comments