PC Camera 开发日志(二十)------- 窗口背景贴图(图覆盖整个窗口)
2008-08-08 17:20
344 查看
希望上一篇日志不要被骂,但是大的公司确实有能力购买皮肤库。但是小作坊就希望程序员是个千面手,什么都能搞定。
下面说的另外一种美化方法就是我们这种劳动力被压榨之下,想出来的对策。
现在看到非常PP的软件,除了用别人写的控件皮肤库之外,最大的特点就是形状都有。什么样的图案,风格都有。
试想一下,我们做桌面的壁纸可以有多PP就有多PP,那么也就是说如果能够把图片资源转化成为我们的界面资源,那么我们的界面想多美就多美。因为只要别人设计的图美我们的界面就一定美。
在VC界面美化中,摈弃WINDOW的默认窗口,基本只要其框架和消息响应机制。其他需要对话框,控件的地方,我们都采用OwnerDraw的方式来实现这写对话框、控件的重现。
例如:对话框的美化。我们可以在MFC资源管理器中直接拖入一个空白对话框,然后选择对应的OwnerDraw属性。在对话框的OnPaint()函数中装载你想要的背景图片,那么整个Dialog的背景就是一副图片了。网上多数这样的程序是将客户区设有背景,或者这个窗口是有背景,但是保留有标题栏的对话框,虽然整个窗口都被背景图填满,但是有时候标题栏的存在会使刷新出现问题。那么我们有时候干脆去掉Dialog的Border属性,让他只有客户区,然后我们自己定义最大、最小、关闭按钮。
如下图所示,我用一张背景图作为Dialog的背景,然后自己放了三个Buttons在上面,自己定义三个Buttons的响应操作。而Buttons控件也是OwnerDraw属性,这样我们才可以将图片加载到Buttons。(当然是因为我们自己封装了新的继承CButton的类实现这个功能)
需要明白的是,默认的标题栏的功能有:当鼠标点击在标题栏区域的时候,可以实现窗口的拖动。在标题栏区域点击右键可以看到系统菜单。
如果我们去掉了标题栏,为了实现Dialog的美化,那么实现窗口拖动的动作需要自己写。
一般会Override CWnd的WM_LBUTTONDOWN消息处理函数。在处理函数中,判断鼠标的位置,然后发送点击了标题栏的消息就可以了。即假装点击了标题栏。
void CMyCamDlg::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
CDialog::OnLButtonDown(nFlags, point);
/*-------------------Sunny--------------------*/
if(DRAGBORDER<=point.x && point.x<=m_WndWidth-DRAGBORDER && DRAGBORDER<=point.y && point.y<=m_WndHeight-DRAGBORDER)
{
// 当鼠标的坐标属于中间区域的时候,不发送拖动窗口的消息。
// 拖动窗口的效果是通过模拟发送点击Caption的消息来实现的; WM_NCLBUTTONDOWN,HCAPTION;
return;
}
else
{
PostMessage(WM_NCLBUTTONDOWN, HTCAPTION, MAKELPARAM(point.x, point.y));
}
}
DRAGBORDER是我自己定义可拖动的边界的宽度。m_WndWidth,m_WndHeight是我获得的窗口的宽度、高度。
按钮的美化基本就是让按钮可以加载BITMAP图片,或者可以加载ICON图标。这样BUTTON就可以比WINDOWS的灰色按钮好看多了。
这两类出现比较多的控件,实现了图片化的化,其他控件也基本可以图片化。
有些例子,可以上国外的开源网站上学习。
CodeProject 就很好。
先说下,如何实现窗口贴上背景图。在Dialog去掉Border属性后。
在InitialDialog代码中写入代码,OnPaint()函数中写入代码:
BOOL CMyCamDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// 设置此对话框的图标。当应用程序主窗口不是对话框时,框架将自动
// 执行此操作
SetIcon(m_hIcon, TRUE); // 设置大图标
SetIcon(m_hIcon, FALSE); // 设置小图标
// TODO: 在此添加额外的初始化代码
/*-------------------Sunny--------------------*/
g_Util.SelectSkin(g_Util.m_SkinsVector,_T("orange"));
// 设置窗口的大小,并初始化窗口背景位图的句柄;
Skin();
// Arrange Buttons
ArrangeButtons();
//return TRUE; // 除非将焦点设置到控件,否则返回 TRUE
}
可以看出来我选择了Orange皮肤,然后Skin()函数设置了窗口大小,窗口大小根据背景图片的大小来定。然后OnPaint()函数中画出这幅背景图。
void CMyCamDlg::Skin()
{
// Get CtlPanel Dialog BkImage from the CtlPanelSkin class;
CString strPath = _T("");
strPath.Format(_T("%s//%s//%s"),g_Util.m_SkinPath, g_Util.m_CurrentSkinName,g_Util.m_SkinContainer.m_CtlPanelSkin.m_BkgImgName);
// paste BkImage;
BITMAPINFO bInfo;
CBitmap tempCBMAP;
m_hBKBMAP = (HBITMAP)::LoadImage(AfxGetInstanceHandle(), strPath, IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION|LR_LOADFROMFILE);
tempCBMAP.Attach(m_hBKBMAP);
tempCBMAP.GetObject(sizeof(bInfo),&bInfo);
m_WndWidth = bInfo.bmiHeader.biWidth;
m_WndHeight = bInfo.bmiHeader.biHeight;
MoveWindow(100,200,m_WndWidth,m_WndHeight);
tempCBMAP.Detach();
tempCBMAP.DeleteObject();
}
strPath中存储了背景图片的完整路径和图片名。
void CMyCamDlg::OnPaint()
{
CPaintDC dc(this); // 用于绘制的设备上下文
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
{
CDialog::OnPaint();
}
//Skin();
/*-------------------Sunny--------------------*/
// paste BkImage;
CBitmap tempCBMAP;
ASSERT(m_hBKBMAP!=NULL);
tempCBMAP.Attach(m_hBKBMAP);
//在内存中创建一个位图兼容设备
//CWindowDC dc(this);
CDC dcMemory;
dcMemory.CreateCompatibleDC(&dc);
//将图片选入兼容设备
CBitmap *pOldBmp=dcMemory.SelectObject(&tempCBMAP);
dc.BitBlt(0,0,m_WndWidth,m_WndHeight,&dcMemory,0,0,SRCCOPY);
dcMemory.SelectObject(pOldBmp);
tempCBMAP.Detach();
// past the effect tool bar
tempCBMAP.DeleteObject();
dcMemory.DeleteDC();
ReleaseDC(&dcMemory);
}
m_hBKBMAP 在Skinner()中初始化的,就是背景图片资源的句柄,我保留了。当然也可以重新在OnPaint中加载,觉得没有这个必要。除非是前面没有加载图片资源。(LoadImage函数加载图片)。
源代码参考(我上载的资源:PC CameraUI2.0中有类似代码)
下面说的另外一种美化方法就是我们这种劳动力被压榨之下,想出来的对策。
现在看到非常PP的软件,除了用别人写的控件皮肤库之外,最大的特点就是形状都有。什么样的图案,风格都有。
试想一下,我们做桌面的壁纸可以有多PP就有多PP,那么也就是说如果能够把图片资源转化成为我们的界面资源,那么我们的界面想多美就多美。因为只要别人设计的图美我们的界面就一定美。
在VC界面美化中,摈弃WINDOW的默认窗口,基本只要其框架和消息响应机制。其他需要对话框,控件的地方,我们都采用OwnerDraw的方式来实现这写对话框、控件的重现。
例如:对话框的美化。我们可以在MFC资源管理器中直接拖入一个空白对话框,然后选择对应的OwnerDraw属性。在对话框的OnPaint()函数中装载你想要的背景图片,那么整个Dialog的背景就是一副图片了。网上多数这样的程序是将客户区设有背景,或者这个窗口是有背景,但是保留有标题栏的对话框,虽然整个窗口都被背景图填满,但是有时候标题栏的存在会使刷新出现问题。那么我们有时候干脆去掉Dialog的Border属性,让他只有客户区,然后我们自己定义最大、最小、关闭按钮。
如下图所示,我用一张背景图作为Dialog的背景,然后自己放了三个Buttons在上面,自己定义三个Buttons的响应操作。而Buttons控件也是OwnerDraw属性,这样我们才可以将图片加载到Buttons。(当然是因为我们自己封装了新的继承CButton的类实现这个功能)
需要明白的是,默认的标题栏的功能有:当鼠标点击在标题栏区域的时候,可以实现窗口的拖动。在标题栏区域点击右键可以看到系统菜单。
如果我们去掉了标题栏,为了实现Dialog的美化,那么实现窗口拖动的动作需要自己写。
一般会Override CWnd的WM_LBUTTONDOWN消息处理函数。在处理函数中,判断鼠标的位置,然后发送点击了标题栏的消息就可以了。即假装点击了标题栏。
void CMyCamDlg::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
CDialog::OnLButtonDown(nFlags, point);
/*-------------------Sunny--------------------*/
if(DRAGBORDER<=point.x && point.x<=m_WndWidth-DRAGBORDER && DRAGBORDER<=point.y && point.y<=m_WndHeight-DRAGBORDER)
{
// 当鼠标的坐标属于中间区域的时候,不发送拖动窗口的消息。
// 拖动窗口的效果是通过模拟发送点击Caption的消息来实现的; WM_NCLBUTTONDOWN,HCAPTION;
return;
}
else
{
PostMessage(WM_NCLBUTTONDOWN, HTCAPTION, MAKELPARAM(point.x, point.y));
}
}
DRAGBORDER是我自己定义可拖动的边界的宽度。m_WndWidth,m_WndHeight是我获得的窗口的宽度、高度。
按钮的美化基本就是让按钮可以加载BITMAP图片,或者可以加载ICON图标。这样BUTTON就可以比WINDOWS的灰色按钮好看多了。
这两类出现比较多的控件,实现了图片化的化,其他控件也基本可以图片化。
有些例子,可以上国外的开源网站上学习。
CodeProject 就很好。
先说下,如何实现窗口贴上背景图。在Dialog去掉Border属性后。
在InitialDialog代码中写入代码,OnPaint()函数中写入代码:
BOOL CMyCamDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// 设置此对话框的图标。当应用程序主窗口不是对话框时,框架将自动
// 执行此操作
SetIcon(m_hIcon, TRUE); // 设置大图标
SetIcon(m_hIcon, FALSE); // 设置小图标
// TODO: 在此添加额外的初始化代码
/*-------------------Sunny--------------------*/
g_Util.SelectSkin(g_Util.m_SkinsVector,_T("orange"));
// 设置窗口的大小,并初始化窗口背景位图的句柄;
Skin();
// Arrange Buttons
ArrangeButtons();
//return TRUE; // 除非将焦点设置到控件,否则返回 TRUE
}
可以看出来我选择了Orange皮肤,然后Skin()函数设置了窗口大小,窗口大小根据背景图片的大小来定。然后OnPaint()函数中画出这幅背景图。
void CMyCamDlg::Skin()
{
// Get CtlPanel Dialog BkImage from the CtlPanelSkin class;
CString strPath = _T("");
strPath.Format(_T("%s//%s//%s"),g_Util.m_SkinPath, g_Util.m_CurrentSkinName,g_Util.m_SkinContainer.m_CtlPanelSkin.m_BkgImgName);
// paste BkImage;
BITMAPINFO bInfo;
CBitmap tempCBMAP;
m_hBKBMAP = (HBITMAP)::LoadImage(AfxGetInstanceHandle(), strPath, IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION|LR_LOADFROMFILE);
tempCBMAP.Attach(m_hBKBMAP);
tempCBMAP.GetObject(sizeof(bInfo),&bInfo);
m_WndWidth = bInfo.bmiHeader.biWidth;
m_WndHeight = bInfo.bmiHeader.biHeight;
MoveWindow(100,200,m_WndWidth,m_WndHeight);
tempCBMAP.Detach();
tempCBMAP.DeleteObject();
}
strPath中存储了背景图片的完整路径和图片名。
void CMyCamDlg::OnPaint()
{
CPaintDC dc(this); // 用于绘制的设备上下文
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
{
CDialog::OnPaint();
}
//Skin();
/*-------------------Sunny--------------------*/
// paste BkImage;
CBitmap tempCBMAP;
ASSERT(m_hBKBMAP!=NULL);
tempCBMAP.Attach(m_hBKBMAP);
//在内存中创建一个位图兼容设备
//CWindowDC dc(this);
CDC dcMemory;
dcMemory.CreateCompatibleDC(&dc);
//将图片选入兼容设备
CBitmap *pOldBmp=dcMemory.SelectObject(&tempCBMAP);
dc.BitBlt(0,0,m_WndWidth,m_WndHeight,&dcMemory,0,0,SRCCOPY);
dcMemory.SelectObject(pOldBmp);
tempCBMAP.Detach();
// past the effect tool bar
tempCBMAP.DeleteObject();
dcMemory.DeleteDC();
ReleaseDC(&dcMemory);
}
m_hBKBMAP 在Skinner()中初始化的,就是背景图片资源的句柄,我保留了。当然也可以重新在OnPaint中加载,觉得没有这个必要。除非是前面没有加载图片资源。(LoadImage函数加载图片)。
源代码参考(我上载的资源:PC CameraUI2.0中有类似代码)
相关文章推荐
- 仿酷狗音乐播放器开发日志二十——换肤功能背景图片控件的制作(附源码)
- 仿酷狗音乐播放器开发日志二十——换肤功能背景图片控件的制作(附源码)
- PC Camera开发日志(十二)------ 窗口的依附
- PC Camera开发日志(十三)------ 窗口贴图闪烁问题
- 【VS开发】修改窗口背景颜色大全
- js+css控制弹出小窗口之后,后整个页面背景图变色,并且不可操作,点击确定,页面跳转。。。
- div背景半透明 覆盖整个可视区域的遮罩层效果
- PC Camera开发日志(十)------ Version2.0时代到来
- 自绘实现半透明水晶按钮(继承CButton,设置BS_OWNERDRAW风格,覆盖DrawItem函数绘制按钮,把父窗口的背景复制到按钮上,实现视觉上的透明,最后通过AlphaBlend实现半透明)
- Kinect For Windows V2开发日志七:照片合成与背景消除 蓝幕技术 多目标动态实时 背景动态
- 开发日志:Tomcat更改启动窗口的标题
- Html5 Canvas开发之清除一个特定区域内的Canvas、宽高技巧、使Canvas填充整个浏览器窗口
- 【Cocos2d-X开发学习笔记】第27期:游戏背景之贴图地图类(CCTileMapAtlas)的使用
- delphi开发日志--登录窗口
- Qt 给主窗口添加背景但不覆盖控件
- div背景半透明,覆盖整个可视区域的遮罩层效果
- iOS开发 设置整个导航栏背景图、字体及标签栏更改选中背景图的颜色
- QMessageBox 窗口大小更改问题(thinkvd开发日志)
- 加载图片覆盖整个窗口
- 窗口背景贴图