📄 class.c
字号:
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;
}
if (! StretchBlt(hDestDc, 0, 0, SmallIconWidth, SmallIconHeight,
hSourceDc, 0, 0, StdBitmapInfo.bmWidth,
StdBitmapInfo.bmHeight, SRCCOPY))
{
DPRINT1("Failed to stretch mask bitmap\n");
goto cleanup;
}
SmallInfo.fIcon = TRUE;
SmallInfo.xHotspot = SmallIconWidth / 2;
SmallInfo.yHotspot = SmallIconHeight / 2;
SmallIcon = CreateIconIndirect(&SmallInfo);
if (NULL == SmallIcon)
{
DPRINT1("Failed to create icon\n");
goto cleanup;
}
cleanup:
if (NULL != SmallInfo.hbmMask)
{
DeleteObject(SmallInfo.hbmMask);
}
if (NULL != OldDestBitmap)
{
SelectObject(hDestDc, OldDestBitmap);
}
if (NULL != SmallInfo.hbmColor)
{
DeleteObject(SmallInfo.hbmColor);
}
if (NULL != hDestDc)
{
DeleteDC(hDestDc);
}
if (NULL != OldSourceBitmap)
{
SelectObject(hSourceDc, OldSourceBitmap);
}
if (NULL != hSourceDc)
{
DeleteDC(hSourceDc);
}
if (NULL != hInfoDc)
{
DeleteDC(hInfoDc);
}
return SmallIcon;
}
/*
* @implemented
*/
ATOM STDCALL
RegisterClassExA(CONST WNDCLASSEXA *lpwcx)
{
RTL_ATOM Atom;
WNDCLASSEXA WndClass;
UNICODE_STRING ClassName;
UNICODE_STRING MenuName = {0};
HMENU hMenu = NULL;
if (lpwcx == NULL || lpwcx->cbSize != sizeof(WNDCLASSEXA) ||
lpwcx->cbClsExtra < 0 || lpwcx->cbWndExtra < 0 ||
lpwcx->lpszClassName == NULL)
{
SetLastError(ERROR_INVALID_PARAMETER);
return 0;
}
/*
* On real Windows this looks more like:
* if (lpwcx->hInstance == User32Instance &&
* *(PULONG)((ULONG_PTR)NtCurrentTeb() + 0x6D4) & 0x400)
* But since I have no idea what the magic field in the
* TEB structure means, I rather decided to omit that.
* -- Filip Navara
*/
if (lpwcx->hInstance == User32Instance)
{
SetLastError(ERROR_INVALID_PARAMETER);
return 0;
}
/* Yes, this is correct. We should modify the passed structure. */
if (lpwcx->hInstance == NULL)
((WNDCLASSEXA*)lpwcx)->hInstance = GetModuleHandleW(NULL);
RtlCopyMemory(&WndClass, lpwcx, sizeof(WNDCLASSEXA));
if (NULL == WndClass.hIconSm)
{
WndClass.hIconSm = CreateSmallIcon(WndClass.hIcon);
}
if (WndClass.lpszMenuName != NULL)
{
if (!IS_INTRESOURCE(WndClass.lpszMenuName))
{
if (WndClass.lpszMenuName[0])
{
RtlCreateUnicodeStringFromAsciiz(&MenuName, WndClass.lpszMenuName);
}
}
else
{
MenuName.Buffer = (LPWSTR)WndClass.lpszMenuName;
}
if (MenuName.Buffer != NULL)
hMenu = LoadMenuA(WndClass.hInstance, WndClass.lpszMenuName);
}
if (IS_ATOM(WndClass.lpszClassName))
{
ClassName.Length =
ClassName.MaximumLength = 0;
ClassName.Buffer = (LPWSTR)WndClass.lpszClassName;
}
else
{
RtlCreateUnicodeStringFromAsciiz(&ClassName, WndClass.lpszClassName);
}
Atom = NtUserRegisterClassEx((WNDCLASSEXW*)&WndClass,
&ClassName,
&MenuName,
NULL,
REGISTERCLASS_ANSI,
hMenu);
TRACE("atom=%04x wndproc=%p hinst=%p bg=%p style=%08x clsExt=%d winExt=%d class=%p\n",
Atom, lpwcx->lpfnWndProc, lpwcx->hInstance, lpwcx->hbrBackground,
lpwcx->style, lpwcx->cbClsExtra, lpwcx->cbWndExtra, WndClass);
if (!IS_INTRESOURCE(WndClass.lpszMenuName))
RtlFreeUnicodeString(&MenuName);
if (!IS_ATOM(WndClass.lpszClassName))
RtlFreeUnicodeString(&ClassName);
return (ATOM)Atom;
}
/*
* @implemented
*/
ATOM STDCALL
RegisterClassExW(CONST WNDCLASSEXW *lpwcx)
{
ATOM Atom;
WNDCLASSEXW WndClass;
UNICODE_STRING ClassName;
UNICODE_STRING MenuName = {0};
HMENU hMenu = NULL;
if (lpwcx == NULL || lpwcx->cbSize != sizeof(WNDCLASSEXW) ||
lpwcx->cbClsExtra < 0 || lpwcx->cbWndExtra < 0 ||
lpwcx->lpszClassName == NULL)
{
SetLastError(ERROR_INVALID_PARAMETER);
return 0;
}
/*
* On real Windows this looks more like:
* if (lpwcx->hInstance == User32Instance &&
* *(PULONG)((ULONG_PTR)NtCurrentTeb() + 0x6D4) & 0x400)
* But since I have no idea what the magic field in the
* TEB structure means, I rather decided to omit that.
* -- Filip Navara
*/
if (lpwcx->hInstance == User32Instance)
{
SetLastError(ERROR_INVALID_PARAMETER);
return 0;
}
/* Yes, this is correct. We should modify the passed structure. */
if (lpwcx->hInstance == NULL)
((WNDCLASSEXW*)lpwcx)->hInstance = GetModuleHandleW(NULL);
RtlCopyMemory(&WndClass, lpwcx, sizeof(WNDCLASSEXW));
if (NULL == WndClass.hIconSm)
{
WndClass.hIconSm = CreateSmallIcon(WndClass.hIcon);
}
if (WndClass.lpszMenuName != NULL)
{
if (!IS_INTRESOURCE(WndClass.lpszMenuName))
{
if (WndClass.lpszMenuName[0])
{
RtlInitUnicodeString(&MenuName, WndClass.lpszMenuName);
}
}
else
{
MenuName.Buffer = (LPWSTR)WndClass.lpszMenuName;
}
if (MenuName.Buffer != NULL)
hMenu = LoadMenuW(WndClass.hInstance, WndClass.lpszMenuName);
}
if (IS_ATOM(WndClass.lpszClassName))
{
ClassName.Length =
ClassName.MaximumLength = 0;
ClassName.Buffer = (LPWSTR)WndClass.lpszClassName;
}
else
{
RtlInitUnicodeString(&ClassName, WndClass.lpszClassName);
}
Atom = (ATOM)NtUserRegisterClassEx(&WndClass,
&ClassName,
&MenuName,
NULL,
0,
hMenu);
TRACE("atom=%04x wndproc=%p hinst=%p bg=%p style=%08x clsExt=%d winExt=%d class=%p\n",
Atom, lpwcx->lpfnWndProc, lpwcx->hInstance, lpwcx->hbrBackground,
lpwcx->style, lpwcx->cbClsExtra, lpwcx->cbWndExtra, WndClass);
return Atom;
}
/*
* @implemented
*/
ATOM STDCALL
RegisterClassA(CONST WNDCLASSA *lpWndClass)
{
WNDCLASSEXA Class;
if (lpWndClass == NULL)
return 0;
RtlCopyMemory(&Class.style, lpWndClass, sizeof(WNDCLASSA));
Class.cbSize = sizeof(WNDCLASSEXA);
Class.hIconSm = NULL;
return RegisterClassExA(&Class);
}
/*
* @implemented
*/
ATOM STDCALL
RegisterClassW(CONST WNDCLASSW *lpWndClass)
{
WNDCLASSEXW Class;
if (lpWndClass == NULL)
return 0;
RtlCopyMemory(&Class.style, lpWndClass, sizeof(WNDCLASSW));
Class.cbSize = sizeof(WNDCLASSEXW);
Class.hIconSm = NULL;
return RegisterClassExW(&Class);
}
/*
* @implemented
*/
DWORD
STDCALL
SetClassLongA (HWND hWnd,
int nIndex,
LONG dwNewLong)
{
PSTR lpStr = (PSTR)dwNewLong;
UNICODE_STRING Value = {0};
BOOL Allocated = FALSE;
DWORD Ret;
TRACE("%p %d %lx\n", hWnd, nIndex, dwNewLong);
/* FIXME - portability!!!! */
if (nIndex == GCL_MENUNAME && lpStr != NULL)
{
if (!IS_INTRESOURCE(lpStr))
{
if (!RtlCreateUnicodeStringFromAsciiz(&Value,
lpStr))
{
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
return 0;
}
Allocated = TRUE;
}
else
Value.Buffer = (PWSTR)lpStr;
dwNewLong = (LONG)&Value;
}
else if (nIndex == GCW_ATOM && lpStr != NULL)
{
if (!IS_ATOM(lpStr))
{
if (!RtlCreateUnicodeStringFromAsciiz(&Value,
lpStr))
{
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
return 0;
}
Allocated = TRUE;
}
else
Value.Buffer = (PWSTR)lpStr;
dwNewLong = (LONG)&Value;
}
Ret = (DWORD)NtUserSetClassLong(hWnd,
nIndex,
dwNewLong,
TRUE);
if (Allocated)
{
RtlFreeUnicodeString(&Value);
}
return Ret;
}
/*
* @implemented
*/
DWORD
STDCALL
SetClassLongW(HWND hWnd,
int nIndex,
LONG dwNewLong)
{
PWSTR lpStr = (PWSTR)dwNewLong;
UNICODE_STRING Value = {0};
TRACE("%p %d %lx\n", hWnd, nIndex, dwNewLong);
/* FIXME - portability!!!! */
if (nIndex == GCL_MENUNAME && lpStr != NULL)
{
if (!IS_INTRESOURCE(lpStr))
{
RtlInitUnicodeString(&Value,
lpStr);
}
else
Value.Buffer = lpStr;
dwNewLong = (LONG)&Value;
}
else if (nIndex == GCW_ATOM && lpStr != NULL)
{
if (!IS_ATOM(lpStr))
{
RtlInitUnicodeString(&Value,
lpStr);
}
else
Value.Buffer = lpStr;
dwNewLong = (LONG)&Value;
}
return (DWORD)NtUserSetClassLong(hWnd,
nIndex,
dwNewLong,
FALSE);
}
/*
* @implemented
*/
WORD
STDCALL
SetClassWord(
HWND hWnd,
int nIndex,
WORD wNewWord)
/*
* NOTE: Obsoleted in 32-bit windows
*/
{
if ((nIndex < 0) && (nIndex != GCW_ATOM))
return 0;
return (WORD) SetClassLongW ( hWnd, nIndex, wNewWord );
}
/*
* @implemented
*/
LONG
STDCALL
SetWindowLongA(
HWND hWnd,
int nIndex,
LONG dwNewLong)
{
return NtUserSetWindowLong(hWnd, nIndex, dwNewLong, TRUE);
}
/*
* @implemented
*/
LONG
STDCALL
SetWindowLongW(
HWND hWnd,
int nIndex,
LONG dwNewLong)
{
return NtUserSetWindowLong(hWnd, nIndex, dwNewLong, FALSE);
}
/*
* @implemented
*/
BOOL
STDCALL
UnregisterClassA(
LPCSTR lpClassName,
HINSTANCE hInstance)
{
UNICODE_STRING ClassName = {0};
NTSTATUS Status;
BOOL Ret;
TRACE("class/atom: %s/%04x %p\n",
IS_ATOM(lpClassName) ? NULL : lpClassName,
IS_ATOM(lpClassName) ? lpClassName : 0,
hInstance);
if (!IS_ATOM(lpClassName))
{
Status = HEAP_strdupAtoW(&ClassName.Buffer, lpClassName, NULL);
if (!NT_SUCCESS(Status))
{
SetLastError(RtlNtStatusToDosError(Status));
return FALSE;
}
RtlInitUnicodeString(&ClassName,
ClassName.Buffer);
}
else
ClassName.Buffer = (PWSTR)((ULONG_PTR)lpClassName);
Ret = NtUserUnregisterClass(&ClassName,
hInstance);
if(!IS_ATOM(lpClassName) && ClassName.Buffer != NULL)
HEAP_free(ClassName.Buffer);
return Ret;
}
/*
* @implemented
*/
BOOL
STDCALL
UnregisterClassW(
LPCWSTR lpClassName,
HINSTANCE hInstance)
{
UNICODE_STRING ClassName = {0};
TRACE("class/atom: %S/%04x %p\n",
IS_ATOM(lpClassName) ? NULL : lpClassName,
IS_ATOM(lpClassName) ? lpClassName : 0,
hInstance);
if (!IS_ATOM(lpClassName))
{
RtlInitUnicodeString(&ClassName,
lpClassName);
}
else
ClassName.Buffer = (PWSTR)((ULONG_PTR)lpClassName);
return NtUserUnregisterClass(&ClassName,
hInstance);
}
/* EOF */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -