第二十五课:位图初步
#define IDB_MYBITMAP 100第一行我们定义了一个值为100的整数宏。 第二行我们把这个整数宏指向所要定义的位图, 这样,编译器就能知道位图所在的路径。
IDB_MYBITMAP BITMAP "c:\project\example.bmp"
MyBitMap BITMAP "c:\project\example.bmp"两种方法效果是一样的。 选择哪一种方法,视乎在程序中你喜欢用整数宏还是用字符串来指向位图。
    该函数返回一个位图句柄。函数有两个参数,其中 hInstance 是程序句柄。 
    lpBitmapName 是位图名字的指针(适用于第二种定义方法)。如果你使用了第一种 
    定义方法,你可以填入指向位图的值或整数宏 
    (对应上例这个值就是100,整数宏是IDB_MYBITMAP)。下面是简单的例子: 
  
.386 
      .model flat, stdcall 
      ................ 
      .const 
      IDB_MYBITMAP    equ 100 
      ............... 
      .data? 
      hInstance  dd ? 
      .............. 
      .code 
      ............. 
          invoke GetModuleHandle,NULL 
          mov hInstance,eax 
      ............ 
          invoke LoadBitmap,hInstance,IDB_MYBITMAP 
      ........... 
    
第二种方法:
.386 
      .model flat, stdcall 
      ................ 
      .data 
      BitmapName  db "MyBitMap",0 
      ............... 
      .data? 
      hInstance  dd ? 
      .............. 
      .code 
      ............. 
          invoke GetModuleHandle,NULL 
          mov hInstance,eax 
      ............ 
          invoke LoadBitmap,hInstance,addr BitmapName 
      ...........
  
   如果函数执行成功,将返回DC内存映像也即“画纸”的句柄。
  
 WinMain proto :DWORD,:DWORD,:DWORD,:DWORD  
   IDB_MAIN   equ 1  
 .data  
   ClassName db "SimpleWin32ASMBitmapClass",0  
   AppName  db "Win32ASM Simple Bitmap Example",0  
 .data?  
   hInstance HINSTANCE ?  
   CommandLine LPSTR ?  
   hBitmap dd ?  
 .code  
   start:  
    invoke GetModuleHandle, NULL  
    mov    hInstance,eax  
    invoke GetCommandLine  
    mov    CommandLine,eax  
    invoke WinMain, hInstance,NULL,CommandLine, SW_SHOWDEFAULT  
    invoke ExitProcess,eax  
 WinMain proc hInst:HINSTANCE,hPrevInst:HINSTANCE,CmdLine:LPSTR,CmdShow:DWORD  
  
    LOCAL wc:WNDCLASSEX  
    LOCAL msg:MSG  
    LOCAL hwnd:HWND  
    mov   wc.cbSize,SIZEOF WNDCLASSEX  
    mov   wc.style, CS_HREDRAW or CS_VREDRAW  
    mov   wc.lpfnWndProc, OFFSET WndProc  
    mov   wc.cbClsExtra,NULL  
    mov   wc.cbWndExtra,NULL  
    push  hInstance  
    pop   wc.hInstance  
    mov   wc.hbrBackground,COLOR_WINDOW+1  
    mov   wc.lpszMenuName,NULL  
    mov   wc.lpszClassName,OFFSET ClassName  
    invoke LoadIcon,NULL,IDI_APPLICATION  
    mov   wc.hIcon,eax  
    mov   wc.hIconSm,eax  
    invoke LoadCursor,NULL,IDC_ARROW  
    mov   wc.hCursor,eax  
    invoke RegisterClassEx, addr wc  
    INVOKE CreateWindowEx,NULL,ADDR ClassName,ADDR AppName,\  
              WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,\  
  
              CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,NULL,NULL,\  
  
              hInst,NULL  
  
    mov   hwnd,eax  
    invoke ShowWindow, hwnd,SW_SHOWNORMAL  
    invoke UpdateWindow, hwnd  
    .while TRUE  
     invoke GetMessage, ADDR msg,NULL,0,0  
     .break .if (!eax)  
     invoke TranslateMessage, ADDR msg  
     invoke DispatchMessage, ADDR msg  
    .endw  
    mov     eax,msg.wParam  
    ret  
   WinMain endp  
 WndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM  
      LOCAL ps:PAINTSTRUCT  
      LOCAL hdc:HDC  
      LOCAL hMemDC:HDC  
      LOCAL rect:RECT  
      .if uMsg==WM_CREATE  
         invoke LoadBitmap,hInstance,IDB_MAIN  
  
         mov hBitmap,eax  
      .elseif uMsg==WM_PAINT  
         invoke BeginPaint,hWnd,addr ps  
  
         mov    hdc,eax  
  
         invoke CreateCompatibleDC,hdc  
  
         mov    hMemDC,eax  
  
         invoke SelectObject,hMemDC,hBitmap  
  
         invoke GetClientRect,hWnd,addr rect  
  
         invoke BitBlt,hdc,0,0,rect.right,rect.bottom,hMemDC,0,0,SRCCOPY  
  
         invoke DeleteDC,hMemDC  
         invoke EndPaint,hWnd,addr ps  
  
    .elseif uMsg==WM_DESTROY  
     invoke DeleteObject,hBitmap  
     invoke PostQuitMessage,NULL  
    .ELSE  
     invoke DefWindowProc,hWnd,uMsg,wParam,lParam  
     ret  
    .ENDIF  
    xor eax,eax  
    ret  
   WndProc endp  
   end start  
 ;---------------------------------------------------------------------  
  
   ;                            
  资源定义
   ;---------------------------------------------------------------------  
  
   #define IDB_MAIN 1  
   IDB_MAIN BITMAP "tweety78.bmp"  
#define IDB_MAIN 1定义整数宏IDB_MAIN的值为1,然后把它指向一个与资源文件处于相同目录文件名为“tweety.bmp"的位图。
IDB_MAIN BITMAP "tweety78.bmp"
    .if uMsg==WM_CREATE  
         invoke LoadBitmap,hInstance,IDB_MAIN  
  
         mov hBitmap,eax  
在处理 WM_CREATE 消息时, 我们通过API函数 LoadBitmap 载入位图资源,并通过函数
返回值取得位图句柄。 
  然后,我们就可以把位图画在窗口客户区上。 
    .elseif uMsg==WM_PAINT  
         invoke BeginPaint,hWnd,addr ps  
  
         mov    hdc,eax  
  
         invoke CreateCompatibleDC,hdc  
  
         mov    hMemDC,eax  
  
         invoke SelectObject,hMemDC,hBitmap  
  
         invoke GetClientRect,hWnd,addr rect  
  
         invoke BitBlt,hdc,0,0,rect.right,rect.bottom,hMemDC,0,0,SRCCOPY  
  
         invoke DeleteDC,hMemDC  
         invoke EndPaint,hWnd,addr ps  
在本例中,我们选用在响应WM_PAINT消息时画出位图。首先我们通过API函数l BeginPaint 获得窗口客户区的DC句柄。 接着我们通过API函数 CreateCompatibleDC 创建该DC 的内存映像,并通过API函数 SelectObject 把位图放进内存映像中。下一步,我们通过API函数 GetClientRect 取得窗口客户区的大小。最后,我们通过API函数 BitBlt 把位图从DC内存映像复制到真正的客户区DC中。 完成显示工作后,我们通过API函数 DeleteDC 释放DC内存映像,并用API函数 EndPaint 释放客户区DC, 结束画图工作。
.elseif uMsg==WM_DESTROY当我们不再需要位图时,通过API函数 DeleteObject 把它释放。
invoke DeleteObject,hBitmap
invoke PostQuitMessage,NULL