C語言Windows程序設計 -> 第十三天 -> 按鈕類控件


C語言Windows程序設計 -> 第十三天 -> 按鈕類控件



    終於到了令人激動的時刻, 盡管在前一階段的學習中我們已經學習了如何在客戶區中繪制簡單的圖形以及如何使用鍵盤和鼠標, 但是距離 Windows意義上的軟件 似乎還是有點遙遠, 而今天, 我們要做的就是將這個距離再縮短一大步! 這階段要學習的就是 子窗口控件 的使用。
    
    在其他一些 Windows應用軟件上我們經常能夠看到一些大致相同的按鈕、復選框、組合框、列表框等控件, 這些控件很有可能就是使用 標准子窗口控件 來實現的。
    
    
一、子窗口的創建
    在講解 "標准子窗口控件" 的使用之前我們首先應該知道如何去創建一個子窗口, 因為這些 "子窗口控件" 實際上都是通過創建一個子窗口的形式來進行創建的, 因此我們應該把理解的重點放在 "子窗口" 上, 而不是 "控件" 上。
    
    子窗口的創建可以將整個客戶區划分為多個矩形區域, 並且每個子窗口都可以有自己的句柄、窗口過程和客戶區, 每個子窗口過程只接收與自身窗口有關的鼠標消息、鼠標消息的參數 lParam 中包含的坐標是相對於 子窗口 客戶區的左上角的。簡單的說, 子窗口具有一個普通窗口的一切特性。
    
    子窗口的創建同樣是使用 CreateWindow 函數進行創建的, 下面我們通過一個示例來認識這個過程:
    代碼已折疊, 點擊展開:

View Code
 1 #include<windows.h>
 2 
 3 LRESULT CALLBACK WndProc( HWND, UINT, WPARAM, LPARAM ) ;
 4 LRESULT CALLBACK ChildWndProc( HWND, UINT, WPARAM, LPARAM ) ;        //子窗口窗口過程
 5 
 6 TCHAR szChildClass[] = TEXT("ChildClass") ;            //子窗口類名稱
 7 
 8 int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow )
 9 {
10     TCHAR szAppName[] = TEXT( "CreateChildWindow" ) ;
11 
12     HWND         hwnd ;
13     MSG          msg ;
14     WNDCLASS     wndclass ;
15 
16     wndclass.lpfnWndProc     = WndProc ;
17     wndclass.lpszClassName     = szAppName ;
18     wndclass.style             = CS_VREDRAW | CS_HREDRAW ;
19     wndclass.hInstance         = hInstance ;
20     wndclass.hCursor         = LoadCursor( NULL, IDC_ARROW ) ;
21     wndclass.hIcon             = LoadIcon( NULL, IDI_APPLICATION ) ;
22     wndclass.cbClsExtra     = 0 ;
23     wndclass.cbWndExtra     = 0 ;
24     wndclass.hbrBackground     = (HBRUSH) GetStockObject( WHITE_BRUSH ) ;
25     wndclass.lpszMenuName      = NULL ;
26 
27     if( !RegisterClass(&wndclass) )
28     {
29         MessageBox( NULL, TEXT("無法注冊窗口類!"), szAppName, MB_OK | MB_ICONERROR ) ;
30         return 0 ;
31     }
32 
33     wndclass.lpszClassName    = szChildClass ;
34     wndclass.cbWndExtra     = sizeof(long) ;
35     wndclass.lpfnWndProc    = ChildWndProc ;
36     RegisterClass( &wndclass ) ;        //注冊子窗口窗口類
37 
38     hwnd = CreateWindow( szAppName, TEXT("創建子窗口 - 演示"),
39         WS_OVERLAPPEDWINDOW, 
40         CW_USEDEFAULT, CW_USEDEFAULT,
41         800, 600,
42         NULL, NULL, hInstance, NULL ) ;
43 
44     ShowWindow( hwnd, iCmdShow ) ;
45     UpdateWindow( hwnd ) ;
46 
47     while( GetMessage(&msg, NULL, 0, 0) )
48     {
49         TranslateMessage( &msg ) ;
50         DispatchMessage( &msg ) ;
51     }
52 
53     return msg.wParam ;
54 }
55 
56 LRESULT CALLBACK WndProc( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam ) 
57 {
58     static HWND childHwnd ;        //子窗口句柄
59 
60     switch(message)
61     {
62     case WM_CREATE:        //在接收到 WM_CREATE 消息時創建一個子窗口
63         childHwnd = CreateWindow( szChildClass, TEXT("子窗口"),
64             WS_CHILDWINDOW | WS_VISIBLE | WS_OVERLAPPEDWINDOW,
65             10, 10,        //在父窗口客戶區(10, 10)位置創建一個子窗口
66             200, 200,    //子窗口的大小為200x200
67             hwnd,        //父窗口句柄
68             (HMENU)1,    //子窗口ID
69             (HINSTANCE) GetWindowLong(hwnd, GWL_HINSTANCE ),
70             NULL ) ;
71         return 0 ;
72 
73     case WM_DESTROY:
74         PostQuitMessage( 0 ) ;
75         return 0 ;
76     }
77     return DefWindowProc( hwnd, message, wParam, lParam ) ;
78 }
79 
80 LRESULT CALLBACK ChildWndProc( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam )
81 {
82     switch(message)
83     {
84     case WM_LBUTTONDOWN:        //處理子窗口的 WM_LBUTTONDOWN 消息
85         RedrawWindow(hwnd, NULL, NULL, RDW_INTERNALPAINT    );
86         MessageBox( hwnd, TEXT("鼠標左鍵在子窗口客戶區中按下!"), TEXT("子窗口消息"), MB_OK );
87         return 0 ;
88     }
89 
90     return DefWindowProc( hwnd, message, wParam, lParam ) ;
91 }

[ 代碼: Demo_01_CreateChildWindow.c ]

    盡管這段代碼有將近100行, 但是我相信有了前面的基礎, 這段代碼也是能夠輕松理解的。
    這段代碼演示的是在父窗口的(10, 10)位置處創建一個大小為 200x200 的子窗口, 效果如下:
   


    
    首先從整體上把握下這段代碼:
        第一步: 聲明父窗口回調函數和子窗口的回調函數:

        LRESULT CALLBACK WndProc( HWND, UINT, WPARAM, LPARAM ) ;
        LRESULT CALLBACK ChildWndProc( HWND, UINT, WPARAM, LPARAM ) ;        //子窗口窗口過程


        第二步: 定義WinMain函數, 在WinMain函數中建立父窗口的 wndclass 窗口類並注冊:

    if( !RegisterClass(&wndclass) )
    {
        MessageBox( NULL, TEXT("無法注冊窗口類!"), szAppName, MB_OK | MB_ICONERROR ) ;
        return 0 ;
    }

 
        第三步: 改變父窗口 wndclass 類中的部分屬性, 使其成為子窗口的 wndclass, 並注冊子窗口窗口類:

    wndclass.lpszClassName = szChildClass ;
    wndclass.cbWndExtra = sizeof(long) ;
    wndclass.lpfnWndProc = ChildWndProc ;
    RegisterClass( &wndclass ) ;        //注冊子窗口窗口類

 
        第四步: 顯示窗口、進入消息循環:

    ShowWindow( hwnd, iCmdShow ) ;
    UpdateWindow( hwnd ) ;

    while( GetMessage(&msg, NULL, 0, 0) )
    {
        TranslateMessage( &msg ) ;
        DispatchMessage( &msg ) ;
    }


        第五步: 定義父窗口回調函數 WndProc, 在處理 WM_CREATE 消息時創建子窗口:

    case WM_CREATE:        //在接收到 WM_CREATE 消息時創建一個子窗口
        childHwnd = CreateWindow( szChildClass, TEXT("子窗口"),
            WS_CHILDWINDOW | WS_VISIBLE | WS_OVERLAPPEDWINDOW,
            10, 10,        //在父窗口客戶區(0, 0)位置創建一個子窗口
            200, 200,    //子窗口的大小為0x0
            hwnd,        //父窗口句柄
            (HMENU)1,    //子窗口ID
            (HINSTANCE) GetWindowLong(hwnd, GWL_HINSTANCE ),
            NULL ) ;
        return 0 ;


        第六步: 定義子窗口回調函數 ChildWndProc:

    LRESULT CALLBACK ChildWndProc( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam )
    {
        switch(message)
        {
        case WM_LBUTTONDOWN:        //處理子窗口的 WM_LBUTTONDOWN 消息
            RedrawWindow(hwnd, NULL, NULL, RDW_INTERNALPAINT    );
            MessageBox( hwnd, TEXT("鼠標左鍵在子窗口客戶區中按下!"), TEXT("子窗口消息"), MB_OK );
            return 0 ;
        }

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

 



    一些細節把握:
        1>. 全局的子窗口類名
            在第四行中的代碼 TCHAR szChildClass[] = TEXT("ChildClass") ; 我們把子窗口類名稱設為全局這是因為在 WinMain 函數中和父窗口的回調函數中都需要用到它的名字。
            
        2>. 在注冊子窗口的窗口類時, 沒有再重新定義一個 WNDCLASS 類型的變量, 而是簡單的復用了一下父窗口中的 wndclass, 其中有3個成員與父窗口不同:
            lpszClassName, 即子窗口類的名稱 ;
            cbWndExtra 被設置成一個 long 型數據所占的存儲單元大小(4字節), 這個成員通知 Windows 在內部結構中給基於這個窗口類的每個窗口預留4個字節的額外存儲空間, 以用來給用戶為每個窗口保存不同的信息 ;
            lPfnWndProc 成員被設置成 ChildWndProc, 表示子窗口類的窗口過程 。
            
        3>. 創建子窗口時的 (HINSTANCE) GetWindowLong(hwnd, RDW_ERASE )
            實際上 CreateWindow 函數在創建子窗口時需要 hInstance 句柄, 而GetWindowLong函數的作用就是獲得有關指定窗口的信息, 函數也獲得在額外窗口內存中指定偏移位地址的32位度整型值, GetWindowLong的原型:
                LONG GetWindowLong( HWND hwnd, int nIndex ) ;
            nIndex 為索引值, 它可以是以下標識符之一:

                GWL_EXSTYLE            //獲得擴展窗口風格
                GWL_STYLE            //獲得窗口風格
                GWL_WNDPROC            //獲得窗口過程的地址
                GWL_HINSTANCE        //獲得應用事例的句柄
                GWL_HWNDPARENT        //獲得父窗口句柄
                GWL_ID                //獲得窗口標識
                GWL_USERDATA        //獲得與窗口有關的32位值。
                DWL_DLGPROC            //獲得對話框過程的地址, 或一個代表對話框過程的地址的句柄
                DWL_MSGRESULT        //獲得在對話框過程中一個消息處理的返回值
                DWL_USER            //獲得應用程序私有的額外信息

 


    在子窗口的窗口過程的處理上, 我們僅僅處理了一個 WM_LBUTTONDWON 消息, 當鼠標在子窗口客戶區中按下左鍵時就彈出一個對話框告訴用戶"鼠標左鍵在子窗口客戶區中按下!"。
    
    這些就是創建一個子窗口的演示。使用子窗口的程序設計有助於程序的結構化和模式化, 提高代碼的復用率。
    
    如果你已經將上面示例中的代碼理解的話, 那么恭喜你! 你已經又向成功邁向了一大步, 因為標准子窗口控件的使用比我們自己創建子窗口還要簡單!
    
   


二、使用標准子窗口控件的按鈕類
    按鈕類: 按鈕類不僅僅是指我們所常見的按鈕控件, 他是一類控件的統稱, 包括: 按鈕、復選框、單選按鈕、組合框。以創建一個按鈕作為示例, 創建一個按鈕並不需要我們再去定義一個WNDCLASS類再去注冊它, 也不需要再去為這個控件指定子窗口過程函數, 因為這些已經在一些相關的頭文件中給完成了, 我們只需要做相關的調用即可:

        case WM_CREATE:        //在接收到 WM_CREATE 消息時創建一個按鈕
        btnHwnd = CreateWindow( TEXT("button"), TEXT("創建按鈕"),
            WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,        //按鈕樣式
            10, 10,        //在父窗口客戶區(10, 10)位置創建一個按鈕
            100, 30,    //按鈕的大小為100x30
            hwnd,        //父窗口句柄
            (HMENU)1,    //按鈕控件ID
            (HINSTANCE) GetWindowLong(hwnd, GWL_HINSTANCE ),
            NULL ) ;
        return 0 ;

 

已折疊, 點擊展開全部:

View Code - CreateButton
 1 #include<windows.h>
 2 
 3 LRESULT CALLBACK WndProc( HWND, UINT, WPARAM, LPARAM ) ;
 4 
 5 int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow )
 6 {
 7     TCHAR szAppName[] = TEXT( "CreateChildWindow" ) ;
 8 
 9     HWND        hwnd ;
10     MSG            msg ;
11     WNDCLASS    wndclass ;
12 
13     wndclass.lpfnWndProc    = WndProc ;
14     wndclass.lpszClassName    = szAppName ;
15     wndclass.style            = CS_VREDRAW | CS_HREDRAW ;
16     wndclass.hInstance        = hInstance ;
17     wndclass.hCursor        = LoadCursor( NULL, IDC_ARROW ) ;
18     wndclass.hIcon            = LoadIcon( NULL, IDI_APPLICATION ) ;
19     wndclass.cbClsExtra        = 0 ;
20     wndclass.cbWndExtra        = 0 ;
21     wndclass.hbrBackground    = (HBRUSH) GetStockObject( WHITE_BRUSH ) ;
22     wndclass.lpszMenuName    = NULL ;
23 
24     if( !RegisterClass(&wndclass) )
25     {
26         MessageBox( NULL, TEXT("無法注冊窗口類!"), szAppName, MB_OK | MB_ICONERROR ) ;
27         return 0 ;
28     }
29 
30     hwnd = CreateWindow( szAppName, TEXT("創建按鈕 - 演示"),
31         WS_OVERLAPPEDWINDOW, 
32         CW_USEDEFAULT, CW_USEDEFAULT,
33         800, 600,
34         NULL, NULL, hInstance, NULL ) ;
35 
36     ShowWindow( hwnd, iCmdShow ) ;
37     UpdateWindow( hwnd ) ;
38 
39     while( GetMessage(&msg, NULL, 0, 0) )
40     {
41         TranslateMessage( &msg ) ;
42         DispatchMessage( &msg ) ;
43     }
44 
45     return msg.wParam ;
46 }
47 
48 LRESULT CALLBACK WndProc( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam ) 
49 {
50     static HWND btnHwnd ;        //子窗口句柄
51 
52     switch(message)
53     {
54     case WM_CREATE:        //在接收到 WM_CREATE 消息時創建一個按鈕
55         btnHwnd = CreateWindow( TEXT("button"), TEXT("創建按鈕"),
56             WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
57             10, 10,        //在父窗口客戶區(10, 10)位置創建一個按鈕
58             100, 30,    //按鈕的大小為100x30
59             hwnd,        //父窗口句柄
60             (HMENU)1,    //按鈕控件ID
61             (HINSTANCE) GetWindowLong(hwnd, GWL_HINSTANCE ),
62             NULL ) ;
63         return 0 ;
64 
65     case WM_DESTROY:
66         PostQuitMessage( 0 ) ;
67         return 0 ;
68     }
69     return DefWindowProc( hwnd, message, wParam, lParam ) ;
70 }

    [代碼: Demo_02_CreateButton.c]
    
    這樣就完成了一個按鈕的創建, 效果:
   


    盡管這個按鈕看起來還有一些問題, 比如為什么按鈕的風格那么難看, 以及按鈕上的文字也不怎么美觀, 沒關系, 這些都是可以解決的, 按鈕的風格問題等把標准控件學習完畢后一次性解決, 這里先把目前我們需要解決的事處理掉再關注這些。
    
    當嘗試點擊這個按鈕時只是覺得他向下凹了一下, 然后又恢復了, 好像什么也沒做一樣, 是的, 實際上他做了很多事情, 比如這個凹陷后又恢復的效果就是系統幫我們完成的, 慶幸的是這個效果是windows幫我們完成的, 要不然我們又要花費更多的代碼來完成這個效果。
    
    1>. 子窗口傳遞信息給父窗口
        如果我們要使用這個按鈕, 我們只需要捕獲這個按鈕向父窗口發送來的消息即可, 這個消息就是 WM_COMMAND, 每當用戶在子窗口上進行一些操作時, 系統就會像父窗口發來 WM_COMMAND 這個消息, 通過 wParam 和 lParam 中的值我們還可以進一步的了解用戶進行的是什么操作。
        WM_COMMAND 消息中 wParam 和 lParam 值含義如下:

LOWORD(wParam) 子窗口ID
HIWORD(wParam) 通知碼
lParam 子窗口句柄



            
        

 

    通知碼的意義就是進一步給出消息的意思, 這些通知碼

#define BN_CLICKED          0            //單擊
#define BN_PAINT            1            //被重繪
#define BN_HILITE           2            //被選擇
#define BN_UNHILITE         3            //高亮被移除
#define BN_DISABLE          4            //被禁用
#define BN_DOUBLECLICKED    5            //被雙擊
#define BN_PUSHED           BN_HILITE
#define BN_UNPUSHED         BN_UNHILITE
#define BN_DBLCLK           BN_DOUBLECLICKED
#define BN_SETFOCUS         6            //被設置焦點
#define BN_KILLFOCUS        7            //失去焦點

 


        實際上這些通知碼大部分我們不會用到, 起碼目前是這樣, 通知碼的6(BN_SETFOCUS) 和 7(BN_KILLFOCUS) 只有當按鈕樣式中包含 BS_NOTIFY 時才會被發送。
        如果要處理按鈕的一些消息, 只需像這樣做既可:

        case WM_COMMAND:
        switch(LOWORD(wParam))        //判斷子窗口ID, 根據子窗口ID做出不同響應
        {
        case 1:        //處理ID為1的子窗口消息
            switch(HIWORD(wParam))    //通過HIWORD(wParam)進一步判斷消息類型
            {
            case BN_CLICKED:        //處理的按下通知碼
                [進行相關的處理]
                break ;
            /*case 其他通知碼*/
            }
            break ;
        /*case 其他子窗口ID*/
        }
        return 0 ;

      
        一個示例: 處理按鈕的單擊消息:

      代碼已折疊, 點擊展開:

View Code
 1 #include<windows.h>
 2 
 3 LRESULT CALLBACK WndProc( HWND, UINT, WPARAM, LPARAM ) ;
 4 
 5 int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow )
 6 {
 7     TCHAR szAppName[] = TEXT( "CreateChildWindow" ) ;
 8 
 9     HWND        hwnd ;
10     MSG            msg ;
11     WNDCLASS    wndclass ;
12 
13     wndclass.lpfnWndProc    = WndProc ;
14     wndclass.lpszClassName    = szAppName ;
15     wndclass.style            = CS_VREDRAW | CS_HREDRAW ;
16     wndclass.hInstance        = hInstance ;
17     wndclass.hCursor        = LoadCursor( NULL, IDC_ARROW ) ;
18     wndclass.hIcon            = LoadIcon( NULL, IDI_APPLICATION ) ;
19     wndclass.cbClsExtra        = 0 ;
20     wndclass.cbWndExtra        = 0 ;
21     wndclass.hbrBackground    = (HBRUSH) GetStockObject( WHITE_BRUSH ) ;
22     wndclass.lpszMenuName    = NULL ;
23 
24     if( !RegisterClass(&wndclass) )
25     {
26         MessageBox( NULL, TEXT("無法注冊窗口類!"), szAppName, MB_OK | MB_ICONERROR ) ;
27         return 0 ;
28     }
29 
30     hwnd = CreateWindow( szAppName, TEXT("創建按鈕 - 演示"),
31         WS_OVERLAPPEDWINDOW, 
32         CW_USEDEFAULT, CW_USEDEFAULT,
33         800, 600,
34         NULL, NULL, hInstance, NULL ) ;
35 
36     ShowWindow( hwnd, iCmdShow ) ;
37     UpdateWindow( hwnd ) ;
38 
39     while( GetMessage(&msg, NULL, 0, 0) )
40     {
41         TranslateMessage( &msg ) ;
42         DispatchMessage( &msg ) ;
43     }
44 
45     return msg.wParam ;
46 }
47 
48 LRESULT CALLBACK WndProc( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam ) 
49 {
50     static HWND btnHwnd ;        //子窗口句柄
51 
52     switch(message)
53     {
54     case WM_CREATE:        //在接收到 WM_CREATE 消息時創建一個按鈕
55         btnHwnd = CreateWindow( TEXT("button"), TEXT("創建按鈕"),
56             WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
57             10, 10,        //在父窗口客戶區(10, 10)位置創建一個按鈕
58             100, 30,    //按鈕的大小為100x30
59             hwnd,        //父窗口句柄
60             (HMENU)1,    //按鈕控件ID
61             (HINSTANCE) GetWindowLong(hwnd, GWL_HINSTANCE ),
62             NULL ) ;
63         return 0 ;
64 
65     case WM_COMMAND:
66         switch(LOWORD(wParam))        //判斷子窗口ID, 根據子窗口ID做出不同響應
67         {
68         case 1:        //處理ID為1的子窗口消息
69             switch(HIWORD(wParam))    //通過HIWORD(wParam)進一步判斷消息類型
70             {
71             case BN_CLICKED:        //處理的按下通知碼
72                 MessageBox( hwnd, TEXT("按鈕被按下!"), TEXT("按鈕消息"), MB_OK ) ;
73                 break ;
74             }
75             break ;
76         }
77         return 0 ;
78 
79     case WM_DESTROY:
80         PostQuitMessage( 0 ) ;
81         return 0 ;
82     }
83     return DefWindowProc( hwnd, message, wParam, lParam ) ;
84 }

        [代碼: Demo_03_DealWithButtonMessage.c]
        
    2>. 父窗口傳遞信息給子窗口
        子窗口可以向父窗口發送消息, 父窗口同樣也可以向子窗口發送消息, 在 WINUSER.H 中定義了8個專用於按鈕的消息:

#define BM_GETCHECK        0x00F0            //獲取單選按鈕或復選框的狀態
#define BM_SETCHECK        0x00F1            //設置單選按鈕或復選按鈕的狀態
#define BM_GETSTATE        0x00F2            //獲取按鈕的狀態
#define BM_SETSTATE        0x00F3            //設置按鈕的狀態
#define BM_SETSTYLE        0x00F4            //設置按鈕樣式
#define BM_CLICK           0x00F5            //模擬用戶點擊一個按鈕
#define BM_GETIMAGE        0x00F6            //獲取按鈕圖片的句柄
#define BM_SETIMAGE        0x00F7            //設置按鈕的新圖像

        使用 SendMessage函數即可將這些消息發送給子窗口, SendMessage 函數原型:

  LRESULT SendMessage(
      HWND hWnd,            //子窗口句柄
      UINT Msg,            //消息
      WPARAM wParam,        //wParam值
      LPARAM lParam        //lParam值
  );

 




三、按鈕類中的更多成員
    要改變按鈕的樣式, 只需在創建子窗口時添加相關的按鈕樣式即可, 除了上面的演示的 BS_PUSHBUTTON 按鈕樣式, 還有更多的樣式如下:


    對這些按鈕的相關常用操作:
        1>. 按鈕(Push Button)
            BS_PUSHBUTTON 和 BS_DEFPUSHBUTTON 樣式的按鈕我們可以強制改變他的顯示狀態(正常或凹陷), 只需要向這個按鈕發送個消息改變他的狀態即可。
            將按鈕凹陷下去:

                SendMessage( btnHwnd, BM_SETSTATE, 1, 0 ) ;

 


            將按鈕正常顯示:

                SendMessage( btnHwnd, BM_SETSTATE, 0, 0 ) ;

 


            也可以通過一個 BM_GETSTATE 的消息獲取按鈕的當前狀態, 被按下時返回 TRUE, 沒有被按下時返回 FLASE。
            
        2>. 復選框(Check Box )
            ①. 將復選框前打勾

                SendMessage( btnHwnd, BM_SETCHECK, 1, 0 ) ;

               
            ②. 取消打勾

        SendMessage( btnHwnd, BM_SETCHECK, 0, 0 ) ;


            也可以通過一個 BM_GETCHECK 的消息獲取按鈕的當前狀態, 被打勾時返回 非0或TRUE, 沒有被打勾時返回 0或FLASE。
            
            BS_3STATEBS_3AUTOSTATE 類型的復選框還具有第三種狀態, 打的勾為灰色, 當 wParam 消息被設為2時這個類型的復選框就會被設為這種狀態。
            
        3>. 單選按鈕(Radio Button)
            單選按鈕的窗口樣式為 BS_RADIOBUTTONBS_AUTORADIOBUTTON, 后者只能用於對話框。單選按鈕沒有切換狀態, 當用戶按下一個單選按鈕時即使再次按下, 他的樣式也不會再變化, 使用 SendMessage 向單選按鈕發送消息可改變其中的標記:
            ①. 標記

                SendMessage( btnHwnd, BM_SETCHECK, 1, 0 ) ;

               
            ②. 取消標記

                SendMessage( btnHwnd, BM_SETCHECK, 0, 0 ) ;

 


            
    一些對窗口的通用操作(包括子窗口):
        1>. 改變按鈕文本
            通過調用 SetWindowText 可以改變按鈕中顯示的文本:
                SetWindowText( hwnd, pszString ) ;
                
            對於普通的窗口來說, 該函數能改變窗口標題欄中的文本, 而對於按鈕控件改變的即為顯示的文本。
            
        2>. 獲取窗口的當前文本
            iLength = GetWindowText( hwnd, pszBuffer, iMaxLength ) ;
            iMaxLength用來限制緩沖區 pszBuffer 所能接收的最長文字數量。
            
        3>. 隱藏窗口
            ShowWindow( hwndChild, SW_HIDE ) ;
            
        4>. 顯示窗口
            ShowWindow( hwndChild, SW_SHOWNORMAL ) ;
            
        5>. 判斷窗口是否可見
            IsWindowVisible( hwndChild ) ;
            非0為可見, 0為不可見。
            
        6>. 禁用窗口
            EnableWindow( hwndChild, FALSE ) ;
            禁用窗口后相關的控件的字符串將變成灰色, 表示不可用, 同時窗口也不再響應鼠標或鍵盤的輸入。
            
        7>. 啟用窗口
            EnableWindow( hwndChild, TRUE ) ;
            
        8>. 判斷窗口是否可用
            IsWindowEnabled( hwndChild ) ;
            啟用返回非0, 禁用返回0。
           

 

示例中的代碼下載: http://files.cnblogs.com/mr-wid/Learn_WinC_day_13.rar


--------------------



wid, 2012.12.10

 

上一篇: C語言Windows程序設計 -> 第十二天 -> 使用計時器

 


免責聲明!

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



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