win32 如何改变窗口过程
工作中用到了这些,就总结了一下,方便以后复习,总要留下点什么东西嘛!
1.CallWindowProc
该函数CallWindowProc将消息信息传送给指定的窗口过程。
函数原型:
LRESULT CallWindowProc(
WNDPROC lpPrevWndFunc,
HWND hWnd,
UINT Msg,
WPARAM wParam,
LPARAMIParam);
参数:
lpPrevWndFunc
:参数主要是指向你要调用的函数句柄
hWnd
:指向接收消息的窗口过程的句柄。
Msg
:指定消息类型。
wParam
:指定其余的、消息特定的信息。该参数的内容与Msg参数值有关。
IParam
:指定其余的、消息特定的信息。该参数的内容与Msg参数值有关。
返回值:返回值指定了消息处理结果,它与发送的消息有关
备注:使用函数CallWindowsProc可进行窗口子分类。通常来说,同一类的所有窗口共享一个窗口过程。子类是一个窗口或者相同类的一套窗口,在其消息被传送到该类的窗口过程之前,这些消息是由另一个窗口过程进行解释和处理的。
2.SetWindowLoog
setWindowLoog函数通过改变与特定窗口相关的窗口过程,使系统调用新的窗口过程来创建子类,新的窗口过程替换了以前的窗口过程。应用程序必须通过调用CallWindowsProc来将新窗日过程没有处理的任何消息传送到以前的窗口过程中,这样就允许应用程序创建一系列窗口过程。
函数原型:
LONG SetWindowLong(
HWND hWnd, // handle to window
int nlndex, // offset of value to set
LONG dwNewLong // new value
);
参数表
参数 类型及说明
hwnd Long
,欲为其获取信息的窗口的句柄
nIndex Long
,欲取回的信息,可以是下述任何一个常数:
GWL_EXSTYLE
扩展窗口样式
GWL_STYLE
窗口样式
GWL_WNDPROC
该窗口的窗口函数的地址
GWL_HINSTANCE
拥有窗口的实例的句柄
GWL_HWNDPARENT
该窗口之父的句柄。不要用SetWindowWord来改变这个值
GWL_ID
对话框中一个子窗口的标识符
GWL_USERDATA
含义由应用程序规定
DWL_DLGPROC
这个窗口的对话框函数地址
DWL_MSGRESULT
在对话框函数中处理的一条消息返回的值
DWL_USER
含义由应用程序规定
dwNewLong Long
这是一个新的窗口过程
子类化的过程实际上是很简单的。先创建一个窗口过程来为被子类化的窗口提供新功能,再用基础窗口类创建一个窗口。然后为该窗口调用GetWindowLong来获得并保存一个指向其初始窗口过程的指针,之后调用SetWindowLong函数,将窗口实例的窗口过程设置成新的窗口过程。这样,新的窗口过程就开始接收发给该窗口的消息了。任何没有被新窗口过程响应的消息都通过调用CallWindowProc传递给到旧的窗口过程。
下面的代码展示了窗口创建及被子类化的过程。子类化窗口过程截获了WM_LBUTTONDOWN消息,并且在窗口收到该消息时使扬声器发出声音。
这个是对新子类化的窗口过程:
LRESULT CALLBACK SCWndProc(HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam);
用WNDPROC 类型缓存旧的窗口过程
WNDPROC lpfnOldProc = 0;
lpfnOldProc = (WNDPROC)SetWindowLong(GetSafeHwnd(), DWL_DLGPROC, (DWORD)SCWndProc);
// 新窗口响应函数,对未截取的消息,返回原消息响应函数执行
LRESULT CALLBACK SCWndProc(HWND hWnd, UINT wMsg, WPARAM wParam,LPARAM lParam)
{
switch (wMsg) {
case WM_LBUTTONDOWN:
MessageBeep(0);
break;
}
return CallWindowProc (lpfnOldProc, hWnd, wMsg, wParam, lParam);
}
请继续看下面,刚好和双缓冲结合用了一下
LRESULT CALLBACK WebbrowserProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
if (msg==WM_PAINT)
{
PAINTSTRUCT ps;
RECT rtClient;
GetClientRect(hWnd, &rtClient);
HDC hdc = BeginPaint(hWnd, &ps);
HDC hMemDC = CreateCompatibleDC(hdc);
HBITMAP hBitmap = CreateCompatibleBitmap(hdc, rtClient.right - rtClient.left, rtClient.bottom - rtClient.top);//rt为RECT变量;
SelectObject(hMemDC, hBitmap);
HBRUSH hbrush, hbrushold;
hbrush = CreateSolidBrush(RGB(255, 0, 0));
hbrushold = (HBRUSH)SelectObject(hMemDC, hbrush);
MoveToEx(hMemDC, 100, 100, NULL);
LineTo(hMemDC, 150, 230);
Rectangle(hMemDC, 200, 200, 300, 300);
Ellipse(hMemDC, 15, 15, 130, 130);
SelectObject(hMemDC, hbrushold);
DeleteObject(hbrush);
BitBlt(hdc, 0, 0, rtClient.right - rtClient.left, rtClient.bottom - rtClient.top,
hMemDC, 0, 0, SRCCOPY);
DeleteDC(hMemDC);
DeleteObject(hBitmap);
EndPaint(hWnd, &ps);
}
else
{
return CallWindowProc(m_pPreProcWebbrowser, hWnd, msg, wParam, lParam);
}
}
m_hwndFram[0] = CreateWindow("static", "1", SS_NOTIFY | STN_CLICKED | STN_DBLCLK | WS_CHILD | WS_BORDER | SS_CENTER | SS_CENTERIMAGE, rc.left, rc.top, (rc.right - rc.left) / 2, (rc.bottom - rc.top) / 2,
hWnd, //父窗口句柄
(HMENU)IDC_STATIC0, //为控件指定一个唯一标识符
NULL, //当前程序实例句柄
NULL
);
m_pPreProcWebbrowser = (WNDPROC)SetWindowLong(m_hwndFram[0], GWL_WNDPROC, (LONG)WebbrowserProc);