zoukankan      html  css  js  c++  java
  • VC++界面开发

    1. 根据bitmap位图生成不规则区域

    // BitmapToRegion : Create a region from the "non-transparent" pixels of a bitma
    // Author :  Jean-Edouard Lachand-Robert (http://www.geocities.com/Paris/LeftBank/1160/resume.htm), June 1998
    // hBmp :   Source bitma
    // cTransparentColor : Color base for the "transparent" pixels (default is black
    // cTolerance :  Color tolerance for the "transparent" pixels
    // A pixel is assumed to be transparent if the value of each of its 3 components (blue, green and red) is
    // greater or equal to the corresponding value in cTransparentColor and is lower or equal to the
    // corresponding value in cTransparentColor + cTolerance
    
    HRGN BitmapToRegion (HBITMAP hBmp, COLORREF cTransparentColor = 0, COLORREF cTolerance = 0x101010)
    {
     HRGN hRgn = NULL;
    
     ASSERT(hBmp);
     if (hBmp)
     {
      // Create a memory DC inside which we will scan the bitmap conten
      HDC hMemDC = CreateCompatibleDC(NULL);
      ASSERT(hMemDC);
      if (hMemDC)
      {
       // Get bitmap siz
       BITMAP bm;
       GetObject(hBmp, sizeof(bm), &bm);
    
       // Create a 32 bits depth bitmap and select it into the memory DC
       BITMAPINFOHEADER RGB32BITSBITMAPINFO = { 
         sizeof(BITMAPINFOHEADER), // biSize
         bm.bmWidth,     // biWidth;
         bm.bmHeight,    // biHeight;
         1,       // biPlanes;
         32,       // biBitCount
         BI_RGB,      // biCompression;
         0,       // biSizeImage;
         0,       // biXPelsPerMeter;
         0,       // biYPelsPerMeter;
         0,       // biClrUsed;
         0       // biClrImportant;
       };
       VOID * pbits32; 
       HBITMAP hbm32 = CreateDIBSection(hMemDC, (BITMAPINFO *)&RGB32BITSBITMAPINFO, DIB_RGB_COLORS, &pbits32, NULL, 0);
       ASSERT(hbm32);
       if (hbm32)
       {
        HBITMAP holdBmp = (HBITMAP)SelectObject(hMemDC, hbm32);
    
        // Create a DC just to copy the bitmap into the memory D
        HDC hDC = CreateCompatibleDC(hMemDC);
        ASSERT(hDC);
        if (hDC)
        {
         // Get how many bytes per row we have for the bitmap bits (rounded up to 32 bits
         BITMAP bm32;
         VERIFY(GetObject(hbm32, sizeof(bm32), &bm32));
         while (bm32.bmWidthBytes % 4)
          bm32.bmWidthBytes++;
    
         // Copy the bitmap into the memory D
         HBITMAP holdBmp = (HBITMAP)SelectObject(hDC, hBmp);
         VERIFY(BitBlt(hMemDC, 0, 0, bm.bmWidth, bm.bmHeight, hDC, 0, 0, SRCCOPY));
    
         // For better performances, we will use the ExtCreateRegion() function to create th
         // region. This function take a RGNDATA structure on entry. We will add rectangles b
         // amount of ALLOC_UNIT number in this structure
         #define ALLOC_UNIT 100
         DWORD maxRects = ALLOC_UNIT;
         HANDLE hData = GlobalAlloc(GMEM_MOVEABLE, sizeof(RGNDATAHEADER) + (sizeof(RECT) * maxRects));
         RGNDATA *pData = (RGNDATA *)GlobalLock(hData);
         pData->rdh.dwSize = sizeof(RGNDATAHEADER);
         pData->rdh.iType = RDH_RECTANGLES;
         pData->rdh.nCount = pData->rdh.nRgnSize = 0;
         SetRect(&pData->rdh.rcBound, MAXLONG, MAXLONG, 0, 0);
    
         // Keep on hand highest and lowest values for the "transparent" pixel
         BYTE lr = GetRValue(cTransparentColor);
         BYTE lg = GetGValue(cTransparentColor);
         BYTE lb = GetBValue(cTransparentColor);
         BYTE hr = min(0xff, lr + GetRValue(cTolerance));
         BYTE hg = min(0xff, lg + GetGValue(cTolerance));
         BYTE hb = min(0xff, lb + GetBValue(cTolerance));
    
         // Scan each bitmap row from bottom to top (the bitmap is inverted vertically
         BYTE *p32 = (BYTE *)bm32.bmBits + (bm32.bmHeight - 1) * bm32.bmWidthBytes;
         for (int y = 0; y < bm.bmHeight; y++)
         {
          // Scan each bitmap pixel from left to righ
          for (int x = 0; x < bm.bmWidth; x++)
          {
           // Search for a continuous range of "non transparent pixels"
           int x0 = x;
           LONG *p = (LONG *)p32 + x;
           while (x < bm.bmWidth)
           {
            BYTE b = GetRValue(*p);
            if (b >= lr && b <= hr)
            {
             b = GetGValue(*p);
             if (b >= lg && b <= hg)
             {
              b = GetBValue(*p);
              if (b >= lb && b <= hb)
               // This pixel is "transparent"
               break;
             }
            }
            p++;
            x++;
           }
    
           if (x > x0)
           {
            // Add the pixels (x0, y) to (x, y+1) as a new rectangle in the regio
            if (pData->rdh.nCount >= maxRects)
            {
             GlobalUnlock(hData);
             maxRects += ALLOC_UNIT;
             VERIFY(hData = GlobalReAlloc(hData, sizeof(RGNDATAHEADER) + (sizeof(RECT) * maxRects), GMEM_MOVEABLE));
             pData = (RGNDATA *)GlobalLock(hData);
             ASSERT(pData);
            }
            RECT *pr = (RECT *)&pData->Buffer;
            SetRect(&pr[pData->rdh.nCount], x0, y, x, y+1);
            if (x0 < pData->rdh.rcBound.left)
             pData->rdh.rcBound.left = x0;
            if (y < pData->rdh.rcBound.top)
             pData->rdh.rcBound.top = y;
            if (x > pData->rdh.rcBound.right)
             pData->rdh.rcBound.right = x;
            if (y+1 > pData->rdh.rcBound.bottom)
             pData->rdh.rcBound.bottom = y+1;
            pData->rdh.nCount++;
    
            // On Windows98, ExtCreateRegion() may fail if the number of rectangles is to
            // large (ie: > 4000). Therefore, we have to create the region by multiple steps
            if (pData->rdh.nCount == 2000)
            {
             HRGN h = ExtCreateRegion(NULL, sizeof(RGNDATAHEADER) + (sizeof(RECT) * maxRects), pData);
             ASSERT(h);
             if (hRgn)
             {
              CombineRgn(hRgn, hRgn, h, RGN_OR);
              DeleteObject(h);
             }
             else
              hRgn = h;
             pData->rdh.nCount = 0;
             SetRect(&pData->rdh.rcBound, MAXLONG, MAXLONG, 0, 0);
            }
           }
          }
    
          // Go to next row (remember, the bitmap is inverted vertically
          p32 -= bm32.bmWidthBytes;
         }
    
         // Create or extend the region with the remaining rectangle
         HRGN h = ExtCreateRegion(NULL, sizeof(RGNDATAHEADER) + (sizeof(RECT) * maxRects), pData);
         ASSERT(h);
         if (hRgn)
         {
          CombineRgn(hRgn, hRgn, h, RGN_OR);
          DeleteObject(h);
         }
         else
          hRgn = h;
    
         // Clean u
         SelectObject(hDC, holdBmp);
         DeleteDC(hDC);
        }
    
        DeleteObject(SelectObject(hMemDC, holdBmp));
       }
    
       DeleteDC(hMemDC);
      } 
     }
    
     return hRgn;
    }

    2. Guide to WIN32 Regions

    ------------------------------------------------------------------------------------------------------------------

    3. CListCtrl 使用技巧

    4. Let Your ListCtrl Adjust its Column Widths Automatically

    5. CGridListCtrlEx - Grid Control Based on CListCtrl

    6. CListCtrl行高的修改

    7. 用ListView/CListCtrl实现QQ风格的好友列表

    ------------------------------------------------------------------------------------------------------------------

    8. Replace a Window's Internal Scrollbar with a customdraw scrollbar Control

    ------------------------------------------------------------------------------------------------------------------

    9. WM_CTLCOLOR消息的用法

    ------------------------------------------------------------------------------------------------------------------

    10. Spy++原理初探

    ------------------------------------------------------------------------------------------------------------------

    11. 一种实现Win32消息处理处理函数的新方法 - 基于Thunk实现的类成员消息处理函数

    ------------------------------------------------------------------------------------------------------------------

    12. 迅雷下载开放引擎

  • 相关阅读:
    Summary for sql join in Oracle DB
    Merge data into table in Oracle
    PLSQL存储过程传出大量异常错误信息
    oracle 11g plsql解析json数据示例
    识别'低效执行'的SQL语句
    如何开启MySQL 5.7.12 的二进制日志
    Linux下ps命令详解 Linux下ps命令的详细使用方法
    Linux(Unix)时钟同步ntpd服务配置方法
    MySQL 常用命令总结
    MySQL 数据库通过日志恢复
  • 原文地址:https://www.cnblogs.com/pure/p/2511412.html
Copyright © 2011-2022 走看看