程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> VC >> 關於VC++ >> 初識WTL(上)

初識WTL(上)

編輯:關於VC++

代碼運行效果圖如下:

1.前言

雖然MFC的功能很強大,但Windows Template Library(WTL)的出現,無疑說明了MFC有一定的弊病。和MFC相比,功能並沒有MFC完善。比如MFC支持doc/view架構,而WTL並不支持。同時,WTL也沒有Microsoft的官方支持。但是,WTL是基於模版(template)的,其應用程序最小只有24KB,同時不象MFC,依賴DLL。但是WTL也實現了CString、CRect、CSize、CPoint等常用的類,還CStaticT<TBase>、CButtonT<TBase>、CListBoxT<TBase>、CComboBoxT<TBase>(這些在WTL庫文件atlctrls.h、atlctrlw.h、atlctrlx.h中就能看到)等用起來和MFC版本也沒太大不同。

2.准備工作

首先安裝WTL AppWizard,現在最高版本應該是WTL7.0,直接運行setup腳本文件就可以了

這樣當你啟動VC6.0後,File/New時,在Project屬性頁就能看到添加了一項ATL/WTL AppWizard。你可以直接把WTL的庫文件( 共16個.h文件)拷貝到vc的安裝目錄VC98/Include中,也可以放到你的工程文件夾中。

3.應用實例1---SDI中狀態欄的應用

(1) File/New,如圖:

(2) OK後,

SDI(Single Document Interface)應用程序通常只有一個主窗口(通常是一個框架窗口,Frame Window)。框架窗口包含菜單、工具欄、狀態欄和稱為視(View)的客戶工作區。

Multip-SDI(Multiple Threads SDI),就像IE浏覽器,使用"文件/新建/窗口"命令後,會出現另一個IE窗口。

MDI(Multiple Document Interface)應用程序有一個主框架窗口,但有多個子框架窗口。每個子窗口都有自己的視(View),和MFC的相似。

Dialog應用程序是基於對話框的。

(3) Next

(4) 在產生的文件中可以看到WTL確實不支持Doc/View.

WTL對單界面線程的封裝:WTL使用一個_Module全局變量來保存全局數據,並通過它來引用應用程序級的代碼。在WTL中,該變量是CAppModule的實例,想象MFC的theApp。

●下面對MyTestWTL.cpp文件中的函數作一些說明:

Ⅰ:

int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE /*hPrevInstance*/, LPTSTR lpstrCmdLine, int nCmdShow)
{
  HRESULT hRes = ::CoInitialize(NULL);
  // If you are running on NT 4.0 or higher you can use the following call instead to
  // make the EXE free threaded. This means that calls come in on a random RPC thread.
  // HRESULT hRes = ::CoInitializeEx(NULL, COINIT_MULTITHREADED);
  ATLASSERT(SUCCEEDED(hRes));
  // this resolves ATL window thunking problem when Microsoft Layer for Unicode (MSLU) is used
  ::DefWindowProc(NULL, 0, 0, 0L);
  AtlInitCommonControls(ICC_COOL_CLASSES | ICC_BAR_CLASSES);    // add flags to support other controls
  hRes = _Module.Init(NULL, hInstance);
  ATLASSERT(SUCCEEDED(hRes));
  int nRet = Run(lpstrCmdLine, nCmdShow);   //程序邏輯,調用全局函數Run()
  _Module.Term();   // 終止模塊
  ::CoUninitialize();
  return nRet;
}

入口函數名為_tWinMain()。當使用UNICODE時,編譯器會將它替換為wWinMain(),否則,為WinMain()。入口函數其實就是主線程(_Module)的起始點,這和SDK,MFC一個道理。一個_Module還維持一個消息循環Map。

Ⅱ:

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實例,該實例包含了這個線程的消息循環。這些消息循環都放在模塊的全局消息循環中,通過線程的ID來索引。這樣,該線程的其它代碼就能訪問得到。每一個應用程序維護一個消息循環隊列Map,應用程序中的每個線程都通過"_Module.AddMessageLoop(&theLoop)",把該線程的消息循環加入到_Module的消息循環Map中。消息循環對象包含了消息過濾和空閒處理。每個線程都可以加入空閒處理代碼和消息過濾。

● 添加代碼:

Ⅰ:在stdafx.h中添加:

#include <atlctrls.h>
#include <atlctrlx.h>
#include <atlctrlw.h>  //這三個是WTL 中實現常用控件類
#include <atldlgs.h>
#include <atlmisc.h>  //WTL 使用類像 CString等
#include <atlddx.h>  //WTL 使用像MFC中DDX/DDV 機制

Ⅱ:添加3個圖標資源:IDR_DEFAULT, IDR_DATE, IDR_TIME

Ⅲ:在MainFrm.h中添加 CMultiPaneStatusBarCtrl m_Mstatus;

Ⅳ:在MainFrm.cpp中添加

在函數最前面聲明兩個數組:

static int arrPanes[] = { IDR_DEFAULT, IDR_DATE, IDR_TIME };
static int arrWidths[] = { 450,200, 600 }; //你自己修改一下值看看有什麼不同

在OnCreate函數中添加:

CreateSimpleStatusBar();
m_Mstatus.SubclassWindow(m_hWndStatusBar);
m_Mstatus.SetPanes(arrPanes,sizeof(arrPanes)/sizeof(int), false);
m_Mstatus.SetPaneWidth(IDR_DEFAULT,400);
m_Mstatus.SetPaneWidth(IDR_DATE,200);
m_Mstatus.SetPaneWidth(IDR_TIME,900);
m_Mstatus.SetPaneIcon(IDR_DEFAULT,AtlLoadIconImage(IDR_DEFAULT, LR_DEFAULTCOLOR));
m_Mstatus.SetPaneIcon(IDR_DATE, AtlLoadIconImage(IDR_DATE, LR_DEFAULTCOLOR));
m_Mstatus.SetPaneIcon(IDR_TIME, AtlLoadIconImage(IDR_TIME, LR_DEFAULTCOLOR));
m_Mstatus.SetPaneText(IDR_DATE,"WTL is very wonderful!",0);
m_Mstatus.SetPaneText(IDR_TIME,"WWW.VCKBASE.COM",0);

這些代碼相信大家一看就會明白!

參考資料:

深入剖析WTL——Win32模型,作者:建新

WTL for MFC Programmers 作者:Michael Dunn

在此深表感謝

本文配套源碼

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved