使用MASM寫Windows程序,其實就是和Windows API打交道,而一個人是不可能記住所有的API用法的,所以API參考手冊是必不可少的,API的參考手冊中函數原型是按匈牙利表示法表示的,下面這個表就是API原型中那些前綴的詳細解釋
資料來源:MicroSoft MSDN Platform SDK 參考
為便于開發Windows應用程序,Windows的開發者新定義了一些數據類型。這些數據類型或是與C/C++中已有的數據類型同義,或是一些新的結構數據類型。引入這些類型的主要目的是為便于程序員開發Windows應用程序,同時也是為了增強程序的可讀性;另一個目的是為了便于程序將來能被移植到其它種類的計算機平臺上或適應Windows將來的新版本的變化。例如,本教程目前使用16位API(Application Program Interface),現在Windows的版本使用32位API,只要將HANDLE等句柄類型定義為32位長,然后重新編譯程序,就可以很方便地將一個使用16位API的Windows應用程序改為使用32位API的程序,使其能運行在32位API Windows上。大部分的數據類型在Windows.h中定義,下面是在這個文件中定義的部分類型:

  #define  PASCAL     pascal
  #define  NEAR      near
  #define  FAR       far
  typedef  unsigned char  BYTE
  typedef  unsigned short WORD
  typedef  unsigned long  DWORD
  typedef  long      LONG
  typedef  char       *PSTR
  typedef   char NEAR    *NPSTR
  typedef  char FAR    *LPSTR
  typedef  void      VOID
  typedef  int       *LPINT
  typedef  LONG      (PASCAL FAR * FARPROC)();


  在Windows.h中,使用typedef還定義了一些新的結構類型。這些結構類型的名字也使用大寫形式的標識符:

類型 說明 
MSG 消息結構 
WNDCLASS 窗口的類的結構 
PAINTSTRUCT 繪圖結構 
POINT 點的坐標的結構 
RECT 矩形結構 


       我們在這里以類型MSG為例來說明類型的定義方法,對于其它類型,在以后用到時再作詳細地說明。類型MSG是一個消息結構,它的定義方式及其各域的含義如下:

  typedef struct tagMSG {
     HWND     hWnd;  // 窗口對象的標識符,該條消息傳遞到它所標識的窗口上
     UINT    message;  // 消息標識符,標識某個特定的消息
     WPARAM   wParam;  // 隨同消息傳遞的16位參數
     LPARAM   lParam;  // 隨同消息傳遞的32位參數
     DWORD     time;  // 消息產生的時間
     POINT      pt;  // 產生消息時光標在屏幕上的坐標
  } MSG;
  typedef MSG FAR *LPMSG;


  其中的POINT類型的定義是:

  typedef struct tagPOINT {
    int x;     /* X坐標 */
    int y;    /* Y坐標 */
  } POINT;
  typedef POINT FAR *LPPOINT;


  Windows.h在定義大部分類型的同時,還定義了該類型的指針類型。例如,上例中的LPPOINT和LPMSG等,其中字母前綴LP表示遠指針類型;若使用NP作為一個類型的前綴,則表示近指針類型;若使用P作為一個類型的前綴時,則表示一般的指針類型,這時由編譯程序時所使用的內存模塊決定這種指針是遠指針或是近指針。在Windows.h中說明的大部分指針類型都采用這里介紹的方法進行說明,例如,LPRECT,它表示一個RECT類型的遠指針。
  在Windows.h中說明的大部分指針類型使用了C/C++的關鍵字const,如果一個指針類型的名字前綴為LPC、NPC或PC,則其中的字母C表示這種類型的指針變量所指向的變量不能通過該指針變量來修改,這種指針類型一般采用下述方法進行說明:

  typedef const POINT FAR * LPCPOINT;
  typedef const REC  FAR * LPCRECT;


  一個使用const修飾的指針(稱其為const指針)可以指向沒有使用const修飾的變量,但沒有使用const修飾的指針不能指向const修飾的變量,例如:

  const POINT pt;
  LPCPOINT lpPoint = &pt;
   // 正確
  LPPOINT  lpPoint = &pt;   // 錯誤

  當向函數傳遞參數時,必須特別注意這個問題,例如:

  void fun(LPPOINT lppt) ;
  ......
  LPCPOINT lpPoint ;
  fun(lpPoint) ;


  編譯器將指示這個函數調用語句是錯誤的。所以,在一個函數不修改一個指針參數所指向的變量的情況下,最好將該參數說明為const指針,使const類型的指針也能用于該函數的參數。Windows.h中說明的大部分函數使用了const指針參數。
  在Windows.h中,大多數語句是用于定義一個常量,例如:

  #denfine WM_QUIT 0X0012

  該語句用標識符WM_QUIT來表示編號為0X0012的消息。每個常量由一個前綴和表示其含義的單詞組成的標識符組成,兩者之間用下畫線隔開。前綴表明這些常量所屬的一般范疇。下面是一些前綴和它們所屬的范疇的說明。

類型 說明 
CS 窗口類的風格(Class Style) 
IDI 預定義的圖標對象的標識符(IDentity of Icon) 
IDC 預定義的光標對象的標識符(IDentity of Cursor) 
WS 窗口的風格(Windows Style) 
CW 創建窗口(Create Windows) 
WM 窗口消息(Windows Message) 
DT 繪制文本(Drawing Text) 

        在變量名的表示方法方面,Windows推薦使用一種稱為“匈牙利表示法”的方法。每個變量名用小寫字母或描述了變量的數據類型的字母作為前綴,變量的名字緊跟其后,且用大寫字母開始的單詞(一個或多個單詞)表示其含義,這樣每個變量都能附加上其數據類型的助記符。例如:

  WORD wOffset ;  /* w表示WORD類型 */
  DWORD dwValue ;  /* dw表示DWORD類型 */

  下面是Windows中常使用的一些字母前綴和它們所代表的數據類型:

類型 說明 
b BOOL,布爾類型 
by BYTE類型 
c char類型 
dw DWORD類型 
fn 函數類型 
i 整型 
l LONG類型 
lp 遠(長)指針(
long pointer) 
n 短整型 
np 近(短)指針(near pointer) 
p 指針 
s 字符串 
sz 以
'\0'結尾的字符串 
w WORD類型 
short,用于表示X坐標時 
short,用于表示Y坐標時 



        Windows程序員也可以根據上述思想和使用目的,發明一些其他的前綴,但要注意,對這些前綴的使用必須保持前后一致。在Windows中,所有的函數根據其用途來命名,它們一般由2到3個英文單詞組成,每個單詞的第一個字母大寫,例如,函數CreateWindow(),由該函數的名字可以知道它的用途是創建一個窗口。

比如說API函數CreateWindowsEx,API原型如下:

HWND CreateWindowEx(
DWORD dwExStyle, 
// extended window style
LPCTSTR lpClassName, // pointer to registered class name
LPCTSTR lpWindowName, // pointer to window name
DWORD dwStyle, // window style
int x, // horizontal position of window
int y, // vertical position of window
int nWidth, // window width
int nHeight, // window height
HWND hWndParent, // handle to parent or owner window
HMENU hMenu, // handle to menu, or child-window identifier
HINSTANCE hInstance, // handle to application instance
LPVOID lpParam // pointer to window-creation data
);


那么根據上述前綴表可以得出,dwExStyle需要一個雙字值,lpClassName與lpWindowName需要一個指向字符串的長指針(在MASM中則是偏移地址),x、y表示需傳遞整數值,nWidth與nHeight表示傳遞短整數,hWndParent表示需要一個窗口句柄,hMenu表示傳遞一個菜單句柄,hInstance表示傳遞的是程序實例句柄,lpParam表示可以傳遞長指針(地址)。
注意看前綴時請不要看前面的類型說明符,而是要看詞的前綴,如DWORD dwExStyle,只需要看dwExStyle就知道傳遞的是雙字數。
另外還有其它的組合,只要稍注意就能行,比如說lpfn表示指向函數的長指針,在MASM中則是一個函數的地址,,還有像lpSecurityAttributes之類的,則是指向SECURITY_ATTRIBUTES結構的長指針(地址),lpvBuffer表示傳遞一個緩存(Buffer)長指針(lp)或者為空(void),還有一些沒有前綴的則是這個詞已經足夠說明它的意思了。等等,熟悉這些前綴的含義可以讓你在學習API的時候進行快速的掌握。并能排除一些錯誤。

為了更好的了解WINDOWS編程,這里我必須介紹幾個基本的概念:
1,句柄:它是WINDOWS編程的基礎。一個句柄是指WINDOWS在內存中使用的一個唯一的整數質,是一個4個字節長的數值,用于標識應用程序中不同對象和相同對象的不同實例。

這里我列出幾種WINDOWS常用的句柄:

HWND: 標示窗口句柄
HINSTANCE:標示當前實例句柄
HCOURSOR:標示光標句柄
HFONT: 標示字體句柄
HPEN:標示畫筆句柄
HBRUSH:標示畫刷句柄
HDC:標示設備環境句柄
HB99vMP:標示位圖句柄
HICON:標示圖標句柄
HMENU:標示菜單句柄
HFILE:標示文件句柄

由于WINDOWS應用程序利用WINDOWS消息來與其它的WINDOWS應用程序及WINDOWS系統進行消息交換。所以消息是一個十分重要的對象它的結構如下。

typedef struct{
  HWND hwnd;     //檢索消息的窗口句柄
  UN99v message;  //代表一個消息的消息質
  WPARAM wParam; //消息附加信息的字參數
  LPARAM lParam; //消息附加信息的長字參數
  DWORD time;    //消息入隊時間
  POINT pt;      //消息發送時鼠標的位置 point.x;point.y;
} tagMSG;

2,消息:VC++中消息都用前綴標示消息所屬的分類,下面我來介紹一下這些前綴

BM表示按鈕控制消息
CB表示組合框控制消息
DM表示默認下壓式按鈕控制消息
EM表示編輯控制消息
LB表示列表框控制消息
SBM表示滾動條控制消息
WM表示窗口消息

現在我來對系統常用的一些消息進行說明:
1,WM_LBUTTONDOWN: 單擊鼠標左鍵時產生
2,WM_LBUTTONUP: 放開鼠標左鍵時產生
3,WM_RBUTTONUP: 放開鼠標右鍵時產生
4,WM_LBUTTONBLCLK: 雙擊鼠標左鍵時產生
5,WM_RBUTTONBLCLK: 雙擊鼠標右鍵時產生
6,WM_KEYDOWN: 按下了一個非系統鍵時產生的消息
7,WM_CHAR: 同上
8,WM_CREATE: 由CreateWindow函數發出的消息
9,WM_DESTROY: 消除窗口時發出的消息
10,WM_QU99v: 退出程序時發送的消息
11,WM_PAINT: 做任何移動操作時發出的消息

介紹了以上的這些基礎入門知識,我們就可以簡單的了解一下WINDOWS API 程序的組成基本結構。它是由入口函數WinMain和窗口函數基本框架,并包含各種數據類型、數據結構與函數等應用組建組成的。其中入口函數WinMain和窗口函數是WINDOWS應用程序的主體。

一個基本的WinMain函數應該具有以下的功能:
1,注冊窗口類,建立窗口及執行其他必要的初始化工作
2,進入消息循環,根據從應用程序消息隊列接受的消息,調用相應的處理過程。
3,當消息循環檢索到WM_QU99v消息時中止程序運行
WinMain函數有三個基本組成部分:函數說明、初始化和消息循環。

(1)函數說明

int WINAPI WinMain
(
HINSTANCE hThisInst, //應用程序當前實例句柄
HINSTANCE hPrevInst, //應用程序其它實例句柄
LPSTR lpszCmdLine,   //指向程序命令行參數的指針
int nCmdShow         //應用程序開始執行時窗口顯示方式的整數值標示
)

(2)初始化
初始化包括窗口類的定義、注冊、創建窗口實例和顯示窗口四部分。(在以后的程序中我將詳細的介紹它們具體的實現方法)

(3)消息循環
WINDOWS應用程序的運行是以消息為核心的。WINDOWS將產生的消息放入應用程序的消息隊列中,而應用程序的WinMain函數從消息循環提取隊列中的消息,并將其傳遞給窗口函數的相應過程處理。

它的基本寫法如下:

MSG Meg;//定義消息
//(...)省略了一些內容
while (GetMessage(&Meg,NULL,0,0)
{
  TranslanteMessage(&Meg);
  DispatchMessage(&Meg);
}