对话框的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

给对话框加上背景皮肤相关推荐

  1. VS2010 MFC中控件、对话框等背景颜色动态修改的方法

    通过类向导,或者手动添加消息:WM_CTLCOLOR,其消息响应函数为: afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) ...

  2. 【VS开发】VS2010 MFC中控件、对话框等背景颜色动态修改的方法

    [VS开发]VS2010 MFC中控件.对话框等背景颜色动态修改的方法 标签(空格分隔):[VS开发] 声明:引用请注明出处http://blog.csdn.net/lg1259156776/ 说明: ...

  3. 怎样给Tab Control控件加上背景颜色或图片

    如果不懂Tab控件添加选项卡(属性页)的请看这篇文章:http://blog.csdn.net/qq_18297675/article/details/50991413 这里我就直接在添加好选项卡的基 ...

  4. 做了一个开源MFC窗口特效及背景皮肤控件,广泛兼容现有界面库

    BoltTestShadow v1.0 本控件实现的功能: 1)窗口开启时的先放大再缩小同时改变透明度直至完全显示,窗口关闭时先缩小再放大同时改变透明度 直至完全消失的功能(不加载皮肤也可以使用) 2 ...

  5. 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 ...

  6. c语言mfc怎么插入背景图片,MFC 对话框添加背景图片详细过程(两种方法)

    给对话框添加背景图片方法很多,在此贴出两种很常见的方法.一种是通过读取位图资源显示位图(BitMap) step: 1.创建内存设备上下文: 2.选择位图,将其装入内存设备上下文: 3.使用BitBl ...

  7. MFC几种给对话框添加背景图的方法

    1,目标 总结几种给MFC对话框添加背景图片的方法. 2,实现 方式一:(适用于多种格式)用CImage类可以加载多种格式的图片,在OnPaint中Draw即可. void CBackgroundDl ...

  8. MFC对话框动态背景(定时器)

    MFC对话框动态背景 一.创建对话框 二.添加背景图片 三.加载图片到对话框 四.添加定时器并初始化 五.运行结果 一.创建对话框 1.打开VS(这里是VS2017),文件->新建->项目 ...

  9. MFC 对话框添加背景图

    // 给对话框添加背景图 BOOL CEditCtrlMultilineDlg::OnEraseBkgnd(CDC* pDC) {// TODO: 在此添加消息处理程序代码和/或调用默认值CDC Me ...

  10. 安卓学习专栏——实战项目酷欧天气(4)给天气页面加上背景图片

    步骤 系列文章 前言 实现效果 项目结构 1.获取必应每日一图 1.1修改修改activity_weather.xml 1.2修改WeatherActivity 2.背景图和状态栏效果修改 2.1修改 ...

最新文章

  1. 第1关:求1000以内所有的水仙花数
  2. springMVC get请求及其请求地址写法
  3. 跟着书本重学CSS(1)
  4. Linux下文件描述符
  5. 江苏c语言二级试题及答案,江苏省计算机二级C语言试题及答案.doc
  6. Android编译笔记一
  7. 浏览器常见bug及解决办法
  8. C++const的多种用法
  9. 【Git】从GitHub到本地clone项目慢的解决方法
  10. Zabbix监控指定端口的步骤
  11. oracle的临时表和With As总结
  12. oracle检查完系统要求不动,w10安装oracle, 正在检查操作系统要求... 实际结果: 6.2...
  13. 数据--第35课 - 创建二叉树
  14. 关于求已知整数数组的连续子数组的最大和的方法 ——基于软件工程的要求给予优化...
  15. 把php文件全改为html文件,怎么把动态的php文件转换成静态的html文件,html文件是php文件…...
  16. gameloft java 游戏_每一款JAVA游戏都是经典,但只有四款游戏,是90%玩家从小玩到大...
  17. 动易模板制作示例(一)
  18. android 外边距,外边距(padding)重叠的及解决办法
  19. FxFactory 7 Pro for Mac(fcpx/ae/pr视觉特效插件包)v7.2.5
  20. 云服务器ECS的简介

热门文章

  1. 常用web服务器:状态监控status页面
  2. 微信小程序 全局状态管理 ,响应式
  3. android汤姆猫的实验报告,毕业设计(论文)-基于Android的会说话的汤姆猫的设计与实现.doc...
  4. android 手表解决方案,智能手表解决方案
  5. Deprecated Gradle features were used in this build, making it incompatible with Gradle 7.0.
  6. iOS开发项目实战狗粮
  7. php本地环境搭建教程,用 phpstudy 搭建本地 php 环境及安装 wordpress 教程
  8. 计算机专业职业理想作文400字,我的理想作文400字(精选4篇)
  9. xamp设置web服务器
  10. html鼠标经过状态,HTML5 - 让Canvas内部元素实现鼠标移入、移出效果(Tooltip提示效果)...