孫鑫VC學(xué)習(xí)筆記_第1頁
孫鑫VC學(xué)習(xí)筆記_第2頁
孫鑫VC學(xué)習(xí)筆記_第3頁
孫鑫VC學(xué)習(xí)筆記_第4頁
孫鑫VC學(xué)習(xí)筆記_第5頁
已閱讀5頁,還剩65頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

1、孫鑫VC+視頻筆記列表(全)簡 介 第一課 Windows程序內(nèi)部運行機制 第二課 MFC程序框架的剖析 第三課 MFC消息映射機制和DC的獲取 第四課 簡單字處理軟件 第五課 菜單編程 第六課 對話框編程1 第七課 對話框編程2 第八課 MFC中各類指針的獲取 第九課 應(yīng)用程序外觀修改 第十課 圖形繪制與通用對話框 第十一課 圖形保存和重繪 第十二課 文件操作 第十三課 文檔和串行化 第十四課 網(wǎng)絡(luò)編程 第十五課 多線程和簡單聊天室制作 第十六課 線程同步與異步套接字編程 第十七課 進程間通信 第十八課 ActiveX 控件 第十九課 動態(tài)鏈接庫 第二十課 Hook鉤子函數(shù) 第0章 簡介 L

2、esson1:Windows程序運行原理及程序編寫流程,窗口產(chǎn)生過程,句柄原理,消息隊列,回調(diào)函數(shù),窗口關(guān)閉與應(yīng)用程序退出的工作關(guān)系,使用VC+的若干小技巧,stdcall與cdecl調(diào)用規(guī)范的比較,初學(xué)者常犯錯誤及注意事項。 Lesson2:C+經(jīng)典語法與應(yīng)用,類的編寫與應(yīng)用,構(gòu)造與析構(gòu)函數(shù),函數(shù)的重載,類的繼承,函數(shù)覆蓋,基類與派生類的構(gòu)造函數(shù)、析構(gòu)函數(shù)先后調(diào)用順序,如何在派生類構(gòu)造函數(shù)中向基類的構(gòu)造函數(shù)傳遞參數(shù),this成員變量,類型轉(zhuǎn)換的內(nèi)幕,虛擬函數(shù)與多態(tài)性,引用和指針變量的區(qū)別與共同處。VC工程的編譯原理與過程,將工程中不同的類拆分到不同的文件中,每一個類由一個.h和.cpp文件共

3、同完成,頭文件重復(fù)定義問題的解決,培養(yǎng)了學(xué)員良好的編程習(xí)慣,也為以后分析MFC AppWizard生成的工程奠定了良好基礎(chǔ)。 Lesson3:講述MFC AppWizard的原理與MFC程序框架的剖析。AppWizard是一個源代碼生成工具,是計算機輔助程序設(shè)計工具,WinMain在MFC程序中是如何從源程序中被隱藏的,theApp全局變量是如何被分配的,MFC框架中的幾個類的作用與相互關(guān)系,MFC框架窗口是如何產(chǎn)生和銷毀的,對窗口類的PreCreateWidow和OnCreate兩個函數(shù)的著重分析,Windows窗口與C+中的CWnd類的關(guān)系。 Lesson4:MFC消息映射機制的剖析,講述

4、如何運用ClassWizard,理解發(fā)送給窗口的消息是如何被MFC框架通過窗口句柄映射表和消息映射表來用窗口類的函數(shù)進行響應(yīng)的。掌握設(shè)備描述表及其封裝類CDC的使用,CDC是如何與具體的設(shè)備發(fā)生關(guān)聯(lián)的,融合具體的畫圖程序進行分析。如何設(shè)置封閉圖形的填充刷子(位圖畫刷與透明畫刷的使用)。 Lesson5:掌握CDC的文字處理程序的編寫,如何產(chǎn)生自定義字體和自定義插入符,熟悉對CString類的使用。通過對卡拉OK程序的編寫,講解定時器的使用和DrawText函數(shù)的巧妙運用。講解如何使用CDC的裁減功能。 Lesson6:菜單的工作原理及編寫應(yīng)用,菜單命令消息在MFC框架程序的幾個類中的傳遞順序和

5、處理過程。標(biāo)記菜單、缺省菜單的實現(xiàn)原理、圖形菜單的實現(xiàn)及常犯錯誤的分析,GetSystemMetrics的應(yīng)用,快捷彈出菜單的實現(xiàn)方式及其命令響應(yīng)函數(shù)有效范圍(與彈出菜單時所指定的父窗口有密切的關(guān)系,最底層的子窗口具有最優(yōu)先的處理機會)。動態(tài)菜單的編寫,如何讓程序在運行時產(chǎn)生新的菜單項及如何手工為這些新產(chǎn)生的菜單命令安排處理函數(shù),如何在頂層窗口中截獲對菜單命令的處理,更進一步掌握CString類的應(yīng)用。 Lesson7:對話框用戶界面程序的編寫,如何向?qū)υ捒蚩丶P(guān)聯(lián)數(shù)據(jù)成員及其實現(xiàn)機理,如何利用對話框類的成員函數(shù)向控件發(fā)送消息和獲取對話框控件的類指針,如何直接利用對話框控件類操縱對話框控件(發(fā)

6、送消息和直接調(diào)用成員函數(shù))。如何在程序運行時產(chǎn)生和銷毀控件。對話框控件的幾種操作方式的優(yōu)劣比較分析。如何實現(xiàn)對話框的部分收縮和展開。如何讓對話框上的文本框在程序啟動后立即獲得焦點,如何利用SetWindowLong改變窗口的回調(diào)函數(shù),通過改變文本框的默認回車處理方式進行演示。實現(xiàn)多個輸入文本框間通過回車逐一向下傳遞焦點的另一種巧妙方法(用缺省按鈕來處理)。 Lesson8:逃跑按鈕的巧妙實現(xiàn)。如何制作屬性頁對話框和向?qū)υ捒?,融合講解組合框(如何調(diào)整組合框的大?。?、列表框、單選按鈕、復(fù)選按鈕等常用對話框控件的多種使用方法。如何限制用戶在不滿足設(shè)定的條件時切換到其他屬性頁和向?qū)ы摗?Lesson

7、9:如何修改MFC AppWizard向?qū)傻目蚣艹绦虻耐庥^和大小,修改圖標(biāo)、光標(biāo)、背景的三種方法。如何增加和刪除工具欄按鈕,如何給應(yīng)用程序增加工具欄,如何顯示和隱藏工具欄。定制狀態(tài)欄,在狀態(tài)欄中添加時鐘顯示,CTime類及其用法。在狀態(tài)欄中添加進度條(主窗口產(chǎn)生后立即產(chǎn)生進度條的巧妙思想,不能在OnCreate函數(shù)中直接處理,要用到自定義消息的方法)。鼠標(biāo)坐標(biāo)顯示,在CView中獲取狀態(tài)欄對象的幾種方式。如何為應(yīng)用程序添加啟動畫面。Lesson10:圖形的繪制,如何使用自定義畫筆(顏色,線寬,線型)。如何為程序中添加選項菜單和選項設(shè)置對話框,如何使用標(biāo)準(zhǔn)顏色對話框,如何使用字體對話框,在選

8、項對話框中實現(xiàn)預(yù)覽功能。實現(xiàn)選項對話框和窗口類中的數(shù)據(jù)交換。如何改變對話框和控件的背景色,如何改變控件的文本顏色,對按鈕控件的特殊處理。如何在窗口中顯示一幅位圖。 Lesson11:如何讓CDC上輸出的文字、圖形具有保持功能,集合類CPtrArray的使用,CPaintDC與CClientDC的區(qū)別與應(yīng)用,OnPaint與OnDraw在CView中的關(guān)系及實現(xiàn)內(nèi)幕,滾動窗口的實現(xiàn),坐標(biāo)空間,映射方式,設(shè)備坐標(biāo)與邏輯坐標(biāo)的轉(zhuǎn)換。元文件設(shè)備描述表的使用,如何利用兼容DC實現(xiàn)圖形的保存和再現(xiàn)。 Lesson12:const char *與char * const的區(qū)別。C語言對文件讀寫的支持,F(xiàn)IL

9、E指針;文本文件和二進制文件的區(qū)別。用文本方式讀寫文件和以二進制方式讀寫文件的注意事項。C+對文件讀寫的支持,ofstream和ifstream的用法。Win32 SDK對文件讀寫的支持,CreateFile函數(shù)、WriteFile函數(shù)、ReadFile函數(shù)的使用;MFC對文件讀寫的支持,CFile類和CFileDialog的使用,文件過濾器的設(shè)置。win.ini文件和注冊表的讀寫方式及相關(guān)知識點。 Lesson13:使用CArchive類對文件進行操作。MFC框架程序提供的文件新建與打開功能內(nèi)部的實現(xiàn)機制。如何利用CDocument類的串行化存儲功能保存與加載數(shù)據(jù)。如何實現(xiàn)類對串行化的支持,

10、CObArray的串行化實現(xiàn)內(nèi)幕。刪除文檔數(shù)據(jù)時常犯的錯誤。MFC框架程序的文檔類和視類的關(guān)系,以及如何獲得相互的指針引用。 Lesson14:網(wǎng)絡(luò)的相關(guān)知識,網(wǎng)絡(luò)程序的編寫,Socket是連接應(yīng)用程序與網(wǎng)絡(luò)驅(qū)動程序的橋梁,Socket在應(yīng)用程序中創(chuàng)建,通過bind與驅(qū)動程序建立關(guān)系。此后,應(yīng)用程序送給Socket的數(shù)據(jù),由Socket交給驅(qū)動程序向網(wǎng)絡(luò)上發(fā)送出去。計算機從網(wǎng)絡(luò)上收到與該Socket綁定的IP+Port相關(guān)的數(shù)據(jù)后,由驅(qū)動程序交給Socket,應(yīng)用程序便可從該Socket中提取接收到的數(shù)據(jù)。網(wǎng)絡(luò)應(yīng)用程序就是這樣通過socket進行數(shù)據(jù)的發(fā)送與接收的。TCP與UDP的工作原理與編

11、寫過程,如何在程序中鏈接庫文件。一個字符界面的聊天程序。 Lesson15:多線程程序的編寫,多線程應(yīng)用中容易出現(xiàn)的問題?;コ鈱ο蟮闹v解,如何使用互斥對象來實現(xiàn)多線程的同步。如何利用命名互斥對象保證應(yīng)用程序只有一個實例運行。應(yīng)用多線程編寫網(wǎng)絡(luò)聊天室程序。 Lesson16:事件內(nèi)核對象、關(guān)鍵代碼段(臨界區(qū))的講解,以及在多線程同步中的應(yīng)用。在Windows下編寫基于消息的網(wǎng)絡(luò)應(yīng)用程序,掌握阻塞與非阻塞網(wǎng)絡(luò)程序的編寫,理解在Windows平臺下,采用異步選擇機制可以提高網(wǎng)絡(luò)應(yīng)用程序的性能。 Lesson17:詳細講解進程間通訊的四種方式:剪貼板、匿名管道、命名管道和郵槽。并比較分析這幾種進程間通

12、信的優(yōu)點和缺點。 Lesson18:ActiveX控件的應(yīng)用與工作原理。ActiveX控件的編寫,如何為控件安排屬性,方法,事件,屬性頁,持久性存儲,控件如何通知容器自身屬性的改變。如何注冊控件與取消控件注冊。在VB和VC中訪問ActiveX控件。Lesson19:動態(tài)鏈接庫程序的編寫。靜態(tài)庫與動態(tài)庫的區(qū)別,以及調(diào)用程序在鏈接靜態(tài)庫和動態(tài)庫時的區(qū)別。如何利用工具查看動態(tài)鏈接庫輸出的函數(shù),Depends工具的使用,C+編譯器名字改編技術(shù)對動態(tài)鏈接庫輸出函數(shù)的影響,extern C的用法,利用模塊定義文件來解決C+名字改編的問題。用typedef定義指向函數(shù)的指針類型,如何獲得動態(tài)連接庫里的函數(shù)的

13、指針。Lesson20:Hook編程。如何安裝鉤子過程,如何編寫全局鉤子,動態(tài)連接庫里的全局變量數(shù)據(jù)共享問題分析。ADO數(shù)據(jù)庫編程。在VB中利用ADO控件和ADO對象訪問數(shù)據(jù)庫,在VC中利用ADO技術(shù)訪問數(shù)據(jù)庫。 第一章 Windows程序內(nèi)部運行機制 這一章比較零散,筆記也很零散 一、windows是事件驅(qū)動方式的程序設(shè)計windows程序設(shè)計是一種事件驅(qū)動方式的程序設(shè)計,主要是基于消息的。當(dāng)用戶需要完成某種功能時,需要調(diào)用OS(操作系統(tǒng))某種支持,然后OS將用戶的需要包裝成消息,并投入到消息隊列中,最后應(yīng)用程序從消息隊列中取走消息并進行響應(yīng)。 二、消息隊列每個應(yīng)用程序OS都為它建立一個消息

14、隊列,消息隊列是個先進先出的緩沖區(qū),其中每個元素都是一個消息,OS將生成的每個消息按先后順序放進消息隊列中,應(yīng)用程序總是取走當(dāng)前消息隊列中的第一條消息,應(yīng)用程序取走消息后便知道用戶的操作和程序的狀態(tài),然后對其處理即消息響應(yīng),消息響應(yīng)通過編碼實現(xiàn)。 三、Window程序入口WinMain函數(shù)是Windows程序入口點函數(shù),由OS調(diào)用,當(dāng)OS啟動應(yīng)用程序的時候,winmain函數(shù)的參數(shù)由OS傳遞的。 四、創(chuàng)建一個完整的窗口需要經(jīng)過下面四個操作步驟1, 設(shè)計一個窗口類。如:WNDCLASS wndcls。2, 注冊窗口類。如:RegisterClass(&wndcls)。3, 創(chuàng)建窗口。如:Crea

15、teWindow(),CreateWindowEX();4, 顯示及更新窗口。如:ShowWindow(),UpdateWindow();其他值得注意的地方1, 消息結(jié)構(gòu)typedef struct tagMSG / msg HWND hwnd; /接收消息的窗口句柄。和哪個窗口相關(guān)聯(lián)。 UINT message; /消息標(biāo)識。消息本身是什么。 WPARAM wParam; /消息的附加信息。具體取決于消息本身。 LPARAM lParam; DWORD time; /消息投遞時間。 POINT pt; /消息投遞時,光標(biāo)在屏幕上的位置。 MSG;2, 掌握windows的消息機制需要掌握兩方

16、面:(1)消息本身。不同消息所代表的用戶操作和應(yīng)用程序的狀態(tài)。(2)對于某個特定的消息來說,要讓OS執(zhí)行某個特定的功能去響應(yīng)消息。3, Window入口函數(shù)說明int WINAPI WinMain( HINSTANCE hInstance, / 當(dāng)前事例句柄。 HINSTANCE hPrevInstance, / 先前事例句柄。32位系統(tǒng)中此值都為NULL LPSTR lpCmdLine, / 命令行指針 int nCmdShow / (窗口)顯示的狀態(tài));要帶參調(diào)用WinMain,類似于命令行的功能,在ProjectsettingDebug頁Program arguments項填寫參數(shù)4,

17、Windows提供的窗口類詳解typedef struct _WNDCLASS UINT style; /窗口的類型 WNDPROC lpfnWndProc; /窗口過程函數(shù)指針(回調(diào)函數(shù)) int cbClsExtra; /窗口類附加字節(jié),為該類窗口所共享。通常0。 int cbWndExtra; /窗口附加字節(jié)。通常設(shè)為0。 HANDLE hInstance; /當(dāng)前應(yīng)用程序事例句柄。 HICON hIcon; /圖標(biāo)句柄 LoadIcon(); HCURSOR hCursor; /光標(biāo)句柄 LoadCursor(); HBRUSH hbrBackground; /畫刷句柄 (HBRUSH

18、)GetStockObject(); LPCTSTR lpszMenuName; /菜單名字 LPCTSTR lpszClassName; /類的名字 WNDCLASS;5, 消息循環(huán):MSG msg;while(GetMessage(&msg,.) /從消息隊列中取出一條消息 TranslateMessage(&msg); /進行消息(如鍵盤消息)轉(zhuǎn)換 DispatchMessage(&msg); /分派消息到窗口的回調(diào)函數(shù)處理,(OS調(diào)用窗口回調(diào)函數(shù)進行處理)。6, 回調(diào)函數(shù)LRESULT CALLBACK WindowProc( /這里WindowProc是個代號名字。 HWND hwn

19、d, / handle to window UINT uMsg, / message identifier WPARAM wParam, / first message parameter LPARAM lParam / second message parameter);說明:兩種函數(shù)調(diào)用約定(_stdcall 和 _cdecl):#define CALLBACK _stdcall /_stdcall 標(biāo)準(zhǔn)調(diào)用預(yù)定,是PASCAL 調(diào)用約定,象DELPHI使用的就是標(biāo)準(zhǔn)調(diào)用約定#define WINAPIV _cdecl / _cdecl 是C 語言形式的調(diào)用約定。主要區(qū)別:函數(shù)參數(shù)傳遞順序

20、 和 對堆棧的清除上。問題:除了那些可變參數(shù)的函數(shù)調(diào)用外,其余的一般都是_stdcall約定。但 C/C+編譯默然的是_cdecl約定。所以如果在VC等環(huán)境中調(diào)用_stdcall約定的函數(shù),必須要在函數(shù)聲明的時加上 _stdcall 修飾符,以便對這個函數(shù)的調(diào)用是使用_stdcall約定(如使用DELPHI編寫的DLL時候)。(VC中可通過這途徑修改:projectsettingsc/c+categary選”Code Generation”,出現(xiàn)Call convention選項,修改之)7, DC句柄的使用(1)使用BeginPaint(),EndPaint()對。注意只能在響應(yīng)WM_PAI

21、NT消息時使用。(2)使用GetDc(),ReleaseDC()對。注意他們不能在響應(yīng)WM_PAINT中使用。8, 其它(1)函數(shù)名代表函數(shù)的首地址。(2)創(chuàng)建窗口的時候一定要基于已經(jīng)注冊的窗口類.第二章 MFC程序框架的剖析說明:本課對應(yīng)教學(xué)視頻的第三課,第二課是C+,被我跳過去。C+我打算另外在用多點的篇幅來討論。重點:MFC運行機制提示:對于不想理解內(nèi)部運行過程的,可以不看這一章,可以看了后面的界面設(shè)計再回頭來看這一章,可能感覺更深刻。這一次課和上一次的課的重點就是MFC的窗口類創(chuàng)建過程,而要反復(fù)說明的就是:MFC的程序和C語言的程序,從執(zhí)行原理上說,是完全一致的。抓住這一點,那么對于理

22、解MFC程序的運行機制也就相對于簡單了。C中的main函數(shù)就相當(dāng)于MFC中的WinMain函數(shù)。感興趣的可以利用VC的斷點設(shè)置自己跟蹤下面講述的各個函數(shù),就明白它的執(zhí)行順序了。一、C語言程序執(zhí)行步驟在C語言中,大約的步驟如下:1, 全局變量內(nèi)存分配2, 進入main函數(shù)二、MFC程序的運行步驟(主要是初始化)打開一個MFC APPWizard(exe)工程,跟蹤其執(zhí)行步驟,可以發(fā)現(xiàn),是以下順序:1) CXXApp中的全局變量定義CXXApp theApp;2) 調(diào)用CXXApp構(gòu)造函數(shù)CXXApp :CXXApp()3) 進入Winmain函數(shù)(_tWinMain為宏,值為WinMain)_t

23、WinMain()4) 完成初始化工作:包括窗口類注冊、窗口產(chǎn)生、顯示和更新pThread-InitInstance()對于MFC程序,MainFrame,View,ToolBar,Controlbar等都是窗口,所以下面的窗口注冊與創(chuàng)建、顯示等要反復(fù)調(diào)用多次,一次對應(yīng)一個窗口(1) 注冊窗口類AfxEndDeferRegisterClass(2) 創(chuàng)建窗口CMainFrame:PreCreateWindow()/反復(fù)調(diào)用一次是給我們修改窗口屬性的機會CFrameWnd:Create()(3) 消息循環(huán)PumpMessage()補充1:在MFC中,由于涉及到(窗口)類定義,所以定義全局變量的時

24、候,需要進行更多的步驟。全局變量涉及到類定義(類似于C中的類型定義)的話,那么需要遵循以下步驟(以MFC的窗口類為例)1) 設(shè)計一個窗口類2) 注冊窗口類3) 創(chuàng)建窗口4) 顯示及更新窗口5) 消息循環(huán)補充2:其他需要注意的幾點1, 每一個MFC程序,有且只有一個從WinApp類派生的類(應(yīng)用程序類),也只有一個從應(yīng)用程序類所事例化的對象,表示應(yīng)用程序本身。在WIN32程序當(dāng)中,表示應(yīng)用程序是通過WINMAIN入口函數(shù)來表示的(通過一個應(yīng)用程序的一個事例號這一個標(biāo)識來表示的)。在基于MFC應(yīng)用程序中,是通過產(chǎn)生一個應(yīng)用程序?qū)ο?,用它來唯一的表示了?yīng)用程序。2, _tWinMain函數(shù)中通過調(diào)用

25、AfxWinMain()函數(shù)來完成它要完成的功能。(Afx*前綴代表這是應(yīng)用程序框架函數(shù),是一些全局函數(shù),應(yīng)用程序框架是一套輔助生成應(yīng)用程序的框架模型,把一些類做一些有機的集成,我們可根據(jù)這些類函數(shù)來設(shè)計自己的應(yīng)用程序)。3, 設(shè)計窗口類:在MFC中事先設(shè)計好了幾種缺省的窗口類,根據(jù)不同的應(yīng)用程序的選擇,調(diào)用AfxEndDeferRegisterClass()函數(shù)注冊所選擇的窗口類。4, PreCreateWindow()是個虛函數(shù),如果子類有則調(diào)用子類的。5, CreateWindowEx()函數(shù)參數(shù)與CREATESTRUCT結(jié)構(gòu)體成員完全一致,CreateWindowEx()函數(shù)與CREA

26、TESTRUCT結(jié)構(gòu)體參數(shù)的對應(yīng)關(guān)系,使我們在創(chuàng)建窗口之前通過可PreCreateWindow(cs)修改cs結(jié)構(gòu)體成員來修改所要的窗口外觀。6,注意兩個函數(shù)。:TranslateMessage(&m_msgCur)函數(shù)進行消息(如鍵盤消息)轉(zhuǎn)換:DispatchMessage(&m_msgCur)函數(shù)分派消息到窗口的回調(diào)函數(shù)處理(實際上分派的消息經(jīng)過消息映射,交由消息響應(yīng)函數(shù)進行處理。)7,可以認為View類窗口是CMainFram類窗口的子窗口。DOCument類是文檔類。DOC-VIEW結(jié)構(gòu)將數(shù)據(jù)本身與它的顯示分離開。文檔類用于數(shù)據(jù)的存儲,加載;視類用于數(shù)據(jù)的顯示,修改8,CTEApp:

27、InitInstance()函數(shù)中通過文檔模板將文檔類,視類,框架類的有機組織一起。語句如下:CSingleDocTemplate* pDocTemplate;pDocTemplate = new CSingleDocTemplate( IDR_MAINFRAME, RUNTIME_CLASS(CTEDoc), RUNTIME_CLASS(CMainFrame), / main SDI frame window RUNTIME_CLASS(CTEView);AddDocTemplate(pDocTemplate);/增加到模板補充3:本課涉及到MFC函數(shù)的源文件位置根目錄找到您安裝VC98下M

28、FC的位置,比如我的機子上為:D:Program FilesMicrosoft Visual StudioVC98MFC。下面提供的就是相對路徑了。CWinApp構(gòu)造函數(shù): MFCSRCAPPCORE.CPPAfxWinMain:MFCSRCWINMAIN.CPPAfxEndDeferRegisterClass: MFCSRCAPPCORE.CPPCFrameWnd:PreCreateWindow()函數(shù)所在文件:MFCSRCWINFRM.CPPCFrameWnd:Create()函數(shù)路徑:MFCSRCWINFRM.CPPCWnd:CreateEx()函數(shù)路徑:MFCSRCWINCORE.CP

29、PCWinThread:Run()方法路徑:MFCSRCTHRDCORE.CPP第三章 MFC消息映射機制和繪圖DC的獲取我們假設(shè)您已經(jīng): 1,知道如何創(chuàng)建一個單文檔的App Wizard 2,知道C+ 類、函數(shù)重載等簡單知識 3,知道如何給View類或者Doc文檔添加成員變量 4,會用MFC的IDE調(diào)試工具最好,那么本文的程序您可以copy去調(diào)試 我們在上一節(jié)講了MFC框架App類、View類、MainFrame類和Doc類的關(guān)系,那么,基于消息的windows MFC程序設(shè)計是如何進行消息映射的呢? 在進行下一節(jié)之前,我們來復(fù)習(xí)一下。 對于一個MFC APPWizard運用程序,CMain

30、Frame和View是窗口類,并且是父子關(guān)系,Doc一般用于數(shù)據(jù)的加載和存儲,View用于圖像的顯示,App中是包括一些(窗口)初始化之類的東西。 我們開始這一節(jié)的內(nèi)容。一、 消息映射機制windows程序設(shè)計是種事件驅(qū)動方式的程序設(shè)計,主要基于消息的。當(dāng)用戶需要完成某種功能時,需要調(diào)用OS某種支持,然后OS將用戶的需要包裝成消息,并投入到消息隊列中,最后應(yīng)用程序從消息隊列中取走消息并進行響應(yīng)。在左邊View類處點右鍵,在出現(xiàn)的菜單里點擊“Add Windows Message Handler”,在出現(xiàn)的對話框里選擇“WM_LBUTTONDOWN”,添加消息映射函數(shù)。回到原文件,我們將看到三處

31、進行了修改:1, 在頭文件(View.h)中聲明消息響應(yīng)函數(shù)原型。/AFX_MSG(CDrawView) /注釋宏afx_msg void OnLButtonDown(UINT nFlags, CPoint point);/AFX_MSG /注釋宏afx_msg宏表示聲明的是一個消息響應(yīng)函數(shù)。2, 在源文件(View.cpp)中進行消息映射。BEGIN_MESSAGE_MAP(CDrawView, CView) /AFX_MSG_MAP(CDrawView) ON_WM_LBUTTONDOWN() /AFX_MSG_MAP在宏BEGIN_MESSAGE_MAP()與END_MESSAGE_MA

32、P()之間進行消息映射。宏ON_WM_LBUTTONDOWN()把消息WM_LBUTTONDOWN與它的響應(yīng)函數(shù)OnLButtonDown()相關(guān)聯(lián)。這樣一旦有消息的產(chǎn)生,就會自動調(diào)用相關(guān)聯(lián)的消息響應(yīng)函數(shù)去處理。宏ON_WM_LBUTTONDOWN()定義如下: #define ON_WM_LBUTTONDOWN() WM_LBUTTONDOWN, 0, 0, 0, AfxSig_vwp, (AFX_PMSG)(AFX_PMSGW)(void (AFX_MSG_CALL CWnd:*)(UINT, CPoint)&OnLButtonDown ,3, 源文件中進行消息響應(yīng)函數(shù)處理。void CD

33、rawView:OnLButtonDown(UINT nFlags, CPoint point) / TODO: Add your message handler code here and/or call default CView:OnLButtonDown(nFlags, point);說明:可見當(dāng)增加一個消息響應(yīng)處理,在以上三處進行了修改。可在消息響應(yīng)函數(shù)里添加消息處理代碼完成對消息的響應(yīng)、處理。消息響應(yīng)的可能方式:1)在基類中針對每種消息做一個虛函數(shù),當(dāng)子類對消息響應(yīng)時候,只要在子類中重寫這個虛函數(shù)即可。缺點:MFC類派生層次很多,如果在基類對每個消息進行虛函數(shù)處理,那么從基類派生的

34、每個子類都將背負一個龐大的虛表,這樣浪費內(nèi)存,故MFC沒有采取這中方式而采取消息映射方式。2)消息映射方式:MFC在后臺維護了一個句柄和C+對象指針對照表,當(dāng)收到一個消息后,通過消息結(jié)構(gòu)里資源句柄(查對照表)就可找到與它對應(yīng)的一個C+對象指針,然后把這個指針傳給基類,基類利用這個指針調(diào)用WindowProc()函數(shù)對消息進行處理,WindowProc()函數(shù)中調(diào)用OnWndMsg()函數(shù),真正的消息路由及處理是由OnWndMsg()函數(shù)完成的。由于WindowProc()和OnWndMsg()都是虛函數(shù),而且是用派生類對象指針調(diào)用的,由多態(tài)性知最總終調(diào)用子類的。在OnWndMsg()函數(shù)處理的

35、時候,根據(jù)消息種類去查找消息映射,判斷所發(fā)的消息有沒有響應(yīng)函數(shù),具體方式是到相關(guān)的頭文件和源文件中尋找消息響應(yīng)函數(shù)聲明(從注釋宏/AFX_MSG(CDrawView)./AFX_MSG之間尋找),消息映射(從宏BEGIN_MESSAGE_MAP(.).END_MESSAGE_MAP()之間尋找),最終找到對應(yīng)的消息處理函數(shù)。當(dāng)然,如果子類中沒有對消息進行處理,則消息交由基類處理。說明:virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam);virtual BOOL OnWndMsg(UINT message,

36、 WPARAM wParam, LPARAM lParam, LRESULT* pResult);二、 繪圖DC的獲取說明:在View類添加WM_LBUTTONDOWN和WM_LBUTTONUP的消息處理函數(shù),我們將用來演示各種DC的獲取,以及顯示效果。View類添加全局變量CPoint m_ptOrigin用來存儲左鍵按下點坐標(biāo)。下面集中來關(guān)注OnLButtonUp中的繪圖程序和效果。以下語句添加于OnLButtonUp函數(shù)中,可以查看不同的效果。1,使用SDK獲取DC句柄:HDC hdc;hdc=:GetDc(m_hWnd);/獲取DC句柄MoveToEx(hdc,m_ptOrigin.x

37、,m_ptOrigin.y,NULL);LineTo(hdc,point.x,point.y);:ReleaseDC(m_hWnd,hdc);/釋放DC2,利用CDC類指針和CWin類成員函數(shù)獲取DC。CDC *pDC=GetDC();pDC-MoveTo(m_ptOrigin);pDC-LineTo(point);ReleaseDC(pDC);3,利用CClientDC對象。(CClientDC類從CDC類派生來的)CClientDC dc(this);dc.MoveTo(m_ptOrigin);dc.LineTo(point);4,利用CWindowDC對象。(CWindowDC類從CDC

38、類派生來的)CWindowDC dc(this);/dc.MoveTo(m_ptOrigin);dc.LineTo(point);5,父窗口(MainFrame框架)和屏幕指針。將上面的dc(this)分別改成GetParent()和GetDesktopWindow(),就可以得到父窗口指針和屏幕窗口指針??梢苑謩e試驗畫線效果。6,利用畫筆改變線條顏色和類型:CPen pen(PS_DOT,1,RGB(0,255,0);/構(gòu)造畫筆對象CClientDC dc(this);CPen *pOldPen=dc.SelectObject(&pen);/將畫筆選入DCdc.MoveTo(m_ptOrig

39、in);dc.LineTo(point);dc.SelectObject(pOldPen);/恢復(fù)先前的畫筆7,使用畫刷(通常利用畫刷去填充矩形區(qū)域):使用單色畫刷CBrush brush(RGB(255,0,0);/構(gòu)造畫刷對象CClientDC dc(this);dc.FillRect(CRect(m_ptOrigin,point),&brush);/用指定的畫刷去填充矩形區(qū)域使用位圖畫刷CBitmap bitmap;/構(gòu)造位圖對象(使用前需要初試化)bitmap.LoadBitmap(IDB_BITMAP1);/初試化位圖對象CBrush brush(&bitmap);/構(gòu)造位圖畫刷CC

40、lientDC dc(this);dc.FillRect(CRect(m_ptOrigin,point),&brush);/用指定的位圖畫刷去填充矩形區(qū)域使用透明畫刷CBrush *pBrush=CBrush:FromHandle(HBRUSH)GetStockObject(NULL_BRUSH);/獲取透明畫刷對象指針CClientDC dc(this);CBrush *pOldBrush=dc.SelectObject(pBrush);/將透明畫刷選入DCdc.Rectangle(CRect(m_ptOrigin,point);dc.SelectObject(pOldBrush);/釋放透

41、明畫刷8,注意點:1)靜態(tài)方法不屬于某一個具體對象,而屬于類本身,在類加載的時候就已經(jīng)為類靜態(tài)方法分配了代碼去,故可用CBrush:FromHandle()形式調(diào)用。2)靜態(tài)方法中,不能引用非靜態(tài)的數(shù)據(jù)成員和方法。3)靜態(tài)數(shù)據(jù)成員需要在類外單獨做初始化,形式如: 變量類型 類名:變量名=初始值;第四章 文本編輯和字處理軟件這一節(jié)我們主要講述文本編輯方面的知識,孫鑫老師的視頻就是一個簡單字處理軟件的制作過程,所以我也是按照順序,敘述此過程。在MFC中CEditView 和 cRichEditView類已經(jīng)完成了初步的文字處理??梢宰寫?yīng)用程序的View類以CEditView 和 cRichEdit

42、View類為基類。下面我們以單文檔視圖為例一、創(chuàng)建插入符。文字在插入符后插入(正如Word中閃爍的光標(biāo))1, 添加View類的WM_CREATE消息響應(yīng)函數(shù)2, 在CXXXView:OnCreate()中添加/獲得當(dāng)前文本度量/字體信息CClientDC dc(this);TEXTMETRIC tm;dc.GetTextMetrics(&tm);/根據(jù)當(dāng)前字體,設(shè)置插入符/光標(biāo)CreateSolidCaret(20,100); /*ShowCaret();3, 創(chuàng)建圖形插入符1),為View類添加成員變量m_bmp;2),把上面的*行用如下語句替換m_bmp.LoadBitmap(IDB_BI

43、TMAP1);CreateCaret(&m_bmp);4, 二、 輸出文字在OnDraw函數(shù)中添加如下代碼1),簡單輸出文字CString str;str=維新科學(xué)技術(shù)培訓(xùn)中心;pDC-TextOut(50,50,str);2),獲取文字框大小備用 CSize sz=pDC-GetTextExtent(str);3),給str重新賦值,以區(qū)別于上一個內(nèi)容。當(dāng)然,之前需要在String Table中添加IDS_WEIXIN str.LoadString(IDS_WEIXIN);pDC-TextOut(0,200,str);4),添加路徑層當(dāng)作圖的時候,如果想要在整幅圖形其中的某個部分和其它部分有

44、所區(qū)別,我們可以把這部分圖形放到路徑層當(dāng)中,然后指定調(diào)用指定互操作模式調(diào)用SelectClipPath( int nMode )函數(shù)來使路徑層和覆蓋在其上新繪圖剪切區(qū)域進行互操作,達到特殊效果。pDC-BeginPath();pDC-Rectangle(50,50,50+sz.cx,50+sz.cy);/路徑層的坐標(biāo)依賴于上面的文字位置pDC-EndPath();pDC-SelectClipPath(RGN_DIFF);5),畫一些方格,看看路徑層的效果。for(int i=0;iMoveTo(0,i);pDC-LineTo(300,i); pDC-MoveTo(i,0);pDC-LineTo

45、(i,300);三、鼠標(biāo)移動插入符給View增加兩個成員變量:CString m_strLine用于存儲當(dāng)前輸入行的內(nèi)容;CPoint m_ptOrigin用于保存鼠標(biāo)移動引起插入符改變時的新行開始位置在OnLButtonDown函數(shù)中添加如下內(nèi)容SetCaretPos(point);/設(shè)置插入符位置m_strLine.Empty();m_ptOrigin=point;/保存此位置另外,給View添加兩個變量四、響應(yīng)鍵盤輸入鍵盤響應(yīng)需要考慮如下內(nèi)容:1, 鼠標(biāo)點擊鍵盤輸入一個字符,顯示到鍵盤上,插入符/光標(biāo)后移一位。2, 回車之后,光標(biāo)下移一行3, 刪除/退格鍵的響應(yīng)下面是程序內(nèi)容:1,給Vi

46、ew類添加WM_CHAR消息響應(yīng)函數(shù)2,在OnChar函數(shù)中添加如下語句CClientDC dc(this);CFont font;font.CreatePointFont(300,華文行楷,NULL);CFont *pOldFont=dc.SelectObject(&font);TEXTMETRIC tm;dc.GetTextMetrics(&tm);if(0x0d=nChar)/回車鍵響應(yīng)程序段 m_strLine.Empty(); m_ptOrigin.y+=tm.tmHeight;else if(0x08=nChar) /用背景色模擬最后一個字符的消失 COLORREF clr=dc.

47、SetTextColor(dc.GetBkColor(); dc.TextOut(m_ptOrigin.x,m_ptOrigin.y,m_strLine); m_strLine=m_strLine.Left(m_strLine.GetLength()-1); dc.SetTextColor(clr);elsem_strLine+=nChar;CSize sz=dc.GetTextExtent(m_strLine);CPoint pt;pt.x=m_ptOrigin.x+sz.cx;pt.y=m_ptOrigin.y;SetCaretPos(pt);dc.TextOut(m_ptOrigin.x

48、,m_ptOrigin.y,m_strLine);dc.SelectObject(pOldFont);五、平滑變色-類似卡拉OK的跟唱文字顏色改變CDC:TextOut()是一個字母一個字母的輸出,達不到平滑效果。CDC:DrawText():將文字的輸出局限于一個矩形區(qū)域,超出矩形區(qū)域的文字都被截斷。利用這一特點,可每隔些時間增加矩形大小,從而可實現(xiàn)人眼中的平滑效果。1,設(shè)置定時器。在View中OnCreate或者其他地方添加SetTimer(1,100,NULL);2,給View類添加WM_TIMER消息響應(yīng)函數(shù)3,給View添加成員變量int m_nWidth用于保存顏色隨時間流逝變化的

49、起點4,在OnTimer中添加如下代碼m_nWidth+=5;/每次位置增加CClientDC dc(this);TEXTMETRIC tm;dc.GetTextMetrics(&tm);/獲取字體屬性CRect rect(0,200, m_nWidth,200+ tm.tmHeight);dc.SetTextColor(RGB(255,0,0);CString str;str.LoadString(IDS_WEIXIN);dc.DrawText(str,rect,DT_LEFT);rect.top=150;rect.bottom=rect.top+tm.tmHeight;dc.DrawTex

50、t(str,rect,DT_RIGHT);CSize sz=dc.GetTextExtent(str);if(m_nWidthsz.cx) m_nWidth=0; dc.SetTextColor(RGB(0,255,0); dc.TextOut(0,200,str);簡單字處理軟件大功告成!第五章 VC菜單相關(guān)編程 閱讀本文前,我們假設(shè)您已經(jīng): 1,知道如何創(chuàng)建一個單文檔的App Wizard 2,知道C+ 類、函數(shù)重載等簡單知識 3,知道如何給View類或者Doc文檔添加成員變量 4,會用MFC的IDE調(diào)試工具最好,那么本文的程序您可以copy去調(diào)試 5,知道如何為某個框架類添加虛函數(shù)或消息

51、處理函數(shù)一、消息的分類:消息的分類:標(biāo)準(zhǔn)消息,命令消息,通告消息。標(biāo)準(zhǔn)消息:除WM_COMMAND之外,所有以WM_開頭的消息。命令消息:來自菜單、加速鍵或工具欄按鈕的消息。這類消息都以WM_COMMAND呈現(xiàn)。在MFC中,通過菜單項的標(biāo)識(ID)來區(qū)分不同的命令消息;在SDK中,通過消息的wParam參數(shù)識別。通告消息:由控件產(chǎn)生的消息,例如,按鈕的單擊,列表框的選擇等均產(chǎn)生此類消息,為的是向其父窗口(通常是對話框)通知事件的發(fā)生。這類消息也是以WM_COMMAND形式呈現(xiàn)。注意:1)從CWnd派生的類,都可以接收到標(biāo)準(zhǔn)消息、命令消息和通告消息。2)從CCmdTarget派生的類,都可以接收

52、到命令消息和通告消息。3)CCmdTarget是CWnd的父類二、菜單消息傳遞過程MFC中菜單項消息如果利用ClassWizard來對菜單項消息分別在上述四個類中進行響應(yīng),則菜單消息傳遞順序:View類Doc類CMainFrame類App類。菜單消息一旦在其中一個類中響應(yīng)則不再在其它類中查找響應(yīng)函數(shù)。當(dāng)點擊一個菜單項的時候,最先接受到菜單項消息的是CMainFrame框架類,CMainFrame框架類將會把菜單項消息交給它的子窗口View類,由View類首先進行處理;如果View類檢測到?jīng)]對該菜單項消息做響應(yīng),則View類把菜單項消息交由文檔類Doc類進行處理;如果Doc類檢測到Doc類中也沒

53、對該菜單項消息做響應(yīng),則Doc類又把該菜單項消息交還給View類,由View類再交還給CMainFrame類處理。如果CMainFrame類查看到CMainFrame類中也沒對該消息做響應(yīng),則最終交給App類進行處理。三、菜單指針的獲取,及相關(guān)設(shè)置在CMainFrame:OnCreate下可以直接實驗以下操作幾個相關(guān)和重要的函數(shù)CMenu* GetMenu( ) ;/CWnd:GetMenu得到窗口菜單欄對象指針。CMenu* GetSubMenu( ) ;/CMenu:GetSubMenu獲得指向彈出菜單對象指針UINT CheckMenuItem( );/CMenu:CheckMenuItem Adds check marks to or removes check marks f

溫馨提示

  • 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)容負責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論