VC++深入詳解學(xué)習(xí)筆記(非常全面)_第1頁(yè)
VC++深入詳解學(xué)習(xí)筆記(非常全面)_第2頁(yè)
VC++深入詳解學(xué)習(xí)筆記(非常全面)_第3頁(yè)
VC++深入詳解學(xué)習(xí)筆記(非常全面)_第4頁(yè)
VC++深入詳解學(xué)習(xí)筆記(非常全面)_第5頁(yè)
已閱讀5頁(yè),還剩60頁(yè)未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡(jiǎn)介

/孫鑫孫鑫VC++視頻筆記列表(全)簡(jiǎn)介第一課 Windows程序內(nèi)部運(yùn)行機(jī)制第二課?MFC程序框架的剖析第三課 MFC消息映射機(jī)制和DC的獲取第四課 簡(jiǎn)單字處理軟件第五課 菜單編程第六課對(duì)話框編程1第七課對(duì)話框編程2第八課MFC中各類指針的獲取第九課應(yīng)用程序外觀修改第十課 圖形繪制與通用對(duì)話框第十一課圖形保存和重繪第十二課文件操作第十三課文檔和串行化第十四課網(wǎng)絡(luò)編程第十五課多線程和簡(jiǎn)單聊天室制作第十六課線程同步與異步套接字編程第十七課進(jìn)程間通信第十八課ActiveX控件第十九課動(dòng)態(tài)鏈接庫(kù)第二十課Hook鉤子函數(shù)第0章簡(jiǎn)介L(zhǎng)esson1:Windows程序運(yùn)行原理及程序編寫流程,窗口產(chǎn)生過程,句柄原理,消息隊(duì)列,回調(diào)函數(shù),窗口關(guān)閉與應(yīng)用程序退出的工作關(guān)系,使用VC++的若干小技巧,stdcall與cdecl調(diào)用規(guī)范的比較,初學(xué)者常犯錯(cuò)誤及注意事項(xiàng)。Lesson2:C++經(jīng)典語(yǔ)法與應(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工程的編譯原理與過程,將工程中不同的類拆分到不同的文件中,每一個(gè)類由一個(gè)。h和。cpp文件共同完成,頭文件重復(fù)定義問題的解決,培養(yǎng)了學(xué)員良好的編程習(xí)慣,也為以后分析MFCAppWizard生成的工程奠定了良好基礎(chǔ)。Lesson3:講述MFCAppWizard的原理與MFC程序框架的剖析。AppWizard是一個(gè)源代碼生成工具,是計(jì)算機(jī)輔助程序設(shè)計(jì)工具,WinMain在MFC程序中是如何從源程序中被隱藏的,theApp全局變量是如何被分配的,MFC框架中的幾個(gè)類的作用與相互關(guān)系,MFC框架窗口是如何產(chǎn)生和銷毀的,對(duì)窗口類的PreCreateWidow和OnCreate兩個(gè)函數(shù)的著重分析,Windows窗口與C++中的CWnd類的關(guān)系.Lesson4:MFC消息映射機(jī)制的剖析,講述如何運(yùn)用ClassWizard,,理解發(fā)送給窗口的消息是如何被MFC框架通過窗口句柄映射表和消息映射表來用窗口類的函數(shù)進(jìn)行響應(yīng)的.掌握設(shè)備描述表及其封裝類CDC的使用,CDC是如何與具體的設(shè)備發(fā)生關(guān)聯(lián)的,融合具體的畫圖程序進(jìn)行分析。如何設(shè)置封閉圖形的填充刷子(位圖畫刷與透明畫刷的使用).Lesson5:掌握CDC的文字處理程序的編寫,如何產(chǎn)生自定義字體和自定義插入符,熟悉對(duì)CString類的使用。通過對(duì)卡拉OK程序的編寫,講解定時(shí)器的使用和DrawText函數(shù)的巧妙運(yùn)用。講解如何使用CDC的裁減功能。Lesson6:菜單的工作原理及編寫應(yīng)用,菜單命令消息在MFC框架程序的幾個(gè)類中的傳遞順序和處理過程。標(biāo)記菜單、缺省菜單的實(shí)現(xiàn)原理、圖形菜單的實(shí)現(xiàn)及常犯錯(cuò)誤的分析,GetSystemMetrics的應(yīng)用,快捷彈出菜單的實(shí)現(xiàn)方式及其命令響應(yīng)函數(shù)有效范圍(與彈出菜單時(shí)所指定的父窗口有密切的關(guān)系,最底層的子窗口具有最優(yōu)先的處理機(jī)會(huì))。動(dòng)態(tài)菜單的編寫,如何讓程序在運(yùn)行時(shí)產(chǎn)生新的菜單項(xiàng)及如何手工為這些新產(chǎn)生的菜單命令安排處理函數(shù),如何在頂層窗口中截獲對(duì)菜單命令的處理,更進(jìn)一步掌握CString類的應(yīng)用。Lesson7:對(duì)話框用戶界面程序的編寫,如何向?qū)υ捒蚩丶P(guān)聯(lián)數(shù)據(jù)成員及其實(shí)現(xiàn)機(jī)理,如何利用對(duì)話框類的成員函數(shù)向控件發(fā)送消息和獲取對(duì)話框控件的類指針,如何直接利用對(duì)話框控件類操縱對(duì)話框控件(發(fā)送消息和直接調(diào)用成員函數(shù)).如何在程序運(yùn)行時(shí)產(chǎn)生和銷毀控件。對(duì)話框控件的幾種操作方式的優(yōu)劣比較分析。如何實(shí)現(xiàn)對(duì)話框的部分收縮和展開。如何讓對(duì)話框上的文本框在程序啟動(dòng)后立即獲得焦點(diǎn),如何利用SetWindowLong改變窗口的回調(diào)函數(shù),通過改變文本框的默認(rèn)回車處理方式進(jìn)行演示。實(shí)現(xiàn)多個(gè)輸入文本框間通過回車逐一向下傳遞焦點(diǎn)的另一種巧妙方法(用缺省按鈕來處理).Lesson8:逃跑按鈕的巧妙實(shí)現(xiàn)。如何制作屬性頁(yè)對(duì)話框和向?qū)?duì)話框,融合講解組合框(如何調(diào)整組合框的大?。?、列表框、單選按鈕、復(fù)選按鈕等常用對(duì)話框控件的多種使用方法。如何限制用戶在不滿足設(shè)定的條件時(shí)切換到其他屬性頁(yè)和向?qū)ы?yè)。Lesson9:如何修改MFCAppWizard向?qū)傻目蚣艹绦虻耐庥^和大小,修改圖標(biāo)、光標(biāo)、背景的三種方法。如何增加和刪除工具欄按鈕,如何給應(yīng)用程序增加工具欄,如何顯示和隱藏工具欄.定制狀態(tài)欄,在狀態(tài)欄中添加時(shí)鐘顯示,CTime類及其用法.在狀態(tài)欄中添加進(jìn)度條(主窗口產(chǎn)生后立即產(chǎn)生進(jìn)度條的巧妙思想,不能在OnCreate函數(shù)中直接處理,要用到自定義消息的方法)。鼠標(biāo)坐標(biāo)顯示,在CView中獲取狀態(tài)欄對(duì)象的幾種方式。如何為應(yīng)用程序添加啟動(dòng)畫面.Lesson10:圖形的繪制,如何使用自定義畫筆(顏色,線寬,線型)。如何為程序中添加選項(xiàng)菜單和選項(xiàng)設(shè)置對(duì)話框,如何使用標(biāo)準(zhǔn)顏色對(duì)話框,如何使用字體對(duì)話框,在選項(xiàng)對(duì)話框中實(shí)現(xiàn)預(yù)覽功能.實(shí)現(xiàn)選項(xiàng)對(duì)話框和窗口類中的數(shù)據(jù)交換。如何改變對(duì)話框和控件的背景色,如何改變控件的文本顏色,對(duì)按鈕控件的特殊處理。如何在窗口中顯示一幅位圖。Lesson11:如何讓CDC上輸出的文字、圖形具有保持功能,集合類CPtrArray的使用,CPaintDC與CClientDC的區(qū)別與應(yīng)用,OnPaint與OnDraw在CView中的關(guān)系及實(shí)現(xiàn)內(nèi)幕,滾動(dòng)窗口的實(shí)現(xiàn),坐標(biāo)空間,映射方式,設(shè)備坐標(biāo)與邏輯坐標(biāo)的轉(zhuǎn)換。元文件設(shè)備描述表的使用,如何利用兼容DC實(shí)現(xiàn)圖形的保存和再現(xiàn)。Lesson12:constchar*與char*const的區(qū)別。C語(yǔ)言對(duì)文件讀寫的支持,F(xiàn)ILE指針;文本文件和二進(jìn)制文件的區(qū)別.用文本方式讀寫文件和以二進(jìn)制方式讀寫文件的注意事項(xiàng)。C++對(duì)文件讀寫的支持,ofstream和ifstream的用法。Win32SDK對(duì)文件讀寫的支持,Creat(yī)eFile函數(shù)、WriteFile函數(shù)、ReadFile函數(shù)的使用;MFC對(duì)文件讀寫的支持,CFile類和C的使用,文件過濾器的設(shè)置。win.ini文件和注冊(cè)表的讀寫方式及相關(guān)知識(shí)點(diǎn).Lesson13:使用CArchive類對(duì)文件進(jìn)行操作。MFC框架程序提供的文件新建與打開功能內(nèi)部的實(shí)現(xiàn)機(jī)制。如何利用CDocument類的串行化存儲(chǔ)功能保存與加載數(shù)據(jù).如何實(shí)現(xiàn)類對(duì)串行化的支持,CObArray的串行化實(shí)現(xiàn)內(nèi)幕。刪除文檔數(shù)據(jù)時(shí)常犯的錯(cuò)誤.MFC框架程序的文檔類和視類的關(guān)系,以及如何獲得相互的指針引用。Lesson14:網(wǎng)絡(luò)的相關(guān)知識(shí),網(wǎng)絡(luò)程序的編寫,Socket是連接應(yīng)用程序與網(wǎng)絡(luò)驅(qū)動(dòng)程序的橋梁,Socket在應(yīng)用程序中創(chuàng)建,通過bind與驅(qū)動(dòng)程序建立關(guān)系。此后,應(yīng)用程序送給Socket的數(shù)據(jù),由Socket交給驅(qū)動(dòng)程序向網(wǎng)絡(luò)上發(fā)送出去。計(jì)算機(jī)從網(wǎng)絡(luò)上收到與該Socket綁定的IP+Port相關(guān)的數(shù)據(jù)后,由驅(qū)動(dòng)程序交給Socket,應(yīng)用程序便可從該Socket中提取接收到的數(shù)據(jù)。網(wǎng)絡(luò)應(yīng)用程序就是這樣通過socket進(jìn)行數(shù)據(jù)的發(fā)送與接收的.TCP與UDP的工作原理與編寫過程,如何在程序中鏈接庫(kù)文件。一個(gè)字符界面的聊天程序。Lesson15:多線程程序的編寫,多線程應(yīng)用中容易出現(xiàn)的問題?;コ鈱?duì)象的講解,如何使用互斥對(duì)象來實(shí)現(xiàn)多線程的同步。如何利用命名互斥對(duì)象保證應(yīng)用程序只有一個(gè)實(shí)例運(yùn)行。應(yīng)用多線程編寫網(wǎng)絡(luò)聊天室程序.Lesson16:事件內(nèi)核對(duì)象、關(guān)鍵代碼段(臨界區(qū))的講解,以及在多線程同步中的應(yīng)用。在Windows下編寫基于消息的網(wǎng)絡(luò)應(yīng)用程序,掌握阻塞與非阻塞網(wǎng)絡(luò)程序的編寫,理解在Windows平臺(tái)下,采用異步選擇機(jī)制可以提高網(wǎng)絡(luò)應(yīng)用程序的性能.Lesson17:詳細(xì)講解進(jìn)程間通訊的四種方式:剪貼板、匿名管道、命名管道和郵槽。并比較分析這幾種進(jìn)程間通信的優(yōu)點(diǎn)和缺點(diǎn).Lesson18:ActiveX控件的應(yīng)用與工作原理。ActiveX控件的編寫,如何為控件安排屬性,方法,事件,屬性頁(yè),持久性存儲(chǔ),控件如何通知容器自身屬性的改變。如何注冊(cè)控件與取消控件注冊(cè)。在VB和VC中訪問ActiveX控件.Lesson19:動(dòng)態(tài)鏈接庫(kù)程序的編寫。靜態(tài)庫(kù)與動(dòng)態(tài)庫(kù)的區(qū)別,以及調(diào)用程序在鏈接靜態(tài)庫(kù)和動(dòng)態(tài)庫(kù)時(shí)的區(qū)別。如何利用工具查看動(dòng)態(tài)鏈接庫(kù)輸出的函數(shù),Depends工具的使用,C++編譯器名字改編技術(shù)對(duì)動(dòng)態(tài)鏈接庫(kù)輸出函數(shù)的影響,extern”C”的用法,利用模塊定義文件來解決C++名字改編的問題。用typedef定義指向函數(shù)的指針類型,如何獲得動(dòng)態(tài)連接庫(kù)里的函數(shù)的指針。Lesson20:Hook編程。如何安裝鉤子過程,如何編寫全局鉤子,動(dòng)態(tài)連接庫(kù)里的全局變量數(shù)據(jù)共享問題分析。ADO數(shù)據(jù)庫(kù)編程。在VB中利用ADO控件和ADO對(duì)象訪問數(shù)據(jù)庫(kù),在VC中利用ADO技術(shù)訪問數(shù)據(jù)庫(kù)。第一章Windows程序內(nèi)部運(yùn)行機(jī)制這一章比較零散,筆記也很零散一、windows是事件驅(qū)動(dòng)方式的程序設(shè)計(jì)windows程序設(shè)計(jì)是種事件驅(qū)動(dòng)方式的程序設(shè)計(jì),主要基于消息的.當(dāng)用戶需要完成某種功能時(shí),需要調(diào)用OS某種支持,然后OS將用戶的需要包裝成消息,并投入到消息隊(duì)列中,最后應(yīng)用程序從消息隊(duì)列中取走消息并進(jìn)行響應(yīng).二、消息隊(duì)列每個(gè)應(yīng)用程序OS都為它建立一個(gè)消息隊(duì)列,消息隊(duì)列是個(gè)先進(jìn)先出的緩沖區(qū),其中每個(gè)元素都是一個(gè)消息,OS將生成的每個(gè)消息按先后順序放進(jìn)消息隊(duì)列中,應(yīng)用程序總是取走當(dāng)前消息隊(duì)列中的第一條消息,應(yīng)用程序取走消息后便知道用戶的操作和程序的狀態(tài),然后對(duì)其處理即消息響應(yīng),消息響應(yīng)通過編碼實(shí)現(xiàn)。三、Window程序入口WinMain函數(shù)是Windows程序入口點(diǎn)函數(shù),由OS調(diào)用,當(dāng)OS啟動(dòng)應(yīng)用程序的時(shí)候,winmain函數(shù)的參數(shù)由OS傳遞的。四、創(chuàng)建一個(gè)完整的窗口需要經(jīng)過下面四個(gè)操作步驟1,設(shè)計(jì)一個(gè)窗口類。如:WNDCLASSwndcls.2,注冊(cè)窗口類。如:RegisterClass(&wndcls)。3,創(chuàng)建窗口。如:Creat(yī)eWindow(),CreateWindowEX();顯示及更新窗口。如:ShowWindow(),Updat(yī)eWindow();其他值得注意的地方1,消息結(jié)構(gòu)typedefstructtagMSG{//msgHWNDhwnd;//接收消息的窗口句柄。和哪個(gè)窗口相關(guān)聯(lián).UINTmessage;//消息標(biāo)識(shí)。消息本身是什么.WPARAMwParam;//消息的附加信息。具體取決于消息本身.LPARAMlParam;DWORDtime;//消息投遞時(shí)間.POINTpt;//消息投遞時(shí),光標(biāo)在屏幕上的位置。}MSG;2,掌握windows的消息機(jī)制需要掌握兩方面:(1)消息本身。不同消息所代表的用戶操作和應(yīng)用程序的狀態(tài)。(2)對(duì)于某個(gè)特定的消息來說,要讓OS執(zhí)行某個(gè)特定的功能去響應(yīng)消息。3,Window入口函數(shù)說明intWINAPIWinMain(HINSTANCEhInstance,//當(dāng)前事例句柄。HINSTANCEhPrevInstance,//先前事例句柄。32位系統(tǒng)中此值都為NULLLPSTRlpCmdLine,//命令行指針intnCmdShow//(窗口)顯示的狀態(tài));要帶參調(diào)用WinMain,類似于命令行的功能,在ProjectèsettingèDebug頁(yè)èProgramarguments項(xiàng)填寫參數(shù)4,Windows提供的窗口類詳解typedefstruct_WNDCLASS{UINTstyle;//窗口的類型WNDPROClpfnWndProc;//窗口過程函數(shù)指針(回調(diào)函數(shù))intcbClsExtra;//窗口類附加字節(jié),為該類窗口所共享.通常0。intcbWndExtra;//窗口附加字節(jié).通常設(shè)為0。HANDLEhInstance;//當(dāng)前應(yīng)用程序事例句柄。HICONhIcon;//圖標(biāo)句柄LoadIcon();HCURSORhCursor;//光標(biāo)句柄LoadCursor();HBRUSHhbrBackground;//畫刷句柄(HBRUSH)GetStockObject();LPCTSTRlpszMenuName;//菜單名字LPCTSTRlpszClassName;//類的名字}WNDCLASS;5,消息循環(huán):MSGmsg;while(GetMessage(&msg,.。.))//從消息隊(duì)列中取出一條消息{TranslateMessage(&msg);//進(jìn)行消息(如鍵盤消息)轉(zhuǎn)換Dispat(yī)chMessage(&msg);//分派消息到窗口的回調(diào)函數(shù)處理,(OS調(diào)用窗口回調(diào)函數(shù)進(jìn)行處理)。}6,回調(diào)函數(shù)LRESULTCALLBACKWindowProc(//這里WindowProc是個(gè)代號(hào)名字.HWNDhwnd,//handletowindowUINTuMsg,//messageidentifierWPARAMwParam,//firstmessageparameterLPARAMlParam//secondmessageparameter);說明:兩種函數(shù)調(diào)用約定(__stdcall和__cdecl):#defineCALLBACK__stdcall//__stdcall標(biāo)準(zhǔn)調(diào)用預(yù)定,是PASCAL調(diào)用約定,象DELPHI使用的就是標(biāo)準(zhǔn)調(diào)用約定#defineWINAPIV__cdecl//__cdecl是C語(yǔ)言形式的調(diào)用約定。主要區(qū)別:函數(shù)參數(shù)傳遞順序和對(duì)堆棧的清除上.問題:除了那些可變參數(shù)的函數(shù)調(diào)用外,其余的一般都是__stdcall約定。但C/C++編譯默然的是__cdecl約定.所以如果在VC等環(huán)境中調(diào)用__stdcall約定的函數(shù),必須要在函數(shù)聲明的時(shí)加上__(dá)stdcall修飾符,以便對(duì)這個(gè)函數(shù)的調(diào)用是使用__stdcall約定(如使用DELPHI編寫的DLL時(shí)候).(VC中可通過這途徑修改:projectèsettingsèc/c++ècategary選"CodeGeneration”,出現(xiàn)Callconvention選項(xiàng),修改之)7,DC句柄的使用(1)使用BeginPaint(),EndPaint()對(duì)。注意只能在響應(yīng)WM_PAINT消息時(shí)使用。(2)使用GetDc(),ReleaseDC()對(duì)。注意他們不能在響應(yīng)WM_PAINT中使用。8,其它(1)函數(shù)名代表函數(shù)的首地址.(2)創(chuàng)建窗口的時(shí)候一定要基于已經(jīng)注冊(cè)的窗口類.第二章MFC程序框架的剖析說明:本課對(duì)應(yīng)教學(xué)視頻的第三課,第二課是C++,被我跳過去。C++我打算另外在用多點(diǎn)的篇幅來討論。重點(diǎn):MFC運(yùn)行機(jī)制提示:對(duì)于不想理解內(nèi)部運(yùn)行過程的,可以不看這一章,可以看了后面的界面設(shè)計(jì)再回頭來看這一章,可能感覺更深刻。這一次課和上一次的課的重點(diǎn)就是MFC的窗口類創(chuàng)建過程,而要反復(fù)說明的就是:MFC的程序和C語(yǔ)言的程序,從執(zhí)行原理上說,是完全一致的.抓住這一點(diǎn),那么對(duì)于理解MFC程序的運(yùn)行機(jī)制也就相對(duì)于簡(jiǎn)單了。C中的main函數(shù)就相當(dāng)于MFC中的WinMain函數(shù).感興趣的可以利用VC的斷點(diǎn)設(shè)置自己跟蹤下面講述的各個(gè)函數(shù),就明白它的執(zhí)行順序了。一、C語(yǔ)言程序執(zhí)行步驟在C語(yǔ)言中,大約的步驟如下:1,全局變量?jī)?nèi)存分配2,進(jìn)入main函數(shù)二、MFC程序的運(yùn)行步驟(主要是初始化)打開一個(gè)MFCAPPWizard(exe)工程,跟蹤其執(zhí)行步驟,可以發(fā)現(xiàn),是以下順序:1)CXXApp中的全局變量定義CXXApptheApp;2)調(diào)用CXXApp構(gòu)造函數(shù)CXXApp::CXXApp(){}3)進(jìn)入Winmain函數(shù)(_tWinMain為宏,值為WinMain)_tWinMain(){}4)完成初始化工作:包括窗口類注冊(cè)、窗口產(chǎn)生、顯示和更新pThread—>InitInstance()對(duì)于MFC程序,MainFrame,View,ToolBar,Controlbar等都是窗口,所以下面的窗口注冊(cè)與創(chuàng)建、顯示等要反復(fù)調(diào)用多次,一次對(duì)應(yīng)一個(gè)窗口(1)注冊(cè)窗口類AfxEndDeferRegisterClass(2)創(chuàng)建窗口CMainFrame::PreCreat(yī)eWindow()//反復(fù)調(diào)用一次是給我們修改窗口屬性的機(jī)會(huì)CFrameWnd::Creat(yī)e()(3)消息循環(huán)PumpMessage()補(bǔ)充1:在MFC中,由于涉及到(窗口)類定義,所以定義全局變量的時(shí)候,需要進(jìn)行更多的步驟。全局變量涉及到類定義(類似于C中的類型定義)的話,那么需要遵循以下步驟(以MFC的窗口類為例)1)設(shè)計(jì)一個(gè)窗口類2)注冊(cè)窗口類3)創(chuàng)建窗口4)顯示及更新窗口5)消息循環(huán)補(bǔ)充2:其他需要注意的幾點(diǎn)1,每一個(gè)MFC程序,有且只有一個(gè)從WinA(yù)pp類派生的類(應(yīng)用程序類),也只有一個(gè)從應(yīng)用程序類所事例化的對(duì)象,表示應(yīng)用程序本身.在WIN32程序當(dāng)中,表示應(yīng)用程序是通過WINMAIN入口函數(shù)來表示的(通過一個(gè)應(yīng)用程序的一個(gè)事例號(hào)這一個(gè)標(biāo)識(shí)來表示的).在基于MFC應(yīng)用程序中,是通過產(chǎn)生一個(gè)應(yīng)用程序?qū)ο?用它來唯一的表示了應(yīng)用程序。2,_tWinMain函數(shù)中通過調(diào)用AfxWinMain()函數(shù)來完成它要完成的功能。(Afx*前綴代表這是應(yīng)用程序框架函數(shù),是一些全局函數(shù),應(yīng)用程序框架是一套輔助生成應(yīng)用程序的框架模型,把一些類做一些有機(jī)的集成,我們可根據(jù)這些類函數(shù)來設(shè)計(jì)自己的應(yīng)用程序)。3,設(shè)計(jì)窗口類:在MFC中事先設(shè)計(jì)好了幾種缺省的窗口類,根據(jù)不同的應(yīng)用程序的選擇,調(diào)用AfxEndDeferRegisterClass()函數(shù)注冊(cè)所選擇的窗口類。4,PreCreat(yī)eWindow()是個(gè)虛函數(shù),如果子類有則調(diào)用子類的。5,CreateWindowEx()函數(shù)參數(shù)與CREATESTRUCT結(jié)構(gòu)體成員完全一致,CreateWindowEx()函數(shù)與CREATESTRUCT結(jié)構(gòu)體參數(shù)的對(duì)應(yīng)關(guān)系,使我們?cè)趧?chuàng)建窗口之前通過可PreCreateWindow(cs)修改cs結(jié)構(gòu)體成員來修改所要的窗口外觀。6,注意兩個(gè)函數(shù)。::TranslateMessage(&m_msgCur)函數(shù)進(jìn)行消息(如鍵盤消息)轉(zhuǎn)換::Dispat(yī)chMessage(&m_msgCur)函數(shù)分派消息到窗口的回調(diào)函數(shù)處理(實(shí)際上分派的消息經(jīng)過消息映射,交由消息響應(yīng)函數(shù)進(jìn)行處理。)7,可以認(rèn)為View類窗口是CMainFram類窗口的子窗口.DOCument類是文檔類。DOC-VIEW結(jié)構(gòu)將數(shù)據(jù)本身與它的顯示分離開.文檔類用于數(shù)據(jù)的存儲(chǔ),加載;視類用于數(shù)據(jù)的顯示,修改8,CTEApp::InitInstance()函數(shù)中通過文檔模板將文檔類,視類,框架類的有機(jī)組織一起.語(yǔ)句如下:CSingleDocTemplate*pDocTemplat(yī)e;pDocTemplat(yī)e=newCSingleDocTemplate(IDR_MAINFRAME,RUNTIME_CLASS(CTEDoc),RUNTIME_CLASS(CMainFrame),//mainSDIframewindowRUNTIME_CLASS(CTEView));AddDocTemplate(pDocTemplat(yī)e);//增加到模板補(bǔ)充3:本課涉及到MFC函數(shù)的源文件位置根目錄找到您安裝VC98下MFC的位置,比如我的機(jī)子上為:D:\ProgramFiles\MicrosoftVisualStudio\VC98\MFC。下面提供的就是相對(duì)路徑了。CWinA(yù)pp構(gòu)造函數(shù):MFCèSRCèAPPCORE。CPPAfxWinMain:MFCèSRCèWINMAIN。CPPAfxEndDeferRegisterClass:MFCèSRCèAPPCORE。CPPCFrameWnd::PreCreateWindow()函數(shù)所在文件:MFCèSRCèWINFRM.CPPCFrameWnd::Create()函數(shù)路徑:MFCèSRCèWINFRM.CPPCWnd::CreateEx()函數(shù)路徑:MFCèSRCèWINCORE.CPPCWinThread::Run()方法路徑:MFCèSRCèTHRDCORE.CPP第三章MFC消息映射機(jī)制和繪圖DC的獲取我們假設(shè)您已經(jīng):1,知道如何創(chuàng)建一個(gè)單文檔的AppWizard2,知道C++類、函數(shù)重載等簡(jiǎn)單知識(shí)3,知道如何給View類或者Doc文檔添加成員變量4,會(huì)用MFC的IDE調(diào)試工具最好,那么本文的程序您可以copy去調(diào)試我們?cè)谏弦还?jié)講了MFC框架App類、View類、MainFrame類和Doc類的關(guān)系,那么,基于消息的windowsMFC程序設(shè)計(jì)是如何進(jìn)行消息映射的呢?在進(jìn)行下一節(jié)之前,我們來復(fù)習(xí)一下.對(duì)于一個(gè)MFCAPPWizard運(yùn)用程序,CMainFrame和View是窗口類,并且是父子關(guān)系,Doc一般用于數(shù)據(jù)的加載和存儲(chǔ),View用于圖像的顯示,App中是包括一些(窗口)初始化之類的東西。我們開始這一節(jié)的內(nèi)容。一、消息映射機(jī)制windows程序設(shè)計(jì)是種事件驅(qū)動(dòng)方式的程序設(shè)計(jì),主要基于消息的.當(dāng)用戶需要完成某種功能時(shí),需要調(diào)用OS某種支持,然后OS將用戶的需要包裝成消息,并投入到消息隊(duì)列中,最后應(yīng)用程序從消息隊(duì)列中取走消息并進(jìn)行響應(yīng)。在左邊View類處點(diǎn)右鍵,在出現(xiàn)的菜單里點(diǎn)擊“AddWindowsMessageHandler”,在出現(xiàn)的對(duì)話框里選擇“WM_LBUTTONDOWN”,添加消息映射函數(shù)?;氐皆募?我們將看到三處進(jìn)行了修改:在頭文件(View.h)中聲明消息響應(yīng)函數(shù)原型。//{{AFX_MSG(CDrawView)//注釋宏afx_msgvoidOnLButtonDown(UINTnFlags,CPointpoint);//}}AFX_M(jìn)SG//注釋宏afx_msg宏表示聲明的是一個(gè)消息響應(yīng)函數(shù).2,在源文件(View.cpp)中進(jìn)行消息映射。BEGIN_MESSAGE_M(jìn)AP(CDrawView,CView)//{{AFX_MSG_MAP(CDrawView)ON_WM_LBUTTONDOWN()//}}AFX_MSG_MAP在宏BEGIN_M(jìn)ESSAGE_MAP()與END_MESSAGE_MAP()之間進(jìn)行消息映射。宏ON_WM_LBUTTONDOWN()把消息WM_LBUTTO(shè)NDOWN與它的響應(yīng)函數(shù)OnLButtonDown()相關(guān)聯(lián).這樣一旦有消息的產(chǎn)生,就會(huì)自動(dòng)調(diào)用相關(guān)聯(lián)的消息響應(yīng)函數(shù)去處理.宏ON_WM_LBUTTONDOWN()定義如下:#defineON_WM_LBUTTONDOWN(){WM_LBUTTO(shè)NDOWN,0,0,0,AfxSig_vwp,(AFX_PMSG)(AFX_PMSGW)(void(AFX_MSG_CALLCWnd::*)(UINT,CPoint))&OnLButtonDown},3,源文件中進(jìn)行消息響應(yīng)函數(shù)處理。voidCDrawView::OnLButtonDown(UINTnFlags,CPointpoint){//TODO:Addyourmessagehandlercodehereand/orcalldefaultCView::OnLButtonDown(nFlags,point);}說明:可見當(dāng)增加一個(gè)消息響應(yīng)處理,在以上三處進(jìn)行了修改.可在消息響應(yīng)函數(shù)里添加消息處理代碼完成對(duì)消息的響應(yīng)、處理。消息響應(yīng)的可能方式:1)在基類中針對(duì)每種消息做一個(gè)虛函數(shù),當(dāng)子類對(duì)消息響應(yīng)時(shí)候,只要在子類中重寫這個(gè)虛函數(shù)即可.缺點(diǎn):MFC類派生層次很多,如果在基類對(duì)每個(gè)消息進(jìn)行虛函數(shù)處理,那么從基類派生的每個(gè)子類都將背負(fù)一個(gè)龐大的虛表,這樣浪費(fèi)內(nèi)存,故MFC沒有采取這中方式而采取消息映射方式。2)消息映射方式:MFC在后臺(tái)維護(hù)了一個(gè)句柄和C++對(duì)象指針對(duì)照表,當(dāng)收到一個(gè)消息后,通過消息結(jié)構(gòu)里資源句柄(查對(duì)照表)就可找到與它對(duì)應(yīng)的一個(gè)C++對(duì)象指針,然后把這個(gè)指針傳給基類,基類利用這個(gè)指針調(diào)用WindowProc()函數(shù)對(duì)消息進(jìn)行處理,WindowProc()函數(shù)中調(diào)用OnWndMsg()函數(shù),真正的消息路由及處理是由OnWndMsg()函數(shù)完成的.由于WindowProc()和OnWndMsg()都是虛函數(shù),而且是用派生類對(duì)象指針調(diào)用的,由多態(tài)性知最總終調(diào)用子類的。在OnWndMsg()函數(shù)處理的時(shí)候,根據(jù)消息種類去查找消息映射,判斷所發(fā)的消息有沒有響應(yīng)函數(shù),具體方式是到相關(guān)的頭文件和源文件中尋找消息響應(yīng)函數(shù)聲明(從注釋宏//{{AFX_MSG(CDrawView).。.//}}AFX_MSG之間尋找),消息映射(從宏BEGIN_MESSAGE_(tái)MAP(。..)..。.END_MESSAGE_MAP()之間尋找),最終找到對(duì)應(yīng)的消息處理函數(shù)。當(dāng)然,如果子類中沒有對(duì)消息進(jìn)行處理,則消息交由基類處理。說明:virtualLRESULTWindowProc(UINTmessage,WPARAMwParam,LPARAMlParam);virtualBOOLOnWndMsg(UINTmessage,WPARAMwParam,LPARAMlParam,LRESULT*pResult);二、繪圖DC的獲取說明:在View類添加WM_LBUTTONDOWN和WM_LBUTTONUP的消息處理函數(shù),我們將用來演示各種DC的獲取,以及顯示效果。View類添加全局變量CPointm_ptOrigin用來存儲(chǔ)左鍵按下點(diǎn)坐標(biāo)。下面集中來關(guān)注OnLButtonUp中的繪圖程序和效果。以下語(yǔ)句添加于OnLButtonUp函數(shù)中,可以查看不同的效果。1,使用SDK獲取DC句柄:HDChdc;hdc=::GetDc(m_hWnd);//獲取DC句柄MoveToEx(hdc,m_ptOrigin。x,m_ptOrigin.y,NULL);LineTo(hdc,point。x,point。y);::ReleaseDC(m_h(yuǎn)Wnd,hdc);//釋放DC2,利用CDC類指針和CWin類成員函數(shù)獲取DC。CDC*pDC=GetDC();pDC—〉MoveTo(m_ptOrigin);pDC—〉LineTo(point);ReleaseDC(pDC);3,利用CClientDC對(duì)象。(CClientDC類從CDC類派生來的)CClientDCdc(this);dc.MoveTo(m_ptOrigin);dc.LineTo(point);4,利用CWindowDC對(duì)象。(CWindowDC類從CDC類派生來的)CWindowDCdc(this);//dc.MoveTo(m_ptOrigin);dc.LineTo(point);5,父窗口(MainFrame框架)和屏幕指針.將上面的dc(this)分別改成GetParent()和GetDesktopWindow(),就可以得到父窗口指針和屏幕窗口指針??梢苑謩e試驗(yàn)畫線效果.6,利用畫筆改變線條顏色和類型:CPenpen(PS_DOT,1,RGB(0,255,0));//構(gòu)造畫筆對(duì)象CClientDCdc(this);CPen*pOldPen=dc.SelectObject(&pen);//將畫筆選入DCdc.MoveTo(m_ptOrigin);dc.LineTo(point);dc。SelectObject(pOldPen);//恢復(fù)先前的畫筆7,使用畫刷(通常利用畫刷去填充矩形區(qū)域):使用單色畫刷CBrushbrush(RGB(255,0,0));//構(gòu)造畫刷對(duì)象CClientDCdc(this);dc.FillRect(CRect(m_ptOrigin,point),&brush);//用指定的畫刷去填充矩形區(qū)域使用位圖畫刷CBitmapbitmap;//構(gòu)造位圖對(duì)象(使用前需要初試化)bitmap。LoadBitmap(IDB_BITMAP1);//初試化位圖對(duì)象CBrushbrush(&bitmap);//構(gòu)造位圖畫刷CClientDCdc(this);dc.FillRect(CRect(m_ptOrigin,point),&brush);//用指定的位圖畫刷去填充矩形區(qū)域使用透明畫刷CBrush*pB(yǎng)rush=CBrush::FromHandle((HBRUSH)GetStockObject(NULL_BRUSH));//獲取透明畫刷對(duì)象指針CClientDCdc(this);CBrush*pOldBrush=dc。SelectObject(pB(yǎng)rush);//將透明畫刷選入DCdc。Rectangle(CRect(m_ptOrigin,point));dc.SelectObject(pOldBrush);//釋放透明畫刷8,注意點(diǎn):1)靜態(tài)方法不屬于某一個(gè)具體對(duì)象,而屬于類本身,在類加載的時(shí)候就已經(jīng)為類靜態(tài)方法分配了代碼去,故可用CBrush::FromHandle()形式調(diào)用。2)靜態(tài)方法中,不能引用非靜態(tài)的數(shù)據(jù)成員和方法。3)靜態(tài)數(shù)據(jù)成員需要在類外單獨(dú)做初始化,形式如:變量類型類名::變量名=初始值;第四章文本編輯和字處理軟件這一節(jié)我們主要講述文本編輯方面的知識(shí),孫鑫老師的視頻就是一個(gè)簡(jiǎn)單字處理軟件的制作過程,所以我也是按照順序,敘述此過程.在MFC中CEditView和cRichEditView類已經(jīng)完成了初步的文字處理??梢宰寫?yīng)用程序的View類以CEditView和cRichEditView類為基類。下面我們以單文檔視圖為例一、創(chuàng)建插入符。文字在插入符后插入(正如Word中閃爍的光標(biāo))1,添加View類的WM_CREATE消息響應(yīng)函數(shù)2,在CXXXView::OnCreate()中添加//獲得當(dāng)前文本度量/字體信息CClientDCdc(this);TEXTMETRICtm;dc.GetTextMetrics(&tm);//根據(jù)當(dāng)前字體,設(shè)置插入符/光標(biāo)Creat(yī)eSolidCaret(20,100);//**ShowCaret();3,創(chuàng)建圖形插入符1),為View類添加成員變量m_bmp;2),把上面的**行用如下語(yǔ)句替換m_bmp.LoadBitmap(IDB_BITMAP1);CreateCaret(&bitmap);4,二、輸出文字在OnDraw函數(shù)中添加如下代碼1),簡(jiǎn)單輸出文字CStringstr;str=”維新科學(xué)技術(shù)培訓(xùn)中心";pDC->TextOut(50,50,str);2),獲取文字框大小備用CSizesz=pDC—>GetTextExtent(str);3),給str重新賦值,以區(qū)別于上一個(gè)內(nèi)容。當(dāng)然,之前需要在StringTable中添加IDS_WEIXINstr.LoadString(IDS_WEIXIN);pDC—>TextOut(0,200,str);4),添加路徑層當(dāng)作圖的時(shí)候,如果想要在整幅圖形其中的某個(gè)部分和其它部分有所區(qū)別,我們可以把這部分圖形放到路徑層當(dāng)中,然后指定調(diào)用指定互操作模式調(diào)用SelectClipPath(intnMode)函數(shù)來使路徑層和覆蓋在其上新繪圖剪切區(qū)域進(jìn)行互操作,達(dá)到特殊效果。pDC->BeginPath();pDC->Rectangle(50,50,50+sz。cx,50+sz.cy);//路徑層的坐標(biāo)依賴于上面的文字位置pDC->EndPath();pDC-〉SelectClipPat(yī)h(RGN_DIFF);5),畫一些方格,看看路徑層的效果。for(inti=0;i<300;i+=10){pDC—>MoveTo(0,i);pDC—>LineTo(300,i);pDC->MoveTo(i,0);pDC->LineTo(i,300);}三、鼠標(biāo)移動(dòng)插入符給View增加兩個(gè)成員變量:CStringm_strLine用于存儲(chǔ)當(dāng)前輸入行的內(nèi)容;CPointm_ptOrigin用于保存鼠標(biāo)移動(dòng)引起插入符改變時(shí)的新行開始位置在OnLButtonDown函數(shù)中添加如下內(nèi)容SetCaretPos(point);//設(shè)置插入符位置m_strLine.Empty();m_ptOrigin=point;//保存此位置另外,給View添加兩個(gè)變量四、響應(yīng)鍵盤輸入鍵盤響應(yīng)需要考慮如下內(nèi)容:1,鼠標(biāo)點(diǎn)擊鍵盤輸入一個(gè)字符,顯示到鍵盤上,插入符/光標(biāo)后移一位。2,回車之后,光標(biāo)下移一行3,刪除/退格鍵的響應(yīng)下面是程序內(nèi)容:1,給View類添加WM_CHAR消息響應(yīng)函數(shù)2,在OnChar函數(shù)中添加如下語(yǔ)句CClientDCdc(this);CFontfont;font.CreatePointFont(300,"華文行楷",NULL);CFont*pOldFont=dc。SelectObject(&font);TEXTMETRICtm;dc.GetTextMetrics(&tm);if(0x0d==nChar)//回車鍵響應(yīng)程序段{m_strLine.Empty();m_ptOrigin。y+=tm.tmHeight;}elseif(0x08==nChar){//用背景色模擬最后一個(gè)字符的消失COLORREFclr=dc.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);}else{m_strLine+=nChar;}CSizesz=dc.GetTextExtent(m_strLine);CPointpt;pt。x=m_ptOrigin.x+sz.cx;pt.y=m_ptOrigin。y;SetCaretPos(pt);dc。TextOut(m_ptOrigin.x,m_ptOrigin。y,m_strLine);dc.SelectObject(pOldFont);五、平滑變色--—類似卡拉OK的跟唱文字顏色改變CDC::TextOut()是一個(gè)字母一個(gè)字母的輸出,達(dá)不到平滑效果。CDC::DrawText():將文字的輸出局限于一個(gè)矩形區(qū)域,超出矩形區(qū)域的文字都被截?cái)?。利用這一特點(diǎn),可每隔些時(shí)間增加矩形大小,從而可實(shí)現(xiàn)人眼中的平滑效果。1,設(shè)置定時(shí)器。在View中OnCreate或者其他地方添加SetTimer(1,100,NULL);2,給View類添加WM_TIMER消息響應(yīng)函數(shù)3,給View添加成員變量m_nWidth用于保存顏色隨時(shí)間流逝變化的起點(diǎn)4,在OnTimer中添加如下代碼m_nWidth+=5;//每次位置增加CClientDCdc(this);TEXTMETRICtm;dc.GetTextMetrics(&tm);//獲取字體屬性CRectrect(0,200,m_nWidth,200+tm。tmHeight);dc.SetTextColor(RGB(255,0,0));CStringstr;str.LoadString(IDS_WEIXIN);dc.DrawText(str,rect,DT_LEFT);rect。top=150;rect。bottom=rect.top+tm.tmHeight;dc.DrawText(str,rect,DT_RIGHT);CSizesz=dc。GetTextExtent(str);if(m_nWidth>sz.cx){m_nWidth=0;dc.SetTextColor(RGB(0,255,0));dc.TextOut(0,200,str);}簡(jiǎn)單字處理軟件大功告成!第五章VC菜單相關(guān)編程閱讀本文前,我們假設(shè)您已經(jīng):1,知道如何創(chuàng)建一個(gè)單文檔的AppWizard2,知道C++類、函數(shù)重載等簡(jiǎn)單知識(shí)3,知道如何給View類或者Doc文檔添加成員變量4,會(huì)用MFC的IDE調(diào)試工具最好,那么本文的程序您可以copy去調(diào)試5,知道如何為某個(gè)框架類添加虛函數(shù)或消息處理函數(shù)一、消息的分類:消息的分類:標(biāo)準(zhǔn)消息,命令消息,通告消息。[標(biāo)準(zhǔn)消息]:除WM_COMMAND之外,所有以WM_開頭的消息。[命令消息]:來自菜單、加速鍵或工具欄按鈕的消息。這類消息都以WM_COMMAND呈現(xiàn)。在MFC中,通過菜單項(xiàng)的標(biāo)識(shí)(ID)來區(qū)分不同的命令消息;在SDK中,通過消息的wParam參數(shù)識(shí)別。[通告消息]:由控件產(chǎn)生的消息,例如,按鈕的單擊,列表框的選擇等均產(chǎn)生此類消息,為的是向其父窗口(通常是對(duì)話框)通知事件的發(fā)生。這類消息也是以WM_COMMAND形式呈現(xiàn).注意:1)從CWnd派生的類,都可以接收到[標(biāo)準(zhǔn)消息]、[命令消息]和[通告消息]。2)從CCmdTarget派生的類,都可以接收到[命令消息]和[通告消息].3)CCmdTarget是CWnd的父類二、菜單消息傳遞過程MFC中菜單項(xiàng)消息如果利用ClassWizard來對(duì)菜單項(xiàng)消息分別在上述四個(gè)類中進(jìn)行響應(yīng),則菜單消息傳遞順序:View類èDoc類èCMainFrame類èApp類.菜單消息一旦在其中一個(gè)類中響應(yīng)則不再在其它類中查找響應(yīng)函數(shù)。當(dāng)點(diǎn)擊一個(gè)菜單項(xiàng)的時(shí)候,最先接受到菜單項(xiàng)消息的是CMainFrame框架類,CMainFrame框架類將會(huì)把菜單項(xiàng)消息交給它的子窗口View類,由View類首先進(jìn)行處理;如果View類檢測(cè)到?jīng)]對(duì)該菜單項(xiàng)消息做響應(yīng),則View類把菜單項(xiàng)消息交由文檔類Doc類進(jìn)行處理;如果Doc類檢測(cè)到Doc類中也沒對(duì)該菜單項(xiàng)消息做響應(yīng),則Doc類又把該菜單項(xiàng)消息交還給View類,由View類再交還給CMainFrame類處理。如果CMainFrame類查看到CMainFrame類中也沒對(duì)該消息做響應(yīng),則最終交給App類進(jìn)行處理。三、菜單指針的獲取,及相關(guān)設(shè)置在CMainFrame::OnCreate下可以直接實(shí)驗(yàn)以下操作幾個(gè)相關(guān)和重要的函數(shù)CMenu*GetMenu();//CWnd::GetMenu得到窗口菜單欄對(duì)象指針。CMenu*GetSubMenu();//CMenu::GetSubMenu獲得指向彈出菜單對(duì)象指針UINTCheckMenuItem();//CMenu::CheckMenuItemAddscheckmarkstoorremovescheckmarksfrommenuitemsinthepop-upmenu。BOOLSetDefaultItem();//CMenu::SetDefaultItemSetsthedefaultmenuitemforthespecifiedmenu。BOOLSetMenuItemBitmaps();//CMenu::SetMenuItemBitmaps設(shè)置位圖標(biāo)題菜單。UINTEnableMenuItem();//CMenu::EnableMenuItem使菜單項(xiàng)有效,無效,或變灰。BOOLSetMenu(CMenu*pMenu);//CWnd::SetMenu在當(dāng)前窗口上設(shè)置新菜單或移除菜單.HMENUDetach();//CMenu::DetachDetachesaWindowsmenufromaCMenuobjectandreturnsthehandle.獲取菜單的寬和高:GetSystemMetrics(SM_CXMENUCHECK),GetSystemMetrics(SM_CYMENUCHECK)例子:1,給菜單項(xiàng)打上標(biāo)記GetMenu()->GetSubMenu(0)—〉CheckMenuItem(0,MF_BYPOSITION|MF_CHECKED);GetMenu()-〉GetSubMenu(0)->CheckMenuItem(ID_|MF_CHECKED);2,設(shè)置缺省菜單項(xiàng)GetMenu()->GetSubMenu(0)—〉SetDefaultItem(1,TRUE);GetMenu()-〉GetSubMenu(0)—>SetDefaultItem(ID_);3,圖形標(biāo)記菜單先創(chuàng)建圖形,注意底色不要是白色m_bitmap。LoadBitmap(IDB_BITMAP1);GetMenu()-〉GetSubMenu(0)->SetMenuItemBitmaps(0,MF_BYPOSITION,&m_bitmap,&m_bitmap);4,屏蔽菜單,使之不能用(需要在CMainFrame::CMainFrame()中設(shè)置m_bAutoMenuEnable=FALSE;)GetMenu()—〉GetSubMenu(0)->EnableMenuItem(1,MF_BYPOSITION|MF_DISABLED|MF_GRAYED);5,取消和加載菜單用此功能,可以動(dòng)態(tài)的修改菜單SetMenu(NULL);//取消菜單項(xiàng)CMenumenu;menu.LoadMenu(IDR_MAINFRAME);SetMenu(&menu);menu.Detach();//菜單句柄和對(duì)象斷開,使對(duì)象析構(gòu)時(shí)不銷毀菜單四、命令更新機(jī)制菜單項(xiàng)狀態(tài)的維護(hù)是依賴于CN_UPDATE_COMMAND_UI消息,誰捕獲CN_UPDATE_COMMAND_UI消息,MFC就在其中創(chuàng)建一個(gè)CCmdUI對(duì)象。在后臺(tái)操作系統(tǒng)發(fā)出WM_INITMENUPOPUP消息,然后由MFC的基類如CFrameWnd接管并創(chuàng)建一個(gè)CCmdUI對(duì)象和第一個(gè)菜單項(xiàng)相關(guān)聯(lián),調(diào)用對(duì)象成員函數(shù)DoUpdat(yī)e()(注:這個(gè)函數(shù)在MSDN中沒有找到說明)發(fā)出CN_UPDATE_COMMAND_UI消息,這條消息帶有指向CCmdUI對(duì)象的指針。此后同一個(gè)CCmdUI對(duì)象又設(shè)置為與第二個(gè)菜單項(xiàng)相關(guān)聯(lián),這樣順序進(jìn)行,直到完成所有菜單項(xiàng)。更新命令UI處理程序僅應(yīng)用于彈出式菜單項(xiàng)上的項(xiàng)目,不能應(yīng)用于永久顯示的頂級(jí)菜單項(xiàng)目。注意:以下兩語(yǔ)句的效果不同.對(duì)菜單項(xiàng)一樣,對(duì)工具欄索引對(duì)應(yīng)不一樣if(0==pCmdUI-〉m_nIndex)pCmdUI->Enable(FALSE);if(ID_〉m_nID)pCmdUI—>Enable(FALSE);五、右鍵彈出菜單1,Project—>AddtoProject—>ComponentsandControls添加popmenu即可。2,靜態(tài)添加菜單方法。1)在資源里編輯一個(gè)菜單2)View中添加WM_RBUTTO(shè)NDOWN消息對(duì)應(yīng)函數(shù)。3)在OnRButtonDown中添加如下CMenumenu;menu.LoadMenu(IDR_MENU1);CMenu*pPopup=menu.GetSubMenu(0);ClientToScreen(&point);pPopup->TrackPopupMenu(TPM_LEFTALIGN|TPM_RIGHTBUTTON,point。x,point.y,GetParent());//不想在框架類顯示就把GetParent()改為this.4)給自己編輯的菜單加對(duì)應(yīng)的處理函數(shù)(利用Classwizard)。如果加在CMainFrame5)3,動(dòng)態(tài)添加菜單(子菜單數(shù)目變化)在MainFrame::OnCreate中試驗(yàn)如下CMenumenu;menu。CreatePopupMenu();GetMenu()->AppendMenu(MF_POPUP,(UINT)menu.m_hMenu,”WinSun”);GetMenu()—〉InsertMenu(2,MF_BYPOSITION|MF_POPUP,(UINT)menu。m_hMenu,”WinSun");menu.AppendMenu(MF_STRING,IDM_HELLO,"Hello");menu。AppendMenu(MF_STRING,112,”Weixin”);menu.AppendMenu(MF_STRING,113,”Mybole”);menu。Detach();響應(yīng)函數(shù)添加方法:1)在resource。h中添加資源ID定義#defineIDM_HELLO1112)在MainFrm。h中聲明消息響應(yīng)。DECLARE_(tái)MESSAGE_MAP()之前添加afx_msgvoidOnHello();3)在MainFrm.cpp中END_MESSAGE_(tái)MAP()之前,添加ON_COMMAND(IDM_HELLO,OnHello)4)在MainFrm。cpp中添加CMainFrame::OnHello()函數(shù)定義4,給系統(tǒng)菜單添加/刪除菜單項(xiàng)GetMenu()->GetSubMenu(0)->AppendMenu(MF_STRING,114,"Welcome");GetMenu()->GetSubMenu(0)->InsertMenu(ID_,MF_BYCOMMAND|MF_STRING,115,"維新”);GetMenu()->DeleteMenu(1,MF_BYPOSITION);GetMenu()->GetSubMenu(0)->DeleteMenu(2,MF_BYPOSITION);*/GetMenu()—>DeleteMenu(GetMenu()->GetSubMenu(1)-〉GetMenuItemID(0),MF_BYCOMMAND);六、動(dòng)態(tài)添加系統(tǒng)菜單項(xiàng)電話本程序:鍵盤輸入人名,空格之后電話號(hào)碼?;剀囍?把人名添加到菜單項(xiàng)。當(dāng)點(diǎn)擊菜單時(shí),顯示電話本信息。1,給View添加private的CStringm_strLine;//存儲(chǔ)輸入的字符串CMenum_menu;//菜單intm_nIndex;//用于計(jì)數(shù),是不是第一次2,添加View的public成員CStringArraym_strArray;3,添加View的WM_CHAR消息響應(yīng)函數(shù)4,在View::OnChar中添加如下代碼CClientDCdc(this);if(0x0d==nChar){if(0==++m_nIndex)//如果是第一次,就創(chuàng)建菜單{m_menu.CreatePopupMenu();GetParent()->GetMenu()->AppendMenu(MF_POPUP,(UINT)m_menu.m_hMenu,"PhoneBook");GetParent()->DrawMenuBar();//立即顯示菜單}m_menu。AppendMenu(MF_STRING,IDM_PHONE1+m_nI(lǐng)ndex,m_strLine。Left(m_strLine.Find(’’)));m_strArray.Add(m_strLine);m_strLine。Empty();Invalidat(yī)e();//擦除先前的背景,防止重疊顯示}else{m_strLine+=nChar;dc.TextOut(0,0,m_strLine);}5,添加菜單的響應(yīng)函數(shù)方法一:1)在Toolbar上添加一個(gè)菜單,其彈出項(xiàng)為ID號(hào)為IDM_PHONE1,IDM_PHONE2,IDM_PHONE3.2)在Rsource.h中添加#defineIDM_PHONE1201#defineIDM_PHONE2202#defineIDM_PHONE32033)利用ClassWizard給菜單項(xiàng)添加響應(yīng)函數(shù),并編輯函數(shù)4)刪除菜單項(xiàng)(其響應(yīng)函數(shù)會(huì)依然存在,并且4步中利用了ID號(hào),可以對(duì)應(yīng)過去)方法二:視頻沒有提供,但我感覺應(yīng)該有其他方法.方法一太死板6,另:由框架類捕獲菜單響應(yīng),而不是由View處理,可以節(jié)約代碼1)給MainFrame添加WM_COMMAND消息響應(yīng)函數(shù)2)在其中添加如下代碼intMenuCmdId=LOWORD(wParam);CMenu2View*pView=(CMenu2View*)GetActiveView();if(MenuCmdId>=IDM_PHONE1&&MenuCmdId〈IDM_PHONE1+pView—〉m_strArray。GetSize()){CClientDCdc(pView);dc.TextOut(0,0,pView—>m_strArray。GetAt(MenuCmdId—IDM_PHONE1));returnTRUE;}第6點(diǎn)提供的方法,不能解決第5點(diǎn)提出方法的限制,響應(yīng)菜單還是和事先編好的ID相對(duì)應(yīng),不能動(dòng)態(tài)增加其他注意的地方:1,彈出菜單(Pop-up)是不能用來作命令響應(yīng)的。此項(xiàng)設(shè)置在菜單屬性欄內(nèi)。2,將Toolbar的ID設(shè)為菜單的ID,二者即發(fā)生了關(guān)聯(lián)。3,在計(jì)算子菜單菜單項(xiàng)的索引的時(shí)候,分隔欄符也算索引。4,消息影射函數(shù)Cpp文件中BEGIN_MESSAGE_MAP(CMenu2View,CView)//{{AFX_MSG_MAP(CMenu2View)//位置1//}}AFX_MSG_MAP位置2END_MESSAGE_M(jìn)AP()頭文件中//{{AFX_MSG(CMenu2View)位置3//}}AFX_MSG位置4DECLARE_MESSAGE_MAP()消息映射在位置1和位置2不一樣,可以調(diào)用Classwizard看到修改結(jié)果位置3和位置4的函數(shù)聲明,隨便放1或2都可以,沒有影響第六章對(duì)話框編程(1)我們假設(shè)您已經(jīng):1,知道如何創(chuàng)建一個(gè)單文檔的AppWizard2,知道C++類、函數(shù)重載等簡(jiǎn)單知識(shí)3,知道如何給View類或者Doc文檔添加成員變量4,會(huì)用MFC的IDE調(diào)試工具最好,那么本文的程序您可以copy去調(diào)試5,知道如何為某個(gè)框架類添加虛函數(shù)或消息處理函數(shù)1,動(dòng)態(tài)創(chuàng)建按鈕1)增加全局變量CButtonm_btn;2)在需要?jiǎng)?chuàng)建的地方//ID號(hào)123可以隨意改變if(!m_btn。m_hWnd)m_btn。Create("維新",BS_DEFPUSHBUTTON|WS_VISIBLE|WS_CHILD,CRect(0,0,100,100),this,123);elsem_btn.DestroyWindow();2,復(fù)制控件在dlg上添加控件時(shí),按?。悖魊l鍵,拖動(dòng)就可以復(fù)制一模一樣的控件3,控件對(duì)齊在對(duì)話框上多個(gè)控件對(duì)齊,可以用layout菜單或者左下角toolbar4,動(dòng)態(tài)編輯stat(yī)ic靜態(tài)文本框CStringstr;if(GetDlgItem(IDC_NUMBER1)->GetWindowText(str),str=="Number1:”)GetDlgItem(IDC_NUMBER1)—〉SetWindowText("數(shù)值1:");elseGetDlgItem(IDC_NUMBER1)->SetWindowText(”Number1:”);要讓static靜態(tài)文本框響應(yīng)消息,需要復(fù)選上notify選項(xiàng)5,Edit文本框獲取/設(shè)置文本內(nèi)容1)方法1charch[10];GetDlgItem(IDC_EDIT1)—〉GetWindowText(ch1,10);GetDlgItem(IDC_EDIT3)->SetWindowText(itoa(at(yī)oi(ch1),ch1,10));2)方法2GetDlgItemText(IDC_EDIT1,ch1,10);SetDlgItemText(IDC_EDIT3,itoa(atoi(ch1),ch1,10));3)方法3SetDlgItemInt(IDC_EDIT3,GetDlgItemInt(IDC_EDIT1));//對(duì)整型數(shù)字的字符串有用4)關(guān)聯(lián)變量法對(duì)每個(gè)Edit控件關(guān)聯(lián)一個(gè)變量,設(shè)置后記得用UpdateData()對(duì)于顯示數(shù)字類的文本框,可以定義value和control兩種類型變量DoDat(yī)aExchange()calledbytheframeworktoexchangeandvalidatedialogdat(yī)aTheframeworkautomaticallycallsUpdateDatawithbSaveAndValidatesettoFALSEwhenamodaldialogboxiscreatedinthedefaultimplementationofCDialog::OnInitDialog.5)利用WM_GETTEXT消息處理獲取文本charch1[10];可以用以下四種方法(m_edit1為關(guān)聯(lián)的控制型變量)::SendMessage(GetDlgItem(IDC_EDIT1)->m_hWnd,WM_GETTEXT,10,(LPARAM)ch1);::SendMessage(m_edit1.m_h(yuǎn)Wnd,WM_GETTEXT,10,(LPARAM)ch1);GetDlgItem(IDC_EDIT1)—>SendMessage(WM_GETTEXT,10,(LPARAM)ch1);m_edit1.SendMessage(WM_GETTEXT,10,(LPARAM)ch1);利用WM_SETTEXT消息處理設(shè)置文本m_edit3。SendMessage(WM_SETTEXT,0,(LPARAM)ch3);6)直接對(duì)對(duì)話框控件進(jìn)行消息發(fā)送SendDlgItemMessage(IDC_EDIT1,WM_GETTEXT,10,(LPARAM)ch1);//獲取文本SendDlgItemMessage(IDC_EDIT3,WM_SETTEXT,0,(LPARAM)ch3);//設(shè)置文本SendDlgItemMessage(IDC_EDIT3,EM_SETSEL,0,-1);7)利用EM_GETSEL,EM_SETSEL的消息處理6,對(duì)話框收縮點(diǎn)擊"收縮<〈"對(duì)話框收縮,點(diǎn)擊"擴(kuò)展〉>”則擴(kuò)展,請(qǐng)看例子代碼7,多個(gè)edit框用Enter鍵切換的方法,三種方法1)捕獲鍵盤消息,在消息函數(shù)中處理(未提供)2)修改Edit的窗口過程:自己寫窗口過程替代原來的窗口過程(比較麻煩的方法)(1)定義窗口過程類型變量WNDPROCprevProc;(2)定義窗口過程函數(shù)LRESULTCALLBACKWinSunProc(HWNDhwnd,UINTuMsg,WPARAMwParam,LPARAMlParam){if(uMsg==WM_CHAR&&wParam==0x0d)//如果是回車{//::SetFocus(::GetNextWindow(hwnd,GW_HWNDNEXT));//獲取下一窗口句柄方法一//SetFocus(::GetWindow(hwnd,GW_HWNDNEXT));//方法二SetFocus(::GetNextDlgTabItem(::GetParent(hwnd),hwnd,FALSE));//方法三return1;}elsereturnprevProc(hwnd,uMsg,wParam,lParam);}(3)添加WM_INITDIALOG對(duì)應(yīng)的函數(shù)(4)在OnI(lǐng)nitDialog中添加prevProc=(WNDPROC)SetWindowLong(GetDlgItem(IDC_EDIT1)->m_hWnd,GWL_WNDPROC,(LONG)WinSunProc);(5)注意edit控件MultiLine復(fù)選屬性選/不選的不同SetWindowLongchangesanattributeofthespecifiedwindow.3)在OnOK(defaultbutton對(duì)應(yīng)的函數(shù))GetFocus()-〉GetNextWindow()-〉SetFocus();//注意最后一個(gè)窗口時(shí)要判斷,不然獲取出錯(cuò)GetFocus()—>GetWindow(GW_HWNDNEXT)-〉SetFocus();//注意同上GetNextDlgTabItem(GetFocus())—〉SetFocus();注意:對(duì)話框初始的OK的ID號(hào)為IDOK,即使刪除按鈕(OnOk函數(shù)存在),依然會(huì)響應(yīng)OnOk函數(shù)第七章對(duì)話框編程(2)我們假設(shè)您已經(jīng):1,知道如何創(chuàng)建一個(gè)單文檔的AppWizard2,知道C++類、函數(shù)重載等簡(jiǎn)單知識(shí)3,知道如何給View類或者Doc文檔添加成員變量4,會(huì)用MFC的IDE調(diào)試工具最好,那么本文的程序您可以copy去調(diào)試5,知道如何為某個(gè)框架類添加虛函數(shù)或消息處理函數(shù)一、簡(jiǎn)單的逃跑按鈕//注意下列方法,定義一個(gè)類為了捕獲鼠標(biāo)移動(dòng)點(diǎn)的方便1,創(chuàng)建一個(gè)基于對(duì)話框的MFCAppWizard工程2,在View窗口點(diǎn)右鍵,添加一個(gè)自定義的類(或者用Classwizard工具添加),基類為CButtonclassCWeiXinBtn:publicCButton3,給CWeiXinBtn類添加成員變量CWeiXinBtn*m_pBtn;4,給對(duì)話框添加倆按鈕,每個(gè)按鈕都關(guān)聯(lián)一個(gè)CWeiXinBtn的變量5,在OnInitDialog添加m_btn1。m_pBtn=&m_btn2;m_btn2.m_pBtn=&m_btn1;6,CWeiXinBtn::OnMouseMove中添加交換顯示的語(yǔ)句ShowWindow(SW_HIDE);m_pBtn->ShowWindow(SW_SHOW);大功告成!當(dāng)然可以SetWindowPos函數(shù)實(shí)現(xiàn)更客觀二、屬性頁(yè)的編輯1,CPropertyPage類在sheet的構(gòu)造函數(shù)中添加propertyPageprop1shee(cuò)t::AddPage把頁(yè)面添加到shee(cuò)t2,屬性頁(yè)變向?qū)ь愋蚿rop1sheep.SetWindowMode();//向?qū)J秸Z(yǔ)句prop1sheet.DoModal();3,第一頁(yè)的"上一步",最后一頁(yè)的"下一步"取消方法在第一個(gè)/最后一頁(yè)屬性頁(yè)類添加虛函數(shù)PnSetActive,并在其中添加((CPropertySheet*)GetParent())->SetWizardButtons(PSWIZB_NEXT);//第一頁(yè)((CPropertySheet*)GetParent())->SetWizardButtons(PSWIZB_BACK|PSWIZB_NEXT);//中間的頁(yè)((CPropertySheet*)GetParent())->SetWizardButtons(PSWIZB_BACK|PSWIZB_FINISH);//最后一頁(yè)4,"下一步"之前,檢查是否已完成“選擇"等在PropertyPage的OnWizardNext函數(shù)中檢查5,編輯對(duì)話框/屬性頁(yè)上的ComBox控件((CComoBox*)GetDlgItmem(IDC_ComBOX1))-〉A(chǔ)ddString("");//增加選項(xiàng)6,獲取List(ComBox)控件,并進(jìn)行編輯intsel=((CComoBox*)GetDlgItmem(IDC_ComBOX1))-〉GetCurSel();CStringm_str;((CComoBox*)GetDlgItmem(IDC_ComBOX1))->GetLBText(sel,&m_str);//取出用戶的選擇7,窗口IDOK==xxx.DoModal()后,其上面的控件生命期仍有效,所以可以用變量接受其值8,List控件的sort屬性選中/不選中,表示是否自動(dòng)排序,注意有時(shí)不需要自己排序下面講述一個(gè)屬性頁(yè)對(duì)話框的使用例程。1,VC++經(jīng)常問題。不能為已建好的類打開文件在VC中為資源(對(duì)話框、屬性頁(yè)等)添加類時(shí),打開classwizard=>添加類,輸入類名,選擇baseclass,點(diǎn)OK之后,彈出不能打開文件的錯(cuò)誤”Unabletoopenthe)forclassxxx"解決辦法:刪除類信息文件XXX.clw;再次調(diào)用classwizard,重新產(chǎn)生一個(gè)xxx。clw即可2,屬性頁(yè)資源的增加在ResourceView里Dialog處點(diǎn)擊右鍵InsertèDialogèIDD_PROPPAGE_LARGE(English(U。S.))注意看屬性頁(yè)資源的屬性:類型-Child,Border—Thin,Systemmenu不復(fù)選,Morestyle中復(fù)選了Disabled也可以通過修改普通對(duì)話框,而成為屬性頁(yè).3,創(chuàng)建類給屬性頁(yè)對(duì)話框添加類的時(shí)候,基類選為CPropertyPage,而不是CDialog4,創(chuàng)建屬性表單利用Classwizard插入一個(gè)新的類,基類選為CPropertySheet5,給屬性表單添加三個(gè)public變量CProp1m_prop1;CProp2m_prop2;CProp3m_prop3;6,在屬性表單的兩個(gè)構(gòu)造函數(shù)增加表單AddPage(&m_prop1);AddPage(&m_prop2);AddPage(&m_prop3);7,在View類添加一個(gè)菜單項(xiàng),添加響應(yīng)函數(shù),添加下列語(yǔ)句CPropSheetpropSheet(”維新屬性表單程序");//propSheet。SetWizardMode();//向?qū)ь悤r(shí)增加這一句if(ID_WIZFINISH==propSheet.DoModal()){//獲取各個(gè)表單項(xiàng)的選項(xiàng),僅作為例子m_iOccupation=propSheet。m_prop1.m_occup

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝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ù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 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ì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論