[英]Change WndProc of the window
I try to change standart WndProc
function. I have this code:我尝试更改标准WndProc
function。我有以下代码:
HWND btn = CreateWindowEx(WS_EX_TRANSPARENT | WS_EX_CLIENTEDGE, L"BUTTON", L"Window title", WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON
, 50, 50, 50, 50, (HWND)XApplicationMainWindow->window->_wnd, (HMENU)123,
(HINSTANCE)GetWindowLongPtr(XApplicationMainWindow->window->_wnd, GWLP_HINSTANCE), NULL);
SetWindowLongPtrW(btn, GWLP_WNDPROC, (LONG_PTR)SubclassWindowProc);
I can use L"BUTTON"
class name, but when I change WndProc
function I'll have a problem.我可以使用L"BUTTON"
class 名称,但是当我更改WndProc
function 时,我会遇到问题。
On this picture, you can see the blank square and normal button.在这张图片上,您可以看到空白方块和普通按钮。 If I try to create new WNDCLASS or WNDCLASSEX
, I'll have nothing... Why?如果我尝试创建新的WNDCLASS or WNDCLASSEX
,我将一无所有……为什么?
How can I change the standart WndProc
function, if I use L"BUTTON"
class name?如果我使用L"BUTTON"
class 名称,如何更改标准WndProc
function?
It's my second WndProc
:这是我的第二个WndProc
:
LRESULT CALLBACK SubclassWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
switch (uMsg) {
case WM_CREATE:
break;
case WM_COMMAND:
//Event click
switch (LOWORD(wParam))
{
case 123:
OutputDebugStringA("Subclass click2");
break;
default:
break;
}
break;
default:
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
return 0;
}
DefWindowProc()
is the wrong window procedure for your SubclassWindowProc()
to be calling. DefWindowProc()
是您要调用的SubclassWindowProc()
的错误 window 过程。
You need to call the previous window procedure that you are replacing - the window procedure that handles all of the button's default behaviors (like drawing the button so it actually looks like a button, and responding to user input like a button, etc).您需要调用之前要替换的 window 过程 - 处理按钮所有默认行为的 window 过程(例如绘制按钮使其实际上看起来像按钮,并像按钮一样响应用户输入等)。 SetWindowLongPtr()
returns a pointer to that procedure to you, but you are currently ignoring it. SetWindowLongPtr()
向您返回指向该过程的指针,但您目前忽略了它。
See Subclassing Controls on MSDN for more details.有关详细信息,请参阅 MSDN 上的子类化控件。
Try this instead:试试这个:
WNDPROC btnWndProc;
LRESULT CALLBACK SubclassWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
switch (uMsg) {
case WM_COMMAND:
//Event click
switch (LOWORD(wParam))
{
case 123:
OutputDebugStringA("Subclass click2");
break;
}
break;
}
return CallWindowProc(hWnd, btnWndProc, uMsg, wParam, lParam);
}
...
HWND btn = CreateWindowEx(...);
btnWndProc = (WNDPROC) SetWindowLongPtrW(btn, GWLP_WNDPROC, (LONG_PTR)SubclassWindowProc);
Alternatively, using SetWindowSubclass()
, which issafer than using SetWindowsLongPtr()
, eg:或者,使用SetWindowSubclass()
,这比使用SetWindowsLongPtr()
更安全,例如:
LRESULT CALLBACK SubclassWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData) {
switch (uMsg) {
case WM_NCDESTROY:
RemoveWindowSubclass(hWnd, SubclassWindowProc, uIdSubclass);
break;
case WM_COMMAND:
//Event click
switch (LOWORD(wParam))
{
case 123:
OutputDebugStringA("Subclass click2");
break;
}
break;
}
return DefSubclassProc(hWnd, uMsg, wParam, lParam);
}
...
HWND btn = CreateWindowEx(...);
SetWindowSubclass(btn, SubclassWindowProc, 1, 0);
Now, that being said, your subclass will never call OutputDebugStringA()
, because it will never receive the WM_COMMAND
message you are expecting.现在,话虽如此,您的子类永远不会调用OutputDebugStringA()
,因为它永远不会收到您期望的WM_COMMAND
消息。 When a button is clicked, a WM_COMMAND
message is not sent to the button itself.单击按钮时,不会向按钮本身发送WM_COMMAND
消息。 The button posts a WM_COMMAND
message to the button's parent window instead (in this case, to XApplicationMainWindow->window->_wnd
).该按钮改为将WM_COMMAND
消息发送到按钮的父级 window (在本例中为XApplicationMainWindow->window->_wnd
)。 So, you need to handle the WM_COMMAND
message in the window procedure of the parent window , not in the window procedure of the button itself.因此,您需要在父 window的 window 过程中处理WM_COMMAND
消息,而不是在按钮本身的 window 过程中。
Otherwise, if you still want to subclass the button itself, you will have to handle the WM_LBUTTON(DOWN|UP)
and WM_KEY(DOWN|UP)
/ WM_CHAR
messages that the button receives and then subsequently translates into a WM_COMMAND
message for its parent window.否则,如果您仍想子类化按钮本身,则必须处理按钮接收到的WM_LBUTTON(DOWN|UP)
和WM_KEY(DOWN|UP)
/ WM_CHAR
消息,然后将其转换为其父级 window 的WM_COMMAND
消息.
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.