对话框对控件的支持使得建立对话框变得格外的简单,而不需要再像建立普通窗口那样
麻烦。用户只需在资源文件中定义好控件,那么Windows在初始化对话框时就会为我们
把控件一一添加上去。当然,用户还需要对控件进行一些初始化的工作。
一、控件使用
1、控件的定义
control 文本 , ID , 类 , 风格 , x , y , 宽度 ,高度 [ ,扩展风格 ]
其中值得注意的是 文本 是控件的初始化值。
这种定义较为麻烦,RC.EXE还为用户提供了一种更加简单的定义方法。
控件名称 [ 文本, ] ID , x , y , 宽度 , 高度 [ ,风格] [ ,扩展风格 ]
控件名称主要如下:
2、为什么可以在资源文件中定义即可?
这是因为Windows在初始化对话框时将每一天控件定义语句转化为:
invoke CreateWindow,类名,文本,风格,x,y,宽度,高度,\
对话框窗口句柄,ID,hInstance,NULL
3、实例
#include <resource.h>
#define ICO_MAIN 0x1000 //图标
#define DLG_MAIN 1 //对话框
//位图文件ID
#define IDB_1 1
#define IDB_2 2
//控件ID
#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 |
WS_MAXIMIZEBOX | WS_MINIMIZEBOX
CAPTION "对话框窗口控件实例"
FONT 9,"宋体"
BEGIN
//子窗口控件定义
GROUPBOX "选项",-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 "模态边框(&Modal Frame)",IDC_MODALFRAME,
65,70,100,12,WS_TABSTOP
AUTORADIOBUTTON "可变边框(&Thick Frame)",IDC_THICKFRAME,
65,85,100,12,WS_TABSTOP
GROUPBOX "标题栏文字",-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 "请在此选择显示在标题栏上面的文字,或者选择'自定义'后自行输入",
-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,119,125,10
LTEXT "0",IDC_VALUE,138,120,50,8
END
二、如何在代码中使用资源?
这里的主要内容就涉及两个方面的内容:
1、调用DialogBoxParam建立对话框时,对话框管理器会自动按照资源文件中定义的对话框模版为用户建立起
对话框。
把用户自定义的对话框过程中WM_INITDIALOG消息去掉:
即去掉该段:
.elseif eax == WM_INITDIALOG
;获得位图句柄备用
invoke LoadBitmap,hInstance,IDB_1
mov hBmp1,eax
invoke LoadBitmap,hInstance,IDB_2
mov hBmp2,eax
;设置对话框图标
invoke LoadIcon,hInstance,ICO_MAIN
invoke SendMessage,hWnd,WM_SETICON,ICON_SMALL,\
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,offset szText3
;设置组合框的初始内容
invoke SendDlgItemMessage,hWnd,IDC_TITLETEXT,\
CB_SETCURSEL,0,0
;灰化自定义框
invoke GetDlgItem,hWnd,IDC_CUSTOMTEXT
invoke EnableWindow,eax,FALSE
;选中"显示图片"
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
可以发现建立的对话框如下:
显然其中没有任何对对话框的初始化,因为初始化的工作需要用户在自定义的对话框过程中
处理。
2、对对话框控件的操作的处理。
操作对话框控件时,对话框过程会接收到WM_COMMAD消息,其wParam参数的低十六位即为用户定义
的ID。可以据此对不同的操作进行处理。另外,值得注意的是,操作滚动条时是不会发送WM_COMMAND
消息的,发送的WM_HSCROLL或WM_VSCROLL。
3、主程序
主程序是相对简单的,只要调用GetModuleHandle获得实例的句柄,保存以备用;然后调用DialogBoxParam
建立模态对话框;最后就是在对话框销毁后调用ExitProcess退出进程。
4、例子代码
.386
.model flat,stdcall
option casemap:none
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
.data?
;实例句柄与位图句柄
hInstance dd ?
hBmp1 dd ?
hBmp2 dd ?
;滚动条位置
dwPos dd ?
.const
;0代表字符串的结束,必须以0结束
szText1 db 'Hello,World!',0
szText2 db 'Title change!',0
szText3 db 'user-defined!',0
.code
;用户定义的对话框过程
_ProcDlgMain proc uses edi ebx esi hWnd,wMsg,wParam,lParam
local @szBuffer[128]:byte
local @stPs
mov eax,wMsg
.if eax == WM_CLOSE
;销毁对话框,释放位图资源
invoke EndDialog,hWnd,NULL
invoke DeleteObject,hBmp1
invoke DeleteObject,hBmp2
.elseif eax == WM_INITDIALOG
;获得位图句柄备用
invoke LoadBitmap,hInstance,IDB_1
mov hBmp1,eax
invoke LoadBitmap,hInstance,IDB_2
mov hBmp2,eax
;设置对话框图标
invoke LoadIcon,hInstance,ICO_MAIN
invoke SendMessage,hWnd,WM_SETICON,ICON_SMALL,\
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,offset szText3
;设置组合框的初始内容
invoke SendDlgItemMessage,hWnd,IDC_TITLETEXT,\
CB_SETCURSEL,0,0
;灰化自定义框
invoke GetDlgItem,hWnd,IDC_CUSTOMTEXT
invoke EnableWindow,eax,FALSE
;选中"显示图片"
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
;用户操作对话框中定义的控件时,对话框过程会收到消息WM_COMMAND,
;消息的wParam的第十六位用户定义的控件ID
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
.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
mov ebx,FALSE
.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 ax == 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
;注意,操作滚动条,不会收到WM_COMMAND消息,而是WM_HSCROLL
.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,20
;右移一页
.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,FALSE
ret
.endif
;保证滚动条范围为0~100
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
5、例子运行结果
可见,其中有了对对话框的初始化。
三、控件资源文件下载