深入剖析WTL框架(六)

 

WTL對框架窗口的封裝

ATL僅僅是封裝了窗口函數和提供了消息映射。實際應用中,需要各種種類的窗口,比如,每個界面線程所對應的框架窗口。WTL正是在ATL基礎上,爲我們提供了框架窗口和其他各種窗口。

所有的應用程序類型中,每個界面線程都有一個框架窗口(Frame)和一個視(View)。它們的概念和MFC中的一樣。

圖示是WTL的窗口類的繼承圖。

WTL框架窗口爲我們提供了:

一個應用程序的標題,窗口框架,菜單,工具欄。

視的管理,包括視的大小的改變,以便與框架窗口同步。

提供對菜單,工具欄等的處理代碼。

在狀態欄顯示幫助信息等等。

WTL視通常就是應用程序的客戶區。它通常用於呈現內容給客戶。

WTL提供的方法是在界面線程的邏輯中創建框架窗口,而視的創建由框架窗口負責。後面會介紹,框架窗口在處理WM_CREATE消息時創建視。

如果要創建一個框架窗口,需要:

從CFrameWindowImpl類派生你的框架窗口。

加入DECLARE_FRAME_WND_CLASS,指定菜單和工具欄的資源ID。

加入消息映射,同時把它與基類的消息映射聯繫起來。同時,加入消息處理函數。

下面是使用ATL/WTL App Wizard創建一個SDI應用程序的主框架窗口的申明。

class CMainFrame : public CFrameWindowImpl<CMainFrame>, 
public CUpdateUI<CMainFrame>,
		             public CMessageFilter, public CIdleHandler
{
public:
	DECLARE_FRAME_WND_CLASS(NULL, IDR_MAINFRAME)
     // 該框架窗口的視的實例
	CView m_view;
     // 該框架窗口的命令工具行
	CCommandBarCtrl m_CmdBar;
	virtual BOOL PreTranslateMessage(MSG* pMsg);
	virtual BOOL OnIdle();
	BEGIN_UPDATE_UI_MAP(CMainFrame)
		UPDATE_ELEMENT(ID_VIEW_TOOLBAR, UPDUI_MENUPOPUP)
		UPDATE_ELEMENT(ID_VIEW_STATUS_BAR, UPDUI_MENUPOPUP)
	END_UPDATE_UI_MAP()
	BEGIN_MSG_MAP(CMainFrame)
		MESSAGE_HANDLER(WM_CREATE, OnCreate)
		COMMAND_ID_HANDLER(ID_APP_EXIT, OnFileExit)
		COMMAND_ID_HANDLER(ID_FILE_NEW, OnFileNew)
		COMMAND_ID_HANDLER(ID_VIEW_TOOLBAR, OnViewToolBar)
		COMMAND_ID_HANDLER(ID_VIEW_STATUS_BAR, OnViewStatusBar)
		COMMAND_ID_HANDLER(ID_APP_ABOUT, OnAppAbout)
		CHAIN_MSG_MAP(CUpdateUI<CMainFrame>)
		CHAIN_MSG_MAP(CFrameWindowImpl<CMainFrame>)
	END_MSG_MAP()
// Handler prototypes (uncomment arguments if needed):
//	LRESULT MessageHandler(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, 
BOOL& /*bHandled*/)
//	LRESULT CommandHandler(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, 
BOOL& /*bHandled*/)
//	LRESULT NotifyHandler(int /*idCtrl*/, LPNMHDR /*pnmh*/, BOOL& /*bHandled*/)
	LRESULT OnCreate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& 
/*bHandled*/);
	LRESULT OnFileExit(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, 
BOOL& /*bHandled*/);
	LRESULT OnFileNew(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, 
BOOL& /*bHandled*/);
	LRESULT OnViewToolBar(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, 
BOOL& /*bHandled*/);
	LRESULT OnViewStatusBar(WORD /*wNotifyCode*/, WORD /*wID*/, HWND 
/*hWndCtl*/, BOOL& /*bHandled*/);
	LRESULT OnAppAbout(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, 
BOOL& /*bHandled*/);
};

DECLARE_FRAME_WND_CLASS()宏是爲框架窗口指定一個資源ID,可以通過這個ID和應用程序的資源聯繫起來,比如框架的圖標,字符串表,菜單和工具欄等等。

WTL視

通常應用程序的顯示區域分成兩個部分。一是包含窗口標題,菜單,工具欄和狀態欄的主框架窗口。另一部分就是被稱爲視的部分。這部分是客戶區,用於呈現內容給客戶。

視可以是包含HWND的任何東西。通過在框架窗口處理WM_CREATE時,將該HWND句柄賦植給主窗口的m_hWndClien成員來設置主窗口的視。

比如,在用ATL/WTL App Wizard創建了一個應用程序,會創建一個視,代碼如下:

class CTestView : public CWindowImpl<CTestView>
{
public:
	DECLARE_WND_CLASS(NULL)

	BOOL PreTranslateMessage(MSG* pMsg);

	BEGIN_MSG_MAP(CTestView)
		MESSAGE_HANDLER(WM_PAINT, OnPaint)
	END_MSG_MAP()

// Handler prototypes (uncomment arguments if needed):
//	LRESULT MessageHandler(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, 
BOOL& /*bHandled*/)
//	LRESULT CommandHandler(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, 
BOOL& /*bHandled*/)
//	LRESULT NotifyHandler(int /*idCtrl*/, LPNMHDR /*pnmh*/, BOOL& /*bHandled*/)
LRESULT OnPaint(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& 
/*bHandled*/);
};

這個視是一個從CWindowImpl派生的窗口。

在主窗口的創建函數中,將該視的HWND設置給主窗口的m_hWndClient成員。

LRESULT CMainFrame::OnCreate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, 
BOOL& /*bHandled*/)
{
    … …
	m_hWndClient = m_view.Create(m_hWnd, rcDefault, NULL, WS_CHILD | WS_VISIBLE 
| WS_CLIPSIBLINGS | WS_CLIPCHILDREN, WS_EX_CLIENTEDGE);
    … …
	return 0;
}

上述代碼爲主窗口創建了視。

到此爲止,我們已經從Win32模型開始,到了解windows界面程序封裝以及WTL消息循環機制,詳細分析了WTL。通過我們的分析,您是否對WTL有一個深入的理解,並能得心應手的開發出高質量的Windows應用程序?別急,隨後,我們還將一起探討開發WTL應用程序的技巧。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章