《Windows編程零基礎》__2 一個完整的程式

來源:互聯網
上載者:User
Windows開發的常識1)視窗Windows中最基本的概念也許就是視窗了,每一個前景程式都至少有一個視窗,一個視窗也是你可以看到的部分,比如,QQ有如下的登入視窗基本上你在Windows中可見的都是一個視窗,視窗也是Windows中用於使用者直接互動的基本元素(GUI程式)。2)控制代碼視窗、檔案、socket、訊號量、管道、郵槽(mailslot)……都是Windows平台中的基本對象,為了操作這些對
象,我們需要一個能夠引用這些對象的東西,這個引用這些對象的東西就是控制代碼(Handle)。控制代碼對於資源就像遙控器對於電視機,用遙控器能更好地操作電視機而不用關心內部實現的細節,控制代碼也是這樣的,用控制代碼你能更好地操作Windows對象,而不需要關係其內部的實現細節。事實上,你想操作Windows對象也只能通過控制代碼操作。比如,你想操作一個線程,你看看SuspendThread的原型如下所示:(第一個參數就是一個線程控制代碼)
SyntaxDWORD WINAPI SuspendThread(  __in  HANDLE hThread);

又比如,你想讀一個檔案,其函數ReadFile的原型如下:(第一個參數就是一個檔案的控制代碼。)

BOOL WINAPI ReadFile(  __in         HANDLE hFile,  __out        LPVOID lpBuffer,  __in         DWORD nNumberOfBytesToRead,  __out_opt    LPDWORD lpNumberOfBytesRead,  __inout_opt  LPOVERLAPPED lpOverlapped);

…………類似的例子還有很多,基本上想操作Windows對象都需要指向它們的控制代碼,控制代碼在語義上與C中的指標一樣,但是,文法上是完全不一樣的。
3)進程一些作業系統教材上對進程的定義為:進程是一個程式的一次運行過程。這個定義其實是對的,但是,也是錯的,為什麼呢?在Windows之前還有許多其它的作業系統,比如OS 360、UNIX……進程的概念提出來的時候Windows 還根本沒出生呢。不過,在Windows中,進程的概念完全不是這樣的,在Windows裡面,進程是程式隔離的基本單元,每一個32位應用程式在自己的進程空間裡面運行,進程只為這個程式提供4G的虛擬位址空間,並且,不同的進程之間互相不干擾(當然,後面會講到,進程之間會通訊)。4)線程在Windows裡面,真正運行程式的其實是線程,線程在進程提供的4G虛擬位址空間裡面運行,它執行PE檔案的.text段。也就是說,線程才是真正的執行體。基本的正常的Windows程式碼建立一個工程,還是按照上次的方法,在上一節裡面有,然後輸入以下代碼:

#include <windows.h>LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow){    static TCHAR szAppName[] = TEXT ("BossJue");    HWND         hwnd;    MSG          msg;    WNDCLASSEX   wndclassex = {0};    wndclassex.cbSize        = sizeof(WNDCLASSEX);    wndclassex.style         = CS_HREDRAW | CS_VREDRAW;    wndclassex.lpfnWndProc   = WndProc;    wndclassex.cbClsExtra    = 0;    wndclassex.cbWndExtra    = 0;    wndclassex.hInstance     = hInstance;    wndclassex.hIcon         = LoadIcon (NULL, IDI_APPLICATION);    wndclassex.hCursor       = LoadCursor (NULL, IDC_ARROW);    wndclassex.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH);    wndclassex.lpszMenuName  = NULL;    wndclassex.lpszClassName = szAppName;    wndclassex.hIconSm       = wndclassex.hIcon;    if (!RegisterClassEx (&wndclassex))    {        MessageBox (NULL, TEXT ("RegisterClassEx failed!"), szAppName, MB_ICONERROR);        return 0;    }    hwnd = CreateWindowEx (WS_EX_OVERLAPPEDWINDOW,                   szAppName,                   TEXT ("WindowTitle"),                  WS_OVERLAPPEDWINDOW,                  CW_USEDEFAULT,                   CW_USEDEFAULT,                   CW_USEDEFAULT,                   CW_USEDEFAULT,                   NULL,                   NULL,                   hInstance,                  NULL);       ShowWindow (hwnd, iCmdShow);    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){static const LPTSTR text = TEXT("Hello,World");    HDC hdc;    PAINTSTRUCT ps;    switch (message)    {    case WM_CREATE:        return (0);    case WM_PAINT:        hdc = BeginPaint (hwnd, &ps);        TextOut (hdc, 0, 0, text, lstrlen(text));        EndPaint (hwnd, &ps);        return (0);    case WM_DESTROY:        PostQuitMessage (0);        return (0);    }    return DefWindowProc (hwnd, message, wParam, lParam);}
運行

按下Ctrl + F5,你可能會碰到如下的連結錯誤:
不要急,這個錯誤的設定是因為Windows把這個程式當作console程式,而console程式預設入口函數是main,而我們在這裡面並沒有定義main,而是定義了一個叫WinMain的入口函數,所以連結器不認,而我們希望的卻是編譯器認為我們這個程式是一個GUI程式,GUI程式的入口函數是WinMain(如果你用#pragma
comment(linker…………)修改的話當然也是可以的,這種方法我在第一章裡面就寫到了。當然,我們還可以直接在Visual Studio IDE裡面直接設定,方法是開啟項目屬性,然後如下設定:這樣設定之後,再按Ctrl + F5,有沒有看到如下的一個視窗呢?對,就是這樣,你看到的就是一個正常的Windows程式的編寫。代碼解釋編寫Windows程式的過程編寫一個Windows程式,你需要做的是三步,第一步是註冊一個視窗類別,第二步是建立視窗,第三步是編寫訊息響應函數。其中第一步和第二步是基本固定的,除了個別的參數需要自己調整之外,最重要的是第三步,一個Windows程式中,代碼量最大的基本都在第三步。在Windows應用程式裡面,如果我們想要接收使用者的輸入、在視窗上面顯示一些資訊……我們都需要處理相關的訊息,Windows把與這個程式相關的事件都以訊息告訴程式,至於怎麼處理這些訊息,則是我們自己的事情。上面的RegisterClassEx
(&wndclassex)其實就是註冊視窗類別CreateWindowEx (WS_EX_OVERLAPPEDWINDOW, 
                 szAppName, 
                 TEXT ("WindowTitle"),
                 WS_OVERLAPPEDWINDOW,
                 CW_USEDEFAULT, 
                 CW_USEDEFAULT, 
                 CW_USEDEFAULT, 
                 CW_USEDEFAULT, 
                 NULL, 
                 NULL, 
                 hInstance,
                 NULL); 其實就是建立視窗,LRESULT CALLBACK WndProc (HWND hwnd, UINT message,WPARAM wParam, LPARAM lParam)其實就是那個訊息處理函數,只不過,這個訊息處理函數不需要我們自己調用,當有訊息的時候,Windows會自己調用這個函數來處理,我們只需要編寫處理代碼,但是,編寫的代碼不需要我們自己手動調用(這也許就是Callback函數的原因)。剩下的剩下的如果還有不懂的自己可以讀msdn,比如,對CreateWindow不熟悉,可以直接在MSDN裡面搜尋CreateWindow,MSDN不僅會告訴你這個函數怎麼用,還會告訴你訊息迴圈是什麼之類的,在此我就不仔細展開說明了。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.