子視窗及其相關

2021-04-19 05:24:12 字數 4173 閱讀 6724

建立子視窗

btnlook

定義了乙個叫做button的結構,它包括了按鈕視窗樣式和描述性字串,它們對應於10個按鈕型態,所有按鈕視窗樣式都以字母「bs」開頭,它表示「按鈕樣式」。10個按鈕子視窗是在wndproc中處理wm_create訊息的過程中使用乙個for迴圈建立的。createwindow呼叫使用下面這些引數:

class name

(類別名稱)

window text

(視窗文字)

window style

(視窗樣式)

x position

(x位置)

y position

(y位置)

width

(寬度)

height

(高度)

parent window

(父視窗)

child window id

(子視窗id)

instance handle

(執行實體控制代碼)

extra parameters

(附加引數)

text ("button")

button[i].sztext

ws_child | ws_visible | button[i].istyle

cxchar

cychar * (1 + 2 * i)

20 * xchar

7 * ychar / 4

hwnd

(hmenu) i

((lpcreatestruct) lparam) -> hinstance

null

類別名稱引數是預先定義的名字。視窗樣式使用ws_child、ws_visible以及在button結構中定義的10個按鈕樣式之一(bs_pushbutton、bs_defpushbutton等等)。視窗文字引數(對於普通視窗來說,它是顯示在標題列中的文字)將在每個按鈕上顯示出來。我簡單地使用標識按鈕樣式文字的x位置和y位置引數,說明子視窗左上角相對于父視窗顯示區域左上角的位置。寬度和高度引數規定了每個子視窗的寬度和高度。請注意,我用的是getdialogbaseunits函式來獲得內定字型字元的寬度和高度。這是對話方塊用來獲得文字尺寸的函式。此函式傳回乙個32位的值,其中低字組表示寬度,高字組表示高度。由於getdialogbaseunits傳回的值與從gettextmetrics獲得的值大致上相同,但getdialogbaseunits有時使用起來會更方便些,而且能夠與對話方塊控制項更好地保持一致。

對每個子視窗,它的子視窗id引數應該各不相同。在處理來自子視窗的wm_command訊息時,id幫助您的視窗訊息處理程式識別出相應的子視窗。注意子視窗id是作為createwindow的乙個引數傳遞的,該引數通常用於指定程式的選單,因此子視窗id必須被強制轉換為hmenu。

createwindow

呼叫的執行實體控制代碼看起來有點奇怪,但是它利用了如下的事實,亦即在處理wm_create訊息的過程中,lparam實際上是指向createstruct (「建立結構」)結構的指標,該結構有乙個hinstance成員。所以將lparam轉換成指向createstruct結構的乙個指標,並取出hinstance。

(有些windows程式使用名為hinst的整體變數,使視窗訊息處理程式能訪問winmain中的執行實體控制代碼。在winmain中,您只需在建立主視窗之前設定:

hinst = hinstance ;

可以用getwindowlong取得執行實體控制代碼:

getwindowlong (hwnd, gwl_hinstance)

這幾種方法都是正確的。)

在呼叫createwindow之後,我們不必再為這些子視窗做任何事情,由windows中的按鈕視窗訊息處理程式負責維護它們,並處理所有的重畫工作(bs_ownerdraw樣式的按鈕例外,它要求程式繪製它,這些將在後面加以討論)。在程式終止時,如果父視窗已經被清除,那麼windows將清除這些子視窗。

子視窗向父視窗發訊息

當您執行btnlook時,將看到在顯示區域的左邊會顯示出不同的按鈕型態。我在前面已經提到過,用滑鼠單擊按鈕時,子視窗控制項就向其父視窗傳送乙個wm_command訊息。btnlook攔截wm_command訊息並顯示wparam和lparam的值,它們的含義如下:

loword (wparam)

hiword (wparam)

lparam

子視窗id

通知碼子視窗控制代碼

如果您正在移植16位windows程式,那麼要注意改變這些訊息引數以容納32位的控制代碼。

子視窗id是在建立子視窗時傳遞給createwindow的值。在btnlook中,這些id被顯示在顯示區域中,並使用0到9分別標識10個按鈕。子視窗控制代碼是windows從createwindow傳回的值。

通知碼更詳細表示了訊息的含義。按鈕通知碼的可能值在windows表頭檔案中定義如下:

表9-1

按鈕通知碼識別符號

bn_clicked

0

bn_paint

1

bn_hilite or bn_pushed

2

bn_unhilite or bn_unpushed

3

bn_disable

4

bn_doubleclicked or bn_dblclk

5

bn_setfocus

6

bn_killfocus

7

實際上,您不會看到這些按鈕值中的大多數。從1到4的通知碼是用於一種叫做bs_userbutton的已不再使用的按鈕的(它已經由bs_ownerdraw和另一種不同的通知方式所替換)。通知碼6到7只有當按鈕樣式包括標識bs_notify才傳送。通知碼5只對bs_radiobutton、bs_autoradiobutton和bs_ownerdraw按鈕傳送,或者當按鈕樣式中包括bs_notify時,也為其它按鈕傳送。

您會注意到,在用滑鼠單擊按鈕時,該按鈕文字的周圍會有虛線。這表示該按鈕擁有了輸入焦點,所有鍵盤輸入都將傳送給子視窗按鈕控制項,而不是傳送給主視窗。但是,當該按鈕控制項擁有輸入焦點時,它將忽略所有的鍵盤輸入,除了spacebar鍵例外,此時spacebar鍵與滑鼠具有相同的效果。

父視窗向子視窗傳送訊息

雖然btnlook中沒有顯示這一事實,但是父視窗訊息處理程式也能向子視窗控制項傳送訊息。這些訊息包括以字首wm開頭的許多訊息。另外,在winuser.h中還定義了8個按鈕說明訊息;字首bm表示「按鈕訊息」。這些按鈕訊息如下表所示:

表9-2

按鈕訊息

bm_getcheck

0x00f0

bm_setcheck

0x00f1

bm_getstate

0x00f2

bm_setstate

0x00f3

bm_setstyle

0x00f4

bm_click

0x00f5

bm_getimage

0x00f6

bm_setimage

0x00f7

bm_getcheck

和bm_setcheck訊息由父視窗傳送給子視窗控制項,以取得或者設定核取方塊和單選按鈕的選中標記。bm_getstate和bm_setstate訊息表示按鈕處於正常狀態還是(滑鼠或spacebar鍵按下時的)「按下」狀態。我們將在討論按鈕的每種型態時,看到這些訊息是如何起作用的。bm_setstyle訊息允許您在按鈕建立之後改變按鈕樣式。

每個子視窗控制項都具有乙個在其兄弟中唯一的視窗控制代碼和id值。對於控制代碼和id這兩者,知道其中的乙個您就可以獲得另乙個。如果您知道子視窗控制項的視窗控制代碼,那麼您可以用下面的敘述來獲得id:

id = getwindowlong (hwndchild, gwl_id) ;

用此函式(與setwindowlong一起)來維護註冊視窗類別時保留的特殊區域的資料。在建立子視窗時,windows保留了gwl_id識別符號訪問的資料。您也可以使用:

id = getdlgctrlid (hwndchild) ;

雖然函式中的「dlg」部分指的是對話方塊,但實際上這是乙個通用的函式。

知道id和父視窗控制代碼,您就能獲得子視窗控制代碼:

hwndchild = getdlgitem (hwndparent, id) ;

C 中如何處理父視窗及其子視窗標題

因為在例子程式中 mainwindow 是唯一乙個訪問該字串的類,所以沒有必要使用屬性機制。有了這兩個新的資料成員,你要做的只是 改寫 wm gettext 處理例程,返回子視窗最大化狀態以及常態時的標題文字。那麼如何改寫 wm gettext 處理例程呢?windows.forms 提供了一些 處...

子視窗呼叫父視窗

相信學計算機的大學生都碰過這樣的程式設計作業吧 程式執行後主視窗隱藏,然後彈出登入框,輸入賬號密碼登陸成功後再關閉登陸框,然後讓之前隱藏的主視窗重新顯示。沒錯,我當時就是這麼笨,怎麼都想不到好的解決辦法 當時的同學都是不管之前隱藏的主視窗,而是直接新建了乙個主視窗 剛好昨晚在做專案時碰到類似的情況,...

Flink的滾動視窗 會話視窗 滑動視窗及其應用

flink作業中的視窗 是指一種對無限資料流設定有限資料集,從而實現了處理無線資料流的機制。視窗本身只是個劃分資料集的依據,它並不儲存資料。當我們需要在時間視窗維度上對資料進行聚合時,視窗是流處理應用中經常需要解決的問題。flink的視窗運算元為我們提供了方便易用的api,我們可以將資料流切分成乙個...