深入浅出MFC第2版(PDF格式)-第89部分
按键盘上方向键 ← 或 → 可快速上下翻页,按键盘上的 Enter 键可回到本书目录页,按键盘上方向键 ↑ 可回到本页顶部!
————未阅读完?加入书签已便下次继续阅读!
采用CMDIFrameWnd 类别。
构造MDI 主窗口,有两个步骤。第一个步骤是new 一个CMDIFrameWnd 对象,第二个
步骤是调用其LoadFrame 函数。此函数内容如下:
// in WNDFRM。CPP
BOOL CFrameWnd::LoadFrame(UINT nIDResource; DWORD dwDefaultStyle;
CWnd* pParentWnd; CCreateContext* pContext)
{
CString strFullString;
if (strFullString。LoadString (nIDResource))
AfxExtractSubString (m_strTitle; strFullString; 0); // first sub…string
if (!AfxDeferRegisterClass(AFX_WNDFRAMEORVIEW_REG))
return FALSE;
// attempt to create the window
LPCTSTR lpszClass = GetIconWndClass (dwDefaultStyle; nIDResource);
LPCTSTR lpszTitle = m_strTitle;
if (!Create (lpszClass; lpszTitle; dwDefaultStyle; rectDefault;
pParentWnd; MAKEINTRESOURCE(nIDResource); 0L; pContext))
{
return FALSE; // will self destruct on failure normally
}
// save the default menu handle
m_hMenuDefault = ::GetMenu(m_hWnd);
// load accelerator resource
LoadAccelTable (MAKEINTRESOURCE(nIDResource));
if (pContext == NULL) // send initial update
SendMessageToDescendants(WM_INITIALUPDATE; 0; 0; TRUE; TRUE);
return TRUE;
}
438
…………………………………………………………Page 501……………………………………………………………
第7章 簡單而完整:MFC 骨幹程式
BOOL CScribbleApp::InitInstance()
{
。。。。
CMainFrame* pMainFrame = new CMainFrame;
if (!pMainFrame…》LoadFrame (IDR_MAINFRAME))
return FALSE;
m_pMainWnd = pMainFrame;
。。。 CFrameWnd::LoadFrame
} CFrameWnd::LoadFrame
CFrameWnd::Create
CFrameWnd::Create
CWnd::CreateEx
::CreateWindowEx
::CreateWindowEx
触发WM_CREATE
BEGIN_MESSAGE_MAP(CMainFrame; CMDIFrameWnd)
BEGIN_MESSAGE_MAP(CMainFrame; CMDIFrameWnd)
ON_WM_CREATE()
ON_WM_CREATE()
。。。
。。。
END_MESSAGE_MAP()
END_MESSAGE_MAP()
CMainFrame::OnCreate
CMainFrame::OnCreate
窗口产生之际会发出WM_CREATE 消息,因此CMainFrame::OnCreate 会被执行起来,
那里将进行工具栏和状态列的建立工作(稍后描述)。LoadFrame 函数的参数(本例为
IDR_MAINFRAME ) 用来设定窗口所使用的各种资源, 你可以从前一页的
CFrameWnd::LoadFrame 源代码中清楚看出。这些同名的资源包括:
// defined in SCRIBBLE。RC
IDR_MAINFRAME ICON DISCARDABLE 〃resScribble。ico〃
IDR_MAINFRAME MENU PRELOAD DISCARDABLE { 。。。 }
IDR_MAINFRAME ACCELERATORS PRELOAD MOVEABLE PURE { 。。。 }
STRINGTABLE PRELOAD DISCARDABLE
BEGIN
IDR_MAINFRAME 〃Scribble Step0〃
(这个字符串将成为主窗口的标题)
。。
END
这种作法(使用LoadFrame 函数)与第6章的作法(使用Create 函数)不相同,请注意。
439
…………………………………………………………Page 502……………………………………………………………
第篇 湷觥 FC 程式設計
工具栏和状态列的诞生 (Toolbar & Status bar)
工具栏和状态列分别由CToolBar 和CStatusBar 掌管。两个对象隶属于主窗口,所以我
们在CMainFrame 中以两个变量(事实上是两个对象)表示之:
class CMainFrame : public CMDIFrameWnd
{
protected: // control bar embedded members
CStatusBar m_wndStatusBar;
CToolBar m_wndToolBar;
。。。
};
主窗口产生之际立刻会发出WM_CREATE,我们应该利用这时机把工具栏和状态列建立
起来。为了拦截WM_CREATE,首先需在Message Map 中设定「映射项目」:
BEGIN_MESSAGE_MAP(CMyMDIFrameWnd; CMDIFrameWnd)
ON_WM_CREATE()
END_MESSAGE_MAP()
ON_ WM_CREATE 这个宏表示,只要WM_CREATE 发生,我的OnCreate 函数就应该被
调用。下面是由AppWizard 产生的OnCreate 标准动作:
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CMDIFrameWnd::OnCreate(lpCreateStruct) == …1)
return …1;
if (!m_wndToolBar。Create(this) ||
!m_wndToolBar。LoadToolBar(IDR_MAINFRAME))
{
TRACE0(〃Failed to create toolbarn〃);
return …1; // fail to create
}
if (!m_wndStatusBar。Create(this) ||
!m_wndStatusBar。SetIndicators(indicators;
sizeof(indicators)/sizeof(UINT)))
{
TRACE0(〃Failed to create status barn〃);
return …1; // fail to create
}
440
…………………………………………………………Page 503……………………………………………………………
第7章 簡單而完整:MFC 骨幹程式
// TODO: Remove this if you don't want tool tips or a resizeable toolbar
m_wndToolBar。SetBarStyle(m_wndToolBar。GetBarStyle() |
CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC);
// TODO: Delete these three lines if you don't want the toolbar to
// be dockable
m_wndToolBar。EnableDocking(CBRS_ALIGN_ANY);
EnableDocking(CBRS_ALIGN_ANY);
DockControlBar(&m_wndToolBar);
return 0;
}
其中有四个动作与工具栏和状态列的产生及设定有关:
m_wndToolBar。Create(this) 表示要产生一个隶属于this (也就是目前这个对象,
也就是主窗口)的工具栏。
m_wndToolBar。LoadToolBar(IDR_MAINFRAME) 将RC 档中的工具栏资源载
入。IDR_MAINFRAME 在RC 档中代表两种与工具栏有关的资源:
IDR_MAINFRAME BITMAP MOVEABLE PURE 〃RESTOOLBAR。BMP〃
IDR_MAINFRAME TOOLBAR DISCARDABLE 16; 15
BEGIN
BUTTON ID_FILE_NEW
BUTTON ID_FILE_OPEN
BUTTON ID_FILE_SAVE
SEPARATOR
BUTTON ID_EDIT_CUT
BUTTON ID_EDIT_COPY
BUTTON ID_EDIT_PASTE
SEPARATOR
BUTTON ID_FILE_PRINT
BUTTON ID_APP_ABOUT
END
LoadToolBar 函数一举取代了前一版的LoadBitmap + SetButtons 两个动作。
LoadToolBar 知道如何把BITMAP 资源和TOOLBAR 资源搭配起来,完成工具栏的
设定。当然啦,如果你不是使用VC++资源工具来编辑工具栏,BITMAP 资源和
TOOLBAR 资源就可能格数不符,那是不被允许的。TOOLBAR 资源中的各ID 值就
441
…………………………………………………………Page 504……………………………………………………………
第篇 湷觥 FC 程式設計
是菜单项目的子集合,因为所谓工具栏就是把比较常用的菜单项目集合起来以按钮
方式提供给使用者。
m_wndStatusBar。Create(this) 表示要产生一个隶属于this 对象(也就是目前这个
对象,也就是主窗口)的状态列。
m_wndStatusBar。SetIndicators(;。。。) 的第一个参数是个数组;第二个参数是数组
元素个数。所谓Indicator 是状态列最右侧的「指示窗口」,用来表示大写键、
数字键等的On/Off 状态。AFXRES。H 中定义有七种indicators :
#define ID_INDICATOR_EXT 0xE700 // extended selection indicator
#define ID_INDICATOR_CAPS 0xE701 // cap lock indicator
#define ID_INDICATOR_NUM 0xE702 // num lock indicator
#define ID_INDICATOR_SCRL 0xE703 // scroll lock indicator
#define ID_INDICATOR_OVR 0xE704 // overtype mode indicator
#define ID_INDICATOR_REC 0xE705 // record mode indicator
#define ID_INDICATOR_KANA 0xE706 // kana lock indicator
本例使用其中三种:
static UINT indicators '' =
static UINT indicators '' =
{{
ID_SEPARATOR; // status line indicator
ID_SEPARATOR; // status line indicator
ID_