Windows界面编程背景图片透明特效使用.docx
《Windows界面编程背景图片透明特效使用.docx》由会员分享,可在线阅读,更多相关《Windows界面编程背景图片透明特效使用.docx(57页珍藏版)》请在冰豆网上搜索。
Windows界面编程背景图片透明特效使用
Windows界面编程第一篇位图背景与位图画刷
可以通过WM_CTLCOLORDLG消息来设置对话框的背景,MSDN上对这个消息的说明如下:
The WM_CTLCOLORDLG messageissenttoadialogboxbeforethesystemdrawsthedialogbox.Byrespondingtothismessage,thedialogboxcansetitstextandbackgroundcolorsusingthespecifieddisplaydevicecontexthandle.
当窗口消息响应函数接收这个消息时,wParam表示对话框的设备上下方即HDC,lParam表示对话框的句柄。
如果程序处理了这个消息,应返回一个画刷。
系统将会用这个画刷来重绘对话框背景。
因此我们在这个WM_CTLCOLORDLG消息中得到对话框的大小,并通过StretchBlt函数将位图缩放后贴到对话框的HDC中就完成了对话框背景的设置,然后返回一个空画刷给系统,这样系统就不会将位图背景给覆盖了。
代码非常简单,要注意的是在使用StretchBlt函数缩放位图时,最好先使用
SetStretchBltMode函数来设置下位图内容伸展模式,这样可以避免缩放后位图失真严重。
SetStretchBltMode函数原型如下:
int SetStretchBltMode(
HDChdc, //handletoDC
int iStretchMode //bitmapstretchingmode
);
第一个参数就是设备上下方即HDC。
第二个参数有四种设置:
1. BLACKONWHITE or STRETCH_ANDSCANS
如果两个或多个像素得合并成一个像素,那么StretchBlt会对像素执行一个逻辑AND运算。
这样的结果是只有全部的原始像素是白色时该像素才为白色,其实际意义是黑色像素控制了白色像素。
这适用于白色背景中主要是黑色的单色点阵图。
2. WHITEONBLACK or STRETCH_ORSCANS
如果两个或多个像素得合并成一个像素,那么StretchBlt会对像素执行逻辑OR运算。
这样的结果是只有全部的原始像素都是黑色时该像素才为黑色,也就是说由白色像素决定颜色。
这适用于黑色背景中主要是白色的单色点阵图。
3. COLORONCOLOR or STRETCH_DELETESCANS
简单地消除图素行或列,而没有任何逻辑组合。
这是通常是处理彩色点阵图的最佳方法。
4. HALFTONE or STRETCH_HALFTONE
根据组合起来的来源颜色来计算目的的平均颜色。
其它技术细节可以见代码中的注释,完整代码如下(也可以下载,下载地址为:
[cpp] viewplaincopyprint?
1.// 对话框位图背景 - WM_CTLCOLORDLG中使用StretchBlt贴图
2.//By MoreWindows-(
3.#include
4.#include "resource.h"
5.
6.const char szDlgTitle[] = "位图背景 使用StretchBlt贴图 MoreWindows-(
7.
8.// 对话框消息处理函数
9.BOOL CALLBACK DlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);
10.
11.int APIENTRY WinMain(HINSTANCE hInstance,
12. HINSTANCE hPrevInstance,
13. LPSTR lpCmdLine,
14. int nCmdShow)
15.{
16. DialogBox(hInstance, MAKEINTRESOURCE(IDD_DIALOG1), NULL, DlgProc);
17. return 0;
18.}
19.
20.
21.BOOL CALLBACK DlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
22.{
23. RECT rcDialog;
24. HBITMAP hBitmap;
25. static BITMAP s_bm;
26. static HDC s_hdcMem;
27.
28. switch (message)
29. {
30. case WM_INITDIALOG:
31. // 设置对话框标题
32. SetWindowText(hDlg, szDlgTitle);
33. // 设置对话框大小可调节
34. SetWindowLong(hDlg, GWL_STYLE, GetWindowLong(hDlg, GWL_STYLE) | WS_SIZEBOX);
35.
36. // 加载背影图片
37. hBitmap = (HBITMAP)LoadImage(NULL, "005.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE | LR_CREATEDIBSECTION);
38. if (hBitmap == NULL)
39. {
40. MessageBox(hDlg, "LoadImage failed", "Error", MB_ICONERROR);
41. exit(0);
42. }
43. else
44. {
45. // 将背影图片放入HDC - s_hdcMem
46. HDC hdc;
47. hdc = GetDC(hDlg);
48. s_hdcMem = CreateCompatibleDC(hdc);
49. SelectObject(s_hdcMem, hBitmap);
50. ReleaseDC(hDlg, hdc);
51.
52. // 得到位图信息
53. GetObject(hBitmap, sizeof(s_bm), &s_bm);
54. }
55.
56. return 0;
57.
58. case WM_COMMAND:
59. switch (LOWORD(wParam))
60. {
61. case IDCANCEL:
62. DeleteDC(s_hdcMem);
63. EndDialog(hDlg, LOWORD(wParam));
64. return TRUE;
65. }
66. break;
67.
68.
69. case WM_SIZE:
70. InvalidateRect(hDlg, NULL, TRUE);
71. return TRUE;
72.
73. case WM_CTLCOLORDLG:
74. GetClientRect(hDlg, &rcDialog);
75. //通过SetStretchBltMode的设置能使StretchBlt在缩放图像更加清晰
76. SetStretchBltMode((HDC)wParam, COLORONCOLOR);
77. StretchBlt((HDC)wParam, 0, 0, rcDialog.right, rcDialog.bottom, s_hdcMem, 0, 0, s_bm.bmWidth, s_bm.bmHeight, SRCCOPY);
78. return (BOOL)((HBRUSH)GetStockObject(NULL_BRUSH));
79. }
80. return FALSE;
81.}
运行结果如下:
在上面这种方法中,我们是在WM_CTLCOLORDLG中贴图来完成背景设置了,也可以创建一个位图画刷,然后在WM_CTLCOLORDLG消息中直接返回这个画刷,这样系统将完成贴图功能。
位图画刷的创建函数为CreatePatternBrush,其函数原型如下:
HBRUSHCreatePatternBrush(
HBITMAPhbmp //handletobitmap
);
只要给这个函数传入位图句柄即可,完整代码如下(下载地址为:
[cpp] viewplaincopyprint?
1.// 对话框位图背景 - 直接在WM_CTLCOLORDLG中使用位图画刷
2.//By MoreWindows-(
3.#include
4.#include "resource.h"
5.
6.const char szDlgTitle[] = "位图画刷 MoreWindows-(
7.
8.
9.// 对话框消息处理函数
10.BOOL CALLBACK DlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);
11.
12.int APIENTRY WinMain(HINSTANCE hInstance,
13. HINSTANCE hPrevInstance,
14. LPSTR lpCmdLine,
15. int nCmdShow)
16.{
17. DialogBox(hInstance, MAKEINTRESOURCE(IDD_DIALOG1), NULL, DlgProc);
18. return 0;
19.}
20.
21.
22.BOOL CALLBACK DlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
23.{
24. static HBRUSH s_hBitmapBrush; //位图画刷
25.
26. switch (message)
27. {
28. case WM_INITDIALOG:
29. // 设置对话框标题
30. SetWindowText(hDlg, szDlgTitle);
31. // 设置对话框大小可调节
32. SetWindowLong(hDlg, GWL_STYLE, GetWindowLong(hDlg, GWL_STYLE) | WS_SIZEBOX);
33.
34. // 加载背影图片
35. HBITMAP hBitmap;
36. hBitmap = (HBITMAP)LoadImage(NULL, "005.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE | LR_CREATEDIBSECTION);
37. if (hBitmap == NULL)
38. {
39. MessageBox(hDlg, "LoadImage failed", "Error", MB_ICONERROR);
40. exit(0);
41. }
42.
43. // 创建位图画刷
44. s_hBitmapBrush = CreatePatternBrush(hBitmap);
45. return 0;
46.
47.
48. case WM_COMMAND:
49. switch (LOWORD(wParam))
50. {
51. case IDCANCEL:
52. DeleteObject(s_hBitmapBrush);
53. EndDialog(hDlg, LOWORD(wParam));
54. return TRUE;
55. }
56. break;
57.
58. case WM_CTLCOLORDLG:
59. return (BOOL)s_hBitmapBrush;
60. }
61. return FALSE;
62.}
运行结果如下:
注意,这两做法在窗口大小超过位图大小时会表现不同,前一种做法会拉伸位图以适应窗口大小,后一种做法是直接平铺。
详见下图:
本篇《Windows界面编程第一篇位图背景与位图画刷》主要介绍了通过WM_CTLCOLORDLG消息来设置对话框的背景,在Windows系统中还有类似于WM_CTLCOLORDLG消息的还有WM_CTLCOLORBTN,WM_CTLCOLOREDIT,WM_CTLCOLORLISTBOX,WM_CTLCOLORSCROLLBAR,WM_CTLCOLORSTATIC这五种来分别管理按钮,编辑框,列表框,滚动条,静态框。
有兴趣的读者可以试验下。
下一篇将介绍调节窗体透明度的方法,欢迎继续浏览《Windows界面编程第二篇半透明窗体》
当窗口的背景用彩色图片来装饰时,其它控件如果还是用灰色的背景会显的比较不谐调,《Windows界面编程第五篇静态控件背景透明化》将介绍如何为静态框设置透明背景。
Windows界面编程第二篇半透明窗体
上一篇《Windows界面编程第一篇位图背景与位图画刷》介绍了通过WM_CTLCOLORDLG消息来来设置对话框的背景以及位图画刷的使用。
本篇将介绍动态调节窗体透明度的方法。
调节窗体透明度可以先使用SetWindowLong为窗体加上WS_EX_LAYERED属性,再使用来SetLayeredWindowAttributes指定窗体的透明度。
这样就可以在程序运行时动态的调节窗体的透明度了。
下面先介绍下SetWindowLong和SetLayeredWindowAttributes函数。
SetWindowLong可以用来设置窗口的一些属性,其函数原型如下:
LONGSetWindowLong(
HWNDhWnd,
int nIndex,
LONGdwNewLong
);
第一个参数表示窗口句柄。
第二个参数代表要设置的哪一种值,如GWL_STYLE表示将设置窗口的风格,这个参数还可以取GWL_EXSTYLE,GWL_WNDPROC,DWL_DLGPROC,GWL_HINSTANCE,GWL_USERDATA等等。
第三个参数表示要设置的值。
比如要设置对话框也能够可调节窗口大小,可以用:
// 设置对话框大小可调节
SetWindowLong(hDlg, GWL_STYLE, GetWindowLong(hDlg, GWL_STYLE)| WS_SIZEBOX);
SetLayeredWindowAttributes在MSDN上解释如下:
The SetLayeredWindowAttributes functionsetstheopacityandtransparencycolorkeyofalayeredwindow.
其函数原型为:
BOOLSetLayeredWindowAttributes(
HWNDhwnd,
COLORREFcrKey,
BYTEbAlpha,
DWORDdwFlags
);
第一个参数表示窗口句柄。
第二个参数表示透明色。
第三个参数表示透明度。
第四个参数表示函数将完成什么样的功能,设置成LWA_COLORKEY表示为窗口指定了透明色,设置成LWA_ALPHA表示将调整窗口的透明度,可以同时设置这两种功能。
程序代码还将用到Slider控件,这种控件可以有如下操作:
1.通过SendMessage + TBM_SETRANGE来设置滑块变化的范围。
2.通过SendMessage + TBM_SETPOS来设置滑块当前位置。
3.通过SendMessage + TBM_GETPOS来获得滑块当前位置。
4.当滑块位置发生变化时,在其父窗口中通过WM_HSCROLL或WM_VSCROLL来响应消息。
下面给出完整的源代码(下载地址:
[cpp] viewplaincopyprint?
1.// 可变透明度窗体 先加上WS_EX_LAYERED属性再SetLayeredWindowAttributes设置透明度
2.//By MoreWindows-(
3.#include
4.#include
5.#include "resource.h"
6.const char szDlgTitle[] = "可变透明度窗体 MoreWindows-(
7.// 对话框消息处理函数
8.BOOL CALLBACK DlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);
9.
10.int APIENTRY WinMain(HINSTANCE hInstance,
11. HINSTANCE hPrevInstance,
12. LPSTR lpCmdLine,
13. int nCmdShow)
14.{
15. DialogBox(hInstance, MAKEINTRESOURCE(IDD_DIALOG1), NULL, DlgProc);
16. return 0;
17.}
18.
19.
20.BOOL CALLBACK DlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
21.{
22. const int INIT_TRANSPARENT = 200; //窗体初始透明度
23. static HBRUSH s_hBitmapBrush; //位图画刷
24.
25. switch (message)
26. {
27. case WM_INITDIALOG:
28. // 设置对话框标题
29. SetWindowText(hDlg, szDlgTitle);
30.
31. // 加载背影图片
32. HBITMAP hBitmap;
33. hBitmap = (HBITMAP)LoadImage(NULL, "005.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE | LR_CREATEDIBSECTION);
34. if (hBitmap == NULL)
35. {
36. MessageBox(hDlg, "LoadImage failed", "Error", MB_ICONERROR);
37. exit(0);
38. }
39.
40. // 创建位图画刷
41. s_hBitmapBrush = CreatePatternBrush(hBi