In depth analysis of C++ WNDCLASS structure and its application in Windows

  • 2020-05-07 20:08:11
  • OfStack

WNDCLASS is a structure supported by the system to store information of a certain type of window, such as ClassStyle, message handler, Icon,Cursor, background Brush, etc. That is, CreateWindow simply turns a form defined by WNDCLASS into an instance. To get WNDCLASS data for a 1 window, use GetClassLong();
RegisterClass() is simply registering a form of type 1 with the system. That is to register the WNDCLASS data you provided as a window class, and define the WNDCLASS identity in WNDCLASS.lpszClassName. The Windows created by CreateWindow or CreateWindowEx must correspond to one WNDCLASS, but one WNDCLASS can have multiple window objects.
There are some predefined window classes, such as ClassName=_T("BUTTON" or "COMBOBOX" or "EDIT" or "LISTBOX" or "MDICLIENT" SCOLLBAR" or "STATIC"), to use these forms, directly create the corresponding object with CreateWindow. To get a window class for a 1 window, use GetClassName();
The callback function in WNDCLASS is the form's message handler: CALLBACK WinProc(MESSAGE msg,LPARAM lparam,WPARAM wParam);
Window class property definition
Structure WNDCLASS contains all the information of a window class, which is also one of the basic data structures used in Windows programming. The application program determines the properties of the window by defining a window class, as follows:


typedef struct _WNDCLASS {
  UINT style;
  WNDPROC lpfnWndProc;
  int cbClsExtra;
  int cbWndExtra;
  HINSTANCE hInstance;
  HICON hIcon;
  HCURSOR hCursor;
  HBRUSH hbrBackground;
  LPCTSTR lpszMenuName;
  LPCTSTR lpszClassName;
  } WNDCLASS, *PWNDCLASS;

For example
Example:


long CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);// The statement 
//WinMain The function is all Windows Application entry, similar c In the language main The function completes //1 The series is defined and initialized, and a message loop is generated. Function description: 
int WINAPI WinMain(HINSTANCE hInstance,    // handle to current instance
               HINSTANCE hPrevInstance, // handle to previous instance
               LPSTR lpCmdLine,       // command line
                int nCmdShow           // show state
)
{
    // Initialization, which includes the definition of the window class, registration, creation of the window instance, and display of the window 4 Part of the 
  HWND hwnd;
  MSG Msg;
  WNDCLASS wndclass;
  char lpszClassName[]=" window "; // The window class name 
  char lpszTitle[]=" The test window "; // Window title 
  // Window class definition, window class defines the form and function of the window, window class definition by giving the window class data structure WNDCLASS Assignment to complete 
  // The data structure contains various properties of the window class 
  wndclass.style =0; //  The window type is the default type CS_   Class Style
  wndclass.lpfnWndProc=WndProc; // Defines a window handler 
  wndclass.cbClsExtra=0; // The window class has no extension 
  wndclass.cbWndExtra=0; // The window instance has no extension 
  wndclass.hInstance=hInstance; // Current instance handle 
  wndclass.hIcon=LoadIcon(NULL,IDI_APPLICATION); // The minimize icon of the window is the default icon 
  wndclass.hCursor=LoadCursor(NULL,IDC_ARROW); //  The window USES an arrow cursor 
  wndclass.hbrBackground=(HBRUSH)(GetStockObject(WHITE_BRUSH)); // The window background is white 
  wndclass.lpszMenuName=NULL; // No menu in window 
  wndclass.lpszClassName=lpszClassName; // The window class is called "window" 
  // The following is the registration of the window class -----------Windows The system itself provides some predefined window classes, and programmers can also customize window classes, which must be registered before use. 
  if(!RegisterClass(&wndclass)) // If registration fails   A warning 
     {MessageBeep(0); return FALSE;}
  // Create window create 1 Instances of Windows by functions CreateWindow() implementation 
  hwnd=CreateWindow( lpszClassName, // Window class name when the window is created 1 Must be based on the window class name that we have already registered, i.e " window " . 
                    lpszTitle, // Window title 
                    WS_OVERLAPPEDWINDOW, // Window style  WS_ Windows Style
                    CW_USEDEFAULT, // The upper left corner of the window is the default  CW_ Create Wndow
                    CW_USEDEFAULT,
                    CW_USEDEFAULT, // The height and width of the window are the default values 
                     CW_USEDEFAULT,
                    NULL, // This window has no parent window 
                    NULL, // This window has no submenu 
                    hInstance, // The current handle to the application that created this window 
                    NULL // This value is not used 
  );
  // Display window 
  ShowWindow(hwnd,nCmdShow);
  // Draw user area 
  UpdateWindow(hwnd);
  // Message loop 
  while(GetMessage(&Msg,NULL,0,0)) //GetMessage() The function is pulled from the message queue of the calling thread 1 Message; For each 1 Each application window thread is created by the operating system 1 Message queue, when our window has a message (that is, all the messages related to the window thread), the manipulation system will put the message into the message queue of that thread, and our window program will pass through this GetMessage() Function fetches from its message queue 1 article 1 A specific message and a response operation. 
  {
  TranslateMessage(&Msg);// right " The message to " Of, as on a keyboard WM_KEYDOWN and WM_KEYUP The message is converted to WM_CHAR Message, and post the transformed new message to our message queue. This transformation operation will not affect the original message, but will only be generated 1 A new message. 
  DispatchMessage(&Msg);//DispatchMessage() The call () function is the callback function that passes the message to the window. This function routes the retrieved message to the operating system, which then calls our window callback function to process the message. 
    }
  return Msg.wParam; // End of message loop   At the end of the program   Return the information to the system 
 }
 
// Window function, which defines the response of the application to different messages received, contains the processing of various messages that the application may receive, and is a collection of message processing branch control statements 
long CALLBACK WndProc(HWND hwnd,
                   UINT message,
                    WPARAM wParam,
                    LPARAM lParam)
{
  switch(message)
  {
    case WM_DESTROY:
      PostQuitMessage(0);
    default: // By default, the system message default handler is used 
      return DefWindowProc(hwnd,message,wParam,lParam);
  }
  return (0);
}

Note: the function pointer of the window callback function defines typedef LRESULT CALLBACK   (* WNDPROC)(HWND, UINT, WPARAM, LPARAM);


WNDPROC OldWndProc;
LRESULT CALLBACK NewWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam){
    switch (Msg)
    {
      ......
    }
    return CallWindowProc(OldWndProc,g_Wnd,Msg,wParam,lParam);
}
OldWndProc = (WNDPROC)GetWindowLong(g_Wnd,GWL_WNDPROC);
SetWindowLong(hwnd, GWL_WNDPROC,(LPARAM)(WNDPROC)NewWndProc);

The callback function of the form class can be modified by calling the SetWindowLong function.
 
What is the difference between wParam and lParam in CallBack function?
  WPARAM     wParam,         is defined as WORD
  LPARAM                     is defined as LONG type
  in Win 3.x, WPARAM is 16-bit, while LPARAM is 32-bit, there is a clear difference between the two.
  in Win32 API, WPARAM and LPARAM are both 32 bits, so there is no essential difference.
  but customarily we prefer to use LPARAM to pass the address and WPARAM to pass the other parameters.


 function MouseHookProc(nCode: Integer; wPar: WPARAM; lPar: LPARAM): lResult; stdcall;

  if I want to determine whether the left mouse button is pressed, wParam==WM_LBUTTONDOWN.
  lParam is of type PMouseHookStruct (pointer to tagMOUSEHOOKSTRUCT), which is used to get the send window handle, mouse coordinates, and other information.
  lParam is cast to PMouseHookStruct.


PMouseHookStruct = ^TMouseHookStruct; 
tagMOUSEHOOKSTRUCT = packed record 
 pt: TPoint; 
 hwnd: HWND; 
 wHitTestCode: UINT; 
 dwExtraInfo: DWORD; 
end; 
TMouseHookStruct = tagMOUSEHOOKSTRUCT; 

Such as:

function GetMsgProc(nCode: Integer; wPara: WPARAM; lPara: LPARAM) 
 : lResult; stdcall; 
var 
 hGetMsgHook : HHOOK ;   
 Msg: TMsg; 
begin 
 if (nCode >= 0) then 
 begin 
  FillChar(pMsgData^, Sizeof(TMessageRecord), #0); 
  Msg := TMsg(Pointer(lPara)^); 
 end; 
 Result := CallNextHookEx(hGetMsgHook, nCode, wPara, lPara); 
end; 

 
Data structure prototype


typedef struct _WNDCLASS{
          UINT style;
           WNDPROC lpfnWndProc;
           int cbClsExtra;
           int cbWndExtra;
           HANDLE hInstance;
           HICON hIcon;
           HCURSOR hCursor;
           HBRUSH hbrBackground;
           LPCTSTR lpszMenuName;
           LPCTSTR lpszClassName;
}WNDCLASS;

Structure that
The WNDCLASS structure contains the class properties registered by the RegisterClass function
Component description
style: specifies the class style. These styles can be combined by bit or operation. The style is as follows:

CS_BYTEALIGNCLIENT: locate the location of the user area of the window on the byte boundary (in the x direction) CS_BYTEALIGNWINDOW: locates the position of the window on the byte boundary (in the x direction) CS_CLASSDC: all window instances of this window class share one window class DC CS_DBLCLKS: allows a double-click mouse key message to be sent to a window CS_GLOBALCLASS: the hInstance arguments that allow a window to be created when the CreateWindow or CreateWindowEx functions are called are different from the hInstance arguments that are passed to RegisterClass when the window class is registered. If the style is not specified, the two hInstance must be the same. CS_HREDRAW: redraws the entire window when the horizontal length changes or moves CS_NOCLOSE: disables the close option of the system menu CS_OWNDC: gives each window instance its own DC. Note that while this is convenient, it must be used sparingly, as each DC takes up about 800 bytes of memory. CS_PARENTDC: set the clipping area of the child window to DC of the parent window so that the window can draw itself on the parent window. Note that this is a child window or getting DC from the system cache, not DC from the parent window. Using this style can improve system performance. CS_SAVEBITS: save the part of the screen blocked by the window in bitmap form, so that when the window is moved, the system can use the saved bitmap to restore the corresponding part of the screen moved, so that the system does not have to send WM_PAINT message to the window blocked by the window. This feature is appropriate for menu-type Windows because it is usually short and goes away after one click. Setting this feature increases the time it takes to display the window, because it usually allocates memory to save the bitmap first. CS_VREDRAW: redraw the entire window when the vertical length changes or moves lpfnWndProc: points to the window procedure

cbClsExtra: specifies the number of bytes to be allocated immediately after the WNDCLASS data structure. The system initializes it to zero.
cbWndExtra: specifies the number of bytes to be allocated immediately after the window instance, which the system initializes to zero. If the application is registering a dialog created with the CLASS directive in the RC resource description file with the WNDCLASS structure, it must set this field to DLGWINDOWEXTRA.
hInstance: identifies the handle to the module instance where the window procedure of the window class resides, not NULL.
hIcon: icon that identifies the window class. The hIcon field must be a handle to an icon; If the hIcon field is NULL, the application must draw an icon whenever the user shrinks the application to the minimum.
hCursor: the cursor that identifies the window class. hCursor must be a handle to a cursor resource. If the hCursor field is NULL, the application must explicitly set the cursor shape whenever the mouse moves over the application window.
hbrBackground: identifies the background brush for the window class. The hbrBackground field must be a handle to the physical brush used to draw the background, or a value of 1 color. If a value of a color is given, it must be one of the standard system colors listed below (the system will add one to the selected color). If a color value is given, it must be converted to the following color of type 1 of HBRUSH:

COLOR_ACTIVEBORDER COLOR_ACTIVECAPTION COLOR_APPWORKSPACE COLOR_BACKGROUND COLOR_BTNFACE COLOR_BTHSHADOW COLOR_BTNTEXT COLOR_CAPTIONTEXT COLOR_GRAYTEXT COLOR_HIGHLIGHT COLOR_HIGHLIGHTTEXT COLOR_INACTIVEBORDER COLOR_INACTIVECAPTION COLOR_MENU COLOR_MENUTEXT COLOR_SCROLLBAR COLOR_WINDOW COLOR_WINDOWFRAME COLOR_WINDOWTEXT When the hbrBackground field is NULL, the application must draw its background itself whenever it needs to draw its user area. The application can determine when the background needs to be colored by processing the WM_ERASEBKGND message or by checking the fErase field of the PAINTSTRUCT structure filled in by the BeginPaint function.

lpszMenuName: a string that points to the end of NULL and describes the resource name of the menu, as shown in the resource file. If you use 1 integer to identify the menu, you can use the MAKEINTRESOURCE macro. If lpszMenuName is NULL,
Then the window of the window class will not have a default menu.
lpszClassName: a string that points to the end of NULL, or a prototype (atom). If the parameter is a stereotype, it must be a class stereotype that was generated by the previous call to RegisterClass or RegisterClassEx functions. The class stereotype must be the low word of lpszClassName, and the high word must be 0. If lpszClassName is a string, it describes the window class name. This class name can be a name registered by RegisterClass or RegisterClassEx, or any predefined control class name.
Structure information Header is declared in winuser.h, including windows.h


Related articles: