1.位图背景与位图画刷

1.WM_CTLCOLORDLG消息

  在对话框画出来之前,系统将该消息发给对话框窗口。通过WM_CTLCOLORDLG消息来设置对话框文本和背景。

  当窗口处理函数处理这个消息时,wParam表示对话框设备上下文(HDC),lParam表示对话框句柄。

  如果处理了这个消息,返回一个画刷,系统用这个画刷重绘对话框背景。  

  因此,在WM_CTLCOLORDLG消息中获得对话框的大小,通过StretchBlt函数将位图缩放后放到对话框中,就完成了背景设置。

  并且,要返回一个空画刷给系统,系统才不会将位图背景覆盖。

  在使用StretchBlt函数前,最好先用SetStretchBltMode函数来设置位图内容伸展模式,避免位图缩放后失真严重。

  int  SetStretchBltMode( HDC  hdc, int  iStretchMode);

  伸展模式:

  BLACKONWHITE / STRETCH_ANDSCANS

    如果两个或多个像素得合成一个像素,那么StretchBlt会对像素执行一个逻辑and运算。只有全部的原始像素是白色时,该像素

    才是白色,其实际意义是黑色像素控制了白色像素,适用于白色背景中是黑色的单色点阵图。

  WHITEONBLACK / STRETCH_ORSCANS

    如果两个或多个像素得合成一个像素,那么StretchBlt会对像素执行一个逻辑or运算。只有全部的原始像素是黑色时,该像素才

    是黑色,也就是说白色像素决定颜色,适用于黑色背景中白色的单色点阵图。

  COLORONCOLOR / STRETCH_DELETESCANS

    简单地消除图素行或列,而没有任何逻辑组合。通常是处理彩色点阵图的最佳方法。

  HALFONE / STRETCH_HALFONE

    根据组合起来的源颜色计算目的的平均颜色。 

  代码:  

 1 #include "stdafx.h"
 2 #include "01位图背景与位图画刷.h"
 3 
 4 WCHAR dlgTitle[] = L"位图背景";
 5 
 6 BOOL CALLBACK DlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
 7 {
 8     RECT rcDialog = { 0 };
 9     HBITMAP hBitmap = 0;
10     static BITMAP s_bm = { 0 };
11     static HDC s_hdcMem = 0;
12     HDC hdc = 0;
13     switch (message)
14     {
15     case WM_INITDIALOG:
16         SetWindowText(hDlg, dlgTitle); //设置对话框标题
17         SetWindowLong(hDlg, GWL_STYLE, GetWindowLong(hDlg, GWL_STYLE) | WS_SIZEBOX); //设置对话框大小可调节
18 
19         //加载背景图片                                                                             
20         hBitmap = (HBITMAP)LoadImage(NULL, L"005.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE | LR_CREATEDIBSECTION);
21         if (hBitmap == NULL)
22         {
23             MessageBox(hDlg, L"fail to load image!", L"Error", MB_ICONERROR);
24             exit(0);
25         }
26 
27         //将背景图放入hdc
28         hdc = GetDC(hDlg);
29         s_hdcMem = CreateCompatibleDC(hdc);
30         SelectObject(s_hdcMem, hBitmap);
31         ReleaseDC(hDlg, hdc);
32 
33         //得到位图信息
34         GetObject(hBitmap, sizeof(s_bm), &s_bm);
35         return FALSE;
36 
37     case WM_SIZE:
38         InvalidateRect(hDlg, NULL, TRUE);
39         return FALSE;
40 
41     case WM_CTLCOLORDLG:
42         //返回一个画刷,系统用该画刷重绘对话框背景,wParam为设备上下文HDC,lParam为窗口句柄
43         //然后返回一个空画刷给系统,这样系统就不会将位图背景给覆盖了
44         GetClientRect(hDlg, &rcDialog);
45         SetStretchBltMode((HDC)wParam, COLORONCOLOR);
46         StretchBlt((HDC)wParam, 0, 0, rcDialog.right, rcDialog.bottom, s_hdcMem, 0, 0, s_bm.bmWidth, s_bm.bmHeight, SRCCOPY);
47         return (BOOL)((HBRUSH)GetStockObject(NULL_BRUSH));
48 
49     case WM_COMMAND:
50         if (IDCANCEL == LOWORD(wParam))
51         {
52             DeleteDC(s_hdcMem);
53             EndDialog(hDlg, LOWORD(wParam));
54             return FALSE;
55         }
56         break;
57     }
58     return FALSE;
59 }
60 
61 
62 int APIENTRY wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow)
63 {
64     DialogBox(hInstance, MAKEINTRESOURCE(IDD_DIALOG1), NULL, DlgProc);
65     return 0;
66 }
View Code

  运行结果:

                

  也可以创建爱你一个位图画刷,然后再WM_CTLCOLORDLG消息中直接返回这个画刷,也能完成设置背景功能

  HBRUSH  CreatePatternBrush( HBITMAP  hbmp); 

  代码: 

 1 #include "stdafx.h"
 2 #include "01位图画刷.h"
 3 
 4 WCHAR szDlgTitle[] = L"位图画刷";
 5 
 6 BOOL CALLBACK DlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParams)
 7 {
 8     static HBRUSH s_hBitmapBrush; //位图画刷
 9     switch (message)
10     {
11     case WM_INITDIALOG: 
12         SetWindowText(hDlg, szDlgTitle); 
13         SetWindowLong(hDlg, GWL_STYLE, GetWindowLong(hDlg, GWL_STYLE) | WS_SIZEBOX);
14 
15         // 加载背影图片  
16         HBITMAP hBitmap;
17         hBitmap = (HBITMAP)LoadImage(NULL, L"005.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE | LR_CREATEDIBSECTION);
18         if (hBitmap == NULL)
19         {
20             MessageBox(hDlg, L"LoadImage failed", L"Error", MB_ICONERROR);
21             exit(0);
22         }
23 
24         // 创建位图画刷  
25         s_hBitmapBrush = CreatePatternBrush(hBitmap);
26         return FALSE;
27 
28     case WM_COMMAND:
29         if (IDCANCEL == LOWORD(wParam))
30         {
31             DeleteObject(s_hBitmapBrush);
32             EndDialog(hDlg, LOWORD(wParam));
33             return TRUE;
34         }
35         break;
36 
37     case WM_CTLCOLORDLG:
38         return (BOOL)s_hBitmapBrush;
39     }
40     return FALSE;
41 }
42 
43 int APIENTRY wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow)
44 {
45     DialogBox(hInstance, MAKEINTRESOURCE(IDD_DIALOG1), NULL, DlgProc);
46     return 0;
47 }
View Code

  运行结果:

  注意,这两做法在窗口大小超过位图大小时会表现不同,前一种做法会拉伸位图以适应窗口大小,后一种做法是直接平铺。

                 

                   

  类似的消息还有WM_CTLCOLORBTN、WM_CTLCOLOREDIT、WM_CTLCOLORLISTBOX、WM_CTLCOLORSCROLLBAR、WM_CTLCOLORSTATIC,分别用于设置按钮、编辑框、列表框、滚动条、静态框。

原文地址:https://www.cnblogs.com/csqtech/p/5882590.html