home *** CD-ROM | disk | FTP | other *** search
/ CD Shareware Magazine 1999 April / CD_Shareware_Magazine_31.iso / Free / Prg / systemmenu.exe / MSysMenu.bas < prev    next >
Encoding:
BASIC Source File  |  1998-10-13  |  5.4 KB  |  133 lines

  1. Attribute VB_Name = "MSysMenu"
  2.   Option Explicit
  3.   ' demo project showing how to manipulate a form's system menu
  4.   ' by Bryan Stafford of New Vision Software« - newvision@imt.net
  5.   ' this demo is released into the public domain "as is" without
  6.   ' warranty or guaranty of any kind.  In other words, use at
  7.   ' your own risk.
  8.   
  9.   
  10.   ' ## see the end of this module for info about subclassing. ##
  11.   
  12.   
  13.   ' these are used in both modules so we declare it as public here
  14.   Public Const WM_SYSCOMMAND As Long = &H112&
  15.   Public Const IDM_ABOUT As Long = 1&
  16.   Public Const IDM_WHO As Long = 2&
  17.   ' you can use any ID that windows isn't already using for the
  18.   ' system menu.  for instance, any number between 0 and 10 is fair game
  19.   
  20.   
  21.   ' this var will hold a pointer to the original message handler so we MUST
  22.   ' save it so that it can be restored before we exit the app.  if we don't
  23.   ' restore it.... CRASH!!!!
  24.   Public procOld As Long
  25.   
  26.   Public Declare Function CallWindowProc& Lib "user32" Alias "CallWindowProcA" (ByVal lpPrevWndFunc&, _
  27.                                                     ByVal hWnd&, ByVal Msg&, ByVal wParam&, ByVal lParam&)
  28.   
  29. 'WARNING!!!! WARNING!!!! WARNING!!!! WARNING!!!! WARNING!!!! WARNING!!!!
  30. '
  31. ' Do NOT try to step through this function in debug mode!!!!
  32. ' You WILL crash!!!  Also, do NOT set any break points in this function!!!
  33. ' You WILL crash!!!  Subclassing is non-trivial and should be handled with
  34. ' EXTREAME care!!!
  35. '
  36. ' There are ways to use a "Debug" dll to allow you to set breakpoints in
  37. ' subclassed code in the IDE but this was not implimented for this demo.
  38. '
  39. 'WARNING!!!! WARNING!!!! WARNING!!!! WARNING!!!! WARNING!!!! WARNING!!!!
  40.   
  41. Public Function MenuProc(ByVal hWnd As Long, ByVal iMsg As Long, _
  42.                                               ByVal wParam As Long, ByVal lParam As Long) As Long
  43.   
  44. 'Debug.Print "Message &H" & Hex$(iMsg) & "  wParam &H" & Hex$(wParam) & "  lParam &H" & Hex$(lParam)
  45.   
  46.   ' this is *our* implimentation of the main message handling routine
  47.   
  48.   ' determine which message was recieved
  49.   Select Case iMsg
  50.     Case WM_SYSCOMMAND
  51.       ' if it's a WM_SYSCOMMAND message then we want to examine it more carefully.
  52.       ' check the word param (wParam) for our itemID.  if it's ours, pop up the message box
  53.       If wParam = IDM_ABOUT Then _
  54.           MsgBox "What do you want to know about this application?!?", _
  55.                                               vbQuestion, "System Menu Demo"
  56.  
  57.       If wParam = IDM_WHO Then _
  58.           MsgBox "Why of course, Bryan Stafford from New Vision Software« did this!", _
  59.                                                           vbInformation, "New Vision Software«"
  60.     
  61.     
  62.   End Select
  63.   
  64.   ' pass all messages on to VB and then return the value to windows
  65.   MenuProc = CallWindowProc(procOld, hWnd, iMsg, wParam, lParam)
  66.  
  67. End Function
  68.  
  69.  
  70. ' What is subclassing anyway?
  71. '
  72. ' Windows runs on "messages".  A message is a unique value that, when
  73. ' recieved by a window or the operating system, tells either that
  74. ' something has happened and that an action of some sort needs to be
  75. ' taken.  Sort of like your nervous system passing feeling messages
  76. ' to your brain and the brain passing movement messages to your body.
  77. '
  78. ' So, each window has what's called a message handler.  This is a
  79. ' function where all of the messages FROM Windows are recieved.  Every
  80. ' window has one.  I mean EVERY window.  That means every button, textbox,
  81. ' picturebox, form, etc...  Windows keeps track of where the message
  82. ' handler (called a WindowProc [short for PROCedure]) in a "Class"
  83. ' structure associated with each window handle (otherwise known as hWnd).
  84. '
  85. ' What happens when a window is subclassed is that you insert a new
  86. ' window procedure in line with the original window procedure.  In other
  87. ' words, Windows sends the messages for the given window to YOUR WindowProc
  88. ' FIRST where you are responsible for handling any messages you want to
  89. ' handle.  Then you MUST pass the remaining messages on to the default
  90. ' WindoProc.  So it looks like this:
  91. '
  92. '  Windows Message Sender --> Your WindowProc --> Default WindowProc
  93. '
  94. ' A window can be subclassed MANY times so it could look like this:
  95. '
  96. '  Windows Message Sender --> Your WindowProc --> Another WindowProc _
  97. '  --> Yet Another WindowProc --> Default WindowProc
  98. '
  99. ' You can also change the order of when you respond to a message by
  100. ' where in your routine you pass the message on to the default WindowProc.
  101. ' Let's say that you want to draw something on the window AFTER the
  102. ' default WindowProc handles the WM_PAINT message.  This is easily done
  103. ' by calling the default proc before you do your drawing.   Like so:
  104. '
  105. ' Public Function WindowProc(Byval hWnd, Byval etc....)
  106. '
  107. '   Select Case iMsg
  108. '     Case SOME_MESSAGE
  109. '       DoSomeStuff
  110. '
  111. '     Case WM_PAINT
  112. '       ' pass the message to the defproc FIRST
  113. '       WindowProc = CallWindowProc(procOld, hWnd, iMsg, wParam, lParam)
  114. '
  115. '       DoDrawingStuff ' <- do your drawing
  116. '
  117. '       Exit Function ' <- exit since we already passed the
  118. '                     '    measage to the defproc
  119. '
  120. '   End Select
  121. '
  122. '   ' pass all messages on to VB and then return the value to windows
  123. '   WindowProc = CallWindowProc(procOld, hWnd, iMsg, wParam, lParam)
  124. '
  125. ' End Function
  126. '
  127. '
  128. ' This is just a basic overview of subclassing but I hope it helps if
  129. ' you were fuzzy about the subject before reading this.
  130. '
  131.  
  132.  
  133.