VC 入門教程(windows入門程序詳解)42200_第1頁
VC 入門教程(windows入門程序詳解)42200_第2頁
VC 入門教程(windows入門程序詳解)42200_第3頁
VC 入門教程(windows入門程序詳解)42200_第4頁
VC 入門教程(windows入門程序詳解)42200_第5頁
已閱讀5頁,還剩36頁未讀 繼續(xù)免費(fèi)閱讀

付費(fèi)下載

下載本文檔

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

文檔簡介

1、VC+入門教程(windows入門程序詳解).txt時尚,就是讓年薪八千的人看上去像年薪十萬。我們總是要求男人有孩子一樣的眼神,父親一樣的能力。一分鐘就可以遇見一個人,一小時喜歡上一個人,一天愛上一個人,但需要花盡一生的時間去忘記一個人。- 不是我寫的.第一講:預(yù)備知識與概念介紹 注:我寫這個專題目的是為VC初學(xué)者提供一個思路,我本人很菜,但我認(rèn)為對于VC初學(xué)者來講,可能有點幫助,當(dāng)然,對于WinSDK編程,我也是剛剛接觸。如果你對WinSDK編程較熟,請與我聯(lián)系,咱們共同來把這個專題做好,如果你發(fā)現(xiàn)了什么錯誤,也麻煩你給我留言指正。我寫的內(nèi)容也基本上是我自己的一些理解,錯誤是肯定有的,如果你

2、發(fā)現(xiàn)我的理解偏差很大的話,麻煩你提醒一下。-小朱!什么是WinSDK:大致說來windows編程有兩種方法: 1.windwos c方式(SDK), 2.c+方式:即對SDK函數(shù)進(jìn)行包裝,如VC的MFC,BCB的OWL等,如果要深入 下去,還是要熟悉SDK。兩種方法有哪些區(qū)別呢:SDK編程就是直接調(diào)用windows的API進(jìn)行編程,但是有上千個API組成(win95的API有兩千多個),這種數(shù)目太大了,對于編程顯然不利。而MFC把這些API封閉起來,共有一百多個類組成。一般只需20多個windows類和另外20多個通用的非windows類就可干活了,這一改變無疑是有很大好處的。盡管MFC如此方

3、便,但是要學(xué)VC,直接去學(xué)MFC卻是不明智的選擇。只有在熟悉了MFC的運(yùn)行機(jī)制的情況下,才有可能深入下去。那些如多少天精通什么什么的書籍其實講的全是些如怎么使用VC這種工具的話題,學(xué)來學(xué)去學(xué)會了怎么會使用VC這種工具,而不能深入MFC編程。象VB這類工具就更令人感覺到太悶了,不過各有各的好處。MFC雖然提高了程序員編程的效率,但是也失去了SDK編程的靈活性.不好意思,跑題了.本專題假定:C語言是windows的源語言,用C進(jìn)行SDK編程是最合適的,你應(yīng)該至少學(xué)過C語言,知道C語言的各種語法等,當(dāng)我說到指針等類似概念的時候,你不至于茫然就行了。你還應(yīng)該安裝了Visual C+6.0,低版本的就不

4、用用了吧,D版的才幾塊錢嗎?推薦與參考資料:1.Petzold的programming windows by petzold,這是我看過的一本書(電子書),不過是E文的,我只看了一半,下載空間一欄能供了該電子書。中文版的是Windows 程序設(shè)計(包括上,下卷),Charles Petzold著,北京博彥發(fā)展有限公司譯,北京大學(xué)出版社出版,本書唯一的缺點就是太貴,價格是160元。一些朋友讓我多推薦一些這方面的書,我也沒辦法,一是這類書目前本就很少,二是如果你非要買的話,肯定要買這本書了,可是經(jīng)典呢!2.還有一本老書值得一提,可能市面上已經(jīng)買不到了,書名Windows 編程,劉振安著,人民郵電出

5、版社出版發(fā)行。一個朋友曾借給我看了幾天我又還了,很容易讀懂的,不過一看日期,95年出版,得!沒希望了。我們學(xué)校圖書館好像也有幾本,不過好像都很爛。3.VC的在線幫助MSDN,有關(guān)SDK的資料在Platform SDK一欄中。下面再加深幾點概念:什么是API:什么是API,有必要再談一下,特別對于從TC過來的朋友和初學(xué)編程的朋友。API,全稱application program interface,意思是應(yīng)用程序編程接口(說起API并不僅僅指windows而言,windows支持的API叫winapi)。winapi就是應(yīng)用程序和windows之間通訊的一個編程界面。windows提供了上千個

6、API函數(shù),以方便程序員來編寫應(yīng)用程序。做數(shù)據(jù)庫管理系統(tǒng)是很少和API打交道的,我以前學(xué)PB,看的十幾本書都沒有專門的章節(jié)來介紹API的。只有到網(wǎng)上看那些PB技巧之類的文章才談及API,不過還要加入一大堆聲明之類的東東。好像VB也是這樣??傊M(jìn)行系統(tǒng)編程,API是必不可少的。API是每個VC高手的必過的一關(guān)。什么是WinSDK編程:WinSDK程序設(shè)計就是API方式的windows程序設(shè)計。SDK,全稱Software Developers Kit,意思是軟件開發(fā)工具箱。它是在windows程序設(shè)計早期,程序員進(jìn)行windows程序設(shè)計所必須購買的一個軟件包(不知道那時候有沒有D版的)。我兩

7、個月前見SDK還不知所云。開始進(jìn)行WinSDK編程用C語言最好,可以撇開C+的特性專心熟悉一下Win32編程的思路以及了解windows的消息運(yùn)行機(jī)制。等把這些有所了解后,慢慢轉(zhuǎn)向C+和MFC編程。不過我的觀點是WinSDK編程永遠(yuǎn)要慢慢進(jìn)行下去,直接接觸底層代碼對MFC源碼的理解是有很大好處的。上周開始用MFC時,按F11進(jìn)行單步跟蹤,一開始見到_tWinMain這樣古怪的東東也沒有感覺到太大的迷惑,不就是相當(dāng)于SDK編程中的WinMain函數(shù)嗎?什么是MFC:MFC,全稱Microsoft Foundation Classes,偽軟把WinAPI進(jìn)行封裝的類庫。它是一個類的集合,通過覆蓋W

8、inAPI,為編程提供了一個面向?qū)ο蟮慕缑?。它使windows程序員能夠利用C+面象對象的特性進(jìn)行編程,類似BCB的OWL,Delphi的VCL組件。它把那些進(jìn)行SDK編程時最繁瑣的部分提供給程序員,使之專注于功能的實現(xiàn)。你不妨把它想象成類似TC提供的函數(shù)庫吧。用Visual C+這種開發(fā)工具編程時,可以用MFC,也可以不用,但MFC是VC的精華所在,從某種意義上來說,不會MFC就是不會使用VC。研究MFC源代碼是件既快樂又痛苦的事情,不過,陣痛之后,嘻嘻,.怎么進(jìn)行WinSDK編程:Visual C+6.0:File-new-Projects-Win32 Application(projec

9、t name)-.我們既然用C語言進(jìn)行,就選第一項An empty project.好累,這篇就寫這么多吧,但愿對你有幫助,也建議多給我提意見,你的反饋是我最大的動力淵源.講的不錯吧,還是比較好懂的.下面接著看. 要自己動手.第二講:WinMain與兩只小板凳的故事 注:呵呵,近兩天收到不少網(wǎng)友來信,要求我繼續(xù)寫下去,說實在的,寫這東西費(fèi)時費(fèi)力。不過一旦想起這些對大家或許有些幫助時,無形的壓力就來了。我所寫的,僅僅是我編程中的感想,如果你有何感想,希望給我留言或到C程序員論劍臺交流,如果你有好的建議,歡迎提出;如果你有好的對VC初學(xué)者有利的作品或文章,也歡迎給本站介紹,我將大力為你推廣。-小朱

10、第一只小板凳:打開an empty project后,在VC的IDE中,打開文本編輯器。輸入以下內(nèi)容:i nclude windows.hint WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)MessageBox (NULL, TEXT (你好,歡迎來到VC之路), TEXT (歡迎), 0) ;return 0 ;把它保存成以.c為擴(kuò)展名的文件,并加入空項目中。編譯.看到了吧,這就我們的第一只小板凳。它就類似于TC下的hello world吧!雖然什么功能也

11、沒實現(xiàn),但它比hello world強(qiáng)多了,因為它向我們展示了一個小窗口。支解第一只小板凳:像TC一樣,它包含一個頭文件windows.h,這是一個最基本的頭文件,它包含其它的windows頭文件.在你的X:Program FilesMicrosoft Visual StudioVC98Include目錄下,打開windows.h這個文件,你就知道它包含什么東東了。像dos下的C編程的main()一樣,windows下的入口是WinMain()函數(shù)。把光標(biāo)放在WinMain()上,按F1鍵。啟動MSDN,如果你沒安裝的話,一定要安裝一下,MSDN是最好的學(xué)習(xí)VC的資料,當(dāng)然,對于我們?nèi)腴T者,有

12、一本書從頭到尾學(xué)一下最好。第一個參數(shù):應(yīng)用程序的當(dāng)前實例句柄。第二個參數(shù):應(yīng)用程序的前一個實例句柄,別管它,對于Win32位而言,它一般是NULL.第三個參數(shù):指向任何傳給程序的命令行參數(shù)。PSTR代表指向字符串的指針。第四個參數(shù):它告訴應(yīng)用程序如何初始化窗口,如最大化,最小化等狀態(tài)。WinMain()所起的作用:初始化,展示,銷毀應(yīng)用程序等。MessageBox(),如果大家在windows下編程,這是一個很常用的API,不用我費(fèi)話了吧!幾個要點:1.句柄(handle):在標(biāo)準(zhǔn)C庫中句柄用來對文件輸入輸出。如下面的代碼:int handle;handle=open(filename,r)i

13、f(handle)read(handle,block,bytesToread);close(handle);在文件被成功打開后,open()返回一個句柄,在read()中使用這個句柄來閱讀這個文件。句柄不是指針。程序不能直接使用句柄來閱讀文件中的信息。如果不能把它傳送給輸入輸出函數(shù)調(diào)用的話,句柄就沒有用了。句柄不返回零。句柄命名以h開始。這是匈牙利表示法的規(guī)定。2.匈牙利表示法:初開始看到這個程序時,你一定感覺到很怪,我當(dāng)時就是這樣的。不知道那些字母怎么回事。因為所有的命名采用了,匈牙利表示法。如消息的前綴使用msg.句柄使用h.函數(shù)使用fn等。多說了,習(xí)慣了就好了.3.有效使用MSDN:想成

14、為VC高手,還要強(qiáng)迫自己習(xí)慣于使用MSDN,看得多了,不怕看不懂,如果僅僅知道功能不知道具體的函數(shù),可用類似的英語單詞去搜索。我平時就用金山詞霸一點點的啃。唉,說起來慚愧,本人英語四級沒過,這學(xué)期連報考都沒有。以后努力了,總感覺到大學(xué)的教育很有問題,好像每個人都在為四六級而奔忙。呵呵,說了這些,真懷疑對你真的有用。有不對的地方,請指出。希望大家共同進(jìn)步,把VC活吃了.第二只小板凳打開VC,file-new-progects-win32 application,并在project name 中輸入hello.順路走下來,選擇第二項。在編輯器中輸入以下程序覆蓋向?qū)Мa(chǎn)生的代碼:i nclude st

15、dafx.h /注意,這個向?qū)Мa(chǎn)生的頭文件不能去掉i nclude LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,PSTR szCmdLine, int iCmdShow)static TCHAR szAppName = TEXT (HelloWin) ;HWND hwnd ;MSG msg ;WNDCLASS wc ;wc.style = CS_HREDRAW | CS_VREDRAW ;wc.lpf

16、nWndProc = WndProc ;wc.cbClsExtra = 0 ;wc.cbWndExtra = 0 ;wc.hInstance = hInstance ;wc.hIcon = LoadIcon (NULL, IDI_APPLICATION) ;wc.hCursor = LoadCursor (NULL, IDC_ARROW) ;wc.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ;wc.lpszMenuName = NULL ;wc.lpszClassName = szAppName ;if (!RegisterCla

17、ss (&wc)MessageBox (NULL, TEXT (This program requires Windows NT!),szAppName, MB_ICONERROR) ;return 0 ;hwnd = CreateWindow (szAppName, / window class nameTEXT (歡迎你的到來!), / window captionWS_OVERLAPPEDWINDOW, / window styleCW_USEDEFAULT, / initial x positionCW_USEDEFAULT, / initial y positionCW_USEDEF

18、AULT, / initial x sizeCW_USEDEFAULT, / initial y sizeNULL, / parent window handleNULL, / window menu handlehInstance, / program instance handleNULL) ; / creation parametersShowWindow (hwnd, iCmdShow) ;UpdateWindow (hwnd) ;while (GetMessage (&msg, NULL, 0, 0)TranslateMessage (&msg) ;DispatchMessage (

19、&msg) ;return msg.wParam ;LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)HDC hdc ;PAINTSTRUCT ps ;RECT rect ;switch (message)case WM_PAINT:hdc = BeginPaint (hwnd, &ps) ;GetClientRect (hwnd, &rect) ;DrawText (hdc, TEXT (你好,歡迎你來到VC之路!), -1, &rect,DT_SINGLELINE | DT_CEN

20、TER | DT_VCENTER) ;EndPaint (hwnd, &ps) ;return 0 ;case WM_DESTROY:PostQuitMessage (0) ;return 0 ;return DefWindowProc (hwnd, message, wParam, lParam) ;按前兩節(jié)講的方法編譯后,就見到我們的第二只小板凳了,可別小看它,對它的全面理解對于學(xué)習(xí)MFC的封裝是有很大好處的。windows的消息循環(huán)機(jī)制等都可通過這個東東解釋出來。好了,咱們年后繼續(xù)努力吧,應(yīng)該應(yīng)付一下該死的考試了.windows消息機(jī)制,我們要用四講來討論消息機(jī)制.第一講:Dos的過程驅(qū)

21、動與Windows的事件驅(qū)動在講本程序的消息循環(huán)之前,我想先談一下Dos與Windows驅(qū)動機(jī)制的區(qū)別:DOS程序主要使用順序的,過程驅(qū)動的程序設(shè)計方法。順序的,過程驅(qū)動的程序有一個明顯的開始,明顯的過程及一個明顯的結(jié)束,因此程序能直接控制程序事件或過程的順序。雖然在順序的過程驅(qū)動的程序中也有很多處理異常的方法,但這樣的異常處理也仍然是順序的,過程驅(qū)動的結(jié)構(gòu)。而Windows的驅(qū)動方式是事件驅(qū)動,就是不由事件的順序來控制,而是由事件的發(fā)生來控制,所有的事件是無序的,所為一個程序員,在你編寫程序時,你并不知道用戶先按哪個按紐,也不知道程序先觸發(fā)哪個消息。你的任務(wù)就是對正在開發(fā)的應(yīng)用程序要發(fā)出或要

22、接收的消息進(jìn)行排序和管理。事件驅(qū)動程序設(shè)計是密切圍繞消息的產(chǎn)生與處理而展開的,一條消息是關(guān)于發(fā)生的事件的消息。Windows編程的特點:C語言編程至少有一個主程序,其名字是main()。Windows程序則至少兩個主程序,一個是WinMain(),int WINAPI WinMain(HINSTANCE hInstance, / handle to current instanceHINSTANCE hPrevInstance, / handle to previous instanceLPSTR lpCmdLine, / command lineint nCmdShow / show sta

23、te);另一個是窗口過程函數(shù)WndProc,它的函數(shù)原型為:long FAR PASCAL WndProc(HWND hWnd,WORD message,WORD wParam,LONG lParam);Windows應(yīng)用程序的編程就圍繞這兩個部份進(jìn)行的。其中WinMain函數(shù)為應(yīng)用程序的入口點,它的名字一定要是WinMain。在Windows中,應(yīng)用程序通過要求Windows完成指定操作,而承擔(dān)這項通信任務(wù)的API函數(shù)就是Windows的相應(yīng)窗口函數(shù)WndProc。在dos里,程序能直接控制事件的發(fā)生順序,結(jié)果等。而在Windows里,應(yīng)用程序不直接調(diào)用任何窗口函數(shù),而是等待Windows調(diào)

24、用窗口函數(shù),請求完成任務(wù)或返回信息。為保證Windows調(diào)用這個窗口函數(shù),這個函數(shù)必須先向Windows登記,然后在Windows實施相應(yīng)操作時回調(diào),所以窗口函數(shù)又稱為回調(diào)函數(shù)。WndProc是一個主回調(diào)函數(shù),Windows至少有一個回調(diào)函數(shù)。回調(diào)函數(shù)WndProc在哪里定義的呢,請看這個語句:wc.lpfnWndProc = WndProc ;將在第七講里詳談.實例:在Windows中,能多次同時運(yùn)行同一個應(yīng)用程序,即運(yùn)行多個副本,每個副本叫做一個“實例”。現(xiàn)在讓我們把這個程序?qū)訉觿兘忾_來,我把自己的理解慢慢地展示給你:我把這個程序支解為四塊一)建立,注冊窗口類.(二)創(chuàng)建窗口.(三)顯示和

25、更新窗口.(四)創(chuàng)建消息循環(huán).(五)終止應(yīng)用程序.(六)窗口過程.(七)處理消息.(一)注冊窗口類:(1)建立窗口類WinMain()是程序的入口,它相當(dāng)于一個中介人的角色,把應(yīng)用程序(指小窗口)介紹給windows.首要的一步是登記應(yīng)用程序的窗口類.窗口種類是定義窗口屬性的模板,這些屬性包括窗口式樣,鼠標(biāo)形狀,菜單等等,窗口種類也指定處理該類中所有窗口消息的窗口函數(shù).只有先建立窗口種類,才能根據(jù)窗口種類來創(chuàng)建Windows應(yīng)用程序的一個或多個窗口.創(chuàng)建窗口時,還可以指定窗口獨有的附加特性.窗口種類簡稱窗口類,窗口類不能重名.在建立窗口類后,必須向Windows登記.建立窗口類就是用WNDCL

26、ASS結(jié)構(gòu)定義一個結(jié)構(gòu)變量,在這個程序中就是指 WNDCLASS wc ;然后用自己設(shè)計的窗口屬性的信息填充結(jié)構(gòu)變量wc的域.要WinMain登記窗口類,首先要填寫一個WNDCLASS結(jié)構(gòu),其定義如下所示:typedef struct _WNDCLASSAUINT style ; /窗口類風(fēng)格WNDPROC lpfnWndProc ; /指向窗口過程函數(shù)的指針int cbClsExtra ; /窗口類附加數(shù)據(jù)int cbWndExtra ; /窗口附加數(shù)據(jù)HINSTANCE hInstance ; /擁有窗口類的實例句柄HICON hIcon ; /最小窗口圖標(biāo)HCURSOR hCursor

27、; /窗口內(nèi)使用的光標(biāo)HBRUSH hbrBackground ;/用來著色窗口背景的刷子LPCSTR lpszMenuName ; /指向菜單資源名的指針LPCSTR lpszClassName ;/ 指向窗口類名的指針在VC6.0里面,把光標(biāo)定位在WNDCLASS上,按F1,即可啟動MSDN,在MSDN里你可看到這個結(jié)構(gòu)原形.在下節(jié)講解這些參數(shù)在本程序中的具體用法.(2)注冊窗口類(1)第一個參數(shù):成員style控制窗口的某些重要特性,在WINDOWS.H中定義了一些前綴為CS的常量,在程序中可組合使用這些常量.也可把sytle設(shè)為0.本程序中為wc.style = CS_HREDRAW

28、| CS_VREDRAW,它表示當(dāng)窗口的縱橫坐標(biāo)發(fā)生變化時要重畫整個窗口。你看:無論你怎樣拉動窗口的大小,那行字都會停留在窗口的正中部,而假如把這個參數(shù)設(shè)為0的話,當(dāng)改動窗口的大小時,那行字則不一定處于中部了。(2)第二個參數(shù):lpfnWndProc包括一個指向該窗口類的消息處理函數(shù)的指針,此函數(shù)稱為窗口過程函數(shù)。它將接收Windows發(fā)送給窗口的消息,并執(zhí)行相應(yīng)的任務(wù)。其原型為:long FAR PASCAL WndProc(HWND ,unsigned,WORD,LONG);并且必須在??於x中回調(diào)它。WndProc是一個回調(diào)函數(shù)(見第五節(jié)),如果暫時無法理解這個模糊的概念意味著什么,可先

29、放過,等到講消息循環(huán)時再詳談。(3)第三,四個參數(shù):cbWndExtra域指定用本窗口類建立的所有窗口結(jié)構(gòu)分配的額外字節(jié)數(shù)。當(dāng)有兩個以上的窗口屬于同一窗口類時,如果想將不同的數(shù)據(jù)和每個窗口分別相對應(yīng)。則使用該域很有用。這般來講,你只要把它們設(shè)為0就行了,不必過多考慮。(4)第五個參數(shù):hInstance域標(biāo)識應(yīng)用程序的實例hInstance,當(dāng)然,實例名是可以改變的。wc.hInstance = hInstance ;這一成員可使Windows連接到正確的程序。(5)第六個參數(shù):成員hIcon被設(shè)置成應(yīng)用程序所使用圖標(biāo)的句柄,圖標(biāo)是將應(yīng)用程序最小化時出現(xiàn)在任務(wù)欄里的的圖標(biāo),用以表示程序仍駐留在

30、內(nèi)存中。Windows提供了一些默認(rèn)圖標(biāo),我們也可定義自己的圖標(biāo),VC里面專有一個制作圖標(biāo)的工具。(6)第七個參數(shù): hCursor域定義該窗口產(chǎn)生的光標(biāo)形狀。LoadCursor可返回固有光標(biāo)句柄或者應(yīng)用程序定義的光標(biāo)句柄。IDC_ARROW表示箭頭光標(biāo).(7)第八個參數(shù):wc.hbrBackground域決定Windows用于著色窗口背景的刷子顏色,函數(shù)GetStockObject返回窗口的顏色,本程序中返回的是白色,你也可以把它改變?yōu)榧t色等其他顏色.試試看(8)第九個參數(shù):lpszMenuName用來指定菜單名,本程序中沒有定義菜單,所以為NULL。(9)第十個參數(shù):lpszClassN

31、ame指定了本窗口的類名。當(dāng)對WNDCLASS結(jié)構(gòu)域一一賦值后,就可注冊窗口類了,在創(chuàng)建窗口之前,是必須要注冊窗口類的,注冊窗口類用的API函數(shù)是RegisterClass,注冊失敗的話,就會出現(xiàn)一個對話框如程序所示,函數(shù)RegisterClass返回0值,也只能返回0值,因為注冊不成功,程序已經(jīng)不能再進(jìn)行下去了。在本程序中注冊窗口類如下:if (!RegisterClass (&wc) MessageBox (NULL, TEXT (This program requires Windows NT!),szAppName,MB_ICONERROR) ;return 0 ; 第二講 消息機(jī)制(

32、二)創(chuàng)建窗口注冊窗口類后,就可以創(chuàng)建窗口了,本程序中創(chuàng)建窗口的有關(guān)語句如下:hwnd = CreateWindow (szAppName, / window class nameTEXT (歡迎你的到來!), / window captionWS_OVERLAPPEDWINDOW, / window styleCW_USEDEFAULT, / initial x positionCW_USEDEFAULT, / initial y positionCW_USEDEFAULT, / initial x sizeCW_USEDEFAULT, / initial y sizeNULL, / pare

33、nt window handleNULL, / window menu handlehInstance, / program instance handleNULL) ; / creation parameters參數(shù)1:登記的窗口類名,這個類名剛才咱們在注冊窗口時已經(jīng)定義過了。參數(shù)2:用來表明窗口的標(biāo)題。參數(shù)3: 用來表明窗口的風(fēng)格,如有無最大化,最小化按紐啊什么的。參數(shù)4,5: 用來表明程序運(yùn)行后窗口在屏幕中的坐標(biāo)值。參數(shù)6,7: 用來表明窗口初始化時(即程序初運(yùn)行時)窗口的大小,即長度與寬度。參數(shù)8: 在創(chuàng)建窗口時可以指定其父窗口,這里沒有父窗口則參數(shù)值為0。參數(shù)9: 用以指明窗口的菜單

34、,菜單以后會講,這里暫時為0。最后一個參數(shù)是附加數(shù)據(jù),一般都是0。CreateWindow()的返回值是已經(jīng)創(chuàng)建的窗口的句柄,應(yīng)用程序使用這個句柄來引用該窗口。如果返回值為0,就應(yīng)該終止該程序,因為可能某個地方出錯了。如果一個程序創(chuàng)建了多個窗口,則每個窗口都有各自不同的句柄.(三)顯示和更新窗口API函數(shù)CreateWindow創(chuàng)建完窗口后,要想把它顯示出現(xiàn),還必須調(diào)用另一個API函數(shù)ShowWindows.形式為:ShowWindow (hwnd, iCmdShow); 其第一個參數(shù)是窗口句柄,告訴ShowWindow()顯示哪一個窗口,而第二個參數(shù)則告訴它如何顯示這個窗口:最小化(SW_M

35、INIMIZE),普通(SW_SHOWNORMAL),還是最大化(SW_SHOWMAXIMIZED)。WinMain在創(chuàng)建完窗口后就調(diào)用ShowWindow函數(shù),并把iCmdShow參數(shù)傳送給這個窗口。你可把iCmdShow改變?yōu)檫@些參數(shù)試試。WinMain()調(diào)用完ShowWindow后,還需要調(diào)用函數(shù)UpdateWindow,最終把窗口顯示了出來。調(diào)用函數(shù)UpdateWindow將產(chǎn)生一個WM_PAINT消息,這個消息將使窗口重畫,即使窗口得到更新.(四)創(chuàng)建消息循環(huán)主窗口顯示出來了,WinMain就開始處理消息了,怎么做的呢?Windows為每個正在運(yùn)行的應(yīng)用程序都保持一個消息隊列。當(dāng)你

36、按下鼠標(biāo)或者鍵盤時,Windows并不是把這個輸入事件直接送給應(yīng)用程序,而是將輸入的事件先翻譯成一個消息,然后把這個消息放入到這個應(yīng)用程序的消息隊列中去。應(yīng)用程序又是怎么來接收這個消息呢?這就講講消息循環(huán)了。應(yīng)用程序的WinMain函數(shù)通過執(zhí)行一段代碼從她的隊列中來檢索Windows送往她的消息。然后WinMain就把這些消息分配給相應(yīng)的窗口函數(shù)以便處理它們,這段代碼是一段循環(huán)代碼,故稱為消息循環(huán)。這段循環(huán)代碼是什么呢?好,往下看:在咱們的第二只小板凳中,這段代碼就是:.MSG msg; /定義消息名while (GetMessage (&msg, NULL, 0, 0)TranslateMe

37、ssage (&msg) ; /翻譯消息DispatchMessage (&msg) ; /撤去消息return msg.wParam ;MSG結(jié)構(gòu)在頭文件中定義如下:typedef struct tagMSGHWND hwnd;UINT message;WPARAM wParam;LPARAM lParam;DWORD time;POINT pt; MSG, *PMSG;MSG數(shù)據(jù)成員意義如下:參數(shù)1:hwnd是消息要發(fā)送到的那個窗口的句柄,這個窗口就是咱們用CreateWindows函數(shù)創(chuàng)建的那一個。如果是在一個有多個窗口的應(yīng)用程序中,用這個參數(shù)就可決定讓哪個窗口接收消息。參數(shù)2:mess

38、age是一個數(shù)字,它唯一標(biāo)識了一種消息類型。每種消息類型都在Windows文件中定義了,這些常量都以WM_開始后面帶一些描述了消息特性的名稱。比如說當(dāng)應(yīng)用程序退出時,Windows就向應(yīng)用程序發(fā)送一條WM_QUIT消息。參數(shù)3:一個32位的消息參數(shù),這個值的確切意義取決于消息本身。參數(shù)4:同上。參數(shù)5:消息放入消息隊列中的時間,在這個域中寫入的并不是日期,而是從Windows啟動后所測量的時間值。Windows用這個域來使用消息保持正確的順序。參數(shù)6:消息放入消息隊列時的鼠標(biāo)坐標(biāo).消息循環(huán)以GetMessage調(diào)用開始,它從消息隊列中取出一個消息:GetMessage(&msg,NULL,0,

39、0),第一個參數(shù)是要接收消息的MSG結(jié)構(gòu)的地址,第二個參數(shù)表示窗口句柄,NULL則表示要獲取該應(yīng)用程序創(chuàng)建的所有窗口的消息;第三,四參數(shù)指定消息范圍。后面三個參數(shù)被設(shè)置為默認(rèn)值,這就是說你打算接收發(fā)送到屬于這個應(yīng)用程序的任何一個窗口的所有消息。在接收到除WM_QUIT之外的任何一個消息后,GetMessage()都返回TRUE。如果GetMessage收到一個WM_QUIT消息,則返回FALSE,如收到其他消息,則返回TRUE。因此,在接收到WM_QUIT之前,帶有GetMessage()的消息循環(huán)可以一直循環(huán)下去。只有當(dāng)收到的消息是WM_QUIT時,GetMessage才返回FALSE,結(jié)束

40、消息循環(huán),從而終止應(yīng)用程序。 均為NULL時就表示獲取所有消息。消息用GetMessage讀入后(注意這個消息可不是WM_QUIT消息),它首先要經(jīng)過函數(shù)TranslateMessage()進(jìn)行翻譯,這個函數(shù)會轉(zhuǎn)換成一些鍵盤消息,它檢索匹配的WM_KEYDOWN和WM_KEYUP消息,并為窗口產(chǎn)生相應(yīng)的ASCII字符消息(WM_CHAR),它包含指定鍵的ANSI字符.但對大多數(shù)消息來說它并不起什么作用,所以現(xiàn)在沒有必要考慮它。下一個函數(shù)調(diào)用DispatchMessage()要求Windows將消息傳送給在MSG結(jié)構(gòu)中為窗口所指定的窗口過程。我們在講到登記窗口類時曾提到過,登記窗口類時,我們曾指

41、定Windows把函數(shù)WindosProc作為咱們這個窗口的窗口過程(就是指處理這個消息的東東)。就是說,Windows會調(diào)用函數(shù)WindowsProc()來處理這個消息。在WindowProc()處理完消息后,代碼又循環(huán)到開始去接收另一個消息,這樣就完成了一個消息循環(huán)。下一個出場的東東就是窗口過程了,先歇一會兒再說吧?再次申明,不是我寫的。覺得作者寫的好轉(zhuǎn)過來和大家一起分享。第三講:Windows消息機(jī)制(3)(五)終止應(yīng)用程序:Windows是一種非剝奪式多任務(wù)操作系統(tǒng)。只有的應(yīng)用程序交出CPU控制權(quán)后,Windows才能把控制權(quán)交給其他應(yīng)用程序。當(dāng)GetMessage函數(shù)找不到等待應(yīng)用程

42、序處理的消息時,自動交出控制權(quán),Windows把CPU的控制權(quán)交給其他等待控制權(quán)的應(yīng)用程序。由于每個應(yīng)用程序都有一個消息循環(huán),這種隱式交出控制權(quán)的方式保證合并各個應(yīng)用程序共享控制權(quán)。一旦發(fā)往該應(yīng)用程序的消息到達(dá)應(yīng)用程序隊列,即開始執(zhí)行GetMessage語句的下一條語句。當(dāng)WinMain函數(shù)把控制返回到Windows時,應(yīng)用程序就終止了。應(yīng)用程序的啟動消息循環(huán)前要檢查引導(dǎo)出消息循環(huán)的每一步,以確保每個窗口已注冊,每個窗口都已創(chuàng)建。如存在一個錯誤,應(yīng)用程序應(yīng)返回控制權(quán),并顯示一條消息。但是,一旦WinMain函數(shù)進(jìn)入消息循環(huán),終止應(yīng)用程序的唯一辦法就是使用PostQuitMessage把消息WM

43、_QUIT發(fā)送到應(yīng)用程序隊列。當(dāng)GetMessage函數(shù)檢索到WM_QUIT消息,它就返回NULL,并退出消息外循環(huán)。通常,當(dāng)主窗口正在刪除時(即窗口已接收到一條WM_DESTROY消息),應(yīng)用程序主窗口的窗口函數(shù)就發(fā)送一條WM_QUIT消息。雖然WinMain指定了返回值的數(shù)據(jù)類型,但Windows并不使用返回值。不過,在調(diào)試一應(yīng)用程序時,返回值地有用的。通常,可使用與標(biāo)準(zhǔn)C程序相同的返回值約定:0表示成功,非0表示出錯。PostQuitMessage函數(shù)允許窗口函數(shù)指定返回值,這個值復(fù)制到WM_QUIT消息的wParam參數(shù)中。為了的結(jié)束消息循環(huán)之后返回這個值,我們的第二只小板凳中使用了以

44、下語句:return msg.wParam ; /表示從PostQuitMessage返回的值例如:當(dāng)Windows自身終止時,它會撤消每個窗口,但不把控制返回給應(yīng)用程序的消息循環(huán),這意味著消息循環(huán)將永遠(yuǎn)不會檢索到WM_QUIT消息,并且的循環(huán)之后的語句也不能再執(zhí)行。Windows的終止前的確發(fā)送一消息給每個應(yīng)用程序,因而標(biāo)準(zhǔn)C程序通常會的結(jié)束前清理現(xiàn)場并釋放資源,但Windows應(yīng)用程序必須隨每個窗口的撤消而被清除,否則會丟失一些數(shù)據(jù)。(六)窗口過程,窗口過程函數(shù)如前所述,函數(shù)GetMessage負(fù)責(zé)從應(yīng)用程序的消息隊列中取出消息,而函數(shù)DispatchMessage()要求Windows將

45、消息傳送給在MSG結(jié)構(gòu)中為窗口所指定的窗口過程。然后出臺的就是這個窗口過程了,這個窗口過程的任務(wù)是干什么呢?就是最終用來處理消息的,就是消息的處理器而已,那么這個函數(shù)就是WindowProc,在Visual C+6.0中按F1啟動MSDN,按下面這個路徑走下來:PlatForm SDK-User Interface services-Windows user Interface-Windowing-Window Procedures-Window Procedure Reference-Windows Procedure Functions-WindowProc啊,太累了,不過我們終于的MSD

46、N中找到了這個函數(shù),前幾次我講解這些API函數(shù)的時候,都是的知道的情況下搜索出來的,所以沒有詳細(xì)給出每個函數(shù)的具體位置,而這次我卻是一點點去找的,還好,沒被累死,體會到MSDN的龐大了吧,不過我用的是MSDN2000,是D版的,三張光盤裝。你用的MSDN如果按這個路徑走下去的話,可能會找不到,不過我想大致也是在這個位置了,找找看!LRESULT CALLBACK WindowProc(HWND hwnd, / handle to windowUINT uMsg, / message identifierWPARAM wParam, / first message parameterLPARAM

47、 lParam / second message parameter);這個函數(shù)我們的第二只小板凳里被我們稱為WndProc.下面講解:不知你注意到了沒有,這個函數(shù)的參數(shù)與剛剛提到的GetMessage調(diào)用把返回的MSG結(jié)構(gòu)的前四個成員相同。如果消息處理成功,WindowProc的返回值為0.Windows的啟動應(yīng)用程序時,先調(diào)用WinMain函數(shù),然后調(diào)用窗口過程,注意:在我們的這個程序中,只有一個窗口過程,實際上,也許有不止一個的窗口過程。例如,每一個不同的窗口類都 有一個與之相對應(yīng)的窗口過程。無論Windows何時想傳遞一個消息到一窗口,都將調(diào)用相應(yīng)的窗口過程。當(dāng)Windows從環(huán)境,或

48、從另一個應(yīng)用程序,或從用戶的應(yīng)用程序中得到消息時,它將調(diào)用窗口過程并將信息傳給此函數(shù)??傊?,窗口過程函數(shù)處理所有傳送到由此窗口類創(chuàng)建的窗口所得到的消息。并且窗口過程有義務(wù)處理Windows扔給它的任何消息。我們在學(xué)習(xí)Windows程序設(shè)計的時候,最主要的就是學(xué)習(xí)這些消息是什么以及是什么意思,它們是怎么工作的。令我們不解的是,在程序中我們看不出來是哪一個函數(shù)在調(diào)用窗口過程。它其實是一個回調(diào)函數(shù).前面已經(jīng)提到,Windows把發(fā)生的輸入事件轉(zhuǎn)換成輸入消息放到消息隊列中,而消息循環(huán)將它們發(fā)送到相應(yīng)的窗口過程函數(shù),真正的處理是在窗口過程函數(shù)中執(zhí)行的,在Windows中就使用了回調(diào)函數(shù)來進(jìn)行這種通信。回

49、調(diào)函數(shù)是輸出函數(shù)中特殊的一種,它是指那些在Windows環(huán)境下直接調(diào)用的函數(shù)。一個應(yīng)用程序至少有一個回調(diào)函數(shù),因為在應(yīng)用程序處理消息時,Windows調(diào)用回調(diào)函數(shù)。這種回調(diào)函數(shù)就是我們前面提到的窗口過程,它對對應(yīng)于一個活動的窗口,回調(diào)函數(shù)必須向Windows注冊,Windows實施相應(yīng)操作即行回調(diào)。每個窗口必須有一個窗口過程與之對應(yīng),且Windows直接調(diào)用本函數(shù),因此,窗口函數(shù)必須采用FAR PASCAL調(diào)用約定。在我們的第二只小板凳中,我們的窗口函數(shù)為WndProc,必須注意這里的函數(shù)名必須是前面注冊的窗口類時,向域wc.lpfnWndProc所賦的WndProc。函數(shù)WndProc就是前

50、面定義的窗口類所生成的所有窗口的窗口函數(shù)。在我們的這個窗口函數(shù)中,WndProc處理了共有兩條消息:WM_PAINT和WM_DESTROY.窗口函數(shù)從Windows中接收消息,這些消息或者是由WinMain函數(shù)發(fā)送的輸入消息,或者是直接來自Windows的窗口管理消息。窗口過程檢查一條消息,然后根據(jù)這些消息執(zhí)行特定的動作未被處理的消息通過DefWindowProc函數(shù)傳回給Windows作缺海上處理??梢园l(fā)送窗口函數(shù)的消息約有220種,所有窗口消息都以WM_開頭,這些消息在頭文件中被定義為常量。引起Windows調(diào)用窗口函數(shù)的原因有很多,如改變窗口大小啊,改變窗口在屏幕上的位置啊什么的。Win

51、dows已經(jīng)把任務(wù)扔給窗口過程了,窗口過程是怎么處理消息的呢?稍息一下,讓我們進(jìn)行下一節(jié):處理消息.第三講:Windows消息機(jī)制(4)注:可能你看這些東西的時候有些亂,不過沒關(guān)系,這很正常,多看幾下MSDN就慢慢明白了,有我寫這個專題的時候,很多概念也太不清楚,不過等我查資料寫下來后,感覺漸漸有些東西也有了點眉目,因為這本身也是個進(jìn)步的過程。 -小朱 (七)處理消息 窗口過程處理消息通常以switch語句開始,對于它要處理的每一條消息ID都跟有一條case語句。大多數(shù)windows proc都有具有下面形式的內(nèi)部結(jié)構(gòu):switch(uMsgId)case WM_(something):/這里

52、此消息的處理過程return 0;case WM_(something else):/這里是此消息的處理過程ruturn 0;default:/其他消息由這個默認(rèn)處理函數(shù)來處理return DefWindowProc(hwnd,uMsgId,wParam,lParam);在處理完消息后,要返回0,這很重要-它會告訴Windows不必再重試了。對于那些在程序中不準(zhǔn)備處理的消息,窗口過程會把它們都扔給DefWindowProc進(jìn)行缺省處理,而且還要返回那個函數(shù)的返回值。在消息傳遞層次中,可以認(rèn)為DefWindowProc函數(shù)是最頂層的函數(shù)。這個函數(shù)發(fā)出WM_SYSCOMMAND消息,由系統(tǒng)執(zhí)行Wi

53、ndows環(huán)境中多數(shù)窗口所公用的各種通用操作,例如,畫窗口的非用戶區(qū),更新窗口的正文標(biāo)題等等等等。再提示一下,以WM_的消息在Windows頭文件中都被定義成了常量,如WM_QUIT=XXXXXXXXXXX,但我們沒有必要記住這個數(shù)值,也不可能記得住,我們只要知道WM_QUIT就OK了。在第二只小板凳中我們只讓窗口過程處理了兩個消息:一個是WM_PAINT,另一個是WM_DESTROY,先說說第一個消息-WM_PAINT.關(guān)于WM_PAINT:無論何時Windows要求重畫當(dāng)前窗口時,都會發(fā)該消息。也可以這樣說:無論何時窗口非法,都必須進(jìn)行重畫。 哎呀,什么又是非法窗口?什么又是重畫???你這人

54、有沒有完,嗯?稍安勿燥,我比你還煩呢?我午飯到現(xiàn)在還沒吃呢!你有點耐心,來點專業(yè)精神好不好?我開始在MSDN里面找有關(guān)這個方面的內(nèi)容了,別急,我找找看:Platform SDK-Graphics and Multimedia Services-Windows GDI-Painting and Drawing-Using the WM_PAINT Message-終于找到了。下面是一大套理論:讓我們把Windows的屏幕想像成一個桌面,把一個窗口想像成一張紙。當(dāng)我們把一張紙放到桌面上時,它會蓋住其他的紙,這樣被蓋住的其他紙上的內(nèi)容都看不到了。但我們只要把這張紙移開,被蓋住的其他紙上的內(nèi)容就會顯示

55、出來了-這是一個很簡單的道理,誰都明白。對于我們的屏幕來說,當(dāng)一個窗口被另一窗口蓋住時,被蓋住的窗口的某些部分就看不到了,我們要想看到被蓋住的窗口的全部面貌,就要把另一個窗口移開,但是當(dāng)我們移開后,事情卻起了變化-很可能這個被蓋住的窗口上的信息被擦除了或是丟失了。當(dāng)窗口中的數(shù)據(jù)丟失或過期時,窗口就變成非法的了-或者稱為無效。于是我們的任務(wù)就來了,我們必須考慮怎樣在窗口的信息丟失時重畫窗口-使窗口恢復(fù)成以前的那個樣子。這也就是我們在這第二只小板凳中調(diào)用UpdateWindow的原因。你忘記了嗎?剛才我們在(三)顯示和更新窗口中有下面的一些文字:WinMain()調(diào)用完ShowWindow后,還需

56、要調(diào)用函數(shù)UpdateWindow,最終把窗口顯示了出來。調(diào)用函數(shù)UpdateWindow將產(chǎn)生一個WM_PAINT消息,這個消息將使窗口重畫,即使窗口得到更新.-這是程序第一次調(diào)用了這條消息。為重新顯示非法區(qū)域,Windows就發(fā)送WM_PAINT消息實現(xiàn)。要求Windows發(fā)送WM_PAINT的情況有改變窗口大小,對話框關(guān)閉,使用了UpdateWindows和ScrollWindow函數(shù)等。這里注意,Windows并非是消息WM_PAINT的唯一來源,使用InvalidateRect或InvalidateRgn函數(shù)也可以產(chǎn)生繪圖窗口的WM_PAINT消息.通常情況下用BeginPaint(

57、)來響應(yīng)WM_PAINT消息。如果要在沒有WM_PAINT的情況下重畫窗口,必須使用GetDC函數(shù)得到顯示緩沖區(qū)的句柄。這里面不再擴(kuò)展。詳細(xì)見MDSN。這個BeginPaint函數(shù)會執(zhí)行準(zhǔn)備繪畫所需的所有步驟,包括返回你用于輸入的句柄。結(jié)束則是以EndPaint();在調(diào)用完BeginPaint之后,WndProc接著調(diào)用GetClientRect:GetClientRect(hwnd,&rect);第一個參數(shù)是程序窗口的句柄。第二個參數(shù)是一個指針,指向一個RECT類型的結(jié)構(gòu)。查MSDN,可看到這個結(jié)構(gòu)有四個成員。WndProc做了一件事,他把這個RECT結(jié)構(gòu)的指針傳送給了DrawText的第

58、四個參數(shù)。函數(shù)DrawText的目的就是在窗口上顯示一行字-你好,歡迎你來到VC之路!,有關(guān)這個函數(shù)的具體用法這里也沒必要說了吧。關(guān)于WM_DESTROY這個消息要比WM_PAINT消息容易處理得多:只要用戶關(guān)閉窗口,就會發(fā)送WM_DESTROY消息(在窗口從屏幕上移去后)。程序通過調(diào)用PostQuitMessage以標(biāo)準(zhǔn)方式響應(yīng)WM_DESTROY消息:PostQuitMessage (0) ;這個函數(shù)在程序的消息隊列中插入一個WM_QUIT消息。在(四)創(chuàng)建消息循環(huán)中我們曾有這么一段話:消息循環(huán)以GetMessage調(diào)用開始,它從消息隊列中取出一個消息:.在接收到除WM_QUIT之外的任何

59、一個消息后,GetMessage()都返回TRUE。如果GetMessage收到一個WM_QUIT消息,則返回FALSE,如收到其他消息,則返回TRUE。因此,在接收到WM_QUIT之前,帶有GetMessage()的消息循環(huán)可以一直循環(huán)下去。只有當(dāng)收到的消息是WM_QUIT時,GetMessage才返回FALSE,結(jié)束消息循環(huán),從而終止應(yīng)用程序。至此,第二支小板凳終于支解完畢!- 不是我寫的.第一講:預(yù)備知識與概念介紹 注:我寫這個專題目的是為VC初學(xué)者提供一個思路,我本人很菜,但我認(rèn)為對于VC初學(xué)者來講,可能有點幫助,當(dāng)然,對于WinSDK編程,我也是剛剛接觸。如果你對WinSDK編程較熟

60、,請與我聯(lián)系,咱們共同來把這個專題做好,如果你發(fā)現(xiàn)了什么錯誤,也麻煩你給我留言指正。我寫的內(nèi)容也基本上是我自己的一些理解,錯誤是肯定有的,如果你發(fā)現(xiàn)我的理解偏差很大的話,麻煩你提醒一下。-小朱!什么是WinSDK:大致說來windows編程有兩種方法: 1.windwos c方式(SDK), 2.c+方式:即對SDK函數(shù)進(jìn)行包裝,如VC的MFC,BCB的OWL等,如果要深入 下去,還是要熟悉SDK。兩種方法有哪些區(qū)別呢:SDK編程就是直接調(diào)用windows的API進(jìn)行編程,但是有上千個API組成(win95的API有兩千多個),這種數(shù)目太大了,對于編程顯然不利。而MFC把這些API封閉起來,共

溫馨提示

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

評論

0/150

提交評論