We will now create a static control which we will draw the tiles on.
我们将创建一个静态控件。在它上面我们将要画图块。
6.1 - Creating the control创建控件We make a new procedure called InitControls that will initialize all the controls on the main window.
我们创建一个将初始化所有主窗口上的控件的名为“initControls”的过程。
.data
ClassStatic db "STATIC",0
.data?
hStatic dd ?
.code
;================================================================================
; Init Controls
;================================================================================
InitControls proc hWnd:DWORD
; Create static window for mosaic:
invoke CreateWindowEx, WS_EX_CLIENTEDGE, ADDR ClassStatic, NULL,\
WS_VISIBLE + WS_CHILD + SS_OWNERDRAW ,\
15, 55, 220, 220,\
hWnd, CID_STATIC, hInstance, NULL
mov hStatic, eax
ret
InitControls endp
At the start of the file, where the prototypes are, add a prototype for this procedure:
在文件的开头,那儿是函数原型。加入这个过程的原型:
InitControls PROTO STDCALL :DWORD
And in the mosaic.inc file:
把这个加入mosaic.inc文件:
CID_STATIC equ 601
The InitControls procedure takes one parameter, hWnd which is the window handle of the main window. The CreateWindowEx function creates a static control with the following styles:
InitControls过程带一个参数——主窗口的窗口句柄hWnd。CreateWindowEx创建一个有一下风格的静态控件:
Clientedge (window has a sunken border like an edit control) "STATIC" as window class, this creates a static control Child window (WS_CHILD), the window is a child window of the main window Ownerdrawn window (SS_OWNERDRAWN). This means that the program takes care of the drawing of the control. CID_STATIC is the ID of the window, this constant is defined in the include file mosaic.inc Left top position: (15,55), size 220x220 客户区边缘(Clientedge)(像编辑框控件的有下凹边框的窗口) “STATIC”作为窗口类名。这创建静态控件。 子窗口(WS_CHILD),是主窗口的子窗口的窗口。 Ownerdrawn窗口(SS_OWNERDRAW)。这个意为程序处理控件的绘出工作。 CID_STATIC是窗口的ID,这个常熟定义在包含文件mosaic.inc中。 坐标位置(15, 55),大小220×220。Finally, the window handle is stored in the dword hStatic (defined in .data?)
最后,窗口句柄储存在dword hStatic中(定义在.data?中)
Now we have to call this procedure:
现在我们必须调用这个函数:
....
.IF eax==WM_CREATE
invoke InitControls, hWnd
....
This code is in the window procedure (WndProc), the WM_CREATE message is sent on creation of the window. Then initcontrols is called and this procedure creates the static control.
这段代码在窗口过程(WndProc)中,在窗口创建时WM_CREATE消息被发送。然后调用initControls而且这个过程创建静态控件。
When the program is assembled, this will be the result:
在程序汇编后,结果会是这样:
6.2 - Adding more controls加入更多控件There will also be a toolbar and a statusbar on the window. You can use CreateWindowEx to create both controls, but there are two functions that simplify creating these controls. They are CreateToolbarEx and CreateStatusWindow. These functions reside in the common controls library, which we have included (includelib comctl32.lib and include comctl32.inc). The library should also be initialized with InitCommonControls but we've already done this.
在窗口上还要有工具栏和状态栏。你可以用CreateWindowEx来创建这两个控件。但这两个函数简化了这些控件的创建。它们是CreatToolbarEx和CreateStatusWindow。这些函数存在与通用控件中。这个我们已经包含了(includelib comctl32.lib和include comctl32.inc)。库也应该被InitCommonControls初始化。但我们已经这么做了。
.data?
hStatus dd ?
.data
StatusParts db 90, 170, -1
DefaultStatusText db "Mosaic 1.0",0
.code
InitControls proc hWnd:DWORD
LOCAL DefaultFont:DWORD
;--- Create a static control ---
............. static control code here............
;--- save default font ---
invoke GetStockObject, DEFAULT_GUI_FONT
mov DefaultFont, eax
; Create statusbar window:
invoke CreateStatusWindow, WS_CHILD + WS_VISIBLE,\
ADDR DefaultStatusText, hWnd, CID_STATUS
mov hStatus, eax
invoke SendMessage, hStatus, WM_SETFONT, DefaultFont, TRUE
invoke SendMessage, hStatus, SB_SETPARTS,3, ADDR StatusParts
...
in mosaic.inc:
CID_STATUS equ 600
There are some changes to the procedure here: There's a new local variable, DefaultFont. GetStockObject returns a standard handle for the default system font. This handle is stored in DefaultFont. The handle doesn't have to be deleted because it's a system handle. Then CreateStatusWindow is called. This function creates a statusbar, with the string DefaultStatusText as default string. Then SendMessage is called twice. The first time, a WM_SETFONT message is sent to the status window to set the font of the control to the default system font. The second time, the status window is divided in 3 part with the SB_SETPARTS message. StatusParts is an array of bytes that contain the coordinates of the right edge of each part. -1 means that it's size is maximal.
这儿对过程有些改动:一个新的局部变量DefaultFont。GetStockObject从缺省系统字体返回一个标准句柄。这个句柄储存在DefaultFont中。这个句柄不必删除因为它是个系统句柄。然后调用CreateStatusWindow。这个函数用字符串DefaultStatusText作为缺省字符串创建状态栏。然后SendMessage被调用两次。第一次时,WM_SETFONT消息被发往状态栏窗口来设置控件的字体为缺省系统字体。第二次时,状态栏被SB_SETPARTS消息分为3部分。StatusParts时个字节数组。其中,包含了每一部分的右边缘坐标。-1意为它的尺寸最大化。
StatusParts db 90, 170, -1
As you can see, this is a byte array (db) with the values 90, 170 and -1. These are the coordinates used by SB_SETPARTS. ADDR is used in the parameter to give a pointer to the array as the parameter, and not the value itself.
正如你所看到的,这是一个有值90, 170 和-1的字节数组。这些是由SB_SETPARTS使用的坐标。在参数中使用ADDR来把指向数组的指针作为参数,而不是值本身。
6.3 – Toolbar工具栏The toolbar will be created with CreateToolbarEx. The Win32 programmer's reference gives this on CreateToolbarEx:
工具栏由CreateToolbarEx创建。《win32程序员参考》,对CreateToolbarEx有如下叙述:
HWND CreateToolbarEx(
HWND hwnd,
DWORD ws,
UINT wID,
int nBitmaps,
HINSTANCE hBMInst,
UINT wBMID,
LPCTBBUTTON lpButtons,
int iNumButtons,
int dxButton,
int dyButton,
int dxBitmap,
int dyBitmap,
UINT uStructSize
);
hwnd: Handle of the parent window
ws: The toolbar window style
wID: Control ID for the toolbar
nBitmaps: Number of button images in the resource bitmap
hBMInst: Instance handle of the aplication that contains the button resource image
wBMID: Resource ID of the buttons bitmap
lpButtons: Pointer to an array of TBBUTTON structures
dxButton/dyButton: Width and height of the buttons on the toolbar
dxBitmap/dyBitmap: Width and height of the images on the buttons.
Hwnd:父窗口的句柄。
ws:工具栏窗口的样式。
wID:工具栏的控件ID。
nBitmaps:在位图资源中的按钮图片数。
hBMInst:程序的实例句柄。其中包含有按钮图片资源。
wBMID:按钮位图的资源ID。
lpButtons:指向TBBUTTON结构的数组的指针。
dxButton/dyButton:工具栏上的按钮的长和宽。
dxBitmap/dyBitmap:工具栏上的图片的长和宽。
As you can see, we need two things for the toolbar: A bitmap resource that contains the images for the buttons, and an array of TBBUTTON structures. Each structure in this array contains information for one button.
正如你所见,我们用toolbar要两件东西:包含用于按钮的图片的位图资源,以及TBBUTTON结构的数组。该数组的每个结构包含一个按钮的信息。
Creating the resource创建资源Open your resource file again (mosaic.rc) and add the following to the file:
再一次打开你的资源文件(mosaic.rc)并添加一下内容进文件:
#define BMP_TOOLBAR 801
BMP_TOOLBAR BITMAP DISCARDABLE "resources\\toolbar.bmp"
This will define a new resource ID, 801 to BMP_TOOLBAR. The second line includes the file toolbar.bmp in the resource file as BMP_TOOLBAR. As usual you'll have to define this ID in your include file too:
这给BMP_TOOLBAR一个新的资源ID,801。第二行包含文件toolbar.bmp为资源文件中的BMP_TOOLBAR。和往常一样,你必须在你的包含文件中定义这个ID:
BMP_TOOLBAR equ 801
The resource you just included is a simple bitmap:
你刚刚包含的资源是一个简单的位图:
The bitmap consists of 6 images with size 32x32 pixels. The toolbar control will extract the button image from this bitmap. It can do this automatically because it knows how many images there are and the size of them.
这位图包含了6个大小为32×32象素的图片。工具栏控件将从这个位图中展开这些按钮图片。这可以自动完成,因为它执拗那有多少图片和它们的大小。
TBBUTTONFurthermore, CreateToolbarEx wants an array of TBBUTTON structures. The definition of TBBUTTON is:
此外,CreateToolbarEx需要一个TBBUTTON结构的数组。TBBUTTON的定义是:
typedef struct _TBBUTTON {
int iBitmap;
int idCommand;
BYTE fsState;
BYTE fsStyle;
DWORD dwData;
int iString;
} TBBUTTON
iBitmap: zero based index to the button image to use for the button
idCommand: Command ID for the button (sent with WM_COMMAND)
fsState: State flags for the button
fsStyle: Style flags for the button
dwData: Application defined value
iString: zero based index of button string (not used here)
iBitmap:用于按钮的以0开始的按钮图片索引。
idCommand:按钮的CommandID(和WM_COMMAND一起发送)
fsState:按钮的状态标志。
fsStyle:按钮的风格标志。
dwData:程序定义的值。
iString:按钮字符串的以0开始的索引(这儿没有用)
idCommand is an identifier that is sent with the WM_COMMAND message if a button is pressed. We will use the same IDs as the in the menu, this makes pressing a button the same as choosing a menu item. We already defined these IDs in the include file so we can use them directly. We will use three styles here:
idCommand是在按钮被按下时和WM_COMMAND消息一起发送。我们会用和菜单一样的ID。这使得按一下按钮和选择一个菜单项起相同作用。我们已经在包含文件中定义了这些ID。因而我们可以直接使用它们。我们在此使用了3个样式:
TBSTYLE_BUTTON: just a normal pushbutton TBSTYLE_CHECKGROUP: A group of buttons of which one at a time can be pressed into the 'enabled state'. We use this style for the tree types of displaying the titles: as numbers, as the demo bitmap, or as a user defined bitmap TBSTYLE_SEP: This is a special style, it doesn't create a button, just a seperator. A seperator can seperate the button groups, but you can use them whenever you want too. TBSTYLE_BUTTON:只是一个普通的按钮 TBSTYLE_CHECKGROUP:一组按钮。其中一次只可以有一个被按下称为有效状态。我们对显示图块的三个模式的按钮使用这种样式:“用数字”,“用演示图”,“用用户定义的图片”。 TBSTYLE_SEP:这是一个特殊的样式,它不会创建按钮,只是分隔栏(Seperator)。一个分隔栏可以把按钮组分开,但你可以在任何你需要的时候使用它们。[in your .data]
ToolbarButtons TBBUTTON <0, MI_OPENBITMAP, TBSTATE_ENABLED, TBSTYLE_BUTTON,0, NULL, NULL>
TBBUTTON <1, MI_NEWGAME, TBSTATE_ENABLED, TBSTYLE_BUTTON,0, NULL, NULL>
TBBUTTON <NULL, NULL, NULL, TBSTYLE_SEP, NULL, NULL>;--- seperator
TBBUTTON <2, MI_USESTANDARD, TBSTATE_ENABLED+TBSTATE_CHECKED, \
TBSTYLE_CHECKGROUP,0, NULL, NULL>
TBBUTTON <3, MI_USENUMBERS, TBSTATE_ENABLED, TBSTYLE_CHECKGROUP,0, NULL, NULL>
TBBUTTON <4, MI_USEFILE, TBSTATE_ENABLED, TBSTYLE_CHECKGROUP,0, NULL, NULL>
TBBUTTON <NULL, NULL, NULL, TBSTYLE_SEP, NULL, NULL>;--- seperator
TBBUTTON <5, MI_ABOUT, TBSTATE_ENABLED, TBSTYLE_BUTTON,0, NULL, NULL>
The brackets <> initialize a structure, each structure member is seperated by a comma. The MI_XXXs are the identifiers used in the menus. The seperators don't need any members of the structures except for the style TBSTYLE_SEP. One of the checkgroup buttons has the style TBSTATE_ENABLED, which enables the button by default.
括号<>初始化一个结构,每个结构成员由逗号分开。MI_XXX是菜单使用的标识符。分隔栏除了样式TBSTYLE_SEP不需要任何其他结构的程序。Checkgroup中的一个按钮有样式TBSTATE_ENABLED,它使这个按钮缺省选中。
Creating the toolbar创建工具栏Now it's time to create the toolbar:
[in your .data?]
hToolbar dd ?
[in your .code]
invoke CreateToolbarEx, hWnd, WS_CHILD + WS_VISIBLE + TBSTYLE_FLAT + WS_BORDER,\
CID_TOOLBAR, 6, hInstance, BMP_TOOLBAR, ADDR ToolbarButtons,\
8, 32, 32, 32, 32, SIZEOF TBBUTTON
mov hToolbar, eax
invoke SendMessage, eax, TB_AUTOSIZE, NULL, NULL
[in mosaic.inc]
CID_TOOLBAR equ 602
This creates a toolbar with:
这用了一下东西创建工具栏:
Style: child window, visible, border and TBSTYLE_FLAT (nice flat toolbar buttons)
Control id: CID_TOOLBAR (602)
Bitmap with button images: BMP_TOOLBAR resource in the module with handle hInstance. The fourth parameter (6) indicates the number of buttons in the bitmap
TBBUTTON structure: ToolbarButtons (ADDR is used to give a pointer to the array)
Buttons: 8 buttons in the array of TBBUTTONs, 32x32 pixels. The bitmaps on the buttons are 32x32 pixels too.
TBBUTTON size: SIZEOF TBBUTTON gives the size of the structure.
样式:child window, visible, border 和 TBSTYLE_FLAT (好看的平坦式工具栏按钮)
控件id:CID_TOOLBAR(602)
包含按钮图片的位图:句柄为hInstance的模块中的BMP_TOOLBAR资源。第四个参数(6)标明了位图中的按钮数。
TBBUTTON结构:工具栏按钮(ADDR用来给出一个指向数组的指针)。
按钮:TBBUTTON的数组中的8个按钮,32×32象素。按钮上的位图也是32×32象素。
TBBUTTON大小:SIEZOF TBBUTTON给出了该结构的大小。
The toolbar handle is stored in hToolbar (dword variable). Finally, the TB_AUTOSIZE message is sent to the toolbar. This ensures that the control has the proper size to display the buttons and images.
工具栏句柄储存在hToolbar中(dword变量)。最后,TB_AUTOSIZE消息被发往工具栏。这确保了控件有显示按钮和图片的恰当尺寸。
6.4 – Done完事If you've done everything correctly, it should look like this:
如果你把所有的事情都正确的完成了,它应该是这样:
If you messed everything up, here are the current files: mosaic3.zip.
如果你要快速地完成所有事情,这里有当前地文件:mosaic3.zip。本文地址:http://com.8s8s.com/it/it29705.htm