您的位置:首页 > 其它

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中有类似代码)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐