OnctlColor没有调用

OnctlColor没有调用,第1张

我亲自试了两种工程,一种是基于对话框的应用程序,另一种是基于单文档的应用程序。如果是基于对话框的应用程序的话只要添加了OnCtlColor函数,运行时就会进入到该函数中,不会出现你说的情况。所以我断定你的是基于单文档的应用程序,现在你添加了一个对话框资源,也在里面加了几个控件。WM_CTLCOLOR消息是在系统绘制对话框时发出的,要绘制对话框你首先得编写代码将对话框显示出来,问题就在这,因为你没有编写将对话框显示的代码,或者你没有执行显示对话框 *** 作的代码。如果不显示对话框怎么会有WM_CTLCOLOR消息产生呢,进而之怎么会调用OnCtlColor函数呢。
显示对话框的代码相信不用我告诉你吧。

不要用控件加背景图!可以直接加的!像下面这样做,我就是这样做的,没问题!
先载入一张,如ID为IDB_BITMAP
头文件中:
CBrush m_brBk;//在public中定义
源文件中:
在初始化函数OnInitDialog()中加入: (或者在构造函数中)
BOOL CTestDlg::OnInitDialog()
{
CDialog::OnInitDialog();
CBitmap bmp;
bmpLoadBitmap(IDB_BITMAP);
m_brBkCreatePatternBrush(&bmp);
bmpDeleteObject();
return TRUE; // return TRUE unless you set the focus to a control
}
再打开类向导,找到WM_CTLCOLOR消息,重载得对应函数OnCtlColor(),
添加如下:
HBRUSH CTestDlg::OnCtlColor(CDC pDC, CWnd pWnd, UINT nCtlColor)
{
HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
if (pWnd == this)
{
return m_brBk;
}
return hbr;
}

Visual C++ 是 Microsoft 至今最全面和最完善的程序开放产品之一,它提供了一组各种各样的为适应几乎每一种编程风格而设计的工具,在编程能力和方便性方面达到了空前的水平。
应用程序的界面设计占用了整个程序设计的很大一部分工作量,一个应用程序是否成功 , 界面的好坏有很大的影响,因此,现代的软件设计特别强调界面设计,并且也做得很好,使用户使用起来很容易,对话框就是 Windows 提供的界面元素的一个,它用来进行信息输入,也可用来把程序的结果或中间结果告诉用户。实际上,它是应用程序中使用最多的一种交互方式。
screenwidth-333)thiswidth=screenwidth-333">
在 Visual C++ 中,对话框的背景通常是灰色的,文字是黑色的(这也是默认值),见下图。

screenwidth-333)thiswidth=screenwidth-333">但用户可以通过使用位图可以很容易地改变对话框的背景,这里,笔者编写了一个 CBmpDialog 类,将位图引入到对话框的背景之中,改善了对话框的视觉效果。添加了位图背景的对话框效果如以下两图所示。
screenwidth-333)thiswidth=screenwidth-333">
CBmpDialog 类的创建过程如下,首先在资源中设计一个对话框,然后创建一个管理该对话框的类,即 CBmpDialog ,基类为 CDialog ,通过类向导为其添加消息处理函数 OnCtlColor ( )和 OnEraseBkgnd ( ) ,并在其头文件 BmpDialogh 中添加以下内容:
# define BITMAP_TILE 0
# define BITMAP_CENTER 1
class CBmpDialog : public CDialog
{
public:
void SetBitmap (UINT ResID,int Type=BITMAP_TILE); // 该函
数装入位图并决定如何显示,缺省放置方式为平铺
private:
int mType; // 定义位图放置方式变量
CBrush mHollowBrush; // 定义一个画笔类
CBitmap mBitmap; // 定义一个位图类
};
接下来在源程序 BmpDialogcpp 加入下列代码:
1 、构造函数 CBmpDialog::CBmpDialog ( ) ,该函数构造了一个 CbmpDialog 对象,并生成一个空画笔,以便被类引用。
CBmpDialog::CBmpDialog (CWnd pParent /=NULL/)
: CDialog (CBmpDialog::IDD, pParent)
{
mHollowBrush CreateStockObject (HOLLOW_BRUSH);
}
2 、 CBmpDialog::OnCtlColor ( ) 函数,当对话框准备显示一个控件时,调用此函数,它返回一个 HBRUSH ,用于绘制控件背景,对于静态控件返回一个空画笔,位图将出现在控件的后面;对于其它控件,则采用 OnCtlColor ( ) 的默认值,并允许控件以普通方式绘制,此时,位图不会出现在控件的后面。
HBRUSH CBmpDialog::OnCtlColor (CDC pDC, CWnd pWnd,
UINT nCtlColor)
{
if (mBitmapGetSafeHandle ( ) !=NULL) // 返回的位图句柄非空时
{
switch (nCtlColor)
{
case CTLCOLOR_STATIC: // 为静态控件时,返回空画笔
pDC->SetBkMode (TRANSPARENT);
return (HBRUSH) mHollowBrushm_hObject;
break;
default: // 对其它控件,采用缺省值
HBRUSH hbr = CDialog::OnCtlColor (pDC,
pWnd, nCtlColor);
return hbr ;
break;
}
}
else // 无位图背景时
{
HBRUSH hbr = CDialog::OnCtlColor (pDC, pWnd, nCtlColor);
return hbr;
}
}
3 、 CBmpDialog::OnEraseBkgnd ( ) 函数,当对话框需要重绘时,框架将调用此函数, OnEraseBkgnd ( ) 显示位图的方式有两种:如果位图居中放置,就先调用基类的 OnEraseBkgnd ( ) ,重新绘制整个背景,然后把位图显示在对话框的中心位置;如果想以铺瓦的方式排列位图,就以对话框的左上角为起点进行排列,直到填满整个对话框。
BOOL CBmpDialog::OnEraseBkgnd (CDC pDC)
{
if (mBitmapm_hObject!=NULL) // 对象句柄非空
{
CDC MemDC;
BITMAP bm;
CRect Rect;
int x=0, y=0;
GetClientRect (&Rect); // 获取客户区大小
mBitmapGetObject (sizeof (BITMAP),&bm); // 用位图上的信息 填充 BITMAP 结构的各个域
MemDCCreateCompatibleDC (pDC); // 初始化内存描述对象
CBitmappOldBitmap=MemDCSelectObject (&mBitmap); // 定 义一个 CBITMAP 类,并初始化为选入到设备描述对象的位图
if (mType==BITMAP_CENTER) // 位图置背景的中心
{
CDialog::OnEraseBkgnd(pDC); // 先重绘整个背景
x= (RectWidth()-bmbmWidth) /2; // 位图左上角横坐标
y= (RectHeight()-bmbmHeight) /2; // 位图左上角纵坐标
pDC->BitBlt
(x, // 目标位图横坐标
y, // 目标位图纵坐标
bmbmWidth, // 要转换的块高度
bmbmHeight, // 要转换的块宽度
&MemDC, // 图形数据的源设备对象
0, // 源位图横坐标
0, // 源位图纵坐标
SRCCOPY); // 转换类型代码, SRCCOPY 表示数据不经修改直接拷贝
}
else // 位图平铺放置
{ // 从左上角开始依次排列位图
while (y<RectHeight ( ) )
{
while (x<RectWidth ( ) )
{
pDC->BitBlt (x,y,bmbmWidth,bmbmHeight,
&MemDC,0,0,SRCCOPY );
x=x+bmbmWidth;
}
x=0;
y=y+bmbmHeight;
}
}
MemDCSelectObject ( pOldBitmap ); // 将位图对象选入
内存 设备描述对象
return TRUE;
}
else // 无位图时产生普通对话框
return CDialog::OnEraseBkgnd (pDC);
}
4 、 CBmpDialog::SetBitmap( ) 函数,通过调用此函数,装入将在对话框中显示的位图,如果函数没有调用,或者位图不存在,就会产生普通的对话框。
void CBmpDialog::SetBitmap (UINT ResID, int Type)
{
mBitmapLoadBitmap (ResID); // 装入位图对象
mType=Type; // 位图放置方式
}
使用该类时,首先必需将位图资源加入到项目中,为其赋予一个资源号,然后声明一个 CBmpDialog 对象,接着调用 SetBitmap ( ) 函数对其进行初始化。如下述语句:
CBmpDialog dlg2;
dlg2SetBitmap(IDB_CLOUDS,BITMAP_CENTER);
dlg2DoModal();
即可产生一个位图居于背景正中的对话框。

---- 其中函数的第一个参数指定了背景颜色,第二个参数指定了文本颜色。下面的例子是将应用程序对话框设置为蓝色背景和红色文本,步骤如下: ---- ① 新建一个基于Dialog的MFC AppWizard应用程序ExampleDlg。 ---- ②在CExampleDlgApp ::InitInstance()中添加如下代码: BOOL CExampleDlgApp: : InitInstance ( ) { … CExampleDlgDlg dlg; m_pMainWnd = &dlg; //先于DoModal()调用,将对话框设置为蓝色背景、红色文本 SetDialogBkColor(RGB(0,0,255),RGB(255,0,0)); //第一个为背景 第二个为字体 int nResponse = dlgDoModal(); … } ---- 编译并运行,此时对话框的背景色和文本色已发生了改变。值得注意的是:在调用DoModal()之前必须先调用SetDialogBkColor,且此方法是将改变应用程序中所有的对话框颜色,并不能针对某一个指定的对话框。 ---- 方法二:重载OnPaint(),即WM_PAINT消息。有关代码如下(以上例工程为准): void CExampleDlgDlg::OnPaint() { if (IsIconic()) … else { CRect rect; CPaintDC dc(this); GetClientRect(rect); dcFillSolidRect(rect,RGB(0,255,0)); //设置为绿色背景 CDialog::OnPaint(); } ---- 方法三:重载OnCtlColor (CDC pDC, CWnd pWnd, UINT nCtlColor),即WM_CTLCOLOR消息。具体步骤如下(以上例工程为准): ---- ①在CExampleDlgDlg的头文件中,添加一CBrush的成员变量: class CExampleDlgDlg : public CDialog { protected: CBrush m_brush; }; ---- ②在OnInitDialog()函数中添加如下代码: BOOL CExampleDlgDlg::OnInitDialog() { // TODO: Add extra initialization here m_brushCreateSolidBrush(RGB(0, 255, 0)); // 生成一绿色刷子 } ---- ③利用ClassWizard重载OnCtlColor(…),即WM_CTLCOLOR消息: HBRUSH CExampleDlgDlg::OnCtlColor (CDC pDC, CWnd pWnd, UINT nCtlColor) { / 这里不必编写任何代码! 下行代码要注释掉 HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor); / return m_brush; //返加绿色刷子 } ---- 方法四:还是重载OnCtlColor (CDC pDC, CWnd pWnd, UINT nCtlColor),即WM_CTLCOLOR消息。具体步骤如下(以上例工程为准): ---- 步骤①、②同上方法三中的步骤①、②。


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/12757809.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-27
下一篇 2023-05-27

发表评论

登录后才能评论

评论列表(0条)

保存