要?jiǎng)?chuàng)建一個(gè)無(wú)標(biāo)題欄的窗口很簡(jiǎn)單,使用如下代碼即可:
HWND hwnd = ::CreateWindowEx(NULL,
szClassName,
“無(wú)標(biāo)題欄窗口”
//創(chuàng)建無(wú)標(biāo)題欄窗口所要用的樣式
WS_POPUP | WS_SYSMENU | WS_SIZEBOX,
100, //窗口所在屏幕上的 x 坐標(biāo)
100, //窗口所在屏幕上的 y 坐標(biāo)
300, //窗口的寬度
300, //窗口的高度
NULL,
NULL,
hInstance,
NULL)
但是沒(méi)有標(biāo)題欄的窗口不能被用戶(hù)移動(dòng),也不能比較方便地關(guān)閉.
在 Windows下,每一個(gè)鼠標(biāo)信息都是由 WM_NCHITTEST 消息產(chǎn)生的,這個(gè)參數(shù)包含了鼠標(biāo)位置的信息,通常情況下,這個(gè)消息都交給 DefWindowProc 函數(shù)處理,這個(gè)函數(shù)會(huì)返回一個(gè)值來(lái)表示鼠標(biāo)按下的部分,如果鼠標(biāo)單擊窗口標(biāo)題欄,處理 WM_NCHITTEST 消息的 DefWindowProc 函數(shù)會(huì)返回 HTCAPTION ,然后 Windows 會(huì)向該窗口發(fā)送 WM_NCLBUTTONDOWN 消息,如果 DefWindowProc 返回值是 HTCLIENT ,Windows 就將屏幕坐標(biāo)轉(zhuǎn)化成窗戶(hù)區(qū)坐標(biāo),并且通過(guò) WM_LBUTTONDOWN 消息傳遞給用戶(hù),為了能在窗戶(hù)區(qū)移動(dòng)窗口,必須讓 Windows 認(rèn)為是在標(biāo)題欄移動(dòng)窗口,實(shí)現(xiàn)代碼如下:
#include <windows.h>
LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);
int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow)
{
char *szClassName = "WndClass";
WNDCLASSEX wndclass;
wndclass.cbSize = sizeof(wndclass);
wndclass.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
wndclass.lpfnWndProc = WndProc;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hIcon = ::LoadIcon(NULL,IDI_APPLICATION);
wndclass.hCursor = ::LoadCursor(NULL,IDC_ARROW);
wndclass.hbrBackground = (HBRUSH)::CreateSolidBrush(RGB(255,255,255));
wndclass.hInstance = hInstance;
wndclass.lpszClassName = szClassName;
wndclass.lpszMenuName = NULL;
wndclass.hIconSm = NULL;
::RegisterClassEx(&wndclass);
HWND hwnd = ::CreateWindowEx(0,
szClassName,
"移動(dòng)窗口",
WS_POPUP | WS_SYSMENU | WS_SIZEBOX,
100,
100,
300,
300,
0,
0,
hInstance,
NULL);
if(hwnd == NULL)
{
::MessageBox(NULL,"創(chuàng)建窗口出錯(cuò)","error",MB_OK);
return -1;
}
::ShowWindow(hwnd,nCmdShow);
::UpdateWindow(hwnd);
MSG msg;
while(::GetMessage(&msg,NULL,0,0))
{
::TranslateMessage(&msg);
::DispatchMessage(&msg);
}
::DeleteObject(wndclass.hbrBackground);
return msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)
{
switch(msg)
{
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = ::BeginPaint(hwnd,&ps);
::EndPaint(hwnd,&ps);
return 0;
}
case WM_NCHITTEST:
{
UINT nHitTest;
nHitTest = ::DefWindowProc(hwnd,msg,wParam,lParam);
//如果鼠標(biāo)左鍵按下, GetAsyncKeyState 的返回值小于0
if(nHitTest == HTCLIENT && ::GetAsyncKeyState(MK_LBUTTON) < 0)
{
nHitTest = HTCAPTION;
}
return nHitTest;
}
case WM_DESTROY:
{
::PostQuitMessage(0);
return 0;
}
}
return ::DefWindowProc(hwnd,msg,wParam,lParam);
}