要创建一个无标题栏的窗口很简单,使用如下代码即可:
HWND hwnd = ::CreateWindowEx(NULL,
szClassName,
“无标题栏窗口”
//创建无标题栏窗口所要用的样式
WS_POPUP | WS_SYSMENU | WS_SIZEBOX,
100, //窗口所在屏幕上的 x 坐标
100, //窗口所在屏幕上的 y 坐标
300, //窗口的宽度
300, //窗口的高度
NULL,
NULL,
hInstance,
NULL)
但是没有标题栏的窗口不能被用户移动,也不能比较方便地关闭.
在 Windows下,每一个鼠标信息都是由 WM_NCHITTEST 消息产生的,这个参数包含了鼠标位置的信息,通常情况下,这个消息都交给 DefWindowProc 函数处理,这个函数会返回一个值来表示鼠标按下的部分,如果鼠标单击窗口标题栏,处理 WM_NCHITTEST 消息的 DefWindowProc 函数会返回 HTCAPTION ,然后 Windows 会向该窗口发送 WM_NCLBUTTONDOWN 消息,如果 DefWindowProc 返回值是 HTCLIENT ,Windows 就将屏幕坐标转化成窗户区坐标,并且通过 WM_LBUTTONDOWN 消息传递给用户,为了能在窗户区移动窗口,必须让 Windows 认为是在标题栏移动窗口,实现代码如下:
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,
" 移动窗口 " ,
WS_POPUP | WS_SYSMENU | WS_SIZEBOX,
100 ,
100 ,
300 ,
300 ,
0 ,
0 ,
hInstance,
NULL);
if (hwnd == NULL)
{
::MessageBox(NULL, " 创建窗口出错 " , " 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);
// 如果鼠标左键按下, 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);
}