【x86彙編】第六章 輸出/輸出和win32編程

文章目錄

輸入/輸出指令和數據的傳送方式

  • 在80Xx86的PC機中,除了內存空間,還有IO空間
  • IO空間用於訪問外設中的寄存器
  • IO空間只能由IO指令訪問
  • 編址方式與內存相同,地址範圍爲0~0FFFFH,共64K
  • 寄存器稱爲端口,分爲狀態寄存器、控制寄存器、數據寄存器
  • 狀態寄存器:描述當前設備所處的工作狀態
  • 控制寄存器:存放控制設備當前工作方式所需的信息
  • 數據寄存器:暫存與CPU交換的數據

輸入/輸出指令

  • I/O空間的訪問不存在分段的問題
  • 保護方式下,存在訪問保護,CPU遇到IO指令時,檢查特權級和IO允許圖

輸入指令IN

IN OPD,OPS

  • 從指定的端口OPS中讀取數據,送入累加器OPD中
  • 外設寄存器地址爲0-255時,可用立即數表示,大於255時,只能DX表示
  • OPD只能是累加器

輸出指令OUT

OUT OPD,OPS

  • 將累加器OPS中的內容,送到外設地址OPD之中
  • 外設寄存器地址爲0-255時,可用立即數表示,大於255時,只能DX表示
  • OPS只能是累加器

串輸入指令INS

INS OPD,DX
INSB — 輸入字節串
INSW — 輸入字串
INSD — 輸入雙字串

  • ( [DX] ) -> ES : [ DI/EDI ]
  • DF=0時增量,DF=1時減量
  • 如果與REP前綴連用,則INS可以傳輸信息塊到連續的存儲空間OPD

串輸出指令OUTS

OUTS DX,OPD
OUTB — 輸出字節串
OUTW — 輸出字串
OUTD — 輸出雙字串

  • DS : [ SI/ESI ] -> ( [DX] )
  • DF=0時增量,DF=1時減量
  • 如果與REP前綴連用,則可以將內存中連續內容送到輸出端口

數據的傳送方式

無條件傳送

  • 在傳送數據時,不考慮外設的工作狀態
  • 在輸入數據時,總認爲外設已經將數據準備就緒
  • 該方式要求外設工作速度與CPU同步

查詢傳送

  • CPU與外設不同步
  • 輸入前,查詢數據是否就緒
  • 輸出前,查詢外設是否就緒
  • 查詢會佔用大量的CPU時間

直接存儲器

  • DMA(direct memory access)
  • 利用DMA控制器管理數據IO,適用於高速IO設備

中斷傳送

外設就緒後,發送中斷請求給CPU

中斷與異常

中斷的概念

  • CPU打斷當前執行程序,轉而爲臨時的事件服務,事後自動恢復
  • 實現這種功能的軟硬件裝置,稱爲中斷系統
  • 處理事件的程序,稱爲中斷處理程序
  • 引起中斷的事件稱爲中斷源

中斷分爲:

  • 外部中斷
    1. 不可屏蔽中斷 NMI
    2. 可屏蔽中斷 INTR
  • 內部中斷
    1. CPU檢測:除法錯誤、單步中斷、協處理器段超越等
    2. 程序檢測:軟中斷,包括INTO,INT N 和 BOUND 等

一般情況下,把外部中斷稱爲中斷,內部中斷稱爲異常

不可屏蔽中斷 NMI

由硬件故障引起,如果不及時響應,機器就無法正常運轉下去

可屏蔽中斷 INTR

可屏蔽中斷由各種外設的中斷請求產生,CPU的IF標誌,決定是否響應中斷

除法出錯

執行除法指令時,如果除數是0,或者商超出了寄存器所能表示的最大範圍,產生一箇中斷號爲0的內部異常

溢出

溢出標誌 OF=1時,執行指令INTO將會產生中斷號爲4的異常

調試異常(單步)

  • 指令地址斷點異常
  • 數據地址斷點異常
  • 一般檢查異常
  • 單步異常(TF=1)
  • 任務轉換斷點異常

軟中斷(INT N)

在這裏插入圖片描述

在這裏插入圖片描述

中斷矢量表

  • 中斷矢量表是中斷號與對應的中斷處理程序之間的連接表
  • 中斷矢量表連續存放了256個表項,每個表項中存放了中斷處理函數入口的段和偏移地址
  • 實方式下,中斷矢量表僅存放16位的段值和16位的偏移值,每個表項佔用4B
  • 保護方式下,中斷矢量表稱爲中斷描述符表(IDT),每個表項存放入口信息、類別、權限等, 佔用8B

中斷描述符分爲:

  • 任務門:執行中斷處理程序時將發生任務轉移
  • 中斷門:主要用於處理外部中斷,響應中斷時自動將TF和IF置零
  • 陷阱門:主要用於處理異常,響應中斷時TF置零

軟中斷及相關代碼

軟中斷指令

INT n

其中n是中斷號,取值範圍0-255

  • 實方式:
    1. FLAGS壓棧,IF、TF置零
    2. CS壓棧,計算新的CS並賦值
    3. IP壓棧,得到新的IP賦值
  • 32位段:
    1. EFLAGS壓棧,IF、TF置零
    2. CS拓展爲32位壓棧,從門或者TSS描述符指向的數據區分離出段選擇符,計算得到新的CS賦值
    3. EIP壓棧,從門或者TSS描述符指向的數據區分離出偏移值,計算得到新的EIP賦值

中斷返回指令

IRET

  • IP/EIP出棧,CS出棧,FLAGS/EFLAGS出棧

中斷處理程序的設計

主要包括:爲尚未分配功能的中斷號設計一箇中斷處理程序,或修改已有的中斷處理程序以擴充其功能

新增一箇中斷處理程序的步驟

  • 根據新增加的功能需求,編制中斷處理程序,遠過程,IRET返回
  • 查看中斷矢量表,找空閒中斷號m
  • 將新編制的中斷處理程序裝入內存,其入口地址送到中斷矢量表

修改已有中斷處理程序以拓展其功能

  • 根據需求編制程序段
  • 將程序裝入內存,將入口地址複製到程序段中,用新的入口地址取代中斷矢量表中已有的入口地址

外設中斷注意事項

  • 必須保護現場
  • 及時開中斷以便CPU能響應更高級的中斷請求
  • 通過選用高效的指令和編制短小的程序來儘快完成中斷處理的任務
  • 恢復現場
  • 通知中斷控制器中斷已結束
  • 利用IRET指令實現中斷返回

軟中斷注意事項

  • 考慮切換堆棧
  • 保護現場
  • 在實方式下應該及時開中斷,以便CPU能響應外設的中斷請求
  • 按照一般速度要求完成中斷處理
  • 恢復現場
  • 堆棧切換還原
  • 一般用IRET指令實現中斷返回

浮點運算

FPU中的寄存器

  • 8個獨立尋址、按寄存器棧組織的80位浮點數據寄存器
  • 3個16位寄存器(狀態字、控制字和標記字寄存器)
  • 2個出錯指針(一個指向最後一條指令,另一個指向最後一個操作數)
  • 1個操作碼,是最後一條非控制的FPU指令操作嗎,由11位寄存器存放

浮點數據寄存區和標記寄存器

  • 8個浮點數據寄存器編號爲FPR0-FPR7
  • 由8個浮點數據寄存器組成首尾相接的堆棧
  • 彙編中使用的浮點寄存器的助記符是ST(0) - ST(7),其中0是棧頂,由狀態寄存器的TOP字段指明
  • 對應每個FPR寄存器,都有一個2位的標記域,含義如下
    1. 00 對應的數據寄存器中存有有效的數據
    2. 01 對應的數據寄存器中數據爲0
    3. 10 對應的數據寄存器中數據是特殊數據(NaN,∞等)
    4. 11 對應的數據寄存器沒有數據

狀態寄存器

狀態寄存器表明FPU當前的各種操作狀態以及每條浮點指令執行後所得結果的特徵,其作用與CPU中的標誌寄存器相當
在這裏插入圖片描述

  • 狀態寄存器的低6位,反應6種錯誤,置位後的錯誤標誌必須指令清除
  • C0-C3是條件標誌位,是根據FPU運算後所得結果自動設置的

控制寄存器

控制寄存器用於控制FPU的異常屏蔽、精度和舍入操作
在這裏插入圖片描述

浮點指令與程序設計

  • FPU具有自己的指令系統
  • 浮點指令屬於ESC(轉義)指令
  • 其前5位的操作碼都是11011B,它們的助記符都是F開頭
  • 操作數不能是立即數

向FPU中裝入數據的指令

FLD OPS ;將主存或ST中的浮點數壓入棧頂
FILD OPS ;將主存中的整數壓入棧頂
FBLD OPS ;將主存中的BCD碼數壓入棧頂

從FPU中取出數據的指令

FST OPD ;將棧頂的數據存放到ST(I)或按變量的浮點格式存放到主存中
FIST OPD ;將棧頂的數據按照整數格式存放到主存中

以上兩條指令不改變FPU內浮點數據寄存器棧的狀態

FSTP OPD ;將棧頂數據,按浮點格式存放到ST(I)或主存中,然後出棧
FISTP OPD ;將棧頂數據,按整數格式,存放主存,然後出棧
FBSTP OPD ;將棧頂數據,按BCD碼格式存入主存,然後出棧

交換指令

FXCH ;ST0和ST1內容交換
FXCH ST(i) ;ST0和STi內容交換

基本算術指令

FADD ST(i),ST(j) ;STi + STj -> STi,i和j至少有一個0,至少有一個是ST0
FADD OPS ;ST0 + OPS -> ST0
FIADD OPS ;ST0 + OPS -> ST0
FSUB ST(i),ST(j) ;STi + STj -> STi,其中至少一個0
FSUB OPS ;ST0 - OPS -> ST0
FISUB OPS ;ST0 - OPS -> ST0
FMUL ST(i),ST(j) ;STi * STj -> STi,其中i和j至少有一個爲0
FMUL OPS ;ST0 * OPS -> ST0
FIMUL OPS ;ST0 * OPS -> ST0
FDIV ST(i),ST(j) ;STi / STj -> STi
FDIV OPS ;ST0 / OPS -> ST0
FIDIV OPS ;ST0 / OPS -> ST0
FSQRT ;計算ST0的平方根 -> ST0

超越函數指令

FSIN
FCOS

控制和常數指令

FINIT:初始化浮點單元
FLDPI:把常數π送到FPU堆棧上
WAIT:使處理器檢查數值異常

WIN32編程

基於Windows運行環境的32位段程序簡稱爲WIN32程序

基礎

32位編程環境

  • 一個完整的編程環境應該包括 編譯工具、彙編程序、連接程序、調試程序
  • windows提供的系統功能不再是軟中斷,而是子程序庫的形式,因此必須先引入,增加外部過程及相關外部變量的說明
  • 按照功能分類,函數代碼放在不同的動態連接庫文件中,函數代碼的位置信息存放在不同的引入庫文件中,函數的原型說明信息存放在不同的頭文件中
  • 在win32編程中,將常用的、組成顯示界面的信息稱爲資源,如菜單、對話框、字符串、圖標和位圖等

庫和頭文件

  • 由於提供了大佬的動態連接庫,引入庫和頭文件,因此編程時只需要指明引入信息即可
  • KERNEL32.LIB:負責處理內存管理和進程調度,對應函數原型說明信息存放在頭文件KERNEL32.INC中
  • USER32.LIB:負責控制用戶界面,對應函數原型說明信息存放在頭文件USER32.INC中
  • GDI32.LIB:負責圖形方面的操作,對應的函數原型說明信息存放在頭文件GDI32.INC中
  • 連接程序需要引入庫的信息,方法有兩種,一是程序中INCLUDELIB說明,二是連接時,指定庫文件路徑
  • WINDOWS.INC將API中常用的常量和結構體定義集中存放於此

宏彙編語言對WIN32編程的支持

段的簡化定義

如果要在程序中使用段名,可以通過預定義符來指定,如:@DATA、@CODE

存儲模型說明MODEL

簡化的段定義僞指令均以符號點 . 引導

.MODEL 存儲模型,語言類型,系統類型,堆棧選項

  • 用於指定程序中各段的屬性、程序運行的環境、調用規則等
  • 存儲模型:指定內存管理模式
  • 語言類型:指定了函數命名、調用和返回的方法
  • 系統類型:目前只有OS_DOS選項
  • 堆棧選項:包括NEARSTACK和FARSTACK
  • 該指令必須放在源文件中所有其它段定義之前,且只能使用一次

在這裏插入圖片描述

定義代碼段CODE

.CODE 段名

說明一個代碼段的開始,同時也表示上一個段的結束

定義數據段DATA?

.DATA 或者 .DATA?

  • 說明一個數據段的開始,同時也表示上一個段的結束
  • 當採用.DATA時,段內的變量初始化,佔用執行文件的存儲空間,其段名指定爲_DATA
  • 當採用.DATA?時,段內變量未初始化,也不佔用存儲空間,其段名指定爲_BSS
其它僞指令

.STACK 堆棧字節數
.CONST 常數段僞指令
.STARTUP 程序開始僞指令

原型說明與函數調用

  • 在子程序參數較多,或者與高級語言混合編程時,使得參數傳遞變得複雜,容易出錯
  • 爲解決此問題,提供了PROTO和INVOKE僞指令,使子程序的說明類似於高級語言的原型說明
原型說明PROTO

函數名 PROTO 函數類型,語言類型,參數名:參數類型…

  • 說明本模塊中要調用的函數
  • 函數類型:指明瞭子程序的類型,可以是NEAR,FAR,NEAR16,NEAR32,FAR16,FAR32
  • 語言類型:指明參數傳遞的方式採用哪種語言的規定
  • PROTO的功能類似於EXTERN,但表達能力更強
完整的函數定義PROC

函數名 PROC 函數類型,語言類型,USES寄存器表,參數名:類別

  • 定義一個新的函數,函數體緊跟其後
  • 與PROTO格式相似,USES後面的寄存器是需要入棧保護的
  • PROTO和PROC都沒有說明返回參數,如果有返回值,默認放在累加寄存器中
  • 如果有多個返回參數,則通過指針存放到調用者的程序空間
函數調用INVOKE

INVOKE 函數名 參數…

  • 調用由完整的函數定義PROC定義的函數
  • 參數可以是各種表達式
  • ADDR BUF 等價於OFFSET BUF,ADDR經驗處理局部變量,而OFFSET不能

局部變量僞指令LOCAL

在函數定義的PROC之後,可以用LOCAL指令說明僅在本函數內使用的局部變量

LOCAL 變量名 數量:類型

結構

結構名 STRUCT
數據定義語句序列
結構名 ENDS

  • 結構是用戶自定義的複合數據類型,它將各種不同類型的數據組織到一個數據結構中,以方便處理複雜的數據項
  • 在描述結構型數據或使用結構型變量之前,需要先對結構進行說明
  • STRUCT和ENDS要配對使用
  • 數據定義語句序列是一組變量的定義語句
  • 結構說明只是定義了一個框架,並未分配主存空間,只有在利用該類型爲自己的程序定義一個結構變量時才進行存儲分配
  • 結構變量一般放在數據段中,而結構說明應該放在結構變量定義之前,不屬於任何段

定義結構變量的一般格式:

變量名 結構名 <字符賦值表>

  • 定義結構變量時,不能對含有多個項目的字段重新賦值,要修改必須通過指令
  • 如果要存取某個結構變量,採用結構變量名.結構字段名的形式,如:MOV EAX,C2.CID

WIN32程序的結構

windows下的程序框架相當複雜,爲了方便程序員,Windows開發包的文檔中規定了各種Windows程序(核心驅動程序、動態鏈接庫、窗口應用程序等)的標準框架

基於窗口的應用程序可以簡單地劃分爲4個部分

  • 主程序:OS首先執行主程序,獲得本程序有關的基本信息後,再調用窗口主程序

  • 窗口主程序:創建指定窗口後,將該窗口收到的消息通過操作系統轉發到窗口消息處理程序

  • 窗口消息處理程序:判斷收到的消息種類,決定調用用戶處理程序中的哪些函數完成相應功能

  • 用戶處理程序:用戶自己實現的程序

  • 主程序:可以根據需求安排任何指令,但爲了適應窗口程序的需要,必須完成規定的初始化工作,主要包括:獲取本程序在主存中的地址(也稱句柄),獲取命令行參數的地址,調用窗口主程序等

  • 句柄:是用來唯一標識某一個程序、窗口等的代號,一般是它們的地址,用戶需要通過API獲取句柄,然後才能通過句柄對所代表的內容進行操作(發送信息等)

  • 用戶處理程序:是完成用戶實際需求的各種函數的集合,一般是用戶按照需求,自行命名、編寫的函數,完全可以按照子程序設計方法編寫

  • 窗口主程序:是一個調用了多個Windows API函數的函數體,一般命名爲WinMain,它首先完成窗口的創建、程序所需資源的裝載等操作,然後不斷從操作系統中獲取對所創建窗口進行操作的信息,並分發到窗口消息處理程序,它的原型說明爲:

WinMain PROTO   hInst       :DWORD,     ;應用程序的實例句柄
                        hPrevInst   :DWORD,     ;前一個實例句柄
                        lpCmdLine   :DWORD,     ;命令行指針,指向以0結束的命令行字符串
                        nCmdShow    :DWORD      ;指出如何顯示窗口

在這裏插入圖片描述

實例:是指主存中實際存在的程序代碼和數據,用於區別程序代碼和數據的描述信息
消息:是指發給應用程序的各種命令,系統將這些命令轉換成統一的格式,按照命令產生的時間順序放在消息隊列中,每個消息用MSG結構定義如下:

MSG STRUCT
    hwnd     DD ?           //窗口句柄,指明消息屬於哪個窗口
    message DD ?            //消息號,指明消息的種類
    wParam  DD ?            //消息的附加信息
    lParam   DD ?            //消息的附加信息
    time       DD ?           //指明消息產生的時間
    pt          POINT <>    //指明消息產生時,光標相對屏幕座標的位置
  • 窗口消息處理程序:主要功能是對接收到的消息進行判斷,以便分類處理,一般命名爲WndProc,原型說明如下:
WndProc     PROTO   hWin : DWORD    //窗口句柄
                            uMsg : DWORD   //消息號,指明消息的種類,是判斷分支的依據
                            wParam:DWORD   //該消息的附加信息,若是子消息號,則是嵌套分支判斷的依據
                            lParam:DWORD   //該消息的附加信息

爲了簡化分支程序的設計,高版本的彙編程序提供了多個條件控制流僞指令,還支持多個比較關係操作符,包括

相等 不等 大於 小於 大於等於 小於等於 邏輯非 邏輯與 邏輯或
== != > < >= <= ! && ||
位測試 進位標誌 符號標誌 零標誌 溢出標誌 奇偶標誌
& CARRY? SIGN? ZERO? OVERFLOW? PARITY

這些操作符可以用於比較變量、寄存器和常數,還可以組合成複雜的條件表達式,在窗口消息處理函數中,常用IF僞指令

.IF 條件表達式
    語句序列
.ELSEIF 條件表達式
    語句序列
.ELSE
    語句序列
.ENDIF

Windows API函數簡介

主程序中使用的API函數

獲取應用程序模塊的句柄

GetModuleHandle PROTO lpModuleName:DWORD

輸入參數lpModuleName是一個地址指針,指向一個正在系統中運行的程序的名字串,指針賦值爲0時,標識獲取調用此API程序的句柄,調用成功時,返回值爲句柄,否則返回0

獲得指向當前命令行緩衝區的指針

GetCommandLine PROTO

調用後返回一個指向當前程序的命令行字符串的地址指針

退出程序

ExitProcess PROTO uExitCode:DWORD

uExitCode標識退出碼,正常退出爲0,退出用戶程序,返回操作系統

窗口主程序中使用的API函數

常用的有以下4類函數

註冊窗口

該函數用於註冊用戶定義的窗口類,若創建的窗口是基於Windows預先定義的類,則不必註冊

RegisterClassEx PROTO lpwex:DWORD

該函數的輸入參數是指向一個按照WNDCLASSEX結構定義的指針,定義如下:

WNDCLASSEX  STRUCT 
    cbSize      DD ?    //大小,字節數
    style        DD ?   //窗口具有的風格,可以用OR
    lpfnWndProc DD ?    //窗口消息處理函數的指針
    cbClsExtra  DD ?    //附加字節數
    cbWndExtra DD ?     //附加字節數
    hInstance   DD ?    //窗口所屬模塊的實例句柄
    hIcon        DD ?   //圖標資源的句柄,爲0時,使用缺省圖標
    hCursor     DD ?    //光標資源的句柄,爲0時缺省
    hbrBackground DD ?   //背景色
    lpszMenuName DD ?   //在資源文件中描述菜單的資源名字符串的指針
    lpszClassName DD ?  //指向類名稱的指針
    hIconSm         DD ?    //與窗口類關聯的小圖標的句柄,爲0時,將hIcon指定的圖標轉換爲合適大小
WNDCLASSEX  ENDS

結構變量初始化時,參數值選擇範圍較大的是窗口風格style和背景色hbrBackgroud
style的取值可以是以下值或者組合

CS_VREDRAW//如果窗口移動或調整大小後改變了用戶區的高度,則重畫整個窗口
CS_HREDRAW//如果窗口移動或調整大小後改變了用戶區的寬度,則重畫整個窗口      
CS_DBLCLKS//當鼠標在該窗口內雙擊時,將雙擊消息發送到窗口消息處理函數
CS_OWNDC//該類的每個窗口都指定單獨的設備上下文句柄
CS_CLASSDC//爲用該類創建的所有窗口指定一個共享的設備上下文句柄
CS_PARENTDC//設置子窗口在父窗口中限制區域以提高性能                   
CS_NOCLOSE//在系統菜單中取消“關閉”功能
CS_SAVEBITS//在幾個窗口間切換時,用位圖的形式保存、恢復本窗口中被覆蓋的內容
CS_BYTEALIGNCLIENT//窗口的用戶使用區在水平X方向的邊界具有字節特性,以提高繪圖性能
CS_BYTEALIGNWINDOW//窗口在水平X方向的邊界具有字節特性,以提高窗口移動和縮放性能 
CS_GLOBALCLASS//強制程序只使用註冊窗口時的實例句柄hInstance來創建窗口

窗口背景色hbrBackgroud可以是以下定義中的一個值,但在給它賦值時,需要在以下基礎上加1

COLOR_SCROLLBAR//滾動條的顏色類型
COLOR_BACKGROUND//背景的顏色類型
COLOR_ACTIVECAPTION//活動標題欄的顏色類型
COLOR_INACTIVECAPTION//未激活標題欄的顏色類型
COLOR_MENU//菜單欄的顏色類型
COLOR_WINDOW//窗口的顏色類型
COLOR_WINDOWFRAME//窗口框架的顏色類型
COLOR_MENUTEXT//菜單文字的顏色類型
COLOR_WINDOWTEXT//窗口文字的顏色類型
COLOR_CAPTIONTEXT//標題文字的顏色類型
COLOR_ACTIVEBORDER//活動邊界的顏色類型
COLOR_INACTIVEBORDER//未激活邊界的顏色類型
COLOR_APPWORKSPACE//程序工作區的顏色類型
COLOR_HIGHLIGHT//高亮的顏色類型
COLOR_HIGHLIGHTTEXT//高亮文字的顏色類型
COLOR_BTNFACE//按鈕面的顏色類型
COLOR_BTNSHADOW//按鈕陰影的顏色類型
COLOR_GRAYTEXT//灰文字的顏色類型
COLOR_BTNTEXT//按鈕文字的顏色類型

創建窗口

CreateWindowEx PROTO 
    dwExStyle : DWORD   //擴展的窗口風格,可爲 0
    lpClassName : DOWRD //指向已註冊類的名字的指針
    lpWindowName : DWORD//指向窗口名字的指針,該名字串會顯示到窗口的標題欄上
    dwStyle : DWORD//窗口的風格
    x : DWORD//窗口左上角頂點的水平座標值
    y : DWORD //窗口左上角頂點的垂直座標值
    nWidth : DWORD//窗口寬度
    nHight : DWORD//窗口高度
    hWndParant : DWORD//父窗口或所屬窗口的句柄,0 表示沒有
    hMenu : DWORD//附加菜單的句柄或子窗口的標識符,0 表示沒有
    hInstance : DWORD//產生該窗口的應用程序的實例句柄
    lpParam : DWORD//指向欲傳給窗口的結構體數據類型參數的指針

如果函數執行成功,則EAX中的返回值是所創建窗口的句柄,執行失敗返回0,創建窗口時,參數dwExStyle和dwStyle是可以根據需要取值的,參數dwExStyle可以是以下的一個或組合

WS_EX_DLGMODALFRAME//指定具有雙邊界的窗口
WS_EX_NOPARENTNOTIFY//當子窗口被創建和取消時,子窗口不向父窗口發送WS_PARENTNOTIFY消息
WS_EX_TOPMOST//指定該窗口總放在最前面
WS_EX_ACCEPTFILES//指定用此方式創建的窗口接受拖放文件
WS_EX_TRANSPARENT//創建一個透明的窗口
WS_EX_CLIENTEDGE//指定窗口的邊界具有凹陷效果
WS_EX_APPWINDOW//在任務條上顯示本窗口的小窗口

參數dwStyle除了可以選用通用的預定值外,還可以選用將創建的窗口所使用的的類所定義的值,dwStyle可以是下列預定值的一種或組合

WS_OVERLAPPED//創建一個重疊式窗口(帶有一個標題欄和邊框)
WS_CHILD//創建一個子窗口
WS_VISIBLE//創建一個初始時可見的窗口
WS_CAPTION//窗口有一個標題欄
WS_VSCROLL//窗口具有一個垂直滾動條
WS_HSCROLL//窗口具有一個水平滾動條
WS_SYSMENU//在標題欄中具有系統菜單框的窗口(應同時指定WS_CAPTION)
WS_THICKFRAME//寬邊框的窗口
WS_MINIMIZEBOX//窗口帶有最小化按鈕
WS_MAXIMIZEBOX//窗口帶有最大化按鈕
WS_OVERLAPPEDWINDOW//窗口具有WS_OVERLAPPED、WS_CAPTION、WS_SYSMENU、WS_THICKFRAME、WS_MINIMIZEBOX 、WS_MAXIMIZEBOX的風格(最常用的)

載入相關資源

在註冊和創建窗口時,有些初始值需要通過API函數獲得,有些需要API函數設定

載入一個圖標
LoadIcon PROTO
    hInstance : DWORD//應用程序實例句柄,當裝入標準圖標時,此參數爲 0
    lpIconName : DWORD//圖標資源的名字或資源的標識符

如果函數執行成功,返回剛裝入的圖標的句柄,否則返回0

載入一個菜單
LoadMenu PROTO
    hInstance : DWORD//應用程序實例句柄
    lpMenuName : DWORD//菜單的名字或菜單資源的標識符

如果函數執行成功,返回剛裝入的菜單資源的句柄,否則返回0

設定菜單
SetMenu PROTO
    hWnd : DWORD//被賦予菜單的窗口的句柄
    hMenu: DWORD//待賦予的菜單資源的句柄; 若爲0,則刪除窗口當前已有的菜單

如果函數執行成功,則返回非 0; 否則返回 0

載入光標
LoadCursor PROTO
    hInstance : DWORD//應用程序實例句柄
    lpCursorName : DWORD//光標的名字或光標資源的標識符

如果函數執行成功, 則返回剛裝入的光標的句柄; 否則返回0
當hInstance爲0時,可以裝入系統預定義光標,即可以將lpCursorName的值賦爲:IDC_ARROW(標準箭頭), IDC_WAIT(時間瓶光標)或 IDC_CROSS(X 形光標)等

獲得用戶去窗口大小
GetClientRect PROTO
    hWnd : DWORD//被檢取座標的用戶區所在的窗口句柄
    lpRect: DWORD//指向一個存放用戶區座標的RECT結構
  • 如果函數執行成功,則返回非0; 否則返回0。
  • 用戶區座標指定用戶矩形區域的左上角和右下角的座標。
  • RECT的結構定義順序爲: left、top、right、bottom
初始化公用控件

InitCommonControls PROTO

該函數將公用控件動態庫裝入系統供程序使用,它沒有輸入參數和返回值

消息循環

獲取消息
GetMessage PROTO
    lpMsg   : DWORD //指向一個MSG結構變量的指針
    hWnd    : DWORD //消息所屬窗口的句柄
    wMsgFilterMin  : DWORD//指定被檢取的最低消息值的整數值
    wMsgFilterMax  : DWORD//指定被檢取的最高消息值的整數值

該函數只檢取與給定窗口有關並且位於給定消息值範圍內的消息。 如果檢取到退出消息WM_QUIT,則返回值爲0,否則,返回非0並將消息信息填到 lpMsg指向的結構變量中

轉換鍵盤消息
TranslateMessage PROTO
    lpMsg  : DWORD  //指向一個MSG結構變量的指針

該函數主要是爲了將鍵盤輸入數據轉換成對應的ASCII碼併產生WM_CHAR消息(該消息的wParam參數的低8位保存着對應鍵的ASCII碼,lParam參數保存着鍵的其他相關信息)
若完成一個字符消息的轉換,則返回非0,否則返回0

分發消息
DispatchMessage PROTO
    lpMsg  : DWORD  //指向一個MSG結構變量的指針

該函數將lpMsg指向的消息傳送到窗口過程(窗口消息處理函數wdProc) 返回值通常被忽略

窗口過程中使用的API函數

消息處理函數

顯示消息框
MessageBoxA PROTO
    hWnd  : DWORD  //該消息框所屬窗口的句柄,爲0時,表示沒有所屬窗口
    lpText  : DWORD//待顯示字符串(結束符爲 0)的首地址指針
    lpCaption  : DWORD//消息框標題字符串(結束符爲0)的首地址指針; 爲0時顯示標題Error
    uType  : DWORD//指定消息框的樣式

返回值爲0表示沒有足夠的內存空間來創建該消息框
非0則表示用戶按下的按鈕號

該函數在屏幕上創建、顯示一個消息框,並在其中顯示各種字符串和多種圖標,還提供了多種可供選擇操作的按鈕。 參數uType指定了在消息框中要顯示哪些按鈕和圖標。 常用的按鈕選項有:

  • MB_OK:僅顯示確認按鈕,其值爲0
  • MB_OKCANCEL:同時顯示確認和取消按鈕,其值爲1
  • MB_YESNOCANCEL:同時顯示是、否和取消按鈕,其值爲3
顯示字符串
TextOut PROTO
    hdc : DWORD //設備上下文句柄
    nXStart  : DWORD//起始顯示位置的 X 座標
    nYStart : DWORD//起始顯示位置的 Y 座標
    lpString : DWORD//待顯示字符串的地址
    cbString : DWORD//串長度

該函數在顯示設備上下文句柄hdc代表的窗口中顯示lpString指示的存儲區中的字符串,字符串在窗口中的起始位置的座標爲nXStart, nYStart, 顯示的字符數由參數cbString決定。 若函數執行成功,則返回非0,否則返回0。 爲了得到指定窗口的hdc,在調用TextOut之前,必須先調用GetDC函數

GetDC PROTO
    hWnd : DWORD //指定窗口的句柄

該函數在執行成功時,返回指定窗口用戶區的設備上下文句柄hdc,否則返回0。

發送消息
SendMessage PROTO
    hWnd : DWORD//接收該消息的窗口的句柄
    uMsg : DWORD//指定要發送的消息,它是消息的標識符
    wParam : DWORD//第一個參數
    lParam : DWORD//第二個參數
  • 該函數把指定的消息發送給指定的窗口
  • 消息的標識符可以自定義,也可以使用系統預定義的

下面是幾個與編輯子窗口相關的預定義消息

  • WM_SETTEXT:用以設置窗口中的文字
  • WM_GETTEXT:把與一個窗口相聯繫的文字拷貝到由調用者提供的緩衝區中
  • WM_GETTEXTLENGTH:獲取與一個窗口相聯繫的文字的長度,以字符個數爲單位
發送退出消息
PostQuitMessage PROTO
    nExitCode : DWORD//退出碼
  • 該函數生成一個退出消息WM_QUIT並加入到所在程序的消息隊列中用以終止消息循環
  • 退出碼nExitCode將賦給WM_QUIT消息的wParam參數
  • 該函數沒有返回值
消息的缺省出來函數
DefWindowProc PROTO
    hWnd : DWORD//本窗口的句柄
    uMsg : DWORD//消息的標識符
    wParam : DWORD//第一個參數
    lParam : DWORD//第二個參數

該函數將本窗口接收但未處理的消息交給操作系統,由操作系統按照缺省的方法進行處理

文件操作

  • 對文件進行操作前,必須要打開或者創建,獲取該文件的句柄
  • 然後利用句柄和操作權限,進行讀寫,讀寫完後要關閉文件
打開和創建
CreateFile PROTO
    lpFileName                : DWORD//指向文件名字符串(結束符爲0)的指針
    dwDesiredAccess        : DWORD//訪問方式
    dwShareMode            : DWORD//共享方式
    lpSecurityAttributes       : DWORD//指向安全信息結構變量的指針
    dwCreationDistributions  : DWORD//創建方式
    dwFlagsAndAttributes     : DWORD//文件屬性
    hTemplateFile                : DWORD//模板文件句柄
  • 該函數打開或創建由lpFileName指向的字符串所描述的文件, 如果執行成功,則返回被打開文件的句柄; 否則返回INVALID_HANDLE_VALUE
  • 訪問方式可以是GENERIC_READ、GENERIC_WRITE、0(只允許獲取與文件有關的信息)
  • 共享方式用於控制該文件是否可以被多個程序同時打開和讀寫,取值爲0(不共享),FILE_SHARE_READ(共享讀),FILE_SHARE_WRITE(共享寫)
  • lpSecurityAttributes爲0時表示該文件不能被子進程繼承
  • 創建方式的值爲CREATE_NEW(創建新文件)、CREATE_ALWAYS(創建新文件,重寫已存在的文件)、OPEN_EXISTING(打開文件)、OPEN_ALWAYS(打開,若不存在則創建)、TRUNCATE_EXISTING(將現有文件縮短到0)
  • 文件屬性常用值:FILE_ATTRIBUTE_ARCHIVE(標記歸檔屬性)、FILE_ATTRIBUTE_HIDDEN(隱藏文件或目錄)、FILE_ATTRIBUTE_READONLY(只讀文件)、FILE_ATTRIBUTE_SYSTEM(系統文件)
  • hTemplateFile如果不爲零,則指定的是一個已經存在的文件句柄,本次創建的新文件將從這個模板文件中複製擴展屬性
關閉
CloseHandle PROTO
    hObject : DWORD//被關閉文件的句柄

調用後,如果EAX中的返回值爲非0,則表示成功,爲0則表示失敗

ReadFile PROTO
    hFile : DWORD//被讀文件的句柄
    lpBuffer : DWORD//用於保存讀入數據的存儲單元的指針
    nNumberOfBytesToRead : DWORD//待讀入的字節數
    lpnumberOfBytesRead : DWORD//從文件中實際讀入的字節數存放的地址
    lpOverlapped : DWORD//指向一個OVERLAPPED結構,用於說明一次異步讀取操作
WriteFile PROTO
    hFile : DWORD//被寫文件的句柄
    lpBuffer : DWORD//待寫數據的存儲區指針
    nNumberOfBytesToWrite : DWORD//待寫入的字節數
    lpnumberOfBytesWritten : DWORD//實際寫入文件的字節數量
    lpOverlapped : DWORD//指向一個OVERLAPPED結構,用於說明一次異步讀取操作
獲取文件長度
GetFileSize PROTO
    hFile : DWORD//文件的句柄
    lpFileSizeHigh : DWORD//指向一個變量,該變量用於存放文件大小的高位雙字

該函數檢取指定文件的字節大小

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章