⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 14. 位图和bitblt.txt

📁 本书介绍了在Microsoft Windows 98、Microsoft Windows NT 4.0和Windows NT 5.0下程序写作的方法
💻 TXT
📖 第 1 页 / 共 5 页
字号:

现在情况是这样:SelectObject呼叫以后,DDB就是内存设备内容的显示平面。处理实际设备内容的每项操作,您几乎都可以用于内存设备内容。例如,如果用GDI画图函数在内存设备内容中画图,那么图像将画在位图上。这是非常有用的。还可以将内存设备内容作为来源,把视讯设备内容作为目的来呼叫BitBlt。这就是在显示器上绘制位图的方法。如果把视讯设备内容作为来源,把内存设备内容作为目的,那么呼叫BitBlt可将屏幕上的一些内容复制给位图。我们将看到这些都是可能的。

载入位图资源


除了各种各样的位图建立函数以外,获得GDI位图对象句柄的另一个方法就是呼叫LoadBitmap函数。使用此函数,您不必担心位图格式。在程序中,您只需简单地按资源来建立位图,这与建立图标或者鼠标光标的方法类似。LoadBitmap函数的语法与LoadIcon和LoadCursor相同:

hBitmap = LoadBitmap (hInstance, szBitmapName) ;
        
如果想加载系统位图,那么将第一个参数设为NULL。这些不同的位图是Windows视觉接口(例如关闭方块和勾选标记)的一小部分,它们的标识符以字母OBM开始。如果位图与整数标识符而不是与名称有联系,那么第二个参数就可以使用MAKEINTRESOURCE宏。由LoadBitmap加载的所有位图最终应用DeleteObject清除。

如果位图资源是单色的,那么从LoadBitmap传回的句柄将指向一个单色的位图对象。如果位图资源不是单色,那么从LoadBitmap传回的句柄将指向一个GDI位图对象,该对象与执行程序的视讯显示器有相同的色彩组织。因此,位图始终与视讯显示器兼容,并且总是选进与视讯显示器兼容的内存设备内容中。采用LoadBitmap呼叫后,就不用担心任何色彩转换的问题了。在下一章中,我们就知道LoadBitmap的具体运作方式了。

程序14-3所示的BRICKS1程序示范了加载一小张单色位图资源的方法。此位图本身不像砖块,但当它水平和垂直重复时,就与砖墙相似了。

程序14-3  BRICKS1
        
BRICKS1.C
        
/*--------------------------------------------------------------------------
        
  BRICKS1.C -- LoadBitmap Demonstration
        
                                                         (c) Charles Petzold, 1998
        
----------------------------------------------------------------------------*/
        
#include <windows.h>
        
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
        
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
        
                          PSTR szCmdLine, int iCmdShow)
        
{
        
           static TCHAR szAppName [] = TEXT ("Bricks1") ;
        
           HWND                         hwnd ;
        
           MSG                           msg ;
        
           WNDCLASS                      wndclass ;
        

           wndclass.style                               = CS_HREDRAW | CS_VREDRAW ;
        
           wndclass.lpfnWndProc                         = WndProc ;
        
           wndclass.cbClsExtra                          = 0 ;
        
          wndclass.cbWndExtra                          = 0 ;
        
           wndclass.hInstance                           = hInstance ;
        
           wndclass.hIcon                               = LoadIcon (NULL, IDI_APPLICATION) ;
        
           wndclass.hCursor                             = LoadCursor (NULL, IDC_ARROW) ;
        
           wndclass.hbrBackground              = (HBRUSH) GetStockObject (WHITE_BRUSH) ;
        
           wndclass.lpszMenuName                = NULL ;
        
           wndclass.lpszClassName               = szAppName ;
        
   
        
           if (!RegisterClass (&wndclass))
        
           {
        
                  MessageBox (NULL, TEXT ("This program requires Windows NT!"),
        
                                                        szAppName, MB_ICONERROR) ;
        
                  return 0 ;
        
    }
        
   
        
           hwnd = CreateWindow ( szAppName, TEXT ("LoadBitmap Demo"),
        
                                  WS_OVERLAPPEDWINDOW,
        
                                  CW_USEDEFAULT, CW_USEDEFAULT,
        
                                CW_USEDEFAULT, CW_USEDEFAULT,
        
                                  NULL, NULL, hInstance, NULL) ;
        

           ShowWindow (hwnd, iCmdShow) ;
        
           UpdateWindow (hwnd) ;
        

           while (GetMessage (&msg, NULL, 0, 0))
        
           {
        
                          TranslateMessage (&msg) ;
        
                         DispatchMessage (&msg) ;
        
           }
        
           return msg.wParam ;
        
}
        

LRESULT CALLBACK WndProc ( HWND hwnd, UINT message, WPARAM wParam,LPARAM lParam)
        
{
        
           static HBITMAP hBitmap ;
        
           static int                    cxClient, cyClient, cxSource, cySource ;
        
           BITMAP                        bitmap ;
        
           HDC                           hdc, hdcMem ;
        
           HINSTANCE                     hInstance ;
        
           int                           x, y ;
        
           PAINTSTRUCT                   ps ;
        
   
        
           switch (message)
        
           {
        
           case   WM_CREATE:
        
                          hInstance = ((LPCREATESTRUCT) lParam)->hInstance ;
        

                         hBitmap = LoadBitmap (hInstance, TEXT ("Bricks")) ;
        

                          GetObject (hBitmap, sizeof (BITMAP), &bitmap) ;
        

                          cxSource = bitmap.bmWidth ;
        
                          cySource = bitmap.bmHeight ;
        

                          return 0 ;
        

           case   WM_SIZE:
        
                          cxClient = LOWORD (lParam) ;
        
                          cyClient = HIWORD (lParam) ;
        
                          return 0 ;
        

           case   WM_PAINT:
        
                          hdc = BeginPaint (hwnd, &ps) ;
        

                          hdcMem = CreateCompatibleDC (hdc) ;
        
                          SelectObject (hdcMem, hBitmap) ;
        

                         for (y = 0 ; y < cyClient ; y += cySource)
        
                          for (x = 0 ; x < cxClient ; x += cxSource)
        
                          {
        
                          BitBlt (hdc, x, y, cxSource, cySource, hdcMem, 0, 0, SRCCOPY) ;
        
         }
        

                          DeleteDC (hdcMem) ;
        
                          EndPaint (hwnd, &ps) ;
        
                          return 0 ;
        
          
        
    case   WM_DESTROY:
        
                          DeleteObject (hBitmap) ;
        
                          PostQuitMessage (0) ;
        
                          return 0 ;
        
           }
        
           return DefWindowProc (hwnd, message, wParam, lParam) ;
        
}
        
BRICKS1.RC (摘录)
        
//Microsoft Developer Studio generated resource script.
        
#include "resource.h"
        
#include "afxres.h"
        
/////////////////////////////////////////////////////////////////////////////
        
// Bitmap
        
BRICKS                                    BITMAP  DISCARDABLE     "Bricks.bmp"
        
BRICKS.BMP
 


 



在Visual C++ Developer Studio中建立位图时,应指明位图的高度和宽度都是8个图素,是单色,名称是「Bricks」。BRICKS1程序在WM_CREATE消息处理期间加载了位图并用GetObject来确定位图的图素尺寸(以便当位图不是8图素见方时程序仍能继续工作)。以后,BRICKS1将在WM_DESTROY消息中删除此位图。

在WM_PAINT消息处理期间,BRICKS1建立了一个与显示器兼容的内存设备内容,并且选进了位图。然后是从内存设备内容到显示区域设备内容一系列的BitBlt函数呼叫,再删除内存设备内容。图14-3显示了程序的执行结果。

顺便说一下,Developer Studio建立的BRICKS.BMP文件是一个设备无关位图。您可能想在Developer Studio内建立一个彩色的BRICKS.BMP文件(您可自己选定颜色),并且保证一切工作正常。

我们看到DIB能转换成与视讯显示器兼容的GDI位图对象。我们将在下一章看到这是如何操作的。


 



图14-3 BRICKS1的屏幕显示
 

单色位图格式


如果您在处理小块单色图像,那么您不必把它们当成资源来建立。与彩色位图对象不同,单色位的格式相对简单一些,而且几乎能全部从您要建立的图像中分离出来。例如,假定您要建立下图所示的位图:


 



您能写下一系列的位(0代表黑色,1代表白色),这些位直接对应于网格。从左到右读这些位,您能给每8字节配置一个十六进制元的字节值。如果位图的宽度不是16的倍数,在字节的右边用零填充,以得到偶数个字节:

0 1 0 1 0 0 0 1 0 1 1 1 0 1 1 1 0 0 0 1 = 51 77 10 00
        
0 1 0 1 0 1 1 1 0 1 1 1 0 1 1 1 0 1 0 1 = 57 77 50 00
        
0 0 0 1 0 0 1 1 0 1 1 1 0 1 1 1 0 1 0 1 = 13 77 50 00
        
0 1 0 1 0 1 1 1 0 1 1 1 0 1 1 1 0 1 0 1 = 57 77 50 00
        
0 1 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 = 51 11 10 00
        
图素宽为20,扫描线高为5,字节宽为4。您可以用下面的叙述来设定此位图的BITMAP结构:

static BITMAP bitmap               = { 0, 20, 5, 4, 1, 1 } ;
        
并且可以将位储存在BYTE数组中:

static BYTE  bits []       = {    0x51, 0x77, 0x10, 0x00,
        
                                  0x57, 0x77, 0x50, 0x00,
        
                                         0x13, 0x77, 0x50, 0x00,
        
                             0x57, 0x77, 0x50, 0x00,
        
                               0x51, 0x11, 0x10, 0x00 } ;
        
用CreateBitmapIndirect来建立位图需要下面两条叙述:

bitmap.bmBits = (PSTR) bits ;
        
hBitmap = CreateBitmapIndirect (&bitmap) ;
        
另一种方法是:

hBitmap = CreateBitmapIndirect (&bitmap) ;
        
SetBitmapBits (hBitmap, sizeof bits, bits) ;
        
您也可以用一道叙述来建立位图:

hBitmap = CreateBitmap (20, 5, 1, 1, bits) ;
        
在程序14-4显示的BRICKS2程序利用此技术直接建

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -