三 Button控制項

2021-06-25 12:32:17 字數 4247 閱讀 4224

在建立視窗的時候,無論是createwindow()函式還是createwindowex()函式,所給定的第乙個引數就是乙個關於類名的字串。而這樣的乙個類名,在之前的程式裡都是在自行自行設定了wndclas***結構體變數後,註冊的視窗類。實際上,win32系統在建立視窗尋找參照的視窗類時,假如並沒有在程式區域性視窗類(程式設計師在應用程式中自行註冊的視窗類)中找到createwindowex()/createwindow()中指定類名的視窗類,會繼續從系統視窗類中查詢是否存在該視窗類。

一些常用的win32系統視窗類,如:button/edit/listbox/static/scrollbar等。

由於使用的是系統視窗類來建立視窗,所以不需要再註冊視窗類,直接建立視窗然後訊息迴圈。

int apientry winmain(hinstance hinstance,

hinstance hprevinstance,

lpstr lpcmdline,

int ncmdshow)

; while(getmessage(&msg,null,0,0))

return 0;

}

但是建立完成後可以發現,單擊按鈕是沒有任何的反應的,因為在button類中預設使用的訊息處理函式沒有對該訊息作出任何的響應,而訊息處理函式系統在建立button視窗型別的時候已經給定了。

所以在這裡需要用到另外乙個函式:

long setwindowlong(

hwnd hwnd, // handle of window

int nindex, // offset of value to set

long dwnewlong // new value

);

setwindowlong()可以更改一些在註冊視窗類時給定的引數值。但是其僅更改第乙個視窗控制代碼引數hwnd所指向的視窗例項的相應引數,而不是改動的整個視窗類的屬性。

其中nindex表示需要更改的引數型別,如訊息處理函式位址,則給定gwl_wndproc巨集。

dwnewlong表示需要改變的新值。

所以,在這只需要再寫乙個訊息處理函式:

wndproc g_oldbuttonproc=null;

lresult callback buttonproc(hwnd hwnd,uint umsg,wparam wparam,lparam lparam)

else if(umsg==wm_lbuttondown)

return callwindowproc(g_oldbuttonproc,hwnd,umsg,wparam,lparam);

}

然後在主函式中建立視窗與訊息迴圈中間加上

g_oldbuttonproc=(wndproc)setwindowlong(hwndbutton,gwl_wndproc,(long)buttonproc);

前面所提到的一些系統視窗類,如button、edit等,一般都叫作控制項。

而這類控制項又一般則不會像前一節一樣直接建立乙個視窗,而是以其他視窗的子視窗的形式出現。

所以一般來講控制項的建立一般都是在父視窗的wm_create訊息中所建立的:

void oncreate(hwnd hwnd,lparam lparam)

基本上引數的給定都與之前一般視窗的建立一致,而唯一要注意的兩處地方就是第四個引數視窗風格,以及倒數第三個引數預設選單控制代碼的給定。

首先來看風格。

由於該button控制項屬於主視窗的子視窗(所以父視窗引數也給定的是主視窗控制代碼hwnd),所以新增了ws_child屬性。

ws_visible使得該控制項可見。

而bs_pushbutton這樣的以bs(button style)開頭是button控制項的專用屬性,bs_pushbutton指的是按鈕視窗,其他的還有:

bs_radiobutton:單選按鈕;

bs_checkbox/bs_aotocheckbox:複選按鈕等等。

然後是預設選單控制代碼的給定。

這裡的給定很獨特。

是乙個完全隨意定義的整數常量(強轉為hmenu)。那是因為在控制項中,是已經不可能新增選單資源了的,所以這個引數在這裡是乙個復用,而其含義則不再表示選單資源控制代碼,表示的是控制項id。

所以在主視窗的wm_create訊息中呼叫上面的oncreate()函式即可建立ok按鈕。

然而建立以後情況與之前乙個樣,單擊按鈕不會有任何的響應。

同樣是因為我們沒有處理訊息處理函式。在這裡我們可以和前面一樣,利用setwindowlong()函式來更改ok按鈕的訊息處理函式。

但是在這裡,更為普遍也更為規範的做法是,處理主函式的wm_command訊息。

wm_command訊息用途很多,這裡是其中的乙個。

當對按鈕進行乙個單擊事件以後,按鈕的預設事件處理函式並非沒有做任何的事情。

在按鈕的單擊事件裡,向其父視窗發出了乙個wm_command訊息。

其中,wparam引數的低16位中記錄了該按鈕的id。

而lparam引數的高16位中記錄了事件的類別,如這裡的單擊則是bn_clicked。

所以需要在主視窗訊息處理函式的wm_command中新增下面函式的呼叫:

void oncommand(hwnd hwnd,wparam wparam,lparam lparam)

; getwindowtext((hwnd)lparam,sztext,sizeof(sztext)/sizeof(sztext[0]));

messagebox(hwnd,sztext,"ok",mb_ok);

} }}

#include#include#define idc_btn_ok		4001

lpcstr g_pszmainwndclass="main";

hinstance g_hinstance=null;

void oncreate(hwnd hwnd,lparam lparam)

void oncommand(hwnd hwnd,wparam wparam,lparam lparam)

; getwindowtext((hwnd)lparam,sztext,sizeof(sztext)/sizeof(sztext[0]));

messagebox(hwnd,sztext,"ok",mb_ok);

} }}lresult callback mainwndproc(hwnd hwnd,uint umsg,wparam wparam,lparam lparam)

return defwindowproc(hwnd,umsg,wparam,lparam);};

wcex.cbsize=sizeof(wcex);

wcex.style=cs_hredraw|cs_vredraw;

wcex.lpfnwndproc=mainwndproc;

wcex.cbcl***tra=0;

wcex.cbwndextra=0;

wcex.hinstance=hinstance;

wcex.hcursor=loadcursor(null,idc_arrow);

wcex.hbrbackground=getsyscolorbrush(color_3dface);

wcex.lpszmenuname=null;

wcex.lpszclassname=g_pszmainwndclass;

return registerclas***(&wcex);

}bool initinstance(hinstance hinstance,int ncmdshow)

int apientry winmain(hinstance hinstance,

hinstance hprevinstance,

lpstr lpcmdline,

int ncmdshow)

; while(getmessage(&msg,null,0,0))

return 0;

}

Button 控制項

button控制項又稱按鈕控制項,是 windows應用程式中最常用的控制項之一,通常用它來執行命令。如果按鈕具有焦點,就可以使用滑鼠左鍵 enter鍵或空格鍵觸發該按鈕的click事件。通過設定窗體的acceptbutton 或 cancelbutton 屬性,無論該按鈕是否有焦點,都可以使使用者...

Button 控制項

button控制項又稱按鈕控制項,是 windows應用程式中最常用的控制項之一,通常用它來執行命令。如果按鈕具有焦點,就可以使用滑鼠左鍵 enter鍵或空格鍵觸發該按鈕的click事件。通過設定窗體的acceptbutton 或 cancelbutton 屬性,無論該按鈕是否有焦點,都可以使使用者...

button控制項

要注意一點,一般都是用panel來裝其他的控制項,不用panel裝也可以,就是會非常醜 下圖就是直接把button放到frame裡的效果 完整 如下,包括按鍵觸發事件的關聯 import wxclass buttonframe wx.frame def init self,parent none,i...