Win32對話框程序(2)


接着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的,至於操作系統是怎么把他們傳進來的,現在沒管~@_@~    

何為句柄?何為實例?如果我們同時運行兩個記事本程序,我們會發現針對它們的不同操作是互不干擾的,這兩個“窗口即使記事本的兩個實例,它們被加載在內存中的不同空間,但為了實現互不干擾的操作和處理,我們需要區分彼此,便使用句柄來標識應用程序的不同實例(兩個記事本的句柄不同),我們能通過句柄訪問相應對象的信息,但句柄不是指針,程序不能利用句柄來直接閱讀文件中的信息,它只是一個唯一的整數值。 

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

 

1
2
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函數

1
2
3
4
5
6
7
8
9
10
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

 

消息分流器

1
2
3
4
5
6
7
8
9
10
11
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消息從字面就基本可以理解。 

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
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/hanyinlong@126/blog/static/99751486201212345130881/

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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM