Win32對話方塊程式(2)

來源:互聯網
上載者:User

標籤:des   style   blog   http   color   io   os   使用   ar   

接著Win32對話方塊程式(1)來寫 ,解決遺留的問題,即理解函數及其調用關係。文章中有些地方是自己的推斷,因此肯定有敘述不準確甚至錯誤的地方,請指正,感謝~ 

*******************************本文分割************************************

 

WinMain函數

Win32對話方塊程式(1)中說了WinMain是應用程式的入口,其輸入參數有四個,根據MSDN上的敘述:

輸入變數聲明 說明
HINSTANCE    hInstance 此應用當前執行個體的控制代碼 
HINSTANCE    hPrevInstance 此應用上一個執行個體的控制代碼,一般都是NULL
LPSTR    lpCmdLine The command line for the application, excluding the program name
int    nCmdShow 設定視窗的顯示方式,比如nCmdShow=SW_MAXIMIZE表示已最大化的視窗,詳見MSDN

因為WinMain是應用程式的入口,即程式啟動並執行第一個函數,所以這四個參數應該是作業系統傳給WinMain的,至於作業系統是怎麼把他們傳進來的,現在沒管[email protected][email protected]~    

何為控制代碼?何為執行個體?如果我們同時運行兩個記事本程式,我們會發現針對它們的不同操作是互不干擾的,這兩個“視窗”即使記事本的兩個執行個體,它們被載入在記憶體中的不同空間,但為了實現互不干擾的操作和處理,我們需要區分彼此,便使用控制代碼來標識應用程式的不同執行個體(兩個記事本的控制代碼不同),我們能通過控制代碼訪問相應對象的資訊,但控制代碼不是指標,程式不能利用控制代碼來直接閱讀檔案中的資訊,它只是一個唯一的整數值。 

lpCmdLine是不包含程式名的命令列,根據MSDN使用函數GetCommandLine()也可返回命令列字串,不過會包含程式名。為了驗證這個所謂的“命令列”是什麼,在WinMain函數體開頭加了兩行代碼將其顯示出來

 

12 MessageBox(NULL, GetCommandLine(), TEXT("CMDLINE"), MB_OK);MessageBox(NULL, lpCmdLine, TEXT("CMDLINE_1p"), MB_OK);

在VC6.0中運行,GetCommandLine()顯示為完整路徑包括程式名,lpCmdLine顯示為空白,如下:

於是我在命令列模式下運行

顯示出所謂的The command line for the application究竟是什麼,也許它可以用於向程式傳遞參數來進行互動式操作。

 

此外,入口函數名並不一定是WinMain,也可以是main(),但需要在main函數體內顯示的調用類似GetCommandLine()這樣的函數來引入WinMain的四個參數並作為變數(後面需要使用),此外還有_tWinMain(需進一步查閱)

現在大體理解了WinMain函數了,接下來看看其他函數都在幹什麼

 

函數及程式架構理解

先貼WinMain函數

12345678910 int APIENTRY WinMain(HINSTANCE hInstance,                     HINSTANCE hPrevInstance,                     LPSTR     lpCmdLine,                     int       nCmdShow){    //Enable IPAddress、Calendar.etc    InitCommonControls();    DialogBox(hInstance, MAKEINTRESOURCE(IDD_MAIN), NULL, Main_Proc);    return 0;}
函數名 參數 說明
InitCommonControls 無 該函數註冊並初始化通用控制項視窗類別,使用某些進階控制項時需要調用此函數,連結器會將你的程式連結到comctl32.lib,然後在程式啟動時,會載入comctl32.dll。(據MSDN,此函數已廢棄,需使用InitCommonControlsEx)
DialogBox (hInstance, MAKEINTRESOURCE(IDD_MAIN), NULL, Main_Proc)

據MSDN,該函數Creates a modal dialog box from a dialog box template resource,然後將控制權交給自訂的Main_Proc函數,此回呼函數通過調用EndDialog函數來終結the modal dialog box。

參數說明:參數1為包含The dialog box template的控制代碼,可以是NULL;參數2是The dialog box template,使用MAKEINTRESOURCE宏來講對話方塊ID(整數)轉化為resource type;參數3為A handle to the window that owns the dialog box;參數4為A pointer to the dialog box procedure,函數指標。 

 

MainDlg.cpp中包含四個函數:

函數名

參數

功能

Main_Proc

(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)

訊息分流器,進行訊息分流 

Main_OnInitDialog

(HWND hwnd, HWND hwndFocus, LPARAM lParam)

return

Main_OnCommand

(HWND hwnd, int id, HWND hwndCtl, UINT codeNotify)

switch(ID),case

Main_OnClose

(HWND hwnd)

 EndDialog

 

訊息分流器
1234567891011 BOOL WINAPI Main_Proc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam){    switch(uMsg)    {        HANDLE_MSG(hWnd, WM_INITDIALOG, Main_OnInitDialog);        HANDLE_MSG(hWnd, WM_COMMAND, Main_OnCommand);        HANDLE_MSG(hWnd, WM_CLOSE, Main_OnClose);    }     return FALSE;}

HANDLE_MSG也是一個宏,它在windowsx.h中定義,如下:

1 #define HANDLE_MSG(hwnd, message, fn) case (message): return HANDLE_##message((hwnd), (wParam), (lParam), (fn))

比如代碼

HANDLE_MSG(hWnd, WM_INITDIALOG, Main_OnInitDialog);

實際被替換為

case (WM_INITDIALOG): return HANDLE_WM_CREATE((hwnd), (wParam), (lParam), (Main_OnInitDialog))

可見,可見訊息分流器的作用就是當訊息出現時將控制權交給不同的程式,一些相關的參數也會同時傳給相應程式。 

如WM_INITDIALOG等為訊息,由作業系統傳遞給程式,根據MSDN,WM_INITDIALOG訊息是在對話方塊馬上要顯示前(即對話方塊記憶體中已經準備好了,但還沒有顯示在螢幕上)發給程式的,程式可以在此時執行一些初始化操作;同理,WM_COMMAND訊息和WM_CLOSE訊息從字面就基本可以理解。 

接下來把其他三個函數的代碼都貼在下面:

1234567891011121314151617181920212223 BOOL Main_OnInitDialog(HWND hwnd, HWND hwndFocus, LPARAM lParam){    return TRUE;} void Main_OnCommand(HWND hwnd, int id, HWND hwndCtl, UINT codeNotify){    switch(id)    {        case IDC_OK:        {                       MessageBox(hwnd,TEXT("歡迎"),TEXT("問好"),MB_OK);        }        break;        default:        break;    }} void Main_OnClose(HWND hwnd){    EndDialog(hwnd, 0);}

可見,Main_Proc函數是一直在執行中的,時刻等待作業系統傳遞訊息進來,根據不同訊息將控制權交予不同的函數,包括初始化和關閉函數,當然實現功能最主要的在函數Main_OnCommand中,對話方塊中有菜單和不同的控制項,通過ID對他們進行標示,如果使用者對他們進行了某種操作(比如單擊),則在Main_OnCommand函數體內進入相應的case,執行其中的代碼,如上,當點擊“確定”按鈕是會彈出“歡迎”對話方塊。

**********************************************************************************************

以上就是《C語言也能幹大事》中介紹的對話方塊程式的基本架構,當然,對話方塊程式應該是Windows編程中很簡單的,還有很多其他的內容需要學習,此外,學習windows編程很重要的一部分就是掌握儘可能多的API,萬丈高樓平地起,一步步來~

 

遺留問題

作業系統是如何向程式傳遞參數的(不急迫),即更深入的理解Windows的訊息傳遞機制;其他……

 

參考
  1. C語言也能幹大事http://rupeng.com/forum/forum-52-1.html

  2. WinMain和main http://blog.163.com/[email protected]/blog/static/99751486201212345130881/

  3. 訊息分流器http://www.cnblogs.com/ifaithu/articles/2478841.html

 

Win32對話方塊程式(2)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.