15天學(xué)習(xí)C語(yǔ)言Windows程序設(shè)計(jì)_第1頁(yè)
15天學(xué)習(xí)C語(yǔ)言Windows程序設(shè)計(jì)_第2頁(yè)
15天學(xué)習(xí)C語(yǔ)言Windows程序設(shè)計(jì)_第3頁(yè)
15天學(xué)習(xí)C語(yǔ)言Windows程序設(shè)計(jì)_第4頁(yè)
已閱讀5頁(yè),還剩116頁(yè)未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡(jiǎn)介

目錄TOC\o"1-5"\h\z\o"CurrentDocument"C語(yǔ)言Windows程序設(shè)計(jì)->第一天->第一個(gè)Windows程序 -2-\o"CurrentDocument"C語(yǔ)言Windows程序設(shè)計(jì)ー>第二天一〉A(chǔ)SCII與Unicode -6-\o"CurrentDocument"C語(yǔ)言Windows程序設(shè)計(jì)ー〉第二天一〉寬字符和C語(yǔ)言 -7 -C語(yǔ)言Windows程序設(shè)計(jì)-〉第三天-〉Windows版printf -10-\o"CurrentDocument"C語(yǔ)言Windows程序設(shè)計(jì)ー〉第三天一〉屬于自己的窗口 -12\o"CurrentDocument"C語(yǔ)言Windows程序設(shè)計(jì)ー〉第四天-〉詳解我的窗口(上) -16\o"CurrentDocument"C語(yǔ)言Windows程序設(shè)計(jì)-〉第四天-〉詳解我的窗口(中) -20-\o"CurrentDocument"C語(yǔ)言Windows程序設(shè)計(jì)-〉第四天-〉詳解我的窗口(下) -24-\o"CurrentDocument"C語(yǔ)言Windows程序設(shè)計(jì)-〉第五天-〉回顧與反思 -28-\o"CurrentDocument"C語(yǔ)言Windows程序設(shè)計(jì)-〉第六天-〉GDI與設(shè)備環(huán)境 -29-\o"CurrentDocument"C語(yǔ)言Windows程序設(shè)計(jì)-〉第七天-〉TextOut與系統(tǒng)字體 -32-\o"CurrentDocument"C語(yǔ)言Windows程序設(shè)計(jì)-〉第ハ天-〉滾動(dòng)條 -38-\o"CurrentDocument"C語(yǔ)言Windows程序設(shè)計(jì)-〉第九天-〉GDI繪圖基礎(chǔ) -57-\o"CurrentDocument"C語(yǔ)言Windows程序設(shè)計(jì)-〉第十天-〉響應(yīng)鍵盤事件 -67-\o"CurrentDocument"C語(yǔ)言Windows程序設(shè)計(jì)-〉第十一天-〉使用鼠標(biāo) -73-\o"CurrentDocument"C語(yǔ)言Windows程序設(shè)計(jì)-〉第十二天-〉使用計(jì)時(shí)器 -80-\o"CurrentDocument"C語(yǔ)言Windows程序設(shè)計(jì)-〉第十三天-〉按鈕類控件 -88-\o"CurrentDocument"C語(yǔ)言Windows程序設(shè)計(jì)-〉第十四天-〉窗口、編輯框樣式 -98-\o"CurrentDocument"C語(yǔ)言Windows程序設(shè)計(jì)-〉第十五天-〉文本輸入框 -99-\o"CurrentDocument"C語(yǔ)言Windows程序設(shè)計(jì)ー實(shí)戰(zhàn):png圖片的解析與顯示 -110-C語(yǔ)言Windows程序設(shè)計(jì)ー>第一天一〉第一個(gè)Windows程序在《Windows程序設(shè)計(jì)》(第五版)第一章的起步中,作者介紹了學(xué)習(xí)Windows程序設(shè)計(jì)的一些基本要求:.能夠從用戶角度熟練的使用Windows;.懂得如何使用C語(yǔ)言;.安裝好了Windows的開(kāi)發(fā)環(huán)境.看起來(lái)要求并不算高(怎么樣?一起來(lái)嘗試下?)。筆者在這里決定使用VisualC++6.0作為開(kāi)發(fā)環(huán)境,雖說(shuō)在VisualStudio這個(gè)大家族中,VC++6早已被長(zhǎng)江后浪推前浪,把VC++6推成了一個(gè)將近淘汰的環(huán)境,但是作者的機(jī)器實(shí)在是有點(diǎn)不夠給カ,啟動(dòng)VS2010時(shí)相對(duì)比較慢???、之,既然CharlesPetzold也假定我會(huì)用VisualC++6.0?那么我就用VC++6好了。,介紹Windows*Windows的歷史;是的,你不用驚訝,Windows在這里就是指的微軟(Microsoft)的那個(gè)操作系統(tǒng),Windows的歷史如果要詳細(xì)介紹的話,我覺(jué)得可能要單開(kāi)個(gè)隨筆分類オ行,所以這里就簡(jiǎn)略的介紹ド,不過(guò)我還是建議你去搜索引擎查找ド關(guān)于Windows的歷史(如果你認(rèn)為有必要的話)。1>.1985年11月,Windows1.0正式推出;IBM與Microsoft共同開(kāi)發(fā),基于DOS系統(tǒng),通過(guò)DOS來(lái)進(jìn)行文件操作,當(dāng)然,2.0、3.0也都是基于DOS的,直到Windows2000的發(fā)布,Windows才徹底的擺脫了DOS,成為真正獨(dú)立的操作系統(tǒng)。2>.1987年11月,Windows2.0推向市場(chǎng);相對(duì)于1.0,2.0在界面上做了些改動(dòng),采用了重疊窗口。3>.1990年5月,Windows3.0推向市場(chǎng);支持Intel286、386、486微處理器的16位保護(hù)模式。4>.1993年7月,Windows'T投放市場(chǎng);Windows家族中第一個(gè)支持Intel386、486、奔騰微處理器32位模式的版本。5>.1995年8月,Windows95發(fā)布;一個(gè)混合的16位/32位Windows系統(tǒng)。6.>1998靠6月,Windows98進(jìn)ス市場(chǎng);基于Windows95編寫,對(duì)Windows95的改進(jìn)。書的作者就將Windows介紹到這里(沒(méi)辦法,人家這本書就是1998年寫好的),后來(lái)的Windows就更猛了,橫掃桌面,Windows2000/2003/XP/Vista/2008/7/8...t都懂得。?Windows的イえ點(diǎn):更加人性化?操作更簡(jiǎn)單?一定還有其他的優(yōu)點(diǎn)。?工作原理的中心思想:"動(dòng)態(tài)鏈接"概念即為Windows工作原理的中心思想,通過(guò)調(diào)用Windows自帶的函數(shù)來(lái)實(shí)現(xiàn)在屏幕上顯示文本與圖形。函數(shù)通過(guò)動(dòng)態(tài)鏈接庫(kù)實(shí)現(xiàn),.dll以及.exe的文件,在Windows98中,這些文件在、Windows\Systeml目錄下,NT的在、WinNT\System或\WinNT\System32,NT以上放在、Windows、System32。?關(guān)于Windows編程?WindowsAPI:API,ApplicationProgrammingInterface,應(yīng)用程序編程接口,WindowsAPI實(shí)際上也就是Windows提供的ー些函數(shù),通過(guò)對(duì)這些函數(shù)的調(diào)用完成應(yīng)用程序的開(kāi)發(fā)。*API文檔:這份文檔里介紹了Windows提供的已公開(kāi)的所有API,你可以下載份離線的,或者去MSDN在線圖書館(MSDXLibraryOnline)查閱這份文檔.上午的隨筆暫時(shí)寫到這里,感覺(jué)寫的有點(diǎn)短,其實(shí)書上寫了很多,仔細(xì)品味了好兒遍,越品味越有種找不到重點(diǎn)的感覺(jué),要是比著書上的句子抄,這博文豈不是太無(wú)味了,我想,這些Windows的背景知識(shí)對(duì)編程影響或許也不是很大,所以在這里就不啰嗦這些了。ド午學(xué)習(xí)"你的第一個(gè)Windows程序”。

?我的第一個(gè)Windows程序,Hello,world!在CharlesPelzold的書中,作者首先回顧了下C語(yǔ)言在控制臺(tái)下通過(guò)標(biāo)準(zhǔn)輸入輸出函數(shù)輸岀"Hello,world!”的程序,代碼如下:#include<stdio.h>intmain(){printf("Hello,world!\n");return0;}同樣,CharlesPetzold也給出了Windows版的"Hello,world!"(其實(shí)他給出的是Hello,windows98!),代碼如下:#include<windows.h>intWINAPIWinMain(HINSTANCEhlnstance,HINSTANCEhPrevInstance,PSTRszCmdLine,intiCmdShow)(MessageBox(NULL,TEXT("Hello,world!"),TEXT("MessageBox"),0);return0;§Hellolorld.c ヨ,mD:\Project\UinC\HenoIorld\HelloVorld.ctinclude<windows.h>intWINAPIUinMain(HINSTANCEhlnstance,HINSTANCEhPreuInstance,PSTRszCndline,intiCndShow)MessageBox(NULL,TEXT("Hello,world!"),TEXT("MessageBox"),0);return0;通過(guò)VisualC++6.0的"文件"一>"新建"一>"工程",選擇"Win32Application"創(chuàng)建ー個(gè)空的項(xiàng)目,再在這個(gè)項(xiàng)目中新建一個(gè)"文件",文件類型為"C++SourceFile",文件以.c為擴(kuò)展名,將上面的代碼敲入或者復(fù)制粘貼到這個(gè)文件內(nèi)容中,經(jīng)過(guò)編譯運(yùn)行就可以得到ー個(gè)對(duì)話框了,趕緊截圖留念吧!在這個(gè)對(duì)話框中,有標(biāo)題欄,標(biāo)題欄的內(nèi)容是"MessageBox",對(duì)話框的內(nèi)容為“Hello,world!",還有一個(gè)"確定"按鈕,而且,沒(méi)有那個(gè)黑框框窗口,一切看起來(lái)都是那么美好,來(lái)ー起看看這段Windows版的Hello,world!吧!?Windows版的Hello,world!代碼注釋?*第一行#include<windows.h>稍微有點(diǎn)C語(yǔ)音基礎(chǔ)的都能明白,這是要包含"windows.h"這個(gè)頭文件,也就說(shuō)明,在下面的代碼中,要用到這個(gè)頭文件,如果我們將#includeくwindows.h>這句去掉再進(jìn)行編譯看看會(huì)有什么情況:Compiling...HelioWorld,cd:\project\lwinc\helloworld\helloworld.c(3):errorC2061:syntaxerror:identifierWinMaind:\project\lwinc\helloworld\helloworld.c(3):errorC2059:syntaxerror:d:\project\lwinc\helloworld\helloworld.c⑶:errorC2146:

syntaxerror:missing')'beforeidentifier,hlnstance'd:\project\lwinc\helloworld\helloworld.c(3):errorC2061:syntaxerror:identifier'hlnstance'd:\project\lwinc\helloworld\helloworld.c(3):errorC2059:syntaxerror:",(d:\project\lwinc\helloworld\helloworld.c(3):errorC2059:syntaxerror:執(zhí)行cl.exe時(shí)出錯(cuò).意料之內(nèi)的,報(bào)錯(cuò)了,第一條就是標(biāo)識(shí)符"WinMain”錯(cuò)誤,具體的細(xì)節(jié)暫時(shí)就不深究了,繼續(xù)向ド看。?關(guān)于windows,h頭文件:在windowsメ這個(gè)頭文件中,實(shí)際上ー經(jīng)包含了若干的其他相關(guān)的頭文件,用書上的話說(shuō),windows」是個(gè)非常重要的包含文件,其中包含的其他比較重耍的頭文件有:WINDEF.H 基本數(shù)據(jù)類型定義WINNT.H 支持Unicode的類型定義WINBASE.H 內(nèi)核函數(shù)WINUSER.H 用戶界面函數(shù)WINGDI.H 圖像設(shè)備接口函數(shù)不過(guò)我還是好奇windows』到底包含了那些頭文件,找到VC6的安裝目錄,打開(kāi)Include文件夾,找到WINDOWS.H并打開(kāi),雖說(shuō)看不太懂,但找#include關(guān)鍵詞還是無(wú)壓カ的.除去上面的5個(gè)還有:■WINRESRC.H■EXCPT.H■STDARG.H■WINNLS.H■WINCON.H■WINVER.H■WINREG.H■WINNETWK.H■CDERR.H■DDE.H■DDEML.H■DLGS.H■LZEXPAND.H■MMSYSTEM.H■NB30.H■RPC.H■SHELLAPI.HBWINPERF.H■WINSOCK2.II■MSWSOCK.H■WINSOCK.H■WINCRYPT.HHCOMMDLG.H■WINSPOOL.H■OLE.H■OLE2.H■WINWLM.H■WINSVC.H■MCX.H■IMM.H?程序的入口在Win32控制臺(tái)程序(Win32ConsoleApplication)中,應(yīng)用程序的入口為main。函數(shù),windows程序的程序入口和Win32控制臺(tái)程序的入口類似,%WinMain()函數(shù).程序的入口函數(shù)在WINBASE.H作出了聲明,聲明如下:intWINAPIWinMain(HINSTANCEhlnstance,HINSTANCEhPrevInstance,LPSTR IpCmdLine,int nShowCmd);其中由聲明可以看出,WinMain函數(shù)的返回值被定義為int型;WINAPI為WinMain函數(shù)的調(diào)用規(guī)則,在WINDEF.H對(duì)"WINAPI”作出了如下宏定義:ttdefineWINAPI__stdcall說(shuō)明,WinMain函數(shù)的調(diào)用規(guī)則為"stdcall"方式,對(duì)于"—stdcal1”調(diào)用規(guī)則,現(xiàn)在暫時(shí)先不去深究,知道有這么回事就行,以后會(huì)詳細(xì)了解到的,現(xiàn)在如果深究"stdcall”就偏離了這篇博文的主題。?WinMain函數(shù)的參數(shù):1>.WinMain的窮?個(gè)參數(shù)HINSTANCEhlnstance,用書上的解釋為"實(shí)例句柄”,由于第一次接觸C語(yǔ)言Windows程序設(shè)計(jì),対這個(gè)句柄的概念也不是很了解,去百科了下,句柄的解釋為"一個(gè)句柄是指使用的ー個(gè)唯一的整數(shù)值,即ー個(gè)四字節(jié)長(zhǎng)的數(shù)值,來(lái)標(biāo)志應(yīng)用程序中的不同對(duì)象和同類對(duì)象中的不同的實(shí)例,諸如,ー個(gè)窗口,按鈕,圖標(biāo),滾動(dòng)條,輸出設(shè)備,控件或者文件等?!薄米园俣劝倏譬`〉句柄。筆者是這樣對(duì)句柄進(jìn)行理解的,在ー個(gè)應(yīng)用程序中,通常創(chuàng)建了很多的窗口、按鈕、標(biāo)簽,或者使用了一個(gè)文件等,在程序的任何地方,只要能夠獲得這個(gè)被稱為句柄的東西,就能夠找到該控件或者窗口在內(nèi)存中的位置,從而對(duì)其進(jìn)行操作。感覺(jué)有點(diǎn)像帶參數(shù)的main函數(shù),只是這里的主函數(shù)參數(shù)為一個(gè)句柄。2>.WinMain函數(shù)的第二個(gè)參數(shù),同樣是個(gè)實(shí)例句柄,但書上又進(jìn)?步解釋說(shuō)在32位的

Windows程序設(shè)計(jì)中,WinMain函數(shù)的實(shí)例句柄概念已不再采用,因此WinMain的第二個(gè)參數(shù)通??偸荖ULL筆者的見(jiàn)解:感覺(jué)馬上就要暈了,疑問(wèn)ー:"因此WinMain的第二個(gè)參數(shù)通??偸荖ULL”,那么第一個(gè)呢?WinMain的第一個(gè)參數(shù)會(huì)不會(huì)也可以是NULL呢?疑問(wèn)二:WinMain函數(shù)的參數(shù)從何而來(lái)?是操作系統(tǒng)么?帶著疑問(wèn)繼續(xù)向下看。3>.WinMain的第三個(gè)參數(shù)是用來(lái)運(yùn)行程序的命令行,PSTR:用來(lái)指向ー個(gè)字符串的指針類型,szCmdLine,sz:表示以〇結(jié)尾的字符串;目的是通過(guò)命令行方式運(yùn)行程序并向主函數(shù)中傳入?yún)?shù),應(yīng)該就像給main函數(shù)傳入?yún)?shù)一樣;4>.WinMain的第四個(gè)參數(shù)是ー個(gè)int型參數(shù),用來(lái)指明程序(窗口)最初如何被顯示,例如最小化?最大化?全屏?筆者的見(jiàn)解:應(yīng)該很有用,經(jīng)常見(jiàn)ー些游戲ー啟動(dòng)就是全屏的,但是這個(gè)參數(shù)也是操作系統(tǒng)傳給程序的么?因?yàn)閺钠綍r(shí)運(yùn)行Windows程序時(shí)都是直接雙擊,并沒(méi)有通過(guò)命令行給它傳入?yún)?shù),在編程時(shí)應(yīng)該對(duì)程序啟動(dòng)時(shí)的顯示方式有交代オ對(duì),這樣系統(tǒng)再運(yùn)行時(shí)再把這個(gè)交代的參數(shù)傳入給程序告訴程序啟動(dòng)時(shí)應(yīng)該如何顯示.(在"筆者的見(jiàn)解"部分的觀點(diǎn)均為筆者個(gè)人的見(jiàn)解,如果有誤肯定指正,我會(huì)及時(shí)更正,避免誤導(dǎo)其他讀者。)?WinMain函數(shù)函數(shù)體的MessageBox函數(shù):intMessageBox(HWNDhWnd,LPCTSTRIpText,LPCTSTRIpCaption,UINTuTypeMessageBoxO,名如其"人",不用猜也知道這個(gè)就是顯示一個(gè)對(duì)話框的函數(shù),打開(kāi)API文檔,MSDNLibrary通過(guò)索引找到MessageBox函數(shù),發(fā)現(xiàn)其聲明如下://intMessageBox(HWNDhWnd,LPCTSTRIpText,LPCTSTRIpCaption,UINTuType//addressoftextinmessagebox,ー個(gè)文本(字符串)的指針//addressoftitleofmessagebox,標(biāo)題字符雷的指針//styleofmessagebox,對(duì)話框的風(fēng)格在上面示例中對(duì)MessageBox函數(shù)的調(diào)用如ド:MessageBox(NULL,TEXT("Hello,world!"),TEXT("MessageBox"),0);第一個(gè)參數(shù)窗口的句柄的實(shí)參為NULL,意思為不屬于任何窗口.第二個(gè)參數(shù)為對(duì)話框的內(nèi)容。第三個(gè)參數(shù)為對(duì)話框的標(biāo)題,但是這兩個(gè)參數(shù)都使用了一個(gè)TEXT。的函數(shù),書上講使用TEXTO的目的是將這些字符串打包到TEXT宏代碼里面,筆者嘗試了不用這個(gè)TEXT。函數(shù)而直接像這樣:MessageBox(NULL,"Hello,world!","MessageBox",0);調(diào)用并沒(méi)有出現(xiàn)警告或者報(bào)錯(cuò)信息,具體使用TEXT。函數(shù)的詳細(xì)原因還不太清楚,暫時(shí)先在這里畫個(gè)圈。第四個(gè)參數(shù)為對(duì)話框的風(fēng)格,ー些以MB開(kāi)頭的ー些常量的組合,可以使用0R(|)運(yùn)算進(jìn)行組合,這些常量定義在W1NUSER.H中,例如常用的有:〉對(duì)話框按鈕類型:#defineMBOK#defineMBOKCANCELftdefineMBABORTRETRYIGNOREttdefineMBYESNOCANCEL卄パハヂ;ncMDVPCMnOxOOOOOOOOL0x0000000IL0x00000002L0x00000003L0x00000005L〃僅有一個(gè)"確定"按鈕〃"確定"+"取消"〃"終止"+"重試"+"忽略"〃"是"+"否"+"取消"http://"且"4."本"〃"重試"+"取消む#defineMB_RETRYCANCEL2〉.對(duì)話框中的圖標(biāo)類型:#defineMBICONHAND0x00000010L〃?個(gè)紅X的錯(cuò)誤/停止圖標(biāo)#defineMBICONQUESTION0x000000201//?個(gè)問(wèn)號(hào)的詢問(wèn)圖標(biāo)#defineMBICONEXCLAMATION0x00000030L〃ー個(gè)黃色感嘆號(hào)的警告圖標(biāo)#defineMB_ICONASTERISK0x00000040L〃ー個(gè)帶有i的信息提示圖標(biāo)同時(shí),在這些圖標(biāo)中有的還可以用其他名稱代替,這些別名在WINUSER.H的定義如下ttdefineMBICONWARNINGMBICONEXCLAMATION〃警告

MBICONHANDMBICONASTERISKMB_ICONHAND〃錯(cuò)誤〃信息〃停止ftdefineMBICONERRORftdefineMBICONINFORMATMBICONHANDMBICONASTERISKMB_ICONHAND〃錯(cuò)誤〃信息〃停止#defineMB_ICONSTOP下午的學(xué)習(xí)暫時(shí)就到這里,在學(xué)習(xí)的過(guò)程中出現(xiàn)了幾個(gè)疑問(wèn),在這里對(duì)疑問(wèn)進(jìn)行ド總結(jié):疑問(wèn)在書中介紹WinMain函數(shù)的參數(shù)時(shí)講到"因此WinMain的第二個(gè)參數(shù)通??偸荖ULL",那么第?個(gè)呢?WinMain的第一個(gè)參數(shù)也可以是NULし嗎?疑問(wèn)二:WinMain函數(shù)的參數(shù)從何而來(lái)?是操作系統(tǒng)么?疑問(wèn)三:使用TEXT()函數(shù)的作用是什么呢?C語(yǔ)言Windows程序設(shè)計(jì)ー>第二天一>ASCII與Unicodeー、ascii1>.關(guān)于ASCHASCI1(AmericanStandardCodeforInformationInterchange,美國(guó)信息互換標(biāo)準(zhǔn)代碼)ASCIIー共包含128個(gè)字符,包括:33個(gè)控制符號(hào),1個(gè)空格,32個(gè)符號(hào),10個(gè)數(shù)字,26個(gè)小寫字母和26個(gè)大寫字母。每個(gè)ASCII字符采用7位二進(jìn)制編碼的方式。ASCII的優(yōu)點(diǎn):十分可靠,普遍扎根在我們的鍵盤、顯示器、系統(tǒng)硬件、打印機(jī)、操作系統(tǒng)等,用途十分廣泛。ASCII的缺點(diǎn):ASCII,美國(guó)信息互換標(biāo)準(zhǔn)代碼,美國(guó)原生,不能滿足其他國(guó)家文字的需求,例如,中國(guó)的漢字?英國(guó)的英鎊符號(hào)(£)?等,這些在ASCII都是找不到的。2>.對(duì)ASCH的擴(kuò)展由于ASC?不能很好的滿足其他國(guó)家文字的需求,所以人們迫切希望能對(duì)ASCH進(jìn)行改進(jìn)。①.國(guó)際化標(biāo)準(zhǔn)組織的擴(kuò)展方案1967年,國(guó)際化標(biāo)準(zhǔn)組織(ISO,InternationalOrganizationforStandardization)推薦了ASCH的ー個(gè)變種,改動(dòng)內(nèi)容包括:從ASCII中,拿出0x40('@'),、0x5B('[')、0x5C(‘ヽ’)、0x5D(']')、0x5E('~')、0x60(''')、0x7B('{')、0x7C(';')、0x7D('}')、0x7E('ヽ')這10個(gè)符號(hào)保留給各個(gè)國(guó)家單獨(dú)使用。這顯然不是解決ASCII國(guó)際化的好方法,首先,其他國(guó)家將這些保留字符重新定義為自己國(guó)家需要的字符后,那么國(guó)際上的?致性將不能得到保證,此外,10個(gè)保留字符遠(yuǎn)遠(yuǎn)不能滿足美國(guó)的東方的ー些國(guó)家使用的象形文字需求,比如我們中國(guó)的漢字。.IBM公司的擴(kuò)展方案IBM公司采用了使用8位二進(jìn)制編碼方式來(lái)表示ASCH,使用ー個(gè)字節(jié)來(lái)儲(chǔ)存字符,這樣,相對(duì)于7位的ASCII就可以多出128個(gè)額外字符空位來(lái)補(bǔ)充ASCII。IBM對(duì)ASCII的主要擴(kuò)展為:補(bǔ)充了一些重音字符、小寫希臘字母、塊圖字符和線圖字符。同時(shí),還將一些補(bǔ)充的字符分配到ASCII的ー些不必要的控制字符上。(注:在操作系統(tǒng)還是字符模式的年代,塊圖字符和線圖字符常用來(lái)被應(yīng)用軟件裝飾自己的程序顯示).微軟公司的擴(kuò)展方案1985年11月,Windows1.0發(fā)布,微軟采用了自己定義的ー套字符集,這套字符集被稱為"ANSI字符集”,是基于ANS!和ISO標(biāo)準(zhǔn)的ー個(gè)草案。在MS-DOS3.3時(shí)代(1987年4月),微軟為了使不同國(guó)家的計(jì)算機(jī)都能正常的顯示字符,微軟采用了代碼頁(yè)概念,不同國(guó)家的字符被規(guī)定在不同的代碼頁(yè)上,例如代碼頁(yè)第437頁(yè)為美國(guó)英語(yǔ),850頁(yè)為拉丁語(yǔ)ー1。用戶只要將代碼頁(yè)設(shè)置到自己所在的國(guó)家就能正常的進(jìn)行エ作,但是如果用戶嘗試著將自己的文檔拿到與另外一個(gè)使用不同代碼頁(yè)的用戶的計(jì)算機(jī)上進(jìn)行修改時(shí),自己的文檔的某些字符將會(huì)顯示成其他字符,這還算好,有解決方案,應(yīng)用軟件可以通過(guò)將代碼頁(yè)信息儲(chǔ)存到文件中,使用時(shí)再進(jìn)行一些代碼頁(yè)的轉(zhuǎn)換。但在后來(lái),隨著代碼頁(yè)數(shù)量的劇增,Windows版本的不斷升級(jí),代碼頁(yè)的混淆問(wèn)題開(kāi)始日益凸顯,DS-DOS的代碼頁(yè)和Windows的代碼頁(yè)以及其他Windows版本的系統(tǒng)發(fā)生了不兼容,例如MS-DOS代碼頁(yè)第855頁(yè)西里爾語(yǔ)在Windows中的1251頁(yè)西里爾語(yǔ)或者M(jìn)acintosh的第10007頁(yè)西里爾語(yǔ)還都不ー樣。微軟為了解決東方?些國(guó)家使用的象形文字問(wèn)題,使用了雙字節(jié)字符集,這些字符集同樣在不同的代碼頁(yè),代碼頁(yè)936(簡(jiǎn)體中文)、949(韓文)、950(繁體中文)以及932(11文)。微軟的這個(gè)雙字節(jié)字符集和你象形的可能有所不同,在這個(gè)雙字節(jié)字符集中,前128個(gè)字符仍然是ASCII。字節(jié)),較高的128個(gè)擴(kuò)展字符以跟隨第二個(gè)字節(jié)的方式用來(lái)表示象形文字(這兩個(gè)字節(jié)被稱為前導(dǎo)字節(jié)和尾隨字節(jié))。所以在這個(gè)代碼頁(yè)中,有一個(gè)字節(jié)的字符,還有2個(gè)字節(jié)的字符,這就導(dǎo)致了兩個(gè)嚴(yán)重的問(wèn)題:1>,在一段字符串中,字符串的長(zhǎng)度不能根據(jù)字節(jié)的個(gè)數(shù)確定,耍想確定字符串的長(zhǎng)度必須檢査每個(gè)字節(jié)是不是雙字節(jié)字符的前導(dǎo)字節(jié)。2>,通過(guò)任意指向字符串中的ー個(gè)指針,無(wú)法知道前ー個(gè)字符的地址,通常要回到字符串的開(kāi)始,一直解析到指針?biāo)诘奈恢?。二、Unicode對(duì)ASCII擴(kuò)展的過(guò)程中,沒(méi)有能夠找到ー個(gè)徹底解決世界上所有書面文字的表示方法,很顯然,1個(gè)字節(jié),256個(gè)字符是無(wú)法表示世界上所有的書面文字的,因此,Unicode誕生了。Unicode使用16位(2字節(jié))的二進(jìn)制編碼方式來(lái)表示字符,我們知道,16位最多能夠表示65536個(gè)字符,65536個(gè)字符對(duì)于世界上的所有書面文字以及ー些特殊符號(hào)來(lái)說(shuō)已經(jīng)足夠用了。在Unicode中,不同國(guó)家使用不同的代碼段,例如,0x0530-0x058F為亞美尼亞語(yǔ)(Armenian)、0x0600-0x06FF為阿拉伯文(Arabic)、OxOEOO-0x0E7F為泰文(Thai)、0x2700-0x27BF為印刷符號(hào)(Dingbats)、0x4E00-0x9FBF為中文。Unicode的優(yōu)點(diǎn):只有一個(gè)字符集,避免了二義性,能夠滿足跨語(yǔ)言、跨平臺(tái)進(jìn)行文本轉(zhuǎn)換、處理的要求。Unicode的缺點(diǎn):Unicode字符的字符串比ASCII字符串占用的內(nèi)存大兩倍。(筆者認(rèn)為,隨著計(jì)算機(jī)性能的不斷提髙,內(nèi)存和外存容量的不斷增加,Unicode這?缺點(diǎn)可以慢慢忽略)。C語(yǔ)言Windows程序設(shè)計(jì)ー>第二天一>寬字符和C語(yǔ)言ー、回顧C(jī)語(yǔ)言中的char數(shù)據(jù)類型1>,在C語(yǔ)言中,首先我們來(lái)聲明一個(gè)字符型變量:charc;我們也可以在聲明時(shí)對(duì)其進(jìn)行初始化:charc='A';這時(shí),字符型變量c就會(huì)被值0x41進(jìn)行初始化,0x41也就是ASCII碼中的‘A'字符;2>.我們還可以定義一個(gè)指向ー個(gè)字符型數(shù)據(jù)的指針,例如:char*p;同樣我們?cè)僮屩羔榩初始化時(shí)指向一個(gè)字符串:char*p="Hello,world!”;

3>,我們?cè)俾暶饕粋€(gè)字符數(shù)組:chara[10];也可以在聲明時(shí)對(duì)其進(jìn)行初始化:chara[10]="Hello";或者:chara[]="Hello";通過(guò)對(duì)C語(yǔ)言的學(xué)習(xí)我們可以知道,char型變量為1個(gè)字節(jié),因此,在charc='A'中,變量c的大小即為1字節(jié);在32位的操作系統(tǒng)中,ー個(gè)指針型的變量需要4字節(jié)的存儲(chǔ)空間,因此在第二個(gè)示例中,char*p="Hello,world!";所需的存儲(chǔ)空間為:4字節(jié)指針變量所需的空間+字符串"HeiIo,world!"的12個(gè)字節(jié)另外再加上一個(gè)字節(jié)用來(lái)表示字符串結(jié)束的0。對(duì)于ー個(gè)字符數(shù)組chara[10];編譯器則會(huì)自動(dòng)保留10個(gè)字節(jié)的儲(chǔ)存空間,對(duì)于charaロ="Hello";這種聲明方式,編譯器會(huì)根據(jù)"Hello"字符串的長(zhǎng)度(5個(gè)字符+?個(gè)結(jié)尾〇)來(lái)決定初始化時(shí)的數(shù)組大小。通過(guò)學(xué)習(xí)Unico加編碼方式,可以知道,ー個(gè)Unicode字符占用2個(gè)字節(jié)的儲(chǔ)存空間,如果我們想用C語(yǔ)言中原有的數(shù)據(jù)類型表示Unicode的2字節(jié)編碼類型,char是不行的,char的儲(chǔ)存空間為ー個(gè)字節(jié),在32位的環(huán)境下,int占4個(gè)字節(jié),而我們僅僅需要的是2字節(jié),并且是無(wú)符號(hào)型數(shù)據(jù),因此,我們可以使用unsignedshortint型數(shù)據(jù)表示一個(gè)2字節(jié)的字符,unsignedshortint為2字節(jié),正好符合2字節(jié)的要求,當(dāng)然,我們也可以將unsignedshortint簡(jiǎn)寫為unsignedshort〇在C語(yǔ)言中的寬字符正是基于short型數(shù)據(jù)的,這ーー數(shù)據(jù)類型在頭文件WCHAR.H中的定義為:typedefunsignedshortwchar_t;所以C語(yǔ)言中的寬字符wchar_t數(shù)據(jù)類型與一個(gè)無(wú)符號(hào)短整形unsignedshortー樣,都是16位寬。如果我們用寬字符wchajt數(shù)據(jù)類型定義ー個(gè)變量并且初始化,如下:wchar_tc='A';那么寬字符wchajt變量c的值為0x0041,學(xué)過(guò)匯編的朋友應(yīng)該知道,如果使用16位的CPU儲(chǔ)存ー個(gè)字,將使用兩個(gè)存儲(chǔ)單元,在這兩個(gè)存儲(chǔ)單元中,低位字節(jié)放在低地址單元中,高位字節(jié)則放在高地址單元中,所以,在這里,處理器依然將從低位內(nèi)存單元即低位字節(jié)開(kāi)始處理字符,‘A’在內(nèi)存中的順序即為0x41->0x00?當(dāng)我們想使用寬字符表示一個(gè)字符串,我們還要通知編譯器這個(gè)字符串將使用寬字符存儲(chǔ),我們用大寫的字母'L'(表示長(zhǎng)整形)來(lái)將這ー消息告訴編譯器,例如:wchar_t*p=L"Hello";那么這個(gè)字符串"Hello”將會(huì)使用12個(gè)字節(jié)來(lái)儲(chǔ)存,這12個(gè)字節(jié)存儲(chǔ)單元的內(nèi)容為:"Hello"這5個(gè)字符占10個(gè)字節(jié),另外加上表示結(jié)束的〇占兩個(gè)字節(jié)。三、有關(guān)寬字符的函數(shù)在C語(yǔ)言的學(xué)習(xí)中,字符串處理函數(shù)我們經(jīng)常使用,比如:unsignedintstrlen(char*s);//求字符串的長(zhǎng)度char*strcat(char*dest,char*src):〃將src所指字符串連接到dest結(jié)尾處intstrcmp(char*sl,char*s2)J〃將李符串sl-與s2比較char*strcpy(char*dest,char*src):〃將src所指字符串復(fù)制到dest結(jié)尾處這些函數(shù)極大的方便了我們對(duì)字符串的處理,遺憾的是,在寬字符類型的字符串中,這些函數(shù)將不再適用,例如我們使用strlen求?個(gè)寬字符字符串的長(zhǎng)度,代碼如下:

ttinclude<stdio.h>ftinclude<string.h>intmainO(wchar_t*p=L*Hello*;printf("%d\n",strlen(p));return0;)運(yùn)行后顯示的結(jié)果為1,很顯然,它沒(méi)有求出正確的長(zhǎng)度,這是因?yàn)?寬字符字符串"Hello”在一段內(nèi)存中存儲(chǔ)的值如下:480065006C006C006F002100這是因?yàn)楫?dāng)strlen找到該字符串的第一個(gè)〇時(shí)就認(rèn)為該字符串已經(jīng)結(jié)束了,所以得到的長(zhǎng)度為1,strlen統(tǒng)計(jì)到的這ー個(gè)字符即為0x48表示的‘H'.幸運(yùn)的是,雖然這些字符串處理函數(shù)不支持對(duì)寬字符的處理,但是我們可以使用為寬字符處理準(zhǔn)備的函數(shù),C語(yǔ)言中每個(gè)字符串處理函數(shù)對(duì)應(yīng)的都有其寬字符版本的字符串處理函數(shù),這些函數(shù)定義在STRING.H頭文件和WCHAR.H中,例如strlen函數(shù)響應(yīng)的寬字符版本為wcslen,wcslen函數(shù)在STRING.H的聲明如下:size_twcslen(constwchar_t*);size,為無(wú)符號(hào)整形unsignedint的別名,STRING.H在頭文件的定義如下:typedefunsignedintsize_t;我們嘗試使用寬字符處理函數(shù)wcslen()求寬字符字符串的長(zhǎng)度:^include<stdio.h>#include<string.h>intmain()(wchar_t*p=L"Hello";printf("%d\n",wcslen(p));return0;)編譯運(yùn)行后的結(jié)果顯示為5,是正確的,同樣,在寬字符中常用的字符串處理函數(shù)如下:函數(shù)名函數(shù)原型函數(shù)功能返回值wchw_t*vcsc?tG?ch?r_t?sl,const?chw_t*s2);挎立所指的字符串連接到S1后面T所指李存串的自地址?exchrwchw_t**cschr(const t??,wcKw_tc);在與后串申找到諄苻第一次出現(xiàn)的位置著找到,則返回該學(xué)存的地址否則返回皿vcscmpintvcscap(constwch?r_t**1,constwch?r_t*s2).讓宇苻第,1與字苻陽(yáng)?2進(jìn)行比較?1<?2,返回負(fù)數(shù).3=?2,詆回O.sl>s2,返回E款wcscpywch?r_t*wcscpy(wchar_l?sl.const?char_t*s2);將s2所指字符串復(fù)的田的結(jié)尾處si所キ?字符曲首地址wcsltnsix?_twcslen(constwch?r_t*s).求,所?時(shí);5s的K度過(guò)回有效字后的個(gè)效wcsstr?ch?r_t?wcsstr(constwch?r_t constwch?r_t?s2):粒土字苻啣2在字存事う中第一次出麗位為若桃到,則返回該位置a地址,否!理返回皿四、遺留問(wèn)題:關(guān)于TEXT。昨天在學(xué)習(xí)過(guò)程中有個(gè)遺留問(wèn)題:MessageBox(NULL,TEXTCHello,world!0,TEXT("MessageBox"),〇);使用TEXT()的作用是什么呢?在今天的學(xué)習(xí)中終于找到了答案。

在定義wchar_t寛ア符類型的字符串時(shí),我們需要在字符串前面加上個(gè)大寫字母‘L’來(lái)告訴編譯器這是ー個(gè)wchajt寛字符型的字符串,而TEXT()正是為了解決在定義如何不加前面的’ビ的。當(dāng)我們使用寬字符時(shí),打開(kāi)TCHAR.H這個(gè)頭文件向下查找,會(huì)看到:ftdefine_T(x)L##x這句宏定義,在ANSIC標(biāo)準(zhǔn)的預(yù)處理中,符號(hào)"##"被解釋為"令牌粘貼”,作用是使得字母'ピ與宏參數(shù)連接在ー起,假如參數(shù)x為"Heilo”,那么經(jīng)過(guò)L##x處理后"Hello"就變成了L"Hello"?這看起來(lái)和TEXT。沒(méi)什么關(guān)系,繼續(xù)向下查找T(x)’會(huì)看到:#define_T(x) _T(x)#define二TEXT(x) _T(x)這兩行宏定義,到這里仍然沒(méi)有看到TEXT。,有了這個(gè)思路,筆者就嘗試著找到TEXT。宏,經(jīng)過(guò)搜索引擎的幫助,終于找到TEXT宏是定義在WINNT.H頭文件中,找到了相關(guān)的定義如下:#defineTEXT(quote)L##quote//rwinnt〃與一#defineTEXT(quote)_TEXT(quote)//rwinnt當(dāng)使用wchajt類型的寬字符時(shí),使用"令牌粘貼",這樣,使用TEXT宏時(shí)就避免了在字符串前面加上一個(gè)大寫字母‘L’了。C語(yǔ)言Windows程序設(shè)計(jì)ー>第三天一〉Windows版printf在Windows中使用printfー、可變參函數(shù)在Windows程序設(shè)計(jì)中,由于Windows不存在標(biāo)準(zhǔn)輸入輸出的概念,這就意味著以前我們學(xué)習(xí)的printf函數(shù)將不再適用,我們知道,C語(yǔ)言標(biāo)準(zhǔn)輸入輸出函數(shù)printf一個(gè)常用的功能就是輸出格式化后的文字,例如:intiAge=18;printf(z,Hello,Iam%dyearsold.\n",iAge);是的,printf函數(shù)的使用確實(shí)十分方便,今天我們要做的就是完成一個(gè)Windows版的printfo關(guān)于sprintf:看ー個(gè)C語(yǔ)言的函數(shù),sprintf這個(gè)函數(shù)在stdio.h頭文件中有聲明,sprintf函數(shù)的主要功能是把格式化的數(shù)據(jù)寫入某個(gè)字符串中,函數(shù)的原型如下:intsprintf(char*buffer,constchar*format,[argument]…);sprintf的第一個(gè)參數(shù)為字符緩沖區(qū),后面的參數(shù)就像printfー樣,是ー個(gè)格式化字符串,函數(shù)的返回值為緩沖區(qū)buffer內(nèi)的有效字符串長(zhǎng)度,我們嘗試使用一下:^include<stdio.h>intmain()(charszBuffer[50]; 〃定義緩沖區(qū)大小為50字節(jié)sprintf(szBuffer,"today:%d-%d-%d”,2012,10,8);//將今天的日期格式化輸出到緩沖區(qū)puts(szBuffer);〃輸出緩沖區(qū)szBuffer中的字符

return0;現(xiàn)在我們已經(jīng)能看到Windows版的printf的影子了,在Windows版的printf中,我們可以使用MessageBox函數(shù)來(lái)替代C語(yǔ)言的標(biāo)準(zhǔn)輸入輸出函數(shù)puts,但是在這之前我們還有一個(gè)重要的問(wèn)題要解決。sprintf的安全版當(dāng)我們使用sprintf時(shí),我們需要首先定義ー個(gè)緩沖區(qū),這個(gè)緩沖區(qū)我們必須定義的足夠大以至于能容納我們格式化輸出的字符串,如果超過(guò)了這個(gè)長(zhǎng)度,程序?qū)?huì)出錯(cuò),這樣是不安全的,這里,使用一snprinlf()函數(shù)來(lái)解決這個(gè)問(wèn)題,一snprintf的原型為:int_snprintf(char*szBuffer,size_tsize,constchar*format,...);_snprintf相對(duì)于sprintf函數(shù)多出了個(gè)參數(shù),size_tsize.這個(gè)參數(shù)的功能是:當(dāng)格式化后的字符串長(zhǎng)度〈size,則將此字符串全部復(fù)制到szBuffer中,并給其后添加一個(gè)字符串結(jié)束符('、0');當(dāng)格式化后的字符串長(zhǎng)度>=size,則僅復(fù)制(size-1)個(gè)字符到緩沖區(qū)szBuffer內(nèi),并在其后添加一個(gè)字符串結(jié)束符('、〇')。我們自己的可變參函數(shù)sprintf有個(gè)變形函數(shù),叫vsprintf,首先看下這個(gè)函數(shù)的原型:intvsprintf(char*szBuffer,constchar*format,valistparam);vsprintf的前兩個(gè)參數(shù)與sprintf相同,第三個(gè)參數(shù)是ー個(gè)valist宏,valist宏就是解決C語(yǔ)言變參問(wèn)題的。va_list宏的用法:我們將用到va」ist的以下幾個(gè)成員:va_listxva_startxva_end;在些宏在STDARG.H頭文件中有定義,打開(kāi)STDARG.H可以看到,其中有句:typedefchar*valist;從這句我們可以看出,va」ist其實(shí)就是char?型類型,ー個(gè)字符型指針;再來(lái)看看vastart宏:va_start(va_listap,char*format);format為函數(shù)的參數(shù),可以用來(lái)指明參數(shù)的類型可以看出,ap為valist類型,也就是可變參數(shù)列表;通過(guò)vastart后,就能使得變參列表與format中的類型ーー對(duì)應(yīng)起來(lái);va_end的作用是銷毀釋放一個(gè)va_list型的參數(shù)列表,例如:valistapvaend(ap);下面我們就可以實(shí)現(xiàn)我們自己的變參了,代碼如下:#include<stdio.h>#include<stdarg.h>intmySprintf(char*szBuffer,constchar*szFormat,...)(intiLength; 〃存儲(chǔ)字符串的長(zhǎng)度信息valistpArgs; 〃聲明一個(gè)valist型變量vastart(pArgs,szFormat);〃讓pArgs指向變參iLength=vsprintf(szBuffer,szFormat,pArgs);〃輸出到緩沖區(qū)szBuffer中va_end(pArgs); 〃釋放pArgs

returniLength; 〃返回字符串長(zhǎng)度)intmain(

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝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ù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 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)論