消息处理:移动窗口

要是去掉了窗口的标题栏怎么移动窗口呢?本文围绕此话题展开说明。

在创建窗口样式的时候传递WS_POPUP和WS_SYSMENU的组合就可以隐藏标题栏。

// Create WindowHWND hWnd = ::CreateWindowEx(NULL, szWindowClass, "Title", WS_POPUP|WS_SYSMENU|WS_SIZEBOX, 100, 100, 300, 300, NULL, NULL, hInstance, NULL); 现在窗口就没办法移动了。也不能比较方便地关闭。下面就通过欺骗windows解决移动窗口的问题。 在windows下,没一个鼠标消息都是由WM_NCHITTEST消息产生的,这个消息的参数包含了鼠标位置的信息。通常是将这个消息让DefWindowProc函数处理,该返回值会返回一个值来告诉Windows鼠标按下的是窗口的那一部分。Windows利用这个返回值来决定要发送的鼠标信息的类型。如果用鼠标左键单击窗口的标题栏,处理WM_NCHITTEST消息的DefWindowProc函数会返回HTCAPTION,,然后Windows会再向该窗口发送WM_NCLBUTTONDOWN消息。如果DefWindowProc函数的返回值是HTCLIENT,Windows就将鼠标所在位置的坐标从屏幕坐标转成客户区坐标,并通过WM_LBUTTONDOWN消息通知用户。

要想在客户区拖动鼠标就能移动窗口,必须骗下Windows,可以通过改变处理WM_NCHITTEST消息的DefWindowProc函数的返回值实现这个。

case WM_NCHITTEST:{UINT nHitTest;nHitTest = ::DefWindowProc(hWnd, WM_NCHITTEST, wParam, lParam);if (nHitTest == HTCLIENT &&::GetAsyncKeyState(MK_LBUTTON) < 0) // 如果鼠标左键按下,GetAsyncKeyState函数的返回值小于0nHitTest = HTCAPTION;return nHitTest;}通过WM_NCHITTEST在DefWindowProc返回值来判断如果是在客户端点击HTCLIENT消息同时是左键就将返回值替换为点击标题栏(HTCAPTION消息)。这样就可以了#include <windows.h>LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow){static TCHAR szAppName[] = TEXT ("欺骗Windows移动窗口");HWNDhwnd;MSGmsg;WNDCLASSEX wndclassex = {0};wndclassex.cbSize= sizeof(WNDCLASSEX);wndclassex.style= CS_HREDRAW | CS_VREDRAW;wndclassex.lpfnWndProc = WndProc;wndclassex.cbClsExtra = 0;wndclassex.cbWndExtra = 0;wndclassex.hInstance= hInstance;wndclassex.hIcon= LoadIcon (NULL, IDI_APPLICATION);wndclassex.hCursor= LoadCursor (NULL, IDC_ARROW);wndclassex.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH);wndclassex.lpszMenuName = NULL;wndclassex.lpszClassName = szAppName;wndclassex.hIconSm= wndclassex.hIcon;if (!RegisterClassEx (&wndclassex)){MessageBox (NULL, TEXT ("RegisterClassEx failed!"), szAppName, MB_ICONERROR);return 0;}hwnd = CreateWindowEx(NULL, szAppName, "Title", WS_POPUP|WS_SYSMENU|WS_SIZEBOX, 100, 100, 300, 300, NULL, NULL, hInstance, NULL);ShowWindow (hwnd, iCmdShow);UpdateWindow (hwnd);while (GetMessage (&msg, NULL, 0, 0)){TranslateMessage (&msg);DispatchMessage (&msg);}return msg.wParam;}LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam){HDC hdc;PAINTSTRUCT ps;switch (message){case WM_CREATE:return (0);case WM_NCHITTEST:{UINT nHitTest;nHitTest = ::DefWindowProc(hwnd, WM_NCHITTEST, wParam, lParam);if (nHitTest == HTCLIENT &&::GetAsyncKeyState(MK_LBUTTON) < 0) // 如果鼠标左键按下,GetAsyncKeyState函数的返回值小于0nHitTest = HTCAPTION;return nHitTest;}case WM_PAINT:hdc = BeginPaint (hwnd, &ps);TextOut (hdc, 0, 0, "A Window!", 27);EndPaint (hwnd, &ps);return (0);case WM_DESTROY:PostQuitMessage (0);return (0);}return DefWindowProc (hwnd, message, wParam, lParam);}

分明是比谁记的都清楚,比谁都更加在意,

消息处理:移动窗口

相关文章:

你感兴趣的文章:

标签云: