百度首页 | 百度空间
 
查看文章
 
Windows编程常用技巧(2)
2008年05月18日 星期日 17:17
14.如何将32 x 32像素图标转换为16 x 16像素值的图标

HICON Convert32x32IconTo16x16(HICON h32x32Icon)
{
  HDC hMainDC, hMemDC1, hMemDC2;
  HICON h16x16Icon;
  BITMAP bmp;
  HBITMAP hOldBmp1, hOldBmp2;
  ICONINFO IconInfo32x32, IconInfo16x16;
  GetIconInfo(h32x32Icon, &IconInfo32x32);
  hMainDC = ::GetDC(m_hWnd);
  hMemDC1 = CreateCompatibleDC(hMainDC);
  hMemDC2 = CreateCompatibleDC(hMainDC);
  GetObject(IconInfo32x32.hbmColor, sizeof(BITMAP), &bmp);
  IconInfo16x16.hbmColor = CreateBitmap( 16, 16, 
                                         bmp.bmPlanes,
                                         bmp.bmBitsPixel,
                                         NULL);

  hOldBmp1 = (HBITMAP) SelectObject( hMemDC1, 
                                     IconInfo32x32.hbmColor);
  hOldBmp2 = (HBITMAP) SelectObject( hMemDC2,
                                     IconInfo16x16.hbmColor);
  StretchBlt(hMemDC2,
       0, 0,
       16, 16,
       hMemDC1,
       0, 0,
       32, 32,
       SRCCOPY
       );
  GetObject(IconInfo32x32.hbmMask, sizeof(BITMAP), &bmp);
  IconInfo16x16.hbmMask = CreateBitmap( 16, 16, 
                                        bmp.bmPlanes, 
                                        bmp.bmBitsPixel,
                                        NULL);
  SelectObject(hMemDC1, IconInfo32x32.hbmMask);
  SelectObject(hMemDC2, IconInfo16x16.hbmMask);
  StretchBlt(hMemDC2,
             0, 0,
             16, 16,
             hMemDC1,
             0, 0,
             32, 32,
             SRCCOPY
       );
  SelectObject(hMemDC1, hOldBmp1);
  SelectObject(hMemDC2, hOldBmp2);
  IconInfo16x16.fIcon = TRUE;
  h16x16Icon = CreateIconIndirect(&IconInfo16x16);
  DeleteObject(IconInfo32x32.hbmColor);
  DeleteObject(IconInfo16x16.hbmColor);
  DeleteObject(IconInfo32x32.hbmMask);
  DeleteObject(IconInfo16x16.hbmMask);
  DeleteDC(hMemDC1);
  DeleteDC(hMemDC2);
  ::ReleaseDC(m_hWnd, hMainDC);
  return h16x16Icon;
}

15.如何建立一个灰度级图标


HICON CreateGrayscaleIcon(HICON hIcon)
{
  HICON       hGrayIcon = NULL;
  HDC         hMainDC = NULL, 
              hMemDC1 = NULL, 
              hMemDC2 = NULL;
  BITMAP      bmp;
  HBITMAP     hOldBmp1 = NULL,
              hOldBmp2 = NULL;
  ICONINFO    csII, csGrayII;
  BOOL        bRetValue = FALSE;

  bRetValue = ::GetIconInfo(hIcon, &csII);
  if (bRetValue == FALSE) return NULL;
  hMainDC = ::GetDC(m_hWnd);
  hMemDC1 = ::CreateCompatibleDC(hMainDC);
  hMemDC2 = ::CreateCompatibleDC(hMainDC);
  if (hMainDC == NULL || 
    hMemDC1 == NULL ||
    hMemDC2 == NULL) 
      return NULL;
  if (::GetObject(csII.hbmColor, 
                sizeof(BITMAP), &
                amp;bmp))
  {
    csGrayII.hbmColor = 
         ::CreateBitmap(csII.xHotspot*2,
                        csII.yHotspot*2, 
                        bmp.bmPlanes, 
                        bmp.bmBitsPixel, 
                        NULL);
    if (csGrayII.hbmColor)
    {
      hOldBmp1 =
         (HBITMAP)::SelectObject(hMemDC1,
                                 csII.hbmColor);
      hOldBmp2 = 
         (HBITMAP)::SelectObject(hMemDC2,
                                 csGrayII.hbmColor);

      ::BitBlt(hMemDC2, 0, 0, csII.xHotspot*2,
               csII.yHotspot*2, hMemDC1, 0, 0,
               SRCCOPY);

      DWORD    dwLoopY = 0, dwLoopX = 0;
      COLORREF crPixel = 0;
      BYTE     byNewPixel = 0;

      for (dwLoopY = 0; dwLoopY < csII.yHotspot*2; dwLoopY++)
      {
        for (dwLoopX = 0; dwLoopX < csII.xHotspot*2; dwLoopX++)
        {
          crPixel = ::GetPixel(hMemDC2, dwLoopX, dwLoopY);

          byNewPixel = (BYTE)((GetRValue(crPixel) * 0.299) +
               (GetGValue(crPixel) * 0.587) +
               (GetBValue(crPixel) * 0.114));
          if (crPixel) ::SetPixel(hMemDC2,
                                  dwLoopX,
                                  dwLoopY,
                                  RGB(byNewPixel,
                                  byNewPixel,
                                  byNewPixel));
        } // for
      } // for

      ::SelectObject(hMemDC1, hOldBmp1);
      ::SelectObject(hMemDC2, hOldBmp2);

      csGrayII.hbmMask = csII.hbmMask;

      csGrayII.fIcon = TRUE;
      hGrayIcon = ::CreateIconIndirect(&csGrayII);
    } // if

    ::DeleteObject(csGrayII.hbmColor);
    //::DeleteObject(csGrayII.hbmMask);
  } // if

  ::DeleteObject(csII.hbmColor);
  ::DeleteObject(csII.hbmMask);
  ::DeleteDC(hMemDC1);
  ::DeleteDC(hMemDC2);
  ::ReleaseDC(m_hWnd, hMainDC);

  return hGrayIcon;
}


16.如何按指定角度旋转显示内存位图(用法和BitBlt类似)

void RotBlt(HDC destDC, int srcx1, int srcy1, int srcx2, int srcy2,
  HDC srcDC , int destx1, int desty1 ,int thetaInDegrees ,DWORD mode)
{
  double theta = thetaInDegrees * (3.14159/180);

  //原图像原始大小
  int width = srcx2 - srcx1;
  int height = srcy2 - srcy1;

  //原图像中心点
  int centreX = int(float(srcx2 + srcx1)/2);
  int centreY = int(float(srcy2 + srcy1)/2);

  //判断出图像可以沿任意方向旋转的矩形框
  if(width>height)height = width;
  else
    width = height;
  HDC memDC = CreateCompatibleDC(destDC);
  HBITMAP memBmp = CreateCompatibleBitmap(destDC, width, height);
  HBITMAP obmp = (HBITMAP) SelectObject(memDC, memBmp);
  //内存DC新在中心点
  int newCentre = int(float(width)/2);
  //开始旋转
  for(int x = srcx1; x<=srcx2; x++)
    for(int y = srcy1; y<=srcy2; y++)
    {
      COLORREF col = GetPixel(srcDC,x,y);
      int newX = int((x-centreX)*sin(theta)+(y-centreY)*cos(theta));
      int newY = int((x-centreX)*cos(theta)-(y-centreY)*sin(theta));
      SetPixel(memDC , newX + newCentre, newY + newCentre, col);
    }

  //复制到目标DC上
  BitBlt(destDC, destx1, desty1, width, height, memDC, 0,0,mode);
  //释放内存
  SelectObject(memDC, obmp);
  DeleteDC(memDC);
  DeleteObject(memBmp);
}


用法:

RotBlt(dc, 0,0,150,150,memDC,200,0, 45, SRCCOPY);


17.如何将指定的窗体,以位图形式复制到系统剪切板上













void CScreenSnapDlg::toClipboard_Bio(CWnd * wnd, BOOL FullWnd)
{
     CDC *dc;
     if(FullWnd)
        { /* 抓取整个窗口 */
   dc = new CWindowDC(wnd);
        } /* 抓取整个窗口 */
     else
        { /* 仅抓取客户区时 */
   dc = new CClientDC(wnd);
        } /* 仅抓取客户区时 */

     CDC memDC;
     memDC.CreateCompatibleDC(dc);

     CBitmap bm;
     CRect r;
     if(FullWnd)
        wnd->GetWindowRect(&r);
     else
         wnd->GetClientRect(&r);
     CString s;
     wnd->GetWindowText(s);
     CSize sz(r.Width(), r.Height());
     bm.CreateCompatibleBitmap(dc, sz.cx, sz.cy);
     CBitmap * oldbm = memDC.SelectObject(&bm);
     memDC.BitBlt(0, 0, sz.cx, sz.cy, dc, 0, 0, SRCCOPY);
     //直接调用OpenClipboard(),而不用wnd->GetParent()->OpenClipboard();
  wnd->OpenClipboard();
     ::EmptyClipboard();
     ::SetClipboardData(CF_BITMAP, bm.m_hObject);
     CloseClipboard();
  //恢复原始环境
     memDC.SelectObject(oldbm);
     bm.Detach();  
  delete dc;
}


18.如何替换HBITMAP中的颜色值

#define COLORREF2RGB(Color) (Color & 0xff00) | ((Color >> 16) & 0xff) \
                                             | ((Color << 16) & 0xff0000)
HBITMAP ReplaceColor (HBITMAP hBmp,COLORREF cOldColor,COLORREF cNewColor)
{
    HBITMAP RetBmp=NULL;
    if (hBmp)
    {    
        HDC BufferDC=CreateCompatibleDC(NULL);     // 源位图DC
        if (BufferDC)
        {
            SelectObject(BufferDC,hBmp);   // 选入DC中
            
            HDC DirectDC=CreateCompatibleDC(NULL);      // 目标DC
            if (DirectDC)
            {
                // 获取源位图大小
                BITMAP bm;
                GetObject(hBmp, sizeof(bm), &bm);
                
                // 初始化BITMAPINFO信息,以便使用CreateDIBSection
                BITMAPINFO RGB32BitsBITMAPINFO; 
                ZeroMemory(&RGB32BitsBITMAPINFO,sizeof(BITMAPINFO));
                RGB32BitsBITMAPINFO.bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
                RGB32BitsBITMAPINFO.bmiHeader.biWidth=bm.bmWidth;
                RGB32BitsBITMAPINFO.bmiHeader.biHeight=bm.bmHeight;
                RGB32BitsBITMAPINFO.bmiHeader.biPlanes=1;
                RGB32BitsBITMAPINFO.bmiHeader.biBitCount=32;
                UINT * ptPixels;    
                HBITMAP DirectBitmap= CreateDIBSection(DirectDC,
                                              (BITMAPINFO *)&RGB32BitsBITMAPINFO, 
                                              DIB_RGB_COLORS,(void **)&ptPixels, 
NULL, 0);
                if (DirectBitmap)
                {
                    HGDIOBJ PreviousObject=SelectObject(DirectDC, DirectBitmap);
BitBlt(DirectDC,0,0,bm.bmWidth,bm.bmHeight,BufferDC,0,0,SRCCOPY);
                    // 转换 COLORREF 为 RGB
                    cOldColor=COLORREF2RGB(cOldColor);
                    cNewColor=COLORREF2RGB(cNewColor);
                    // 替换颜色
                    for (int i=((bm.bmWidth*bm.bmHeight)-1);i>=0;i--)
                    {
                        if (ptPixels[i]==cOldColor) ptPixels[i]=cNewColor;
                    }
                    // 修改位图 DirectBitmap
                    SelectObject(DirectDC,PreviousObject);
                    // 完成
                    RetBmp=DirectBitmap;
                }
                // 释放DC
                DeleteDC(DirectDC);
            }
            // 释放DC
            DeleteDC(BufferDC);
        }
    }
    return RetBmp;
}


用法:

HBITMAP hBmp2 = LoadBitmap(g_hinstance,MAKEINTRESOURCE(IDB_SAMPLEBITMAP));
HBITMAP hBmp = ReplaceColor(hBmp2,0xff0000,0x00ff00); // 替换蓝色为绿色
......
DeleteObject(hBmp2);
DeleteObject(hBmp);

19.如何转换并保存位图













//****************************************************************************
//* 名称:DDBToDIB
//* 功能:设备相关转换为设备无关位图
//****************************************************************************
HANDLE CScreenSnapDlg::DDBToDIB( CBitmap& bitmap, DWORD dwCompression /*
= BI_RGB */) 
{
    BITMAP    bm;
    BITMAPINFOHEADER    bi;
    LPBITMAPINFOHEADER  lpbi;
    DWORD    dwLen;
    HANDLE    hDIB;
    HANDLE    handle;
    HDC     hDC;
    HPALETTE   hPal;

    CWindowDC   dc( this );
    CPalette   pal;
    //如果支持调色板的话,则建立它
    if( dc.GetDeviceCaps( RASTERCAPS ) & RC_PALETTE )
    {
        UINT        nSize   = sizeof(LOGPALETTE) + ( sizeof(PALETTEENTRY) * 256 );
        LOGPALETTE* pLP     = (LOGPALETTE*)new BYTE[nSize];
        pLP->palVersion     = 0x300;
        pLP->palNumEntries = (unsigned short)GetSystemPaletteEntries( dc, 0, 255, 
        pLP->palPalEntry );

        pal.CreatePalette( pLP );

        //释放
        delete[] pLP;
    }

    ASSERT( bitmap.GetSafeHandle() );

    //不支持BI_BITFIELDS类型
    if( dwCompression == BI_BITFIELDS )
        return NULL;

    //如果调色板为空,则用默认调色板
    hPal = (HPALETTE) pal.GetSafeHandle();
    if (hPal==NULL)
        hPal = (HPALETTE) GetStockObject(DEFAULT_PALETTE);

    //获取位图信息
    bitmap.GetObject(sizeof(bm),(LPSTR)&bm);

    //初始化位图信息头
    bi.biSize        = sizeof(BITMAPINFOHEADER);
    bi.biWidth        = bm.bmWidth;
    bi.biHeight         = bm.bmHeight;
    bi.biPlanes         = 1;
    bi.biBitCount        = (unsigned short)(bm.bmPlanes * bm.bmBitsPixel) ;
    bi.biCompression    = dwCompression;
    bi.biSizeImage        = 0;
    bi.biXPelsPerMeter    = 0;
    bi.biYPelsPerMeter    = 0;
    bi.biClrUsed        = 0;
    bi.biClrImportant    = 0;

    //计算信息头及颜色表大小
    int nColors = 0;
    if(bi.biBitCount <= 8)
        {
        nColors = (1 << bi.biBitCount);
        }
    dwLen  = bi.biSize + nColors * sizeof(RGBQUAD);

    hDC = ::GetDC(NULL);
    hPal = SelectPalette(hDC,hPal,FALSE);
    RealizePalette(hDC);

    //为信息头及颜色表分配内存
    hDIB = GlobalAlloc(GMEM_FIXED,dwLen);

    if (!hDIB){
        SelectPalette(hDC,hPal,FALSE);
        ::ReleaseDC(NULL,hDC);
        return NULL;
    }

    lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDIB);

    *lpbi = bi;

    //调用 GetDIBits 计算图像大小
    GetDIBits(hDC, (HBITMAP)bitmap.GetSafeHandle(), 0L, (DWORD)bi.biHeight,
            (LPBYTE)NULL, (LPBITMAPINFO)lpbi, (DWORD)DIB_RGB_COLORS);

    bi = *lpbi;

    //图像的每一行都对齐(32bit)边界
    if (bi.biSizeImage == 0){
        bi.biSizeImage = ((((bi.biWidth * bi.biBitCount) + 31) & ~31) / 8) 
                        * bi.biHeight;

        if (dwCompression != BI_RGB)
            bi.biSizeImage = (bi.biSizeImage * 3) / 2;
    }

    //重新分配内存大小,以便放下所有数据
    dwLen += bi.biSizeImage;
    handle = GlobalReAlloc(hDIB, dwLen, GMEM_MOVEABLE) ;
    if (handle != NULL)
        hDIB = handle;
    else
        {
        GlobalFree(hDIB);

        //重选原始调色板
        SelectPalette(hDC,hPal,FALSE);
        ::ReleaseDC(NULL,hDC);
        return NULL;
        }

    //获取位图数据
    lpbi = (LPBITMAPINFOHEADER)hDIB;

    //最终获得的DIB
    BOOL bGotBits = GetDIBits( hDC, (HBITMAP)bitmap.GetSafeHandle(),
                0L,                      //扫描行起始处
                (DWORD)bi.biHeight,      //扫描行数
                (LPBYTE)lpbi             //位图数据地址
                + (bi.biSize + nColors * sizeof(RGBQUAD)),
                (LPBITMAPINFO)lpbi,      //位图信息地址
                (DWORD)DIB_RGB_COLORS);  //颜色板使用RGB

    if( !bGotBits )
    {
        GlobalFree(hDIB);
        
        SelectPalette(hDC,hPal,FALSE);
        ::ReleaseDC(NULL,hDC);
        return NULL;
    }

    SelectPalette(hDC,hPal,FALSE);
    ::ReleaseDC(NULL,hDC);
    return hDIB;
}

//********************************************************************************
//* 名称:SaveBitmapToFile
//* 功能:保存为位图文件
//********************************************************************************
BOOL CScreenSnapDlg::SaveBitmapToFile(HBITMAP hBitmap , CString lpFileName) 
{      
 HDC    hDC;
  //设备描述表  
    int    iBits;
 //当前显示分辨率下每个像素所占字节数
 WORD            wBitCount;
 //位图中每个像素所占字节数
 DWORD           dwPaletteSize=0, 
 //定义调色板大小, 位图中像素字节大小 ,位图文件大小 , 写入文件字节数
  dwBmBitsSize,
  dwDIBSize, dwWritten;
 BITMAP          Bitmap;        
 BITMAPFILEHEADER   bmfHdr;
 //位图属性结构    
    BITMAPINFOHEADER   bi;
    //位图文件头结构       
 LPBITMAPINFOHEADER lpbi;   
 //位图信息头结构     
    HANDLE          fh, hDib, hPal,hOldPal=NULL; 
//指向位图信息头结构,定义文件,分配内存句柄,调色板句柄
//计算位图文件每个像素所占字节数
   hDC = CreateDC("DISPLAY",NULL,NULL,NULL);
   iBits = GetDeviceCaps(hDC, BITSPIXEL) * 
   GetDeviceCaps(hDC, PLANES);
   DeleteDC(hDC);
   if (iBits <= 1)
      wBitCount = 1;
   else if (iBits <= 4)
      wBitCount = 4;
   else if (iBits <= 8)
      wBitCount = 8;
   else if (iBits <= 24)
      wBitCount = 24;
   //计算调色板大小
   if (wBitCount <= 8)
      dwPaletteSize = (1 << wBitCount) *sizeof(RGBQUAD);
   
   //设置位图信息头结构
   GetObject(hBitmap, sizeof(BITMAP), (LPSTR)&Bitmap);
   bi.biSize            = sizeof(BITMAPINFOHEADER);
   bi.biWidth           = Bitmap.bmWidth;
   bi.biHeight          = Bitmap.bmHeight;
   bi.biPlanes          = 1;
   bi.biBitCount         = wBitCount;
   bi.biCompression      = BI_RGB;
   bi.biSizeImage        = 0;
   bi.biXPelsPerMeter     = 0;
   bi.biYPelsPerMeter     = 0;
   bi.biClrUsed         = 0;
   bi.biClrImportant      = 0;

   dwBmBitsSize = ((Bitmap.bmWidth *
    wBitCount+31)/32)* 4
  *Bitmap.bmHeight ;

   //为位图内容分配内存
   hDib  = GlobalAlloc(GHND,dwBmBitsSize+
 dwPaletteSize+sizeof(BITMAPINFOHEADER));
   lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDib);
   *lpbi = bi;

   // 处理调色板   
   hPal = GetStockObject(DEFAULT_PALETTE);
   if (hPal)
   {
    hDC  = ::GetDC(NULL);
    hOldPal = SelectPalette(hDC, (HPALETTE)hPal, FALSE);
       RealizePalette(hDC);
   }

   // 获取该调色板下新的像素值
   GetDIBits(hDC, hBitmap, 0, (UINT) Bitmap.bmHeight,
  (LPSTR)lpbi + sizeof(BITMAPINFOHEADER)+dwPaletteSize,
  (LPBITMAPINFO)lpbi, DIB_RGB_COLORS);

   //恢复调色板   
   if (hOldPal)
   {
      SelectPalette(hDC, (HPALETTE)hOldPal, TRUE);
      RealizePalette(hDC);
      ::ReleaseDC(NULL, hDC);
   }

   //创建位图文件    
 fh = CreateFile(lpFileName, GENERIC_WRITE, 
   0, NULL, CREATE_ALWAYS,
         FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL);

   if (fh == INVALID_HANDLE_VALUE)
      return FALSE;

   // 设置位图文件头
   bmfHdr.bfType = 0x4D42;  // "BM"
   dwDIBSize    = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + 
dwPaletteSize + dwBmBitsSize;  
   bmfHdr.bfSize = dwDIBSize;
   bmfHdr.bfReserved1 = 0;
   bmfHdr.bfReserved2 = 0;
   bmfHdr.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) 
      + (DWORD)sizeof(BITMAPINFOHEADER)
     + dwPaletteSize;
   // 写入位图文件头
   WriteFile(fh, (LPSTR)&bmfHdr, sizeof
 (BITMAPFILEHEADER), &dwWritten, NULL);
   // 写入位图文件其余内容
   WriteFile(fh, (LPSTR)lpbi, dwDIBSize, 
   &dwWritten, NULL);
   //消除内存分配  
   GlobalUnlock(hDib);
   GlobalFree(hDib);
   CloseHandle(fh);
   return TRUE;
}


20.如何获取局域网上计算机名及它们的IP地址

● 连接ws2_32.lib和 mpr.lib库

● #include winsock2.h

CString strTemp;
struct hostent *host;
struct in_addr *ptr; // 检索IP地址 
DWORD dwScope = RESOURCE_CONTEXT;
NETRESOURCE *NetResource = NULL;
HANDLE hEnum;
WNetOpenEnum( dwScope, NULL, NULL, 
             NULL, &hEnum );
WSADATA wsaData;
WSAStartup(MAKEWORD(1,1),&wsaData);
if ( hEnum )
{
    DWORD Count = 0xFFFFFFFF;
    DWORD BufferSize = 2048;
    LPVOID Buffer = new char[2048];
    WNetEnumResource( hEnum, &Count, 
        Buffer, &BufferSize );
    NetResource = (NETRESOURCE*)Buffer;
    char szHostName[200];
    unsigned int i;
    for ( i = 0; 
        i < BufferSize/sizeof(NETRESOURCE); 
        i++, NetResource++ )
    {
        if ( NetResource->dwUsage == 
            RESOURCEUSAGE_CONTAINER && 
            NetResource->dwType == 
            RESOURCETYPE_ANY )
        {
            if ( NetResource->lpRemoteName )
            {
                CString strFullName = 
                    NetResource->lpRemoteName;
                if ( 0 == 
                    strFullName.Left(2).Compare("\\\\") )   
                    strFullName = 
                        strFullName.Right(
                            strFullName.GetLength()-2);

                gethostname( szHostName, 
                    strlen( szHostName ) );
                host = gethostbyname(strFullName);

                if(host == NULL) continue; 
                ptr = (struct in_addr *) 
                    host->h_addr_list[0];                    

                // =. 分隔开IP:211.40.35.76.             
                int a = ptr->S_un.S_un_b.s_b1;  // 211           
                int b = ptr->S_un.S_un_b.s_b2;  // 40
                int c = ptr->S_un.S_un_b.s_b3;  // 35
                int d = ptr->S_un.S_un_b.s_b4;  // 76

                strTemp.Format("%s -->  %d.%d.%d.%d",
                    strFullName,a,b,c,d);
                AfxMessageBox(strTemp);
            }
        }
    }

    delete Buffer;
    WNetCloseEnum( hEnum ); 
}

WSACleanup();


类别:电脑应用 | 添加到搜藏 | 浏览() | 评论 (0)
 
最近读者:
 
网友评论:
发表评论:
姓 名:
网址或邮箱: (选填)
内 容:
验证码:
 

     

©2008 Baidu