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

📄 icon.c

📁 winNT技术操作系统,国外开放的原代码和LIUX一样
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
 *  ReactOS kernel
 *  Copyright (C) 1998, 1999, 2000, 2001 ReactOS Team
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
/* $Id: icon.c 25732 2007-02-05 20:59:18Z fireball $
 *
 * PROJECT:         ReactOS user32.dll
 * FILE:            lib/user32/windows/icon.c
 * PURPOSE:         Icon
 * PROGRAMMER:      Casper S. Hornstrup (chorns@users.sourceforge.net)
 * UPDATE HISTORY:
 *      09-05-2001  CSH  Created
 */

/* INCLUDES ******************************************************************/

#include <user32.h>

#include <wine/debug.h>


/* FUNCTIONS *****************************************************************/

HICON
ICON_CreateIconFromData(HDC hDC, PVOID ImageData, ICONIMAGE* IconImage, int cxDesired, int cyDesired, int xHotspot, int yHotspot)
{
   BYTE BitmapInfoBuffer[sizeof(BITMAPINFOHEADER) + 2 * sizeof(RGBQUAD)];
   BITMAPINFO *bwBIH = (BITMAPINFO *)BitmapInfoBuffer;
   ICONINFO IconInfo;

   IconInfo.fIcon = TRUE;
   IconInfo.xHotspot = xHotspot;
   IconInfo.yHotspot = yHotspot;

   /* Load the XOR bitmap */
   IconInfo.hbmColor = CreateDIBitmap(hDC, &IconImage->icHeader, CBM_INIT,
                                      ImageData, (BITMAPINFO*)IconImage,
                                      DIB_RGB_COLORS);

   /* Make ImageData point to the start of the AND image data. */
   ImageData = ((PBYTE)ImageData) + (((IconImage->icHeader.biWidth *
                                      IconImage->icHeader.biBitCount + 31) & ~31) >> 3) *
                                      (IconImage->icHeader.biHeight );

   /* Create a BITMAPINFO header for the monocrome part of the icon. */
   bwBIH->bmiHeader.biBitCount = 1;
   bwBIH->bmiHeader.biWidth = IconImage->icHeader.biWidth;
   bwBIH->bmiHeader.biHeight = IconImage->icHeader.biHeight;
   bwBIH->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
   bwBIH->bmiHeader.biPlanes = 1;
   bwBIH->bmiHeader.biSizeImage = 0;
   bwBIH->bmiHeader.biCompression = BI_RGB;
   bwBIH->bmiHeader.biClrImportant = 0;
   bwBIH->bmiHeader.biClrUsed = 0;
   bwBIH->bmiHeader.biXPelsPerMeter = 0;
   bwBIH->bmiHeader.biYPelsPerMeter = 0;

   bwBIH->bmiColors[0].rgbBlue = 0;
   bwBIH->bmiColors[0].rgbGreen = 0;
   bwBIH->bmiColors[0].rgbRed = 0;
   bwBIH->bmiColors[0].rgbReserved = 0;

   bwBIH->bmiColors[1].rgbBlue = 0xff;
   bwBIH->bmiColors[1].rgbGreen = 0xff;
   bwBIH->bmiColors[1].rgbRed = 0xff;
   bwBIH->bmiColors[1].rgbReserved = 0;

   /* Load the AND bitmap. */
   IconInfo.hbmMask = CreateDIBitmap(hDC, &bwBIH->bmiHeader, 0,
                                     ImageData, bwBIH, DIB_RGB_COLORS);

   SetDIBits(hDC, IconInfo.hbmMask, 0, IconImage->icHeader.biHeight,
             ImageData, bwBIH, DIB_RGB_COLORS);

   /* Create the icon based on everything we have so far */
   return NtUserCreateCursorIconHandle(&IconInfo, FALSE);
}

HICON
ICON_CreateCursorFromData(HDC hDC, PVOID ImageData, ICONIMAGE* IconImage, int cxDesired, int cyDesired, int xHotspot, int yHotspot)
{
   /* FIXME - color cursors */
   BYTE BitmapInfoBuffer[sizeof(BITMAPINFOHEADER) + 2 * sizeof(RGBQUAD)];
   BITMAPINFO *bwBIH = (BITMAPINFO *)BitmapInfoBuffer;
   ICONINFO IconInfo;
   PVOID XORImageData = ImageData;

   IconInfo.fIcon = FALSE;
   IconInfo.xHotspot = xHotspot;
   IconInfo.yHotspot = yHotspot;

   /* Create a BITMAPINFO header for the monocrome part of the icon */
   bwBIH->bmiHeader.biBitCount = 1;
   bwBIH->bmiHeader.biWidth = IconImage->icHeader.biWidth;
   bwBIH->bmiHeader.biHeight = IconImage->icHeader.biHeight;
   bwBIH->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
   bwBIH->bmiHeader.biPlanes = 1;
   bwBIH->bmiHeader.biSizeImage = 0;
   bwBIH->bmiHeader.biCompression = BI_RGB;
   bwBIH->bmiHeader.biClrImportant = 0;
   bwBIH->bmiHeader.biClrUsed = 0;
   bwBIH->bmiHeader.biXPelsPerMeter = 0;
   bwBIH->bmiHeader.biYPelsPerMeter = 0;

   bwBIH->bmiColors[0].rgbBlue = 0;
   bwBIH->bmiColors[0].rgbGreen = 0;
   bwBIH->bmiColors[0].rgbRed = 0;
   bwBIH->bmiColors[0].rgbReserved = 0;

   bwBIH->bmiColors[1].rgbBlue = 0xff;
   bwBIH->bmiColors[1].rgbGreen = 0xff;
   bwBIH->bmiColors[1].rgbRed = 0xff;
   bwBIH->bmiColors[1].rgbReserved = 0;

   /* Load the AND bitmap */
   IconInfo.hbmMask = CreateDIBitmap(hDC, &bwBIH->bmiHeader, 0,
                                     XORImageData, bwBIH, DIB_RGB_COLORS);
   if (IconInfo.hbmMask)
   {
      SetDIBits(hDC, IconInfo.hbmMask, 0, IconImage->icHeader.biHeight,
                XORImageData, bwBIH, DIB_RGB_COLORS);
   }

   IconInfo.hbmColor = (HBITMAP)0;

   /* Create the icon based on everything we have so far */
   return NtUserCreateCursorIconHandle(&IconInfo, FALSE);
}


/*
 * @implemented
 */
HICON
STDCALL
CopyIcon(
  HICON hIcon)
{
  ICONINFO IconInfo;

  if(NtUserGetCursorIconInfo((HANDLE)hIcon, &IconInfo))
  {
    return NtUserCreateCursorIconHandle(&IconInfo, FALSE);
  }
  return (HICON)0;
}


/*
 * @implemented
 */
HICON
STDCALL
CreateIcon(
  HINSTANCE hInstance,
  int nWidth,
  int nHeight,
  BYTE cPlanes,
  BYTE cBitsPixel,
  CONST BYTE *ANDbits,
  CONST BYTE *XORbits)
{
  ICONINFO IconInfo;

  IconInfo.fIcon = TRUE;
  IconInfo.xHotspot = nWidth / 2;
  IconInfo.yHotspot = nHeight / 2;
  IconInfo.hbmMask = CreateBitmap(nWidth, nHeight, 1, 1, ANDbits);
  if(!IconInfo.hbmMask)
  {
    return (HICON)0;
  }
  IconInfo.hbmColor = CreateBitmap(nWidth, nHeight, cPlanes, cBitsPixel, XORbits);
  if(!IconInfo.hbmColor)
  {
    DeleteObject(IconInfo.hbmMask);
    return (HICON)0;
  }

  return NtUserCreateCursorIconHandle(&IconInfo, FALSE);
}


/*
 * @implemented
 */
HICON
STDCALL
CreateIconFromResource(
  PBYTE presbits,
  DWORD dwResSize,
  BOOL fIcon,
  DWORD dwVer)
{
  return CreateIconFromResourceEx(presbits, dwResSize, fIcon, dwVer, 0, 0, LR_DEFAULTSIZE|LR_SHARED );
}


/*
 * @implemented
 */
HICON
STDCALL
CreateIconFromResourceEx(
  PBYTE pbIconBits,
  DWORD cbIconBits,
  BOOL fIcon,
  DWORD dwVersion,
  int cxDesired,
  int cyDesired,
  UINT uFlags)
{
  ICONIMAGE* SafeIconImage;
  HICON hIcon;
  ULONG HeaderSize;
  ULONG ColourCount;
  PVOID Data;
  HDC hScreenDc;
  WORD wXHotspot;
  WORD wYHotspot;

  /*
    FIXME - does win support LR_SHARED? According to msdn it does but we don't
            have useful information to identify the icon
  if (uFlags & LR_SHARED)
  {
    DbgPrint("FIXME: need LR_SHARED support in CreateIconFromResourceEx()\n");
  }
  */

  DPRINT("dwVersion, cxDesired, cyDesired are all ignored in this implementation!\n");

  if (! fIcon)
    {
      wXHotspot = *(WORD*)pbIconBits;
      pbIconBits += sizeof(WORD);
      wYHotspot = *(WORD*)pbIconBits;
      pbIconBits += sizeof(WORD);
      cbIconBits -= 2 * sizeof(WORD);
    }
  else
    {
      wXHotspot = cxDesired / 2;
      wYHotspot = cyDesired / 2;
    }

  /* get an safe copy of the icon data */
  SafeIconImage = RtlAllocateHeap(GetProcessHeap(), 0, cbIconBits);
  if (SafeIconImage == NULL)
    {
      return NULL;
    }
  memcpy(SafeIconImage, pbIconBits, cbIconBits);

  /* take into acount the original height was for both the AND and XOR images */
  if(fIcon)
    SafeIconImage->icHeader.biHeight /= 2;

  if (SafeIconImage->icHeader.biSize == sizeof(BITMAPCOREHEADER))
    {
      BITMAPCOREHEADER* Core = (BITMAPCOREHEADER*)SafeIconImage;
      ColourCount = (Core->bcBitCount <= 8) ? (1 << Core->bcBitCount) : 0;
      HeaderSize = sizeof(BITMAPCOREHEADER) + ColourCount * sizeof(RGBTRIPLE);
    }
  else
    {
      ColourCount = (SafeIconImage->icHeader.biBitCount <= 8) ?
                       (1 << SafeIconImage->icHeader.biBitCount) : 0;
      HeaderSize = sizeof(BITMAPINFOHEADER) + ColourCount * sizeof(RGBQUAD);
    }

  /* make data point to the start of the XOR image data */
  Data = (PBYTE)SafeIconImage + HeaderSize;

  /* get a handle to the screen dc, the icon we create is going to be compatable with this */
  hScreenDc = CreateCompatibleDC(NULL);
  if (hScreenDc == NULL)
    {
      RtlFreeHeap(GetProcessHeap(), 0, SafeIconImage);
      return(NULL);
    }

  if(fIcon)
    hIcon = ICON_CreateIconFromData(hScreenDc, Data, SafeIconImage, cxDesired, cyDesired, wXHotspot, wYHotspot);
  else
    hIcon = ICON_CreateCursorFromData(hScreenDc, Data, SafeIconImage, cxDesired, cyDesired, wXHotspot, wYHotspot);
  RtlFreeHeap(GetProcessHeap(), 0, SafeIconImage);
  DeleteDC(hScreenDc);

  return hIcon;
}


/*
 * @implemented
 */
HICON
STDCALL
CreateIconIndirect(PICONINFO IconInfo)
{
  BITMAP ColorBitmap;
  BITMAP MaskBitmap;

  if(!IconInfo)
  {
    SetLastError(ERROR_INVALID_PARAMETER);
    return (HICON)0;
  }

  if(!GetObjectW(IconInfo->hbmMask, sizeof(BITMAP), &MaskBitmap))
  {
    return (HICON)0;
  }
  /* FIXME - does there really *have* to be a color bitmap? monochrome cursors don't have one */
  if(/*IconInfo->hbmColor &&*/ !GetObjectW(IconInfo->hbmColor, sizeof(BITMAP), &ColorBitmap))
  {
    return (HICON)0;
  }

  /* FIXME - i doubt this is right (monochrome cursors */
  /*if(ColorBitmap.bmWidth != MaskBitmap.bmWidth ||
     ColorBitmap.bmHeight != MaskBitmap.bmWidth)
  {
    SetLastError(ERROR_INVALID_PARAMETER);
    return (HICON)0;
  }*/

  return (HICON)NtUserCreateCursorIconHandle(IconInfo, TRUE);
}

⌨️ 快捷键说明

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