用C語言寫聊天工具,類似于QQ_第1頁
用C語言寫聊天工具,類似于QQ_第2頁
用C語言寫聊天工具,類似于QQ_第3頁
用C語言寫聊天工具,類似于QQ_第4頁
用C語言寫聊天工具,類似于QQ_第5頁
已閱讀5頁,還剩69頁未讀, 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

1、. . . . C 語言究竟能干什么序言鑒于現(xiàn)在已經(jīng)大三了,很多同學很迷茫,自己學的東西到底能做什么,將來自己到底能干什么?我不想看著同學迷茫的面孔,特別是幾個好兄弟,有幾個想學習編程,但又苦苦找不到門路的兄弟,所以想寫點東西,希望對大家又點略微的幫助,以盡兄弟我的微薄之力。很多同學學了C語言之后,可能難免會有所感嘆:這就是C語言!總是感覺C語言竟然能寫出Windows、Linux?為了解除同學們的疑惑,也愿為同學們指點編程之道吧。我寫的這些東西采用C語言,計劃通過編程實例來講解C編程的一些知識,讓大家對C能又更深一層的理解和認識。當然,大家不要指望看了這些之后會寫出一個操作系統(tǒng)來,但是我想,

2、如果你認真看了的話,寫一個類似與 的聊天程序應(yīng)該不難。本來書是假期里照顧媽媽時寫的,原想是1、不讓自己的水平停滯不前,溫故知新(兩個月的假期是很長的)2. 幫助一些同學,解決編程上的困惑3.希望媽媽快點康復(fù)4.讓母親和家里人知道自己一直都很努力,我是好樣的但現(xiàn)在母親已經(jīng)能夠不在了,所以第三點,就改為原母親在天之靈得到慰藉,早日放下煩惱,不用惦記我們。C語言的基本語法我是不打算再提了,很多C語言編程的書,就是將一些基本的數(shù)據(jù)類型、數(shù)據(jù)結(jié)構(gòu)、語法,然后就是一些數(shù)值計算的實例,大多數(shù)都是雷同的,難免有抄襲之嫌,而且頁沒有多少實用價值。本書以實用實例作為編程指導(dǎo),指引大家編寫真正實用的程序。了解到大家

3、對黑客程序、病毒、窗口類程序比較感興趣,因此我就拿這些實例進行講解?;诖蠹一径加肳indows XP SP3,我也就在這個系統(tǒng)上把程序調(diào)試成功后再給大家講解。編程環(huán)境,我還是喜歡VisualC+ 6.0本書計劃從四個大的方面來講,這四個方面是:窗口類、文件操作類、網(wǎng)絡(luò)類、數(shù)據(jù)庫類。都是時下流行的編程必備技術(shù),也是軟件開發(fā)者,必須掌握的技術(shù)。中間以實例講解,逐步學習,相信大家看完后會有很大的提高的。第一章 窗口類程序的編寫這一章就先來講解下窗口類程序的編寫。因為現(xiàn)在程序沒有界面,就像人沒有臉面一樣,而且好的界面更能吸引人。從基本的界面開始,相信能給大家指明出一條路的,使大家很容易地掌握窗口序

4、的編寫。其實界面設(shè)計利用VC 6.0 的MFC,很容易地制作出來。這里從底層開始寫代碼來寫界面程序,使大家知道一些底層的東西,為以后學習打下好的基礎(chǔ),相信您學了這些,再用VC 的MFC會得心應(yīng)手的。1.1用 C 寫的第一個一個窗口程序 作為編程的開始,我們還是以一個Hello World來開始我們的學習之旅。代碼如下: #include <stdio.h> void main() printf("Hello World!"); 這是一個再簡單不過的C程序了,只要有點C語言的知識就能夠懂的,不過這里估計還有些人,到現(xiàn)在還不知道#include <stdio.

5、h>中的頭文件stdio.h到底是什么東西,我就來說下了,stdio.h是一個文本文件,存在于磁盤上的,已VC為例它的位置如下圖:也許你聽說過printf()函數(shù)是在stdio.h中預(yù)定義的,但是你見過其定義的形式?jīng)]有,沒有且看下圖其定義形式,就如圖中所示,也許你并不懂前面那些東西是什么,不用擔心,以后我會慢慢解釋給大家的。函數(shù)是先定義才能使用的,所以stdio.h中定義printf函數(shù),我我們在引用了stdio.h頭文件后就可以在程序中調(diào)用printf函數(shù)了。上面是在命令行中顯示一個“Hello World!”,沒什么意思,下面我寫一個窗口程序,顯示個Hello World!#incl

6、ude <windows.h>void main()MessageBox(NULL," Hello World!","我的第一個窗口程序",MB_OK);編譯運行后如下圖:彈出的是一個對話框,上面有Hello World,還有一個標題和一個“確定”按鈕。當然你會說這對話框也算個窗口嗎?這里肯定的告訴你:是的,對話框是窗口程序的一個子集。你可能還會這樣問,這樣一個簡單的窗口有啥用呢,其實這樣的窗口非常有用,我們在操作計算機的時候,會出現(xiàn)一些警告或提示的對話框,都是基本是這種方法寫出來的。就算是這個很簡單,學習本來不就是有易向難,有淺顯深奧去的過

7、程嗎。整個效果幾乎就是靠一個函數(shù)MessageBox的功勞。這里也先不介紹這個函數(shù)了,說些其他的。其實用C編寫一些惡程序,就是把編程環(huán)境中所提供的一些函數(shù)熟悉了基本就可以了。用VC來寫成序,其中的頭文件有很多,定義了很多Windows API 函數(shù) 、數(shù)據(jù)結(jié)構(gòu)、宏,可以讓我們大家運用,通過它們,我們可以快速開發(fā)出使用的程序。這些Windows API在微軟的MSDN上查,上面有很多說明,部分還有代碼示例。不會是可以輸入函數(shù)名,查找相關(guān)信息,建議大家用英文版的Library,因為其容比中文版的全面,英語不好的同學呢,就先看中文了中文MSDN:msdn.microsoft./library/zh-

8、cn/英文MSDN:msen.micorsoft./library/en-us/到這里,我們就完成第一個有界面程序的編寫,你感覺寫有界面的程序難嗎?顯然不難。下面看一個向鋒和波波感興趣的程序:九九乘法采用命令行形式#include “stdio.h”int i=0,j=0;for(i=1;i<10;i+)for(j=1;j<i+1;j+)printf(“%d*%d=%d t”,j,i,j*i);printf(“n”);和那個javascript效果都是一樣的,所以語言只要學好一樣,其他的就很容易旁通的,學習就撿一種學好,不要貪多。好的,這一節(jié)就這樣吧,大家先各自了解下微軟的MSDN

9、,對以后的學習會有很大的幫助的。1.2 第一個真正的窗口程序上一節(jié)中,我們用MessageBox函數(shù)輕松地實現(xiàn)了一個對話框窗口,可能你會說,那僅僅是個沒有用的對話框而已,是的,只是對話框而已。我之所以以一個對話框為例呢,是因為我只是想讓你知道寫一個有界面的程序并不是件難辦的事。明白了這一點后,我們繼續(xù)。今天來編寫一個真正的窗口程序。下面就該羅嗦一段了,由于大家以前并沒有寫過什么窗口程序,寫的都是命令行下的,我們知道在命令行下的程序都有一個主函數(shù)main,這個函數(shù)也就是程序的入口函數(shù)。我們現(xiàn)在用VC 6.0來寫,而且要寫窗口類程序,VC 6.0給我們提供了一個專門用作窗口類程序的入口函數(shù)WinM

10、ain()這個函數(shù)原型是這樣的int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTRlpCmdLine, int nCmdShow);大家是不是感覺這個函數(shù)挺復(fù)雜的,有這么幾個參數(shù),而像main好像就沒有參數(shù)。其實main是有參數(shù),這個向鋒和小四是知道了的。但是main函數(shù)的參數(shù)是可以省略的,而WinMain是不可以省的。這里也要對VC 6.0的編譯模式改下看下圖依次 是“工程”“設(shè)置”“連接”,在“工程選項”里把console改為windows就可以了。如果認真學了匯編,或是手寫命令編譯連接過C程序,就會知

11、道這是干什么的。Console是控制臺的意思,以前我們用mian函數(shù)寫的程序都是以控制臺模式連接的,所以很少會有界面的?,F(xiàn)在我們要寫有界面的程序,所以要選Windows(窗口)模式了。我們寫入以下代碼,并按照上面說的方法去做,看看結(jié)果#include "windows.h"int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPreInstance, LPSTR lpCmdLine, int nShowCmd)MessageBox(NULL,"WinMain創(chuàng)建的窗口程序","WinMain&qu

12、ot;,MB_OK);return 0;結(jié)果如下圖:與第一節(jié)中的這段代碼代碼比較下#include “windows.h”void main()MessageBox(NULL," Hello World!","我的第一個窗口程序",MB_OK);兩者比較下,后者多了個cmd窗口??梢娪胢ain寫的并沒有完全脫離命令行呀。所以以后我們寫窗口程序就用winmain了。好了,轉(zhuǎn)過來,我們來看看WinMain()函數(shù),其中有4個參數(shù)先看下解釋(看不明白得先看完):hInstance:應(yīng)用程序當前事例的句柄。hPrelnstance:應(yīng)用程序的先事例的句柄。對于同

13、一個程序打開兩次,出現(xiàn)兩個窗口第一次打開的窗口就是先前實例的窗口。對于一個32的位程序,該參數(shù)總為NULL。lpCmdLine:指向應(yīng)用程序命令行的空字符串的指針,不包括函數(shù)名。獲得整個命令行,參看GetCommandLine。nCmdShow:指明窗口如何顯示(是隱藏還是顯示,有沒有最大化按鈕之類的)。取值可以參考MSDN這里我相信有一個詞大家好應(yīng)該比較陌生,句柄(HANDLE)是吧。下面我就來簡單的說下句柄其實就是Windows系統(tǒng)中一個東西的唯一標識。就是系統(tǒng)中有很多運行的程序或者資源之類的,為了更好的管理使用,Windows系統(tǒng)給它們每人一個ID一樣。懂得網(wǎng)頁制作的人應(yīng)該知道網(wǎng)頁中各個

14、元素的ID吧,網(wǎng)頁的ID如果重復(fù)話可能出現(xiàn)錯誤。那么系統(tǒng)的句柄會不會有一樣的,那是肯定不會有的了,就和我們的學號一樣,系統(tǒng)自動分配每一個模塊的句柄,是不會一樣的了。對于句柄大家可以先這樣理解著,不用一下子搞懂得。以后學著學著就明白了。估計大家對那幾個參數(shù)的類型改犯迷糊了吧。其實那幾個類型,并不是什么新類型,都是Windows開發(fā)人員為了自己和他人編程方便,同過基本的C語言語法定義一種新的結(jié)構(gòu)體,或者是共同體,再者就是枚舉類型。我知道結(jié)構(gòu)體、共同體和枚舉類型,很多老師是沒有講到的,因為在書的后邊,很多教C的,又是很垃圾的老師,所以不會講那么快的。其實結(jié)構(gòu)體這些數(shù)據(jù)類型,就是通過我們常用的字符、整

15、型、浮點等數(shù)據(jù)類型構(gòu)造一個比較復(fù)雜的類型而已,舉個例子,就是我們知道C沒有一個數(shù)據(jù)類型可以描述一個人吧,那么我構(gòu)造一個是不是很方便我們編程呢。我們可以這樣構(gòu)造一個struct Peopleint age;/年齡char sex2;/性別int height;/身高我們這樣定義以后就可以在我們以后的程序中利用這個數(shù)據(jù)類型了,People zhangsan;把zhangsan的身高172放到zhangsan.height中。這樣可以方便完成很多工作。所以結(jié)構(gòu)體是很簡單的,還有其他的復(fù)雜數(shù)據(jù)類型也是很簡單的,都是有常用的簡單的類型來結(jié)合到一起構(gòu)造一個復(fù)雜的而已。這和JAVA定義類是很相似的,java

16、定義個人類,不是可以這樣的public class Peoplepublic int age;public string sex;public height; 看起來都差不多,而且用法也很相像。唯一的差別其實就是類可以有方法,而結(jié)構(gòu)體是沒有的(經(jīng)過特殊處理也是可以的,這里不用考慮)。上面是為了讓大家了解下復(fù)雜數(shù)據(jù)類型的定義,羅嗦了一大堆。下面來看下WinMain中第一個參數(shù)的類型HINSTANCE這個只是個結(jié)構(gòu)體而已,實際上和HANDLE這個類型差不多,但是有一點差別,而HANDLE是這樣typedef PVOID HANDLE;定義的,PVOID是什么呢,我們來看下typedef void

17、*PVOID;說明PVOID是一個指針,初始指向空(void)。因此可以知道句柄也是個指針而已??粗@么復(fù)雜原來也只是指針。這些都可以在微軟的msdn上查得到的,而且很詳細的那個第二個LPSTR 根據(jù)字面上的意思就知道是字符串類型了。查一查果然是。大家一定要利用好msdn,很有用的。本節(jié)就到此結(jié)束了,主要是說明了一個WinMain函數(shù)和結(jié)構(gòu)體的事情,東西也不算太多,大家應(yīng)該能接受得了吧。下節(jié)就來點復(fù)雜點深點的東西,希望大家做好心理準備。1.3 窗口程序的編寫在來啰嗦之前,希望大家能夠做好準備,這一節(jié)知識有點多,容有點長。但愿大家能夠一口氣讀完,如果一口氣讀不完,那就換口氣接著讀。上節(jié)中我們用M

18、essageBox()就實現(xiàn)了一個真正的窗口。MessageBox()中的原型如下:Int MessageBox(HWND hWnd,LPCTSTR lpText,LPCTSTR lpCaption,UINTuType);參數(shù)解釋hWnd 所屬對話框所屬窗口的句柄,如果是NULL,則此對話框不屬于任何一個窗口。lpText 對話框窗口的顯示容。lpCaption 對話框窗口的標題。uType 對話框的樣式和動作(像是確定按鈕,還是取消按鈕就是設(shè)置這里的)關(guān)于這個函數(shù)的細節(jié)可以看這里msdn.microsoft./en-us/library/ms645505(VS.85).aspx到此為止,你也

19、算是會了窗口程序的編寫,但只是一個開始,不過這已經(jīng)很好,可能會讓你感覺到了C的魅力,也可能會稍微解點C語言能干什么的疑惑。在開始寫代碼之前,我有必要把細節(jié)和原理先說明下。Windows下一個窗口創(chuàng)建的過程有以下幾個步驟:1. 程序創(chuàng)建一個窗口,首先要向Windows系統(tǒng)注冊一個窗口類wndclassex,其實就是定義一個變量,變量的類型是WNDCLASSEX(結(jié)構(gòu)體)。該結(jié)構(gòu)體的定義與介紹看這里(msdn.microsoft./en-us/library/ms633577(VS.85).aspx),typedef struct UINT cbSize; UINT style

20、; WNDPROC lpfnWndProc; int cbClsExtra; int cbWndExtra; HINSTANCE hInstance; HICON hIcon; HCURSOR hCursor; HBRUSH hbrBackground; LPCTSTR lpszMenuName; LPCTSTR lpszClassName; HICON hIconSm; WNDCLASSEX, *PWNDCLASSEX;成員介紹cbSize 值為sizeof(WNDCLASSEX),在調(diào)用Ge

21、tClassInfoEx前必須要先設(shè)置它值。style 窗口類的樣式,它的值可以是窗口樣式值的任意組合。可以有以下的值lpfnWndProc 指向窗口處理函數(shù)(回調(diào)函數(shù))。處理窗口事件,像單擊鼠標會怎樣,右擊鼠標會怎樣,都是由此函數(shù)控制的。cbClsExtra 為窗口類的額外信息做記錄,系統(tǒng)初始化為0。cbWndExtra 記錄窗口實例的額外信息,系統(tǒng)初始為0.如果程序使用WNDCLASSEX注冊一個從資源文件里創(chuàng)建的對話框,則此參數(shù)必須設(shè)置為DLGWINDOWEXTRAhIcon 窗口類的圖標,為資源句柄,如果設(shè)置為NULL,系統(tǒng)將為窗口提供一個默認的圖標。hCursor 窗口類的鼠標樣式,

22、為鼠標樣式資源的句柄,如果設(shè)置為NULL,系統(tǒng)提供一個默認的鼠標樣式。hbrBackground 窗口類的背景刷,為背景刷句柄,也可以為系統(tǒng)顏色值,如果顏色值已給出,則必須轉(zhuǎn)化為以下的HBRUSH的值· COLOR_ACTIVEBORDER · COLOR_ACTIVECAPTION · COLOR_APPWORKSPACE · COLOR_BACKGROUND · COLOR_BTNFACE · COLOR_BTNSHADOW · COLOR_BTNTEXT · COLOR_CAPTIONTEXT ·

23、COLOR_GRAYTEXT · COLOR_HIGHLIGHT · COLOR_HIGHLIGHTTEXT · COLOR_INACTIVEBORDER · COLOR_INACTIVECAPTION · COLOR_MENU · COLOR_MENUTEXT · COLOR_SCROLLBAR · COLOR_WINDOW · COLOR_WINDOWFRAME · COLOR_WINDOWTEXT lpszMenuName 指向一個以NULL結(jié)尾的字符床,同目錄資源的名字一樣。如果使用整型

24、id表示菜單,可以用MAKEINTRESOURCE定義一個宏。如果它的值為NULL,那么該類創(chuàng)建的窗口將都沒有默認的菜單。lpszClassName 窗口類的名字,字符串類型。hIconSm 小圖標的句柄,在任務(wù)欄顯示的圖標,可以和上面的那個一樣。定義一個WNDCLASSEX類型變量后,在給變量成員初始化后,我們就可以用RegisterWindowEx(&wndclassex)來注冊這個窗口類了。這個注冊過程,就和我們平常創(chuàng)建一個項目一樣,都要先注冊才能創(chuàng)建 。2. 創(chuàng)建窗口這一步很簡單,就是利用CreateWindowEx()函數(shù)來創(chuàng)建就是了。CreateWindowEx函數(shù)的原型如

25、下:HWND CreateWindowEx(          DWORD dwExStyle,    LPCTSTR lpClassName,    LPCTSTR lpWindowName,    DWORD dwStyle,    int x,  

26、60; int y,    int nWidth,    int nHeight,    HWND hWndParent,    HMENU hMenu,    HINSTANCE hInstance,    LPVOID lpParam);參數(shù)說明dwExStyle:指定窗口的

27、擴展風格。該參數(shù)可以是下列值:WS_EX_ACCEPTFILES:指定以該風格創(chuàng)建的窗口接受一個拖拽文件。WS_EX_APPWINDOW:當窗口可見時,將一個頂層窗口放置到任務(wù)條上。WS_EX_CLIENTEDGE:指定窗口有一個帶陰影的邊界。WS_EX_CONTEXTHELP:在窗口的標題條包含一個問號標志。WS_EX_CONTROLPARENT:允許用戶使用Tab鍵在窗口的子窗口間搜索。WS_EX_DLGMODALFRAME:創(chuàng)建一個帶雙邊的窗口;該窗口可以在dwStyle中指定WS_CAPTION風格來創(chuàng)建一個標題欄。WS_EX_LEFT:窗口具有左對齊屬性,這是缺省設(shè)置的。WS_EX_

28、LEFTSCROLLBAR:如果外殼語言是如Hebrew,Arabic,或其他支持reading order alignment的語言,則標題條(如果存在)則在客戶區(qū)的左部分。若是其他語言,在該風格被忽略并且不作為錯誤處理。WS_EX_LTRREADING:窗口文本以LEFT到RIGHT(自左向右)屬性的順序顯示。這是缺省設(shè)置的。WS_EX_MDICHILD:創(chuàng)建一個MD子窗口。WS_EX_NOPATARENTNOTIFY:指明以這個風格創(chuàng)建的窗口在被創(chuàng)建和銷毀時不向父窗口發(fā)送WM_PARENTNOTFY消息。WS_EX_OVERLAPPED:WS_EX_CLIENTEDGEWS_EX_WIN

29、DOWEDGE的組合。WS_EX_PALETTEWINDOW:WS_EX_WINDOWEDGE, WS_EX_TOOLWINDOW和WS_WX_TOPMOST風格的組合WS_EX_RIGHT:窗口具有普通的右對齊屬性,這依賴于窗口類。WS_EX_RIGHTSCROLLBAR:垂直滾動條在窗口的右邊界。這是缺省設(shè)置的。WS_EX_RTLREADING:如果外殼語言是如Hebrew,Arabic,或其他支持讀順序?qū)R(reading order alignment)的語言,則窗口文本是一自左向右)RIGHT到LEFT順序的讀出順序。WS_EX_STATICEDGE:為不接受用戶輸入的項創(chuàng)建一個3一

30、維邊界風格WS_EX_TOOLWIDOW:創(chuàng)建工具窗口,即窗口是一個游動的工具條。WS_EX_TOPMOST:指明以該風格創(chuàng)建的窗口應(yīng)放置在所有非最高層窗口的上面并且停留在其L,即使窗口未被激活。使用函數(shù)SetWindowPos來設(shè)置和移去這個風格。WS_EX_TRANSPARENT:指定以這個風格創(chuàng)建的窗口在窗口下的同屬窗口已重畫時,該窗口才可以重畫。由于其下的同屬富日已被重畫,該窗口是透明的。IpClassName: 窗口類的名字。lpWindowName:指向一個指定窗口名的空結(jié)束的字符串指針。其實就是窗口的名字。dwStyle:指定創(chuàng)建窗口的風格。該參數(shù)可以是下列窗口風格的組合再加上說

31、明部分的控制風格。x:窗口的橫坐標。y:窗口的豎坐標。nWidth:窗口的寬度。nHeight:窗口的高度。hMenu:菜單句柄,或依據(jù)窗口風格指明一個子窗口標識。hlnstance:與窗口相關(guān)聯(lián)的模塊事例的句柄。lpParam:指向一個值的指針,該值傳遞給窗口 WM_CREATE消息返回值:如果函數(shù)成功,返回值為新窗口的句柄:如果函數(shù)失敗,返回值為NULL。若想獲得更多錯誤信息,請調(diào)用GetLastError函數(shù)。3. 顯示窗口顯示窗口就是更簡單的事情了。連個函數(shù)輕松搞定,第一個函數(shù)就是ShowWindow(),原型如下:BOOL ShowWindow(  &#

32、160;       HWND hWnd,/當前的窗口句柄    int nCmdShow /可見狀態(tài));因為CreateWindowEx函數(shù)創(chuàng)建的窗口是在存中的,并沒有顯示到顯示器上,用ShowWindow()函數(shù),設(shè)定窗口的可見狀態(tài),并把數(shù)據(jù)從存中移動到顯卡上,以便顯示。第二個函數(shù)就是UpdateWindow();函數(shù)原型:BOOL UpdateWindow(HWND hWnd);描述:這個 UpdateWindow 函數(shù)通過發(fā)送重繪消息 WM_PAINT 給目

33、標窗體來更新目標窗體客戶區(qū)的無效區(qū)域。如果那個窗體的無效區(qū)域沒有,就不發(fā)送重繪消息 WM_PAINT 了 。注意了,這個 API 函數(shù)是直接發(fā)送消息 WM_PAINT 給目標窗體的,沒有進入過消息隊列。函數(shù)參數(shù):hWnd 一個要更新的窗體的句柄函數(shù)返回值:如果函數(shù)調(diào)用成功,返回值為非零值。如果函數(shù)調(diào)用不成功,返回值為零。經(jīng)過這三步后,一個窗口就實現(xiàn)了,就創(chuàng)建了出來,難不,也真夠難的,Windows想的正周到,把創(chuàng)建過程的每一個細節(jié)都給想到了,每毫秒可能發(fā)生的事情都想到了,難怪Windows那么貴,還不開源。也算是人間的產(chǎn)品嘛,費的心血可真不少呀。說難其實也不難,創(chuàng)建一個窗口程序也就三步:一注冊

34、,二創(chuàng)建,三顯示。很容易就ok了。這T他媽容易了吧。原來就是這些的,我想我已經(jīng)說的挺明白的了,如果你有什么疑惑,可以給我發(fā)(cangsanbujin126.)下面我們就按照上面所說的來編程實現(xiàn)一個窗口:#include <windows.h>/回調(diào)函數(shù)LRESULT WINAPI WinProc(HWND hWnd,UINT Msg,WPARAM wParam,LPARAM lParam) switch(Msg)/處理消息過程,什么是消息,下節(jié)再講 case WM_DESTROY:/響應(yīng)鼠標單擊關(guān)閉按鈕事件 PostQuitMessage(0);/退出消息隊列,至于什么是消息隊列,

35、下節(jié)說 return 0;/退出函數(shù) return DefWindowProc(hWnd,Msg,wParam,lParam);/主函數(shù)int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nShowCmd) char *cName = "myWindow" WNDCLASSEX wc; HWND hWnd; MSG Msg; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.cbSize = sizeof(WNDCLASSEX);

36、 wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);/通過函數(shù)來設(shè)置一個白色的背景,這里大家設(shè)置為NULL看看,會很有趣的 wc.hCursor = NULL;/不設(shè)置 wc.hIcon = NULL;/不設(shè)置 wc.hIconSm = NULL;/不設(shè)置 wc.hInstance = hInstance;/當前程序的句柄,hInstance是有系統(tǒng)給傳遞的 wc.lpfnWndProc = WinProc;/窗口處理過程的回調(diào)函數(shù)。 wc.lpszClassName =(LPSTR)cName;/窗口類的名字。 wc.lpszMen

37、uName = NULL;/目錄名,不設(shè)置 wc.style = CS_HREDRAW | CS_VREDRAW; RegisterClassEx(&wc);/在系統(tǒng)中注冊 hWnd = CreateWindowEx(WS_EX_CLIENTEDGE,cName,"我的窗口我喜歡",WS_OVERLAPPEDWINDOW, 200,100,600,400,NULL,NULL,hInstance,NULL);/創(chuàng)建窗口,窗口標題為"我的窗口我喜歡" if(hWnd = NULL) /容錯處理 MessageBox(NULL,"There&

38、#39;s an Error","Error Title",MB_ICONEXCLAMATION|MB_OK); return 0; ShowWindow(hWnd,nShowCmd);/顯示窗口 UpdateWindow(hWnd); /下面是對消息的循環(huán)處理,大家先不必管這些,下節(jié)課我會細說的while(GetMessage(&Msg,NULL,0,0) TranslateMessage(&Msg);/翻譯消息 DispatchMessage(&Msg);/分派消息 return Msg.message;編譯運行后,可以看到一個白色背景

39、的窗口出來了。如下圖哎,這一節(jié),篇幅可是真有點長的,看完估計得換幾口氣吧,但是只要你看到了這些,你的水平就立馬上了一個檔次。想你看完后也許會頭昏腦脹的,沒有再看下去的信心的,但是估計當你把我的代碼復(fù)制到VC中編譯運行后,看到一個可愛的窗口時,肯定又會重新點燃你心中學習的熱情吧,因為你已經(jīng)看到了成功,看到了成就,一種成就感猶然自心中生,自信也提起來了,這比什么都好,人嘛就得對自己充滿信心的。所以大家要發(fā)揚持之以恒的精神,堅持和我一起把這段苦悶的入門過程給走完,那么編程就不再是痛苦,而是一種樂趣。其實寫這些程序很多東西都不用去記的想WNDCLASSEX結(jié)構(gòu)的成員與成員作用,這些都不用去死記,只要知

40、道有這么個東西,到時時再查就可以了,編程用到的函數(shù)、結(jié)構(gòu)體那么多,誰想記呀。這一節(jié)已經(jīng)留下了些問題,在下節(jié)介紹的,大家如果有余力的話,可以先查下資料的。1.4 鼠標指針特效大家在都玩過網(wǎng)絡(luò)游戲吧,里面的界面都是很吸引人的,好的界面的確能給人以美的感受。而里面的鼠標并不是我們平常見到的箭頭了,而是獨具匠心的。網(wǎng)游我就只玩過魔域,所以就以魔域為例,魔域中的鼠標是這樣的。今天我們就來實現(xiàn)讓鼠標到程序窗口上就變?yōu)槲覀兿胍膱D案。在寫代碼之前,我們還是先來看下先驅(qū)知識,這里要說的就是上節(jié)說資源了,當時大家看了可能并不知道什么是資源,這里就詳細說一下。大家知道Windows程序都有圖標,鼠標有光標,窗口上

41、有圖片、按鈕、文字等等,這些都是程序的部分,這樣就是程序的資源。程序沒有進入存運行的時候,我們就叫它可執(zhí)行文件吧,在磁盤保存的時候,并不只是保存了程序運行的代碼部分(即cpu指令部分),還有一些圖片、字符、按鈕、圖標并不是在代碼段的??蓤?zhí)行文件的大致機構(gòu)如下圖一個可執(zhí)行文件是很復(fù)雜的,這里就簡單的畫這么一個難看的圖,知道資源所在的大概位置,能理解程序的執(zhí)行部分和知道程序的圖標是從哪來的就可以了。今天我們只是修改鼠標的指針,所以用到的資源,只有鼠標的光標資源而已。資源的源文件是以rc為擴展名的腳本文件(仍然是C語言格式的,很簡單),有資源編譯器Rc.exe編譯成以res為擴展名的二進制資源文件,

42、最后用連接器,把res文件和obj文件連接到一起就成了我們的程序exe文件了,現(xiàn)在知道了程序編譯后要連接了吧。光標的圖片格式有兩中cur和ani的。這個文件我在魔域的圖片庫里面找到了就復(fù)制到,當前項目目錄下。下面來定義下資源文件myOwnCursor.rc/myOwnCursor.rc written by xhk 2009.3.1#include<resource.h> /資源文件要用到的圖文件#defineCUR0x1000/定義資源的ID,為整型idCURCURSOR "myOwnCursor.ani"/用到的光標圖案寫完后,在命令提示符下進入目錄,然后用

43、rc.exe編譯,輸入rc myOwnCursor.rc命令,回車我們查看下項目目錄下多了個myOwnCursor.RES的文件,就是編譯生成的二進制資源件。接下來就該編寫代碼了,來應(yīng)用這個資源文件,建立myOwnCursor.c文件,其實代碼和上節(jié)所寫代碼很相似的,只是稍微加以修改而已。#include <windows.h>#define CUR 0x1000/預(yù)定義光標的id/回調(diào)函數(shù)LRESULT WINAPI WinProc(HWND hWnd,UINT Msg,WPARAM wParam,LPARAM lParam) switch(Msg)/處理消息過程,什么是消息,下

44、節(jié)再講 case WM_DESTROY:/響應(yīng)鼠標單擊關(guān)閉按鈕事件 PostQuitMessage(0);/退出消息隊列,至于什么是消息隊列,下節(jié)說 return 0;/退出函數(shù) return DefWindowProc(hWnd,Msg,wParam,lParam);/主函數(shù)int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nShowCmd) char *cName = "myWindow" WNDCLASSEX wc; HWND hWnd; MSG Msg

45、; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.cbSize = sizeof(WNDCLASSEX); wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);/通過函數(shù)來設(shè)置一個白色的背景,這里大家設(shè)置為NULL看看,會很有趣的wc.hCursor = LoadCursor(hInstance,MAKEINTRESOURCE(CUR);/這里改了,來載入光標資源 wc.hIcon = NULL;/不設(shè)置 wc.hIconSm = NULL;/不設(shè)置 wc.hInstance = hInstance;

46、/當前程序的句柄,hInstance是有系統(tǒng)給傳遞的 wc.lpfnWndProc = WinProc;/窗口處理過程的回調(diào)函數(shù)。 wc.lpszClassName =(LPSTR)cName;/窗口類的名字。 wc.lpszMenuName = NULL;/目錄名,不設(shè)置 wc.style = CS_HREDRAW | CS_VREDRAW; RegisterClassEx(&wc);/在系統(tǒng)中注冊 hWnd = CreateWindowEx(WS_EX_CLIENTEDGE,cName,"我的窗口我喜歡",WS_OVERLAPPEDWINDOW, 200,100

47、,600,400,NULL,NULL,hInstance,NULL);/創(chuàng)建窗口,窗口標題為"我的窗口我喜歡" if(hWnd = NULL) /容錯處理 MessageBox(NULL,"There's an Error","Error Title",MB_ICONEXCLAMATION|MB_OK); return 0; ShowWindow(hWnd,nShowCmd);/顯示窗口 UpdateWindow(hWnd); /下面是對消息的循環(huán)處理,大家先不必管這些,下節(jié)課我會細說的while(GetMessage(&am

48、p;Msg,NULL,0,0) TranslateMessage(&Msg);/翻譯消息 DispatchMessage(&Msg);/分派消息 return Msg.message;用vc編譯生成myOwnCursor.obj,把myOwnCursor.obj和myOwnCursor.res放到同一個文件夾下,然后在命令行下進入它們所在的目錄 ,輸入命令:linke kernel32.lib user32.lib gdi32.lib /subsystem:windows myOwnCursor.obj myOwnCursor.res把兩個文件連接成myOwnCursor.ex

49、e.運行后界面如下;看到了吧,當鼠標移入窗口的時候,光標就變成了那個手型圖案了, 這和魔域的是一樣的。到現(xiàn)在想想一個特效又咋地,不還是一句一句代碼寫出來的,而特效和普通程序往往只有數(shù)據(jù)代碼不同而已。網(wǎng)絡(luò)游戲的界面很好看,也只不過是資源文件用的比較多而已,而且計算量很大,所以網(wǎng)游總是很占存的,因為圖片、聲音文件都很大,而且變換比較多、快,就比較占用資源了。其實再好的程序,只要有了思路,就能寫出來,而且寫出來也難的,是不是,今天大家應(yīng)該會有點收獲了,都會設(shè)計個性的鼠標光標了,比起以前學習C的東西,應(yīng)該有一種層次感了吧。這些東西都比較接近系統(tǒng)了,所以學了之后,你對Windows系統(tǒng)也會有很深的了解的

50、。如果各位看官看到本節(jié)還有興趣繼續(xù)看下去,那么這對小人就是一種支持,小人在此過了;如果看官覺得看這些沒有半點收獲,那么請看官不要再勉強自己看下去了,免得浪費看官大人的寶貴時間,那是小人所承擔不起的??傊?,要想寫好程序,就得多練,編譯連接過程中很容易發(fā)現(xiàn)錯誤的所在,那么這時你解決一個錯誤你就提高一次,解決的錯誤越多越快,你就學的越多越快。終于后來你會發(fā)現(xiàn),你太難找到錯誤了,那么恭喜你,你已經(jīng)升級為大蝦了,已經(jīng)完全脫離了菜菜級了。希望大家繼續(xù)努力!1.5 在窗口上寫上“Hello World”這一節(jié)我們乘勝追擊,來繼續(xù)深入學習下,學習窗口處理時間的東東。 也許你以前聽說過,windows系統(tǒng)是消

51、息驅(qū)動的,可是可能根本就不知道什么消息,更不知道什么消息驅(qū)動了。其實什么是消息呢,說白了就是我們點鼠標擊鍵盤而程序發(fā)生反應(yīng),消息是一種數(shù)據(jù),就是我們點鼠標擊鍵盤后,系統(tǒng)把我們的操作封裝到數(shù)據(jù)中,然后發(fā)送給程序,讓程序?qū)ξ覀凕c鼠標擊鍵盤的動作做出反應(yīng),當然程序也可以置之不理。Windows可是一個多任務(wù)的系統(tǒng),而且同時可能產(chǎn)生很多的擊鍵動作,那么同時可能能會有很多消息,windows系統(tǒng)為了更好的管理維護這些消息,就把這些消息加入消息隊列中,消息隊列其實就是消息的集合。學過VB的人知道,VB中的程序是事件驅(qū)動的,因為一般都是發(fā)生時,調(diào)用相應(yīng)的事件處理函數(shù),所以整個處理過程都好像是事件引發(fā)的一樣。

52、這里的事件就是指我們擊鍵的動作等。學過JAVA的人知道,JAVA中有事件適配器,來捕獲相應(yīng)的事件,并交給相應(yīng)的處理方法進行處理。其實三種語言的處理過程也都是小異,只不過JAVA和VB把這些處理過程給封裝了,VB尤其封裝的更厲害,所以編程者不必考慮和知道這中間的細節(jié)問題,仍然可以編寫出實用的程序,但正是由于細節(jié)的原因,用VB的開發(fā)的程序并不能高效地處理問題。而C語言本身就是面向過程的語言,所以這一過程可以用C語言更好地表現(xiàn)出來,這也是我用C而不用C+的原因之一。通過前幾節(jié)的學習,我們知道了,在窗口程序中都有一個處理窗口的函數(shù),其實所有的消息將會得到怎樣的處理,都是此函數(shù)安排的?,F(xiàn)在大家再回去看看

53、那個程序代碼和注釋,相信應(yīng)該能明白些了吧。系統(tǒng)產(chǎn)生的消息是不斷的,但是中間是有間隔的,程序要想知道有沒有自己的消息,得不停地去問系統(tǒng),問系統(tǒng)當前有沒有屬于自己的消息,這就需要一個循環(huán)來實現(xiàn)了。下面先看下前兩節(jié)種用到的消息循環(huán)代碼:while(GetMessage(&Msg,NULL,0,0) TranslateMessage(&Msg);/翻譯消息 DispatchMessage(&Msg);/分派消息 Windows為消息定義一種新的數(shù)據(jù)類型MSG,用于保存消息的相關(guān)信息。在windows中GetMessage函數(shù)從消息隊列種取得消息,填寫好MSG結(jié)構(gòu)并返回,如果獲取

54、的消息是WM_QUIT消息,則退出循環(huán)。TranslateMessage將MSG結(jié)構(gòu)傳給Windows進行一些鍵盤消息的轉(zhuǎn)換,當有鍵盤按下或者放開時,Windows產(chǎn)生WM_KEYDOWN和WM_KEYUP或WM_SYSKEYDOWN和WM_SYSKEYUP消息(像WM_KEYDOWN這些都是微軟定義的一些宏,是什么意思,看字面意思就可以知道了),但是這些消息的參數(shù)種包含的是按鍵的掃描碼(暫時不用理會),轉(zhuǎn)換成常用的ASCII碼要經(jīng)過查表,很不方便,TranslatMessage遇到鍵盤消息則將掃描碼轉(zhuǎn)換成ASCII碼并在消息隊列種插入WM_CHAR或WM_SYSCHAR消息,參數(shù)就是轉(zhuǎn)換好的

55、ASCII碼,如此一來,要處理鍵盤消息的話只要是處理WM_CHAR消息就好了。菊與刀非鍵盤消息TranslateMessage則不做處理。最后,由DispatchMessage將消息發(fā)送到窗口對應(yīng)的窗口過程去處理。窗口過程返回后DispatchMessage函數(shù)才返回,然后開始新一輪的消息循環(huán)。想想我們這節(jié)的目的是為了在潔白的窗口種寫下“Hello World”,那么我們怎么來留下我們的筆跡呢?窗口我們是能做出來了,那么怎么在上面寫東西呢,等等,在上面寫東西的前提是不是窗口做出來之后,當初我是這么想的,后來看到別人的代碼才知道原來可以在窗口繪制的過程就繪制“Hello world”了。Wind

56、ows有時真是個細心的家伙,把窗口創(chuàng)建到顯示的一瞬間又給劃分了很多小的過程。在繪制窗口時,Windows會產(chǎn)生WM_PAINT消息,那么我們在得到這個個消息的時候,來留下我們的筆跡,豈不就是下手最早的時刻。其實Windows在屏幕上輸出文字和圖像是一樣的,都是在屏幕上畫,和我們在紙上畫圖和寫字是一樣的,都是用筆來畫的,只不過用的筆不一樣而已,如果牽強用一支筆去做所有的工作,效果并不會理想的。Windows的筆也是這樣的,不過這些筆是函數(shù)而已,畫圖和畫文字的函數(shù)不一樣而已。下面就接著上節(jié)修改的代碼繼續(xù)修改,必要的注釋和改變的地方我會標明的#include <windows.h>#define CUR 0x1000/預(yù)定義光標的idHDC hDC;/HDC是指設(shè)備上下文(暫時不用管,只要能這樣用就可以了)的句柄/PAINTSTRUCT要繪制的信息,詳情請登陸msdn.microsoft./en-us/library/dd162768(VS.85).aspx/了解下就可以了,沒什么重要的東西PAINTSTRUCT paint;RECT rect;/RECT用來存儲窗口信息的結(jié)構(gòu),只要是窗口的坐標、寬度和高度。/回調(diào)函數(shù)LRESULT WINAPI WinProc(HWND hWnd,UINT Msg,WPARAM wParam,LPARAM lParam) switch

溫馨提示

  • 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. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論