








Study with the several resources on Docsity
Earn points by helping other students or get them with a premium plan
Prepare for your exams
Study with the several resources on Docsity
Earn points to download
Earn points by helping other students or get them with a premium plan
Window Classes, System classes, Styles of System Classes, Creating ButtonWindow Class, Get and Set Window Long, Sub Classing, Types of Subclassing, Get or Set ClassLong. As you can see in this file, how descriptive above mentioned points are explained in this lecture of computer programming. VU is one of best university for computer science in our country.
Typology: Study notes
1 / 14
This page cannot be seen from the preview
Don't miss anything!









Up till now, we have been registering window classes before creating a window. A number
of window classes are pre-registered / pre-coded in Windows, and their window procedures
are also pre-written.
A system class is a window class registered by the system. Many system classes are
available for all processes to use, while others are used only internally by the system.
Because the system registers these classes, a process cannot destroy them.
Microsoft Windows NT/Windows 2000/Windows XP: The system registers the system
classes for a process, the first time one of its threads calls a User or a Windows Graphics
Device Interface (GDI) function.
There are two types of System Window Classes.
The following table describes the system classes that are available for use by all processes.
Class Description
Button The class for a button.
ComboBox The class for a combo box.
Edit The class for an edit control.
ListBox The class for a list box.
MDIClient The class for an MDI client window.
ScrollBar The class for a scroll bar.
Static The class for a static control.
The following table describes the system classes that are available only for use by the
system.
Class Description
ComboLBox The class for the list box contained in a combo box.
DDEMLEvent Windows NT/Windows 2000/Windows XP: The class for Dynamic Data
Exchange Management Library (DDEML) events.
Message Windows 2000/Windows XP: The class for a message-only window.
#32768 The class for a menu.
#32769 The class for the desktop window.
This style places text on the left side of the radio button or check box when combined with a radio button or check box style. This style is same as the BS_RIGHTBUTTON style.
This style creates an owner-drawn button. The owner window receives a
WM_DRAWITEM message when a visual aspect of the button has changed. Do not combine the BS_OWNERDRAW style with any other button styles.
This style creates a push button that posts a WM_COMMAND message to the owner
window when the user selects the button.
This style creates a small circle with text. By default, the text is displayed to the right of the
circle. To display the text to the left of the circle, combine this flag with the
BS_LEFTTEXT style (or with the equivalent BS_RIGHTBUTTON style). Use radio buttons for groups of related, but mutually exclusive choices.
This style has become obsolete, but provided for compatibility with 16-bit versions of
Windows. Applications should use BS_OWNERDRAW instead.
This style specifies that the button displays a bitmap.
This style places text at the bottom of the button rectangle.
This style centers text horizontally in the button rectangle.
This style specifies that the button displays an icon.
This style specifies that the button is two-dimensional; it does not use the default shading to create a 3-D image.
This style Left-justifies the text in the button rectangle. However, if the button is a check
box or radio button that does not have the BS_RIGHTBUTTON style, the text is left justified on the right side of the check box or radio button.
This style wraps the button text to multiple lines if the text string is too long to fit on a
single line in the button rectangle.
This style enables a button to send BN_KILLFOCUS and BN_SETFOCUS to help
notification messages to its parent window.
Note that buttons send the BN_CLICKED notification message regardless of whether it has this style. To get BN_DBLCLK notification messages, the button must have the BS_RADIOBUTTON or BS_OWNERDRAW style.
This style makes a button (such as a check box, three-state check box, or radio button) and
look and act like a push button. The button looks raised when it isn't pushed or checked,
and sunken when it is pushed or checked.
This style right-justifies text in the button rectangle. However, if the button is a check box
or radio button that does not have the BS_RIGHTBUTTON style, the text is right justified
on the right side of the check box or radio button.
This style positions a radio button's circle or a check box's square on the right side of the
button rectangle. This is same as the BS_LEFTTEXT style.
This style specifies that the button displays text.
This style places text at the top of the button rectangle.
Microsoft Windows 2000: A composite style bit that results from using the OR operator on
BS_* style bits. It can be used to mask out valid BS_* bits from a given bitmask. Note that
this is out of date and does not correctly include all valid styles. Thus, you should not use this style.
This style places text in the middle (vertically) of the button rectangle.
For button, we will use our well known API CreateWindow to create a button.
hWnd = CreateWindow( "BUTTON", "Virtual University", BS_RADIOBUTTON |
WS_VISIBLE | WS_OVERLAPPEDWINDOW | WS_CAPTION, 50, 50, 200, 100,
NULL, NULL, hInstance, NULL);
This button has no parent. If you want to place this button on any window, you should
provide hWndParent member with parent Window handle and add WS_CHILD style in its
dwStyle member.
Certain window data is cached, so changes you make using SetWindowLong will not take effect until you call the SetWindowPos function. Specifically, if you change any of the frame styles, you must call SetWindowPos with the SWP_FRAMECHANGED flag for the cache to be updated properly. If you use SetWindowLong with the GWL_WNDPROC index to replace the window procedure, the window procedure must conform to the guidelines specified in the description of the WindowProc callback function. If you use SetWindowLong with the DWL_MSGRESULT index to set the return value for a message processed by a dialog procedure, you should return TRUE directly afterwards. Otherwise, if you call any function that results in your dialog procedure receiving a window message, the nested window message could overwrite the return value you set using DWL_MSGRESULT. Calling SetWindowLong with the GWL_WNDPROC index creates a subclass of the window class used to create the window. An application can subclass a system class, but should not subclass a window class, created by another process. The SetWindowLong function creates the window subclass by changing the window procedure associated with a particular window class, causing the system to call the new window procedure instead of the previous one. An application must pass any messages not processed by the new window procedure to the previous window procedure by calling CallWindowProc. This allows the application to create a chain of window procedures. Reserve extra window memory by specifying a nonzero value in the cbWndExtra member of the WNDCLASSEX structure used with the RegisterClassEx function.
Sub-classing allows you to change the behavior of an existing window, typically a control,
by inserting a message map to intercept the window's messages. For example, suppose you
have a dialog box with an edit control that you want to accept only non-numeric characters. You could do this by intercepting WM_CHAR messages destined for the edit control and
discarding any messages indicating that a numeric character has been entered.
Subclassing is a technique that allows an application to intercept messages destined for
another window. An application can augment, monitor, or modify the default behavior of a window by intercepting messages meant for another window. Sub-classing is an effective
way to change or extend the behavior of a window without redeveloping the window.
Subclassing the default control window classes (button controls, edit controls, list controls,
combo box controls, static controls, and scroll bar controls) is a convenient way to obtain
the functionality of the control and to modify its behavior. For example, if a multi-line edit control is included in a dialog box and the user presses the ENTER key, the dialog box
closes. By subclassing the edit control, an application can have the edit control insert a
carriage return and line feed into the text without exiting the dialog box. An edit control
does not have to be developed specifically for the needs of the application
The first step in creating a window is registering a window class by filling a WNDCLASS structure and calling RegisterClass. One element of the WNDCLASS structure is the address of the window procedure for this window class. When a window is created, the 32- bit versions of the Microsoft Windows operating system take the address of the window procedure in the WNDCLASS structure and copy it to the new window's information structure. When a message is sent to the window, Windows calls the window procedure through the address in the window's information structure. To subclass a window, you substitute a new window procedure that receives all the messages meant for the original
window by substituting the window procedure address with the new window procedure address. When an application subclasses a window, it can take three actions with the message: (1) pass the message to the original window procedure; (2) modify the message and pass it to the original window procedure; (3) not pass the message. The application subclassing a window can decide when to react to the messages it receives. The application can process the message before, after, or both before and after passing the message to the original window procedure.
The two types of subclassing are instance subclassing and global subclassing. Instance subclassing is subclassing an individual window's information structure. With instance subclassing, only the messages of a particular window instance are sent to the new window procedure. Global subclassing is replacing the address of the window procedure in the WNDCLASS structure of a window class. All subsequent windows created with this class have the substituted window procedure's address. Global subclassing affects only windows created after the subclass has occurred. At the time of the subclass, if any windows of the window class that is being globally subclassed exist, the existing windows are not affected by the global subclass. If the application needs to affect the behavior of the existing windows, the application must subclass each existing instance of the window class.
Two sub-classing rules apply to instance and global sub-classing in Win32.
Subclassing is allowed only within a process. An application cannot subclass a window or
class that belongs to another process.
The reason for this rule is simple: Win32 processes have separate address spaces. A window procedure has an address in a particular process. In a different process, that address does not contain the same window procedure. As a result, substituting an address from one process with an address from another process does not provide the desired result, so the 32-bit versions of Windows do not allow this substitution (that is, subclassing from a different process) to take place. The SetWindowLong and SetClassLong functions prevent this type of subclassing. You can not subclass a window or class that is in another process. End of story.
One way to add subclassing code into another process is much more complicated: It involves using the OpenProcess, WriteProcessMemory, and CreateRemoteThread functions to inject code into the other process. I don't recommend this method and won't go into any details on how to do it. For developers who insist on using this method,
The subclassing process may not use the original window procedure address directly.
In Win16, an application could use the window procedure address returned from SetWindowLong or SetClassLong to call the procedure directly. After all, the return value is simply a pointer to a function, so why not just call it? In Win32, this is a definitive no-no. The value returned from SetWindowLong and GetClassLong may not be a pointer to the previous window procedure at all. Win32 may return a pointer to a data structure that it can use to call the actual window procedure. This occurs in Windows NT when an application subclasses a Unicode window with a non-Unicode window procedure, or a non-Unicode window with a Unicode window procedure. In this case, the operating system must perform a translation between Unicode and ANSI for the messages the window receives. If an application uses the pointer to this structure to directly call the window procedure, the
SetWindowLong(hEditWnd, GWL_WNDPROC, (DWORD) lpfnOldWndProc);
// // Here is a sample subclass function. // LONG FAR PASCAL SubClassFunc( HWND hWnd, UINT Message, WPARAM wParam, LONG lParam) { // // When the focus is in an edit control inside a dialog box, the // default ENTER key action will not occur. //
if ( Message == WM_GETDLGCODE ) return DLGC_WANTALLKEYS;
return CallWindowProc(lpfnOldWndProc, hWnd, Message, wParam, lParam); }
The GetClassLong() function retrieves the specified 32-bit (LONG) value from the
WNDCLASS structure associated with the specified window. This will can be back ground
brush, handle to instance, handle to windows procedure and handle to Icon etc.
LONG SetClassLong(
HWND hWnd, // handle to window
int nIndex, // offset of value to set n LONG dwNewLong // new value
);
Parameters hWnd Handle to the window and, indirectly, the class to which the window belongs. nIndex This member specifies the 32-bit value to replace. To set a 32-bit value in the extra class memory, specify the positive, zero-based byte offset of the value to be set. Valid values are in the range zero through the number of bytes of extra class memory, minus four; for example, if you specified 12 or more bytes of extra class memory, a value of 8 would be an index to the third 32-bit integer. To set any other value from the WNDCLASSEX structure, specify one of the following values.
GCL_CBCLSEXTRA: Sets the size, in bytes, of the extra memory associated with the class. Setting this value does not change the number of extra bytes already allocated.
GCL_CBWNDEXTRA: Sets the size, in bytes, of the extra window memory associated with each window in the class. Setting this value does not change the number of extra bytes already allocated.
GCL_HBRBACKGROUND: Replaces a handle to the background brush associated with the class.
GCL_HCURSOR: Replaces a handle to the cursor associated with the class. GCL_HICON: Replaces a handle to the icon associated with the class.
GCL_HICONSM: Replace a handle to the small icon associated with the class.
GCL_HMODULE: Replaces a handle to the module that registered the class.
GCL_MENUNAME: Replaces the address of the menu name string. The string identifies the menu resource associated with the class.
GCL_STYLE: Replaces the window-class style bits.
GCL_WNDPROC: Replaces the address of the window procedure associated with the class. dwNewLong This member specifies the replacement value. Return Value If the function succeeds, the return value is the previous value of the specified 32- bit integer. If the value was not previously set, the return value is zero. If the function fails, the return value is zero. To get extended error information, call GetLastError.
LONG GetClassLong(
HWND hWnd, // handle to window int nIndex // offset of value to retrieve
);
If you use the SetClassLong function and the GCL_WNDPROC index to replace the window procedure, the window procedure must conform to the guidelines specified in the description of the WindowProc callback function. Calling SetClassLong with the GCL_WNDPROC index creates a subclass of the window class that affects all windows subsequently created with the class. An application can subclass a system class, but should not subclass a window class created by another process. Reserve extra class memory by specifying a nonzero value in the cbClsExtra member of the WNDCLASSEX structure used with the RegisterClass function. Use the SetClassLong function with care. For example, it is possible to change the background color for a class by using SetClassLong , but this change does not immediately repaint all windows belonging to the class.
Superclassing involves creating a new class that uses the window procedure of an existing class for basic functionality.
Super-classing defines a class that adds new functionality to a predefined window class, such as the button or list box controls.
The following example defines a new class with partly or wholly modified behavior of a
pre-defined window class.
DLGPROC oldWindowProc; // Global variable
WNDCLASS wndClass;
GetClassInfo(hInstance, “BUTTON”, &wndClass);
GetClassInfo API gets the information about class. Information includes windows style, procedure, background brush, icon and cursors.
WndClass.hInstance = hInstance;
wndClass.lpszClassName = “BEEPBUTTON”;
OldWindowProc = wndClas.lpfnWndProc; wndClas.lpfnWndProc = myWindowProc;
After getting class information we fill the new window class and register it again by using
RegisterClass API
if(! RegisterClass( &wndClass ) )
{
return 0;
}
After registering new window class with the new procedure, create a window with the new
register class name. This registered class name will be different from the old registered
class name.
hWnd = CreateWindow(“BEEPBUTTON", "Virtual University", WS_VISIBLE |
WS_OVERLAPPEDWINDOW,
50, 50, 200, 100,
NULL, NULL, hInstance, NULL);
noldWindowProc = (WNDPROC)SetWindowLong(hWnd, GWL_WNDPROC,
(LONG)myWindowProc);
while(GetMessage(&msg, NULL, 0, 0) > 0)
{ if(msg.message == WM_LBUTTONUP) DispatchMessage(&msg);
return msg.wParam
This new windows procedure myWindowProc will call the old window procedure after its
normal message processing.
LRESULT CALLBACK myWindowProc(HWND hWnd, UINT message,
WPARAM wParam, LPARAM lParam)
{
switch (message) { case WM_LBUTTONDOWN: MessageBeep(0xFFFFFFFF); Break; default: return CallWindowProc(oldWindowProc, hWnd, message, wParam, lParam);
return 0; }
Tips: After implementation of Sub-classing or Super Classing don’t forget to call window procedure function.
In this lecture, we learnt about system windows classes. System window classes include
buttons, combo boxes, list box, etc. We studied about Button System Window class. We
discussed how to change windows attributes by using SetWindowLong and GetWindowLong APIs. Using SetWindowLong and GetWindowLong, we can also make a
new procedure and change the message behavior of a window. Using SetClassLong and
GetClassLong, we can change one of the attributes of a registered class. Changing class
values will effect the change for every window that is using this class. This is called sub-
classing. We also knew about Super-classing in which we register new window class by using the properties of previous window class.