版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
第13章MFC編程13.1Windows編程及MFC簡(jiǎn)介13.2基于對(duì)話框的應(yīng)用程序設(shè)計(jì)13.3單文檔(SDI)和多文檔(MDI)應(yīng)用程序
本章小結(jié)習(xí)題
本章以VisualC++6.0為開(kāi)發(fā)環(huán)境,簡(jiǎn)要介紹利用WindowsAPI(ApplicationProgrammingInterface)和MFC(MicrosoftFoundationClasses)編寫(xiě)Windows應(yīng)用程序的基本方法。微軟基礎(chǔ)類(lèi)庫(kù)MFC是微軟為開(kāi)發(fā)人員提供的一個(gè)面向?qū)ο蟮腤indows編程接口,它提供了一個(gè)標(biāo)準(zhǔn)化的結(jié)構(gòu)和豐富的MFC庫(kù),用MFC開(kāi)發(fā)的程序具有標(biāo)準(zhǔn)的Windows界面,對(duì)用戶而言直觀易用。13.1Windows編程及MFC簡(jiǎn)介
Windows編程就是基于Microsoft公司的Windows操作系統(tǒng)的編程,利用它可以開(kāi)發(fā)運(yùn)行在Windows操作系統(tǒng)下的應(yīng)用程序。Widows編程和常見(jiàn)的控制臺(tái)程序不同,它是基于窗口的。利用VisualC++6.0為開(kāi)發(fā)環(huán)境開(kāi)發(fā)Windows應(yīng)用程序可以有兩種途徑。一種是直接調(diào)用Windows操作系統(tǒng)提供的API(應(yīng)用程序接口)函數(shù),這種方法稱(chēng)為WindowsAPI編程(也簡(jiǎn)稱(chēng)為Windows編程)。另一種是利用MFC(微軟基礎(chǔ)類(lèi)庫(kù)),這種方法稱(chēng)為MFC編程。利用C語(yǔ)言開(kāi)發(fā)Windows應(yīng)用程序時(shí)通常選擇第一種方法。利用C++開(kāi)發(fā)Windows應(yīng)用程序時(shí)兩種方法都可以選擇。
MFC是微軟提供的一個(gè)基礎(chǔ)類(lèi)庫(kù),它封裝了大部分的WindowsAPI,對(duì)于使用C++語(yǔ)言開(kāi)發(fā)Windows應(yīng)用程序的開(kāi)發(fā)者來(lái)說(shuō),用MFC比直接用WindowsAPI容易一些。另外,MFC中還提供了很好的應(yīng)用程序框架,其中最突出的就是它的“文檔-視”結(jié)構(gòu)。13.1.1Windows
API編程基礎(chǔ)
Windows是一個(gè)應(yīng)用于微型計(jì)算機(jī)上的基于窗口的圖形化用戶界面的操作系統(tǒng)。它主要由窗口和菜單構(gòu)成。
1.Windows編程中的基本概念
1)窗口窗口是Windows程序的基本組成部分,它是用戶與應(yīng)用程序進(jìn)行交互的場(chǎng)所。圖13.1是一個(gè)典型的Windows窗口示意圖。圖13.1
Windows窗口示意圖
2)句柄句柄是Windows編程中一個(gè)很重要的概念,它是由系統(tǒng)分配的用來(lái)唯一標(biāo)識(shí)Windows程序中不同對(duì)象的一個(gè)4字節(jié)的整數(shù)值。常用的句柄類(lèi)型有以下幾種:
HWND 窗口句柄
HINSTANS 實(shí)例句柄
HMENU 菜單句柄
HCURSOR 光標(biāo)句柄
HICON 圖標(biāo)句柄
HDC 設(shè)備句柄
HPEN 畫(huà)筆句柄
HBRUSH 畫(huà)刷句柄句柄是一個(gè)比較抽象的概念,可簡(jiǎn)單理解為要操作一個(gè)Windows對(duì)象,就要獲得它的句柄,這如同我們要操作一個(gè)勺子,就要去拿勺子的柄的道理一樣。
3)事件和消息
Windows程序是基于事件或消息驅(qū)動(dòng)的,其基本思想是,用特定的事件確定應(yīng)用程序的控制流程。程序要花費(fèi)其大部分時(shí)間來(lái)等待這些事件,并提供代碼響應(yīng)其中部分事件。例如,當(dāng)用戶單擊鼠標(biāo)按鍵時(shí),一個(gè)事件就發(fā)生了,一條描述該事件的消息將被加入到消息隊(duì)列,然后在適當(dāng)?shù)臅r(shí)候被發(fā)送到鼠標(biāo)光標(biāo)下的當(dāng)前窗口,該窗口響應(yīng)事件的代碼將接收到該事件,然后執(zhí)行。當(dāng)程序完成了對(duì)事件的響應(yīng)之后,它就返回等待狀態(tài)。在Windows中消息用一個(gè)結(jié)構(gòu)體MSG來(lái)表示,它的定義如下:
typedefstructtagMSG
{
HWND hwnd;
UINT message;
WPARAM wParam;
LPARAM lParam;
DWORD time;
POINT pt;
}MSG,*PMSG;該結(jié)構(gòu)體中各元素的含義如下:
hwnd:接收該消息的窗口句柄。
message:消息值,它的類(lèi)型為UNIT。
wParam:消息的字參數(shù),類(lèi)型為WPARAM。
lParam:消息的長(zhǎng)字參數(shù)。字參數(shù)和長(zhǎng)字參數(shù)對(duì)不同的消息有不同的含義。
time:消息發(fā)送的時(shí)間。
pt:消息發(fā)送時(shí)光標(biāo)在屏幕上的坐標(biāo)。在MSG結(jié)構(gòu)體中的元素的類(lèi)型都是一些比較陌生的用大寫(xiě)字母表示的類(lèi)型。這些類(lèi)型其實(shí)是用C++的typedef關(guān)鍵字定義的一些別名。我們可以通過(guò)查找MSDN來(lái)確定其含義,也可以在VC++6.0中輸入這些類(lèi)型,在其上單擊右鍵,選擇GotoDifinitionof…就可以看見(jiàn)它的原始定義了。通過(guò)以上方法可以確定:UINT就是unsignedint;WPARAM也是unsignedint;LPARAM就是long;DWORD就是unsignedlong;POINT是一個(gè)結(jié)構(gòu)體,定義如下:
typedefstructtagPOINT
{
LONGx;
LONGy;
}POINT,*PPOINT,NEAR*NPPOINT,FAR*LPPOINT;
Windows程序中的常用消息有:
WM_LBUTTONDOWN:按下鼠標(biāo)左鍵;
WM_LBUTTONUP:放開(kāi)鼠標(biāo)左鍵;
WM_RBUTTONDOWN:按下鼠標(biāo)右鍵;
WM_RBUTTONUP:放開(kāi)鼠標(biāo)右鍵;
WM_LBUTTONDBLCLK:雙擊鼠標(biāo)左鍵;
WM_RBUTTONDBLCLK:雙擊鼠標(biāo)右鍵;
WM_KEYDOWN:按下鍵盤(pán)上的一個(gè)非系統(tǒng)鍵;
WM_CLOSE:關(guān)閉一個(gè)窗口;
WM_QUIT:退出程序。
4)?WinMain函數(shù)
WinMain函數(shù)是WindowsAPI編程的入口函數(shù),就像控制臺(tái)程序的入口函數(shù)Main一樣。它的主要作用是顯示主窗口,完成消息循環(huán)。
5)消息循環(huán)
Windows程序中每發(fā)生一個(gè)事件時(shí),系統(tǒng)都把產(chǎn)生的消息放到應(yīng)用程序的消息隊(duì)列中。WinMain函數(shù)的消息循環(huán)語(yǔ)句從消息隊(duì)列中逐個(gè)取出消息,并將其傳送給窗口函數(shù)進(jìn)行相應(yīng)處理。消息循環(huán)一般采用如下形式:
while(GetMessage(&msg,NULL,0,0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
API函數(shù)GetMessage從消息隊(duì)列中取出消息,TranslateMessage和DispatchMessage翻譯消息并將它傳送給窗口函數(shù)進(jìn)行相應(yīng)處理。
6)窗口函數(shù)窗口函數(shù)是一個(gè)回調(diào)函數(shù)?;卣{(diào)函數(shù)是用戶按照系統(tǒng)規(guī)定的形式提供給系統(tǒng)調(diào)用的函數(shù)。它主要對(duì)消息循環(huán)發(fā)送來(lái)的消息進(jìn)行分類(lèi)處理。其原型如下:
LRESULTCALLBACKWindowProc(
HWNDhwnd,
UINTuMsg,
WPARAMwParam,
LPARAMlParam
);
7)窗口類(lèi)
Windows編程中的窗口類(lèi)不是指某個(gè)特定的C++類(lèi),而是一個(gè)描述Windows窗口屬性的數(shù)據(jù)結(jié)構(gòu),其定義如下:
typedefstruct_WNDCLASS
{ UINTstyle; WNDPROClpfnWndProc; intcbClsExtra; intcbWndExtra; HANDLEhInstance; HICONhIcon;
HCURSORhCursor;
HBRUSHhbrBackground; LPCTSTRlpszMenuName; LPCTSTRlpszClassName;
}WNDCLASS;
WNDCLASS主要成員的含義如下:
lpfnWndProc:窗口函數(shù)的指針。
hInstance:窗口類(lèi)所屬的應(yīng)用程序的實(shí)例句柄。
hIcon和hCursor:窗口類(lèi)的圖標(biāo)和光標(biāo)。
2.Windows編程實(shí)例下面通過(guò)一個(gè)實(shí)例具體講解如何編寫(xiě)簡(jiǎn)單的Windows應(yīng)用程序。本程序在WinMain函數(shù)中創(chuàng)建一個(gè)主窗口,用鼠標(biāo)左鍵單擊主窗口時(shí)彈出一個(gè)消息框。在VC++6.0中執(zhí)行菜單命令File→New,彈出如圖13.2所示的對(duì)話框,輸入工程名HelloWorld,選擇Win32Application,彈出如圖13.3所示的對(duì)話框,選擇一個(gè)空工程,點(diǎn)擊Finish完成。再選擇菜單命令File→New,彈出如圖13.2所示的對(duì)話框,在Files選項(xiàng)卡中選擇C++SourceFile,取文件名為HelloWorld。點(diǎn)擊OK按鈕,完成HelloWorld.cpp文件的建立,然后輸入如程序13.1所示的代碼。圖13.2新建工程對(duì)話框(1)圖13.3新建工程對(duì)話框(2)
【程序13.1】#include<windows.h>
//窗口函數(shù)原型聲明
LRESULTCALLBACKWndProc(HWND,UINT,WPARAM,LPARAM);
//WinMain函數(shù)
intWINAPIWinMain(HINSTANCEhInstance,HINSTANCEhPrevInstance,PSTRszCmdLine,intiCmdShow)
{
HWNDhwnd; //主窗口句柄
MSGmsg; //消息變量
WNDCLASSwndclass; //窗口類(lèi)
wndclass.style=CS_HREDRAW|CS_VREDRAW;
wndclass.lpfnWndProc=WndProc;
wndclass.cbClsExtra=0;
wndclass.cbWndExtra=0;
wndclass.hInstance=hInstance;
wndclass.hIcon=LoadIcon(NULL,IDI_APPLICATION);
wndclass.hCursor=LoadCursor(NULL,IDC_ARROW);
wndclass.hbrBackground=(HBRUSH)GetStockObject
(WHITE_BRUSH);
wndclass.lpszMenuName=NULL;
wndclass.lpszClassName="HelloWorld!";
//注冊(cè)窗口類(lèi)
if(!RegisterClass(&wndclass))
{
MessageBox(NULL,"Cannotregisterthewindowclass!","HelloWorld!", MB_ICONERROR);
return0;
}
//創(chuàng)建主窗口
hwnd=CreateWindow("HelloWorld!","HelloWorld!",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,CW_USEDEFAULT,
CW_USEDEFAULT,CW_USEDEFAULT,
NULL,NULL,hInstance,NULL);
ShowWindow(hwnd,iCmdShow);
UpdateWindow(hwnd);
//消息循環(huán)
while(GetMessage(&msg,NULL,0,0))
{ TranslateMessage(&msg); DispatchMessage(&msg);
}
return1;
}
//窗口函數(shù)
LRESULTCALLBACKWndProc(HWNDhwnd,UINTmessage,WPARAMwParam,LPARAMlParam)
{
switch(message)
{ //處理鼠標(biāo)左鍵按下消息
caseWM_LBUTTONDOWN: //退出消息框
MessageBox(NULL,"HelloWorld!","HelloWorld!",MB_OK);
break;
//處理程序退出消息
caseWM_DESTROY: PostQuitMessage(0); return0;
}
returnDefWindowProc(hwnd,message,wParam,lParam);
}這個(gè)小程序包括了前面所講到的WindowsAPI編程的大部分元素,提供了一個(gè)完整的體系結(jié)構(gòu),其他的程序都可以按這個(gè)結(jié)構(gòu)去改寫(xiě)。13.1.2MFC編程簡(jiǎn)介從程序13.1中可以看到,直接使用WindowsAPI函數(shù)來(lái)開(kāi)發(fā)Windows應(yīng)用程序的代碼量很大。MFC是面向?qū)ο蟪绦蛟O(shè)計(jì)與應(yīng)用框架的完美結(jié)合,它將傳統(tǒng)的API進(jìn)行了分類(lèi)封裝,并且為用戶創(chuàng)建了程序的一般框架。在使用MFC開(kāi)發(fā)Windows應(yīng)用程序時(shí)還可以直接調(diào)用WindowsAPI函數(shù),因此MFC框架既方便了用戶也保證了靈活性。VC++6.0開(kāi)發(fā)平臺(tái)還為MFC提供了很好的向?qū)В凑障驅(qū)c(diǎn)擊鼠標(biāo)就能形成用戶自己的程序構(gòu)架,在此框架的基礎(chǔ)上增加自己的代碼就非常方便了。
1.MFC基本類(lèi)介紹
MFC提供了100多個(gè)類(lèi)對(duì)不同的功能進(jìn)行了封裝,下面介紹MFC應(yīng)用程序開(kāi)發(fā)中常用的類(lèi)。
1)?CObject類(lèi)
CObject是大多數(shù)MFC類(lèi)的根類(lèi)或基類(lèi),它有很多有用的特性,例如對(duì)運(yùn)行時(shí)類(lèi)信息的支持,對(duì)動(dòng)態(tài)創(chuàng)建的支持,對(duì)串行化的支持,對(duì)象診斷輸出,等等。MFC從CObject派生出許多類(lèi),具備其中的一個(gè)或多個(gè)特性。用戶也可以從CObject類(lèi)派生出自己的類(lèi),利用CObject類(lèi)的這些特性。
2)?CWinApp類(lèi)
CWinApp為應(yīng)用程序類(lèi),它用于Windows操作系統(tǒng)應(yīng)用程序的初始化、運(yùn)行和終止。利用MFC開(kāi)發(fā)Windwos應(yīng)用程序時(shí)必須建立一個(gè)繼承自CWinApp的類(lèi),并構(gòu)造一個(gè)全局的該派生類(lèi)的對(duì)象。
3)?CDocument類(lèi)
CDocument是應(yīng)用程序文檔類(lèi)的基類(lèi),它用于對(duì)應(yīng)用程序的文檔進(jìn)行操作,例如文檔的創(chuàng)建、加載和保存。
4)?CView類(lèi)
CView類(lèi)是應(yīng)用程序視類(lèi)的基類(lèi),一個(gè)視類(lèi)與一個(gè)文檔類(lèi)相關(guān)聯(lián),視類(lèi)封裝了程序的視圖功能。視圖是在用戶和文檔之間建立的一個(gè)可視化的界面。
5)?CFrameWnd類(lèi)
CFrameWnd為應(yīng)用程序框架窗口類(lèi)的基類(lèi),它是CWnd類(lèi)的子類(lèi)??蚣艽翱谝话惆藛雾?xiàng)、工具欄、狀態(tài)欄和視圖窗口。
6)?CWnd類(lèi)
CWnd為MFC類(lèi)庫(kù)的窗口類(lèi)提供了基本的功能。窗口是Windows應(yīng)用程序的最基本的組成部分。CWnd提供了非常多的成員函數(shù)來(lái)封裝對(duì)窗口的各種操作。
7)?CDialog類(lèi)
CDialog是對(duì)話框類(lèi)的基類(lèi),它封裝了對(duì)對(duì)話框的各種操作,它繼承自CWnd,因?yàn)閷?duì)話框本身就是一類(lèi)特殊的窗口。MFC中還包括許多繼承自CDialog的通用對(duì)話框類(lèi),包括CFileDialog、CColorDialog、CFontDialog、CPintDialog等。從這些通用對(duì)話框的名稱(chēng)就可以了解其用途。2.通過(guò)應(yīng)用程序向?qū)?chuàng)建MFC應(yīng)用程序
VC++6.0提供了向?qū)?AppWizard)來(lái)生成MFC應(yīng)用程序的框架。下面介紹如何利用向?qū)Ы⒁粋€(gè)類(lèi)似于程序13.1所完成的功能。點(diǎn)擊菜單命令File→New,彈出如圖13.2所示的新建工程對(duì)話框。選擇MFCAppWizard[exe],輸入工程名HelloWorldMFC,點(diǎn)擊OK按鈕,彈出如圖13.4所示的AppWizard對(duì)話框,選擇Singledocument(單文檔模式),點(diǎn)擊Next按鈕將進(jìn)入MFCAppWizard-Step2對(duì)話框,AppWizard提供了設(shè)置功能。選擇Finish按鈕,使其余選項(xiàng)都保持默認(rèn),完成工程的創(chuàng)建。圖13.4新建工程對(duì)話框(3)執(zhí)行以上操作后,應(yīng)用程序向?qū)ppWizard建立了一個(gè)程序框架,點(diǎn)擊工具欄執(zhí)行按鈕,將看到如圖13.5所示的程序框架。在這個(gè)程序框架中,常用的標(biāo)題欄、菜單欄、工具欄和狀態(tài)欄都已經(jīng)建立好,基本上已經(jīng)是一個(gè)完整的程序了。接下來(lái)用戶可以在此框架的基礎(chǔ)上實(shí)現(xiàn)自己的功能。下面實(shí)現(xiàn)在窗口中單擊鼠標(biāo)后彈出消息框的功能?;氐絍C編譯環(huán)境后單擊左邊Workspace窗口下方的ClassView選項(xiàng)卡,如圖13.6所示。可見(jiàn)AppWizard建立了CHelloWorldMFCApp、CHelloWorldMFCDoc、ChelloWorld-MFCView、CMainFrame類(lèi),它們分別是前面介紹過(guò)的CWinApp、CDocument、CView、CFrameWnd類(lèi)的子類(lèi),它們共同構(gòu)成了應(yīng)用程序框架,如圖13.6所示。圖13.5程序框架圖13.6
ClassView選項(xiàng)卡在CHelloWorldMFCView類(lèi)上單擊鼠標(biāo)右鍵,選擇AddWindowsMessageHandler,打開(kāi)如圖13.7所示的對(duì)話框,為類(lèi)CHelloWorldMFCView添加消息處理,再雙擊左邊的WM_LBUTTONDOW,為應(yīng)用程序添加鼠標(biāo)左鍵按下消息處理。單擊EditExisting按鈕,可在ClassView中發(fā)現(xiàn)類(lèi)CHelloWorldMFCView已多了一個(gè)成員函數(shù)OnLButtonDown,這就是鼠標(biāo)左鍵按下的消息處理回調(diào)函數(shù),為它添加如下代碼:
voidCHelloWorldMFCView::OnLButtonDown(UINTnFlags,CPointpoint)
{ //TODO:Addyourmessagehandlercodehereand/orcalldefault MessageBox("HelloWorldMFC!!"); CView::OnLButtonDown(nFlags,point);
}編譯運(yùn)行程序后在程序窗口上單擊就會(huì)彈出一個(gè)消息框,如圖13.8所示。前面簡(jiǎn)要介紹了兩種編寫(xiě)Windows應(yīng)用程序的方法——基于WindowsAPI和基于MFC的應(yīng)用程序設(shè)計(jì)。本章后面的內(nèi)容主要介紹基于MFC的Windows應(yīng)用程序的基本設(shè)計(jì)方法。圖13.7消息處理對(duì)話框圖13.8彈出消息框13.2基于對(duì)話框的應(yīng)用程序設(shè)計(jì)對(duì)話框是Windwos的重要資源,它通常設(shè)計(jì)為帶有若干控件的一類(lèi)窗口。對(duì)話框在程序中的主要作用是和用戶交互,接收用戶的輸入信息或向用戶展示程序的輸出信息。利用MFC提供的程序框架,可以設(shè)計(jì)一類(lèi)基于對(duì)話框的應(yīng)用程序,這類(lèi)程序的主窗口就是一個(gè)對(duì)話框和若干控件。13.2.1利用MFC的AppWizard創(chuàng)建基于對(duì)話框的應(yīng)用程序可以利用VC++6.0為工程向?qū)Ы⒒趯?duì)話框的應(yīng)用程序,步驟如下:
(1)打開(kāi)VC++6.0,選擇菜單命令File→New,彈出如圖13.9所示的新建工程對(duì)話框。圖13.9新建工程對(duì)話框(1)
(2)選擇MFCAppWizard[exe],填入工程名DialogApp,單擊OK按鈕,進(jìn)入如圖13.10所示的MFCAppWizard-Step1對(duì)話框。
3)選擇Dialogbased單選按鈕,點(diǎn)擊Finish按鈕完成工程的創(chuàng)建。系統(tǒng)即為我們建立了一個(gè)默認(rèn)的對(duì)話框模板,如圖13.11所示。模板上有一個(gè)確定按鈕、一個(gè)取消按鈕和一個(gè)靜態(tài)控件(其上顯示文字“TODO:在這里設(shè)置對(duì)話控制?!?。在這個(gè)對(duì)話框模板上可以添加自己需要的控件來(lái)構(gòu)成基于對(duì)話框應(yīng)用程序的界面。這個(gè)對(duì)話框稱(chēng)為主對(duì)話框,與其對(duì)應(yīng)的類(lèi)在Wo(hù)rkspace窗口的ClassView中可以看到,即CDialogAppDlg,這個(gè)類(lèi)是對(duì)話框類(lèi)CDialog的一個(gè)子類(lèi)。
(4)編譯運(yùn)行程序就可以看到MFC框架為我們建立的默認(rèn)對(duì)話框應(yīng)用程序。圖13.10新建工程對(duì)話框(2)圖13.11默認(rèn)對(duì)話框模板13.2.2Windows控件簡(jiǎn)介圖13.12標(biāo)準(zhǔn)控件控件是一些特殊的窗口,通常作為對(duì)話框的子窗口出現(xiàn),用戶通過(guò)對(duì)控件的操作完成和應(yīng)用程序的交互。Windows提供的標(biāo)準(zhǔn)控件有按鈕控件、編輯框控件、列表框控件、組合框、滾動(dòng)條控件、進(jìn)度條控件和靜態(tài)控件等。它們?cè)诔绦蛑腥鐖D13.12所示。在MFC的類(lèi)中,與以上標(biāo)準(zhǔn)控件相對(duì)應(yīng)的有CButton、CEdit、CList、CCombBox、CScrollBar、CProgressCtrl和CStatic等。由于控件也是窗口,因此以上類(lèi)都是繼承自MFC窗口類(lèi)CWnd的子類(lèi),所有CWnd類(lèi)提供的方法對(duì)控件都有效。例如窗口的顯示/隱藏、禁用/使用等。圖13.12標(biāo)準(zhǔn)控件一個(gè)程序中的控件以其ID唯一標(biāo)識(shí)自己,控件的ID號(hào)通常為一預(yù)定義的系統(tǒng)分配的整數(shù)值。它們?cè)赗esource.h頭文件中以宏的形式定義。下面以按鈕控件和編輯框控件為例簡(jiǎn)單介紹一下MFC中控件的使用,其他控件的使用和它們類(lèi)似,具體情況可查找MSDN。
1.按鈕控件按鈕控件包括普通按鈕、單選按鈕、復(fù)選按鈕、組框按鈕等。其中組框主要是為了對(duì)控件進(jìn)行分組說(shuō)明。除組框外其他按鈕都處理鼠標(biāo)消息,當(dāng)接收到鼠標(biāo)消息時(shí)向其父窗口(裝載按鈕的對(duì)話框窗口)發(fā)送一個(gè)命令消息(WM_COMMAND消消息),對(duì)話框的窗口過(guò)程函數(shù)根據(jù)消息的字參數(shù)確定出發(fā)送消息按鈕的ID,然后調(diào)用相應(yīng)的消息處理函數(shù)。而其分窗口一般都提供一個(gè)消息處理函數(shù)來(lái)執(zhí)行一定的操作。例如在對(duì)話框中點(diǎn)擊確定按鈕時(shí),系統(tǒng)將向?qū)υ捒虬l(fā)送一個(gè)WM_COMMAND消息,并調(diào)用消息處理函數(shù)關(guān)閉對(duì)話框。在MFC中與按鈕對(duì)應(yīng)的類(lèi)為CButton,CButton類(lèi)的主要方法如表13.1所示。表13.1CButton類(lèi)的主要方法
2.編輯框控件編輯框控件一般用來(lái)向應(yīng)用程序輸入消息或向用戶顯示程序的輸出結(jié)果,它分為單行的和多行的。當(dāng)用戶操作編輯框時(shí),編輯框向其父窗口發(fā)送WM_COMMAND消息,該消息的字參數(shù)wParam的低字節(jié)為發(fā)送消息的控件ID號(hào),高字節(jié)為標(biāo)識(shí)用戶對(duì)編輯框操作的消息通知碼。在MFC中對(duì)這些消息通知碼都進(jìn)行了消息映射,將其映射到一個(gè)回調(diào)函數(shù)中,用戶只需要在消息通知碼的回調(diào)函數(shù)中編寫(xiě)自己的代碼,程序會(huì)在用戶對(duì)編輯框進(jìn)行某種操作時(shí)自動(dòng)調(diào)用這個(gè)消息映射回調(diào)函數(shù)。這種消息映射機(jī)制是MFC中常見(jiàn)的一種處理消息的方法。在MFC中與編輯框?qū)?yīng)的類(lèi)為CEdit,CEdit的主要方法如表13.2所示。表13.2
CEdit類(lèi)的主要方法13.2.3基于對(duì)話框的應(yīng)用程序?qū)嵗馕霰竟?jié)將實(shí)現(xiàn)如圖13.13所示的簡(jiǎn)單計(jì)算器程序,用戶點(diǎn)擊“計(jì)算”按鈕時(shí),程序會(huì)根據(jù)左邊的選擇將按鈕上面前兩個(gè)編輯框中的數(shù)字進(jìn)行運(yùn)算并顯示在最后一個(gè)編輯框中。
1.程序界面設(shè)計(jì)繼續(xù)使用13.2.1節(jié)中創(chuàng)建的工程來(lái)完成程序的設(shè)計(jì)。選擇WorkSpace窗口的ResourceView選項(xiàng)卡,展開(kāi)Dialog文件夾前面的小十字。雙擊其下的IDD_DIALOGAPP_DIALOG,進(jìn)入主對(duì)話框模板編輯狀態(tài)。這時(shí)在VC窗口的右邊就能看到如圖13.14所示的控件窗口(如果沒(méi)有可在工具欄空白處單擊右鍵,在快捷菜單中選擇control)。按照?qǐng)D13.14所示的界面從控件窗口中拖出相應(yīng)的控件并擺放到相應(yīng)的位置。圖13.13實(shí)例程序效果圖圖13.14控件窗口
2.控件屬性的設(shè)置
VC++6.0環(huán)境提供了可視化設(shè)置控件屬性的功能。選中某個(gè)控件后單擊右鍵菜單中的Properties或者選中控件后直接按回車(chē)鍵都會(huì)彈出如圖13.15所示的控件屬性設(shè)置對(duì)話框。通過(guò)該對(duì)話框可以設(shè)置控件的ID、標(biāo)題(Caption)、風(fēng)格等屬性。其中控件ID是每個(gè)控件都必須設(shè)置的內(nèi)容,它唯一標(biāo)識(shí)了整個(gè)程序中用到的控件,可以輸入任意合法的標(biāo)識(shí)符,VC會(huì)將其定義為一個(gè)宏,并為其分配一個(gè)唯一的整數(shù)值??蓪?duì)各個(gè)控件設(shè)置其屬性,如表13.3所示。
圖13.15控件屬性設(shè)置對(duì)話框表13.3控件屬性表
3.成員變量的綁定編輯好了控件以后,為了在程序中更方便地操作控件,可以在對(duì)話框類(lèi)中為控件綁定一個(gè)成員變量。MFC提供了DDX(動(dòng)態(tài))技術(shù),不但可以為控件綁定與其對(duì)應(yīng)的類(lèi)類(lèi)型的變量,還可以綁定與控件操作的數(shù)據(jù)相關(guān)的類(lèi)型的變量。例如,可以為編輯框綁定CEdit類(lèi)型的變量,也可以綁定int、float等類(lèi)型的數(shù)據(jù)。如果為其綁定了float類(lèi)型的變量,改變了該變量的值就會(huì)在編輯框中顯示出來(lái);同時(shí),如果運(yùn)行程序時(shí)通過(guò)輸入改變了控件的內(nèi)容,與其綁定的變量的值也會(huì)改變。執(zhí)行菜單命令View→ClassWizard或按快捷鍵Ctrl+W,打開(kāi)如圖13.16所示的ClassWizard對(duì)話框。選擇MemberVariables選項(xiàng)卡,在Classname中選擇主對(duì)話框類(lèi)CDialogAppDlg類(lèi),在下面的控件ID中選擇IDE_MULTI1,點(diǎn)擊AddVariable為表示被乘數(shù)的編輯框綁定變量,彈出如圖13.17所示的添加成員變量對(duì)話框,變量名輸入m_multi1,綁定類(lèi)型為Value,變量類(lèi)型為float。此方法為其他控件綁定的變量如表13.4所示。在圖13.16中只能看到ID為IDR_ADD的單選按鈕,原因是在設(shè)置控件屬性時(shí)為IDR_ADD設(shè)置了Group屬性。為單選按鈕設(shè)置Group屬性后它將和其后與其ID相連的單選按鈕分為一組,只為第一個(gè)按鈕綁定變量即可操作整組單選按鈕。以上綁定的所有變量都是做為主對(duì)話框類(lèi)CDialogAppDlg的成員變量,可以在WorkSpace的ClassView窗口中找到類(lèi)CDialogAppDlg,查看ClassWizard添加的成員變量。圖13.16ClassWizard對(duì)話框
圖13.17添加成員變量對(duì)話框表13.4控件綁定變量
4.添加消息處理并完成程序功能下面為程序添加代碼部分。本實(shí)例程序是在點(diǎn)擊“計(jì)算”按鈕后執(zhí)行操作的,所以應(yīng)該將實(shí)現(xiàn)代碼放在“計(jì)算”按鈕的處理代碼中。前面講過(guò)點(diǎn)擊一個(gè)按鈕后,按鈕將向其父窗口發(fā)送一個(gè)WM_COMMAND消息。在MFC中通過(guò)消息映射機(jī)制將消息的處理映射到一個(gè)函數(shù)上,稱(chēng)其為消息處理函數(shù)。下面就為按鈕“計(jì)算”添加消息處理函數(shù)和代碼。打開(kāi)ClassWizard對(duì)話框,選擇MessageMaps選項(xiàng)卡,確保類(lèi)名為CDialogAppDlg,在左邊選擇IDB_COMPUT,右邊選擇BN_CLICKED,點(diǎn)擊按鈕AddFuction后點(diǎn)擊EditCode按鈕。這時(shí)MFC向?qū)⒆詣?dòng)為主對(duì)話框類(lèi)CDialogAppDlg添加一個(gè)成員函數(shù),函數(shù)原型為CDialogAppDlg::OnComput(),這個(gè)函數(shù)就是“計(jì)算”按鈕的消息處理函數(shù),在該函數(shù)中添加如下代碼:
voidCDialogAppDlg::OnComput()
{
//TODO:Addyourcontrolnotificationhandlercodehere
UpdateData(true);
switch(m_radioType)
{ case0:
//當(dāng)選中“加法”按鈕時(shí)
m_type="+";
m_result=m_multi1+m_multi2;
break;
case1: //當(dāng)選中“減法”按鈕時(shí)
m_type="-";
m_result=m_multi1-m_multi2;
break; case2:
//當(dāng)選中“乘法”按鈕時(shí)
m_type="×";
m_result=m_multi1*m_multi2;
break; case3:
//當(dāng)選中“除法”按鈕時(shí)
m_type="÷";
if(m_multi2==0)
{ MessageBox("除數(shù)不能為零!!"); break; } else
{ m_result=m_multi1/m_multi2; break; } } UpdateData(false);
}以上代碼中函數(shù)UpdateData()是父類(lèi)CWnd類(lèi)的成員函數(shù),它有一個(gè)bool類(lèi)型的參數(shù),參數(shù)取true表示用與控件綁定的變量的值來(lái)更新控件的內(nèi)容,參數(shù)取false表示用控件的內(nèi)容來(lái)更新與控件綁定的變量的值。switch(m_radioType)語(yǔ)句中,m_radioType為與單選按鈕組綁定的成員變量,選擇了第一個(gè)按鈕時(shí)它的值為0,后面依次加1。m_type="+"語(yǔ)句是根據(jù)選擇的計(jì)算類(lèi)型將表示運(yùn)算符的靜態(tài)變量的內(nèi)容改為相應(yīng)的運(yùn)算符。m_result=m_multi1+m_multi2語(yǔ)句是將第一個(gè)編輯框和第二個(gè)編輯框中的數(shù)加起來(lái)放到第三個(gè)編輯框中,由于MFC采用了DDX函數(shù)機(jī)制,因此改變了m_result的值就等于改變了與其綁定的控件上要顯示的內(nèi)容。
5.編譯運(yùn)行程序程序的編譯運(yùn)行結(jié)果如圖13.18所示。圖13.18程序運(yùn)行結(jié)果13.3單文檔(SDI)和多文檔(MDI)應(yīng)用程序常見(jiàn)的Windows應(yīng)用程序大多都是以文檔或視圖來(lái)組織程序結(jié)構(gòu)的,文檔或視圖結(jié)構(gòu)將數(shù)據(jù)和數(shù)據(jù)的顯示分離開(kāi)。文檔專(zhuān)門(mén)用于組織程序中用到的數(shù)據(jù)以及數(shù)據(jù)結(jié)構(gòu)并將其存檔到硬盤(pán)等永久性介質(zhì)中。視圖則用來(lái)將文檔中的數(shù)據(jù)顯示給用戶,并將用戶操作修改后的數(shù)據(jù)傳送給文檔來(lái)處理。根據(jù)程序能夠同時(shí)打開(kāi)的文檔的數(shù)目,可以把基于文檔視圖結(jié)構(gòu)的應(yīng)用程序分為單文檔(SDI)的和多文檔(MDI)的。單文檔的應(yīng)用程序同時(shí)只能打開(kāi)一個(gè)文檔。例如Windows提供的畫(huà)圖和記事本程序都是單文檔結(jié)構(gòu)的。多文檔應(yīng)用程序可以同時(shí)打開(kāi)多個(gè)文檔進(jìn)行編輯,這些文檔還可以具有不同的文檔模板。例如Office系列的程序都是多文檔的應(yīng)用程序。13.3.1文檔/視圖結(jié)構(gòu)概述利用VC++6.0生成的程序框架可以是基于對(duì)話框的也可以是基于單文檔或基于多文檔的,這可以在新建工程時(shí)的工程向?qū)ppWizard中選擇(如圖13.4所示)。AppWizard生成的單文檔或多文檔應(yīng)用程序框架主要由兩個(gè)窗口和三個(gè)類(lèi)組成。兩個(gè)窗口是框架窗口和視圖窗口。兩個(gè)窗口之間的關(guān)系如圖13.19所示??蚣艽翱谥饕脕?lái)放置系統(tǒng)菜單、工具欄、狀態(tài)欄等。視圖窗口則是覆蓋在框架窗口之上的一個(gè)窗口,主要用來(lái)向用戶顯示信息或接收用戶的輸入信息。三個(gè)類(lèi)分別是框架窗口類(lèi)、視圖窗口類(lèi)和文檔類(lèi)??蚣艽翱陬?lèi)的名稱(chēng)一般固定為CMainFrame,它是類(lèi)CFrameWnd的子類(lèi)。視圖類(lèi)的名字為C***View(***代表工程名),它為CView的子類(lèi)。文檔類(lèi)的名字為C***Doc,它為CDocument類(lèi)的子類(lèi)。圖13.19框架窗口與視圖窗口的關(guān)系13.3.2文檔/視圖結(jié)構(gòu)中的一些重要概念
1.文檔視圖之間的互操作文檔和視圖之間存在一相互操作的接口,如下所示:
CView::GetDocument()函數(shù):檢索其文檔的指針。
CDocument::UpdateAllViews()函數(shù):更新與某文檔相連的視圖。
CDocument::OnNewDocument()函數(shù):初始化文檔成員。
CFrameWnd::GetActiveDocument()函數(shù):從任何CFrameWnd的派生類(lèi)中,訪問(wèn)目前活動(dòng)的文檔。
2.文檔類(lèi)的處理
MFC的文檔視圖結(jié)構(gòu)中對(duì)文檔的處理一般采用以下幾步:
(1)從CDocument類(lèi)派生出自己的文檔類(lèi)。
(2)在文檔類(lèi)中添加描述程序數(shù)據(jù)結(jié)構(gòu)的數(shù)據(jù)成員。
(3)在用戶的文檔中覆蓋基類(lèi)的串行化虛函數(shù)Serialize,該函數(shù)可以將數(shù)據(jù)存儲(chǔ)到永久介質(zhì)上或從永久介質(zhì)上讀取數(shù)據(jù)。
3.文檔的串行化文檔的串行化是指將文檔類(lèi)中數(shù)據(jù)成員的值保存在磁盤(pán)文件中,或者將存儲(chǔ)在文件中的數(shù)據(jù)讀取到相應(yīng)的成員變量中的過(guò)程。文檔的串行化一般通過(guò)在自己的文檔類(lèi)中覆蓋基類(lèi)CDocument的成員函數(shù)Serialize來(lái)實(shí)現(xiàn),該函數(shù)的形式如下所示:
voidCMyDoc::Serialize(CArchive&ar)
{ if(ar.IsStoring()) { //TODO:addstoringcodehere } else { //TODO:addloadingcodehere }
}該函數(shù)中用到的類(lèi)CArchive封裝了對(duì)文件的操作。ar.IsStoring()函數(shù)用來(lái)判斷是從文檔中讀取數(shù)據(jù)還是向文檔中寫(xiě)入數(shù)據(jù)。
4.視圖類(lèi)的處理視圖類(lèi)的處理步驟如下:
(1)從視圖類(lèi)CView中派生出自己的視圖類(lèi)。
(2)重載視圖類(lèi)的OnDraw函數(shù),該函數(shù)根據(jù)文檔類(lèi)將Windows消息和用戶界面對(duì)象(如菜單項(xiàng))與視圖類(lèi)中的消息處理函數(shù)進(jìn)行連接。
(3)實(shí)現(xiàn)消息處理函數(shù),以解釋用戶的輸入。
(4)根據(jù)需要,在派生的視圖類(lèi)中重載CView的其他成員函數(shù)。13.3.3菜單的編輯和使用基于文檔視圖結(jié)構(gòu)的單文檔或多文檔應(yīng)用程序中經(jīng)常要用到菜單資源。AppWizard已經(jīng)在單文檔和多文檔程序中建立了一個(gè)主菜單資源。首先新建一個(gè)單文檔應(yīng)用程序,展開(kāi)資源視圖。然后雙擊Menu子項(xiàng)下的ID為IDR_MAINFRAME的菜單資源,就會(huì)進(jìn)入菜單資源的編輯狀態(tài),如圖13.20所示,可以發(fā)現(xiàn)AppWizard已經(jīng)在該菜單資源中添加了“文件”、“編輯”等一些常用的子菜單。圖13.20菜單資源在菜單資源中通過(guò)鼠標(biāo)點(diǎn)擊就能很容易地為菜單資源增加子菜單和菜單項(xiàng)。這里為主菜單增加一個(gè)子菜單,名字為“顯示”,為該子菜單增加一個(gè)菜單項(xiàng)“消息”,設(shè)置它的ID為IDM_MSG,如圖13.21所示。有了菜單項(xiàng)后就可以為該菜單項(xiàng)增加處理函數(shù)了。打開(kāi)ClassWizard對(duì)話框,按圖13.22設(shè)置后點(diǎn)擊AddFunction按鈕,就會(huì)在CMainFrame類(lèi)中為菜單項(xiàng)增加一個(gè)消息處理函數(shù)OnMsg()。圖13.21增加菜單項(xiàng)圖13.22為菜單項(xiàng)添加消息處理函數(shù)在OnMsg()函數(shù)中完成如下代碼:
voidCMainFrame::OnMsg()
{ //TODO:Addyourcommand
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 北師大版六年級(jí)下數(shù)學(xué)表格式教案
- 酶解法制備高效環(huán)保洗滌劑配方
- 森林經(jīng)營(yíng)實(shí)施方案
- 2024高中地理第二章地球上的大氣第二節(jié)氣壓帶和風(fēng)帶第1課時(shí)氣壓帶和風(fēng)帶的形成學(xué)案新人教版必修1
- 2024高中物理第四章電磁感應(yīng)章末質(zhì)量評(píng)估含解析新人教版選修3-2
- 2024高中語(yǔ)文第三單元因聲求氣吟詠詩(shī)韻將進(jìn)酒訓(xùn)練含解析新人教版選修中國(guó)古代詩(shī)歌散文欣賞
- 2024高中語(yǔ)文精讀課文一第2課2魯迅:深刻與偉大的另一面是平和二作業(yè)含解析新人教版選修中外傳記蚜
- 2024高考化學(xué)一輪復(fù)習(xí)第2章元素與物質(zhì)世界第6講氧化還原反應(yīng)的基本概念和規(guī)律學(xué)案
- 2024高考地理一輪復(fù)習(xí)專(zhuān)練58區(qū)域地理環(huán)境的差異和發(fā)展含解析新人教版
- 2025高考數(shù)學(xué)考二輪題型專(zhuān)項(xiàng)練3客觀題8+3+3標(biāo)準(zhǔn)練(C)-專(zhuān)項(xiàng)訓(xùn)練【含答案】
- DB3303T 059-2023 政務(wù)信息化項(xiàng)目軟件開(kāi)發(fā)費(fèi)用測(cè)算規(guī)范
- 2025年慢性阻塞性肺疾病全球創(chuàng)議GOLD指南修訂解讀課件
- DB11-T 825-2021綠色建筑評(píng)價(jià)標(biāo)準(zhǔn)
- 石油石化用化學(xué)劑產(chǎn)品質(zhì)量認(rèn)可實(shí)施細(xì)則
- 木地板木基層隱蔽驗(yàn)收記錄.doc
- 科室投訴及糾紛月總結(jié)會(huì)議記錄.doc
- 大乘廣智的涵義
- 五通一平施工組織設(shè)計(jì)圖文
- 物流術(shù)語(yǔ)中英文對(duì)照大全10頁(yè)
- 魯教版初中英語(yǔ)七年級(jí)下冊(cè)單詞漢語(yǔ)(背誦)
- 2021年園林綠化工程定額規(guī)定及苗木預(yù)算價(jià)格
評(píng)論
0/150
提交評(píng)論