class.c

来自「一个类似windows」· C语言 代码 · 共 965 行 · 第 1/2 页

C
965
字号
/* $Id: class.c 23388 2006-07-31 05:48:26Z jimtabor $
 *
 * COPYRIGHT:       See COPYING in the top level directory
 * PROJECT:         ReactOS user32.dll
 * FILE:            lib/user32/windows/class.c
 * PURPOSE:         Window classes
 * PROGRAMMER:      Casper S. Hornstrup (chorns@users.sourceforge.net)
 * UPDATE HISTORY:
 *      09-05-2001  CSH  Created
 */

#include <user32.h>

#include <wine/debug.h>

extern BOOL ControlsInitialized;

/*
 * @implemented
 */
BOOL
STDCALL
GetClassInfoExA(
  HINSTANCE hinst,
  LPCSTR lpszClass,
  LPWNDCLASSEXA lpwcx)
{
    UNICODE_STRING ClassName = {0};
    BOOL Ret;

    if (lpszClass == NULL)
    {
        SetLastError(ERROR_INVALID_PARAMETER);
        return FALSE;
    }

    if (IS_ATOM(lpszClass))
    {
        ClassName.Buffer = (PWSTR)((ULONG_PTR)lpszClass);
    }
    else
    {
        if (!RtlCreateUnicodeStringFromAsciiz(&ClassName,
                                              lpszClass))
        {
            SetLastError(ERROR_NOT_ENOUGH_MEMORY);
            return FALSE;
        }
    }

    /* Register built-in controls if not already done */
    if (! ControlsInitialized)
    {
        ControlsInitialized = ControlsInit(ClassName.Buffer);
    }

    Ret = NtUserGetClassInfo(hinst,
                             &ClassName,
                             (LPWNDCLASSEXW)lpwcx,
                             TRUE);

    if (!IS_ATOM(lpszClass))
    {
        RtlFreeUnicodeString(&ClassName);
    }

    return Ret;
}


/*
 * @implemented
 */
BOOL
STDCALL
GetClassInfoExW(
  HINSTANCE hinst,
  LPCWSTR lpszClass,
  LPWNDCLASSEXW lpwcx)
{
    UNICODE_STRING ClassName = {0};

    if (lpszClass == NULL)
    {
        SetLastError(ERROR_INVALID_PARAMETER);
        return FALSE;
    }

    if (IS_ATOM(lpszClass))
    {
        ClassName.Buffer = (PWSTR)((ULONG_PTR)lpszClass);
    }
    else
    {
        RtlInitUnicodeString(&ClassName,
                             lpszClass);
    }

    /* Register built-in controls if not already done */
    if (! ControlsInitialized)
    {
        ControlsInitialized = ControlsInit(ClassName.Buffer);
    }

    return NtUserGetClassInfo(hinst,
                              &ClassName,
                              lpwcx,
                              FALSE);
}


/*
 * @implemented
 */
BOOL
STDCALL
GetClassInfoA(
  HINSTANCE hInstance,
  LPCSTR lpClassName,
  LPWNDCLASSA lpWndClass)
{
  WNDCLASSEXA w;
  BOOL retval;

  if ( !lpClassName || !lpWndClass )
  {
    SetLastError(ERROR_INVALID_PARAMETER);
    return FALSE;
  }

  if ( hInstance == User32Instance )
  {
    hInstance = NULL;
  }

  w.cbSize = sizeof(w);
  retval = GetClassInfoExA(hInstance,lpClassName,&w);
  if (retval)
  {
    RtlCopyMemory ( lpWndClass, &w.style, sizeof(WNDCLASSA) );
  }
  return retval;
}

/*
 * @implemented
 */
BOOL
STDCALL
GetClassInfoW(
  HINSTANCE hInstance,
  LPCWSTR lpClassName,
  LPWNDCLASSW lpWndClass)
{
  WNDCLASSEXW w;
  BOOL retval;

  if(!lpClassName || !lpWndClass)
  {
    SetLastError(ERROR_INVALID_PARAMETER);
    return FALSE;
  }

  if ( hInstance == User32Instance )
  {
    hInstance = NULL;
  }

  w.cbSize = sizeof(w);
  retval = GetClassInfoExW(hInstance,lpClassName,&w);
  if (retval)
  {
    RtlCopyMemory (lpWndClass,&w.style,sizeof(WNDCLASSW));
  }
  return retval;
}


/*
 * @implemented
 */
DWORD STDCALL
GetClassLongA(HWND hWnd, int nIndex)
{
   switch (nIndex)
   {
      case GCL_HBRBACKGROUND:
         {
            DWORD hBrush = NtUserGetClassLong(hWnd, GCL_HBRBACKGROUND, TRUE);
            if (hBrush != 0 && hBrush < 0x4000)
               hBrush = (DWORD)GetSysColorBrush((ULONG)hBrush - 1);
            return hBrush;
         }

      case GCL_MENUNAME:
         {
            PUNICODE_STRING Name;
            Name = (PUNICODE_STRING)NtUserGetClassLong(hWnd, nIndex, TRUE);
            if (IS_INTRESOURCE(Name))
               return (DWORD)Name;
            else
               return (DWORD)heap_string_poolA(Name->Buffer, Name->Length);
         }

      default:
         return NtUserGetClassLong(hWnd, nIndex, TRUE);
   }
}

/*
 * @implemented
 */
DWORD STDCALL
GetClassLongW ( HWND hWnd, int nIndex )
{
   switch (nIndex)
   {
      case GCL_HBRBACKGROUND:
         {
            DWORD hBrush = NtUserGetClassLong(hWnd, GCL_HBRBACKGROUND, TRUE);
            if (hBrush != 0 && hBrush < 0x4000)
               hBrush = (DWORD)GetSysColorBrush((ULONG)hBrush - 1);
            return hBrush;
         }

      case GCL_MENUNAME:
         {
            PUNICODE_STRING Name;
            Name = (PUNICODE_STRING)NtUserGetClassLong(hWnd, nIndex, FALSE);
            if (IS_INTRESOURCE(Name))
               return (DWORD)Name;
            else
               return (DWORD)heap_string_poolW(Name->Buffer, Name->Length);
         }

      default:
         return NtUserGetClassLong(hWnd, nIndex, FALSE);
   }
}


/*
 * @implemented
 */
int STDCALL
GetClassNameA(
  HWND hWnd,
  LPSTR lpClassName,
  int nMaxCount)
{
    ANSI_STRING ClassName;

    ClassName.MaximumLength = nMaxCount;
    ClassName.Buffer = lpClassName;

    return NtUserGetClassName(hWnd,
                              (PUNICODE_STRING)&ClassName,
                              TRUE);
}


/*
 * @implemented
 */
int
STDCALL
GetClassNameW(
  HWND hWnd,
  LPWSTR lpClassName,
  int nMaxCount)
{
    UNICODE_STRING ClassName;

    ClassName.MaximumLength = nMaxCount;
    ClassName.Buffer = lpClassName;

    return NtUserGetClassName(hWnd,
                              &ClassName,
                              FALSE);
}


/*
 * @implemented
 */
WORD
STDCALL
GetClassWord(
  HWND hWnd,
  int nIndex)
/*
 * NOTE: Obsoleted in 32-bit windows
 */
{
    if ((nIndex < 0) && (nIndex != GCW_ATOM))
        return 0;

    return (WORD) NtUserGetClassLong ( hWnd, nIndex, TRUE );
}


/*
 * @implemented
 */
LONG
STDCALL
GetWindowLongA ( HWND hWnd, int nIndex )
{
  return NtUserGetWindowLong(hWnd, nIndex, TRUE);
}


/*
 * @implemented
 */
LONG
STDCALL
GetWindowLongW(HWND hWnd, int nIndex)
{
  return NtUserGetWindowLong(hWnd, nIndex, FALSE);
}

/*
 * @implemented
 */
WORD
STDCALL
GetWindowWord(HWND hWnd, int nIndex)
{
  return (WORD)NtUserGetWindowLong(hWnd, nIndex,  TRUE);
}

/*
 * @implemented
 */
WORD
STDCALL
SetWindowWord ( HWND hWnd,int nIndex,WORD wNewWord )
{
  return (WORD)NtUserSetWindowLong ( hWnd, nIndex, (LONG)wNewWord, TRUE );
}

/*
 * @implemented
 */
UINT
STDCALL
RealGetWindowClassW(
  HWND  hwnd,
  LPWSTR pszType,
  UINT  cchType)
{
	/* FIXME: Implement correct functionality of RealGetWindowClass */
	return GetClassNameW(hwnd,pszType,cchType);
}


/*
 * @implemented
 */
UINT
STDCALL
RealGetWindowClassA(
  HWND  hwnd,
  LPSTR pszType,
  UINT  cchType)
{
	/* FIXME: Implement correct functionality of RealGetWindowClass */
	return GetClassNameA(hwnd,pszType,cchType);
}

/*
 * Create a small icon based on a standard icon
 */
static HICON
CreateSmallIcon(HICON StdIcon)
{
   HICON SmallIcon = NULL;
   ICONINFO StdInfo;
   int SmallIconWidth;
   int SmallIconHeight;
   BITMAP StdBitmapInfo;
   HDC hInfoDc = NULL;
   HDC hSourceDc = NULL;
   HDC hDestDc = NULL;
   ICONINFO SmallInfo;
   HBITMAP OldSourceBitmap = NULL;
   HBITMAP OldDestBitmap = NULL;

   SmallInfo.hbmColor = NULL;
   SmallInfo.hbmMask = NULL;

   /* We need something to work with... */
   if (NULL == StdIcon)
   {
      goto cleanup;
   }

   SmallIconWidth = GetSystemMetrics(SM_CXSMICON);
   SmallIconHeight = GetSystemMetrics(SM_CYSMICON);
   if (! GetIconInfo(StdIcon, &StdInfo))
   {
      DPRINT1("Failed to get icon info for icon 0x%x\n", StdIcon);
      goto cleanup;
   }
   if (! GetObjectW(StdInfo.hbmMask, sizeof(BITMAP), &StdBitmapInfo))
   {
      DPRINT1("Failed to get bitmap info for icon 0x%x bitmap 0x%x\n",
              StdIcon, StdInfo.hbmColor);
      goto cleanup;
   }
   if (StdBitmapInfo.bmWidth == SmallIconWidth &&
       StdBitmapInfo.bmHeight == SmallIconHeight)
   {
      /* Icon already has the correct dimensions */
      return StdIcon;
   }

   /* Get a handle to a info DC and handles to DCs which can be used to
      select a bitmap into. This is done to avoid triggering a switch to
      graphics mode (if we're currently in text/blue screen mode) */
   hInfoDc = CreateICW(NULL, NULL, NULL, NULL);
   if (NULL == hInfoDc)
   {
      DPRINT1("Failed to create info DC\n");
      goto cleanup;
   }
   hSourceDc = CreateCompatibleDC(NULL);
   if (NULL == hSourceDc)
   {
      DPRINT1("Failed to create source DC\n");
      goto cleanup;
   }
   hDestDc = CreateCompatibleDC(NULL);
   if (NULL == hDestDc)
   {
      DPRINT1("Failed to create dest DC\n");
      goto cleanup;
   }

   OldSourceBitmap = SelectObject(hSourceDc, StdInfo.hbmColor);
   if (NULL == OldSourceBitmap)
   {
      DPRINT1("Failed to select source color bitmap\n");
      goto cleanup;
   }
   SmallInfo.hbmColor = CreateCompatibleBitmap(hInfoDc, SmallIconWidth,
                                              SmallIconHeight);
   if (NULL == SmallInfo.hbmColor)
   {
      DPRINT1("Failed to create color bitmap\n");
      goto cleanup;
   }
   OldDestBitmap = SelectObject(hDestDc, SmallInfo.hbmColor);
   if (NULL == OldDestBitmap)
   {
      DPRINT1("Failed to select dest color bitmap\n");
      goto cleanup;
   }
   if (! StretchBlt(hDestDc, 0, 0, SmallIconWidth, SmallIconHeight,
                    hSourceDc, 0, 0, StdBitmapInfo.bmWidth,
                    StdBitmapInfo.bmHeight, SRCCOPY))
   {
     DPRINT1("Failed to stretch color bitmap\n");
     goto cleanup;
   }

   if (NULL == SelectObject(hSourceDc, StdInfo.hbmMask))
   {
      DPRINT1("Failed to select source mask bitmap\n");
      goto cleanup;
   }
   SmallInfo.hbmMask = CreateBitmap(SmallIconWidth, SmallIconHeight, 1, 1,
                                    NULL);
   if (NULL == SmallInfo.hbmMask)
   {
      DPRINT1("Failed to create mask bitmap\n");
      goto cleanup;
   }
   if (NULL == SelectObject(hDestDc, SmallInfo.hbmMask))
   {
      DPRINT1("Failed to select dest mask bitmap\n");
      goto cleanup;

⌨️ 快捷键说明

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