Windows程序设计 读书笔记 位图和BitBlt。

一、位图   -- 光栅图像 -- 缩放会失真

  元文件 -- 矢量图像 -- 缩放不失真

二、一些函数:

  1、BitBlt (bit blit)

  直接拷贝位图象素。

  2、BOOL CDC::StretchBlt( int x, int y, int nWidth, int nHeight, CDC* pSrcDC, int xSrc, int ySrc, int nSrcWidth, int nSrcHeight, DWORD dwRop );

  可以缩放、翻转。

  翻转方法:x 表示目的地X坐标,nWidth表示目的地宽度,正的表示向右,负的表示向左。 源的宽度和目的宽度正负不一致,即为翻转。  y坐标同理。

  StretchBlt函数缩放图形会失真,可以用SetStretchBltMode方法来控制失真。

  复制模式dwRop 。这个实际上是在源设备、目标设备和画刷三者之间做逻辑操作。

  3、BOOL CDC::PatBlt( int x, int y, int nWidth, int nHeight, DWORDdwRop );

  图案块传送

  这个函数实际上就是StretchBlt去掉源设备的情况,只是目标设备和画刷之间的逻辑操作。

 

三、GDI位图对象有时候也被称为设备相关位图或DDB。

  DDB依赖于具体设备,它只能存在于内存中(视频内存或系统内存),其颜色模式必须与特定的输出设备相一致,使用系统调色板。一般只能载入色彩较简单的DDB位图,对于颜色较丰富的位图,需使用DIB才能长期保存。

  DDB保存在GDI模式内部,由应用程序软件的数字句柄引用。如:HBITMAP hBitmap;

  创建DDB获得句柄 hBitmap = GreateBitmap(...);//分配并初始化GDI内存中的一些内存来存储关于位图的信息,以及实际位图的位信息。应用程序不能直接访问这段内存。位图与设备描述表无关。

  一般只有在创建单色位图的时候才用GreateBitmap,更多的时候用CreateCompatibleBitmap来简化问题。

  hBitmap = CreateCompatibleBitmap(hdc,cx,cy)创建与设备兼容的位图。

  还有一个创建DDB的函数 hBitmap = CreateBitmapIndirect(&bitmap)

  也可以在创建位图后,设置位图位信息 SetBitmapBits(hBitmap , cBytes,&bits);//一般只用来设置单色。比如用来写字。

  还有一个获得DDB句柄的方法: hBitmap = LoadBitmap(...);//与视频显示器兼容。

  清除内存: DeleteObject(hBitmap);

四、内存设备描述表

  HDC hdcMem = CreateCompatibleDC(hdc); //创建与hdc兼容的内存设备描述表,如果hdc为NULL,那创建与视频显示器相兼容的内存设备描述表。

  SelectObject(hdcMem,hBitmap);//将DDB选入设备描述表。只有选进的位图是单色的,或者和与兼容设备有相同的彩色结构时,SelectObject才会起作用。其实创建兼容设备描述表,就是设定具有相同的彩色结构。

  DeleteDC(hdcMem);//清除。

五、GetTextExtentPoint,判断一个字串的大小(范围)。在Win32环境中,最好使用GetTextExtentPoint32,它提供了更精确的计算结果。

  在设备上写字,然后贴在客户区:

case WM_CREATE:
          hdc = GetDC (hwnd) ;
          hdcMem  = CreateCompatibleDC (hdc) ;

          GetTextExtentPoint32 (hdc, szText, lstrlen (szText), &size) ;
          cxBitmap = size.cx ;
          cyBitmap = size.cy ;
          hBitmap = CreateCompatibleBitmap (hdc, cxBitmap, cyBitmap) ;

          ReleaseDC (hwnd, hdc) ;

          SelectObject (hdcMem, hBitmap) ;
          TextOut (hdcMem, 0, 0, szText, lstrlen (szText)) ;
          return 0 ;
case WM_PAINT:
          hdc = BeginPaint (hwnd, &ps) ;

          switch (iSize)
          {
          case IDM_BIG:
               StretchBlt (hdc, 0, 0, cxClient, cyClient, 
                           hdcMem, 0, 0, cxBitmap, cyBitmap, SRCCOPY) ;
               break ;

          case IDM_SMALL:
               for (y = 0 ; y < cyClient ; y += cyBitmap)
               for (x = 0 ; x < cxClient ; x += cxBitmap)
               {
                    BitBlt (hdc, x, y, cxBitmap, cyBitmap, 
                            hdcMem, 0, 0, SRCCOPY) ;
               }
               break ;
          }

          EndPaint (hwnd, &ps) ;
          return 0 ;

  六、GetObject(ByVal hObject As Long, ByVal nCount As Long, lpObject As Any)取得对指定对象进行说明的一个结构。如获取HBITMAP大小。对于不同的Object,如BITMAP、画刷等,返回的结构体不同。

  七、掩码。

  掩码的实质就是通过SRCCOPY、SRCAND.....这类的参数,用BitBlt这类的方法,将源DC复制到目的DC。

  原理:黑色为0,白色为1,  然后用包含白色或黑色位图的源DC,对目的DC进行逻辑运算。

  范例:

LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
static HBITMAP hBitmapImag, hBitmapMask ;
static HINSTANCE hInstance ;
static int cxClient, cyClient, cxBitmap, cyBitmap ;
BITMAP bitmap ;
HDC hdc, hdcMemImag, hdcMemMask ;
int x, y ;
PAINTSTRUCT ps ;

switch (message)
{
case WM_CREATE:
hInstance = ((LPCREATESTRUCT) lParam)->hInstance ;

// Load the original image and get its size

hBitmapImag = LoadBitmap (hInstance, TEXT ("Matthew")) ;
GetObject (hBitmapImag, sizeof (BITMAP), &bitmap) ;
cxBitmap = bitmap.bmWidth ;
cyBitmap = bitmap.bmHeight ;

// Select the original image into a memory DC

hdcMemImag = CreateCompatibleDC (NULL) ;
SelectObject (hdcMemImag, hBitmapImag) ;

// Create the monochrome mask bitmap and memory DC

hBitmapMask = CreateBitmap (cxBitmap, cyBitmap, 1, 1, NULL) ;
hdcMemMask = CreateCompatibleDC (NULL) ;
SelectObject (hdcMemMask, hBitmapMask) ;

// Color the mask bitmap black with a white ellipse

SelectObject (hdcMemMask, GetStockObject (BLACK_BRUSH)) ;
Rectangle (hdcMemMask, 0, 0, cxBitmap, cyBitmap) ;
SelectObject (hdcMemMask, GetStockObject (WHITE_BRUSH)) ;
Ellipse (hdcMemMask, 0, 0, cxBitmap, cyBitmap) ;

// Mask the original image

BitBlt (hdcMemImag, 0, 0, cxBitmap, cyBitmap,
hdcMemMask, 0, 0, SRCAND) ;

DeleteDC (hdcMemImag) ;
DeleteDC (hdcMemMask) ;

return 0 ;

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

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

// Select bitmaps into memory DCs

hdcMemImag = CreateCompatibleDC (hdc) ;
SelectObject (hdcMemImag, hBitmapImag) ;

hdcMemMask = CreateCompatibleDC (hdc) ;
SelectObject (hdcMemMask, hBitmapMask) ;

// Center image

x = (cxClient - cxBitmap) / 2 ;
y = (cyClient - cyBitmap) / 2 ;

// Do the bitblts

BitBlt (hdc, x, y, cxBitmap, cyBitmap, hdcMemMask, 0, 0, 0x220326) ;
BitBlt (hdc, x, y, cxBitmap, cyBitmap, hdcMemImag, 0, 0, SRCPAINT) ;

DeleteDC (hdcMemImag) ;
DeleteDC (hdcMemMask) ;

EndPaint (hwnd, &ps) ;
return 0 ;

case WM_DESTROY:
DeleteObject (hBitmapImag) ;
DeleteObject (hBitmapMask) ;
DeleteDC(mydc);
PostQuitMessage (0) ;
return 0 ;
}
return DefWindowProc (hwnd, message, wParam, lParam) ;
}

八、创建一副位图,并对他进行操作:

hdc = GetDC (hwnd) ;
          hdcMem = CreateCompatibleDC (hdc) ;
          hBitmap = CreateCompatibleBitmap (hdc, cxTotal, cyTotal) ;
          ReleaseDC (hwnd, hdc) ;
          
          SelectObject (hdcMem, hBitmap) ;
          Rectangle (hdcMem, -1, -1, cxTotal + 1, cyTotal + 1) ;
          
          hBrush = CreateHatchBrush (HS_DIAGCROSS, 0L) ;
          SelectObject (hdcMem, hBrush) ;
          SetBkColor (hdcMem, RGB (255, 0, 255)) ;
          Ellipse (hdcMem, cxMove, cyMove, cxTotal - cxMove, cyTotal - cyMove) ;
          DeleteDC (hdcMem) ;
          DeleteObject (hBrush) ;

九、

  hwnd = GetDesktopWindow () //获取桌面窗口句柄

  LockWindowUpdate(hwnd)//禁止窗口被其他程序刷新

  LockWindowUpdate (NULL) ;//取消禁止

  GetDCEx (hwnd, NULL, DCX_CACHE | DCX_LOCKWINDOWUPDATE) ;

原文地址:https://www.cnblogs.com/aoyihuashao/p/1721339.html