浏览器大全:是一个提供流行浏览器教程、在线学习分享的学习平台!

在Windows95/98中完成苹果窗口界面

高波 马惠业

有没有想过在Windows环境下实现苹果电脑窗口界面的风格?下面就以实现苹果电脑窗口风格为例,进行一次奇妙的旅行。  

原 理  
仔细观察苹果窗口,发现和Windows窗口的区别主要体现在标题栏和控制按钮(即最小化、恢复、关闭按钮)。所以我们应该把主要精力集中在这两点上,直接对Windows窗口已有的标题栏和控制按钮进行修改。  
由于标题栏和控制按钮都属于非客户区,所以关键是获得非客户区的CDC,可以通过GetWindowDC()来获得。GetWindowDC()可以获得整个窗口的CDC,当然也包括非客户区的CDC,得到此CDC后,确定标题条的确切位置,就可以在标题栏上为所欲为了。如图1所示,在标题栏的位置装入一幅位图(截取了苹果窗口的一幅位图),在位图上加上文字标题(此标题具有3D效果,感觉还不错吧,其实就是把相同的字用不同的颜色和坐标写了两次)和控制按钮(实际也是一幅位图,只不过在鼠标单击时显示另一幅位图,看起来就像是一个按钮),由于控制按钮是自己加的,所以要由自己负责单击按钮的处理。到此为止,虽然准备好了窗口的标题栏和按钮,但还没有机会显示。我们知道要在窗口的客户区上画东东,只需响应Windows的客户区重画消息,在此消息处理函数中实现具体的操作。同理,要在非客户区上画东东,也只需响应Windows的非客户区重画消息,在消息处理函数中完成标题栏和按钮的绘制。  


具体实现  
采用VC6.0在Windows98下实现这种技术。  
下面以生成一个苹果界面风格的对话框为例对这种方法进行详细的阐述。  

1、用APPWIZARD(应用程序向导)生成一个新的应用程序(SDI与MDI均可),在 RESOURCE VIEW里面添加一个DIALOG资源。  
2、添加一个新的对话框类。在ClassWizard中选择添加新类,输入类名CTestDlg并且选取基类CDIALOG。这样就建立起对话框类和对话框资源之间的联系。  
3、在RESOURCE VIEW 中加入按钮和标题栏和背景位图。  
在主菜单中的INSERT 菜单项下面选择RESOURCE,然后选择添加BITMAP,这样你就可以在RESOURCEVIEW 中看到BITMAP项,下面点击鼠标右键,选择IMPORT,从已有的位图文件中选出苹果风格的按钮和标题栏,并且分别赋予不同的ID。  
4、在自己创建的CTestDlg类中添加新的按钮和新的标题栏。
(1)首先在CTestDlg的构造函数中装入位图资源。程序如下:  

CTestDlg::CTestDlg(int nID,
CWnd* pParent /*=NULL*/)
: CDialog(nID, pParent)
{
//{{AFX_DATA_INIT(CTestDlg)
// NOTE: the ClassWizard will add
member initialization here
//}}AFX_DATA_INIT
m_bPressed=FALSE;  
//load the bitmap of button_down
m_bitmapPressed.LoadBitmap(IDB_BUTTONDOWN);
//load the bitmap of button_up
m_bitmapUnpressed.LoadBitmap(IDB_BUTTONUP);
//load the bitmap of caption
m_bitmapCaption.LoadBitmap(IDB_CAPTION);
//load the bitmap of background
m_bmpBk.LoadBitmap(IDB_BKGROUND);
}

(2)分别得到标题栏和按钮的位置。  

首先得到按钮的位置:  

void CTestDlg::GetButtonRect(CRect& rect)  
{
GetWindowRect(&rect);
// for small caption use SM_CYDLGFRAME
rect.top += GetSystemMetrics(SM_CYFRAME)+1;
// for small caption use SM_CYSMSIZE
rect.bottom =rect.top +GetSystemMetrics
(SM_CYSIZE)-4;
// for small caption use SM_CXDLGFRAME
rect.left =rect.right -GetSystemMetrics
(SM_CXFRAME) -  
// for small caption use SM_CXSMSIZE
GetSystemMetrics(SM_CXSIZE))-1;
// for small caption use SM_CXSMSIZE
rect.right =rect.left +GetSystemMetrics
(SM_CXSIZE)-3;  
}
然后得到标题栏的位置:
void CTestDlg::GetCaptionRect(CRect &rect)
{
GetWindowRect(&rect);
// for small caption use SM_CYSMSIZE
rect.bottom =rect.top +GetSystemMetrics
(SM_CYSIZE)+3;  
}

5.在按钮和标题栏对应的位置上分别画出苹果风格的按钮和标题栏。  

首先画出按钮:  

void CTestDlg::DrawButton()  
{
// if window isn't visible or is minimized, skip
if (!IsWindowVisible() IsIconic())
return;
// get appropriate bitmap
CDC memDC;
CDC* pDC = GetWindowDC();
memDC.CreateCompatibleDC(pDC);
memDC.SelectObject(m_bPressed ?
&m_bitmapPressed : &m_bitmapUnpressed);
// get button rect and convert it into non
-client area coordinates
CRect rect, rectWnd;
GetButtonRect(rect);
GetWindowRect(rectWnd);
rect.OffsetRect(-rectWnd.left, -rectWnd.top);
int width,height;
BITMAP *pBitMap;
pBitMap = new BITMAP;
if (m_bPressed)
m_bitmapPressed.GetBitmap(pBitMap);
else
m_bitmapUnpressed.GetBitmap(pBitMap);
width=pBitMap->bmWidth;
height=pBitMap->bmHeight;
// draw it
pDC->StretchBlt( rect.left, rect.top, rect.Width(),
rect.Height(), &memDC, 0, 0,
width,height,SRCCOPY );
memDC.DeleteDC();
ReleaseDC(pDC);
delete pBitMap;
}
然后画出标题栏:
void CTestDlg::DrawCaption()
{
if (!IsWindowVisible() IsIconic())
return;
// get appropriate bitmap
CDC memDC;
CDC* pDC = GetWindowDC();
memDC.CreateCompatibleDC(pDC);
memDC.SelectObject(m_bitmapCaption);
// get button rect and convert it into non
-client area coordinates
CRect rect, rectWnd;
GetCaptionRect(rect);
GetWindowRect(rectWnd);
rect.OffsetRect(-rectWnd.left, -rectWnd.top);
// draw the caption  
int width,height;
BITMAP *pBitMap;
pBitMap = new BITMAP;
m_bitmapCaption.GetBitmap(pBitMap);
width=pBitMap->bmWidth;
height=pBitMap->bmHeight;
pDC->StretchBlt( rect.left, rect.top, rect.Width(),
rect.Height(), &memDC, 0, 0, width,
height, SRCCOPY );
//get the the text of the caption and
draw it with 3D style
pDC->SetBkColor(RGB(209,209,209));
CString caption;
GetWindowText(caption);
caption = “ "+caption+“ ";
rect.OffsetRect(0,4);
//draw the text of the caption with gray color
pDC->SetTextColor(RGB(128,128,128));
pDC->DrawText
(caption,rect,DT_CENTER DT_VCENTER);
//move the coordinate to left and up
rect.OffsetRect(-1,-1);
pDC->SetBkMode(TRANSPARENT);
//draw the text of the caption with white color
pDC->SetTextColor(RGB(255,255,255));
//255,255,255 128,128,128
pDC->DrawText
(caption,rect,DT_CENTER DT_VCENTER);
memDC.DeleteDC();
ReleaseDC(pDC);
delete pBitMap;
}

6.处理鼠标点击按钮的消息。  

要响应鼠标左键在标题栏上的单击,需要添加相应的消息映射函数。  

通过在OnNcLButtonDown中给关闭按钮换一副图像,来实现按钮被按下的效果,同时完成窗口的关闭。  

void CTestDlg::OnNcLButtonDown
(UINT nHitTest, CPoint point)  
{
if (nHitTest == HTCAPTION)
{
// see if in area we reserved for button
CRect rect;
GetButtonRect(rect);
if (rect.PtInRect(point))
{
m_bPressed = !m_bPressed;
DrawButton();
CDialog::OnCancel();
}
}
CDialog::OnNcLButtonDown(nHitTest, point);
}

7.处理窗口非客户区的重画。  

这里主要是对标题栏和按钮的重画。通过ClassWizard给对话框添加非客户区重画的消息映射函数。  

void CTestDlg::OnNcPaint()  
{
// draw caption first
CDialog::OnNcPaint();

// then draw button on top
DrawCaption();
DrawButton();
}

8.给对话框加上背景,在此为一幅位图:  

void CTestDlg::OnPaint()  
{
CPaintDC dc(this);
// device context for painting
CDC memDC;
memDC.CreateCompatibleDC(&dc);
memDC.SelectObject(m_bmpBk);
CRect rect, rectWnd
GetWindowRect(rect);
GetClientRect(rect);
int width,height;
BITMAP *pBitMap;
pBitMap = new BITMAP;
m_bmpBk.GetBitmap(pBitMap);
width=pBitMap->bmWidth;
height=pBitMap->bmHeight;
dc.StretchBlt( rect.left, rect.top, rect.Width(),  
rect.Height(),  
&memDC, 0, 0,width,height, SRCCOPY );  
}

至此为止,一个具有苹果窗口风格的对话框就新鲜出炉了!怎么样?味道还不错吧?  

但是,如果每次要用到对话框的时候都如此这般,岂不是太...那个了吧!不要惊慌,只需稍做改变就可一劳永逸了。将此对话框的构造函数的说明部分改为下面黑体所示即可,就这么简单。(用黑体表示强调的部分)  

CTestDlg::CTestDlg(int nID, CWnd
* pParent /*=NULL*/)
: CDialog(nID, pParent)
{
//{{AFX_DATA_INIT(CTestDlg)
// NOTE: the ClassWizard will add  
member initialization here
//}}AFX_DATA_INIT
m_bPressed=FALSE;  
m_bitmapPressed.LoadBitmap
(IDB_BUTTONDOWN);
m_bitmapUnpressed.LoadBitmap
(IDB_BUTTONUP);
m_bitmapCaption.LoadBitmap(IDB_CAPTION);
m_bmpBk.LoadBitmap(IDB_BKGROUND);
m_brushButton.CreateSolidBrush
(RGB(192,192,255));
}

以后,凡是用到对话框的时候,在VC的资源编辑器中把对话框设置好,把父类改为此对话框类即可,当然,要把此对话框类包括在你的Project中,图1所示的对话框就是继承于此对话框。  

在CMyDialog的.h文件中将CDialog 改为CTestDlg:  

Class CMyDialog: public CTestDlg  
void CNewapple1Doc::OnDialog1()  
{
// TODO: Add your command handler code here
CMyDialog dlg;
dlg.DoModal();


相关软件

2345加速浏览器官方版

2345加速浏览器官方版 | 56.2MB

2345加速浏览器官方版

新一代2345加速浏览器采用Chromium和IE双内核,主打极速与安全特性。基于Chromium深度定制,引入网页智能预加载技术,访问网页更快速..

QQ浏览器官方正式版

QQ浏览器官方正式版 | 49.67MB

QQ浏览器官方正式版

QQ浏览器秉承TT浏览器1-4系列方便易用的特点,但技术架构不同,交互和视觉表现也重新设计,采用Chromium内核+IE双内核,让浏览快速稳定...

百度浏览器最新版下载

百度浏览器最新版下载 | 13.3MB

百度浏览器最新版下载

q百度浏览器,是一款简洁轻快、智能懂你的浏览器。依靠百度强大的搜索平台,在满足用户浏览网页的基础上,它整合百度体系业务优势,带给用户更方便的浏览方式功能...

UC浏览器官方正式版

UC浏览器官方正式版 | 44.2MB

UC浏览器官方正式版

UC浏览器(UC Browser)是UC Mobile Limited在2004年8月开发的一款软件,分uc手机浏览器和uc浏览器电脑版。UC浏览器是全球使用量最大的第三方手机浏览器...

猎豹浏览器2022最新版下载

猎豹浏览器2022下载 | 45MB

猎豹浏览器2022最新版下载

猎豹安全浏览器对Chrome的Webkit内核进行了超过100项的技术优化,访问网页速度更快。其具有首创的智能切换引擎,动态选择内核匹配不同网页...

360安全浏览器官方版下载

360安全浏览器下载 | 21.4MB

360安全浏览器官方版下载

360安全浏览器拥有全国最大的恶意网址库,采用恶意网址拦截技术,可自动拦截挂马、欺诈、网银仿冒等恶意网址。独创沙箱技术,在隔离模式即使访问****也不会感染...