Explain Win32 window subclassing

From - http://www.vckbase.com/index.php/wv/1065
Maybe you need a special Edit to limit the input of floating point numbers, but the existing Edit can't do the job - because it Only limited case or pure numbers can be used. When you ask for help on the forum, a netizen tells you: "Use subclassing." You may see a glimmer of light and a series of questions at the same time: What is subclassing? What is the rationale for subclassing? How to implement subclassing? Let me start with a simple C++ program and solve your doubts step by step.
First, let me list this C++ program for you:
#include < iostream >
using namespace std;
class Parent
{
public:
void func(void) { cout << “func of Parent” << endl; }
};
class Child : public Parent
{
public:
void func(void) { cout << “func of Child” << endl; }
};
void main()
{
Parent p;
Child c;
p.func();
c.func();
}
Now let me explain. In this code I define two C++ classes: a parent class and a child class, and the child class inherits from the parent class; they have a member function func with the same name. In the main function, I construct the objects of the parent class and the child class respectively, and call their respective member functions func. The result is as follows:
func of Parent
func of Child
In short, this code is that the subclass rewrites the func member function according to its own needs. The principle of subclassing in Win32 is similar, except that subclassing does not actually overload any function like C++, but handles it by intercepting some messages in the Windows system. For example, please see the following simple window callback procedure:
LRESULT CALLBACK ProcMain(HWND hDlg, UINT Msg, WPARAM wParam, LPARAMlParam)
{
switch (Msg)
{
case WM_CLOSE:
EndDialog(hDlg, 0);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
}
return 0;
}
In this callback, I manually handle two messages: when the "Close" button is clicked (WM_CLOSE), I close the dialog (EndDialog); when the dialog is destroyed (WM_DESTROY), I report to the system The exit message is sent in the message queue to complete the end job (PostQuitMessage). In other words, if you change the response code of WM_CLOSE to:
case WM_CLOSE:
ShowWindow(hDlg, SW_MINIMIZE);
break;
In this way, the dialog box will be the same as MSN, after clicking "Close", it will be completed Minimized work too. So how do you manually respond to a window procedure's defined system controls?
We can use the function pointer method to intercept the messages we are interested in, and then let the predefined window procedure process them after processing. This process is roughly as follows:
WNDPROC OldProc;
OldProc = (WNDPROC)SetWindowsLong(hWnd, GWL_WNDPROC, (LONG)NewProc);
Of course, the new window procedure NewProc here is implemented by you in advance. After the above code is executed, when the system processes the window message of hWnd, it will first enter the NewProc callback process you implemented, and then after processing the message you are interested in, it will return to the original through the CallWindowProc function and the OldProc you saved in advance. The rest of the work is done during the callback.
The above is the principle analysis of window subclassing. Now I will use an example to actually explain how to subclass the window.
The interface for this example is as follows:

The edit box at the top of the interface is used to limit the floating-point input, and the following is an ordinary hyperlink.
Well, let me start to complete the subclassing of these two windows according to the steps: the
first step, when the main window dialog box is initialized, save the original window procedure and set up a new window procedure. The code is as follows:
case WM_INITDIALOG:
EditProc = (WNDPROC)SetWindowLong(GetDlgItem(hDlg, IDC_EDIT), GWL_WNDPROC, (LONG)ProcFloat);
StaticProc = (WNDPROC)SetWindowLong(GetDlgItem(hDlg, IDC_ST_HOMEPAGE), GWL_WNDPROC, (LONG)ProcLink);
break;
The second step is to implement the window procedure of the floating point edit box:
LRESULT CALLBACK ProcFloat(HWND hWnd, UINT Msg, WPARAM wParam, LPARAMlParam)
{
if (Msg == WM_CHAR && wParam != ”.” && (wParam <= ” 0” || wParam >= ”9”) && wParam != VK_BACK)
{
MessageBeep(MB_OK);
return 0;
}
else
return CallWindowProc(EditProc, hWnd, Msg, wParam, lParam);
}
What needs to be explained here is that due to the needs of the control itself, only one message needs to be intercepted, which is the WM_CHAR of the received character. When the character entered by the user is not a decimal point, 0-9 and the backspace key (be careful not to lose the backspace key, otherwise you will find that your edit box cannot delete the wrongly entered number), a sound is issued to prompt the input mistake. As for other messages, call the original callback function for processing.
The third step is to implement the window procedure of the hyperlink:
LRESULT CALLBACK ProcLink(HWND hWnd, UINT Msg, WPARAM wParam, LPARAMlParam)
{
switch (Msg)
{
case WM_SETCURSOR:
SetCursor(LoadCursor(NULL, IDC_HAND));
break;
case WM_LBUTTONDOWN:
ShellExecute(NULL, “open”, “ http://home.ncust.edu.cn/~titilima “, NULL, NULL, SW_SHOWNORMAL);
break;
default:
return CallWindowProc(StaticProc, hWnd, Msg, wParam, lParam);
}
return 0;
}
This code is easy to understand: it completes two things, one is to set the cursor pointer to a hand shape (note: for earlier Windows systems, there is no predefined IDC_HAND pointer, this time you need to be in the EXE resources Draw a hand pointer by yourself, such as the hand pointer in Delphi is drawn by yourself), the second is to open the web page link you want to open when you click the left mouse button.
In fact, for hyperlinks, the main thing is implemented outside of subclassing - its font color (note that this code is implemented in the callback process of the main window dialog):
case WM_CTLCOLORSTATIC:
if ( GetDlgItem(hDlg, IDC_ST_HOMEPAGE) == (HWND)lParam)
{
SetTextColor((HDC)wParam, 0xff0000);
SetBkMode((HDC)wParam, TRANSPARENT);
return (LRESULT)CreateSolidBrush(GetSysColor(COLOR_BTNFACE));
}
break;
also A few points to note are:
1. Your Static hyperlink must have a unique resource ID, for example, mine is IDC_ST_HOMEPAGE, so that you can use GetDlgItem to obtain its handle to complete subclassing;
2. You must It sets the SS_NOTIFY style to ensure that it can notify the parent window dialog when it is clicked;
3. The processing of clicking it to open the web page can also be placed outside the subclass, and the WM_COMMAND message of the main window dialog can also be processed implement this function.
The window subclassing of Win32 is introduced here. You can click here to download the supporting source code of this article. There are detailed comments in the code.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326137085&siteId=291194637