如何解决GetWindowLonghwnd,0是什么意思?
LRESULT WINAPI TextViewWndProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)
{
TextView* ptv = (TextView*)GetWindowLong(hwnd,0);
switch (msg)
{
case WM_NCCREATE:
if ((ptv = new TextView(hwnd)) == nullptr)
return FALSE;
SetWindowLong(hwnd,(LONG)ptv);
return TRUE;
}
代码来自:http://www.catch22.net/tuts/neatpad/neatpad-overview
这里的TextView
是所有者绘制的控件。
我的问题是:
GetWindowLong(hwnd,0)
SetWindowLong(hwnd,(LONG)ptv);
那是什么意思?我已经搜索了MSDN it says:
当
hWnd
参数标识一个对话框时,以下值也可用。...
DWL_MSGRESULT
0检索在对话框过程中处理的消息的返回值。
如果函数成功,则返回值为请求的值。
如果函数失败,则返回值为零。要获取扩展的错误信息,请调用GetLastError。
如果先前未调用
SetWindowLong
,则GetWindowLong
对于额外的窗口或类存储器中的值将返回零。
解决方法
根据GetWindowLong()
文档:
nIndex
类型:int
要检索的值的从零开始的偏移量。 有效值的范围是从零到额外的窗口内存的字节数,减去四;例如,如果您指定了12个或更多字节的额外内存,则值8将是第三个32位整数的索引。
...
当hWnd参数标识对话框时,以下值也可用。
DWL_MSGRESULT
0
检索在对话框过程中处理的消息的返回值。
有问题的代码用于包装TextView
对象的窗口。该窗口不是对话框,调用InitTextView()
会调用一个WNDCLASSEX
函数,该函数会在注册cbWndExtra
时注册sizeof(TextView*)
字段为RegisterClassEx()
的{{1}} :
BOOL InitTextView()
{
WNDCLASSEX wcx;
//Window class for the main application parent window
wcx.cbSize = sizeof(wcx);
wcx.style = 0;
wcx.lpfnWndProc = TextViewWndProc; // <--
wcx.cbClsExtra = 0;
wcx.cbWndExtra = sizeof(TextView *); // <--
wcx.hInstance = GetModuleHandle(0);
wcx.hIcon = 0;
wcx.hCursor = LoadCursor (NULL,IDC_IBEAM);
wcx.hbrBackground = (HBRUSH)0; //NO FLICKERING FOR US!!
wcx.lpszMenuName = 0;
wcx.lpszClassName = TEXTVIEW_CLASS; // <--
wcx.hIconSm = 0;
return RegisterClassEx(&wcx) ? TRUE : FALSE;
}
然后有一个CreateTextView()
函数,使用该注册的类创建一个新窗口,从而创建一个新的TextView
对象:
HWND CreateTextView(HWND hwndParent)
{
return CreateWindowEx(WS_EX_CLIENTEDGE,TEXTVIEW_CLASS,_T(""),// <--
WS_VSCROLL |WS_HSCROLL | WS_CHILD | WS_VISIBLE,hwndParent,GetModuleHandle(0),0);
}
在窗口的WM_NCCREATE
处理程序中,创建了一个新的TextView
对象,并且指向该对象的指针直接存储在HWND
本身中,位于窗口额外内存的偏移量0处。然后,同一窗口的其他消息处理程序可以检索该TextView*
指针,并根据需要使用该对象。在这种情况下,WM_NCDESTROY
和WM_PAINT
专门:
LRESULT WINAPI TextViewWndProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)
{
TextView *ptv = (TextView *)GetWindowLong(hwnd,0);
switch(msg)
{
// First message received by any window - make a new TextView object
// and store pointer to it in our extra-window-bytes
case WM_NCCREATE:
if((ptv = new TextView(hwnd)) == 0)
return FALSE;
SetWindowLong(hwnd,(LONG)ptv);
return TRUE;
// Last message received by any window - delete the TextView object
case WM_NCDESTROY:
delete ptv;
return 0;
// Draw contents of TextView whenever window needs updating
case WM_PAINT:
return ptv->OnPaint();
default:
break;
}
return DefWindowProc(hwnd,msg,wParam,lParam);
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。