要是去掉了窗口的标题栏怎么移动窗口呢?本文围绕此话题展开说明。
在创建窗口样式的时候传递WS_POPUP和WS_SYSMENU的组合就可以隐藏标题栏。
// Create Window HWND hWnd = ::CreateWindowEx(NULL, szWindowClass, "Title", WS_POPUP|WS_SYSMENU|WS_SIZEBOX, 100, 100, 300, 300, NULL, NULL, hInstance, NULL);现在窗口就没办法移动了。也不能比较方便地关闭。下面就通过欺骗windows解决移动窗口的问题。
要想在客户区拖动鼠标就能移动窗口,必须骗下Windows,可以通过改变处理WM_NCHITTEST消息的DefWindowProc函数的返回值实现这个。
case WM_NCHITTEST: { UINT nHitTest; nHitTest = ::DefWindowProc(hWnd, WM_NCHITTEST, wParam, lParam); if (nHitTest == HTCLIENT && ::GetAsyncKeyState(MK_LBUTTON) < 0) // 如果鼠标左键按下,GetAsyncKeyState函数的返回值小于0 nHitTest = 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移动窗口"); HWND hwnd; MSG msg; 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函数的返回值小于0 nHitTest = 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); }