本筆記參考《windows程序設(shè)計(jì)》Charles Petzold,匯編版本參考《匯編通訊》Zoologist

開始

學(xué)習(xí)windows程序設(shè)計(jì)的條件有三:

熟悉windows操作系統(tǒng),只要使用電腦的人八成都挺熟悉

2了解C語言,作者這么說,我想我會(huì)c++應(yīng)該沒什么問題吧

3準(zhǔn)備好開發(fā)環(huán)境VC6匯編版本使用Masmplus

Window簡史

無非是操作系統(tǒng)的更新?lián)Q代,微軟就這么贏了。但還是跟著intel的腳步走的吧,intel拿出什么CPU,他就對應(yīng)更新一下。為了不至于像蘋果那么慘就拖泥帶水的在保護(hù)模式下有什么虛擬8086.這樣就可以運(yùn)行大量8086那個(gè)時(shí)代的軟件。

關(guān)于DLL

書上關(guān)于dll做了一些簡單的敘述,應(yīng)用程序和dll是多對多的關(guān)系,如果一個(gè)dll為多個(gè)應(yīng)用程序使用,那么該dll為共享dll文件。Dll文件和可執(zhí)行文件一樣包含可執(zhí)行代碼,但必須由應(yīng)用程序直接或間接的調(diào)用。如果是靜態(tài)連接就是將所有代碼編寫入一個(gè)可執(zhí)行文件,此時(shí)當(dāng)多個(gè)應(yīng)用程序,要調(diào)用某個(gè)函數(shù)時(shí)就會(huì)有多個(gè)拷貝,浪費(fèi)了內(nèi)存空間。若采用動(dòng)態(tài)連接,則根據(jù)描述信息定位到相應(yīng)的函數(shù)就可以了。并不會(huì)有多個(gè)拷貝,因?yàn)?/font>Win32系統(tǒng)保證內(nèi)存中只有DLL的一份復(fù)制品,這是通過內(nèi)存映射文件實(shí)現(xiàn)的。

關(guān)于API

API是系統(tǒng)函數(shù)和相關(guān)數(shù)據(jù)類型和數(shù)據(jù)結(jié)構(gòu)的集合。總之是系統(tǒng)現(xiàn)成提供給我們的資源。

Windows版HelloWorld

//========================

// (c)狗尾草2008.1.18

//========================

#include<windows.h>

int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nShowCmd)

{

 MessageBox(NULL,"HelloWorld!","Henry's first windows program",MB_OK);

 return 0;

}

有了IDE直接點(diǎn)編譯連接即可,運(yùn)行結(jié)果見圖。

頭文件windows.h中包含了其他windows頭文件,例如

WINDEF.H 基本型態(tài)定義。 

WINNT.H 支持Unicode的型態(tài)定義。 

WINBASE.H Kernel函數(shù)。  

WINUSER.H 使用者接口函數(shù)。  

WINGDI.H 圖形設(shè)備接口函數(shù)。

他們包含了系統(tǒng)的一些函數(shù),數(shù)據(jù)類型和結(jié)構(gòu)。以及一些常量的定義。

其中WINAPI會(huì)比較讓人感到疑惑,其實(shí)就是一種調(diào)用函數(shù)的約定,書上并未給出解釋

#define WINAPI _stdcall

他表示的是一種函數(shù)參數(shù)的入棧方式,分為c和pascal類型,c是從最后一個(gè)參數(shù)開始而pascal則剛好相反,其實(shí)c的入棧方式可以保證參數(shù)個(gè)數(shù)不確定的情況出現(xiàn)。

大致如下,關(guān)于產(chǎn)生函數(shù)修飾名沒有什么意義就不講了。

_cdecl

從右至左入棧,由調(diào)用者把參數(shù)彈出。

_stdcall

從右至左入棧,由被調(diào)用者把參數(shù)彈出。

WinMain參數(shù)詮釋

hInstance是該實(shí)例的句柄,用來唯一標(biāo)識(shí)一個(gè)實(shí)例的常量。

hPrevInstance是該實(shí)例前運(yùn)行的副本,如果已有一個(gè)程序運(yùn)行,可以直接從它那里獲取一些資源。

CmdLine執(zhí)行程序的命令列,用慣命令的人一定知道的。就是命令后跟著的那些一般帶杠的參數(shù)

nShowCmd是程序最初的顯示方式。

MessgeBox函數(shù)

第一個(gè)參數(shù)是窗口句柄,這里沒有定義窗口類,自然也沒什么窗口實(shí)例。所以為NULL

第二個(gè)參數(shù)是顯示的內(nèi)容

第三個(gè)參數(shù)是標(biāo)題欄內(nèi)容

#define MB_OK 0x00000000L 

最后一個(gè)是對話框按鈕,是一些帶MB_前綴的常量。還可以使用或運(yùn)算符指定圖示。實(shí)驗(yàn)中發(fā)現(xiàn)定義圖示時(shí)彈出對話框的聲音也發(fā)生變化,看來這些常量背后還很復(fù)雜。

匯編版本

;========================

; (c)狗尾草 2008.1.18

;========================

.386

.Model Flat, StdCall

Option Casemap :None

include windows.inc

include user32.inc

include kernel32.inc

IncludeLib user32.lib

IncludeLib kernel32.lib

.data

 titles db 'henry''s first windows program'

 content db 'HelloWorld!'

.data?

.code

 start:

 invoke MessageBox,NULL,offset content,offset titles,MB_OKCANCEL

 invoke ExitProcess,0

 end start

.386是指令集指定

.model用來指定內(nèi)存模式Flat是平坦模式

Option Casemap :None大小寫不區(qū)分

Invoke是函數(shù)調(diào)用語句,其實(shí)和c沒什么區(qū)別,參數(shù)用逗號分隔

編寫過程中

 titles db 'henry''s first windows program'

匯編沒有轉(zhuǎn)義字符,所以這里的''是對引號的特殊處理,天殺說是由編譯器處理的。