给对话框加上背景皮肤
对话框的skin
前段时间有些学生问我,怎么给我们做的对话框加上漂亮的skin,特别是就像qq游戏的登录以及游戏界面一样(qq游戏的登录界面就是一个对话框)。
经过一些曲折,我在www.codeproject.com中找到了一些给对话框及控件加skin的方式,在下面我通过一个例子给出了其中一种最简单的方法,通过这种方式作出的对话框会根据skin图片的大小调整。
在我的例子中,我用了首先做了一个简单的基于对话框的程序。然后给我们的工程插入一个图片资源。给这个bitmap资源一个资源ID号IDB_MAIN。为对话框类加入以下的数据成员和成员函数。
CSkinDlg : public CDialog
{
public:
CSkinDlg();
HBITMAP m_hBmp;
HRGN m_hWndRgn;
HRGN DIBToRgn(HBITMAP hBmp,COLORREF BkColor,BOOL Direct); // Handle the Skin
//…
};
在构造函数中加入以下代码:
CSkinDlg::CSkintDlg(CWnd* pParent /*=NULL*/)
: CDialog(CSkinDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CSkinDlg)
//}}AFX_DATA_INIT
m_hBmp=(HBITMAP)LoadImage(AfxGetApp()->m_hInstance,
MAKEINTRESOURCE(IDB_MAIN),
IMAGE_BITMAP,0,0,LR_CREATEDIBSECTION);
m_hWndRgn=DIBToRgn(m_hBmp,0x00ff00,FALSE);
}
在你的对话框类中插入函数HRGN DIBToRgn(HBITMAP hBmp, COLORREF BkColor, BOOL Direct)
,
并加入以下的代码:
HRGN CSkinDlg ::DIBToRgn(HBITMAP hBmp, COLORREF BkColor, BOOL Direct)
{
// use to return the handle of the HGRN
HRGN hRgn = NULL;
#define MAX_ALLOC_RECTS 100
//the difference of the color
COLORREF Tolerance=0x00101010;
if (hBmp)
{
//creat the dib to save the dc
HDC hMemDC = CreateCompatibleDC(NULL);
if (hMemDC)
{
BITMAP bm;
//get the info of the bitmap
GetObject(hBmp, sizeof(bm), &bm);
BITMAPINFOHEADER BmpInfoh = { // the struct of the bitmap
sizeof(BITMAPINFOHEADER), // biSize
bm.bmWidth, // biWidth;
bm.bmHeight, // biHeight;
1, // biPlanes;
32, // biBitCount
BI_RGB, // biCompression;
0, // biSizeImage;
0, // biXPelsPerMeter;
0, // biYPelsPerMeter;
0, // biClrUsed;
0 // biClrImportant;
};
//design a void point to point to the bitmap
LPVOID pBit32;
//creat a DIB
HBITMAP hDib32 = CreateDIBSection(hMemDC,
(BITMAPINFO *)&BmpInfoh,
DIB_RGB_COLORS, &pBit32, NULL, 0);
if (hDib32)
{
//copy dib to DC
HBITMAP hOldib32 = (IBITMAP)SelectObject(hMemDC, hDib32);
// create a DC to save orgin bitmap
HDC hDC = CreateCompatibleDC(hMemDC);
if (hDC)
{
BITMAP bm32;
// get the new 34 bit Dib size
GetObject(hDib32, sizeof(bm32), &bm32);
//make sure the 32Dib's every line pilex's is 4 's times
while (bm32.bmWidthBytes % 4)
bm32.bmWidthBytes++;
//copy the orginal dib to DC
HBITMAP holdBmp = (HBITMAP)SelectObject(hDC, hBmp);
//copy dib to memory DC
BitBlt(hMemDC, 0, 0, bm.bmWidth, bm.bmHeight, hDC, 0, 0, SRCCOPY);
DWORD MaxRects = MAX_ALLOC_RECTS;
SYSTEM_INFO Sysinfo;
//get memory size
GetSystemInfo(&Sysinfo);
//make a stack which can chang big
//alloct memory
HANDLE hRcData=HeapCreate(HEAP_GENERATE_EXCEPTIONS,Sysinfo.dwPageSize, 0);
RGNDATA * pRcData=(RGNDATA*)HeapAlloc(hRcData,HEAP_ZERO_MEMORY,
sizeof(RGNDATAHEADER)+sizeof(RECT)*MaxRects);
//fill the the RGNDATA struck
pRcData->rdh.dwSize = sizeof(RGNDATAHEADER);
pRcData->rdh.iType = RDH_RECTANGLES;
pRcData->rdh.nCount = pRcData->rdh.nRgnSize = 0;
SetRect(&pRcData->rdh.rcBound, MAXLONG, MAXLONG, 0, 0);
BYTE hr,hg,hb,lr,lg,lb;
switch(BkColor)
{
case RGB(255,255,255): //if the bkcolor is white
hr = GetRValue(BkColor);
hg = GetGValue(BkColor);
hb = GetBValue(BkColor);
lr = min(0xff, hr - GetRValue(Tolerance));
lg = min(0xff, hg - GetGValue(Tolerance));
lb = min(0xff, hb - GetBValue(Tolerance));
break;
case RGB(0,0,0): //if the bkcolor is black
lr = GetRValue(BkColor);
lg = GetGValue(BkColor);
lb = GetBValue(BkColor);
hr = min(0xff, lr + GetRValue(Tolerance));
hg = min(0xff, lg + GetGValue(Tolerance));
hb = min(0xff, lb + GetBValue(Tolerance));
break;
default: //if the bkcolor is other color
Tolerance=0x111111;
lr =max(0, GetRValue(BkColor)-GetRValue(Tolerance));
lg = max(0,GetGValue(BkColor)-GetGValue(Tolerance));
lb = max(0,GetBValue(BkColor)-GetBValue(Tolerance));
hr=min(0xff,GetRValue(BkColor)+GetRValue(Tolerance));
hg=min(0xff,GetGValue(BkColor)+GetGValue(Tolerance));
hb=min(0xff,GetBValue(BkColor)+GetBValue(Tolerance));
break;
}
// Get the bit point and do the search
BYTE *pBits = (BYTE *)bm32.bmBits +
(bm32.bmHeight - 1) * bm32.bmWidthBytes;
for (int y = 0; y < bm.bmHeight; y++)
{
for (int x = 0; x < bm.bmWidth; x++)
{
int x0 = x;
DWORD *pColor = (DWORD *)pBits + x;
BYTE dr,dg,db;
while (x < bm.bmWidth)
{
dr=GetRValue(*pColor);
dg=GetGValue(*pColor);
db=GetBValue(*pColor);
if ((dr>= lr && dr<= hr) && (dg>=lg&&dg<=hg)
&& (db>=lb&&db<=hb))
{
if(Direct)
break;
else
{
pColor++;
x++;
}
}
else if(Direct)
{
pColor++;
x++;
}
else
break;
}
if (x > x0)
{
if (pRcData->rdh.nCount >= MaxRects)
{
MaxRects += MAX_ALLOC_RECTS;
//re alloc the stack
pRcData=(RGNDATA*)HeapReAlloc(
hRcData,HEAP_ZERO_MEMORY,pRcData,
sizeof(RGNDATAHEADER)+sizeof(RECT)*MaxRects);
}
RECT *pr = (RECT *)&pRcData->Buffer;
SetRect(&pr[pRcData->rdh.nCount], x0, y, x, y+1);
pRcData->rdh.rcBound.left = x0;
pRcData->rdh.rcBound.top = y;
pRcData->rdh.rcBound.right = x;
pRcData->rdh.rcBound.bottom = y+1;
pRcData->rdh.nCount++;
if (pRcData->rdh.nCount == 3000)
{
HRGN tmphRgn = ExtCreateRegion(NULL,
sizeof(RGNDATAHEADER) + (sizeof(RECT) * MaxRects),
pRcData);
if (hRgn)
{
CombineRgn(hRgn, hRgn, tmphRgn, RGN_OR);
DeleteObject(tmphRgn);
}
else
hRgn = tmphRgn;
pRcData->rdh.nCount = 0;
SetRect(&pRcData->rdh.rcBound,
MAXLONG, MAXLONG, 0, 0);
}
}
}
// search next line
pBits -= bm32.bmWidthBytes;
}
HRGN tmphRgn = ExtCreateRegion(NULL,
sizeof(RGNDATAHEADER) + (sizeof(RECT) * MaxRects), pRcData);
if (hRgn)
{
CombineRgn(hRgn, hRgn, tmphRgn, RGN_OR);
DeleteObject(tmphRgn);
}
else
hRgn = tmphRgn;
// make a rect ,use this rect xor to the BkColor
//then we can get the rect we want
if(!Direct)
{
HRGN hRect=CreateRectRgn(0,0,bm.bmWidth,bm.bmHeight);
if(hRect)
{
CombineRgn(hRgn,hRgn,hRect,RGN_XOR);
DeleteObject(hRect);
}
else
return NULL;
}
//release the memory
HeapFree(hRcData,HEAP_NO_SERIALIZE,pRcData);
SelectObject(hDC, holdBmp);
DeleteDC(hDC);
DeleteObject(holdBmp);
}
SelectObject(hMemDC,hOldib32);
DeleteDC(hMemDC);
DeleteObject(hOldib32);
DeleteObject(hDib32);
}
else
DeleteDC(hMemDC);
}
}
return hRgn;
}
加入一个ON_WM_ERASEBKND消息,在这里面删除对话框的背景:
BOOL CSkinDlg::OnEraseBkgnd(CDC* pDC)
{
if(m_hBmp)
{
BITMAP bm;
GetObject(m_hBmp,sizeof(bm),&bm);
HDC hMemdc=CreateCompatibleDC(pDC->m_hDC);
if(hMemdc)
{
HBITMAP hOldBmp=(HBITMAP)SelectObject(hMemdc,m_hBmp);
if(hOldBmp)
{
BitBlt(pDC->m_hDC,0,0,bm.bmWidth,bm.bmHeight,hMemdc,0,0,SRCCOPY);
SelectObject(hMemdc,hOldBmp);
DeleteDC(hMemdc);
DeleteObject(hOldBmp);
return TRUE;
}
else
DeleteDC(hMemdc);
}
}
return CDialog::OnEraseBkgnd(pDC);
}
最后在OnInitDialog
中写入以下代码
BOOL CSkinDlg::OnInitDialog()
{
//…
// Show the Skin
if(m_hWndRgn)
SetWindowRgn(m_hWndRgn,TRUE);
return TRUE; // return TRUE unless you set the focus to a control
}
这就是所有的过程,通过这个过程以后,我们的对话框的背景变为了我们引入的bitmap图片。
Tuesday, September 20, 2005
给对话框加上背景皮肤相关推荐
- VS2010 MFC中控件、对话框等背景颜色动态修改的方法
通过类向导,或者手动添加消息:WM_CTLCOLOR,其消息响应函数为: afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) ...
- 【VS开发】VS2010 MFC中控件、对话框等背景颜色动态修改的方法
[VS开发]VS2010 MFC中控件.对话框等背景颜色动态修改的方法 标签(空格分隔):[VS开发] 声明:引用请注明出处http://blog.csdn.net/lg1259156776/ 说明: ...
- 怎样给Tab Control控件加上背景颜色或图片
如果不懂Tab控件添加选项卡(属性页)的请看这篇文章:http://blog.csdn.net/qq_18297675/article/details/50991413 这里我就直接在添加好选项卡的基 ...
- 做了一个开源MFC窗口特效及背景皮肤控件,广泛兼容现有界面库
BoltTestShadow v1.0 本控件实现的功能: 1)窗口开启时的先放大再缩小同时改变透明度直至完全显示,窗口关闭时先缩小再放大同时改变透明度 直至完全消失的功能(不加载皮肤也可以使用) 2 ...
- VC中为对话框添加背景图片
From: http://blog.ezcn8.com/2011/06/11/vc%E4%B8%AD%E4%B8%BA%E5%AF%B9%E8%AF%9D%E6%A1%86%E6%B7%BB%E5%8 ...
- c语言mfc怎么插入背景图片,MFC 对话框添加背景图片详细过程(两种方法)
给对话框添加背景图片方法很多,在此贴出两种很常见的方法.一种是通过读取位图资源显示位图(BitMap) step: 1.创建内存设备上下文: 2.选择位图,将其装入内存设备上下文: 3.使用BitBl ...
- MFC几种给对话框添加背景图的方法
1,目标 总结几种给MFC对话框添加背景图片的方法. 2,实现 方式一:(适用于多种格式)用CImage类可以加载多种格式的图片,在OnPaint中Draw即可. void CBackgroundDl ...
- MFC对话框动态背景(定时器)
MFC对话框动态背景 一.创建对话框 二.添加背景图片 三.加载图片到对话框 四.添加定时器并初始化 五.运行结果 一.创建对话框 1.打开VS(这里是VS2017),文件->新建->项目 ...
- MFC 对话框添加背景图
// 给对话框添加背景图 BOOL CEditCtrlMultilineDlg::OnEraseBkgnd(CDC* pDC) {// TODO: 在此添加消息处理程序代码和/或调用默认值CDC Me ...
- 安卓学习专栏——实战项目酷欧天气(4)给天气页面加上背景图片
步骤 系列文章 前言 实现效果 项目结构 1.获取必应每日一图 1.1修改修改activity_weather.xml 1.2修改WeatherActivity 2.背景图和状态栏效果修改 2.1修改 ...
最新文章
- 第1关:求1000以内所有的水仙花数
- springMVC get请求及其请求地址写法
- 跟着书本重学CSS(1)
- Linux下文件描述符
- 江苏c语言二级试题及答案,江苏省计算机二级C语言试题及答案.doc
- Android编译笔记一
- 浏览器常见bug及解决办法
- C++const的多种用法
- 【Git】从GitHub到本地clone项目慢的解决方法
- Zabbix监控指定端口的步骤
- oracle的临时表和With As总结
- oracle检查完系统要求不动,w10安装oracle, 正在检查操作系统要求... 实际结果: 6.2...
- 数据--第35课 - 创建二叉树
- 关于求已知整数数组的连续子数组的最大和的方法 ——基于软件工程的要求给予优化...
- 把php文件全改为html文件,怎么把动态的php文件转换成静态的html文件,html文件是php文件…...
- gameloft java 游戏_每一款JAVA游戏都是经典,但只有四款游戏,是90%玩家从小玩到大...
- 动易模板制作示例(一)
- android 外边距,外边距(padding)重叠的及解决办法
- FxFactory 7 Pro for Mac(fcpx/ae/pr视觉特效插件包)v7.2.5
- 云服务器ECS的简介
热门文章
- 常用web服务器:状态监控status页面
- 微信小程序 全局状态管理 ,响应式
- android汤姆猫的实验报告,毕业设计(论文)-基于Android的会说话的汤姆猫的设计与实现.doc...
- android 手表解决方案,智能手表解决方案
- Deprecated Gradle features were used in this build, making it incompatible with Gradle 7.0.
- iOS开发项目实战狗粮
- php本地环境搭建教程,用 phpstudy 搭建本地 php 环境及安装 wordpress 教程
- 计算机专业职业理想作文400字,我的理想作文400字(精选4篇)
- xamp设置web服务器
- html鼠标经过状态,HTML5 - 让Canvas内部元素实现鼠标移入、移出效果(Tooltip提示效果)...