青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

笑看風云淡

寵辱不驚,看庭前花開花落;去留無意,望天空云卷云舒
posts - 96, comments - 48, trackbacks - 0, articles - 0
  C++博客 :: 首頁 :: 新隨筆 ::  :: 聚合  :: 管理

ATL的GUI程序設計(四)

Posted on 2007-10-17 10:42 天之驕子 閱讀(609) 評論(0)  編輯 收藏 引用
四章 對話框和控件

對于Win32 GUI的程序設計來說,其實大部分的情況下我們都不需要自己進行窗口類的設計,而是可以使用Win32中與用戶交互的標準方式——對話框(Dialog Box)。我們可以在VC IDE的資源設計器中設計對話框資源,并在其上放置各種控件資源——的確是非常方便。在本章里,李馬將要向諸位介紹如何利用ATL來操作對話框,以及如何操作對話框上的各種控件。

題外話先

ATL,是的,正是由于我所講的是“ATL的GUI程序設計”,所以我才可能將內容直接經由CWindowImpl過渡到CDialogImpl——而不是過渡到你先前所熟悉的CFrameWnd和Doc/View體系。況且,即使這之后我深入到了CDialogImpl之中,我也不會講到你所熟悉的DDX/DDV機制。再三考慮之下,我還是決定把這些東西在CDialogImpl前一并當作題外話說出來,先。

再來回顧一下ATL的性質。它是一個被設計用來開發COM組件的Framework,所以對GUI部分的支持——套用一句2006年的流行語來說:那是相~~當~~(加重且延長聲音地)少。于是,它沒有“框架窗口”這個概念,更不會有Doc/View體系。其實我對MFC的這一設計特點感覺不錯,畢竟它可以通過一個簡單的CFrameWnd類來實現一個標準的SDI/MDI框架,而且其中帶有工具欄、狀態欄和一個用來容納視圖的標準的工作區域。我們可以通過控制框架窗口中的View及其相關的Doc類型來完成特定文檔類型的讀寫與顯示。——但是,很不幸,這一切都只屬于偉大的MFC;在ATL中,我們什么都沒有。

另外,在對話框的技術領域中,使用ATL的我們也不會享有數據交換與驗證(DDX/DDV)的支持。這一所謂的缺憾我并不想多加評價,一是因為我并不了解MFC中DDX/DDV的內部機制,二是因為我直覺上認為這是影響MFC效率的罪魁之一。在MFC中,我們可以通過向導的支持輕易地為表單的輸入域加入輸入校驗與限制,而且表現在源代碼上的僅僅是幾個宏而已——我自認天下沒有免費的午餐,這幾個簡單的宏既然能為我們包辦一切,那我們勢必會相應地失去些東西,要不然忒便宜了也就。

題外話的最后不免落入俗套,我將會向諸位介紹解決以上缺憾的方法。——也許你猜到了,就是從WTL中尋找解決方案。WTL是對ATL的擴展,所以它的很多代碼可以直接拿過來用(當然可能需要一些小小的修改)。而且,不知道WTL的設計者是不是為了拉攏MFC的開發人員,總之它里面添加了很多與MFC相似的元素,例如以上所說的框架窗口和DDX/DDV。

CDialogImpl

與ATL窗口類CWindowImpl相對應,ATL的對話框類名為CDialogImpl。它的定義如下:

template <class T, class TBase = CWindow>
class ATL_NO_VTABLE CDialogImpl : public CDialogImplBaseT< TBase >
{
// ...
};

你可以從上面的代碼看到,CDialogImpl與CWindowImpl類似,也經歷了一系列的繼承鏈。不過,它較之CWindowImpl的模板參數要簡單得多——畢竟是標準對話框,有些東西是不用操心的。

CDialogImpl的使用方法大致如下:

class CYourDlg : public CDialogImpl< CYourDlg >
{
public:
enum { IDD = IDD_YOUR_DLG };
public:
BEGIN_MSG_MAP( CYourDlg )
// 消息映射
END_MSG_MAP()
public:
// 消息響應函數
///////////////////
// 其余的部分...
};

和CWindowImpl不一樣,CDialogImpl不需要使用DECLARE_WND_CLASS來定義窗口類。在原來DECLARE_WND_CLASS的位置,一個枚舉代替了原來窗口類定義的部分。這里的枚舉列表必須有一個被命名為IDD,并且它的值要被設置為相應的對話框資源ID。呃……寫到這里,我仿佛已經感覺到了你的不快,但CDialogImpl的實現即是如此(以CDialogImpl::DoModal為例):

// from CDialogImpl::DoModal
return ::DialogBoxParam(_Module.GetResourceInstance(), MAKEINTRESOURCE(T::IDD),
hWndParent, (DLGPROC)T::StartDialogProc, dwInitParam);

當然,如果你不喜歡這么做的話,也可以自己從CDialogImplBaseT派生出屬于你的對話框類。

再回到CDialogImpl的話題上來。這個類主要有以下幾個常用的成員函數:

成員函數 說明
DoModal 顯示一個模態對話框
EndDialog 銷毀一個模態對話框
Create 創建一個非模態對話框
DestroyWindow 銷毀一個非模態對話框

這樣看來是不是和MFC十分相似?事實上,如果你已經定義好了一個對話框類,那么它的使用和MFC的對話框類的確沒什么兩樣:

CYourDlg dlg;
dlg.DoModal();

控件的使用

從與用戶交互的角度來看,控件是對話框上必不可少的元素。在Win32 GUI程序設計中,對控件的操作大可歸為兩個方面:一是對控件進行操作,二是響應控件的事件。排除子類化的事件響應(后面我會專門介紹如何在ATL中進行控件的子類化),那么這兩方面的具體實現就是:

  • 使用窗口操作的API函數或發送消息來操作控件。
  • 處理WM_COMMAND或WM_NOTIFY來響應控件的事件。

根據順序,李馬來為大家介紹一下如何對控件進行操作先。這通常可以經由CWindow及其派生類實現,以下代碼示范了如何禁用一個控件:

CWindow ctrl = GetDlgItem( IDC_CONTROL );
ctrl.EnableWindow( FALSE );

如果你要操作的控件需要用到特定的特性(也就是通過發送消息來實現的特有行為),當然你可以通過使用CWindow::SendMessage來實現,不過我并不推薦你使用這種方法,因為SendMessage是不會對消息參數進行類型檢查的。而且,考慮到代碼的可復用性,你可以對CWindow進行派生以達到目的。例如,對于列表控件的封裝可以是類似下面這個樣子:

class CListBox : public CWindow
{
public:
int AddString( LPCTSTR lpszString )
{
return ::SendMessage( m_hWnd, LB_ADDSTRING, 0, (LPARAM)lpszString );
}
};

然后,這樣進行調用:

CListBox list;
list.Attach( GetDlgItem( IDC_LIST ) );
list.AddString( _T("This is a test line") );

可能你會有所疑問:為什么CWindow的例子直接使用了“=”來進行賦值,而CListBox則要使用Attach來初始化。當然,其實這兩者并沒有實質上的區別,只不過是CWindow重載了operator=操作符,而CListBox沒有這樣做罷了(嚴格說來,派生自CWindow的CListBox當然繼承了CWindow的operator=,但是它并不能用于CListBox對象,如果強行使用則會得到一個“error C2679: binary '=' : no operator defined which takes a right-hand operand of type 'struct HWND__ *' (or there is no acceptable conversion)”的錯誤)。如果你也希望CListBox支持operator=的初始化方式,可以這樣來對CListBox進行封裝:

class CListBox : public CWindow
{
public:
CListBox& operator=( HWND hWnd )
{
m_hWnd = hWnd;
return *this;
}
public:
int AddString( LPCTSTR lpszString )
{
return ::SendMessage( m_hWnd, LB_ADDSTRING, 0, (LPARAM)lpszString );
}
};

下面來介紹對控件事件的處理。通常控件在某些事件發生時會以發送WM_COMMAND(普通控件)或WM_NOTIFY(公共控件)消息的方式通知其父窗口,然后我們在其父窗口的窗口過程中處理這些消息即可。WM_COMMAND和WM_NOTIFY的參數意義如下:

  WM_COMMAND WM_NOTIFY
wParam HIWORD(wParam)為通知消息代碼,LOWORD(wParam)為控件ID 發生通知消息的控件ID,不過仍建議使用lParam參數中的ID
lParam 發生通知消息的控件句柄 一個指向NMHDR結構的指針,這個結構中包含了通知消息的各種信息

在ATL中,可以使用如下的宏來進行各種消息的分流(在此將Windows消息分流的宏也一并加上):

消息分流宏 說明
MESSAGE_HANDLER 用于將某個特定消息分流至一個消息處理函數。
MESSAGE_RANGE_HANDLER 用于將某個范圍內的消息一并分流至同一個消息處理函數。
COMMAND_HANDLER 用于將來自特定ID、特定通知碼的WM_COMMAND消息分流至一個消息處理函數。
COMMAND_ID_HANDLER 用于將來自特定ID的WM_COMMAND消息分流至一個消息處理函數。
COMMAND_CODE_HANDLER 用于將來自特定通知碼的WM_COMMAND消息分流至一個消息處理函數。
COMMAND_RANGE_HANDLER 用于將來自某個ID范圍內的WM_COMMAND消息分流至一個消息處理函數。
NOTIFY_HANDLER 用于將來自特定ID、特定通知碼的WM_NOTIFY消息分流至一個消息處理函數。
NOTIFY_ID_HANDLER 用于將來自特定ID的WM_NOTIFY消息分流至一個消息處理函數。
NOTIFY_CODE_HANDLER 用于將來自特定通知碼的WM_NOTIFY消息分流至一個消息處理函數。
NOTIFY_RANGE_HANDLER 用于將來自某個ID范圍內的WM_NOTIFY消息分流至一個消息處理函數。

另外,處理Windows消息、WM_COMMAND消息、WM_NOTIFY消息的消息處理函數應該分別滿足如下規格要求:

// atlwin.h
// Handler prototypes:
// 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);

李馬牌通訊錄管理系統

別誤會,這并不是什么正兒八經的所謂“信息管理系統”,而只是我為本章寫下的一個簡單示例而已。這里面并不涉及數據的存儲,而只是為演示本章的內容而實現了必要的流程而已。在此李馬并不打算對這個程序的代碼進行過多解說,僅僅點出幾點需要特殊說明的。

  1. 由于程序中使用了公共控件ListView,所以在WinMain的開頭需要對公共控件庫進行初始化:
    // 初始化公共控件先
    INITCOMMONCONTROLSEX init;
    init.dwSize = sizeof( init );
    init.dwICC = ICC_LISTVIEW_CLASSES;
    InitCommonControlsEx( &init );
    在此我有必要指出,對公共控件庫的初始化應該盡量使用InitCommonControlsEx,即使InitCommonControls貌似更加方便一些。我曾經做過測試,一個使用了DateTime控件并由InitCommonControls初始化的應用程序在WinXP sp2 + VC 6.0編譯完成后,在Win2K下是不能運行的。
  2. CMainDlg::OnRadioSex是為了演示COMMAND_RANGE_HANDLER而寫的一個消息處理函數,其實針對這個示例并不用編寫之——因為Windows系統會自動對Radio按鈕進行檢選狀態的處理;但如若考慮到多組Radio按鈕存在的情況,CMainDlg::OnRadioSex這樣的處理函數便會凸顯出它的用處。
  3. LListView::GetSelectionMark并不能用來準確判斷ListView的選中項,尤其是在選中項被刪除之后。

只有注冊用戶登錄后才能發表評論。
網站導航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            国产精品久久久久久五月尺| 亚洲人成7777| 国产亚洲在线观看| 国产精品亚洲成人| 亚洲欧美日韩精品| 亚洲国产va精品久久久不卡综合| 久久久国产精品一区二区中文| 欧美激情一区二区在线 | 国产精品wwwwww| 亚洲国产黄色| 久久久久一区二区| 亚洲欧美日韩久久精品| 欧美视频免费| 亚洲性图久久| 一本色道久久综合亚洲精品按摩| 欧美高清视频一二三区| 亚洲国产精品一区二区三区| 久久亚洲综合网| 欧美一级日韩一级| 国产午夜精品全部视频在线播放 | 国内精品久久久久久久果冻传媒 | 国产精品乱码一区二三区小蝌蚪| 亚洲理论在线观看| 亚洲大胆视频| 欧美sm极限捆绑bd| 亚洲美女诱惑| 亚洲人成高清| 欧美日韩国产成人精品| 亚洲美女精品久久| 日韩视频一区二区在线观看 | 亚洲理伦电影| 欧美国产欧美亚洲国产日韩mv天天看完整 | 亚洲激情婷婷| 亚洲人成精品久久久久| 欧美精品一区二区久久婷婷| 国产精品99久久久久久有的能看 | 亚洲精品欧美日韩| 欧美日韩精品国产| 日韩一区二区久久| 亚洲尤物在线| 美女诱惑一区| 欧美日韩国产精品专区| 亚洲亚洲精品三区日韩精品在线视频| 欧美精品在线观看91| 亚洲欧美视频在线| 亚洲午夜精品久久| 国产亚洲在线观看| 亚洲福利电影| 欧美日韩一区二区三区免费| 欧美一区二区精品| 久久久久一区二区三区四区| 日韩网站在线观看| 亚洲欧美在线看| 欧美一区二区日韩| 欧美三级免费| 日韩视频一区| 国产精品一区二区三区乱码 | 性娇小13――14欧美| 久久久999国产| 日韩一区二区精品在线观看| 亚洲欧美激情在线视频| 在线播放不卡| 亚洲视频在线播放| 亚洲人成人一区二区三区| 在线亚洲精品| 亚洲韩日在线| 午夜亚洲福利| 一区二区三区.www| 久久综合导航| 久久成人国产| 欧美系列精品| 亚洲电影免费在线| 国产亚洲欧美一区二区| 99国产精品久久久久久久| 狠狠色综合播放一区二区| 99这里只有精品| 亚洲国产天堂久久综合| 欧美一区二区成人| 亚洲欧美综合| 欧美精品午夜| 亚洲国产精品一区二区www| 韩日欧美一区二区三区| 亚洲欧美成人网| 亚洲一区亚洲二区| 欧美丰满高潮xxxx喷水动漫| 久久蜜桃资源一区二区老牛| 国产精品男女猛烈高潮激情 | 久久青草久久| 欧美专区日韩视频| 欧美亚男人的天堂| 99精品热视频| 中文av一区特黄| 欧美欧美全黄| 亚洲精选视频免费看| 亚洲精品三级| 欧美激情亚洲激情| 亚洲黄色三级| 9国产精品视频| 欧美精品在线观看播放| 欧美黄色一区| 欲色影视综合吧| 久久亚洲综合| 亚洲国产精品福利| 亚洲日本视频| 欧美日本不卡视频| 日韩视频免费观看| 亚洲欧美在线免费| 国产精品亚洲一区| 欧美一区二区三区在线观看| 久久婷婷国产麻豆91天堂| 精品69视频一区二区三区| 久久夜色撩人精品| 91久久中文| 亚洲欧美另类中文字幕| 国产日韩精品在线观看| 久久深夜福利| 久久久久久午夜| 99精品热6080yy久久| 中文精品视频| 久久精品伊人| 久久在线播放| 久久精品国产清高在天天线| 欧美福利小视频| 国产日韩1区| 午夜电影亚洲| 亚洲人久久久| 欧美日韩激情小视频| 在线观看日韩国产| 亚洲理论电影网| 国产欧美二区| 免费h精品视频在线播放| 欧美大尺度在线| 国产欧美日韩一区| 亚洲精品久久久久久久久久久| 黄色一区二区在线观看| 免费不卡欧美自拍视频| 麻豆免费精品视频| 伊人久久综合97精品| 欧美高清视频免费观看| 国产精品久久久久久久久婷婷| 亚洲五月六月| 亚洲欧美在线一区二区| 久久国产日本精品| 久久久九九九九| 国内精品视频666| 久久亚洲春色中文字幕| 国语自产精品视频在线看抢先版结局 | 欧美精品在线一区| 国产精品青草综合久久久久99| 黄色成人在线| 欧美激情一区二区三区蜜桃视频| 免费观看亚洲视频大全| 一区二区精品在线| 亚洲欧美激情四射在线日| 亚洲大胆女人| 亚洲精品视频在线| 欧美成人午夜激情视频| 怡红院精品视频在线观看极品| 亚洲欧美卡通另类91av| 老司机精品久久| 午夜日韩在线观看| 一二三四社区欧美黄| 久久久噜噜噜久久人人看| 99精品99| 激情久久综艺| 国产精品一区二区三区久久久| 欧美激情按摩| 免费在线观看日韩欧美| 久久国产精品久久久久久电车| 正在播放亚洲一区| 亚洲精品免费在线播放| 久久深夜福利| 久久精品国产清高在天天线| 亚洲自拍偷拍色片视频| 一本色道久久88精品综合| 亚洲精品一区在线| 亚洲经典一区| 亚洲国产mv| 最近中文字幕mv在线一区二区三区四区| 国产在线高清精品| 国产精品任我爽爆在线播放| 欧美色视频在线| 欧美午夜激情视频| 国产精品av久久久久久麻豆网| 欧美日韩在线播放三区四区| 欧美了一区在线观看| 欧美大片免费观看| 欧美电影美腿模特1979在线看| 欧美成人激情视频免费观看| 牛牛影视久久网| 欧美精品一区二区三| 欧美区在线观看| 亚洲欧美春色| 欧美一区三区三区高中清蜜桃 | 欧美韩日精品| 91久久精品美女高潮| 亚洲九九爱视频| 亚洲欧美国产视频| 久久夜精品va视频免费观看| 免费成人毛片|