TWin是所有窗口的父类,TDlg是对话框子类,处理了WM_INITDILOG等消息,
创建过程:首先aboutDlg = new TAboutDlg;然后Create(),最后Show();
Create()是TDlg类的函数,首先把当前的TWin对象aboutDlg的指针加入到wndArray中,然后调用SDK函数
CreateDialog来完成对话框的创建,然后进入TApp的WinProc,调用TDlg的WinProc函数来处理消息,
发送WM_INITDIALOG消息,调用TAboutDlg类的EvCreate函数来处理,
接着是Show()函数,发送WM_NCPAINT消息,接着发送WM_PAINT消息,后面是CTLCOLOR消息,调用
EventCtlColor()函数来处理(5次)。后面一直发送WM_NCPAINT消息;
接下来则是TAboutDlg来处理按钮消息了,按下按钮后会访问指定的网页。处理EvCommand消息,
访问IPMSGURL_MSGSTR指定的网页,
在msgStr。h文件中有定义:#define IPMSGURL_MSGSTR "http://www.ipmsg.org/index.html.en"
TAboutDlg是关于对话框,这里仅
分析TDlg类和TAboutDlg类的代码:
//对话框类,TWin的子类
class TDlg : public TWin
{
protected:
LPSTR resName;//资源的名字
UINT resId;//资源的id
BOOL modalFlg;//模式对话框还是非模式对话框
public:
TDlg(LPSTR _name, TWin *_parent = NULL);
TDlg(UINT resid, TWin *_parent = NULL);
virtual ~TDlg();
virtual BOOL Create(HINSTANCE hI = NULL);
virtual void Destroy(void);
virtual int Exec(void);
virtual void EndDialog(int);
UINT ResId(void)
{
return resId;
}
virtual BOOL EvCreate(LPARAM lParam);
virtual BOOL EvCommand(WORD wNotifyCode, WORD wID, LPARAM hwndCtl);
virtual BOOL EvSysCommand(WPARAM uCmdType, POINTS pos);
virtual BOOL EvQueryOpen(void);
virtual BOOL PreProcMsg(MSG *msg);
virtual LRESULT WinProc(UINT uMsg, WPARAM wParam, LPARAM lParam);
};
TDlg的实现文件:
static char *tdlg_id =
"@(#)Copyright (C) H.Shirouzu 1996-2001 tdlg.cpp Ver0.95";
#include "tlib.h"
TDlg::TDlg(LPSTR _resName, TWin *_parent) : TWin(_parent)
{
// 将字符串_resName复制到resname中
resName = strdup( _resName );
resId = 0;
modalFlg = FALSE;//默认的都是非模式对话框
}
TDlg::TDlg(UINT _resId, TWin *_parent) : TWin(_parent)
{
resName = NULL;
resId = _resId;
modalFlg = FALSE;//默认的都是非模式对话框
}
TDlg::~TDlg() // 调用EndDialog方法来关闭对话框
{
if ( hWnd )
{
EndDialog(FALSE);
}
//释放resName资源
if ( resName )
{
free( resName );
}
}
BOOL TDlg::Create(HINSTANCE hInstance)
{
//把preWnd指向当前窗口,这里并没有加入wndarray,因为这时的hwnd还没有建立起来
TApp::AddWin( this );
if ( ( hWnd = ::CreateDialog( hInstance ? hInstance : TApp::hI,
resId ? (LPCSTR)resId : resName, parent ? parent->hWnd : NULL,
(DLGPROC)TApp::WinProc) ) == NULL )
{
return TApp::DelWin(this), FALSE;
}
else
{
return TRUE;
}
}
int TDlg::Exec(void)
{
TApp::AddWin(this);
modalFlg = TRUE;//默认的是modalFlg
int result = ::DialogBox(TApp::hI, resId ? (LPCSTR)resId : resName,
parent ? parent->hWnd : NULL, (DLGPROC)TApp::WinProc);
modalFlg = FALSE;
return result;
}
void TDlg::Destroy(void)
{
EndDialog(FALSE);
}
LRESULT TDlg::WinProc(UINT uMsg, WPARAM wParam, LPARAM lParam)
{
LRESULT result = 0;
switch (uMsg)
{
case WM_INITDIALOG://create hwnd完毕后发送WM_INITDIALOG
//完成其他的创建,这里dlg类处理了initdialog消息
return EvCreate(lParam);
case WM_CLOSE:
EvClose();
return 0;
case WM_COMMAND: // 处理控件消息
EvCommand(HIWORD(wParam), LOWORD(wParam), lParam);
return 0;
case WM_SYSCOMMAND://处理系统菜单消息,比如右键菜单命令
EvSysCommand(wParam, MAKEPOINTS(lParam));
return 0;
case WM_TIMER://处理timer消息
EvTimer(wParam, (TIMERPROC)lParam);
return 0;
case WM_NCDESTROY://释放资源,在wndarray中删除自己对应的TWin对象
GetWindowRect(&rect);
EvNcDestroy();
//在app的winarray中删除自己
TApp::DelWin(this);
hWnd = 0;//删除自己对应的窗口对象
return 0;
case WM_QUERYENDSESSION: // Dialog
return !EvQueryEndSession((BOOL)wParam, (BOOL)lParam);
case WM_ENDSESSION:
EvEndSession((BOOL)wParam, (BOOL)lParam);
return 0;
case WM_QUERYOPEN:
return EvQueryOpen();
case WM_PAINT:
EvPaint();
return 0;
case WM_NCPAINT:
EvNcPaint((HRGN)wParam);
return 0;
case WM_SIZE: // 调整大小
EvSize((UINT)wParam, LOWORD(lParam), HIWORD(lParam));
return 0;
case WM_GETMINMAXINFO:
EvGetMinMaxInfo((MINMAXINFO *)lParam);
return 0;
case WM_SETCURSOR:
return EvSetCursor((HWND)wParam, LOWORD(lParam), HIWORD(lParam));
case WM_MOUSEMOVE:
return EvMouseMove((UINT)wParam, MAKEPOINTS(lParam));
case WM_NCHITTEST:
return EvNcHitTest(MAKEPOINTS(lParam), &result), result;
case WM_MEASUREITEM:
return EvMeasureItem((UINT)wParam, (LPMEASUREITEMSTRUCT)lParam);
case WM_DRAWITEM:
return EvDrawItem((UINT)wParam, (LPDRAWITEMSTRUCT)lParam);
case WM_NOTIFY:
return EvNotify((UINT)wParam, (LPNMHDR)lParam);
case WM_CONTEXTMENU://EvContextMenu 处理上下文菜单消息
//弹出一个右键菜单
return EvContextMenu((HWND)wParam, MAKEPOINTS(lParam));
case WM_HOTKEY:
return EvHotKey((int)wParam);
case WM_LBUTTONUP:
case WM_RBUTTONUP:
case WM_NCLBUTTONUP:
case WM_NCRBUTTONUP:
case WM_LBUTTONDOWN:
case WM_RBUTTONDOWN:
case WM_NCLBUTTONDOWN:
case WM_NCRBUTTONDOWN:
case WM_LBUTTONDBLCLK:
case WM_RBUTTONDBLCLK:
case WM_NCLBUTTONDBLCLK:
case WM_NCRBUTTONDBLCLK:
//EventButton处理所有的鼠标消息
EventButton(uMsg, wParam, MAKEPOINTS(lParam));
return 0;
case WM_HSCROLL:
case WM_VSCROLL:
EventScroll(uMsg, LOWORD(wParam), HIWORD(wParam), (HWND)lParam);
return 0;
case WM_INITMENU:
case WM_INITMENUPOPUP: // 处理初始化menu消息
EventInitMenu(uMsg, (HMENU)wParam, LOWORD(lParam), (BOOL)HIWORD(lParam));
return 0;
case WM_MENUSELECT:
EvMenuSelect(LOWORD(wParam), (BOOL)HIWORD(wParam), (HMENU)lParam);
return 0;
case WM_DROPFILES:
EvDropFiles((HDROP)wParam);
return 0;
case WM_CTLCOLORBTN:
case WM_CTLCOLORDLG:
case WM_CTLCOLOREDIT:
case WM_CTLCOLORLISTBOX:
case WM_CTLCOLORMSGBOX:
case WM_CTLCOLORSCROLLBAR:
case WM_CTLCOLORSTATIC:
return EventCtlColor(uMsg, (HDC)wParam, (HWND)lParam,
(HBRUSH *)&result), result;
case WM_KILLFOCUS:
case WM_SETFOCUS:
EventFocus(uMsg, (HWND)wParam);
return 0;
default: // 默认的用户消息都使用EventUser来处理!比如WM_DELAYSETTEXT等消息
if (uMsg >= WM_USER && uMsg <= 0x7FFF || uMsg >= 0xC000 && uMsg <= 0xFFFF)
{
return EventUser(uMsg, wParam, lParam);
}
}
return FALSE;
}
BOOL TDlg::PreProcMsg(MSG *msg)
{
if ( hAccel && ::TranslateAccelerator(hWnd, hAccel, msg) )
{
return TRUE;
}
if ( !modalFlg )
{
return ::IsDialogMessage(hWnd, msg);
}
return FALSE;
}
BOOL TDlg::EvSysCommand(WPARAM uCmdType, POINTS pos)
{
return FALSE;
}
//处理对话框上的ok 和cancel按钮
BOOL TDlg::EvCommand(WORD wNotifyCode, WORD wID, LPARAM hwndCtl)
{
switch (wID)
{
case IDOK: case IDYES:
EndDialog(TRUE);
return TRUE;
case IDCANCEL: case IDNO:
EndDialog(FALSE);
return TRUE;
}
return FALSE;
}
BOOL TDlg::EvQueryOpen(void)
{
return FALSE;
}
BOOL TDlg::EvCreate(LPARAM lParam)
{
return TRUE;
}
void TDlg::EndDialog(int result)
{
if ( ::IsWindow(hWnd) )
{
if ( modalFlg )
{
::EndDialog(hWnd, result);
}
else // 非模式对话框,直接destroyWindow
{
::DestroyWindow(hWnd);
}
}
}
TAboutDlg类的代码很少:
//关于对话框,只需要重载create和响应WM_COMMAND消息的EvCommand函数
class TAboutDlg : public TDlg
{
public:
TAboutDlg(TWin *_parent = NULL);
virtual BOOL EvCommand(WORD wNotifyCode, WORD wID, LPARAM hwndCtl);
virtual BOOL EvCreate(LPARAM lParam);
};
TAboutDlg类的实现代码:
TAboutDlg::TAboutDlg(TWin *_parent) : TDlg(ABOUT_DIALOG, _parent)
{
}
BOOL TAboutDlg::EvCreate(LPARAM lParam)
{
//把窗口的图标设置为默认的主窗口的图标
SetDlgIcon(hWnd);
if ( rect.left == CW_USEDEFAULT )
{
//获得window的rect
GetWindowRect(&rect);
//xsize和ysize是window的宽和高
int xsize = rect.right - rect.left, ysize = rect.bottom - rect.top;
//获得屏幕的高和宽
int cx = ::GetSystemMetrics(SM_CXFULLSCREEN),
cy = ::GetSystemMetrics(SM_CYFULLSCREEN);
int x = ( cx - xsize ) / 2;
int y = ( cy - ysize ) / 2;
//调整窗口的位置
MoveWindow( ( x < 0 ) ? 0 : x % ( cx - xsize ), ( y < 0 ) ? 0 : y % (cy - ysize),
xsize, ysize, FALSE);
}
else
{
MoveWindow(rect.left, rect.top, rect.right - rect.left,
rect.bottom - rect.top, FALSE);
}
return TRUE;
}
BOOL TAboutDlg::EvCommand(WORD wNotifyCode, WORD wID, LPARAM hWndCtl)
{
switch (wID)
{
case IDOK:
case IDCANCEL: // 直接EndDialog干掉模态对话框,或者destroywindow(非模态)
EndDialog(TRUE);
return TRUE;
case IPMSG_ICON:
case IPMSGWEB_BUTTON:
//如果按下了button IPMSGWEB_BUTTON 则 访问IPMSGURL_MSGSTR所指定的网站
if ( wID == IPMSGWEB_BUTTON || wNotifyCode == 1 )
{
::ShellExecute(NULL, NULL, IPMSGURL_MSGSTR, NULL, NULL, SW_SHOW);
}
return TRUE;
}
r