对话框的位图背景
关于将位图设置为对话框背景的文章。不需要 API。

引言
本文旨在提供一种将位图设置为对话框背景的解决方案。将位图设置为背景,您可以将控件放置在位图上,而不会被遮挡。使用资源编辑器将位图放入对话框中会强制位图位于前景,并阻碍放置其他控件。
背景
在我忙于设计和构建USB控制接口的工业工程毕业项目时,最后一步是编写一个应用程序与该板进行通信。 我选择了一个易于使用的图形界面。 在CAD上绘制PCB几个小时后,我截取了一个屏幕转储,并认为它最终确定了。 当我使用资源编辑器将屏幕转储插入到应用程序中时,我发现没有显示任何GUI绘图命令。 在删除位图以确保正在绘制OnPaint
指令后,我意识到该位图绘制为前景,并且资源编辑器中没有强制位图进入背景的选项。 我在互联网上搜索解决方案。 我发现了一些可能的解决方案,但是它们都涉及下载另一位作者编写的API。 我挑战自己,是否有可能提出解决此问题的自己的解决方案。 我成功了,并在此处描述我的解决方案。
使用代码
步骤 1: 在资源编辑器中将位图图像加载到“位图”下。 将深度从 16 色更改为 24 位真彩色。
步骤 2: 为位图分配资源 ID,并将对话框大小调整为位图的大小。 这样可以确保 Windows 不会用屏幕转储填充空白区域。 禁用最大化框,否则必须处理 OnSize
消息以调整位图的大小,以填充剩余区域。 最好在 OnInitDialog();
中使用 SW_SHOWNORMAL
而不是 SW_MAXIMIZE
。
步骤 3: 在位图的头文件中,在“受保护”下添加 Cbitmap
类、CSize
句柄和 CBrush
句柄,如下例所示
// Dialog Data
enum { IDD = IDD_BITMAPBACKGROUND_DIALOG };
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
Cbitmap Background; // For Holding The bitmap
CBrush BrushHol; //For Handling Background of Text in Static Text
CSize bitmapSize; // For Holding The bitmap Size
步骤 4: 在 OnInitDialog()
中加载位图,并获取位图尺寸,如下例所示
BOOL CbitmapBackgroundDlg::OnInitDialog()
{
CDialog::OnInitDialog();
SetIcon(m_hIcon, TRUE);
SetIcon(m_hIcon, FALSE);
ShowWindow(SW_SHOWNORMAL);
//Load bitmap From Resource, Get bitmap Size
Background.LoadbitmapW(IDB_BACKGROUND); //Load bitmap
BITMAP bm; //Create bitmap Handle to get dimensions
Background.Getbitmap(&bm); //Load bitmap into handle
bitmapSize = CSize(bm.bmWidth, bm.bmHeight); // Get bitmap Sizes;
Invalidate(1);
//Force the dialog to repaint itself;
//End bitmap Information
return TRUE; // return TRUE unless you set the focus to a control
}
步骤 5: 添加 WM_ERASEBKGND
消息 (OnEraseBkgnd
)
步骤 6: 编辑 OnEraseBkgnd
并添加以下内容
BOOL CbitmapBackgroundDlg::OnEraseBkgnd(CDC* pDC)
{
CDC dcMemory;
dcMemory.CreateCompatibleDC(pDC);
Cbitmap* pOldbitmap = dcMemory.SelectObject(&Background);
CRect rcClient;
GetClientRect(&rcClient);
const CSize& sbitmap = bitmapSize;
pDC->BitBlt(0,0,sbitmap.cx,sbitmap.cy,&dcMemory,0,0,SRCCOPY);
dcMemory.SelectObject(pOldbitmap);
return TRUE;
//return CDialog::OnEraseBkgnd(pDC); Remove and return TRUE
}
步骤 7: 添加 OnDestroy()
并释放为位图创建的资源,如下例所示
void CbitmapBackgroundDlg::OnDestroy()
{
CDialog::OnDestroy();
Background.DeleteObject(); // Delete Background bitmap
BrushHol.DeleteObject();
// Delete Brush
}
步骤 8: 处理静态文本等控件的背景色。 这将确保使用与位图相同的背景绘制文本。 将以下内容添加到对话框创建函数中
CbitmapBackgroundDlg::CbitmapBackgroundDlg(CWnd* pParent /*=NULL*/)
: CDialog(CbitmapBackgroundDlg::IDD, pParent)
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
BrushHol.CreateStockObject(HOLLOW_BRUSH);
//Used for background painting of text. Add This Line
}
步骤 9: 添加 OnCtlColor
。 这指示 Windows 使您的背景模式透明。 以后可以使用它来更改文本和控件的颜色,如下例所示
HBRUSH CbitmapBackgroundDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
// HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
pDC->SetBkMode(TRANSPARENT);
if( pWnd->GetDlgCtrlID() == IDC_STATIC)
//Example of changing Text colour specific to a certain
//Static Text Contol in this case IDC_STATIC.
{
pDC->SetTextColor(RGB(255, 0, 0));
}
// TODO: Return a different brush if the default is not desired
return BrushHol;
}
关注点
我希望您发现这个 Windows 操作实验与我一样有趣。 您可能希望通过在 OnPaint()
函数中绘制文本来消除 OnCtlColor
。 这是我使用的方法。
历史
- 2007 年 5 月 28 日 - 发布原始版本