(譯)win32asm實例-6

 

6.0 - The tiles window圖塊窗口

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: <?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

InitControls過程帶一個參數——主窗口的窗口句柄hWndCreateWindowEx創建一個有一下風格的靜態控件:

  • 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:

在程序彙編後,結果會是這樣:

mosaic_static.gif

<?xml:namespace prefix = v ns = "urn:schemas-microsoft-com:vml" />

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來創建這兩個控件。但這兩個函數簡化了這些控件的創建。它們是CreatToolbarExCreateStatusWindow。這些函數存在與通用控件中。這個我們已經包含了(includelib comctl32.libinclude 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.

這兒對過程有些改動:一個新的局部變量DefaultFontGetStockObject從缺省系統字體返回一個標準句柄。這個句柄儲存在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一個新的資源ID801。第二行包含文件toolbar.bmp爲資源文件中的BMP_TOOLBAR。和往常一樣,你必須在你的包含文件中定義這個ID

BMP_TOOLBAR equ 801

The resource you just included is a simple bitmap:

你剛剛包含的資源是一個簡單的位圖:

restoolbar.gif

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象素的圖片。工具欄控件將從這個位圖中展開這些按鈕圖片。這可以自動完成,因爲它執拗那有多少圖片和它們的大小。

TBBUTTON

Furthermore, 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 (好看的平坦式工具欄按鈕)
控件idCID_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:

如果你把所有的事情都正確的完成了,它應該是這樣:

mosaic_toolstatus.gif

If you messed everything up, here are the current files: mosaic3.zip.

如果你要快速地完成所有事情,這裏有當前地文件:mosaic3.zip
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章