Graphical Images

This section is dedicated to graphics. Because the basics of Windows graphics are easily understood , I'll offer one simple example illustrating the output of graphical images. However, it is first necessary to explain several basic concepts:

  • The coordinate system for the output of graphic images is the same as for text output. Coordinates are measured in logical units that, by default, coincide with pixels. If desired, this proportion can be changed.

  • Drawing color can be created using three methods . When the SetPixel function is used, the color of a given point is specified. For lines, it is necessary to specify the pen color. To specify the color of graphic objects, it is necessary to specify the brush color.

  • The pen is created using the CreatePen function, and the brush is created using the CreateSolidBrush function, which you have used already: To create a colored picture, it is possible to create several pens and brushes beforehand and then choose the required ones when necessary using the Selectobject function, which you have also used already.

  • The following API functions can be used for drawing:

    • setPixel Set the specified pixel color.

    • LineTo Draw a line from the current point to the point having the specified coordinates. This point, in its turn , becomes the current point.

    • MoveToEx Change the current point.

    • Arc Draw an arc.

    • Rectangle Draw a rectangle.

    • RoundRect Draw a rectangle with rounded corners.

    • Ellipse, Pie Draw ellipses and elliptical sectors.

  • If a brush color set when drawing a closed figure was different from the background color, the closed figure will be filled with this color.

  • To set the proportion between logical units and pixels, the SetMapMode function is used.

  • To specify the input area, it is possible to use the SetViewportExtEx function.

    The SetviewportOrgEx function can be used to specify the starting point of the input area.

After providing this introductory information, it is time to demonstrate the program. It is simple but still implements the basic principles of working with graphics.

After you click the left mouse button for the first time, the horizontal line will be drawn. When you click the mouse button a second time, an inclined line will be drawn; the third click draws a colored rectangle. The source code of this program is provided in Listing 7.5, and the result of its execution is shown in Fig. 7.2.

image from book
Figure 7.2: The result of executing the program in Listing 7.5
Listing 7.5: A simple program demonstrating how to work with graphics
image from book
 ; The GRAPH1.INC file ; Constants ; The message arrives when the window is closed WM_DESTROY       equ 2 ; The message arrives when the window is created WM_CREATE        equ 1 ; The message arrives when you click the left mouse button in the window area WM_LBUTTONDOWN   equ 201h ; The message arrives when the window is redrawn WM_PAINT         equ 0Fh ; Window properties CS_VREDRAW       equ 1h CS_HREDRAW       equ 2h CS_GLOBALCLASS   equ 4000h WS_OVERLAPPEDWINDOW equ 000CF0000H stylcl           equ CS_HREDRAW+CS_VREDRAW+CS_GLOBALCLASS DX0              equ 600 DY0              equ 400 ; Color components RGBW             equ (50 or (50 shl 8)) or (255 shl 16) ; Window color RGBR             equ 150 ; Region color RGBL             equ 0 ; Line color RGBP equ 255 or (100 shl 8) ; Point color ; Identifier of the standard icon IDI_APPLICATION equ 32512 ; Cursor identifier IDC_CROSS equ 32515 ; Window display mode SW_SHOWNORMAL equ 1 ; Prototypes of external procedures EXTERN      CreateWindowExA@48:NEAR EXTERN      DefWindowProcA@16:NEAR EXTERN      DispatchMessageA@4:NEAR EXTERN      ExitProcess@4:NEAR EXTERN      GetMessageA@16:NEAR EXTERN      GetModuleHandleA@4:NEAR EXTERN      LoadCursorA@8:NEAR EXTERN      LoadIconA@ 8:NEAR EXTERN      PostQuitMessage@4:NEAR EXTERN      RegisterClassA@4:NEAR EXTERN      ShowWindow@8:NEAR EXTERN      TranslateMessage@4:NEAR EXTERN      UpdateWindow@4:NEAR EXTERN      BeginPaint@8:NEAR EXTERN      EndPaint@8:NEAR EXTERN      GetStockObject@4:NEAR EXTERN      CreateSolidBrush@4:NEAR EXTERN      GetSystemMetrics@4:NEAR EXTERN      GetDC@4:NEAR EXTERN      CreateCompatibleDC@4:NEAR EXTERN      SelectObject@8:NEAR EXTERN      CreateCompatibleBitmap@12@:NEAR EXTERN      PatBlt24:NEAR EXTERN      BitBlt@36:NEAR EXTERN      ReleaseDC@8:NEAR EXTERN      DeleteObject@4:NEAR EXTERN      InvalidateRect@12:NEAR EXTERN      GetStockObject@4:NEAR EXTERN      DeleteDC@4:NEAR EXTERN      CreatePen@12:NEAR EXTERN      SetPixel@16:NEAR EXTERN      LineTo@12:NEAR EXTERN      MoveToEx@16:NEAR EXTERN      Rectangle@20:NEAR ; Structures ; Message structure MSGSTRUCT STRUC         MSHWND     DD ?  ; Identifier of the window                          ; that receives the message         MSMESSAGE  DD ?  ; Message identifier         MSWPARAM   DD ?  ; Additional information about the message         MSLPARAM   DD ?  ; Additional information about the message         MSTIME     DD ?  ; Message sending time         MSPT       DD ?  ; Cursor position when the message was sent MSGSTRUCT  ENDS ;---------------------- WNDCLASS STRUC         CLSSTYLE         DD ? ; Window style         CLSLPFNWNDPROC   DD ? ; Pointer to the window procedure         CLSCBCLSEXTRA    DD ? ; Information about additional bytes                              ; for this structure         CLSCBWNDEXTRA    DD ? ; Information about additional bytes                              ; for the window         CLSHINSTANCE     DD ? ; Application descriptor         CLSHICON         DD ? ; Window icon identifier         CLSHCURSOR       DD ? ; Window cursor identifier         CLSHBRBACKGROUND DD ? ; Window brush identifier         MENNAME          DD ? ; Menu name identifier         CLSNAME          DD ? ; Specifies the window class name WNDCLASS ENDS ;--- PAINTSTR STRUC     hdc    DD 0     fErase DD 0     left   DD 0     top    DD 0     right  DD 0     bottom DD 0     fRes   DD 0     fIncUp DD 0     Reserv DB 32 dup(0) PAINTSTR ENDS ;-------------- RECT STRUC     L   DD ? ; X  Top left corner     T   DD ? ; Y  Top left corner     R   DD ? ; X  Bottom right corner     B   DD ? ; Y  Bottom right corner RECT ENDS ; The GRAPH.ASM file .586P ; Flat memory model .MODEL FLAT, stdcall ;---------------------------------------- include graph1.inc ; Include libraries includelib c:\masm32\lib\user32.lib includelib c:\masm32\lib\kernel32.lib includelib c:\masm32\lib\gdi32.lib ;---------------------------------------- ; Data segment _DATA SEGMENT         NEWHWND  DWORD 0         MSG    MSGSTRUCT  <?>         WC     WNDCLASS   <?>         PNT    PAINTSTR   <?>         HINST  DWORD 0         TITLENAME BYTE 'Graphics in a window', 0         NAM    BYTE 'CLASS32', 0         XT     DWORD 30         YT     DWORD 30         XM     DWORD ?         YM     DWORD ?         HDC    DWORD ?         MEMDC  DWORD ?         HPEN   DWORD ?         HBRUSH DWORD ?         P      DWORD 0 ; Output indicator         XP     DWORD ?         YP     DWORD ? _DATA ENDS ; Code segment _TEXT SEGMENT START: ; Get application descriptor         PUSH   0         CALL   GetModuleHandleA@4         MOV    [HINST], EAX REG_CLASS: ; Fill window structure ; Style         MOV   [WC.CLSSTYLE], stylcl ; Message-handling procedure         MOV   [WC.CLSLPFNWNDPROC], OFFSET WNDPROC         MOV   [WC.CLSCBCLSEXTRA], 0         MOV   [WC.CLSCBWNDEXTRA], 0         MOV   EAX,[HINST]         MOV   [WC.CLSHINSTANCE], EAX ;----------Window icon         PUSH  IDI_APPLICATION         PUSH  0         CALL  LoadIconA@8         MOV   [WC.CLSHICON], EAX ;---------- Window cursor         PUSH  IDC_CROSS         PUSH  0         CALL  LoadCursorA@8         MOV   [WC.CLSHCURSOR], EAX ;----------     PUSH RGBW ; Brush color     CALL CreateSolidBrush@4 ; Create a brush         MOV   [WC.CLSHBRBACKGROUND], EAX         MOV   DWORD PTR [WC.MENNAME], 0         MOV   DWORD PTR [WC.CLSNAME], OFFSET NAM         PUSH  OFFSET WC         CALL RegisterClassA@4 ; Create a window of the registered class         PUSH  0         PUSH  [HINST]         PUSH  0         PUSH  0         PUSH  DY0       ; DY0  Window height         PUSH  DX0       ; DX0  Window width         PUSH  100       ; The Y coordinate         PUSH  100       ; The X coordinate         PUSH  WS_OVERLAPPEDWINDOW         PUSH  OFFSET TITLENAME ; Window name         PUSH  OFFSET NAM       ; Class name         PUSH  0         CALL  CreateWindowExA@48 ; Check for error         CMP   EAX, 0         JZ    _ERR         MOV   [NEWHWND], EAX ; Window descriptor ;---------------------------------         PUSH  SW_SHOWNORMAL         PUSH  [NEWHWND]         CALL  ShowWindow@8 ; Show the newly created window ;---------------------------------         PUSH  [NEWHWND]         CALL  UpdateWindow@4 ; Redraw the visible part of a window ; Message-handling loop MSG_LOOP:         PUSH  0         PUSH  0         PUSH  0         PUSH  OFFSET MSG         CALL  GetMessageA@16         CMP   AX, 0         JE    END_LOOP         PUSH  OFFSET MSG         CALL  TranslateMessage@4         PUSH  OFFSET MSG         CALL  DispatchMessageA@4         JMP   MSG_LOOP END_LOOP: ; Exit the program (close the process)         PUSH  [MSG.MSWPARAM]         CALL  ExitProcess@4 _ERR:         JMP END LOOP ;----------------------------------------------------- ; Window procedure ; Placement of parameters in the stack ; [EBP+014H]  ; LPARAM ; [EBP+10H]   ; WAPARAM ; [EBP+0CH]   ; MES ; [EBP+8]     ; HWND WNDPROC   PROC         PUSH  EBP         MOV   EBP, ESP         PUSH  EBX         PUSH  ESI         PUSH  EDI         CMP   DWORD PTR [EBP+0CH], WM_DESTROY         JE    WMDESTROY         CMP   DWORD PTR [EBP+0CH], WM_CREATE         JE    WMCREATE         CMP   DWORD PTR [EBP+0CH], WM_PAINT         JE    WMPAINT         CMP   DWORD PTR [EBP+0CH], WM_LBUTTONDOWN         JE    LBUTTON         JMP   DEFWNDPROC LBUTTON:         CMP   P, 0         JNE   F1 ; Line (horizontal)         MOV   YP, 50 ; Y         MOV   XP, 10 ; X         MOV   ECX, 200 LL:         PUSH  ECX         PUSH  RGBP         PUSH   YP         PUSH  XP         PUSH  MEMDC         CALL  SetPixel@16         INC   XP         POP   ECX         LOOP  LL         INC   P         JMP   F3 F1:         CMP   P, 1         JNE   F2 ; Set the current coordinates to the end of the previous line         PUSH  0         PUSH  YP         PUSH  XP         PUSH  MEMDC         CALL  MoveToEx@16 ; Line drawn by a pen         PUSH  300         PUSH  550         PUSH  MEMDC         CALL  LineTo@12         INC   P         JMP   F3 F2:         CMP   P, 2         JNE   FIN ; Closed rectangle ; Select a brush for filling the closed area         PUSH  HBRUSH         PUSH  MEMDC         CALL  SelectObject@8 ; Draw a filled rectangle ; If you do not choose a brush, ; the rectangle will not be filled         PUSH  350         PUSH  400         PUSH  200         PUSH  200         PUSH  MEMDC         CALL  Rectangle@20         INC   P F3: ; Issue a command to redraw the window         PUSH  0         PUSH  OFFSET RECT         PUSH  DWORD PTR [EBP+08H]         CALL  InvalidateRect@12 FIN:         MOV   EAX, 0         JMP   FINISH WMPAINT:         PUSH  OFFSET PNT         PUSH  DWORD PTR [EBP+08H]         CALL  BeginPaint@8         MOV   HDC, EAX  ; Save the context (descriptor) ; Copy the virtual window to the real one         PUSH  0CC0020h   ; SRCCOPY = display the image as is         PUSH  0          ; YCoordinate of the source         PUSH  0          ; X  Coordinate of the source         PUSH  MEMDC      ; Source context         PUSH  YM         ; Height         PUSH  XM         ; Width         PUSH  0          ; Y  Where         PUSH  0          ; X  Where         PUSH  HDC        ; Context  Where CALL BitBlt@36 ;----------------Close the window context         PUSH  OFFSET PNT         PUSH  DWORD PTR [EBP+08H]         CALL  EndPaint@8         MOV   EAX, 0         JMP   FINISH WMCREATE: ; Screen size         PUSH  0 ; X         CALL  GetSystemMetrics@4         MOV   XM, EAX         PUSH  1 ; Y         CALL  GetSystemMetrics@4         MOV   YM, EAX ; Open the window context         PUSH  DWORD PTR [EBP+08H]         CALL  GetDC@4         MOV   HDC, EAX ; Create the device context compatible with this window         PUSH  EAX         CALL  CreateCompatibleDC@4         MOV   MEMDC, EAX ; Create a bitmap compatible to the hdc context in memory         PUSH  YM         PUSH  XM         PUSH  HDC         CALL  CreateCompatibleBitmap@12 ; Choose the bitmap in this context         PUSH  EAX         PUSH  MEMDC         CALL  SelectObject@8 ; Brush color         PUSH  RGBW         CALL  CreateSolidBrush@4 ; Create a brush ; Choose the brush in the given context         PUSH  EAX         PUSH  MEMDC         CALL  SelectObject@8 ; Fill the rectangular area         PUSH  0F00021h ; PATCOPY = Fill with the specified color         PUSH  YM         PUSH  XM         PUSH  0         PUSH  0         PUSH  MEMDC         CALL  PatBlt@24 ; Create a pen and a brush for drawing         PUSH  RGBR         CALL  CreateSolidBrush@4 ; Create a brush         MOV   HBRUSH, EAX ; Specify the pen         PUSH  RGBR ; Color         PUSH  0    ; Thickness = 1         PUSH  0    ; Solid line         CALL  CreatePen@12         MOV   HPEN, EAX ; Delete the context         PUSH  HDC         PUSH  DWORD PTR [EBP+08H]         CALL  ReleaseDC@8         MOV   EAX, 0         JMP   FINISH DEFWNDPROC:         PUSH  DWORD PTR [EBP+14H]         PUSH  DWORD PTR [EBP+10H]         PUSH  DWORD PTR [EBP+0CH]         PUSH  DWORD PTR [EBP+08H]         CALL  DefWindowProcA@16         JMP   FINISH WMDESTROY: ; Delete the pen         PUSH  HPEN         CALL DeleteDC@4 ; Delete the brush         PUSH  HBRUSH         CALL  DeleteDC@4 ; Delete the virtual window         PUSH  MEMDC         CALL  DeleteDC@4 ; Exit         PUSH  0         CALL  PostQuitMessage@4 ; WM_QUIT         MOV   EAX, 0 FINISH:         POP   EDI         POP   ESI         POP   EBX         POP   EBP         RET   16 WNDPROC ENDP _TEXT ENDS END START 
image from book
 

My explanation of graphical output would be incomplete without considering the topic of manipulating bitmap images. Consider the sequence of actions that need to be carried out for output of a bitmap image. Practical examples of graphics output will be provided in later chapters.

  1. Load the bitmap image and store its descriptor.

  2. Get the device handle for the memory area, in which the image will be stored.

  3. Select the image in the given context.

  4. Copy the image to the screen using the BitBlt function.

Using resources is a convenient way of working with bitmap images. Resources can be generated directly within the program or loaded from a file.

These topics will be covered later.

Note 

To a professional in the field of Windows programming, it might seem strange that I write custom string functions instead of using the available API functions. Yes, such functions exist. And the reason I neglect them is straightforward. First, my book is intended not only for advanced programmers but also for beginners that are just starting to master programming in the Assembly language. Second, as I mentioned in the Introduction, this book is an attempt to create some symbiosis of Assembly language and Windows programming. By following this principle, you will not always solve problems using only API functions. However, because I understand the importance of string API functions, I'll provide examples of their use in due time.



The Assembly Programming Master Book
The Assembly Programming Master Book
ISBN: 8170088178
EAN: 2147483647
Year: 2004
Pages: 140
Authors: Vlad Pirogov

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net