使用資源—對話框—在對話框中使用子窗口控件
子窗口控件是一些Windows預(yù)定義類,它們實(shí)際上就是一個個以對話框?yàn)楦复翱诘淖哟翱?。對于程序員來說,在對話框中使用它們的時候并不需要手工去逐一創(chuàng)建,只需要在對話框中定義就可以了,“對話框管理器”會在初始化對話框的時候,根據(jù)定義語句自動建立所有的子窗口。
1、子窗口控件的定義
子窗口控件定義的一般語法是:
CONTROL 文本, ID, 類, 風(fēng)格, x, y, 寬度, 高度 [, 擴(kuò)展風(fēng)格]
“文本”指控件的初始化值,“ID”是子窗口向?qū)υ捒蜻^程發(fā)送WM_COMMAND中用的ID值,“類”可以是按鈕(Button)、靜態(tài)(Static)、編輯(Edit)、滾動條(ScrollBar)、列表框(ListBox)和組合框(ComboBox),這些類都是Windows系統(tǒng)中已經(jīng)預(yù)定義的,“對話框管理器”在初始化的時候把每一條控件定義語句轉(zhuǎn)換成下面的CreateWindow命令:
invoke CreateWindow, 類名, 文本, 風(fēng)格, x, y, 寬度, 高度, 對話框窗口句柄, ID,
hInstance, NULL
正因?yàn)槿绱?,所有可以?/span>CreateWindow建立的子窗口都可以在資源中定義,只要知道要使用的類和風(fēng)格就可以了。所以除了上面這些基本的類之外,對話框中還可以使用一些通用控件,如“日期”(SysDateTimePick32)、“月歷”(SysMonthCal32)、“熱鍵”(msctls_hotkey32)和“列表”(SysListView32)等,括號內(nèi)是它們的類名,只要把定義語句的“類”寫成對應(yīng)的名稱就可以了。
基于同一個預(yù)定義類的控件根據(jù)風(fēng)格屬性的不同,外表可能完全不同,如單選鈕、復(fù)選框和分組框使用的類都是Button類,文本、圖標(biāo)框、位圖框和線條等都是Static類。使用CONTROL語句定義的時候可能不是很直觀,所以Rc.exe資源編譯器允許使用另一種語法來書寫控件定義:
控件名稱 [文本,] ID, x, y, 寬度, 高度 [, 風(fēng)格] [, 擴(kuò)展風(fēng)格]
這里使用“控件名稱”而不是“類”是因?yàn)檫@個名稱只是Rc.exe使用的縮寫,并不是真正的Windows類的名稱,“控件名稱”由Rc.exe解釋成“類”名,同時為它使用了幾種默認(rèn)的風(fēng)格,定義語句中風(fēng)格屬性實(shí)際上是附加在默認(rèn)風(fēng)格上的,表5.4列出了每種控件使用的類和默認(rèn)屬性,除了表中列出的默認(rèn)屬性外,每種控件還被默認(rèn)定義了WS_CHILD和WS_VISIBLE屬性。
資源腳本中使用的控件名稱
控件名稱
|
說明
|
基于的類
|
默認(rèn)窗口風(fēng)格
|
PUSHBUTTON
|
按鈕
|
Button
|
BS_PUSHBUTTON, WS_TABSTOP
|
DEFPUSHBUTTON
|
默認(rèn)按鈕
|
Button
|
BS_DEFPUSHBUTTON, WS_TABSTOP
|
CHECKBOX
|
復(fù)選框
|
Button
|
BS_CHECKBOX, WS_TABSTOP
|
AUTOCHECKBOX
|
自動復(fù)選框
|
Button
|
BS_AUTOCHECKBOX, WS_TABSTOP
|
STATE3
|
3態(tài)復(fù)選框
|
Button
|
BS_3STATE, WS_TABSTOP
|
AUTO2STATE
|
自動3態(tài)復(fù)選框
|
Button
|
BS_AUTO3STATE, WS_TABSTOP
|
RADIOBUTTON
|
單選框
|
Button
|
BS_RADIOBUTTON, WS_TABSTOP
|
AUTORADIOBUTTON
|
自動單選框
|
Button
|
BS_AUTORADIOBUTTON, WS_TABSTOP
|
GROUPBOX
|
分組框
|
Button
|
BS_GROUPBOX
|
SCROLLBAR
|
滾動條
|
ScrollBar
|
SBS_HORZ
|
CTEXT
|
居中文本
|
Static
|
SS_CENTER, WS_GROUP
|
LTEXT
|
左對齊文本
|
Static
|
SS_LEFT, WS_GROUP
|
RTEXT
|
右對齊文本
|
Static
|
SS_RIGHT, WS_GROUP
|
ICON
|
圖標(biāo)框
|
Static
|
SS_ICON
|
EDITTEXT
|
文本編輯
|
Edit
|
ES_LEFT, WS_BORDER, WS_TABSTOP
|
COMBOBOX
|
組合框
|
ComboBox
|
CBS_SIMPLE, WS_TABSTOP
|
LISTBOX
|
列表框
|
ListBox
|
LBS_NOTIFY, WS_BORDER
|
看下面的例子:
GROUPBOX “選項(xiàng)”, -1, 55, 5, 120, 100
PUSHBUTTON “退出”, IDCANCEL, 255, 115, 50, 14
這兩條語句和下面的語句編譯后產(chǎn)生的二進(jìn)制資源文件是一模一樣的:
CONTROL “選項(xiàng)”, -1, “Button”, BS_GROUPBOX | WS_TABSTOP, 55, 5, 120, 100
CONTROL “退出”, IDCANCEL, “Button”, BS_PUSHBUTTON | WS_TABSTOP, 255, 115, 50, 14
第一種語句的用法比第二種語句不但要直觀許多,而且不必書寫默認(rèn)的窗口風(fēng)格。
當(dāng)用到的控件沒有縮寫語法時,那就必須用CONTROL定義了,下面的兩句分別定義了一條橫線和一個圖片框,它們并沒有縮寫的用法:
CONTROL “”, -1, “Static”, SS_ETCHEDHORZ | WS_CHILD | WS_VISIBLE, 60, 65, 110, 1
CONTROL BMP_ID, -1, “Static”, SS_BITMAP | WS_CHILD | WS_VISIBLE, 5, 5, 40, 95
下面以一個例子來演示各種子窗口控件的用法。
//Control.rc
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
#include <resource.h>
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
#define ICO_MAIN 0x1000 //圖標(biāo)
#define DLG_MAIN 0x1
#define IDB_1 1
#define IDB_2 2
#define IDC_ONTOP 101
#define IDC_SHOWBMP 102
#define IDC_ALOW 103
#define IDC_MODALFRAME 104
#define IDC_THICKFRAME 105
#define IDC_TITLETEXT 106
#define IDC_CUSTOMTEXT 107
#define IDC_BMP 108
#define IDC_SCROLL 109
#define IDC_VALUE 110
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
ICO_MAIN ICON "Main.ico"
IDB_1 BITMAP "Picture1.bmp"
IDB_2 BITMAP "Picture2.bmp"
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
DLG_MAIN DIALOG 193, 180, 310, 134
STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME
CAPTION "對話框子窗口控件示例"
FONT 9, "宋體"
{
GROUPBOX "選項(xiàng)", -1, 55, 5, 120, 100
AUTOCHECKBOX "總在最前面", IDC_ONTOP, 65, 20, 100, 12
AUTOCHECKBOX "顯示圖片", IDC_SHOWBMP, 65, 35, 100, 12
AUTOCHECKBOX "允許更換圖片", IDC_ALOW, 65, 50, 100, 12
CONTROL "", -1, "Static", SS_ETCHEDHORZ | WS_CHILD | WS_VISIBLE, 60, 65, 110, 1
AUTORADIOBUTTON "模態(tài)邊框(&Modal Frame)", IDC_MODALFRAME, 65, 70, 100, 12, WS_TABSTOP
AUTORADIOBUTTON "可變邊框(&Thick Frame)", IDC_THICKFRAME, 65, 85, 100, 12, WS_TABSTOP
GROUPBOX "標(biāo)題欄文字", -1, 180, 5, 125, 100, BS_GROUPBOX
COMBOBOX IDC_TITLETEXT, 190, 20, 105, 70, CBS_DROPDOWNLIST | WS_TABSTOP
LTEXT "自定義文字:", -1, 190, 40, 105, 10
EDITTEXT IDC_CUSTOMTEXT, 190, 55, 105, 12
LTEXT "請?jiān)诖诉x擇顯示在標(biāo)題欄上面的文字,或者選擇“自定義”后自行輸入", -1, 191, 73, 105, 26, WS_BORDER
CONTROL "", -1, "Static", SS_ETCHEDHORZ | WS_CHILD | WS_VISIBLE, 5, 110, 300, 1
DEFPUSHBUTTON "更換圖片(&C)", IDOK, 200, 115, 50, 14
PUSHBUTTON "退出(&X)", IDCANCEL, 255, 115, 50, 14
CONTROL IDB_1, IDC_BMP, "Static", SS_BITMAP | WS_CHILD | WS_VISIBLE, 5, 5, 40, 95
SCROLLBAR IDC_SCROLL, 6, 118, 125, 10
LTEXT "0" IDC_VALUE, 138, 119, 50, 8
}
//Control.asm
.386
.model flat, stdcall
option casemap :none
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Include 文件定義
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
include windows.inc
include user32.inc
includelib user32.lib
include kernel32.inc
includelib kernel32.lib
include gdi32.inc
includelib gdi32.lib
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Equ 等值定義
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
ICO_MAIN equ 1000h
DLG_MAIN equ 1
IDB_1 equ 1
IDB_2 equ 2
IDC_ONTOP equ 101
IDC_SHOWBMP equ 102
IDC_ALOW equ 103
IDC_MODALFRAME equ 104
IDC_THICKFRAME equ 105
IDC_TITLETEXT equ 106
IDC_CUSTOMTEXT equ 107
IDC_BMP equ 108
IDC_SCROLL equ 109
IDC_VALUE equ 110
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 數(shù)據(jù)段
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.data?
hInstance dd ?
hBmp1 dd ?
hBmp2 dd ?
dwPos dd ?
.const
szText1 db 'Hello, World!', 0
szText2 db '嘿,你看到標(biāo)題欄變了嗎?', 0
szText3 db '自定義', 0
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 代碼段
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.code
_ProcDlgMain proc uses ebx edi esi hWnd, wMsg, wParam, lParam
local @szBuffer[128]:byte
mov eax, wMsg
.if eax == WM_CLOSE
invoke EndDialog, hWnd, NULL
invoke DeleteObject, hBmp1
invoke DeleteObject, hBmp2
.elseif eax == WM_INITDIALOG
;*******************************************************************************
; 設(shè)置標(biāo)題欄圖標(biāo)
;*******************************************************************************
invoke LoadIcon, hInstance, ICO_MAIN
invoke SendMessage, hWnd, WM_SETICON, ICON_BIG, eax
;*******************************************************************************
; 初始化組合框
;*******************************************************************************
invoke SendDlgItemMessage, hWnd, IDC_TITLETEXT, CB_ADDSTRING, 0, addr szText1
invoke SendDlgItemMessage, hWnd, IDC_TITLETEXT, CB_ADDSTRING, 0, addr szText2
invoke SendDlgItemMessage, hWnd, IDC_TITLETEXT, CB_ADDSTRING, 0, addr szText3
invoke SendDlgItemMessage, hWnd, IDC_TITLETEXT, CB_SETCURSEL, 0, 0
invoke GetDlgItem, hWnd, IDC_CUSTOMTEXT
invoke EnableWindow, eax, FALSE
invoke LoadBitmap, hInstance, IDB_1
mov hBmp1, eax
invoke LoadBitmap, hInstance, IDB_2
mov hBmp2, eax
;*******************************************************************************
; 初始化單選鈕和復(fù)選框
;*******************************************************************************
invoke CheckDlgButton, hWnd, IDC_SHOWBMP, BST_CHECKED
invoke CheckDlgButton, hWnd, IDC_ALOW, BST_CHECKED
invoke CheckDlgButton, hWnd, IDC_THICKFRAME, BST_CHECKED
;*******************************************************************************
; 初始化滾動條
;*******************************************************************************
invoke SendDlgItemMessage, hWnd, IDC_SCROLL, SBM_SETRANGE, 0, 100
;*******************************************************************************
.elseif eax == WM_COMMAND
mov eax, wParam
.if ax == IDCANCEL
invoke EndDialog, hWnd, NULL
invoke DeleteObject, hBmp1
invoke DeleteObject, hBmp2
;*******************************************************************************
; 更換圖片
;*******************************************************************************
.elseif ax == IDOK
mov eax, hBmp1
xchg eax, hBmp2
mov hBmp1, eax
invoke SendDlgItemMessage, hWnd, IDC_BMP, STM_SETIMAGE, IMAGE_BITMAP, eax
;*******************************************************************************
; 設(shè)置是否“總在最前面”
;*******************************************************************************
.elseif ax == IDC_ONTOP
invoke IsDlgButtonChecked, hWnd, IDC_ONTOP
.if eax == BST_CHECKED
invoke SetWindowPos, hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE or SWP_NOSIZE
.else
invoke SetWindowPos, hWnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE or SWP_NOSIZE
.endif
;*******************************************************************************
; 演示隱藏和顯示圖片控件
;*******************************************************************************
.elseif ax == IDC_SHOWBMP
invoke GetDlgItem, hWnd, IDC_BMP
mov ebx, eax
invoke IsWindowVisible, ebx
.if eax
invoke ShowWindow, ebx, SW_HIDE
.else
invoke ShowWindow, ebx, SW_SHOW
.endif
;*******************************************************************************
; 演示允許和灰化“更換圖片”按鈕
;*******************************************************************************
.elseif ax == IDC_ALOW
invoke IsDlgButtonChecked, hWnd, IDC_ALOW
.if eax == BST_CHECKED
mov ebx, TRUE
.else
xor ebx, ebx
.endif
invoke GetDlgItem, hWnd, IDOK
invoke EnableWindow, eax, ebx
;*******************************************************************************
.elseif ax == IDC_MODALFRAME
invoke GetWindowLong, hWnd, GWL_STYLE
and eax, not WS_THICKFRAME
invoke SetWindowLong, hWnd, GWL_STYLE, eax
.elseif eax == IDC_THICKFRAME
invoke GetWindowLong, hWnd, GWL_STYLE
or eax, WS_THICKFRAME
invoke SetWindowLong, hWnd, GWL_STYLE, eax
;*******************************************************************************
; 演示處理下拉式組合框
;*******************************************************************************
.elseif ax == IDC_TITLETEXT
shr eax,16
;*******************************************************************************
.if ax == CBN_SELENDOK
invoke SendDlgItemMessage, hWnd, IDC_TITLETEXT, CB_GETCURSEL, 0, 0
.if eax == 2
invoke GetDlgItem, hWnd, IDC_CUSTOMTEXT
invoke EnableWindow, eax, TRUE
.else
mov ebx, eax
invoke SendDlgItemMessage, hWnd, IDC_TITLETEXT, CB_GETLBTEXT, ebx, addr @szBuffer
invoke SetWindowText, hWnd, addr @szBuffer
invoke GetDlgItem, hWnd, IDC_CUSTOMTEXT
invoke EnableWindow, eax, FALSE
.endif
.endif
;*******************************************************************************
; 在文本框中輸入文字
;*******************************************************************************
.elseif ax == IDC_CUSTOMTEXT
invoke GetDlgItemText, hWnd, IDC_CUSTOMTEXT, addr @szBuffer, sizeof @szBuffer
invoke SetWindowText, hWnd, addr @szBuffer
.endif
;*******************************************************************************
; 處理滾動條消息
;*******************************************************************************
.elseif eax == WM_HSCROLL
mov eax, wParam
.if ax == SB_LINELEFT
dec dwPos
.elseif ax == SB_LINERIGHT
inc dwPos
.elseif ax == SB_PAGELEFT
sub dwPos, 10
.elseif ax == SB_PAGERIGHT
add dwPos, 10
.elseif ax == SB_THUMBPOSITION || ax == SB_THUMBTRACK
mov eax, wParam
shr eax,16
mov dwPos,eax
.else
mov eax,TRUE
ret
.endif
cmp dwPos, 0
jge @F
mov dwPos, 0
@@:
cmp dwPos,100
jle @F
mov dwPos,100
@@:
invoke SetDlgItemInt, hWnd, IDC_VALUE, dwPos, FALSE
invoke SendDlgItemMessage, hWnd, IDC_SCROLL, SBM_SETPOS, dwPos, TRUE
;*******************************************************************************
.else
mov eax, FALSE
ret
.endif
mov eax,TRUE
ret
_ProcDlgMain endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
start:
invoke GetModuleHandle, NULL
mov hInstance, eax
invoke DialogBoxParam, hInstance, DLG_MAIN, NULL, offset _ProcDlgMain, NULL
invoke ExitProcess, NULL
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
end start