版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
任課教師信息姓名:鐘樑手機618765)Email:zlkmust@163.comVisualC++學(xué)習(xí)參考學(xué)習(xí)步驟:1、掌握C++的核心知識:繼承、派生、多態(tài)性。2、熟悉利用API進行WINDOWS開發(fā)的基本原理,如消息映射。3、學(xué)習(xí)MFC程序開發(fā),多利用MSDN或者網(wǎng)上資源進行自學(xué)。4、細分方向的開發(fā),如圖形圖像方面。參考資料:1、MSDN2、MFC程序設(shè)計第二版,清華大學(xué)出版社。3、深入淺出MFC,華東理工大學(xué)出版社。4、,VisualC++簡介VisualStudio是一種集成開發(fā)環(huán)境,其提供了包括VisualC++,VisualBasic,C#,ASP.NET,SQLServerExpress在內(nèi)的多項開發(fā)功能。VisualC++是VisualStudio的一個子集,其不是一門語言,而是多種開發(fā)技術(shù)的合集,主要包括:1)Win32API(WindowsSDK開發(fā))2)Win32Console(傳統(tǒng)C/C++開發(fā))3)MFC(MicrosoftFoundationClasses)4)ATL(ActiveTemplateLibrary)VisualC++簡介VisualC++功能:WEB控件:如銀行的各種安全控件、甚至各種流氓控件。通信的程序:聊天工具如QQ、BT下載工具、視頻點播工具等。圖形圖像處理:VisualC++在圖形圖像處理上有先天的優(yōu)勢,可以說是圖形圖像處理領(lǐng)域的唯一選擇。游戲開發(fā):VisualC++可以很方便的調(diào)用OpenGL和DirectX,是游戲開發(fā)的首選工具。
底層開發(fā)及二次開發(fā):VisualC++有強大的底層開發(fā)功能,并能很方便為其它設(shè)計軟件進行二次開發(fā),如AutoCAD,TransModel。VisualC++簡介利用VC編制windows程序主要有兩種方法:(1)SDK(SoftwareDevelopmentKit)軟件開發(fā)工具包(2)MFC(MicrosoftFoundationClassLibrary)微軟基本類庫傳統(tǒng)的結(jié)構(gòu)化WINDOWS程序開發(fā)(SDK):SDK的編程方式就是傳統(tǒng)的C的編程方式。通過調(diào)用庫函數(shù)(win32API,也就是ApplicationProgrammingInterface,即操作系統(tǒng)留給應(yīng)用程序的一個調(diào)用接口)來實現(xiàn)程序的搭建。
優(yōu)點在于:程序比較小,效率高。缺點在于:無框架化結(jié)構(gòu),API函數(shù)混亂,實現(xiàn)一個簡單窗口程序就需要上百行代碼。VisualC++簡介MFC程序開發(fā):MFC是面向?qū)ο蟪绦蛟O(shè)計與Applicationframework的完美結(jié)合。它是把WinAPI進行封裝的類庫,是一個類的集合。它通過覆蓋WindowAPI,為編程提供了一個面向?qū)ο蟮慕缑妗?yōu)點在于:利用C++面象對象的特性進行編程,提供了一般性框架,大大縮短開發(fā)時間,易于實現(xiàn)代碼移植,而且使得用戶界面元素的編寫變得容易起來。缺點在于:封裝復(fù)雜,細節(jié)隱藏過深,入門難度大,且不便于全面掌握其內(nèi)部機理。面向?qū)ο蟾拍罨仡?、類基本格式:
class類名稱
{public:
公有成員
protected:
保護型成員
private:
私有成員
};類成員函數(shù)聲明的一般形式:
返回類型函數(shù)名(形參表);類成員函數(shù)定義的一般形式(類外定義):
返回類型類名::函數(shù)名(形參表)
{//函數(shù)體
}類屬性(成員變量)的申明同普通變量申明一致面向?qū)ο蟪绦蛟O(shè)計——復(fù)習(xí)2、類的構(gòu)造函數(shù)構(gòu)造函數(shù)的作用: 用于在對象創(chuàng)建時,對對象的屬性進行初始化。構(gòu)造函數(shù)的特點:是一個函數(shù),但沒有返回值類型。是一個和類名同名的函數(shù)。只在對象創(chuàng)建時,自動地被編譯器調(diào)用。其它特征和普通函數(shù)相同,可以重載(即可以有多個版本的構(gòu)造函數(shù))。面向?qū)ο蟪绦蛟O(shè)計——復(fù)習(xí)構(gòu)造函數(shù)的一般聲明方式:類名(形參表);構(gòu)造函數(shù)的一般實現(xiàn)方式: 類名::類名(形參表) {//函數(shù)體; }構(gòu)造函數(shù)的另一種實現(xiàn)方式: 類名::類名(形參表):初始化列表
{//函數(shù)體; }
初始化列表形式:屬性(值或形參),屬性(值或形參)…面向?qū)ο蟪绦蛟O(shè)計——復(fù)習(xí)3、類的析構(gòu)函數(shù)析構(gòu)函數(shù)的作用:
用于在對象生命期結(jié)束后,對對象占用的內(nèi)存進行清理工作。析構(gòu)函數(shù)的特點:是一個函數(shù),但沒有返回值類型。是一個在“類名”前加上“~”符號的函數(shù)。只在對象生命期結(jié)束時,自動地被編譯器調(diào)用。析構(gòu)函數(shù)一個類中只能有一個,且不能重載。面向?qū)ο蟪绦蛟O(shè)計——復(fù)習(xí)4、this指針指向當前對象的指針。例:Point類為例
voidmain(){ Pointpt[3];for(intid=0;id<3;id++){ pt[id].SetX(id);pt[id].SetY(id);}}voidPoint::SetX(intnewX){m_iX=newX;}誰的m_iX?怎么確定的?voidPoint::SetX(intnewX){this->m_iX=newX;}面向?qū)ο蟪绦蛟O(shè)計——復(fù)習(xí)(類的)繼承:一個新類從已有的類那里獲得其已有的特性(屬性和方法)。獲得方:子類或派生類給予方(被獲得方):父類或基類繼承的關(guān)系:繼承是一種“是一個(is-a)”的關(guān)系。即如果一個子類B繼承了父類A,我們可以說B是一個A。5、繼承的概念面向?qū)ο蟪绦蛟O(shè)計——復(fù)習(xí)派生類的一般申明形式:class類名
:繼承控制基類名{//類聲明};6、基類和派生類的申明基類的申明同一般類的申明方式??梢允莗ublic,private,protected;注意:基類的屬性和方法在派生類中都保存了相應(yīng)的一份拷貝面向?qū)ο蟪绦蛟O(shè)計——復(fù)習(xí)7、多重繼承派生類可以繼承自多個類,一般申明形式:class類名
:繼承控制基類名,繼承控制基類名,…8、繼承情況下的構(gòu)造派生類負責基類的構(gòu)造派生類利用初始化列表構(gòu)造基類的屬性。派生類總是負責直接基類的構(gòu)造。有多個基類的情況下,派生類對基類的構(gòu)造順序取決于繼承順序,先繼承的先構(gòu)造,最后構(gòu)造自身。析構(gòu)順序與此相反。9、派生類和基類的關(guān)系以及安全賦值問題:
派生類和基類的關(guān)系為”is-a”的關(guān)系,即:
派生類是一個基類面向?qū)ο蟪绦蛟O(shè)計——復(fù)習(xí)派生類的對象可以通過多種方式安全的賦值給基類1)、派生類對象可以直接賦值給基類對象。2)、派生類對象可以初始化給基類的引用。3)、派生類對象可以初始化給基類的指針。動態(tài)綁定靜態(tài)綁定基類的對象卻無法安全的賦值給派生類面向?qū)ο蟪绦蛟O(shè)計——復(fù)習(xí)10、虛函數(shù)與多態(tài)虛函數(shù)的形式:virtual成員函數(shù)申明虛函數(shù)的意義:該成員函數(shù)在派生類中會有不同的實現(xiàn)方式,即該行為因類型不同有不同的表現(xiàn)方法(多態(tài))多態(tài)的使用:第一步:必須存在繼承關(guān)系。第二步:需要表現(xiàn)出多態(tài)性的成員方法必須聲明為基類的虛函數(shù)。第三步:在派生類中將從基類繼承而來的虛函數(shù)按照需求進行重新定義。第四步:將派生類的對象賦值給基類的引用或者指針第五步:通過該基類的引用或者指針調(diào)用相應(yīng)的虛函數(shù),就能根據(jù)對應(yīng)的派生類表現(xiàn)出相應(yīng)的行為。面向?qū)ο蟪绦蛟O(shè)計——復(fù)習(xí)11、虛函數(shù)的注意事項
幾乎所有的成員函數(shù)都可以申明為虛函數(shù)(包括析構(gòu)函數(shù)),但構(gòu)造函數(shù)不能申明為虛函數(shù)(包括拷貝構(gòu)造函數(shù)。)12、純虛函數(shù)與抽象類純虛函數(shù):一個必須由派生類實現(xiàn)的基類的成員方法,其實質(zhì)是一個“占位符”。作用是告訴該基類的派生類,此方法必須由派生類實現(xiàn)。聲明方法:虛成員函數(shù)聲明=0;
如:virtualvoidGoToSchool()=0;抽象類:即包含了純虛函數(shù)的類。注意:抽象類不能實例化(即不能定義對象)面向?qū)ο蟪绦蛟O(shè)計——復(fù)習(xí)13、new和delete:在堆上申請和釋放內(nèi)存new的一般格式:
new類型(初值)
或new類型[數(shù)量]delete的一般格式:
delete指針 或delete[]指針1)、必須成對使用2)、new和delete在創(chuàng)建和刪除對象的時候會自動調(diào)用類的構(gòu)造函數(shù)和析構(gòu)函數(shù)。WINDOWS程序設(shè)計基礎(chǔ)基本概念:Windows程序設(shè)計是完全不同于Dos環(huán)境下的程序設(shè)計,是一種事件驅(qū)動的程序設(shè)計方法。主要是基于消息的。當用戶需要完成某種功能時,會調(diào)用操作系統(tǒng)的某種支持,操作系統(tǒng)將用戶的需要包裝成某種消息,并投遞到消息隊列當中。然后利用應(yīng)用程序從消息隊列中取走消息并進行響應(yīng)。消息:指Windows發(fā)出的一個通知,告訴應(yīng)用程序某個事情發(fā)生了,每一次鍵盤按鍵,鼠標單擊,窗口更新都會產(chǎn)生消息。程序中的消息:在WINDOWS開發(fā)中,一個消息被定義成了一個結(jié)構(gòu)體typedefStructtagMsg{//…}MSG;WINDOWS程序設(shè)計基礎(chǔ)MSG的內(nèi)部結(jié)構(gòu)typedefstructtagMSG{//msgHWNDhwnd;
UINTmessage;
WPARAMwParam;
LPARAMlParam;
DWORDtime;
POINTpt;
}MSG;
//消息來源的窗口句柄//消息ID//消息的附加參數(shù)//消息產(chǎn)生的時間//消息產(chǎn)生的窗口位置其為消息的實質(zhì),通常為WM_XXX的樣式//如鼠標消息WINDOWS程序設(shè)計基礎(chǔ)消息隊列:
操作系統(tǒng)會為每個應(yīng)用程序建立一個消息隊列。這個隊列是個先進先出的緩沖區(qū):消息響應(yīng):當應(yīng)用程序收到消息的時候,針對這個消息的進行處理的過程就叫消息響應(yīng)。消息1消息2……消息n消息產(chǎn)生消息響應(yīng)消息響應(yīng)是通過程序?qū)崿F(xiàn)的,這也是Windows應(yīng)用程序的主要代碼區(qū)。WINDOWS程序設(shè)計基礎(chǔ)消息的傳遞機制:檢索隊列中是否存在消息屬于某一個窗口WINDOWS程序設(shè)計基礎(chǔ)窗口:窗口是屏幕上的一個矩形區(qū)域WINDOWS程序設(shè)計基礎(chǔ)句柄(HANDLE):資源的標識
句柄,是整個windows編程的基礎(chǔ)。一個句柄是指一個用來標志應(yīng)用程序中的不同對象和同類對象中的不同的實例的唯一存在的32位整數(shù)值,其特性類似一個地址。
在Windows編程中,句柄可以看做是相關(guān)資源或?qū)嵗缫粋€窗口,按鈕,圖標,滾動條,輸出設(shè)備,控件或者文件等,的唯一標示。句柄在Windows編程中,大量使用,如HINSTANCE(實例句柄)HBITMAP(位圖句柄)HDC(設(shè)備描述表句柄)HICON(圖標句柄)實際上,WINDOWS編程中的所有句柄均統(tǒng)一為:HXXXWINDOWS程序設(shè)計基礎(chǔ)WINDOWS自定義類型簡介:
為了維護方便,WINDOWS將C/C++的內(nèi)建類型都進行了重新定義,其一般定義規(guī)則為:
typedeftypeTYPE;如:int對應(yīng)INT,char對應(yīng)CHAR,float對應(yīng)FLOAT
同時,WINDOWS還按照匈牙利命名法的相關(guān)規(guī)則對相關(guān)類型指針進行了重新定義,如LPSTR,PBYTE等。另外,WINDOWS還按照需要重新定義了一些類型,如WPARAM,LPARAM,WORD等,其實質(zhì)也是內(nèi)建類型的重命名。參考:ms-help://MS.VSCC.v90/MS.MSDNQTR.v90.chs/winprog/winprog/windows_data_types.htmWINDOWS程序設(shè)計基礎(chǔ)UNICODE簡介:傳統(tǒng)的英文字符采用的是ASCII編碼,但A的意思是American,這也是ASCII編碼最大的問題。而要表示中文、日語在內(nèi)的東方語系,ASCII就不能滿足要求,這時候引入了雙字節(jié)的UNICODE碼?!產(chǎn)’979700ASCIIUNICODEcharc=‘a(chǎn)’wchar_tc=‘a(chǎn)’“abc”char*p=“abc”;wchar_t*p=L“abc”;WINDOWS程序設(shè)計基礎(chǔ)C/C++語言的UNICODE類型以及對應(yīng)函數(shù):定義頭文件:wchar.hstrlenstrcatstrcpystrcmpASCII版UNICODE版getcwcslenwcscatwcscpywcscmpgetwcASCII版UNICODE版putcputwcputcharputwchargetchargetwcharprintfwprintfsprintfwsprintf類型:wchar_t實質(zhì):typedefunsignedshortwchar_tWINDOWS程序設(shè)計基礎(chǔ)練習(xí):請定義兩個UNICODE字符串,并將大的字符串連接到小的字符串后面。wchar_t*p1=L”Hello”;wchar_t*p2=L”myclass”;intnewLength=wcslen(p1)+wcslen(p2);wchar_t*p3=newwchar_t[newLength+1];if(wcscmp(p1,p2)){wcscpy(p3,p2);wcscat(p3,p1);}else{wcscpy(p3,p1);wcscat(p3,p2);}WINDOWS程序設(shè)計基礎(chǔ)WINDOWS程序中的UNICODE類型:TCHAR:解決通用的關(guān)鍵WINDOWS使用了一個預(yù)定義宏來解決可能存在的ASCII和UNICODE不通用問題,TCHAR!#ifdefUNICODEtypedefwchar_t
TCHAR#elsetypedefcharTCHAR同時,為了簡便操作,還定義了一個更簡短的宏_T/_TEXT,來表示一個通用字符串來源:#define_T(x)__T(x)UNICODE:#define__T(x)L##xASCII:#define__T(x)xWINDOWS程序設(shè)計基礎(chǔ)例:一個TCHAR數(shù)組TCHARt[10]={_T(“abcde”)};TCHARt[10]={‘a(chǎn)’,‘b’,‘c’,‘d’,‘e’};t[5]=‘d’;TCHAR*p=_T(“Hello”);intlen=lstrlen(p);TCHAR*q=_T(“World”);lstrcat(p,q);WINDOWS定義了一系列的操作TCHAR的函數(shù):lstrlenlstrcpylstrcpynlstrcatlstrcmpWINDOWS程序設(shè)計基礎(chǔ)WINDOWS程序中的定義的其他UNICODE類型:PCHAR,LPCH,PCH,LPSTR,PSTR=CHAR*(char*)LPCCH,PCCH,LPCSTR,PCSTR=CONST
CHAR*PWCHAR,LPWCH,PWCH,LPWSTR,PWSTR=WCHAR*LPCWCH,PCWCH,LPCWSTR,PCWSTR=CONST
WCHAR
CHAR*LPCTSTR=CONSTTCHAR*LPTSTR=TCHAR*WINDOWS程序設(shè)計基礎(chǔ)WINDOWSSDK程序設(shè)計WINDOWS程序設(shè)計基礎(chǔ)例:一個完整的程序HelloWindowsSDKWINDOWS程序設(shè)計基礎(chǔ)程序源代碼://helloWin.cpp#include<tchar.h>#include<Windows.h>#pragmacomment(lib,"Winmm.lib")LRESULTCALLBACKWndProc(HWND,UINT,WPARAM,LPARAM);intWINAPIWinMain(HINSTANCEhInstance,HINSTANCEhPrevInstance,LPSTRlpCmdLine,intiCmdShow){
//申明消息處理函數(shù)//WinMain函數(shù)入口,原型查閱MSDN//調(diào)用lib,為了聲音WINDOWS程序設(shè)計基礎(chǔ)staticTCHARszAppName[]=_T("Hello");HWNDhWnd;MSGmsg;WNDCLASSwndClass;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=szAppName;//程序名//窗口句柄//消息結(jié)構(gòu)體//窗口結(jié)構(gòu)體//窗口模式初始化//窗口過程函數(shù)//窗口實例句柄//讀取圖標//讀取光標//窗口背景設(shè)為白色//設(shè)置菜單//設(shè)置窗口類名WINDOWS程序設(shè)計基礎(chǔ)if(!RegisterClass(&wndClass)){MessageBox(NULL,_T("程序出錯"),szAppName,MB_ICONERROR);return0;}hWnd=CreateWindow(szAppName, _T("Hello"), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,NULL, NULL, hInstance, NULL);//注冊窗口//創(chuàng)建窗口//程序名和窗口名//窗口樣式//x和y坐標//高度和寬度//父窗口句柄//菜單句柄//實例句柄//附加參數(shù)WINDOWS程序設(shè)計基礎(chǔ)ShowWindow(hWnd,iCmdShow);UpdateWindow(hWnd);while(GetMessage(&msg,NULL,0,0)){ TranslateMessage(&msg); DispatchMessage(&msg);}returnmsg.wParam;}//WinMainEnd//顯示窗口//更新窗口,發(fā)送WM_PAINT//消息循環(huán)WINDOWS程序設(shè)計基礎(chǔ)LRESULTCALLBACKWndProc(HWNDhWnd,UINTmessage,WPARAMwParam,LPARAMlParam){HDChdc;PAINTSTRUCTps;RECTrect;switch{//…代碼見下頁}returnDefWindowProc(hWnd,message,wParam,lParam);}//定義一個設(shè)備上下文句柄//定義一個繪制結(jié)構(gòu)體//矩形區(qū)域//消息處理,見下頁//默認的消息處理函數(shù)WINDOWS程序設(shè)計基礎(chǔ)switch(message){caseWM_CREATE:PlaySound(_T("hello.wav"),NULL,SND_FILENAME|SND_ASYNC);return0;caseWM_PAINT: hdc=BeginPaint(hWnd,&ps);
GetClientRect(hWnd,&rect);
DrawText(hdc,_T("HelloWindowsSDK!"),-1,&rect,DT_SINGLELINE|DT_RIGHT|DT_BOTTOM); EndPaint(hWnd,&ps); return0;caseWM_DESTROY: PostQuitMessage(0); return0;}//對消息進行處理//處理WM_CREATE消息//處理WM_PAINT消息//關(guān)閉窗口消息WINDOWS程序設(shè)計基礎(chǔ)入口函數(shù):WinMainintWINAPIWinMain(
HINSTANCEhInstance,
HINSTANCEhPrevInstance,
LPSTRlpCmdLine,
intnShowCmd)當前實例之前實例命令行窗口顯示模式實例句柄字符串,typedefchar*LPSTR如同C/C++的Main函數(shù)一樣,WinMain代表了一個WINDOWS程序的入口點,其樣式必須保持不變。WINDOWS程序設(shè)計基礎(chǔ)WINDOWS程序設(shè)計基本流程:1、設(shè)計窗口typedefstruct_WNDCLASS{UINTstyle;WNDPROClpfnWndProc;intcbClsExtra;intcbWndExtra;HINSTANCEhInstance;HICONhIcon;HCURSORhCursor;HBRUSHhbrBackground;LPCTSTRlpszMenuName;LPCTSTRlpszClassName;}WNDCLASS;
窗口類型窗口過程函數(shù)指針當前應(yīng)用程序句柄圖標句柄光標句柄背景畫刷句柄窗口類名WNDCLASSwc;//初始化相關(guān)字段WINDOWS程序設(shè)計基礎(chǔ)2、注冊窗口RegisterClass(&wc);3、創(chuàng)建窗口HWNDCreateWindow(LPCTSTRlpClassName,//已注冊的窗口類的名字LPCTSTRlpWindowName,//窗口的名字,即標題欄上顯示的文字DWORDdwStyle,//窗口的類型intx,//窗口顯示時左上角的x坐標inty,//窗口顯示時左上角的y坐標intnWidth,//窗口寬度intnHeight,//窗口高度HWNDhWndParent,//父窗口的句柄HMENUhMenu,//菜單的句柄HINSTANCEhInstance,//實例的句柄LPVOIDlpParam//與窗口相關(guān)的附加參數(shù));HWNDhwnd=CreateWindow(…);WINDOWS程序設(shè)計基礎(chǔ)4、顯示和更新窗口ShowWindow(hWnd,iShowCmd);創(chuàng)建好的窗口句柄顯示狀態(tài)UpdateWindow(hWnd);5、開始消息循環(huán)MSGmsg;
while(GetMessage(&msg,NULL,0,0))
{ TranslateMessage(&msg);
//翻譯消息
DispatchMessage(&msg);
//分派消息
}來源于WinMain參數(shù),有3種狀態(tài):SW_SHOWNORMAL,SW_SHOWMAXMIZED,SW_SHOWMINNOACTIVEWINDOWS程序設(shè)計基礎(chǔ)消息循環(huán)相關(guān)函數(shù):BOOLGetMessage(LPMSGlpMsg,//消息
HWNDhWnd,//哪個窗口的消息隊列
UINTwMsgFilterMin,//消息的最小值
UINTwMsgFilterMax//消息的最大值);1)GetMessage:負責從消息隊列中獲取消息消息過濾2)TranslateMessage:翻譯消息BOOLTranslateMessage(constMSG*lpMsg);例:鍵盤按下某個鍵會產(chǎn)生WM_KEYDOWN消息,但是要知道到底按下的那個鍵,需將按鍵信息的ASCII碼插入消息,并翻譯為WM_CHAR消息進行處理。WINDOWS程序設(shè)計基礎(chǔ)2)DispatchMessage:分發(fā)消息DispatchMessage函數(shù)的作用是將收到的消息傳給窗口的回調(diào)函數(shù)(CallBackFunction),即窗口過程函數(shù)去處理。這個窗口過程函數(shù)就是在設(shè)計窗口類時指定的。回調(diào)函數(shù)的概念:回調(diào)函數(shù)是一個由開發(fā)者實現(xiàn),但交由系統(tǒng)自動調(diào)用的函數(shù)。其往往通過函數(shù)指針的方式賦值給某個其它函數(shù)或者數(shù)據(jù)結(jié)構(gòu)作為參數(shù)。窗口過程函數(shù)是一個典型的回調(diào)函數(shù)。WINDOWS程序設(shè)計基礎(chǔ)6、窗口過程函數(shù)(消息處理)。函數(shù)原型:LRESULTCALLBACKFuncName(
HWNDhWnd,
UINTmsg,
WPARAMwParam,
LPARAMlParam
)所屬窗口消息附加參數(shù)內(nèi)部結(jié)構(gòu):switch(msg){caseWM_XXX://Dosomething;//…}returnDefWindowProc(hWnd,Msg,wParam,lParam);函數(shù)名自定實際是一個unsignedintMFC程序設(shè)計基礎(chǔ)MFC程序設(shè)計,從向?qū)砷_始:選擇MFC應(yīng)用程序MFC程序設(shè)計基礎(chǔ)直接下一步MFC程序設(shè)計基礎(chǔ)選擇應(yīng)用程序類型:這里使用單文檔這里調(diào)節(jié)樣式MFC程序設(shè)計基礎(chǔ)這里可以設(shè)置擴展名,標題等MFC程序設(shè)計基礎(chǔ)數(shù)據(jù)庫支持,這里不選擇MFC程序設(shè)計基礎(chǔ)添加高級功能,這里不更改MFC程序設(shè)計基礎(chǔ)查看向?qū)傻念悾⒖筛鶕?jù)需要進行更改MFC程序設(shè)計基礎(chǔ)運行結(jié)果MFC程序設(shè)計基礎(chǔ)向?qū)傻某绦蚯鍐魏皖惽鍐危篗FC程序設(shè)計基礎(chǔ)如果把這里改成CEditViewMFC程序設(shè)計基礎(chǔ)
可見,利用MFC進行WINDOWS程序設(shè)計,相比SDK來說要方便的多但問題是MFC有SDK編程那種清晰結(jié)構(gòu)嗎?MFC程序設(shè)計基礎(chǔ)MFC中消失的WinMain試圖在項目中尋找WinMain會得到以下結(jié)果難道MFC中沒有入口點函數(shù)嗎?MFC的類層次結(jié)構(gòu)MFC是一個用面向?qū)ο筮M行封裝后的類層次結(jié)構(gòu)MFC的類層次結(jié)構(gòu)MFC9.0的所有類ms-help://MS.VSCC.v90/MS.MSDNQTR.v90.chs/dv_vclib/html/19d70341-e391-4a72-94c6-35755ce975d4.htmMFC的類層次結(jié)構(gòu)解析
從CWinApp派生出了CMyApp,代表應(yīng)用程序本身。
從CView派生出了CMyView,代表一個視圖窗口。
從CFrameWnd派生出了CMyFrameWnd,代表一個框架窗口。
線程類,實際上一個應(yīng)用程序就等于一個線程。
消息映射MFC的類層次結(jié)構(gòu)解析virtualBOOLInitInstance();virtualBOOLRun()virtualBOOLInitInstance();virtualBOOLRun()virtualBOOLInitApplication();virtualBOOLInitInstance();問題的關(guān)鍵:MFC程序怎么開始的呢?MFC程序的生死循環(huán)1、MFC程序的活水源頭,CMyWinApp的全局對象。2、鏈接期隱式鏈接的WinMain函數(shù)。//inAPPMODUL.CPP#define_tWinMainWinMain;MFC程序的生死循環(huán)3、真正的入口點,多態(tài)的威力:AfxWinMain()//inWINMAIN.CPP,AfxWinMain簡略版
AfxWinMain(…){ CWinApp*pApp=AfxGetApp(); pApp->InitApplication(); pApp->InitInstance(); pApp->Run(); AfxWinTerm();}獲取全局對象
由于CWinApp重寫,所以調(diào)用的是CWinApp的版本。
由于CMyApp重寫了InitInstance(),所以調(diào)用的是CMyApp的版本。MFC程序的生死循環(huán)3.1InitInstance,窗口的設(shè)計、注冊與創(chuàng)建//DOCTEMPL.CPP的264行CFrameWnd*pFrame=(CFrameWnd*)m_pFrameClass->CreateObject();在這個函數(shù)內(nèi)會通過new算子創(chuàng)建框架類CMainFrame。//DOCTEMPL.CPP的277行pFrame->LoadFrame(m_nIDResource,WS_OVERLAPPEDWINDOW|FWS_ADDTOTITLE,NULL,&context))在這個函數(shù)內(nèi)完成窗口類的注冊,產(chǎn)生主窗口并加掛菜單等諸元素,并指定窗口標題、文件標題、文件擴展名等。MFC程序的生死循環(huán)3.2InitInstance,窗口的顯示和更新m_pMainWnd是一個定義在CWinThread中的public成員,類型為CFrameWnd/CFrameWndEx;MFC程序的生死循環(huán)4、隱晦的消息循環(huán),pApp->Run();//inThredCore.cpp,Run簡單版由于派生類沒有重寫過Run(),所以這里調(diào)用的是CWinThread的版本。BOOLCWinThread::Run() {do GetMessage(); TranslateMessage(); DispathMessage(); }While(PeekMessage())MFC程序的生死循環(huán)5、不存在的窗口過程函數(shù),取而代之的消息映射消息映射的基本使用方法:DECLARE_MESSAGE_MAP()申明消息映射BEGIN_MESSAGE_MAP(類名,基類名)//消息映射END_MESSAGE_MAP()開始消息映射結(jié)束消息映射6,程序的結(jié)束:AfxWinTerm();MFC程序的生死循環(huán)不用向?qū)蒑FC程序:第一步:包含頭文件<afxwin.h>第二步:從CWinApp派生出CMyApp,重載虛函數(shù)InitInstance();classCMyApp:publicCWinApp{public:virtualBOOLInitInstance();}第三步:從CFrameWnd派生出CMyWnd,實現(xiàn)構(gòu)造函數(shù)以創(chuàng)建窗口。MFC程序的生死循環(huán)classCMyWnd:publicCFrameWnd{public:CMyWnd();
};第四步:為CMyWnd添加消息映射。DECLARE_MSG_MAP()BEGIN_MSG_MAP(CMyWnd,CFrameWnd)
END_MSG_MAP()ON_WM_PAINT()afx_msgvoidOnPaint();MFC程序的生死循環(huán)代碼清單://inhelloMFC.h#include<afxwin.h>classCMyApp:publicCWinApp
{public: virtualBOOLInitInstance();
};classCMyWnd:publicCFrameWnd{public: CMyWnd(); afx_msgvoidOnPaint(); DECLARE_MESSAGE_MAP();};MFC程序的生死循環(huán)//inhelloMFC.cppCMyAppmyApp;BOOLCMyApp::InitInstance()
{
m_pMainWnd=newCMyWnd;
m_pMainWnd->ShowWindow(SW_SHOW);
m_pMainWnd->UpdateWindow();
returnTRUE;}//forCMyWndBEGIN_MESSAGE_MAP(CMyWnd,CFrameWnd) ON_WM_PAINT()END_MESSAGE_MAP()MFC程序的生死循環(huán)CMyWnd::CMyMainWnd()
{
Create(NULL,_T("TheHelloApplication"));}voidCMyWnd::OnPaint(){ CPaintDCdc(this); CRectrect; GetClientRect(&rect); dc.DrawText(_T("HelloWorld"),-1,rect,DT_CENTER|DT_SINGLELINE|DT_VCENTER);}MFC程序的生死循環(huán)執(zhí)行結(jié)果:MFC程序的生死循環(huán)來龍去脈:隱式鏈接afx_msgvoidOnPaint();上述程序的創(chuàng)建步驟:創(chuàng)建一個Console程序,項目->屬性中修改以下設(shè)置:MFC重要概念——窗口封裝所有的Windows程序設(shè)計,可以說是基于消息和窗口的程序設(shè)計,幾乎所有常見的控件都可以說是一個窗口。出于這個理由,MFC將所有的窗口進行了抽象,得到了CWnd類,并從這個基類派生出了多種窗口和控件。對話框視圖類控件類框架類MFC重要概念——消息處理MFC采取了一套封裝后的消息處理機制,稱為消息映射。通過消息映射,將消息和相應(yīng)的消息處理函數(shù)綁定,從而實現(xiàn)了消息處理功能。使用規(guī)則如下:1、申明消息映射
要使用消息映射,首先要申明消息映射。在需要進行消息映射的類申明文件里面添加:DECLARE_MSG_MAP()實際上是一個預(yù)編譯宏,定義了一個用于存放消息的數(shù)據(jù)結(jié)構(gòu)和一個指向該數(shù)據(jù)結(jié)構(gòu)的數(shù)據(jù)結(jié)構(gòu)基類結(jié)構(gòu)消息處理MFC重要概念——消息處理2、開始消息循環(huán)要使用消息循環(huán),必須在類對應(yīng)的cpp文件中添加如下語句:
BEGIN_MESSAGE_MAP(派生類名,基類名)基類結(jié)構(gòu)基類結(jié)構(gòu)BEGIN_MESSAGE_MAP(derive,base)其實也是一個預(yù)編譯宏,其完成了派生類和基類消息的鏈接如:BEGIN_MESSAGE_MAP(CMyWnd,CFrameWnd)CMyWndCFrameWndMFC重要概念——消息處理3、填充消息映射以及定義消息處理函數(shù)在完成BEGIN_MESSAGE_MAP(derive,base)后,需要進行消息映射的填充,并定義對應(yīng)的消息處理函數(shù)。填充消息映射對應(yīng)afx_msgOnPaint()對應(yīng)afx_msgOnLButtonDown(UINT,CPoint)有afx_msg的函數(shù)才是消息處理函數(shù)MFC重要概念——消息映射模式
標準Windows消息的對應(yīng)規(guī)則
概念:標準Windows消息是指以“WM_”開頭的消息,有100多個,主要用于處理基本的繪制、鍵盤、鼠標等消息。對應(yīng)規(guī)則:一般情況下
WM_XXX
消息對應(yīng)的消息映射為ON_WM_XXX(),消息處理函數(shù)為afx_msg
OnXXX(…)WM_PAINTON_WM_PAINT()OnPaint()MFC根據(jù)消息類型不同,采取了四種不同的映射模式:如:WM_CHARON_WM_CHAR()OnChar()MFC重要概念——消息映射模式
例1:鼠標定位程序。當鼠標左鍵在窗口上點擊時,彈出消息框提示鼠標點擊位置。MFC重要概念——消息映射模式例1的實現(xiàn):第一步:利用向?qū)?chuàng)建一個基于對話框的MFC應(yīng)用程序MFC重要概念——消息映射模式第二步:添加對應(yīng)的消息映射
在生成的對話框程序中找到基類為CDialog的類(所在頭文件和源文件一般命名為CXXXDlg.h/cpp),在源文件中找到消息映射,添加ON_WM_LBUTTONDOWN(),以處理鼠標左鍵單擊消息。MFC重要概念——消息映射模式第三步:在類中添加對應(yīng)的消息處理函數(shù)第四步:實現(xiàn)該消息處理函數(shù)CString是一個字符串類,類似stringCString::Format(…),類似sprintf函數(shù),格式化字符串。CWnd::MessageBox(輸出文本,標題,樣式)字符分為unicode和ascii兩種,對應(yīng)wchar和char,這里的_T是一種自動判斷的手段。實際上MFC中定義了一種通用字符TCHAR,也會自動判斷MFC重要概念——消息映射模式ON_COMMAND消息ON_COMMAND消息主要是為了映射菜單命名,其基本映射規(guī)則為:ON_COMMAND(<命令id>,<memberFxn>);其處理函數(shù)的原型均為:afx_msgvoidmemberFxn();例:如何建立菜單,并響應(yīng)菜單消息。菜單創(chuàng)建和ON_COMMAND例:如何建立菜單,并響應(yīng)菜單消息。第一步:利用向?qū)?chuàng)建一個單文檔程序第二步:切換到資源視圖第三步:打開Menu,并選擇
IDR_MAINFRAME第四步:雙擊進入編輯模式MFC重要概念——消息映射模式續(xù)前例:第五步,添加一個菜單Test,取消Popup屬性,ID取名ID_TEST_MENU。菜單的Popup樣式:Popup菜單是一種頂層菜單,其可以包含子菜單但一般不響應(yīng)消息,如word里面的“文件”菜單就是個Popup菜單。MFC重要概念——消息映射模式第六步,添加消息處理函數(shù)和消息映射。MFC重要概念——消息映射模式執(zhí)行結(jié)果:MFC重要概念——消息映射模式補充:上例第六步消息映射的向?qū)砑幽J剑哼x擇哪個類響應(yīng)消息選擇消息類型輸入消息處理函數(shù)名MFC重要概念——消息映射模式ON_CONTROL/ON_NOTIFY
這兩個消息映射都是用于控件,如按鈕、列表、編輯框等的消息,這兩個消息映射的原型如下:ON_CONTROL(<wNotifyCode>,<id>,<memberFxn>)ON_NOTIFY(<wNotifyCode>,<id>,<memberFxn>)消息代碼控件id消息處理函數(shù)對應(yīng)消息處理函數(shù)原型:ON_CONTROL:afx_msgvoidMemberFunction();ON_NOTIFY:afx_msgvoidMemberFunction(NMHDR*pNotifyStruct,LRESULT*result);一個附加信息的數(shù)據(jù)結(jié)構(gòu)MFC重要概念——消息映射模式例:按鈕消息的使用。第一步:前例的基于對話框的應(yīng)用程序,切換到資源視圖,雙擊Dialog,利用工具箱添加按鈕。MFC重要概念——消息映射模式第二步:添加消息處理,使用ON_CONTROL向?qū)傻臑镺N_BN_CLICKED(IDC_BUTTON1,處理函數(shù))MFC重要概念——消息映射模式自定義消息映射:ON_MESSAGEMFC允許用戶自己定義消息,自定義消息必須在WM_USER的基礎(chǔ)上定義,且自定消息的消息映射使用ON_MESSAGE。自定義消息的一般格式:#defineCUSMSGWM_USER+N;N最大可以是0x7FFF。ON_MESSAGE的原型:ON_MESSAGE(<msgID>,<func>)如:#defineBEGINADDWM_USER+5MFC重要概念——消息映射模式自定義消息映射:ON_MESSAGEON_MESSAGE的消息處理函數(shù)原型:afx_msgLRESULTFuncName(WPARAM,LPARAM)實際上是一個long實際上是一個unsignedint,主要用作一些特殊參數(shù)的傳送。自定義消息一般需要通過發(fā)送消息傳遞,原型為:LRESULT
CWND::SendMessage(
UINT
message,
WPARAM
wParam
=
0,
LPARAM
lParam
=
0
);
MFC重要概念——消息映射模式例:一個加法的自定義消息處理,以前面的對話框程序為基礎(chǔ)第一步:定義一個自己的消息第二步:申明消息處理函數(shù)第三步:消息映射第四步:消息處理MFC重要概念——消息映射模式第五步:當按鈕按下的時候發(fā)送消息MFC重要概念——資源文件MFC生成的代碼中包括了兩個文件:Resource.h和xxx.rc,這兩個文件實際上包含了當前應(yīng)用程序所使用的所有MFC的資源。.rc文件
xxx.rc文件包含了整個工程的所有資源信息,包括對話框、位圖、菜單、圖標、工具欄以及字符串等資源;他們的大小,風(fēng)格,字體等屬性信息,都包含在其中;一般情況下不用去寫和修改,由MFC自動維護MFC重要概念——資源文件Resource.h文件
Resource.h文件包含了整個工程的所有資源信息的常量定義:ID的命名規(guī)則MFC重要概念——消息處理3、填充消息映射以及定義消息處理函數(shù)填充消息映射以及定義消息處理函數(shù)實際上是為了形成消息循環(huán)基類結(jié)構(gòu)基類結(jié)構(gòu)CFrameWndCMyWndmsgHandler1msgHandler2msgHandler1msgHandler2基類結(jié)構(gòu)CWndmsgHandler1msgHandler2
形成這樣的消息循環(huán)的最大的好處是:消息可以在循環(huán)中流動,某些派生類處理不了或不愿處理的消息可以交由基類處理。MFC重要概念——消息處理MFC存在的消息循環(huán)示例深入閱讀:《深入淺出MFC》MFC重要概念——繪制(CDC)WINDOWS采用了GraphicsDeviceInterface(GDI,圖形設(shè)備接口)來進行圖形輸出,其基本機制是設(shè)備描述表(DC,DeviceContext)。而MFC將GDI利用面向?qū)ο筮M行了重新封裝,從而形成了CDC類,使用系統(tǒng)提供的DC進行圖形輸出和繪制。CDC的使用在MFC應(yīng)用程序中使用CDC進行繪圖一般有三種模式,第一種:在普通程序中
CDC*pDC=GetDC();//Drawsomething;
ReleaseDC(pDC);必須成對出現(xiàn)MFC重要概念——繪制(CDC)CDC的第二種使用方式:在WM_PAINT消息對應(yīng)的消息處理函數(shù)afx_msgvoidOnPaint()中。PAINTSTRUCTps;CDC*pDC=BeginPaint(&ps);//DrawsomethingEndPaint(&ps);必須成對出現(xiàn)WM_PAINT消息:WM_PAINT消息是一個重要的初始化消息,一個窗口在產(chǎn)生的時候所有的繪制工作都由該消息處理(對話框由OnDraw處理),并且當窗口刷新的時候,都會產(chǎn)生WM_PAINT消息進行重繪。如果想對窗口進行自定義繪制,都應(yīng)該覆蓋來自基類的WM_PAINT消息對應(yīng)的處理函數(shù)OnPaint()進行繪制。MFC重要概念——繪制(CDC)CDC的第三種使用方式:如果不想僅在當前窗口繪圖,而想在整個窗口的任意地方繪圖。這時候應(yīng)該使用CWnd::GetWindowDC()代替CWnd::GetDC(),并繼續(xù)使用ReleaseDC()釋放。由于CDC有多種使用方式,為了減輕記憶負擔,MFC對這三種方式進行了重新的封裝,類圖如下:CObject除OnPaint外的繪制向GDI文件繪圖OnPaint專用在窗口任意位置繪圖MFC重要概念——繪制(CDC)例1:在前例手動生成的MFC程序中加入以下功能,點擊窗口出現(xiàn)自動畫兩條對角線,在整個窗口的左上角畫圓。實現(xiàn)步驟:第一步:添加WM_PAINT和WM_LBUTTONDOWN消息映射提示:和WM_LBUTTONDOWN類似的鼠標消息還有WM_L/R/MBUTTONUP,WM_R/MBUTTONDOWN/UP,WM_L/R/MBUTTONDBCLICKMFC重要概念——繪制(CDC)針對第一個功能:在非OnPaint畫圖CRect是一個矩形類voidCDC::MoveTo(intx,inty);將DC移動到某一個位置voidCDC::LineTo(intx,inty);DC從上一位置開始畫一條線到傳入的(x,y)坐標。MFC重要概念——繪制(CDC)客戶窗口(ClientWindow)和窗口的概念。窗口,可以理解為桌面或者屏幕客戶窗口,即當前運行的程序的窗口(0,0)(0,0)voidCWnd::GetWindowRect(LPRECTlpRect)voidCWnd::GetClientRect(LPRECTlpRect)MFC重要概念——繪制(CDC)父窗口和子窗口的概念:CWnd*CWnd::GetParent()CWnd*CWnd::GetParent()獲取父窗口的大小CWnd*pWnd=GetParent();pWnd->GetClientRect(&rect);MFC重要概念——繪制(CDC)針對功能2:假設(shè)鼠標右鍵點擊窗口后,在左上角畫一個圓第一步:添加消息映射第二步:實現(xiàn)Ellipse,畫圓的原型MFC重要概念——繪制(CDC)設(shè)備描述表的屬性:
設(shè)備描述表(DC)可以看做是一個繪制工具,我們可以根據(jù)需要,設(shè)置該工具的屬性,從而完成相應(yīng)功能。MFC重要概念——繪制(CDC)例3:文本和背景顏色設(shè)置文本顏色可以使用CDC::SetTextColor(COLORREFref)COLORREF實際上是一個RGB一般用法RGB(X,X,X)紅色:RGB(255,0,0)綠色:RGB(0,255,0)藍色:RGB(0,0,255)常用顏色:MFC重要概念——繪制(CDC)上例的實現(xiàn)代碼:基于手動生成的MFC框架//inOnPaintCDC::DrawText原型intDrawText(
constCString&str,
LPRECTlpRect,
UINTnFormat
);
這是一個排版模式,一般使用DT_CENTER(水平居中)|DT_VCENTER(垂直居中)MFC重要概念——繪制(CDC)將上例代碼進行修改:MFC重要概念——繪制(CDC)畫筆(CPen)和畫刷(CBrush)的使用例4:矩形繪制:當鼠標點擊窗口的某個位置時,以這個位置為起點,畫一個長為200,寬為100的矩形。MFC重要概念——繪制(CDC)例4的部分代碼展示:調(diào)用Crect的構(gòu)造函數(shù)構(gòu)造BOOL
Rectangle(
int
x1,
int
y1,
int
x2,
int
y2
);
BOOL
Rectangle(
LPCRECT
lpRect
);
函數(shù)原型:MFC重要概念——繪制(CDC)更改例4的要求為畫一個帶有紅色邊框的矩形:修改后的代碼:MFC重要概念——繪制(CDC)例4修改后的代碼解析:CPen*pPen=newCPen(PS_SOLID,2,RGB(255,0,0));構(gòu)造了一個CPen的對象,CPen的構(gòu)造函數(shù)有如下原型:CPen(
int
nPenStyle,
int
nWidth,
COLORREF
crColor
);
筆的屬性,可以是PS_SOLID(實線),PS_DASH(虛線),PS_DOT(點線)等。筆的寬度,以像素為單位。MFC重要概念——繪制(CDC)例4修改后的代碼解析:CPen*pOldPen=dc.SelectObject(pPen);設(shè)備描述表選擇使用pPen作為當前的畫筆,并返回之前使用的畫筆。CPen*
SelectObject(
CPen*
pPen
);
CBrush*
SelectObject(
CBrush*
pBrush
);
virtual
CFont*
SelectObject(
CFont*
pFont
);
CBitmap*
SelectObject(
CBitmap*
pBitmap
);
int
SelectObject(
CRgn*
pRgn
);
CGdiObject*SelectObject(
CGdiObject*pObject
);
CDC::SelectObject的功能就是為當前設(shè)備描述表選擇一種“工具”來進行繪制,并返回之前使用的“工具”所以使用完后要恢復(fù)原“工具”:MFC重要概念——繪制(CDC)更改例4的要求為畫一個紅色的矩形:修改后的代碼:MFC重要概念——繪制(CDC)代碼解析:CBrush*pBr=newCBrush(RGB(255,0,0));構(gòu)造了一個CBrush的對象,CBrush的構(gòu)造函數(shù)有如下原型:nIndex所有取值的樣式CBrush(
COLORREF
crColor
);
CBrush(
int
nIndex,
COLORREF
crColor
);explicitCBrush(CBitmap*pBitmap);
MFC重要概念——繪制(CDC)補充,CBitmap的使用VC++可以很方便的顯示圖片,特別是BMP格式。要顯示一張圖片一般有如下的步驟。1、準備一張大小合適的BMP圖片。2、在資源視圖里,利用導(dǎo)入資源導(dǎo)入該圖片。3、構(gòu)建一個CBitmap的對象,利用CBitmap::LoadBitmap(UINT)讀取該圖片。4、利用畫刷就可以將圖片“刷”到屏幕的特定位置。MFC重要概念——繪制(CDC)例:CBitmap的使用1、準備一張217x221的圖片。2、導(dǎo)入該圖片3、導(dǎo)入完成后會自動取名為IDB_BITMAPX補充—資源與資源文件為當前代碼加入資源文件,繪制一個圖標:切換到資源視圖后:補充—資源與資源文件VS會為每個添加的資源按照一定的命名規(guī)則進行ID的設(shè)置也可以自行設(shè)置,右鍵,屬性在ID一欄進行修改,同時注意Filename一欄,有一個icon1.ico標注,該文件存放位置為:當前項目名\項目名\這是一個相對路徑,當前項目名類似于程序安裝文件夾,因此,為了統(tǒng)一管理資源,可以在當前項目名\項目名下建立不同的資源文件夾管理資源。游戲程序設(shè)計—資源與資源文件注意:資源ID也可以是字符串加載資源往往使用LoadXXX函數(shù),對應(yīng)參數(shù)一般為(以Cbitmap為例)://資源字符串名//資源ID名另外:有些函數(shù)要求傳入資源ID的字符串形式,這時候可以使用MAKEINTRASOURCE宏MFC重要概念——繪制(CDC)4、創(chuàng)建CBitmap對象,LoadBitmap,并構(gòu)造位圖畫刷在CView及派生類中要實現(xiàn)畫圖功能,不需要處理WM_PAINT,而只需要重載CView::OnDraw函數(shù)MFC重要概念——繪制(CDC)例4:經(jīng)過兩次修改以后的結(jié)果是:有一個黑色的邊框,什么原因?怎么去除呢?主要原因是:邊框的線使用CPen來畫,所以應(yīng)該創(chuàng)建一支紅色的筆。MFC重要概念——繪制(CDC)拓展訓(xùn)練:利用鼠標寫字。MFC重要概念——繪制(CDC)代碼展示(基于無向?qū)傻腗FC程序):第一步:為窗口類添加成員變量,以保存當前鼠標位置,并添加BOOL變量記錄是否開始繪制第二步:添加消息映射,處理WM_MOUSEMOVE(鼠標移動)和WM_LBUTTONDOWN消息第三步:在WM_LBUTTONDOWN的消息處理函數(shù)中:操作系統(tǒng)會將鼠標點擊的位置傳到這個point里。MFC重要概念——繪制(CDC)第四步:在WM_MOUSEMOVE的消息處理函數(shù)中:其基本邏輯是:如果目前處于畫線狀態(tài),首先移動到上一個起點A,然后從點A畫一條到當前點B的線,并且保存當前點B位下一次繪制的起點。MFC重要概念——繪制(CDC)繪制的映射模式:簡單的說,映射模式是設(shè)備描述表(DC)的一個屬性,用于確定邏輯坐標值到設(shè)備坐標值的一個轉(zhuǎn)換。如:dc.Rectangle(CRect(0,0,200,100));我們知道這是畫了一個長為200,寬為100的矩形,但是單位是多少呢?是厘米還是英寸還是像素呢?這時候可以使用CDC::SetMapMode(UINTmode)來設(shè)置。但是SetMapMode還有一個功能是設(shè)置起點坐標和坐標軸方向。MFC重要概念——繪制(CDC)常用的映射模式及坐標軸對應(yīng):映射模式一個邏輯單位對應(yīng)的距離X軸和Y軸的方向MM_TEXT1像素左上角(0,0)+x+yMM_LOMETRIC0.1MM+x-yMM_HIMETRIC0.01MM+x-yMM_LO/HIENGLISH0.1/0.01IN+x-yMFC重要概念——繪制(CDC)例5:基于前例沒有用向?qū)傻腗FC框架,以鼠標點擊為起點畫一個長為200mm,寬為30mm的具有藍色邊框的綠色矩形。實例代碼:(省略消息映射)//創(chuàng)建一個藍色畫筆和一個綠色畫刷//使用創(chuàng)建的畫筆和畫刷并保存原工具//1邏輯單位對應(yīng)0.1mm//設(shè)置映射模式后,y軸向下為負,所以-300運行結(jié)果不正常MFC重要概念——繪制(CDC)例5結(jié)果運行不正常的原因:
由于我們平時使用坐標系的時候是邏輯坐標系,而不是物理坐標。而在設(shè)置映射模式后,原本鼠標點下的位置point的坐標代表的單位卻不再是邏輯坐標而是以0.1毫米為單位的坐標,這就造成了運行的不正常。因此,應(yīng)該將point轉(zhuǎn)換為邏輯坐標。使用:voidCDC::DPtoLP(
LPPOINT
lpPoints,
int
nCount
=
1
)
const;
voidCDC::DPtoLP(
LPRECT
lpRect
)
const;
voidCDC::DPtoLP(
LPSIZE
lpSize
)
const;
MFC重要概念——繪制(CDC)例5的正常代碼:將鼠標點擊位置的設(shè)備(物理)坐標轉(zhuǎn)換為邏輯坐標。MFC重要概念——繪制(CDC)繪圖模式:例6.1:橡皮筋線的繪制
基本思路:和用鼠標寫字的例子類似,但不同的是我們需要保留一開始的起點,以便鼠標左鍵放開后,能繪制一條從原始起點到開始起點的線。同時,需要保留當前鼠標移動到的位置,以繪制一條從起點到當前鼠標位置的線。鼠標按下的起點鼠標移動時的點鼠標放開時的終點MFC重要概念——繪制(CDC)第一步:添加一個保存鼠標點擊起點的變量第二步:在OnLButtonDown消息處理函數(shù)中保存起點坐標。第三步:在OnMouseMove消息處理函數(shù)中畫線。MFC重要概念——繪制(CDC)運行結(jié)果:有問題鼠標按下的起點鼠標移動時的點鼠標放開時的終點問題的關(guān)鍵是原來畫的線沒有被刪
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 自建公寓轉(zhuǎn)讓合同模板
- 蘇寧超市加盟合同模板
- GPS基礎(chǔ)知識培訓(xùn)課件
- 老房子翻新合同模板
- 保價協(xié)議合同模板
- 店鋪租店鋪合同模板
- 吊裝手勢圖片及吊裝現(xiàn)場圖片
- 社團演出贊助合同模板
- 定做地坪工程合同模板
- 2024年大學(xué)生憲法知識競賽經(jīng)典題庫及答案(50題)
- 頸椎病的治療
- 小班美術(shù)《小刺猬背果果》課件
- 人教版數(shù)學(xué)三年級上冊《1-4單元綜合復(fù)習(xí)》試題
- 空調(diào)水系統(tǒng)管道冷量、流量及管徑計算方法和選取表
- 皮下氣腫護理查房
- 西方經(jīng)濟學(xué) 課件 10 失業(yè)與通貨膨脹理論
- 快速康復(fù)外科在泌尿外科患者圍手術(shù)期護理中的應(yīng)用進展
- 婦科護理宮頸炎盆腔炎的護理
- 第6課《求助電話》課件
- 防火封堵報價范本
- 奇正藏藥行業(yè)分析
評論
0/150
提交評論