MFC背景图片修改
改变CListCtrl、CHeaderCtrl高度、字体、颜色和背景

改变CListCtrl、CHeaderCtrl⾼度、字体、颜⾊和背景改变 CListCtrl、CHeaderCtrl ⾼度、字体、颜⾊和背景作者:摘要 ⽤CListCtrl来显⽰数据⽐较⽅便,有时候我们需要标注某⼀列或某⼀个单元格的背景和字体颜⾊,或者需要改变⼀下⾏⾼和字体⼤⼩,CListCtrl要改变这些并不是很⽅便。
本⽂将介绍如何派⽣⼀个类来改变CListCtrl及其表头的⾼度、字体⼤⼩、列背景颜⾊、单元格背景颜⾊、列字体颜⾊、单元格字体颜⾊。
关键字: ⾃绘 ⼦类化 颜⾊ CListCtrl CHeaderCtrl⼀、 实现过程1.表头修改 新建⼀个MFC类CHeaderCtrlCl,其基类为CHeaderCtrl,响应OnPaint消息实现⾃绘,实现代码请看源代码(由于代码较占篇幅,所以就不贴上来了,抱歉),在头⽂件中定义函数LRESULT OnLayout( WPARAM wParam, LPARAM lParam ),之后⼿动添加消息响应ON_MESSAGE(HDM_LAYOUT, OnLayout),在消息响应中改变⾼度,实现代码如下:LRESULT CHeaderCtrlCl::OnLayout( WPARAM wParam, LPARAM lParam ){LRESULT lResult = CHeaderCtrl::DefWindowProc(HDM_LAYOUT, 0, lParam);HD_LAYOUT &hdl = *( HD_LAYOUT * ) lParam;RECT *prc = hdl.prc;WINDOWPOS *pwpos = hdl.pwpos;int nHeight = (int)(pwpos->cy * m_Height); //改变⾼度,m_Height为倍数pwpos->cy = nHeight;prc->top = nHeight;return lResult;}2. 表的修改 新建⼀个MFC类CListCtrlCl,其基类为CListCtrl,定义⼀个CHeaderCtrlCl的成员变量m_Header,重载PreSubclassWindow(),在函数中修改控件类型为⾃绘模式,然后⼦类化表头,代码如下:void CListCtrlCl::PreSubclassWindow(){// TODO: 在此添加专⽤代码和/或调⽤基类ModifyStyle(0,LVS_OWNERDRAWFIXED);CListCtrl::PreSubclassWindow();CHeaderCtrl *pHeader = GetHeaderCtrl();m_Header.SubclassWindow(pHeader->GetSafeHwnd());}添加成员变量,保存⼀些基本信息。
MFC对话框背景---图片背景---背景色

对话框的背景1、添加位图背景首先在资源视图中添加bmp图片:选择项目名右击---添加—添加资源---Bitmap---导入---选择res文件中的位图(如果res文件中无位图请提前添加),此时可以知道位图ID为IDB_BITMAP1(1)picture控件添加背景在对话框中添加picture控件,并修改其属性,选中picture控件在属性表中修改Type为Bitmap,Image为IDB_BITMAP1。
此时图片就显示在对话框中(2)在CPP文件中初始化显示位图添加位图后,在源文件XXXDlg.cpp的void C XXX Dlg::OnPaint()函数中添加初始化代码如下:void CbeijingDlg::OnPaint(){if (IsIconic()){CPaintDC dc(this); // 用于绘制的设备上下文SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);// 使图标在工作区矩形中居中int cxIcon = GetSystemMetrics(SM_CXICON);int cyIcon = GetSystemMetrics(SM_CYICON);CRect rect;GetClientRect(&rect);int x = (rect.Width() - cxIcon + 1) / 2;int y = (rect.Height() - cyIcon + 1) / 2;// 绘制图标dc.DrawIcon(x, y, m_hIcon);}else{CPaintDC dc(this);CRect rect;GetClientRect(&rect);CDC dcMem;dcMem.CreateCompatibleDC(&dc);CBitmap bmpBackground;bmpBackground.LoadBitmap(IDB_BITMAP1);BITMAP bitmap;bmpBackground.GetBitmap(&bitmap);CBitmap *pbmpPri=dcMem.SelectObject(&bmpBackground);dc.StretchBlt(0,0,rect.Width(),rect.Height(),&dcMem,0,0,bitmap.bmWidth,bitmap.bmHeight,SRCCOPY);}}2、设置纯色背景点击对话框添加成员变量CBrush m_brush,然后在源文件XXXDlg.cpp初始化位置添加如下代码:// TODO: 在此添加额外的初始化代码?m_brush.CreateSolidBrush(RGB(0,0,255)); /////添加的代码,用于创建蓝色画刷return TRUE; // 除非将焦点设置到控件,否则返回TRUE然后找到WM_CTLCOLOR消息,添加对应的函数OnCtlColor()添加如下代码:HBRUSH CbeijingsehewenziDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor){HBRUSH hbr = CDialogEx::OnCtlColor(pDC, pWnd, nCtlColor);// TODO: 在此更改DC 的任何特return m_brush;// TODO: 如果默认的不是所需画笔,则返回另个画笔// return hbr;}这样运行后对话框背景色就变为蓝色。
MFC中改变对话框背景的几个消息函数OnEraseBkgnd、 OnPaint、 OnCtlColor的调用顺序

MFC中改变对话框背景的几个消息函数OnEraseBkgnd、OnPaint、OnCtlColor的调用顺序设置对话框背景颜色及背景图片可在OnCtlColor(),OnEraseBkgnd(),OnPaint()里设置,对话框初始化完毕,显示时调用OnSize()->OnEraseBkgnd(),->OnPaint()->OnCtlColor(), 若想改变对话框大小,比如全屏显示ShowWindow(SW_SHOWMAXIMIZED);UpdateWindow();其中ShowWindow会调用OnSize()->OnEraseBkgnd(),UpdateWindow();调用OnPaint()->OnCtlColor(),若对话框中没有设置消息响应OnEraseBkgnd(),,则系统默认消息响应OnEraseBkgnd()会调用OnCtlColor()设置对话框背景(即替代OnEraseBkgnd())对话框的背景设置可在OnCtlColor()中进行,因为OnCtlColor()一般会被多次调用,所以要想设置的CFont,CBrush等应在OnInitDialog中初始化,若要在OnCtlColor()中设置,在设置前先调用Detach就可以了,如下示例HBRUSH CDb3Dlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor){if(pWnd->GetDlgCtrlID()==IDC_STATIC5){m_font.CreatePointFont(300,"宋体");pDC->SelectObject(&m_font);m_font.Detach();pDC->SetBkMode(TRANSPARENT);return (HBRUSH)::GetStockObject(NULL_BRUSH);}}但是如果在OnCtlColor()在设置背景图片,则图片不会随对话框大小按比例缩放所以可调用StretchBlt()函数设置,如下示例:void CDb3Dlg::OnPaint(){CClientDC cdc(this); CDC comdc;comdc.CreateCompatibleDC(&cdc);CBitmap bitmap;bitmap.LoadBitmap(IDB_BITMAP2);comdc.SelectObject(&bitmap);CRect rect;GetClientRect(rect);BITMAP bit;bitmap.GetBitmap(&bit);cdc.StretchBlt(0,0,rect.Width(),rect.Height(),&comdc,0,0,bit.bmWidth,bit.bmHeight,SRCCOPY);}//全屏显示对话框背景图片(限bmp格式)用了两年的VC,其实对OnPaint的工作原理一直都是一知半解。
MFC 对话框 背景图片 以及消除 字体重影 字体重叠

很多人都想改变对话框的背景图,其实很简单,只需要一个函数就可以了,不过还是有问题的,下面讲述。
只需要响应WM_ERASEBKGND消息,然后重载OnEraseBkgnd(CDC*pDC)这个函数就可以,首先我们要添加消息响应,由于该消息不能用MFC ClassWizard添加,因为ClassWizard 没有该消息添加的选项,我们需要手动添加,只需要在消息响应MAP添加一下ON_WM_ERASEBKGND(),如下所示:BEGIN_MESSAGE_MAP(CSerialTestDlg, CDialog)//{{AFX_MSG_MAP(CSerialTestDlg)ON_WM_ERASEBKGND()//添加重绘背景消息响应//}}AFX_MSG_MAPEND_MESSAGE_MAP()我们然后进行消息响应,添加消息响应函数,然后在对话框类的声明文件添加该函数的声明virtual BOOL OnEraseBkgnd(CDC*pDC);在实现文件中进行该函数的书写,如:BOOL CSerialTestDlg::OnEraseBkgnd(CDC*pDC){CBitmap m_bitmap;m_bitmap.LoadBitmap(IDB_DLGBK);//加载背景图片,选择你对应的图片IDCDC dcCompatible;dcCompatible.CreateCompatibleDC(pDC);dcCompatible.SelectObject(&m_bitmap);CRect rect;GetWindowRect(&rect);ScreenToClient(&rect);//选择客户区域BITMAP bmp;m_bitmap.GetBitmap(&bmp);pDC->StretchBlt(0,0,rect.Width(),rect.Height(),&dcCompatible,0,0,bmp.bmW idth,bmp.bmHeight,SRCCOPY);//绘制BMP背景图m_bitmap.DeleteObject();return TRUE;}但是这样做一般就可以,细心的人会发现字体有重叠,比如说静态文本框和EDIT控件,如果选择只读模式,作为输出,这时EDIT的背景是BMP背景图片,但是字体重叠,如下图,我这样就行消除。
MFC界面美化

SDI和MDI程序中对非客户区(标题栏、左右下边界)的美化基本思路是重载CMainFrame类的DefWindowProc()函数,并判断消息为:WM_NCPAINT,WM_NCACTIV ATE,WM_NOTIFY的时候,调用自己的绘制窗口标题栏的函数。
用GetSystemMetrics(SM_CSFRAME)和GetSystemMetrics(SM_CYFRAME)可以取得标题栏的左上角的坐标。
最大化,最小化的按钮自己画,如果不是在标准的位置,一定要记录下他们的位置,并且在WM_NCLBUTTONDOWN消息处理函数中判断是否是点击了按钮,以做出相应的处理。
系统图标也可以自己重新画。
主要任务有贴图(包括标题栏、左边界、右边界、下边界、系统图标、最大化、最小化、关闭按钮)、处理消息(屏蔽系统自带按钮、双击状态栏改变大小、鼠标停放在三个自绘按钮上时改变按钮图标、单击自绘按钮时作出相应反应)。
一、响应的消息及重载的函数响应的消息及重载的函数都在CMainFrame类中。
响应DefWindowProc函数,在其中判断消息是不是WM_NCPAINT、WM_MOVE、WM_NCACTIV ATE、WM_NOTIFY,若是则重画标题栏、左框架、右框架、下框架、最大化、最小化、关闭按钮(放在一个函数里)。
响应消息WM_NCHITTEST,使鼠标位于自绘按钮时返回相应hittest值,同时屏蔽自带按钮的鼠标事件。
简言之,当鼠标位于自绘按钮时,让系统误以为鼠标位于相应按钮,而当鼠标位于系统自带按钮时,让系统误以为鼠标只是位于标题栏。
自绘图标与之类似,不再赘述。
响应消息WM_NCMOUSEMOVE,判断光标是不是位于自绘最大化、最小化、关闭按钮区域,如是则重画相应的按钮。
响应消息WM_NCLBUTTONDOWN,判断单击左键时鼠标是否位于自绘制的最大化、最小化、关闭按钮或图标区域,如是则执行相应的按钮操作。
响应消息WM_NCLBUTTONDBCLK,使双击标题栏时窗口能最大化或还原。
MFC使用Skin++美化皮肤

MFC使⽤Skin++美化⽪肤查了好⼏天关于MFC应⽤程序换肤的资料,经过各种莫名其妙的问题的困扰,现分享⼀下⾃⼰的体会。
希望可以避免⼀些弯路。
另外会在附上⼀些资源。
环境:Windows 7 + VS2012 + SkinSharp(注:Skin++、USkin、SkinMagic ⽤法相同)1. 新建⼀个⼯程(⼯程名:Demo)(⽐如⼀个基于对话框的MFC程序)如图所⽰,注意不要勾选Use Unicode libraries ,否则可能会出现以下错误:见图2. 添加相关⽂件(.h .lib .dll 以及⽪肤⽂件)下⾯就以SkinSharp、Skin++、USkin、SkinMagic中的⼀种(SkinSharp)进⾏⽰范,其他三种的操作基本是⼤同⼩异。
如图将SkinH.h和SkinH.lib⽂件导⼊⼯程⽂件的⽬录中,如下图所⽰:请注意VC++6.0和VS2012下⼯程⽬录的不同之处,应该是Demo->Demo⽂件夹下(Demo是⼯程名),然后加⼊⼯程的Header Files下:3. 添加必要的代码3.1 在stdafx.h中添加#include "SkinH.h"#pragma comment(lib, "SkinH.lib")如图:在BOOL CDemoApp::InitInstance() 函数下写SkinH_Attach();这句语句是加载默认的⽪肤⽂件:skinh.she3.3 试着编译⼯程,产⽣Debug⽂件(或者Release⽂件)将以下⽂件放⼊Debug⽬录(⼯程根⽬录下的Debug⽂件夹)中如图:3.4 再次编译⼯程即可看到换肤的效果:(添加的是只是skinh.she⽪肤⽂件)3.5 实现更“⾃由”的换肤将SkinH_Attach(); 改为下句SkinH_AttachEx("../Debug/Skins/Green.she", NULL);运⾏效果如下:3.6 如果出现缺少SkinH.dll,就将该⽂件再放到C:\Windows\System32和C:\Windows\SysWOW64⽂件夹下,然后重新编译运⾏就可以了。
位图按钮-更换皮肤

位图按钮——给按钮换肤用MFC基本控件添加的按钮,总是显得比较枯燥。
为了让平实的按钮表现出更加丰富的效果,我们可以使用CBitmapButton类给按钮添加位图,让按钮换上穿上新装,显示出它华丽的一面。
下面就简单介绍一下实现的步骤。
1.新建MFC应用程序工程,应用程序类型选择基于对话框。
2.我们现在转到资源面板,双击对话框,打开对话框编辑器,给对话框添加一个按钮控件,设置资源ID(假定设置的ID为IDBMBUTTON),在风格页中勾上Owner draw。
3.现在添加准备好的位图资源,设置资源ID。
每个按钮最多可以包含四张图片,分别代表正常、按下、获得焦点和禁用四种状态,其中第一张图片是必须的。
在这里假定它们的ID为BUTTONU,BUTTOND,BUTTONF,BUTTONX,最后一个字母用来代表四种不同的状态。
4.接下来就可以在CXXXDlg类中添加CBitmapButton类型变量了,这里假定名称为m_button。
5.在有了CBitmapButton类型对象后,接下来就在CXXXDlg类的构造函数中为它载入位图,使用的代码如下:if(!m_button.LoadBitmaps(BUTTONU, BUTTOND, BUTTONF, BUTTONX)){TRACE0("Failed to load bitmaps for button\n");AfxThrowResourceException();}6.最后一部就是让CBitmapButton类对象的窗口过程替换掉默认按钮控件的窗口过程(也就是WINDOWS意义上的派生子类),听起来很复杂,其实也蛮简单,只需要在CXXXDlg类的OnInitDialog()函数中添加如下的语句就可以完成:VERIFY(m_button.SubclassDlgItem(IDBMBUTTON, this));m_button.SizeToContent();好了,到这里所有的工作就完成了,编译运行一下看看效果如何。
MFC 小技巧(更换皮肤,背景,标题栏,透明)

1.背景透明在MainFrame.Cpp中找到int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)函数添加代码SetWindowLong(this->GetSafeHwnd(), GWL_EXSTYLE, GetWindowLong(this->GetSafeHwnd(), GWL_EXSTYLE)^0x80000);// 添加库HINSTANCE hInst = LoadLibrary("User32.DLL");if(hInst){typedef BOOL (WINAPI *ShowLayer)(HWND,COLORREF,BYTE,DWORD);ShowLayer fun = NULL;// 读取函数指针fun = (ShowLayer)GetProcAddress(hInst, "SetLayeredWindowAttributes");if (fun)fun(this->GetSafeHwnd(), 0, 230, 2);FreeLibrary(hInst);}HBITMAP startpic;CStaticstartPics;startpic=(HBITMAP) ::LoadImage(NULL,"snakeNet.bmp",IMAGE_BITMAP,110,50,LR_LOADFROMF ILE|LR_DEFAULTSIZE);startPics.Create(NULL,WS_CHILD|WS_VISIBLE|SS_BITMAP|SS_CENTERIMAGE,CRect(200,457,20 0+110,457+50),this,NULL);startPics.SetBitmap(startpic);GetSafeHwnd(), 0, 230, 2);里面的参数230是改变透明度对话框的函数好像不一样2.更换背景图片首先先找一张图片将其格式转换成.Bmp格式然后在VC中ctrl+R 新建一个bitmap资源然后在资源栏中右击选择引入然后选择你的那张BMP格式图片出现这个不用理然后在View类中添加CBrush类型的m_brushBackground变量然后在View的构造函数中添加代码CBitmap bmp;bmp.LoadBitmap(IDB_BITMAP2); ///加载位图m_brushBackground.CreatePatternBrush(&bmp); ///创建位图画刷其中IDB_BITMAP2是你图片的ID号然后在OnDraw(CDC* pDC)函数中添加代码CRectrect;GetClientRect(rect);///取得客户区域pDC->FillRect(rect,&m_brushBackground); ///用背景画刷填充区域然后调试就发现背景好看多了3.标题栏标题栏图标找一个IOC格式的图片直接把名字改成工程文件夹中rs文件夹中的ico格式图片的名字直接替换就行了标题栏名字在App。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
MFC添加背景图片方法
此文系转载,忘了博客地址了
VC++中如何给对话框加背景图片(2010-03-22 16:57:59)
方法一:
1、声明成员变量CBrush m_brush;
2、在InitDialog中添加代码:
CBitmap bmp;
bmp.LoadBitmap(IDB_BITMAP1); //IDB_BITMAP1是图片资源ID
m_brush.CreatePatternBrush(&bmp);
3、重载对话框的OnCtlColor,改最后的返回值:
1 return (HBRUSH)m_brush; 方法二:
把下面这段代码加进OnPaint()里就行了
CPaintDC dc(this);
CBitmap bitmap;
bitmap.LoadBitmap(IDB_BITMAP1); //这个IDB_BITMAP1要自己添加
CBrush brush;
brush.CreatePatternBrush(&bitmap);
CBrush* pOldBrush = dc.SelectObject(&brush);
dc.Rectangle(0,0,200,200); // 这些参数可以调整图片添加位置和大小
dc.SelectObject(pOldBrush);
方法三:使用StretchBlt()函数,具有图像自适应窗体功能
CPaintDC dc(this);
CBitmap bitmap;
bitmap.LoadBitmap(IDB_BITMAP1); //这个IDB_BITMAP1要自己添加 CBrush brush;
brush.CreatePatternBrush(&bitmap);
CBrush* pOldBrush = dc.SelectObject(&brush);
dc.Rectangle(0,0,200,200); // 这些参数可以调整图片添加位置和大小 dc.SelectObject(pOldBrush);。