在Windows应用程序中,对话框是应用最广泛也是比较难控制其风格(外表)的
一类窗口。Windows 3.x所提供的传统的对话框一般都有一个单调的蓝色的边框
和白色窗口背景,即使采用Borland C++所提供的BorDlg风格的对话框,用自定义
控制(BWCC)来美化对话框的背景及内容,呆板的边框还是一成不变的。相信用过
Windows 95的朋友在享受其强大功能的同时,一定也为它所提供的具有立体感的
界面而感叹吧。事实上,在Windows 3.x中,我们也是可以作出更美观的窗口来
的,中文之星2.0就是一个很好的例子。
要想按自己的意愿来绘制一个普通窗口或对话框的边界,一般来说有两种方
法:一种是在系统绘制边框之后再在其上重新绘制一遍;另一种是彻底接管对边框
的绘制权,禁止系统的干涉。前一种方法对于含有菜单的窗口较为适应,能够保证
窗口始终以自定义方式出现,但是在
窗口更新时,这种方式会产生闪烁现象;第二种方式比较适应于没有菜单的窗口,
更新时不会发生闪烁现象,但是如果处理不好有时系统会暂时重新获得绘制权,使
得窗口以另外一种形象出现。下面作者要介绍的方法将结合使用这两种方法,以
求取得较好的效果。
在一个窗口的边界(非用户区)需要重画时,窗口将接到消息WM_NCPAINT,通常
该消息将被传送给窗口的DefWndProc函数进行缺省的处理,我们只要使应用程序
处理这个消息而不是交给Windows就可以实现第二种方法。由于对话框有许多普
通窗口不具有的特性,因此如果希望比较完善地控制对话框的风格,还要适当用第
一种方式做辅助。作者采取的做法为每当对话框被激活时都重画一遍。
下面就是笔者基于以上思想而编制的一个边界有立体效果的对话框类。将
该类做成通用的动态连接库就可以供其他程序使用。
//以下为头文件说明
#if !defined(_NEW_STYLE_DIALOG_)
#define _NEW_STYLE_DIALOG_
#include <owl.h>
extern PTModule TheModule;
_CLASSDEF(TNewDialog)
class TNewDialog : public TDialog {
HPEN DarkGrayPen,LightGrayPen;
HPEN WhitePen,BlackPen;
HBRUSH LightGrayBrush,BlueBrush;
HBRUSH NullBrush;
void CreateDrawObject(void);
public:
TNewDialog(PTWindowsObject AParent, LPSTR AName, PTModule AModule = NULL)
:TDialog(AParent,AName,AModule)
{ CreateDrawObject(); }
TNewDialog(PTWindowsObject AParent, int
ResourceId, PTModule AModule = NULL)
:TDialog(AParent,ResourceId,AMod-ule)
{ CreateDrawObject(); }
~TNewDialog();
virtual void WMNCPaint(RTMessage Msg)
=[WM_FIRST+WM_NCPAINT];
virtual void WMActivate(RTMessage Msg)
=[WM_FIRST+WM_ACTIVATE];
void DrawFrame(); };
#endif
//以下为动态连接库和类成员函数体
#include "newdlg.h"
PTModule TheModule;
int FAR PASCAL LibMain(HINSTANCE hIn-stance, WORD , WORD , LPSTR lpCmd -Line)
{
int TheStatus;
TheModule = new TModule("NEWDL-GDLL",hInstance, lpCmdLine);
TheStatus = TheModule->Status;
if ( TheStatus != 0 ) {
delete TheModule;
TheModule = NULL; }
return (TheStatus == 0);
}
int FAR PASCAL WEP ( int /*bSystemExit*/ )
{return 1;}
TNewDialog::~TNewDialog()
{
DeleteObject(DarkGrayPen);
DeleteObject(LightGrayPen);
DeleteObject(WhitePen);
DeleteObject(BlackPen);
DeleteObject(LightGrayBrush);
DeleteObject(BlueBrush);
DeleteObject(NullBrush);
}
void TNewDialog::CreateDrawObject(void)
{
DarkGrayPen = (HPEN)CreatePen(
PS_SOLID,1,RGB(128,128,128));
LightGrayPen= (HPEN)CreatePen(
PS_SOLID,1,RGB(192,192,192));
WhitePen = (HPEN)GetStockObject(WHITE_PEN);
BlackPen = (HPEN)GetStockObject(BLACK_PEN);
LightGrayBrush = (HBRUSH)GetStockObject( LTGRAY_BRUSH);
NullBrush = (HBRUSH)GetStockObject(
NULL_BRUSH);
LOGBRUSH lb;
lb.lbStyle = BS_SOLID;
lb.lbColor = RGB( 0, 0, 128);
lb.lbHatch = NULL;
BlueBrush = CreateBrushIndirect(&lb);
}
void TNewDialog::WMActivate(RTMessage Msg)
{
if(Msg.WParam==WA_ACTIVE ||
Msg.WParam==WA_CLICKACTIVE)
DrawFrame();
}
void TNewDialog::WMNCPaint(RTMessage )
{ DrawFrame(); }
void TNewDialog::DrawFrame()
{
RECT rWinRect;
HDC hWinDC;
LONG DLGStyle;
HPEN oldPen;
HBRUSH oldBrush;
int r,b;
hWinDC = GetWindowDC(HWindow);
G etWindowRect(HWindow,&rWinRect);
r = rWinRect.right-rWinRect.left-1;
b = rWinRect.bottom-rWinRect.top-1;
oldPen = (HPEN)SelectObject(
hWinDC,DarkGrayPen);
oldBrush=(HBRUSH)SelectObject(
hWinDC,NullBrush);
Rectangle(hWinDC,0,0,r,b);
SelectObject(hWinDC,BlueBrush);
Rectangle(hWinDC,5,4,r-4,24);
SelectObject(hWinDC,BlackPen);
MoveTo(hWinDC,0,b);
LineTo(hWinDC,r,b);
LineTo(hWinDC,r,-1);
SelectObject(hWinDC,WhitePen);
MoveTo(hWinDC,1,b-2);
LineTo(hWinDC,1,1);
LineTo(hWinDC,r-1,1);
MoveTo(hWinDC,r-5,5);
LineTo(hWinDC,r-5,23);
LineTo(hWinDC,4,23);
SelectObject(hWinDC,LightGrayPen);
SelectObject(hWinDC,NullBrush);
Rectangle(hWinDC,2,2,r-1,b-1);
Rectangle(hWinDC,3,3,r-2,b-2);
Rectangle(hWinDC,4,4,r-3,b-3);
SelectObject(hWinDC,DarkGrayPen);
MoveTo(hWinDC,5,4);
LineTo(hWinDC,r-4,4);
DLGStyle = GetWindowLong(HWindow,
GWL_STYLE);
if(DLGStyle & WS_SYSMENU) {
SelectObject(hWinDC,LightGrayPen);
SelectObject(hWinDC,LightGrayBrush);
Rectangle(hWinDC,6,5,24,23);
SelectObject(hWinDC,BlackPen);
SelectObject(hWinDC,NullBrush);
Rectangle(hWinDC,8,12,21,15);
SelectObject(hWinDC,WhitePen);
MoveTo(hWinDC,9,13);
LineTo(hWinDC,20,13);
SelectObject(hWinDC,DarkGrayPen);
MoveTo(hWinDC,9,15);
LineTo(hWinDC,21,15);
LineTo(hWinDC,21,12);
}
SelectObject(hWinDC,oldPen);
SelectObject(hWinDC,oldBrush);
ReleaseDC(HWindow,hWinDC);
}