亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

WTL介紹

系統 2309 0

WTL簡單介紹

關鍵詞 :? WTL ??? ??????????????????????????????????????

WTL是一個好東東.它開發的程序都很短小精悍.對開發WIN32的應用有很好的優點.它不用MFC開發.但可以高速產生窗體和控件.

以文本方式查看主題

-?? 溫馨小筑 ??(http://www.learnsky.com/bbs/index.asp)
--?? 電腦編程 ??(http://www.learnsky.com/bbs/list.asp?boardid=6)
----?? WTL簡單介紹 ??(http://www.learnsky.com/bbs/dispbbs.asp?boardid=6&id=407)

WTL簡單介紹

vcmfc

? ? ? 在ATL出現的時候,一些部分COM的編程人員開始認為開發COM運用是一種快樂,由于使用它非常方便地開發小規模的COM組件,但好景不長,現實的COM組件是包羅相當廣泛的,特別當它們準備使用包裝我窗體控件,發現ATL提供了相當的稀少。因此Microsoft推出了半成品與沒有技術支持的WTL,這也是WTL誕生的原因。

? ? ? 非常多初次接觸WTL都問“WTL這三個字母代表什么呢?”:WTL全稱為Windows Template Library,構架于ATL之上,採用C++模板技術來包裝大部窗體控制,并給出一個與MFC類似的應用框架。

? ? ? ?他們緊跟著問“那我怎樣得到它呢?”:因為WTL是Microsoft推出的,在Microsoft的PlatForm SDK中就有,下面是部分畫面:

或者能過下面鏈接下載: http://msdn.microsoft.com/msdn-files/027/001/586/wtl31.exe

? ? ? 跟著問題又來了,“我該怎樣使用它們呢?”:在你安裝完了WTL SDK之后,在安裝文件夾中有一個AtlApp60.Awx的向導文件,將它復制到你安裝Visual C++的文件夾:Microsoft Visual Studio//common//mesdev98//bin//ide//文件夾下(實在不行使用Windows的搜索文件查找.awx),這是,在VC的應用程序向導里就有跟MFC類似的WTL應用程序向導。

? ? ? 假設你是MFC的使用者,你可能會再問“WTL與MFC在包裝窗體控制有哪些不同呢?”:我僅僅能用下面表格回答你:

Feature

MFC

WTL

Stand-alone library

Yes

No (built on ATL)

AppWizard support

Yes

Yes

Clazard support

Yes

No

Officially supported by Microsoft

Yes

No (Supported by volunteers inside MS)

Support for OLE Documents

Yes

No

Support for Views

Yes

Yes

Support for Documents

Yes

No

Basic Win32 & Common Control Wrappers

Yes

Yes

Advanced Common Control Wrappers (Flat scrollbar, IP Address, Pager Control, etc.)

No

Yes

Command Bar support (including bitmapped context menus)

No (MFC does provide dialog bars)

Yes

CString

Yes

Yes

GDI wrappers

Yes

Yes

Helper classes (CRect, Cpoint, etc.)

Yes

Yes

Property Sheets/Wizards

Yes

Yes

SDI, MDI support

Yes

Yes

Multi-SDI support

No

Yes

MRU Support

Yes

Yes

Docking Windows/Bars

Yes

No

Splitters

Yes

Yes

DDX

Yes

Yes (not as extensive as MFC)

Printing/Print Preview

Yes

Yes

Scrollable Views

Yes

Yes

Custom Draw/Owner Draw Wrapper

No

Yes

Message/Command Routing

Yes

Yes

Common Dialogs

Yes

Yes

HTML Views

Yes

Yes

Single Instance Applications

No

No

UI Updating

Yes

Yes

Template-based

No

Yes

Size of a statically linked do-nothing SDI application with toolbar, status bar, and menu

228KB +
MSVCRT.DLL (288KB)

24k (with /OPT:NOWIN98)
(+ MSVCRT.DLL if you use CString)

Size of a dynamically linked do-nothing SDI application with toolbar, status bar, and menu

24KB +
MFC42.DLL (972KB) +
MSVCRT.DLL (288KB)

N/A

Runtime Dependencies

CRT (+ MFC42.DLL, if dynamically linked)

None (CRT if you use CString)

? ? ? ?最后再說兩句。因為WTL不是Microsoft的正式產品,因此得不到Microsoft的技術支持,盡管有不少民間技術團體的支持,但這還不夠;關于WTL的技術文章相當的少,并且WTL使用C++的Template技術,這是一種相對較新的技術,無法與MFC混合使用,使用它須要又一次學習它,以致于相當少的人使用它。

?


--??作者:admin
--??公布時間:2005-1-11 2:11:00

--??

什么是WTL????? 選擇自 dairyman000 的 Blog??
keyword?? WTL ATL COM?
出處??? http://www.idevresource.com/com/library/bytesize/wtl.asp ?

簡單介紹
WTL 在開發人員之間的悄悄傳播已經超過一年了, 傳聞它是基于ATL的,并在微軟內部使用.這理所當然的引起了ATL開發人員社區的主意.這些人從ATL1.1開始,就一直為ATL控件書寫UI代碼,可是他們發現,他們的所寫的代碼經常就是純的Win32 GDI代碼.我告訴您, WTL并沒有多大不同.

是不是讓人失望? 不,由于ATL僅僅是對COM進行了簡單的封裝,這也是ATL的強大之處. 是的,寫ATL您必須通曉COM. 您在ATL上額外花費的功夫跟您學習COM所作的努力比起來,簡直微不足道.這跟那些須要把主要精力花費在學習類庫本身,忽略COM的庫是全然不同的.

WTL與此相似.您須要懂得Win32窗體技術和GDI.僅僅要您懂得,學習WTL就似清風撫面,再簡單只是了.假設您不懂 這些,那么您最好使用VB來寫UI代碼.

WTL有什么?

它給各種類型的應用程序提供了一個主要的框架.注意,盡管您沒有MFC那樣的文檔/視結構,可是您有視(views). 在WTL有大量的代碼讓您來管理視,并且增加您自己的代碼也非常easy.??WTL有AppWizard,能夠讓您生成SDI, MDI 和多線程SDI程序多線程SDI跟IE或Windows Explorer非常像.它看起來是打開了多個程序實例,實際上這些窗體都是屬于一個進程的).

另外,您的程序能夠是基于對話框的,也能夠是基于視的.視能夠是基于CWindowImpl的,也能夠是基于控件,甚至是IE里的一個HTML頁.您能夠選擇您的程序是否須要一個rebar, command bar (CE-like), toolbar 和/或status bar.另外,您的程序能夠主持ActiveX控件,以及成為一個COMserver.

這里有幾個關于視的選項. WTL提供splitter窗體類(這樣在一個視里您能夠有兩個窗體)和scroll窗體類(這樣您的窗體能夠比它顯示的"視"小). WTL也有個相似MFC的UpDateUI的東西,可是它們不是非常一樣 - 基本的差別是您須要把須要更新的項用宏映射標注出來,然后您在您的類里增加運行UpdateUI的代碼. DDX/DDV在WTL也支持,相同相似MFC,但有不同. 您必須加一個宏映射來實現DoDataExchange,然后增加調用它的代碼.

如今WTL也有GDI類了.然而,HDC的封裝類就像CWindow一樣,僅僅進行了非常easy的封裝 - 它差點兒沒有增加不論什么新的功能.只是,在WTL,你能夠得到播放meta文件和OpenGL支持. 最有價值的我猜應該是打印機DC的那些繼承類 - WTL有打印機支持,甚至打印預覽. 當然也有GDI對象的封裝. 諸如畫筆,畫刷,區域等.

WTL對全部的Win32 (和W2K) 通用對話框進行了封裝.相同雖然簡單,可是它的確使請求字體或者文件變的很的簡單.
合成了舊的AtlControls.h,新加了一些封裝類. 這些封裝類封裝了W2K控件,以及一些不屬于Win32的"控件",像Command Bar, bitmap button, hyperlink 和 wait cursor.

WTL 終于把消息分離帶入了ATL! 一些新的MSG映射宏將消息分離,調用您類里的消息處理函數.消息處理函數的參數的值是從消息分離得到的.唯一令人頭痛的是,您須要查看頭文件以確定函數參數的意義.

最后,WTL另一些有用類.最重要的是CString. 不錯,它是從MFC克隆得到的(copy on write),具有(在我知道的范圍內)MFC版本號的全部方法.還有查找文件的API的封裝類,以及CRect, CSize and CPoint.

總結

假設您打算寫一個Win32 界面程序,我建議您在考慮MFC之前,先試試WTL.使用WTL來寫您的代碼, 程序將變得小巧些,也更有效率些.使用WTL, 您還將得到ATL支持COM優點.而MFC沒有對COM的支持.
您能夠在2000年一月份的平臺SDK中找到WTL.在MSI選項頁的Source Code section下.


作者Blog: http://blog.csdn.net/dairyman000/


--??作者:admin
--??公布時間:2005-1-11 2:11:00

--??

WTL 體系結構

緒論

????? WTL 終于來了 , 并且提供了我所希望的功能 . 我在 WTL Bytesize ( 譯文 )的文章列出 WTL 主要特征 . 在本文中 , 我將描寫敘述一下 WTL 的體系結構 , 同一時候我會給出一些簡單的樣例來演示怎樣使用它的那些特征 . 希望可以對您有所幫助 .

WTL 應用程序的類型

???? WTL有好幾種應用程序類型,供您在AppWizard選取.

?

????下表對這些應用程序進行了描寫敘述. 這樣的彈性構成了WTL體系結構的一部分.

應用程序類型 描寫敘述
SDI Application 單文本界面 – 僅僅有一個窗體
Multiple Threads SDI 單個進程擁有一個或多個窗體
MDI Application 多文本界面 – 在框架內,您能夠有零個或多個子窗體
Dialog Based 基于對話框模版

????你可能還是首次聽說多線程SDI應用程序,可是不用操心,它的概念非常easy理解.一個多線程SDI程序啟動后它會有一個窗體, 窗體顯示了一個文檔. 當你想要程序要再創建一個文檔時,問題就出現了--SDI程序僅僅能顯示一個文檔.為了解決問題,多線程SDI創建了還有一個SDI窗體.看起來是一個新的實例在執行,實際上它只是是原來的進程創建了一個新的窗體,并把它依附到進程的一個新線程. IE的新建窗體就是這樣做的.

????除了多線程SDI,全部這些應用程序都能夠作為COMserver, 而且應用程序向導(AppWizard)為此提供了一個選項.另外應用程序向導還能夠讓你指定該程序是否主持ActiveX控件.令人費解的是,不同的程序類型,選取"Host ActiveX Controls"的地方不同.除對話框應用程序外的其它類型在第一頁上選取,而對話框類型卻放到第二頁.

????第二頁的其它選項,對對話框程序以外的類型都是可用的.它們讓你指定程序是否須要工具條(toolbar),狀態條(status bar)和視窗體(View Window).

????假設選取了"Toolbar"選項,你能夠通過"Rebar"選擇是否將工具條放入IE Rebar控件中. 假設你選取了Rebar, 你就能夠通過框架窗體(frame window)的成員m_hWndToolBar(后邊會有具體的描寫敘述)來訪問它.你能夠依照你的意愿,在里邊增加其它的工具條. 選取了"Rebar"后, 你能夠決定是否選取"Command Bar". Command bar非常像CE的command bar控件.僅僅是WTL是用一個類來實現,而在CE, command bar是一個系統窗體類(system window class). Command bar非常實用,它能夠把窗體也增加到工具條中去. 假設你選取了這個選項, 工具條和菜單都將被當做toolbar來實現.這使菜單項也能夠有關聯的圖標,而且當你移動鼠標到一個菜單項上時,該菜單項會被置成高亮.從Office 97以來, Office軟件的菜單都具有上述特征.

????第二頁還有指定程序是否使用視的選項(多半你想要使用), 同一時候你能夠決定這些視怎樣實現. 下表列出了全部可選的視.

描寫敘述
Generic Window 一個簡單的窗體. 此類窗體同意程序猿編寫WM_PAINT消息的處理函數. 適用于須要直接進行paint的文檔.
Form 這類視具有一個對話框模版.適用于帶ActiveX 控件的窗體. 應用程序來操作這些控件.
List Box 這個視是個list box.它最簡單的形式意味著能夠通過調用AddString() 方法來加入字符串.
Edit 這個視是個edit control. 本質上,它提供了一個像Notepad一樣的程序.
List View 這個視是個list view 通用控件.用這個控件來顯示相關的項(比方, 控制面板是一個Explorer主持的List View, 全部的項都是控制面板applet).
Tree View 這個視是個tree view 通用控件. 這個適用于具有層次關系的數據,比方,能夠用它來顯示數據庫的schema. 頂層分支為表和存儲過程,次級的分支為表中的字段.
Rich Edit 這個視是個rich edit 控件,像WordPad.
HTML Page 這個視主持了一個IE Web Browser 控件. 它把主持的一個web page當成一個視.

????本文的樣例須要一個對話框模版,同一時候還須要菜單,因此Form view是個理想的選擇.


--??作者:admin
--??公布時間:2005-1-11 2:14:00

--??

WTL體系結構

程序線程

????跟ATL一樣,WTL程序也須要一個 _Module 全局變量來保存全局數據,方便應用級代碼訪問.在WTL中,這個變量是 CAppModule CServerAppModule 的實例,后者在程序同一時候作為一個COMserver時用到.每一個應用程序具有一個或者多個UI線程.WTL使用兩種方式來管理這些線程.

????假設應用程序僅僅有一個UI線程(除了多線程SDI以外,其它程序類型默認僅僅有一個UI線程),線程調用全局函數 run() :

int Run(LPTSTR? /*lpstrCmdLine*/? = NULL, int nCmdShow = SW_SHOWDEFAULT)
{
????CMessageLoop theLoop;
????_Module.AddMessageLoop(&theLoop);
????CMainFrame wndMain;
????if (wndMain.CreateEx() == NULL)
????{
????????ATLTRACE(_T("Main window creation failed!//n"));
????????return 0;
????}
????wndMain.ShowWindow(nCmdShow);
????int nRet = theLoop.Run();
????_Module.RemoveMessageLoop();
????return nRet;
}

????線程的消息循環包括在 CMessageLoop 內部.函數創建了一個 CMessageLoop 實例, 把它放入全局的消息循環映射(message loop map)數組. 以線程ID為索引,線程中執行的其它的代碼能夠訪問到這個實例. 消息循環對象包括了message filter和idle handler. 執行在這個UI線程的UI元件(UI element)能夠有它自己的idle handler,在線程的消息隊列為空時執行 譯注:通過 CMessageLoop::AddIdleHandler() 把這個UI元件增加到 CMessageLoop 的idle handler 數組中 . ?CMessageLoop::Run() 包括了UI線程的主消息映射(main message map).下邊是它的偽代碼:

MSG m_msg;
int CMessageLoop::Run()
{
????for (;;)
????{
????????while (!::PeekMessage(&m_msg, NULL, 0, 0, PM_NOREMOVE))
????????????DoIdleHandlers();
????????bRet = ::GetMessage(&m_msg, NULL, 0, 0);
????????if(bRet == -1)
????????????continue;?
????????else if(!bRet)
????????????break;
????????if (!DoMessageFilters(&m_msg))
????????{
????????????::TranslateMessage(&m_msg);
????????????::DispatchMessage(&m_msg);
????????}
????}
????return (int)m_msg.wParam;
}


????能夠看到,這個函數推動著消息隊列. 沒有消息時, 執行注冊到線程的idle hander. 假設在隊列中檢測到消息,把它取出來,傳給每一個message filter. 假設消息沒有被這些函數處理,它將依照通常的方式,發送到目標窗體.

????假設程序有超過一個的UI線程,能夠用WTL的線程管理器,多線程SDI就是這樣做的. 主線程作為一個管理者線程,它會為每一個新窗體創建一個新的新線程. 主要流程例如以下:

int nRet = m_dwCount;
DWORD dwRet;
while(m_dwCount > 0)
{
????dwRet = ::MsgWaitForMultipleObjects(m_dwCount, m_arrThreadHandles,
????????FALSE, INFINITE, QS_ALLINPUT);
????if(dwRet >= WAIT_OBJECT_0 && dwRet <= (WAIT_OBJECT_0 + m_dwCount - 1))
????????RemoveThread(dwRet - WAIT_OBJECT_0);
????else if(dwRet == (WAIT_OBJECT_0 + m_dwCount))
????{
????????::GetMessage(&msg, NULL, 0, 0);
????????if(msg.message == WM_USER)
????????????AddThread(_T(""), SW_SHOWNORMAL);
????}
}


那些線程句柄放在一個數組中. 線程通過 AddThread() 增加到數組(同一時候啟動線程),? RemoveThread() 從數組移走. wait語句在兩種情況下會被打斷: 線程死亡(將線程從數組中移出) 或線程收到了 WM_USER 消息(一個線程在一個新線程里新建了一個窗體). 線程管理者為程序中的一個類,因此能夠在循環中增加自己的message handler, 比方,當程序有不止一種窗體類型時. 創建一個新的窗體非常easy,僅僅需在隨意一個窗體中調用:

: :PostThreadMessage(_Module.m_dwMainThreadID, WM_USER, 0, 0L);

這個循環會一直執行下去,直到全部的UI線程都關閉了. UI線程具有一個thread procedure,它跟單UI線程的Run()方法一樣.只是,因為線程管理者使用了 MsgWaitForMultipleObjects() , 這意味者最多僅僅能有 MAXIMUM_WAIT_OBJECTS -1個UI線程,這也意味著最多僅僅能創建63個窗體.?

框架

????WTL實際上是兩類窗體: 框架窗體和視圖窗體. 正如名字所暗示的那樣, 框架窗體為窗體提供標題欄(caption bar)和邊框,你的代碼用它來處理工具條(tool bar)和菜單項命令.你看到的程序窗體實際上是視圖窗體, 視圖覆蓋了框架窗體的客戶區.客戶區是指框架窗體沒有被諸如狀態條,工具條之類的修飾部件所遮擋的部分.

????線程會創建主框架窗體的一個實例,創建視圖的工作由主框架窗體的 WM_CREATE 消息處理函數完畢. 對于SDI程序來說,這個過程非常easy. 把視圖類的一個實例作為主框架類的一個成員,調用視圖類的 Create() 方法就可以.MDI程序略微有些不同, MDI主框架窗體通過 CMDIFrameWindowImpl<>::CreateMDIClient() 建立一個名為 MDICLIENT 的窗體. 這個客戶窗體將 CMDIChildWindowImpl<> 窗體當做它的子窗體,子窗體有一個視圖.這也反映了這么一個事實,MDI程序能夠具有零個或者多個子窗體,每一個都有邊框和標題欄.

框架窗體的OnCreate()非常有意思,讓我看看:

LRESULT OnCreate(UINT, WPARAM, LPARAM, BOOL&)
{
???? // create command bar window
????HWND hWndCmdBar = m_CmdBar.Create(m_hWnd, rcDefault,
????????NULL, ATL_SIMPLE_CMDBAR_PANE_STYLE);
???? // attach menu
????m_CmdBar.AttachMenu(GetMenu());
???? // load command bar images
????m_CmdBar.LoadImages(IDR_MAINFRAME);
???? // remove old menu
????SetMenu(NULL);
????HWND hWndToolBar = CreateSimpleToolBarCtrl(m_hWnd, IDR_MAINFRAME,
????????FALSE, ATL_SIMPLE_TOOLBAR_PANE_STYLE);
????CreateSimpleReBar(ATL_SIMPLE_REBAR_NOBORDER_STYLE);
????AddSimpleReBarBand(hWndCmdBar);
????AddSimpleReBarBand(hWndToolBar, NULL, TRUE);
????CreateSimpleStatusBar();
????m_hWndClient = m_view.Create(m_hWnd, rcDefault, NULL,
????????WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN,
????????WS_EX_CLIENTEDGE);
????UIAddToolBar(hWndToolBar);
????UISetCheck(ID_VIEW_TOOLBAR, 1);
????UISetCheck(ID_VIEW_STATUS_BAR, 1);
????CMessageLoop* pLoop = _Module.GetMessageLoop();
????pLoop->AddMessageFilter(this);
????pLoop->AddIdleHandler(this);
????return 0;
}

????這是從一個SDI程序拿來的一段代碼,該程序有一個基于command bar的工具條和一個狀態條. 函數的第一行創建了一個command bar實例,然后對它進行初始化,在當中增加框架窗體的菜單和工具條位圖. 這段代碼先將菜單取出,把全部的下拉菜單轉換為工具條button,并將菜單保存在一個變量中,以備后用. 給人的感覺是菜單是由工具條實現的-那我們就把它叫做工具條菜單(menu toolbar)吧. 然后Command Bar將程序工具條的圖標裝入image list 并將它們的ID保存在數組中. 當點擊工具條菜單的button時,commandbar會找到相應的子菜單,創建一個彈出菜單. Command bar將子菜單項的ID和它保存的ID進行比較,這些ID跟image list中的工具條button圖標是相關聯的. 假設比較成功, 則將關聯的圖標加到菜單項上去. 這意味著同樣ID的菜單項和工具條button具有同樣的圖標.

接下來, 創建工具條并把它關聯到commandbar, 然后創建狀態條和視圖.能夠看到視圖的 HWND 存放在框架窗體的 m_hWndClient 變量中. 這個窗體句柄在框架窗體的 WM_SIZE ?handler中會用到.當框架窗體改變大小時,它告知視圖改變自身,于此同一時候也要考慮狀態條和command bar.?

在下來的三行(從調用 UIAddToolBar() 開始) 用來顯示在執行時會改變狀態的UI項(UI item).文章后面還會重提這個話題. 最后,訪問消息循環(message loop), 你應該還記得該消息循環存放在一全局數組中. ?GetMessageLoop() ?取得當前線程的消息循環,增加框架窗體的message filter和idle handler, 分別默認是 PreTranslateMessage() OnIdle() .

框架窗體繼承于下面類:

class CMainFrame :?
????public CFrameWindowImpl<CMainFrame>,?
????public CUpdateUI<CMainFrame>,?
????public CMessageFilter,?
????public CIdleHandler


后兩個抽象類宣稱了框架窗體類實現了 PreTranslateMessage() OnIdle() . 從 CUpdateUI<> 繼承表示框架類支持UI update map.


--??作者:admin
--??公布時間:2005-1-11 2:15:00

--??

WTL體系結構

視圖

視圖窗體看起來顯得非常easy:

class CMyView : public CWindowImpl<CMyView>
{
public:
????DECLARE_WND_CLASS(NULL)
????BOOL PreTranslateMessage(MSG* pMsg)
????{
????????pMsg;
????????return FALSE;
????}
????BEGIN_MSG_MAP(CMyView)
????????MESSAGE_HANDLER(WM_PAINT, OnPaint)
????END_MSG_MAP()
????LRESULT OnPaint(UINT, WPARAM, LPARAM, BOOL&)
????{
????????CPaintDC dc(m_hWnd);
???????? //TOD Add your drawing code here
????????return 0;
????}
};


上面是一個SDI程序的視圖類. 多線程SDI和MDI的視圖類在本質上也跟這個一樣,但他們沒有 PreTranslateMessage() 方法. SDI程序就是使用這個函數,趕在框架類處理消息之前把消息抓住.? PreTranslateMessage() 在SDI的框架類中的實現是,直接將消息轉發給視圖類.?

這里顯示的視圖實際上沒有做什么工作.你應該自己在 OnPaint() 函數中增加畫出文檔內容的代碼.假設須要支持輸入,如鼠標的點擊和鍵盤的按鍵,你應該增加對應消息處理函數到類和映射中. 能夠看到這個窗體是從 CWindowImpl <> 繼承下來的,假設你想讓它基于一個Win32控件的話,就應該從定義在AtlCtrls.h文件里某個WTL類繼承.

假設想在基于 CWindowImpl<> 的類里加上滾動欄,那么你應該把基類換成 CScrollWindowImpl<> ,同一時候把消息鏈給它:

class CMyView : public CScrollWindowImpl<CMyView>
{
public:
????typedef CScrollWindowImpl<CMyView> parent;
????BEGIN_MSG_MAP(CMyView)
????????CHAIN_MSG_MAP(parent)
????END_MSG_MAP()
????void DoPaint(CDCHandle dc)
????{
????}
};

基類保證窗體具備滾動欄,并提供滾動欄消息的默認處理.視圖類不再有 WM_PAINT 的處理函數,由于它已被 CScrollWindowImpl<> 處理.依據滾動欄的位置, CScrollWindowImpl<> 畫出視圖相相應的部分. 取而代之的是,在你的類里實現 DoPaint() ,在這里你須要畫出整個視圖.假設你想指定滾動的范圍,大小或起點,你須要加上處理 WM_CREATE 消息的函數,把這些初始化代碼放到里邊.

正如我先前所提到的,框架窗體會改變視圖窗體的大小,以使它客戶區未被狀態條和工具條覆蓋的部分為視圖所填充. 在大多數情況下,這樣就夠了.可是當你想要一個具有Windows Explorer樣子的程序時,該怎么辦呢? Windows Explorer的窗體包括了一個tree view 和一個list view,還有兩者之間的切割條. WTL的解決方式非常easy:使用splitter窗體!

為此你須要改變一下框架窗體,讓它創建splitter窗體的一個實例作為它的視圖. 比如, 在你的框架類里有例如以下的數據成員:

CSplitterWindow m_view;
CTreeViewCtrl m_tree;
CListViewCtrl m_list;


你能夠在 OnCreate() 創建一個splitter窗體:

// get the frame client rect, so that we set the splitter initial size
// and we can get the splitter bar in the centre
RECT rect;
GetClientRect(&rect);
m_hWndClient = m_view.Create(m_hWnd, rect,
????NULL, WS_CHILD | WS_VISIBLE);
m_tree.Create(m_view, rcDefault, NULL,
????WS_CHILD | WS_VISIBLE | TVS_HASBUTTONS | TVS_HASLINES | TVS_LINESATROOT,
????WS_EX_CLIENTEDGE);
m_list.Create(m_view, rcDefault,
????NULL, WS_CHILD | WS_VISIBLE | LVS_REPORT, WS_EX_CLIENTEDGE);
m_view.SetSplitterPanes(m_tree, m_list);
m_view.SetSplitterPos();


Splitter窗體如同一個視圖,將框架窗體作為它的父窗體. 在這段代碼里,我將框架窗體客戶區的實際大小傳給了splitter窗體. 我也能夠在這里使用? rcDefault ,由于一旦框架窗體創建完畢,框架窗體就會轉發 WM_SIZE 消息給splitter. 這樣splitter能夠立即改變自身的大小來填充框架. 然而,當我準備使用不帶參數的 SetSplitterPos() ,把切割條設置于窗體中線時,出現了問題.Splitter窗體使用它的大小來決定中線的位置,由于 rcDefault 告訴窗體它的大小是0(因此中線的位置也是0),從而意味著切割條將出如今z最左邊,將左窗體隱藏了起來.

創建了splitter窗體后,你須要創建那些你想要切割的窗體了.它們將作為splitter窗體的子窗體被創建.最后你將這些子窗體通過 SetSplitterPanes() 加到splitter窗體中去,并確定切割條的位置所在.

UI Update

菜單項能夠被設置為有效或無效,能夠帶check記號或著像radiobutton一樣,在一組菜單項中同一時候有且僅僅有一個能被check.此外,菜單項還能夠帶圖標和文字. 全部的這些狀態都能夠在執行時依據程序中的某個值進行改變.工具條在某種程度上能夠看做是菜單的易見形態,由于它們的button能夠個別地,或者作為一組的一部分被置成有效或無效,推入推出. UI update機制同意你指定哪些UI元件(UI element)的狀態能夠在執行時改變. WTL使用例如以下的UI update映射來實現這一功能:

BEGIN_UPDATE_UI_MAP(CMainFrame)
????UPDATE_ELEMENT(ID_FILE_SAVERESULTS, UPDUI_MENUPOPUP | UPDUI_TOOLBAR)
????UPDATE_ELEMENT(ID_VIEW_TOOLBAR, UPDUI_MENUPOPUP)
????UPDATE_ELEMENT(ID_VIEW_STATUS_BAR, UPDUI_MENUPOPUP)
END_UPDATE_UI_MAP()

這個樣例指出三個菜單項在執行時有一個狀態須要顯示,當中的一個, ID_FILE_SAVERESULTS,另一個工具條button跟它相關聯. WTL通過建立一個數組來保存這些信息.為此你須要完畢雙方面的工作:

首先是UI元件的狀態. 假設是菜單項, 你能夠使用 UIEnable() 使能該菜單項,? UISetCheck() 設置check記號,? UISetText() 改變菜單的文字.假設是工具條button,那么你使用 UIEnable() 使能該button,? UISetCheck() 或者 UISetRadio() 決定button是推入還是推出.下邊的代碼依據是否有文本被選中,來使能Cut菜單項和工具條button:

BOOL bSelected = GetSelected();
UIEnable(ID_EDIT_CUT, bSelected);


你能夠把這種代碼放入對應處理函數中(如一個菜單項的狀態依賴于另一個菜單項的動作,將它放入后者的處理函數中),或者放入 OnIdle() 方法,通過檢查某個類變量來決定元件的狀態.

其次是確定各個UI元件是否都被更新了,為此你須要調用 CUpdateUI<> 的某個 方法將UI元件增加到列表中.主菜單已被自己主動增加,可是其它的不論什么菜單和全部的工具條必須分別通過調用 UIAddMenuBar() UIAddToolBar() 手動增加.

其它另一堆事情要注意. 首先,設置了工具條的狀態后,使用 UIUpdateToolBar() 以使工具條狀態更新. 對于菜單,你不需如此,由于子菜單是動態生成的 . UIUpdateMenuBar() 這種方法也存在,可是它的作用是把菜單恢復到初始狀態,假設你改變過某些項的文字, 調用 UIUpdateMenuBar() 的結果可能不是你所期望的(由于菜單項的文字會變成老的).?

雖然另一個方法 UISetRadio() ,可是還沒有一個把幾個菜單項或者工具條button當做radiobutton組(也就是說,有一個并且僅僅有一個被選中)的機制.假設你希望得到這樣效果,你必須自己編碼,只是它并不難.


--??作者:admin
--??公布時間:2005-1-11 2:16:00

--??

WTL體系結構

對話框
ATL的對話框支持一向非常好,對此WTL新增了通用對話框的封裝. 本質上是為對話框增加了輸入驗證和回調函數. 比方, 你想在用戶改變年Open對話框中的目錄時有所動作,那么你應該從 CFileDialogImpl<> 繼承一個類,實現 OnFolderChange() :

class CMyFileDialog : public CFileDialogImpl<CMyFileDialog>
{
public:
????CMyFileDialog(BOOL b)?
????????: CFileDialogImpl<CMyFileDialog>(b) { }
????void OnFolderChange(LPOFNOTIFY lpon)
????{
????????char strFolder[MAX_PATH];
????????if (GetFolderPath(strFolder, sizeof(strFolder)) > 0)
????????{
????????????MessageBox(strFolder);
????????}
????}
};

當目錄的路徑改變時, CFileDialogImpl<> 調用 OnFolderChange() .該函數使用基類的 GetFolderPath() ,來取得新路徑.

控件

WTL為全部的Win32和通用控件提供了封裝類,包含Windows 2000新增加的. 盡管僅僅是簡單的包裝,可是它們使這些控件更加easy訪問.譬如,你能記清楚從List View讀出當前選定項的文字的消息和須要傳的參數嗎?(實際上, 你須要發送兩個消息, 一個是得到選定項的索引,還有一個是讀出它的文字.) WTL的作者為你完畢了這些煩人的工作, 提供了一個簡單的封裝函數供你使用.

使用這些控件類有兩種方法. 假設你的對話框里有一個控件, 你能夠將控件的 HWND 依附到一個封裝對象,使用封裝類的方法來訪問控件.這樣的方法簡化了你讀寫控件數據和處理 notification 消息的代碼.?

另外的使用方法是把這些類加到你的視圖類的繼承層次中去:

class CMyView : public CWindowImpl<CMyView, CListBox>

這表示 CWindowImpl<> CListBox 繼承而來,因此創建的窗體將是一個list box (由于窗體類的名字是通過調用?
CListBox::GetWndClassName() 得到的). 另外, ATL的窗體機制會子類化這個窗體,將發給它的消息路由到你的消息映射中去. 它保留了老的窗體函數,這樣,你沒有處理的消息將由老的窗體函數來處理.當你的視圖類從控件類繼承時,WTL就會使用這一技術.

在notification消息和子類化這個主題上,有一點非常值得指出,那就是當某事件發生時,絕大多數窗體控件都會發送notification消息給它們的父窗體.讓你窗體來處理這些 notification 消息要比子類化一個已存在控件窗體(或子類化一個已存在的類,然后建立一個實例),從而在控件之前取得消息好得多. 譬如, 你想處理button的click事件,你所須要做的僅僅是處理 BN_CLICKED ? notification .它將由button發送給你的窗體類.另外的一種方法是從 CContainedWindow<> 子類化BUTTON窗體來處理 click 消息.?

我之所以說這個是由于一個知名的ATL鼓吹者給我一份代碼里就是這么做的.他的代碼取得一個簡單的button click 事件所花的時間是別人的3到4倍,由于他子類化了button控件,而不是簡單的處理 BN_CLICKED ? notification .

WTL還提供了一些新的控件,在win32中沒有對等者. 你已經看到過一個 -- command bar, 實際上還有其它一些非常實用類:

?

類?? 描寫敘述
CBitmapButton 這是一個用位圖替代標題的button.你能夠提供一個image list,里邊包括button在正常狀態,失效, 推入和鼠標落在button上的圖表.
CHyperLink 讓你建立一個static控件,它代表一個hyperlink,這樣當用戶點擊它時,默認的web瀏覽器打開該鏈接.
CWaitCursor 這只是是在它的構造函數中把鼠標圖標改成等待狀態,而在析構函數中還原.
CCheckListViewCtrl 在每一項邊上都有一個check box的list box.
CMultiPaneStatusBarCtrl 具有多個pane的狀態條

?


?

WTL介紹


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 成人影院vs一区二区 | 日韩一级特黄毛片在线看 | 91年精品国产福利线观看久久 | 成人一级毛片 | 毛片一级在线观看 | 一级一片免费播放 | 天天搞天天搞 | 自拍偷自拍亚洲精品被多人伦好爽 | 69视频在线观看福利视频 | 中文字幕91在线 | 免费观看国产网址你懂的 | 成年午夜性视频免费播放 | 四虎影院最新 | 95视频在线观看在线分类h片 | 久青草视频在线播放 | 亚洲一区二区三区精品影院 | 很黄很色的免费视频 | 成人免费视频网 | 亚洲一区二区三区高清视频 | 中文字幕久久久久一区 | 夜夜爽66| 国产亚洲精品久久久久久久网站 | 免费高清在线爱做视频 | 久久91精品国产一区二区 | 草操影院 | 日韩欧美 在线播放 | 天天操操 | 国产成人精品影院狼色在线 | 久久99国产综合精品 | 美国免费三片在线观看 | 国产视频一区二区在线播放 | 久久99国产亚洲精品观看 | 色片网| 91精品国产自产91精品 | 一级片成人 | 亚洲综合色丁香麻豆 | 四虎影院新网址 | 久久伦理片| 天天做夜夜爽 | 日本一级在线播放线观看视频 | 久久婷婷网 |