LinkWise Logo spacing      Home of PicViewPlus
spacing
spacing
spacing gray camera spacing Home
spacing
spacing gray camera spacing Features
spacing
spacing gray camera spacing Comparison
spacing
spacing gray camera spacing Screen Shots
spacing
spacing gray camera spacing Going Digital?
spacing
spacing gray camera spacing Download
spacing
spacing gray camera spacing FAQ
spacing
spacing gray camera spacing About
spacing
spacing gray camera spacing Useful Links
spacing
spacing red camera flash spacing How Did He Do That?
spacing
spacing spacing
spacing
How Did He Do That?

(This page is for programmers)


Occasionally I get asked how I implemented some interesting program feature in code, since they may want to do something similar. Very often, the seed idea for what I do comes from other similar programs, programming newsgroups, tech e-mails, reference books, or non-related software I've written before. Since I've so often been helped by others, I've added this web page for those programmers who may want to implement some of the things they find useful in PicViewPlus.

All the code that follows is in Microsoft Visual Basic .NET. It should be easily convertable to C#.


The Windows XP "Look" of Controls

By default, applications built with the .NET architecture have the standard, if somewhat drab appearing, set of controls used in years past. In contrast, Microsoft written .NET applications for Windows XP often sport an "XP Themes" look to them. Unfortunately, there is no easy way to get this new look in your controls when using Microsoft's Visual Studio environment.

But with a little effort, there is a way to do it. John Robbins discusses it in his posting on his website. Unfortunately, it omits some key information. Karl Moore admits he spent quite a while trying to get this feature to work. See his article also. Karl give a whole series of steps. Unfortunately, his directions are over-complicated and some steps simply don't make sense.

So, after reviewing both writeups, and trying it myself, this is what you have to do.

  1. Karl is right on when he says the first step is, where possible, to set the FlatStyle property of your controls to System. This is important. (Strangely, John omits this step)

  2. Both Karl and John agree you need a manifest file. It is an XML file and should be placed in your application's Bin directory, where your Exe file resides. But both Karl and John give different and incorrect naming advice. If your program name is MyProg, your Exe would be MyProg.Exe, and the manifest file should be named MyProg.Exe.manifest.

In design mode, your controls will look no different from before. They will only have the new XP look when you run your program.

Use the following text in your manifest file, replacing MyProg and MyProg Description with the name and description of your application. It doesn't seem to make any difference what the version is.

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity 
    version="1.0.0.0" 
    processorArchitecture="X86" 
    name="MyProg"
    type="win32" 
/>
<description>MyProg Description</description>
<dependency> 
    <dependentAssembly> 
        <assemblyIdentity 
            type="win32" 
            name="Microsoft.Windows.Common-Controls" 
            version="6.0.0.0" 
            processorArchitecture="X86" 
            publicKeyToken="6595b64144ccf1df" 
            language="*" 
        /> 
    </dependentAssembly> 
</dependency> 
</assembly>


Selecting a Rectangular Area

The ability to zoom into an arbitrary rectangular area is really handy, especially when you can dynamically show this rectangle as the user creates it with the mouse. The first step is to create a MouseDown event for the picture box control, as this event defines a vertex of the selection rectangle:

 Private Sub picSlide_MouseDown(ByVal sender As Object, _
    ByVal e As System.Windows.Forms.MouseEventArgs) Handles picSlide.MouseDown

      'Get the MouseDown click coordinates and save them in public variables for use
      'during subsequent MouseMove events (where we draw a selection rectangle)
      MouseDownX = e.X
      MouseDownY = e.Y

      'Initialize for rectangular area generation
      MouseOldX = MouseDownX
      MouseOldY = MouseDownY

      MouseDownViewRectX = ViewRectX
      MouseDownViewRectY = ViewRectY

      'Get the button that was pressed along with the mouse click.
      Dim ShiftCtrlAlt As Short = System.Windows.Forms.Control.ModifierKeys \ &H10000
      'ShiftCtrlAlt is set as follows:
      '  Shift-
      '  CtrlAlt    Keyboard key pressed simultaneously
      '  -------    -----------------------------------
      '     1       Shift
      '     2       Ctrl
      '     3       Shift and Ctrl
      '     4       Alt
      '     5       Shift and Alt
      '     6       Ctrl and Alt
      '     7       Shift and Ctrl and Alt

      'Set the mouse mode up here
      MouseDownShiftCtrlAlt = ShiftCtrlAlt
   End Sub

The MouseMove event code does all the work for the visual display. The key point to keep in mind here is that all draws to the screen are done in complementary move. This has two benefits. One is that redrawing a line simply restores the original graphics under the line. The other is that no matter what color the underlying graphics, the selection rectangle line will always be visible, since its color will be "opposite" to that of the underlying color.


   Private Sub picSlide_MouseMove(ByVal sender As Object, _
      ByVal e As System.Windows.Forms.MouseEventArgs) Handles picSlide.MouseMove
      'Get the mouse-click coordinates
      Dim MouseX As Integer = e.X
      Dim MouseY As Integer = e.Y

      '-----------------------------------------------------------------------
      'Now check to see if the user is dragging the mouse to make a zoom frame
      '-----------------------------------------------------------------------
   
      'Get the mouse button that the user clicked.
      Dim MouseButton As Short = e.Button \ &H100000
      'MouseButton is set as follows:
      '  Mouse
      '  Button    Key pressed
      '  ------    -------------------
      '    1       Left mouse button was clicked/is pressed
      '    2       Right mouse button was clicked
      '    4       Wheel/center button was clicked

      'MouseDownShiftCtrlAlt is Public
      If MouseDownShiftCtrlAlt = 0 Then

         If MouseButton = 1 Then

            'From the microsoft.public.dotnet.framework.drawing newsgroup, 
            '   re: ControlPaint.DrawReversibleFrame
            Dim ZoomFrame As Rectangle
            'Draw the frame that is associated with the old mouse position,
            ' effectively erasing it, but only if there is a frame already there
            If (MouseDownX <> MouseOldX) Or (MouseDownY <> MouseOldY) Then
               ZoomFrame = picSlide.RectangleToScreen(New Rectangle(MouseOldX, MouseOldY, _
                  MouseDownX - MouseOldX, MouseDownY - MouseOldY))
               ControlPaint.DrawReversibleFrame(ZoomFrame, Me.BackColor, FrameStyle.Thick)
            End If

            'Don't draw a selection rectangle unless its bigger than a minimum size
            If (Math.Abs(MouseX - MouseDownX) > 10) Or (Math.Abs(MouseY - MouseDownY) > 10) Then
               'Draw the frame that is associated with the new mouse position
               ZoomFrame = picSlide.RectangleToScreen(New Rectangle(MouseX, MouseY, _
                  MouseDownX - MouseX, MouseDownY - MouseY))
               ControlPaint.DrawReversibleFrame(ZoomFrame, Me.BackColor, FrameStyle.Thick)
               'Update the old mouse position
               MouseOldX = MouseX
               MouseOldY = MouseY

               'Note that if we drew a regular rectangle here, we could only see it if we did
               ' a picSlide.Refresh(), but doing that using ControlPaint.DrawReversibleFrame
               ' tries to erase our frame
            Else
               'Initialize to no rectangle drawn
               MouseOldX = MouseDownX
               MouseOldY = MouseDownY
            End If

         End If
      End If

   End Sub

Finally, the MouseUp event erases the selection rectangle, gets the selection rectangle coordinates, and takes the appropriate graphics action.


  Private Sub picSlide_MouseUp(ByVal sender As Object, _
     ByVal e As System.Windows.Forms.MouseEventArgs) Handles picSlide.MouseUp
      'Pan and/or Zoom into/outof the image

      If MouseDownShiftCtrlAlt = 0 Then
         'If there is a selection frame, erase it by redrawing it
         ' (since the drawing is done in "invert" mode)
         Dim ZoomFrame As Rectangle
         'Draw the frame that is associated with the old mouse position, effectively erasing it,
         'but only if there is a frame already there
         If (MouseDownX <> MouseOldX) Or (MouseDownY <> MouseOldY) Then
            ZoomFrame = picSlide.RectangleToScreen(New Rectangle(MouseOldX, MouseOldY, _
               MouseDownX - MouseOldX, MouseDownY - MouseOldY))
            ControlPaint.DrawReversibleFrame(ZoomFrame, Me.BackColor, FrameStyle.Thick)
         End If
      End If

      'Get the mouse-click (mouse up) coordinates
      Dim MouseX As Integer = e.X
      Dim MouseY As Integer = e.Y

      'Get the mouse button that the user clicked.
      Dim MouseButton As Short = e.Button \ &H100000
      'MouseButton is set as follows:
      '  Mouse
      '  Button    Key pressed
      '  ------    -------------------
      '    1       Left mouse button was clicked
      '    2       Right mouse button was clicked
      '    4       Wheel/center button was clicked

      'Check for the Left mouse button
      If MouseButton = 1
 
         ' (MouseX,MouseY) and (MouseDownX,MouseDownY) define the two corners
         'of the selection rectangle. i.e., get the size of the zoom rectangle
         Dim ZoomRectangleSizeX As Integer = Math.Abs(MouseX - MouseDownX)
         Dim ZoomRectangleSizeY As Integer = Math.Abs(MouseY - MouseDownY)

         'Using the zoom rectangle, take some graphics action here
      End If
   End Sub



spacing

Contact: Software Support        © 2003, LinkWise Software