编程技巧20法之七:建立灰度级图标

发表于:2007-06-17来源:作者:点击数: 标签:
15.如何建立一个灰度级图标 HICONCreateGrayscaleIcon(HICONhIcon) { HICONhGrayIcon=NULL; HDChMainDC=NULL,hMemDC1=NULL,hMemDC2=NULL; BITMAPbmp; HBITMAPhOldBmp1=NULL,hOldBmp2=NULL; ICONINFOcsII,csGrayII; BOOLbRetValue=FALSE; bRetValue=::GetIcon

          
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), &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));
        } 
      } 

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

      csGrayII.hbmMask = csII.hbmMask;

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

    ::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);

原文转自:http://www.ltesting.net