(譯)win32asm實例-7

 

7.0 - Drawing the tiles畫圖塊

The tile control is already made, now it's time for the drawing of the tiles. The tile image can be one of these images:

圖塊控件已經被創建了,現在是畫圖塊的時候了。圖塊的圖象可以是這些圖象中的一個:

  • Numbered tiles (just a matrix of numbers) <?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

  • The demo bitmap (a resource)

  • A bitmap the user chooses

  • 編號的圖塊(只是數字矩陣)

  • 演示位圖(一個資源)

  • 用戶選擇的位圖

For now we will use the numbered tiles, the bitmap stuff will be added later. Furthermore, there are 4 color schemes.

現在,我們將使用編號的圖塊,位圖的內容將在後面添加。此外,還有4種顏色。

7.1 - How it works它是如何工作的

We'll use device contexts many times. A device context is a set of graphic objects that affect the output. These graphic objects can be pens, bitmaps, brushes, palette etc. The device contexts we use are:

我們將多次使用device context(設備環境)。一個device context是一些影響輸出的圖形物體的集合。這些物體可以是penbitmapbrushespalette等。我們使用的device context有:

  • Device contexts (DCs) of windows (The bitmap object in these DCs is what you actually see of the control)

  • Back buffer DC. All the drawing will first be done on a so called back buffer. This prevents flickering as drawing directly to a control will show the process of drawing as well.

  • Image DC. This DC contains the tile image currently used (numbered tiles/demo bitmap/user bitmap).

  • 窗口的device contextDC)(這些DC中的圖象是你實際看見的控件)

  • Back buffer DC。所有的繪畫工作在一個所謂的back buffer中事先完成。這克服了直接繪出控件的閃爍和顯示繪出過程等困難。

  • 圖象DC。這個DC包含了當前使用的圖塊的圖象(編號的圖塊、演示圖片、用戶圖片)

First the bitmap the user chooses, (the numbered tiles, which are drawn at runtime, the demo bitmap or a user bitmap), is put in the ImageDC. Then the 3D effect of the tiles (highlites and shadows) are drawn on the bitmap in the DC. Now remember this: The imageDC will not change from here, only if the user selects another tile type. The drawing is done tile by tile on the back buffer. For each tile, the tile is extracted from the ImageDC, then placed at the current position of that tile. An array will hold the tile positions.

首先,用戶選擇的圖片(在運行時繪出的編號圖塊,演示圖片,或用戶圖片)被放入圖象DC。然後圖塊的3d效果在DC中繪在圖片上。現在記住這個:在這,圖象DC不會改變。只有當用戶選擇了另一個圖塊類型時纔會。繪畫工作是在back buffer中一圖塊一圖塊的完成的。對於每個圖塊,那個圖塊從圖象DC中展開,然後放入那個圖塊的當前位置。一個數組將保存這些圖塊的位置。

7.2 - Creating the graphic objects創建圖象物體

A new procedure is introduced, InitBitmaps:

引入一個新的過程,InitBitmap

InitBitmaps         PROTO   STDCALL :DWORD
[in your .data?]
BackBufferDC        dd  ?
hBackBuffer         dd  ?
ImageDC             dd  ?
hImage              dd  ?
hBackgroundColor    dd  ?
hTileColor          dd  ?
hFont               dd  ?
TextColor           dd  ?
[in your .data]
FontFace            db  "Arial",0
[in your .code]
;================================================================================
;                           Init Bitmaps
;================================================================================
InitBitmaps proc hWnd:DWORD
; Create DC's for backbuffer and current image
    invoke  CreateCompatibleDC, NULL
    mov     BackBufferDC, eax
    
    invoke  CreateCompatibleDC, NULL
    mov     ImageDC, eax

; Create bitmap for backbuffer:
    invoke  GetDC, hWnd
    push    eax
    invoke  CreateCompatibleBitmap, eax, 200+20,200+20
    mov     hBackBuffer, eax
    pop     eax
    invoke  ReleaseDC, hWnd, eax
    invoke  SelectObject, BackBufferDC, hBackBuffer
    
; Create Arial font for the numbers 
    invoke  CreateFont, -30, NULL, NULL, NULL, FW_EXTRABOLD, /
            FALSE, FALSE, FALSE, NULL, NULL, NULL, NULL, NULL, ADDR FontFace
    mov     hFont, eax

; Select font in Image DC
   invoke   SelectObject, ImageDC, hFont
   
   invoke   CreateSolidBrush, 0FF8000h
   mov      hBackgroundColor, eax
   invoke   CreateSolidBrush, 0FF8080h
   mov      hTileColor, eax
   
   mov      TextColor, 0800000h
ret
InitBitmaps endp

Let's examine the procedure step by step:

讓我們一步步的看這個過程:

    invoke  CreateCompatibleDC, NULL
    mov     BackBufferDC, eax
    
    invoke  CreateCompatibleDC, NULL
    mov     ImageDC, eax

CreateCompatibleDC creates a new DC that is compatible with a given window. If NULL is given as parameter (window handle), it is compatible with the default window. One DC is created for the backbuffer, the handle is stored in BackBufferDC. The other is for the image DC, stored in ImageDC.

CreateCompatibleDC創建一個和給定的窗口兼容的新的DC。如果NULL作爲參數(窗口句柄)給出,它是和缺省窗口兼容。一個爲back buffer創建的DC的句柄保存在backbufferDC中。另一個是圖象DC,存於ImageDC中。

    ; Create bitmap for backbuffer:
    invoke  GetDC, hWnd
    push    eax
    invoke  CreateCompatibleBitmap, eax, 200+20,200+20
    mov     hBackBuffer, eax
    pop     eax
    invoke  ReleaseDC, hWnd, eax
    invoke  SelectObject, BackBufferDC, hBackBuffer

CreateCompatibleBitmap creates a new bitmap object that is compatible with a given DC. First we get the DC of the main window with GetDC. The handle is pushed onto the stack to save it for ReleaseDC. CreateCompatibleBitmap is then called, with the main window DC as DC, and 220x220 as bitmap size. The extra 20 pixels are for the margins. The bitmap handle is saved in hBackBuffer, the window DC handle is popped of the stack again and released (ReleaseDC should always be used with GetDC). Finally, SelectObject selects a graphic object in a DC. Here, the bitmap just created is put in the backbuffer DC.

CreateCompatibleBitmap創建一個和給定的DC兼容的圖片對象。首先我們用GetDC獲得主窗口的DC。這個句柄爲ReleaseDC壓入棧中保存。然後用主窗口的DC220×220作爲圖片大小調用CreateCompatibleBitmap。額外的20象素用於邊框。圖片句柄存於hBackBuffer,窗口DC句柄再被彈出棧然後釋放(ReleaseDC總是和GetDC一起使用)最後,SelectObjectDC中選擇一個圖片對象。這兒,剛創建的bitmap被放入backbufferDC中。

; Create Arial font for the numbers 
    invoke  CreateFont, -30, NULL, NULL, NULL, FW_EXTRABOLD, /
            FALSE, FALSE, FALSE, NULL, NULL, NULL, NULL, NULL, ADDR FontFace
    mov     hFont, eax

; Select font in Image DC
   invoke   SelectObject, ImageDC, hFont

To draw the numbers on the tiles, we need a font. CreateFont creates such a font. Look it up in your reference, FontFace is the name of the font, "Arial". -30 is a size for the font. The handle for the font is saved in hFont and then the font is selected in the ImageDC so we can write with the font on the image DC.

要在圖塊上畫數字,我們要字體。CreateFont創建這樣一個字體。在你的參考中查找它。FontFace是字體名,“Arial”,-30是字體的大小。字體的句柄存於hFont中然後字體被ImageDC選擇因而我們可以在imageDC中用這個字體寫字了。

   invoke   CreateSolidBrush, 00FFFFFFh
   mov      hBackgroundColor, eax
   invoke   CreateSolidBrush, 00FF0000h
   mov      hTileColor, eax
   
   mov      TextColor, 000000h

Finally, a few brush handles are made, they are not selected in any DC right now, but they will be later. CreateSolidBrush creates a brush with a certain color, you can use the handle to draw things (lines etc) with the brush. TextColor is not a brush, it's just a color value (we don't need a brush for the text color, only the color value).

最後,一個畫刷的句柄被創建,它們現在沒有被任何DC選擇,但在以後會。CreateSolidBrush創建一個有一定顏色的畫刷,你可以用這個句柄來用刷子畫東西(比如直線)。TextColor不是刷子,它只是顏色值(我們不因文本顏色需要刷子,只是顏色值)

Note: the image bitmap is not created yet, the DC is already available, but as the user can choose the type of bitmap, this bitmap is made when the user selects a type, then it is selected in the DC.

注意:圖象圖片仍未被創建,DC已經存在了。但用戶可以選擇圖片類型。圖片在用戶選擇類型時創建,然後在DC中被選擇。

A function to free all these handles is necessary too:

一個用於釋放所有這些句柄的函數也是必要的:

DeleteBitmaps   PROTO STDCALL
;================================================================================
;                           Delete Bitmaps
;================================================================================
DeleteBitmaps proc
    invoke  DeleteDC, BackBufferDC
    invoke  DeleteDC, ImageDC
    invoke  DeleteObject, hImage
    invoke  DeleteObject, hBackBuffer
    invoke  DeleteObject, hFont
    invoke  DeleteObject, hBackgroundColor
    invoke  DeleteObject, hTileColor
ret
DeleteBitmaps endp

 

Then both functions should be called:

然後要調用兩個函數:

...
.IF     eax==WM_CREATE
        invoke  InitControls, hWnd
        invoke  InitBitmaps, hWnd ;<<< insert here
.ELSEIF eax==WM_DESTROY
        invoke  DeleteBitmaps     ;<<< other one here
        invoke  PostQuitMessage, NULL
...

On creation of the main window, the bitmaps and DCs are initialized, before destroying, the bitmaps and DCs are deleted again.

在主窗口的創建過程中,圖片和DC被初始化。在窗口摧毀前,圖片和DC被再次刪除。

7.3 - Tile mode圖塊模式

Create a new procedure, SetBitmap:

創建一個新的過程,SetBitmap

[in mosaic.inc]
IMAGETYPE_STANDARD  equ     0
IMAGETYPE_NUMBERS   equ     1
IMAGETYPE_BITMAP    equ     2

[in .data?]
CurImageType        dd      ?       ;Current image type

[in .code]
SetBitmap   PROTO   STDCALL :DWORD, :DWORD
;================================================================================
;                           Set Bitmap
;================================================================================
SetBitmap   proc hWnd:DWORD, ImageType:DWORD
    mov     eax, ImageType
    .IF eax==IMAGETYPE_NUMBERS
        ;--- delete old image ---
        invoke  DeleteObject, hImage
        ;--- Get DC ---
        invoke  GetDC, hWnd
        push    eax
        ;--- Create new bitmap for the numbers bitmap ---
        invoke  CreateCompatibleBitmap, eax, 200, 200
        mov     hImage, eax
        pop     eax
        ;--- Release DC ---
        invoke  ReleaseDC, hWnd, eax
        ;--- Select new bitmap in DC ---
        invoke  SelectObject, ImageDC, hImage
        ;--- Draw numbers on the bitmap ---
        invoke  DrawNumbers
        ;--- Create the 3D effect on the bitmap ---
        invoke  CreateTiles
    .ENDIF
    ;--- Set the new image type ---
    mov     eax, ImageType
    mov     CurImageType, eax
ret
SetBitmap   endp

The SetBitmap procedure selects the type of image to use for the tiles. The procedure takes 2 parameters: hWnd, the handle of the main window, and ImageType, which can be one of these constants: IMAGETYPE_STANDARD, IMAGETYPE_NUMBERS, IMAGETYPE_BITMAP. These constants are defined in the include file. Right now, the procedure only reacts to IMAGETYPE_NUMBERS, we will implement the other two later. When the numbers image type is chosen, the old image (hImage) is deleted, and a new one is created with CreateCompatibleBitmap. Then two functions are called, DrawNumbers and CreateTiles, which are defined in the code below. DrawNumbers just draws an array of numbers on the new bitmap. CreateTiles draws the 3D effect on the bitmap. The CreateTiles procedure will be used for the other two image types too.

SetBitmap過程選擇了用於圖塊的圖象類型。過程帶2個參數,hWnd主窗口句柄和圖片類型。圖片類型可以爲這些常數中的一個:IMAGETYPE_STANDARD, IMAGETYPE_NUMBERS, IMAGETYPE_BITMAP。這些常數在包含文件中定義了。當前,過程僅對IMAGETYPE_NUMBERS作出反應,我們將在後面實現另外的兩個。當編號圖片類型被選擇,舊的圖象(hImage)被刪除,而新的由CreateCompatibleBitmap創建。然後兩個函數被調用,DrawNumbers CreateTiles,它們在下面的代碼中定義。Draw Numbers只是在新的圖片上畫上數字。CreateTiles在圖片上畫上3D效果。CreateTile過程也將在其他的兩種圖象類型中使用。

GetCoordinates  PROTO   STDCALL :DWORD
DrawNumbers     PROTO   STDCALL
.data
NumberFormat    db      "%lu",0
Rect200         RECT    <0,0,200,200>
.data?
Buffer          db      200 dup (?)
.code
;================================================================================
;                           Draw Numbers
;================================================================================
DrawNumbers proc uses ebx edi
LOCAL   TempRect:RECT
    ; --- Set the textcolor of ImageDC to TextColor ---
    invoke  SetTextColor, ImageDC, TextColor
    ; --- Fill the imageDC with the tile color brush ---
    invoke  FillRect, ImageDC, ADDR Rect200, hTileColor
    ; --- Set the background mode to transparent (for the text) ---
    invoke  SetBkMode, ImageDC, TRANSPARENT
    
    ; --- Loop through all the numbers and draw them one by one ---
    xor     ebx, ebx
    .WHILE  ebx<16
        mov     eax, ebx
        inc     eax
        invoke  GetCoordinates, eax
        mov     dx, ax      ; dx  = row
        shr     eax, 16     ; ax  = column
        and     edx, 0ffffh ; make sure that edx = dx
        imul    edx, edx, 50;} Multipy edx as well as eax with 50
        imul    eax, 50     ;} 
        mov     TempRect.left, eax
        mov     TempRect.top, edx
        add     eax, 50
        add     edx, 50
        mov     TempRect.right, eax
        mov     TempRect.bottom, edx
        mov     eax, ebx
        inc     eax
        invoke  wsprintf, ADDR Buffer, ADDR NumberFormat, eax
        invoke  DrawText, ImageDC, ADDR Buffer, -1, ADDR TempRect,/
                DT_CENTER or DT_SINGLELINE or DT_VCENTER
    inc ebx
    .ENDW
ret
DrawNumbers endp

;================================================================================
;                           GetCoordinates
;================================================================================
GetCoordinates proc dwTile:DWORD
    mov     eax, dwTile
    dec     eax
    cdq
    mov     ecx, 4
    div     ecx
    ;eax=quotient = row
    ;edx=remainder = column
    shl     edx, 16
    add     eax, edx
ret
GetCoordinates endp

Two new procedures here, GetCoordinates is a little procedure that will be used several times in the program. It uses a 0-based index of the tiles (tile 0, tile 1, tile 2) etc. and returns the row of the tile (0,1,2,3) in the low word of eax, the column of the tile (0,1,2,3) in the high word of eax. The calculation is quite simple. Divide the tile index by 4, the remainder will be the column, the quotient the row of the tile. The shl instruction shifts the colomn in the high word (shift 16 bits left), and add adds the row.

這兒有兩個過程,GetCoordinates是一個將在程序中多次使用的小過程。它使用0開始的圖塊索引(圖塊0,圖塊1,圖塊2)等,並在eax的低字中返回圖塊所在的排(0,1,2,3),在eax的高字中返回圖片所在的縱行(0,1,2,3)。計算很簡單,把圖塊的索引除4,餘數爲縱行數,商爲圖塊所在的排數。Shl指令移動高字中的行數(左移16位),而add加上排數。

The DrawNumbers procedure works like this:

DrawNumbers過程的工作原理如下:

Set textcolor to the value of the TextColor variable
Fill the complete bitmap with the tilecolor brush (rect200 is a RECT structure that defines the area of 200x200 pixels starting at (0,0))
Set the background mode to TRANSPARENT to prevent an ugly background around the text.

設置文本顏色爲TextColor變量的值。用圖塊顏色的刷子填充完整的圖片(rect200是一個定義了從(00)開始的200×200象素區域的結構)設置背景模式爲TRANSPARENT,以防止難看字背景的空色。

The tile loop:

Tile循環

Loop from 0 to 15 {
    - GetCoordinates(currentloopvalue)
    - Extract row and column from return value
      multiply the row and the column with 50
      (this gives the image coordinates of the tile)
    - Fill a RECT structure (TempRect) with the coordinates of
      the tile.
    - Use wsprintf to convert the tile number into text.
      (NumberFormat is the format the number should be outputted
      in, buffer is a temporary buffer)
    - Use DrawText to draw the number at the right coordinates
}

015開始循環{

-獲得座標(當前的循環值)
-從返回值中解開行和列的值。用行數和列數乘以50(這給出了圖塊的圖象座標)
-用圖塊座標填寫RECT結構(臨時結構)
-使用wsPrint把圖塊數翻譯爲文本。(NumberFormat是數字應被輸出的給世,buffer是一個臨時緩存)
-使用DrawText在恰當處繪出數字。

CreateTiles draws the button-style 3D effect on the tiles by drawing black & white lines at the right places:

CreateTiles通過在恰當地方會上黑和白的線條在圖塊上繪出3D效果。

CreateTiles     PROTO   STDCALL
;================================================================================
;                           Create Tiles
;================================================================================
CreateTiles proc uses ebx esi edi
    invoke  GetStockObject, BLACK_PEN
    invoke  SelectObject, ImageDC, eax
; Dark lines, vertical. x = 50k - 1 (k=1,2,3,4)
; ebx = k
; esi = x
    xor     ebx, ebx    
    inc     ebx 
    ; ebx is 1 now
    
    .WHILE  ebx<5   ; (ebx= 1,2,3,4)
        mov     eax, 50
        mul     ebx
        mov     esi, eax
        dec     esi
        invoke  MoveToEx, ImageDC, esi, 0, NULL
        invoke  LineTo, ImageDC, esi, 199
    inc ebx
    .ENDW

; Dark lines, horizontal. y = 50k - 1 (k=1,2,3,4)
; ebx = k
; esi = y
    xor     ebx, ebx    
    inc     ebx 
    ; ebx is 1 now
    .WHILE  ebx<5   ; (ebx= 1,2,3,4)
        mov     eax, 50
        mul     ebx
        mov     esi, eax
        dec     esi
        invoke  MoveToEx, ImageDC, 0, esi, NULL
        invoke  LineTo, ImageDC, 199, esi
    inc ebx
    .ENDW
    invoke  GetStockObject, WHITE_PEN
    invoke  SelectObject, ImageDC, eax
; Light lines, vertical. x = 50k  (k=0,1,2,3)
; ebx = k
; esi = x
    xor     ebx, ebx    

    .WHILE  ebx<4   ; (ebx= 0,1,2,3)
        mov     eax, 50
        mul     ebx
        mov     esi, eax
        invoke  MoveToEx, ImageDC, esi, 0, NULL
        invoke  LineTo, ImageDC, esi, 199
    inc ebx
    .ENDW

; Light lines, horizontal. y = 50k (k=0,1,2,3)
; ebx = k
; esi = y
    xor     ebx, ebx    

    ; ebx is 1 now
    
    .WHILE  ebx<4   ; (ebx= 0,1,2,3)
        mov     eax, 50
        mul     ebx
        mov     esi, eax
        invoke  MoveToEx, ImageDC, 0, esi, NULL
        invoke  LineTo, ImageDC, 199, esi
    inc ebx
    .ENDW
    
ret
CreateTiles endp

This procedure is quite easy to understand. It draws 4 sets of lines. Each line is drawn by first getting a brush with GetStockObject (retrieves a standard brush color from windows). This brush is selected in the imagedc. Then the current point is moved to the startpoint of the line with MoveToEx, and the line is drawn with LineTo.

這個過程很容易理解。它畫4條線。每條線先由GetStockObject獲得刷子(從窗口取得標準刷顏色)。這個刷子在imageDC中被選擇然後當前位置被MoveToEX移到線的起點,而線由LineTo繪出。

7.4 – Drawing繪畫

The procudure below will be used in the future too, but the code of it is temporary right now, it just draws the image DC on the static control to show if your code worked. Furthermore, some additional procedures are introduced to initialize everything correctly.

下面的過程也將在以後使用。但它的代碼現在暫時是正確的。它只是在靜態控件上畫imageDC來顯示你的代碼是否在工作。此外,附加的過程被用來正確的初始化每一件東西:

DrawProc    PROTO   STDCALL :DWORD, :DWORD
InitGame    PROTO   STDCALL :DWORD


[in .code]

;================================================================================
;                           Draw Numbers
;================================================================================
DrawProc proc uses ebx edi esi hWnd:DWORD, hDC:DWORD
    invoke  BitBlt, hDC, 9, 9, 220, 220, ImageDC, 0, 0, SRCCOPY
ret
DrawProc endp
;================================================================================
;                           InitGame
;================================================================================
InitGame    proc    hWnd:DWORD
    invoke  SetBitmap, hWnd, IMAGETYPE_NUMBERS
ret
InitGame    endp


[In the WM_CREATE handler of WndProc, below 'invoke InitBitmaps, hWnd']
    invoke      InitGame, hWnd
[In the messagehandler in WndProc, between the other ELSEIFs]
    .ELSEIF eax==WM_DRAWITEM
        mov     eax, wParam
        .IF     eax==CID_STATIC
            push    ebx
            mov     ebx, lParam
            assume  ebx:ptr DRAWITEMSTRUCT
            invoke  DrawProc, hWnd, [ebx].hdc
            assume  ebx:nothing
            pop     ebx
            xor     eax, eax
            inc     eax
        .ELSE
            xor     eax, eax
        .ENDIF

The DrawProc and InitGame are fairly easy to understand. BitBlt copies a part of a bitmap from one DC to another. Here the complete bitmap in ImageDC is copied to the DC of the static control window.

DrawProcInitGame相當容易理解。BitBlt從一個DC拷貝一部分圖片到另一箇中。這兒,ImageDC中的完整的圖片被拷貝到靜態控件窗口的DC中。

The WM_DRAWITEM message requires some more explanation:
WM_DRAWITEM is sent to the main window when one of the owner-drawn controls needs to be drawn. An owner-drawn control is a control that is drawn by the program instead of windows. When this message is sent, wParam contains the ID of the control that needs to be drawn. Here the .IF eax==CID_STATIC finds out if it is the static control (the tiles window) that needs to be drawn. If not (.ELSE), 0 is returned from WndProc (xor eax, eax). 0 tells windows that the message is not handled by the program. lParam is a pointer to a DRAWITEMSTRUCT.

WM_DRAWITEM消息需要更多一些的解釋:
當一個ownerdrawn控件需要繪出時,WM_DRAWITEM被髮往主窗口。一個ownerdrawn控件是一個由程序而不是由Windows來繪出的控件。消息被髮送時,wParam包含了需要繪出的控件的ID。這兒,.IF eax== CID_STATIC找出它是否是需要繪出的靜態控件(圖塊窗口)。如果不是(.ELSE,WndProc返回0xor eax, eax)。0告訴Windows這個消息沒有被程序處理。Iparam是一個指向DRAWITEMSTRUCT的指針。

 mov     ebx, lParam
 assume  ebx:ptr DRAWITEMSTRUCT
 invoke  DrawProc, hWnd, [ebx].hdc
 assume  ebx:nothing

First, lParam is put in ebx. Now ebx is a pointer to the DRAWITEMSTRUCT structure. The assume statement gives masm more information about the register. assume ebx:ptr DRAWITEMSTRUCT tells masm that ebx is a pointer to a DRAWITEMSTRUCT structure. Now you can use the structure members directly on ebx. hdc is one of these members, it contains the handle to the device context of the window. The control will show whatever there is on that DC. This DC is passed to DrawProc. Don't forget to tell masm to assume nothing for ebx (assume ebx:nothing), otherwise masm thinks ebx is a pointer to DRAWITEMSTRUCT throughout the whole program. Very important is that you should save ebx in your procedures (that's why the push ebx/pop ebx instructions are included). Windows assumes the values of the ebx, esi and edi registers do not change when your window procedure is called by windows (this applies to all callback functions in windows, always save ebx, esi & edi).

首先,Iparam被放入ebx。現在ebx是一個指向DRAWITEMSTRUCT結構的指針。Assume語句告訴masm關於寄存器的更多信息。Assume ebx:ptr DRAWITEMSTRUCT告訴masm ebx是一個指向DRAWITEMSTRUCT結構的指針。現在你可以使用ebx中的結構成員了。控件將告訴你在那個DC中有什麼。這個DC被傳遞給DrawProc。不要忘記告訴masm assume nothing fo ebx(assume ebx:nothing),否則masm在整個程序都會認爲ebx是指向DRAWITEMSTRUCT的指針。非常重要的是你應該在你的過程中保存ebx(這是包含push ebx/pop ebx指令的原因)。Windows假定在你的窗口過程被windows調用時,ebxesiedi寄存器的值不會改變(這對Windows中的所有回調函數都是這樣,總是保存ebxesiedi

7.5 – Done完事

The current project files are here: mosaic4.zip

當前的工程文件在這兒:mosaic4.zip

If you assemble the program and run it, you should see this:

如果你彙編程序並運行它,你將看到:

mosaic_firstnumbers.gif

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

As you can see, the tiles are drawn correctly.

正如你可以看到哦,圖塊被正確的繪出。

發佈了61 篇原創文章 · 獲贊 1 · 訪問量 10萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章