原型:
WINUSERAPI
LONG
WINAPI
SetWindowLongA(
_In_ HWND hWnd,
_In_ int nIndex,
_In_ LONG dwNewLong);
WINUSERAPI
LONG
WINAPI
SetWindowLongW(
_In_ HWND hWnd,
_In_ int nIndex,
_In_ LONG dwNewLong);
#ifdef UNICODE
#define SetWindowLong SetWindowLongW
#else
#define SetWindowLong SetWindowLongA
#endif // !UNICODE
//第二个参数:
#define GWL_WNDPROC (-4)
#define GWL_HINSTANCE (-6)
#define GWL_HWNDPARENT (-8)
#define GWL_STYLE (-16)
#define GWL_EXSTYLE (-20)
#define GWL_USERDATA (-21)
#define GWL_ID (-12)
#ifdef _WIN64
#undef GWL_WNDPROC
#undef GWL_HINSTANCE
#undef GWL_HWNDPARENT
#undef GWL_USERDATA
1.GWL_STYLE、GWL_EXSTYLE都懂
2.就说这两个:GWL_WNDPROC、GWL_USERDATA
全局变量版本:
[
//子控件
static HWND g_hWndBtn;
static WNDPROC g_wndBtnProc;
//按钮
static LRESULT APIENTRY BtnProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
if (uMsg == WM_LBUTTONDOWN)
{
::MessageBox(NULL, L"mywnd2", 0, MB_OK);
return TRUE;
}
return CallWindowProc(g_wndBtnProc, hwnd, uMsg, wParam, lParam);
}
//关闭按钮
g_hWndBtn = ::CreateWindowW(L"BUTTON", L"点击", WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, 0, 0, 0, 0, hParent, nullptr, GetModuleHandle(0), nullptr);
if (g_hWndBtn)
{
g_wndBtnProc = (WNDPROC)SetWindowLong(g_hWndBtn, GWL_WNDPROC, (LONG)BtnProc);//设置响应
}
]
---
成员变量版本:
[
HWND m_hWndBtn;
WNDPROC m_wndBtnProc;
static LRESULT APIENTRY BtnProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
if (uMsg == WM_LBUTTONDOWN)
{
::MessageBox(NULL, L"mywnd1", 0, MB_OK);
return TRUE;
}
CMyWnd *pThis = (CMyWnd *)GetWindowLong(hwnd, GWL_USERDATA);
if (!pThis)
{
return 0;
}
return CallWindowProc(pThis->m_wndBtnProc, hwnd, uMsg, wParam, lParam);
}
//关闭按钮
m_hWndBtn = ::CreateWindowW(L"BUTTON", L"点击", WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, 0, 0, 0, 0, this->m_hWnd, nullptr, GetModuleHandle(0), nullptr);
if (m_hWndBtn)
{
m_wndBtnProc = (WNDPROC)SetWindowLong(m_hWndBtn, GWL_WNDPROC, (LONG)BtnProc);//设置响应
SetWindowLong(m_hWndBtn, GWL_USERDATA, (LONG)this);
}
]
说明:
1.SetWindowLong使用GWL_WNDPROC时,第三个参数是全局函数或静态全局函数,不能使用成员的
2.使用全局变量方便,局部变量版本可以用SetWindowLong(m_hWndBtn, GWL_USERDATA, (LONG)this);实现,但维护起来
有时比较麻烦
所以用第一种就好了