MFC改变背景色.docx
- 文档编号:23110822
- 上传时间:2023-04-30
- 格式:DOCX
- 页数:13
- 大小:96.57KB
MFC改变背景色.docx
《MFC改变背景色.docx》由会员分享,可在线阅读,更多相关《MFC改变背景色.docx(13页珍藏版)》请在冰豆网上搜索。
MFC改变背景色
VC++6.0更改窗口背景图的练习
2008-11-2611:
00:
18|分类:
VC++|标签:
|字号大中小订阅
程序运行结果如下
在未更改背景图前的效果
上述效果,是去掉了标题栏,在刚刚新建完工程时,其本身为一个最普通的对话框,只是加了一行代码进行了修改,以下为初始的对话框效果
保留标题栏,只更改背景图:
以下,是关键的代码:
************************************************
******
************************************************
ModifyStyle(WS_CAPTION,WS_MINIMIZEBOX,SWP_DRAWFRAME);//去掉标题栏
SetWindowText("窗口标题");//设置对话框的标题
m_bmpBackground.LoadBitmap(IDB_BITMAP1);//窗体背景图片//
voidCTestDlg:
:
OnPaint()
{
if(IsIconic())
{
CPaintDCdc(this);//devicecontextforpainting
SendMessage(WM_ICONERASEBKGND,(WPARAM)dc.GetSafeHdc(),0);
//Centericoninclientrectangle
intcxIcon=GetSystemMetrics(SM_CXICON);
intcyIcon=GetSystemMetrics(SM_CYICON);
CRectrect;
GetClientRect(&rect);
intx=(rect.Width()-cxIcon+1)/2;
inty=(rect.Height()-cyIcon+1)/2;
//Drawtheicon
dc.DrawIcon(x,y,m_hIcon);
}
else
{
//CDialog:
:
OnPaint();
//这段装载背景图
CPaintDCdc(this);//对话框的dc//CPaintDC是从CDC派生出来的。
在构造时自动调用CWnd:
:
BeginPaint,析构时调用CWnd:
:
EndPaint。
通常CPaintDC用来响应WM_PAINT消息。
一般应用在OnPaint函数
CDCdcMem;
dcMem.CreateCompatibleDC(&dc);//创建与对话框dc兼容的内存dc
CRectrect;
GetClientRect(&rect);//该函数获取窗口客户区的坐标。
BITMAPbitMap;
m_bmpBackground.GetBitmap(&bitMap);//好像是设置背景图
CBitmap*pbmpOld=dcMem.SelectObject(&m_bmpBackground);//将背景位图选入内存dc中
dc.SetStretchBltMode(HALFTONE);//这句保证放缩后不失真
dc.StretchBlt(0,0,rect.Width(),rect.Height(),&dcMem,0,0,bitMap.bmWidth,bitMap.bmHeight,SRCCOPY);//将内存dc中的位图拉伸显示在对话框的dc中
//dc.BitBlt(0,0,rect.Width(),rect.Height(),&dcMem,0,0,SRCCOPY);
}
}
第一步,定义一个CBitmap对象CBitmapm_bmpBackground;
第二步,用m_bmpBackground.LoadBitmap(IDB_BITMAP1);将资源文件中的图片载入;
第三步,
//上面是从资源文件载入,下面改成从位图文件载入
//m_bmpBackground.LoadBitmap(IDB_BITMAP1);//窗体背景图片//
LoadBmpPic("c:
\\1.bmp",m_bmpBackground);
boolCDlgVideo:
:
LoadBmpPic(constCStringstrBmpPath,CBitmap&bmp)
{
HBITMAPbitmap;
try
{
bmp.Detach();
bitmap=(HBITMAP):
:
LoadImage(NULL,strBmpPath,IMAGE_BITMAP,0,0,LR_CREATEDIBSECTION|LR_LOADFROMFILE|LR_DEFAULTSIZE);
if(bmp.Attach(bitmap))
returntrue;
}
catch(...)
{
returnfalse;
}
returntrue;
}
[转]MFC中设置窗体的背景色,图片,插入音乐
来源:
柳雨新的日志
一、设置背景颜色的三种方法:
1、我们知道程序在运行的时候会调用OnPain函数,那么我们可以在这里设置背景颜色。
voidCFlipCardsDlg:
:
OnPaint()
{
if(IsIconic())
{
//保持不变
}
else
{
CRectrc;
GetClientRect(&rc);//获取客户区
CPaintDCdc(this);
dc.FillSolidRect(&rc,RGB(0,160,0));//填充客户区颜色
CDialog:
:
OnPaint();
}
}
2、第二种方法只要一条语句,但是这里要注意这里绘制的颜色是针对程序中所有的对话框(如果是单文档的话,好像不行)
SetDialogBkColor(RGB(0,0,255),RGB(255,0,0));
//前一个RGB是背景色,后一RGB是文本颜色
该函数放在工程的APP文件的初始化函数中。
3、第三种方法,利用ClassWizard重载OnCtlColor(),即WM_CTLCOLOR消息
在要着色的对话框中申明一个变量,CBRUSHm_hbrush;然后在项目的Dlg类初始化函数中给m_hbrush赋值。
m_brush.CreateSolidBrush(RGB(0,255,0));
然后在OnCtlColor(...)返回该画刷就可以了,如下。
HBRUSHCFlipCardsDlg:
:
OnCtlColor(CDC*pDC,CWnd*pWnd,UINTnCtlColor)
{
HBRUSHhbr=CDialog:
:
OnCtlColor(pDC,pWnd,nCtlColor);
//TODO:
ChangeanyattributesoftheDChere
switch(nCtlColor)
{
caseCTLCOLOR_DLG:
HBRUSHaBrush;
aBrush=CreateSolidBrush(RGB(0,150,0));
hbr=aBrush;
break;
}
//TODO:
Returnadifferentbrushifthedefaultisnotdesired
returnhbr;
}
这样为对话框着色就可以实现了。
二、给MFC添加背景图图片代码:
定位到voidCXXXDlg:
:
OnPaint(),在if()...else()中的else()下添加如下代码:
//CDialog:
:
OnPaint();//要禁止这个调用
CPaintDCdc(this);
CRectrect;
GetClientRect(&rect);
CDCdcMem;
dcMem.CreateCompatibleDC(&dc);
CBitmapbmpBackground;
bmpBackground.LoadBitmap(IDB_BITMAP);
//IDB_BITMAP是你自己的图对应的ID
BITMAPbitmap;
bmpBackground.GetBitmap(&bitmap);
CBitmap*pbmpOld=dcMem.SelectObject(&bmpBackground);dc.StretchBlt(0,0,rect.Width(),rect.Height(),&dcMem,0,0,
bitmap.bmWidth,bitmap.bmHeight,SRCCOPY);
三、MFC中设置背景音乐问题
#include
#pragmacomment(lib,"Winmm.lib")
PlaySound函数的声明为:
BOOLPlaySound(LPCSTRpszSound,HMODULEhmod,DWORDfdwSound);
第一种方法是直接播出声音文件,相应的代码为:
PlaySound("c:
//win95//media//TheMicrosoftSound.wav",NULL,SND_FILENAME|SND_ASYNC);
注意参数中的路径使用两个连续的反斜杠转义代表一个反斜杠。
第二种方法是把声音文件加入到资源中,然后从资源中播放声音。
VisualC++支持WAVE型资源,用户在资源视图中单击鼠标右键并选择Import命令,然后在文件选择对话框中选择TheMicrosoftSound.wav文件,则该文件就会被加入到WAVE资源中。
假定声音资源的ID为IDR_STARTWIN,则下面的调用同样会输出启动声音:
PlaySound((LPCTSTR)IDR_STARTWIN,AfxGetInstanceHandle(),SND_RESOURCE|SND_ASYNC);
第三种方法是用PlaySound播放系统声音,Windows启动的声音是由SystemStart定义的系统声音,因此可以用下面的方法播放启动声音:
PlaySound("SystemStart",NULL,SND_ALIAS|SND_ASYNC);
函数sndPlaySound的功能与PlaySound类似,但少了一个参数。
函数的声明为:
BOOLsndPlaySound(LPCSTRlpszSound,UINTfuSound);
除了不能指定资源名字外,参数lpszSound与PlaySound的是一样的。
参数fuSound是如何播放声音的标志,可以是SND_ASYNC、SND_LOOP、SND_MEMORY、SND_NODEFAULT、SND_NOSTOP和SND_SYNC的组合,这些标志的含义与PlaySound的一样。
第四种方法:
sndPlaySound不能直接播放声音资源。
要用该函数播放WAVE文件,可按下面的方式调用:
sndPlaySound(“MYSOUND.WAV”,SND_ASYNC);
自己把资源添在Debug文件夹里。
先载入一张图片,ID为IDB_BITMAP2
TestDlg.h中:
CBrushm_brBk;//在public中定义
TestDlg.cpp中:
在初始化函数OnInitDialog()中加入:
BOOLCTestDlg:
:
OnInitDialog()
{
CDialog:
:
OnInitDialog();
CBitmapbmp;
bmp.LoadBitmap(IDB_BITMAP2);
m_brBk.CreatePatternBrush(&bmp);
bmp.DeleteObject();
returnTRUE;//returnTRUEunlessyousetthefocustoacontrol
}
再打开类向导,找到WM_CTLCOLOR消息,重载得对应函数OnCtlColor(),
添加如下:
HBRUSHCTestDlg:
:
OnCtlColor(CDC*pDC,CWnd*pWnd,UINTnCtlColor)
{
HBRUSHhbr=CDialog:
:
OnCtlColor(pDC,pWnd,nCtlColor);
if(pWnd==this)
{
returnm_brBk;
}
returnhbr;
}
按照上面的方法一路COPY下来运行,OK!
并且由于图片是做为背景显示的,所以再添的按钮都能很好的显示出来,非常方便。
总结一下其中出现的变量和函数。
CBrush:
类CBrush封装了Windows图形设备接口(GDI)中的画刷,画刷也就是采取什么方案填充图形的背景的工具。
OnInitDialog():
用于对对话框类的变量的初始化(注意:
是在产生对话框之前就初始化),是WM_INITDIALOG消息产生的消
息处理函数,覆盖该函数可改变对话框初始设置。
用法:
virtualBOOLOnInitDialog();返回值指定对话框是否对它的一个控件设置输入焦点。
如果OnInitDialog返回非零
值,Windows将输入焦点设在对话框的第一个控件上,只有在对话框明确将输入焦点设在某控件上,应用返回0。
CBitmap:
类CBitmap封装了Windows图形设备接口(GDI)中的位图,并且提供操纵位图的成员函数。
LoadBitmap():
CBitmap类的一个成员函数,从应用的可执行文件中加载一个命名的位图资源来初始化位图对象。
用法:
BOOLLoadBitmap(LPCTSTRlpszRecourceName);BOOLLoadBitmap(UINTnIDResource);返回值调用成功时返回非零值,
否则为0。
参数lpszResourceName指向一个包含了位图资源名字的字符串(该字符串以null结尾)。
NIDResource指定位图资源
中资源的ID号。
本函数从应用的可执行文件中加载由lpszResourceName指定名字或者由nIDResource指定的ID号标志的位图资
源。
加载的位图被附在Cbitmap对象上。
如果由lpszResourceName指定名字的对象不存在,或者没有足够的内存加载位图,函
数将返回0。
可以调用函数CgdiObject:
:
DeleteObject删除由LoadBitmap加载的位图,否则Cbitmap的析构函数将删除该位图对象。
CreatePatternBrush():
CBrush类的一个成员函数,用位图指定的模式初始化画刷。
用法:
BOOLCreatePatternBrush(CBitmap*pBitmap);返回值调用成功时返回非零值,否则为0。
参数pBitmap指定一个位图。
本
函数用位图指定的模式初始化画刷。
此画刷随后就可用于任何支持光栅操作的设备上下文。
由bBitmap指定的位图一般用以下
的函数初始化:
CBitmap:
:
CreateBitmap、CBitmap:
:
CreateBitmapIndirect、CBitmap:
:
LoadBitmap或Cbitmap:
:
CreateCompatibleBitmap。
DeleteObject():
CgdiObject类的一个成员函数,从内存中删除附加给CGdiObject的WindowsGDI对象,释放与此对象相关
的系统存储空间。
GdiObject类为各种Windows图形设备接口(GDI)对象,如位图、区域、画刷、画笔、调色板、字体等提供
了一些基本类。
我们不会直接构造一个CGdiObject对象,而是使用某一个派生类如CPen或CBrush创建。
用法:
BOOLDeleteObject();如果GDI对象被成功删除,则返回非零值,否则为0。
通过释放附加的GDI对象占有的系统存储来删除它
们。
与CGdiObject对象有关的存储不受此调用的影响。
如果CGdiObject对象正被选入设备上下文中,则应用不可对此对象调用
DeleteObject,。
当一个模式画刷被删除时,与之相关联的位图不被删除。
位图必须被独立删除。
HBRUSH:
数据类型,用于定义画刷句柄。
在Windows环境中,句柄是用来标识项目的,这些项目包括:
module,task,
instance,file,blockofmemory,menu,control,font,resource,icon,cursor,string,GDIobject等,包括
bitmap,brush,metafile,palette,pen,region以及设备描述表devicecontext。
实际上,句柄是一个标识符,用来表示
对象或者项目,是一个32位的正整数。
应用程序几乎总是通过调用一个Windows函数来获得一个句柄,之后其他的Windows函数
就可以使用这个句柄,以引用相应的对象。
WM_CTLCOLOR消息:
WM_CTLCOLOR是一个由控制(Control)发送给它父窗口的通知消息(Notificationmessage)。
利用向导映射
该消息产生函数:
HBRUSHCAboutDlg:
:
OnCtlColor(CDC*pDC,CWnd*pWnd,UINTnCtlColor);参数pDC是TestDlg的设备上下
文,pWnd是TestDlg中发送该消息的control指针,nCtlColor是Control的类型编码。
WM_CTLCOLOR是系统在绘制控件的时候自
动发送的,如果需要自定义,就截取这个消息并重载它的响应函数,用classWizard添加WM_CTLCOLOR消息然后编辑其
OnCtlColor函数。
这样Windows向应用程序发送消息WM_CTLCOLOR,应用程序处理WM_CTLCOLOR消息并返回一个用来绘画窗体背
景的刷子句柄
====================================
//放在OnPaint()里
{//设置背景图片
CRectrect;
GetClientRect(&rect);
CDC*pDC=GetDC();
CDCmemdc;
memdc.CreateCompatibleDC(pDC);
CBitmapbitmap;
//从资源中载入位图
bitmap.LoadBitmap(IDB_BITMAP1);
memdc.SelectObject(bitmap);
pDC->BitBlt(0,0,rect.Width(),rect.Height(),&memdc,0,0,SRCCOPY);
}
==========================================
对于VC++文档、视结构中的视图,从用户的角度来看,只是可以改变大小、位置的普通窗口,同其他基于Windows应用程序的窗口是一样的;从程序员的角度来看,视图并不是普通的窗口,而是从MFC库中CView类派生的类对象。
像任何VC++对象一样,视图对象的行为由类的成员函数(数据成员)决定,包括派生类中应用程序定义的函数和从基类继承来的函数。
提出问题
视图的背景一般来说是白色的,在缺省情况下,它和系统定义的颜色COLOR_WINDOW是一致的。
设计者一般会希望自己的程序可以让用户轻松地改变窗口背景颜色,或是用漂亮的图片来充填背景。
我们可以用Windows函数SetSysColors来重新指定COLOR_WINDOW所对应的实际颜色,来达到改变视图背景颜色的目的。
但这样会同时改变其他应用程序的视图窗口背景,使得整个Windows系统的颜色设置产生混乱。
另外,我们可能会用以下方法来设置视图的背景颜色,即在CView的OnDraw函数中添写如下一段程序代码:
voidCTestView:
:
OnDraw(CDC*pDC)
{
CTestDoc*pDoc=GetDocument();
ASSERT_VALID(pDoc);
CRectrectClient;
CBrushbrushBkColor;
GetClientRect(rectClient);
brushBkColor.CreateSolidBrush(RGB(255,0,0));
pDC->DPtoLP(rectClient);
pDC->FillRect(rectClient,&brushBkColor);
…
}
这样可以达到改变当前应用程序的视图背景的目的,但同时也产生了一些不良影响,使得程序运行效果不尽如人意。
分析问题
我们知道,在VC++的文档、视结构中,CView的OnDraw函数用于实现绝大部分图形绘制的工作。
如果用户改变窗口尺寸,或者显示隐藏的区域,OnDraw函数都将被调用来重画窗口。
并且,当程序文档中的数据发生改变时,一般必须通过调用视图的Invalidate(或InvalidateRect)成员函数来通知Windows所发生的改变,对Invalidate的调用也会触发对OnDraw函数的调用。
正因为OnDraw函数被频繁调用,所以在其执行时,每次都刷新填充一次视图客户区域,便会使屏幕不稳定,产生闪烁现象。
笔者通过对VC++应用程序框架结构和Windows消息映射系统的仔细研究,找到另外一种改变视图背景的方法,其执行效果比上述两种方法都好。
其实在程序调用OnDraw函数之前,会触发一个Windows消息:
WM_ERASEBKGND,以擦除视图刷新区域。
在缺省情况下,Windows系统使用视图窗口注册时窗口类中的成员hbrBackground所描述的画刷来擦除屏幕,这一般会将屏幕刷新成COLOR_WINDOW所对应的颜色。
因此,在OnDraw函数中设置背景颜色的执行过程是这样的:
先将屏幕刷新成COLOR_WINDOW所对应的颜色,接着又在OnDraw函数中填充其他颜色,这正是产生屏幕闪烁的根本原因。
解决问题
通过上述分析,我们应将视图背景颜色填充移到Windows消息:
WM_ERASEBKGND所对应的消息映射函数中,而不是在OnDraw函数中。
我们可以通过下列步骤实现这一过程:
在文档类中增加一成员变量m_viewBkColor保存当前背景颜色,同时增加两个成员函数GetViewBkColor和SetViewBkColor对其进行读写操作。
这样做的好处是可以对m_viewBkColor成员进行序列化,将其和文档联系在一起,打开某一文档时,其背景将和上一次程序操作该文档时的背景保持一致。
在视图类中为视图的Windows消息WM_ERASEBKGND增加消息映射函数OnEraseBkgnd,代码如下:
BOOLCTestView:
:
OnEraseBkgnd(CDC*pDC)
{
CRectrect;
CBrushbrush;
brush.CreateSolidBrush(GetDocument()->GetViewBkColor());
pDC->GetClipBox(rect);
pDC->FillRect(rect,&brush);
returntrue;
}
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- MFC 改变 景色