打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
Windows界面编程第三篇 异形窗体 普通版

分类: Windows编程 Windows界面编程

    上一篇《Windows界面编程第二篇 半透明窗体》介绍了先使用SetWindowLong为窗体加上WS_EX_LAYERED属性,再使用SetLayeredWindowAttributes调整窗体的透明度。本篇将使用这二个函数来完成另一个实用的功能——异形窗口(异形窗体)。

异形窗口的原理很简单,首先加载一张位图画刷作窗口背景,然后设置透明色就可以使得窗口由矩形变成任意形状。这样使得窗口的显示更加美观。

 

    下面先简单介绍下Win32 SDK方式创建窗口的流程(按《Windows程序设计》中的大体流程):

1.设置WNDCLASS类型的变量,这个变量将描述窗口的风格、窗口消息处理函数、程序图标、光标、窗口背景画刷等待。

2.使用RegisterClassWNDCLASS类型的变量注册下。

3.使用CreateWindowCreateWindowEx创建窗口,这里可以设置窗口的初始位置、初始大小、扩展属性等等。

4.通过ShowWindowUpdateWindow将窗口显示出来。

5.窗口显示完成后,在WinMain()函数中添加消息处理:   

       MSG msg;

       while (GetMessage(&msgNULL, 0, 0))

       {

              TranslateMessage(&msg);

              DispatchMessage(&msg);

       }

通过这五步就完成了一个窗口的创建了。

对于窗口消息函数,一般只要在WM_DESTROY消息中调用下PostQuitMessage(0);其它的消息都可以使用默认消息处理函数DefWindowProc

 

对于异形窗口,可以在WM_CREATE即窗口初始化时设置好透明色就完成了窗口形状的改变,不过为了支持鼠标对窗口的拖曳,还要在WM_LBUTTONDOWN消息中加入:

PostMessage(hwndWM_SYSCOMMANDSC_MOVE | HTCAPTION, 0);

这样,异形窗口就可以在屏幕上像普通窗口一样的移动了。

 

完整的源代码如下所示(下载地址:http://download.csdn.net/download/morewindows/4966815):

  1. //   异形窗口1  窗口背景使用位图画刷再指定透明色  
  2. //By MoreWindows-(http://blog.csdn.net/MoreWindows)  
  3. #include <windows.h>  
  4.   
  5. const char szAppName[] = "异形窗口1 MoreWindows-(http://blog.csdn.net/MoreWindows)";  
  6.   
  7. /* 
  8.  * 函数名称: GetWindowSize 
  9.  * 函数功能: 得到窗口的宽高 
  10.  * hwnd      窗口句柄 
  11.  * pnWidth   窗口宽 
  12.  * pnHeight  窗口高 
  13. */  
  14. void GetWindowSize(HWND hwnd, int *pnWidth, int *pnHeight);  
  15.   
  16.   
  17. /* 
  18.  * 函数名称: InitBitmapWindow 
  19.  * 函数功能: 位图窗口初始化 
  20.  * hinstance 进程实例 
  21.  * hBitmap   位图句柄 
  22.  * nCmdshow  显示方式-与ShowWindow函数的第二个参数相同 
  23. */  
  24. BOOL InitBitmapWindow(HINSTANCE hinstance, HBITMAP hBitmap, int nCmdshow);  
  25.   
  26. // 位图窗口消息处理函数  
  27. LRESULT CALLBACK BitmapWindowWndPrco(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParm);  
  28.   
  29.   
  30. int APIENTRY WinMain(HINSTANCE hInstance,  
  31.                      HINSTANCE hPrevInstance,  
  32.                      LPSTR     lpCmdLine,  
  33.                      int       nCmdShow)  
  34. {  
  35.     //设置窗口背景画刷为图片画刷,再指定透明颜色即可以创建透明区域。  
  36.     HBITMAP  hBitmap;  
  37.     hBitmap = (HBITMAP)LoadImage(NULL, "Kitty.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);  
  38.     if (hBitmap == NULL)  
  39.     {  
  40.         MessageBox(NULL, "位图加载失败""Error", MB_ICONERROR);  
  41.         return 0;  
  42.     }  
  43.     if (!InitBitmapWindow(hInstance, hBitmap, nCmdShow))  
  44.         return 0;  
  45.   
  46.     MSG msg;  
  47.     while (GetMessage(&msg, NULL, 0, 0))  
  48.     {  
  49.         TranslateMessage(&msg);  
  50.         DispatchMessage(&msg);  
  51.     }  
  52.     DeleteObject(hBitmap);  
  53.   
  54.     return msg.wParam;  
  55. }  
  56.   
  57.   
  58. BOOL InitBitmapWindow(HINSTANCE hinstance, HBITMAP hBitmap, int nCmdshow)  
  59. {  
  60.     HWND hwnd;  
  61.     WNDCLASS wndclass;  
  62.       
  63.     wndclass.style       = CS_VREDRAW | CS_HREDRAW;  
  64.     wndclass.lpfnWndProc = BitmapWindowWndPrco;   
  65.     wndclass.cbClsExtra  = 0;  
  66.     wndclass.cbWndExtra  = 0;  
  67.     wndclass.hInstance   = hinstance;     
  68.     wndclass.hIcon       = LoadIcon(NULL, IDI_APPLICATION);  
  69.     wndclass.hCursor     = LoadCursor(NULL, IDC_ARROW);  
  70.     wndclass.hbrBackground = CreatePatternBrush(hBitmap);//位图画刷  
  71.     wndclass.lpszMenuName  = NULL;  
  72.     wndclass.lpszClassName = szAppName;  
  73.       
  74.     if (!RegisterClass(&wndclass))  
  75.     {  
  76.         MessageBox(NULL, "Program Need Windows NT!""Error", MB_ICONERROR);  
  77.         return FALSE;  
  78.     }  
  79.   
  80.     BITMAP bm;  
  81.     GetObject(hBitmap, sizeof(bm), &bm);  
  82.     hwnd = CreateWindowEx(WS_EX_TOPMOST,  
  83.                         szAppName,  
  84.                         szAppName,   
  85.                         WS_POPUP,  
  86.                         CW_USEDEFAULT,   
  87.                         CW_USEDEFAULT,   
  88.                         bm.bmWidth,   
  89.                         bm.bmHeight,  
  90.                         NULL,  
  91.                         NULL,  
  92.                         hinstance,  
  93.                         NULL);  
  94.     if (hwnd == NULL)  
  95.         return FALSE;  
  96.       
  97.     ShowWindow(hwnd, nCmdshow);  
  98.     UpdateWindow(hwnd);  
  99.       
  100.     return TRUE;  
  101. }  
  102.   
  103. LRESULT CALLBACK BitmapWindowWndPrco(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParm)  
  104. {  
  105.     static HDC s_hdcMem;  
  106.     static HBRUSH s_hBackBrush;  
  107.       
  108.     switch (message)  
  109.     {  
  110.     case WM_CREATE:  
  111.         {  
  112.             // 设置分层属性  
  113.             SetWindowLong(hwnd, GWL_EXSTYLE, GetWindowLong(hwnd, GWL_EXSTYLE) | WS_EX_LAYERED);  
  114.             // 设置透明色  
  115.             COLORREF clTransparent = RGB(0, 0, 0);  
  116.             SetLayeredWindowAttributes(hwnd, clTransparent, 0, LWA_COLORKEY);  
  117.         }  
  118.         return 0;  
  119.   
  120.           
  121.     case WM_KEYDOWN:   
  122.         switch (wParam)  
  123.         {  
  124.         case VK_ESCAPE: //按下Esc键时退出  
  125.             SendMessage(hwnd, WM_DESTROY, 0, 0);  
  126.             return 0;  
  127.         }  
  128.         break;  
  129.       
  130.   
  131.     case WM_LBUTTONDOWN: //当鼠标左键点击时可以拖曳窗口  
  132.         PostMessage(hwnd, WM_SYSCOMMAND, SC_MOVE | HTCAPTION, 0);   
  133.         return 0;  
  134.   
  135.   
  136.     case WM_DESTROY:  
  137.         PostQuitMessage(0);  
  138.         return 0;  
  139.     }  
  140.     return DefWindowProc(hwnd, message, wParam, lParm);  
  141. }  
  142.   
  143. void GetWindowSize(HWND hwnd, int *pnWidth, int *pnHeight)  
  144. {  
  145.     RECT rc;  
  146.     GetWindowRect(hwnd, &rc);  
  147.     *pnWidth = rc.right - rc.left;  
  148.     *pnHeight = rc.bottom - rc.top;  
  149. }  

运行结果如下:

 

 

现在总结下异形窗口的创建,先通过创建位图画刷来做窗口的背景画刷,再通过SetWindowLong为窗体加上WS_EX_LAYERED属性,然后使用SetLayeredWindowAttributes指定窗口的透明色来完成窗口形状的调整。为了支持鼠标的拖曳,在WM_LBUTTONDOWN消息中作了特殊处理,使得异形窗口可以像普通窗口一样在屏幕上移动。

 

本篇程序中的异形窗口的大小是无法设置的,只能和位图一样。下一篇《Windows界面编程第四篇 异形窗体 高富帅版》将介绍窗口大小可以指定的异形窗口。欢迎继续浏览。


本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
windows编程——背景图片和透明特效的使用2
MFC 播放MP3
孙鑫VC视频教程笔记之第一课“Windows程序的内部运行原理”
windows窗口的创建
Win32编程基础知识_天空总是蓝色的
Windows 程序内部运行机制
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服