65.9K
CodeProject 正在变化。 阅读更多。
Home

对话框的位图背景

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.95/5 (15投票s)

2007年5月28日

CPOL

3分钟阅读

viewsIcon

101377

downloadIcon

7440

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

Screenshot - image002.jpg

引言

本文旨在提供一种将位图设置为对话框背景的解决方案。将位图设置为背景,您可以将控件放置在位图上,而不会被遮挡。使用资源编辑器将位图放入对话框中会强制位图位于前景,并阻碍放置其他控件。

背景

在我忙于设计和构建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 日 - 发布原始版本
© . All rights reserved.