(搬运工)创建一个可移动的无标题栏窗口

要创建一个无标题栏的窗口很简单,使用如下代码即可:
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 认为是在标题栏移动窗口,实现代码如下:

 

#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,
                                     
" 移动窗口 " ,
                                     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);
}

 

你可能感兴趣的:((搬运工)创建一个可移动的无标题栏窗口)