1. 程式人生 > >初級 WINDOWS API C++語言版 程式設計(轉)

初級 WINDOWS API C++語言版 程式設計(轉)

當我們使用著漂亮的介面,方便快捷的應用程式的時候。我們才會發現,以前曾編寫的程式是多麼的粗糙(TC編寫的程式)。簡單的介面,16色的顯示系統,大大的落後於計算機的發展。簡單的說就是殺雞用牛刀。如何該改變這種情況呢?Microsoft公司在推出windows作業系統的時候給出了簡單易行的解決方案。這就是WINDOWS平臺API應用程式介面。當然API也是發展的,它從WIN 16 API發展到了現在普遍使用的WIN 32 API。只有充分理解API函式功能和用法,才能深入到WINDOWS系統的內部,才能充分挖掘出作業系統給我們提供的強大功能。現在就讓我們放棄那DOS應用程式,進入WINDOWS程式設計的海洋之中吧。

要想了解WINDOWS API那麼我們必須先了解WINDOWS下的程式是如何進行驅動的。同學們可以很清楚的發現到,當你在使用WINDOWS記事本的時候,當鍵盤輸入字元的時候字就會出現在螢幕上。當你移動滑鼠的時候,游標就會在螢幕上移動。雙擊滑鼠、單擊滑鼠就會有相應的事件發生。這些都是由於WINDOWS具有的事件驅動的屬性造成的。比如說當你按下鍵盤的字元鍵的時候,訊息佇列就會向程式傳送WM_CHAR的訊息,如果你所寫的程式中含有處理這個訊息的函式,程式就會執行它。

為了更好的瞭解WINDOWS程式設計,這裡我必須介紹幾個基本的概念:
1,控制代碼:它是WINDOWS程式設計的基礎。一個控制代碼是指WINDOWS在記憶體中使用的一個唯一的整數質,是一個4個位元組長的數值,用於標識應用程式中不同物件和相同物件的不同例項。

這裡我列出幾種WINDOWS常用的控制代碼:

HWND: 標示視窗控制代碼
HINSTANCE:標示當前例項控制代碼
HCOURSOR:標示游標控制代碼
HFONT: 標示字型控制代碼
HPEN:標示畫筆控制代碼
HBRUSH:標示畫刷控制代碼
HDC:標示裝置環境控制代碼
HBITMP:標示點陣圖控制代碼
HICON:標示圖示控制代碼
HMENU:標示選單控制代碼
HFILE:標示檔案控制代碼

由於WINDOWS應用程式利用WINDOWS訊息來與其它的WINDOWS應用程式及WINDOWS系統進行訊息交換。所以訊息是一個十分重要的物件它的結構如下。

typedef struct{
  HWND hwnd;     //檢索訊息的視窗控制代碼
  UNIT 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_QUIT: 退出程式時傳送的訊息
11,WM_PAINT: 做任何移動操作時發出的訊息

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

一個基本的WinMain函式應該具有以下的功能:
1,註冊視窗類,建立視窗及執行其他必要的初始化工作
2,進入訊息迴圈,根據從應用程式訊息佇列接受的訊息,呼叫相應的處理過程。
3,當訊息迴圈檢索到WM_QUIT訊息時中止程式執行
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);
}


本人水平有限請大家見諒。


在上一篇中我著重介紹了WINDOWS API32程式的基本結構框架,您一定想完成自己的第一個WINDOWS程式吧?別忙我先向您介紹一下API的視窗函式,只有瞭解它您才能進行程式設計。

什麼是視窗函式呢?它又定義了什麼呢?視窗函式定義了應用程式對接受到的不同訊息的響應,其中包含了應用程式對各種可能接受到的訊息的處理過程,是訊息處理分支控制語句的集合。一般來說,視窗函式由一個或多個switch語句組成。每一個case語句對應一種訊息,當應用程式接受到一個訊息時,在視窗函式內的相應的case語句就會被啟用並執行相應的響應程式模組。

簡單的說視窗函式就是應用程式處理接受到的訊息的函式,其中包含了應用程式對各種可能接受到的有用的訊息的處理過程。

視窗函式的一般格式是這樣的:

LRESULT CALLBACK WndProc
( HWND hwnd,     //視窗控制代碼
  UNIT message,  //代表所處理訊息的訊息值
  WPARAM wParam, //訊息的附加引數(1)
  LPARAM lParam  //訊息的附加引數(2)
)
{
  ... //省略
  switch(message) //message為標識訊息的訊息值
  {
    case...
      ...
    break;
      ...
    case WM_DESTROY:
      PostQuitMessage(0);
    default:
      return DefWindowProc(hwnd,message,wParam,lParam);
  }
  return(0);
}

視窗函式主體內容是訊息處理語句,它由多個case語句組成。您只需要將視窗可能接收到的訊息在case語句中編寫相應的處理程式段就可以了。

在case語句的訊息處理程式段中一般都有對訊息WM_DESTROY的處理。這個訊息是關閉視窗時發出的。一般情況下,應用程式呼叫函式PostQuitMessage響應這條訊息。PostQuitMessage函式的定義如下:

void PostQuitMessage(int nExitCode); //nExitCode為應用程式退出程式碼

在處理case語句中不包含的資訊時我們用這個預設處理:

return DefWindowProc(hwnd,message,wParam,lParam);

來保證所有傳送到視窗的訊息都得到了應有的處理。

除了瞭解視窗函式的基本結構,我們還要掌握一些基本WINDOWS程式的資料結構

(1)MSG,前文已介紹過了
(2)WNDCLASS
結構WNDCLASS包含一個視窗類的全部資訊。應用程式通過定義一個視窗類來確定視窗的屬性。它的定義如下:

typedef struct tagWNDCLASS
{
  UNIT style;           //視窗的樣式,一般為0
  WNDPROC lpfWndProc;   //指向視窗函式的指標
  int cbClsExtra;       //分配在視窗類結構後的位元組數
  int cbWndExtra;       //分配在視窗例項後的位元組數
  HINSTANCE hInstance;  //定義視窗類的應用程式的例項控制代碼
  HICON hIcon;          //視窗類的圖示
  HCURSOR hCursor;      //視窗類的游標
  HBRUSH hbrBackground; //視窗類的背景刷
  LPCSTR lpszMenuName;  //視窗類的選單資源名
  LPCSTR lpszClassName; //視窗類名
} WNDCLASS;

現在我就可以教您寫出自己的第一個WINDOWS程式(點選此處下載)

#include <windows.h>

//視窗函式說明
LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);

//初始化視窗類
//WinMain函式說明
int WINAPI WinMain( HINSTANCE hInstance,HINSTANCE hPrevInst, LPSTR lpszCmdLine, int nCmdShow)
{
  HWND hwnd ;
  MSG Msg ;
  WNDCLASS wndclass ;
  char lpszClassName[] = "視窗";  //視窗類名
  char lpszTitle[]= "My_Windows"; //視窗標題名

  //視窗類的定義
  wndclass.style = 0;              //視窗型別為預設型別
  wndclass.lpfnWndProc = WndProc ; //視窗處理函式為WndProc
  wndclass.cbClsExtra = 0 ;        //視窗類無擴充套件
  wndclass.cbWndExtra = 0 ;        //視窗例項無擴充套件
  wndclass.hInstance = hInstance ; //當前例項控制代碼
  wndclass.hIcon = LoadIcon( NULL, IDI_APPLICATION) ;
  //視窗的最小化圖示為預設圖示
  wndclass.hCursor = LoadCursor( NULL, IDC_ARROW) ;
  //視窗採用箭頭游標
  wndclass.hbrBackground = GetStockObject( WHITE_BRUSH) ;
  //視窗背景為白色
  wndclass.lpszMenuName = NULL ;   //視窗中無選單
  wndclass.lpszClassName = lpszClassName ; //視窗類名為"視窗示例"

  //視窗類註冊
  if( !RegisterClass( &wndclass))  //如果註冊失敗則發出警告聲音
  {
    MessageBeep(0) ;
    return FALSE ;
  }

  //建立視窗
  hwnd=CreateWindow(lpszClassName, //視窗類名
    lpszTitle,                     //視窗例項的標題名
    WS_OVERLAPPEDWINDOW,           //視窗的風格
    CW_USEDEFAULT,
    CW_USEDEFAULT,                 //視窗左上角座標為預設值
    CW_USEDEFAULT,
    CW_USEDEFAULT,,                //視窗的高和寬為預設值
    NULL,                          //此視窗無父視窗
    NULL,                          //此視窗無主選單
    hInstance,                     //建立此視窗的應用程式的當前控制代碼
    NULL) ;                        //不使用該值

  //顯示視窗
  ShowWindow( hwnd, nCmdShow) ;
  //繪製使用者區
  UpdateWindow(hwnd);
  //訊息迴圈
  while(GetMessage(&Msg, NULL, 0, 0))
  {
    TranslateMessage(&Msg);
    DispatchMessage(&Msg);
  }

  return Msg.wParam; //訊息迴圈結束即程式終止時將資訊返回系統
}

//視窗函式
LRESULT CALLBACK WndProc(HWND hwnd,UINT message,WPARAM wParam, LPARAM lParam)
{
  switch(message)
  {
    case WM_DESTROY:
    PostQuitMessage(0); //呼叫PostQuitMessage發出WM_QUIT訊息

    default: //預設時採用系統訊息預設處理函式
    return DefWindowProc(hwnd,message,wParam,lParam);
  }
  return 0;
}

您的程式成功了嗎?在下一章我將向您介紹WINDOWS繪圖。

由於上一章的文章中我沒有向大家介紹清楚初試化的具體實現,造成很多的讀者無法很好的理解,這是我的失誤。本人現在補上,請大家原諒。

  一個Windows API程式的初始化主要分為為四個部分。1、視窗類的定義2、視窗類的註冊3、建立視窗例項4、顯示視窗

①視窗類定義
  在Windows應用程式中,視窗類定義了視窗的形式與功能。它的定義過程通過給視窗類資料結構WNDCLASS賦值來完成,這個資料結構包含視窗類的各個屬性。視窗類的定義常用到以下幾個函式,在這裡一一介紹。

1、LoadIcon函式
LoadIcon函式的作用是在應用程式中載入一個視窗圖示。它的原型為:

HICON LoadIcon
(
  HINSTANCE hInstance, //圖示資源所在的模組控制代碼;
              //如果使用NULL,就會使用系統預定義的圖示
  LPCTSTR lpIconName //圖示資源名或系統預定義的圖示標識名
)


2、LoadCursor函式
LoadCursor函式作用是在應用程式中載入一個視窗游標。它的原型為:


HCURSOR LoadCursor
(
  HINSTANCE hInstance,//游標資源所在的模組控制代碼;
              //如果使用NULL,它就會使用系統預定義的游標
  LPCTSTR lpCursorName//圖示資源名或系統預定義的游標標識名
)


3、GetStockObject函式
應用程式通過呼叫GetStockObject函式來獲取系統提供的背景刷,它的原型為:


HBRUSH GetStockObject(int nBrush);
//nBrush 為系統提供的背景刷標示名


②註冊視窗類
  Windows系統本身提供部分預定義的視窗類,我們也可以自己定義視窗類,視窗類必須先註冊後使用。視窗類註冊使用的函式是RegisterClass()實現。它的原型為:

RegisterClass(&wndclass);
//wndclass為視窗的類結構(前面第二篇文章已經介紹過了)


③建立視窗
  視窗註冊之後就要把它例項化,簡單的說就是建立一個視窗的例項。它是由函式CreateWindow()實現,函式的原型為:


HWND CreateWindow
(
  LPCTSTR lpszClassName,//視窗例項的類的名字
  LPCTSTR lpszTitle,    //視窗標題名
  DWORD dwStyle,    //新建立的視窗的樣式(後面將會詳細介紹)
  int x,          //視窗左上角的橫座標
  int y,          //視窗左上角的縱座標
  int nWidth,        //視窗的寬度
  int nHeight,       //視窗的高度
  HWND hwndParent,   //該視窗的父視窗的控制代碼
  HMENU hMenu,     //視窗主選單控制代碼
  HINSTANCE hInstance, //建立視窗的應用程式當前控制代碼
  LPVOID lpParam     //指向一個傳遞給視窗的引數值的指標
)


  那麼視窗的樣式有哪些呢?

標識 說明
WS_BORDER 建立一般帶邊框的視窗
WS_CAPTION 建立一個帶標題欄的視窗
WS_HSCROLL 建立一個帶水平滾動條的視窗
WS_MAXIMIZEBOX 建立一個帶最大化按鈕的視窗
WS_MINIMIZEBOX 建立一個帶最小化按鈕的視窗
WS_OVERLAPPED 建立一個帶邊框和標題欄的視窗
WS_OVERLAPPEDWINDOW 建立一個帶邊框、標題欄、系統選單及最大化、最小化按鈕的視窗
WS_POPUP 建立一彈出式視窗
WS_POPUPWINDOW 建立一帶邊框和系統選單的彈出式視窗
WS_SYSMENU 建立一帶系統選單的視窗
WS_VSCROLL 建立一帶垂直滾動條的視窗

  當然為了實現具有多種風格的視窗,WINAPI提供了“|”來表示並(∪)的意思。例如我們要實現一個即具有垂直滾動條又具有水平滾動條的彈出式視窗時可以輸入:WS_BSCOLL|WS_VSCROLL|WM_POPUP

④顯示視窗
  以上的操作均由函式實現,顯示視窗當然也不例外。視窗類的顯示由ShowWindow和UpdateWindow函式實現。應用程式呼叫ShowWindow函式在螢幕上顯示視窗,其形式為:


BOOL ShowWindow(hwnd,nCmdShow)
//其中hwnd為視窗控制代碼,nCmdShow為視窗顯示形式標識


nCmdShow共有六個可選值


標識 說明
SW_HIDE 隱藏視窗
SW_SHOWNORMAL 顯示並激活視窗
SW_SHOWMINIMIZE 顯示並最小化視窗
SW_SHOWMAXIMIZE 顯示並最大化視窗
SW_SHOWNOACTIVE 顯示但不啟用視窗
SW_RESTORE 恢復視窗原來的位置及尺寸

在視窗顯示之後,應用程式應使用UpdateWindow函式更新並繪製使用者區,併發出WM_PAINT訊息。它的形式為:


BOOL UpdataWindow(hwnd);
//hwnd為視窗控制代碼