找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 252|回复: 3

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

[复制链接]

52

主题

62

回帖

0

积分

版主

积分
0
发表于 2013-10-6 23:03:02 | 显示全部楼层 |阅读模式
上一篇《Windows界面编程第二篇 半透明窗体》介绍了先使用SetWindowLong为窗体加上WS_EX_LAYERED属性,再使用SetLayeredWindowAttributes调整窗体的透明度。本篇将使用这二个函数来完成另一个实用的功能??异形窗口(异形窗体)。
异形窗口的原理很简单,首先加载一张位图画刷作窗口背景,然后设置透明色就可以使得窗口由矩形变成任意形状。这样使得窗口的显示更加美观。

    下面先简单介绍下Win32 SDK方式创建窗口的流程(按《Windows程序设计》中的大体流程):
1.设置WNDCLASS类型的变量,这个变量将描述窗口的风格、窗口消息处理函数、程序图标、光标、窗口背景画刷等待。
2.使用RegisterClassWNDCLASS类型的变量注册下。
3.使用CreateWindowCreateWindowEx创建窗口,这里可以设置窗口的初始位置、初始大小、扩展属性等等。
4.通过ShowWindowUpdateWindow将窗口显示出来。
5.窗口显示完成后,在WinMain()函数中添加消息处理:   
       MSG msg;
       while (GetMessage(&msg, NULL, 0, 0))
       {
              TranslateMessage(&msg);
              DispatchMessage(&msg);

       }
通过这五步就完成了一个窗口的创建了。
对于窗口消息函数,一般只要在WM_DESTROY消息中调用下PostQuitMessage(0);其它的消息都可以使用默认消息处理函数DefWindowProc

对于异形窗口,可以在WM_CREATE即窗口初始化时设置好透明色就完成了窗口形状的改变,不过为了支持鼠标对窗口的拖曳,还要在WM_LBUTTONDOWN消息中加入:
PostMessage(hwnd, WM_SYSCOMMAND, SC_MOVE | HTCAPTION, 0);
这样,异形窗口就可以在屏幕上像普通窗口一样的移动了。

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

[attachment=1113]



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

本篇程序中的异形窗口的大小是无法设置的,只能和位图一样。

本章源代码回复可见!!
[attachment=1114]


2

主题

25

回帖

0

积分

新手上路

积分
0
发表于 2013-10-7 14:20:00 | 显示全部楼层
: 我看看

1

主题

23

回帖

0

积分

新手上路

积分
0
发表于 2013-10-15 09:14:48 | 显示全部楼层
                        

0

主题

7

回帖

0

积分

新手上路

积分
0
发表于 2013-11-22 17:15:22 | 显示全部楼层
谢谢楼主~~~
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

果子博客
扫码关注微信公众号

Archiver|手机版|小黑屋|风叶林

GMT+8, 2026-2-1 04:40 , Processed in 0.081492 second(s), 21 queries .

Powered by 风叶林

© 2001-2026 Discuz! Team.

快速回复 返回顶部 返回列表