Microsoft KB Archive/244236

= How To Use the System Color on ScrollBars Under Windows NT =

Article ID: 244236

Article Last Modified on 7/13/2004

-

APPLIES TO


 * Microsoft Visual Basic 6.0 Learning Edition
 * Microsoft Visual Basic 6.0 Professional Edition
 * Microsoft Visual Basic 6.0 Enterprise Edition

-



This article was previously published under Q244236



SUMMARY
The background color of the horizontal and vertical scrollbar controls is white under Microsoft Windows NT, while the system color is used under Microsoft Windows 9.x. To use the system color on Windows NT, it is necessary to subclass the form to prevent the WM_CTLCOLORSCROLBAR windows message from being processed by the default windows procedure (WindowProc) of the form.

WARNING: Failure to unhook a window before its imminent destruction results in application errors, Invalid Page Faults, and data loss. This is due to the fact that the new WindowProc function being pointed to no longer exists, but the window has not been notified of the change. Always unhook the sub-classed window upon unloading the sub-classed form or exiting the application. This is especially important while debugging an application that uses this technique within the Microsoft Visual Basic Development Environment (IDE). Pressing the END button or selecting END from the Run menu without unhooking can cause an Invalid Page Fault and close Microsoft Visual Basic.



MORE INFORMATION
Microsoft Windows controls applications by sending messages to the windows that are created by each application. These messages alert the targeted window when it is time to redraw, when a mouse button is pressed, and all of the other information a window needs to know in order to act appropriately.

Thus, a minimal Windows application consists of a function that processes these messages (called WindowProc). This function is registered with the system when the window is created so the system knows where to send messages.

The WM_CTLCOLORSCROLLBAR message is sent to the parent window of a scrollbar control when the control is about to be drawn. By responding to this message, the parent window can use the device context handle (hDC) to set the background color of the scroll bar control. If this message is intercepted and not passed on to the WindowProc, the scrollbar is set to the system color.

The following sample consists of a simple form with two CommandButtons and a vertical scrollbar. It intercepts the WM_CTLCOLORSCROLLBAR message and discards it.

NOTES:
 * The scrollbar control flickers unless at least one other control is sited on the form. Setting the TabStop property of the VScrollBar to False prevents it from getting the focus.


 * It is generally a good idea to start a hook from the Form_Load procedure and end it from the Form_Unload procedure. In this sample, CommandButtons are used so that the difference in the VScrollBar is more readily apparent.

Step-by-Step Example
 Start a new Visual Basic Standard EXE project. Form1 is created by default. Add two CommandButtons and a VScrollBar to Form1. Set the TabStop property of VScrollBar1 to False. On the Project menu, click Add Module to add a BAS Module to the project.  Add the following code to the General Declarations section of Module1: Option Explicit

Declare Function CallWindowProc Lib "user32" Alias _ "CallWindowProcA" (ByVal lpPrevWndFunc As Long, _ ByVal hwnd As Long, ByVal Msg As Long, _ ByVal wParam As Long, ByVal lParam As Long) As Long

Declare Function SetWindowLong Lib "user32" Alias _ "SetWindowLongA" (ByVal hwnd As Long, _ ByVal nIndex As Long, ByVal dwNewLong As Long) As Long

Public Const GWL_WNDPROC = -4 public Const WM_CTLCOLORSCROLLBAR = 311

Public Sub Hook lpPrevWndProc = SetWindowLong(gHW, GWL_WNDPROC, _  AddressOf WindowProc) End Sub

Public Sub Unhook Dim temp As Long temp = SetWindowLong(gHW, GWL_WNDPROC, lpPrevWndProc) End Sub

Function WindowProc(ByVal hw As Long, ByVal uMsg As Long, _                   ByVal wParam As Long, ByVal lParam As Long) As Long If uMsg <> WM_CTLCOLORSCROLLBAR Then Debug.Print uMsg, hw     WindowProc = CallWindowProc(lpPrevWndProc, hw, uMsg, wParam, lParam) End If End Function   Add the following code to the General Declarations section of Form1: Option Explicit

Dim lpPrevWndProc As Long Dim gHW As Long

Private Sub Form_Load gHW = Me.hwnd Command1.Caption = "Hook" Command2.Caption = "Unhook" End Sub

Private Sub Command1_Click Hook VScroll1.Refresh End Sub

Private Sub Command2_Click Unhook End Sub  Run the project and click the Hook button to hook the form. Observe that the scrollbar changes from white to the system color. Click the Unhook button and then terminate the program.</li></ol>

<div class="references_section">