https://git.reactos.org/?p=reactos.git;a=commitdiff;h=245513e7eceb3cb445c51…
commit 245513e7eceb3cb445c51a989769c967260d4882
Author: Justin Miller <justin.miller(a)reactos.org>
AuthorDate: Wed Jan 29 02:08:11 2025 -0800
Commit: Justin Miller <justinmiller100(a)gmail.com>
CommitDate: Sun Mar 9 04:07:55 2025 -0700
[USER32_VISTA] Import input.c misc.c win.c from wine-10.0
---
win32ss/user/user32_vista/wine/input.c | 889 ++++++++++++++++
win32ss/user/user32_vista/wine/misc.c | 545 ++++++++++
win32ss/user/user32_vista/wine/win.c | 1731 ++++++++++++++++++++++++++++++++
3 files changed, 3165 insertions(+)
diff --git a/win32ss/user/user32_vista/wine/input.c
b/win32ss/user/user32_vista/wine/input.c
new file mode 100644
index 00000000000..38c44d7d831
--- /dev/null
+++ b/win32ss/user/user32_vista/wine/input.c
@@ -0,0 +1,889 @@
+/*
+ * USER Input processing
+ *
+ * Copyright 1993 Bob Amstadt
+ * Copyright 1996 Albrecht Kleine
+ * Copyright 1997 David Faure
+ * Copyright 1998 Morten Welinder
+ * Copyright 1998 Ulrich Weigand
+ * Copyright 2012 Henri Verbeet
+ * Copyright 2018 Zebediah Figura for CodeWeavers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "user_private.h"
+#include "dbt.h"
+#include "wine/debug.h"
+#include "wine/plugplay.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(win);
+WINE_DECLARE_DEBUG_CHANNEL(keyboard);
+
+/***********************************************************************
+ * get_locale_kbd_layout
+ */
+static HKL get_locale_kbd_layout(void)
+{
+ ULONG_PTR layout;
+
+ /* FIXME:
+ *
+ * layout = main_key_tab[kbd_layout].lcid;
+ *
+ * Winword uses return value of GetKeyboardLayout as a codepage
+ * to translate ANSI keyboard messages to unicode. But we have
+ * a problem with it: for instance Polish keyboard layout is
+ * identical to the US one, and therefore instead of the Polish
+ * locale id we return the US one.
+ */
+
+ layout = GetUserDefaultLCID();
+ layout = MAKELONG( layout, layout );
+ return (HKL)layout;
+}
+
+
+/***********************************************************************
+ * keybd_event (USER32.@)
+ */
+void WINAPI keybd_event( BYTE bVk, BYTE bScan,
+ DWORD dwFlags, ULONG_PTR dwExtraInfo )
+{
+ INPUT input;
+
+ input.type = INPUT_KEYBOARD;
+ input.ki.wVk = bVk;
+ input.ki.wScan = bScan;
+ input.ki.dwFlags = dwFlags;
+ input.ki.time = 0;
+ input.ki.dwExtraInfo = dwExtraInfo;
+ NtUserSendInput( 1, &input, sizeof(input) );
+}
+
+
+/***********************************************************************
+ * mouse_event (USER32.@)
+ */
+void WINAPI mouse_event( DWORD dwFlags, DWORD dx, DWORD dy,
+ DWORD dwData, ULONG_PTR dwExtraInfo )
+{
+ INPUT input;
+
+ input.type = INPUT_MOUSE;
+ input.mi.dx = dx;
+ input.mi.dy = dy;
+ input.mi.mouseData = dwData;
+ input.mi.dwFlags = dwFlags;
+ input.mi.time = 0;
+ input.mi.dwExtraInfo = dwExtraInfo;
+ NtUserSendInput( 1, &input, sizeof(input) );
+}
+
+
+/***********************************************************************
+ * GetCursorPos (USER32.@)
+ */
+BOOL WINAPI DECLSPEC_HOTPATCH GetCursorPos( POINT *pt )
+{
+ return NtUserGetCursorPos( pt );
+}
+
+
+/**********************************************************************
+ * ReleaseCapture (USER32.@)
+ */
+BOOL WINAPI DECLSPEC_HOTPATCH ReleaseCapture(void)
+{
+ return NtUserReleaseCapture();
+}
+
+
+/**********************************************************************
+ * GetCapture (USER32.@)
+ */
+HWND WINAPI GetCapture(void)
+{
+ GUITHREADINFO info;
+ info.cbSize = sizeof(info);
+ return NtUserGetGUIThreadInfo( GetCurrentThreadId(), &info ) ? info.hwndCapture :
0;
+}
+
+
+/*****************************************************************
+ * DestroyCaret (USER32.@)
+ */
+BOOL WINAPI DestroyCaret(void)
+{
+ return NtUserDestroyCaret();
+}
+
+
+/*****************************************************************
+ * SetCaretPos (USER32.@)
+ */
+BOOL WINAPI SetCaretPos( int x, int y )
+{
+ return NtUserSetCaretPos( x, y );
+}
+
+
+/*****************************************************************
+ * SetCaretBlinkTime (USER32.@)
+ */
+BOOL WINAPI SetCaretBlinkTime( unsigned int time )
+{
+ return NtUserSetCaretBlinkTime( time );
+}
+
+
+/***********************************************************************
+ * GetInputState (USER32.@)
+ */
+BOOL WINAPI GetInputState(void)
+{
+ return NtUserGetInputState();
+}
+
+
+/******************************************************************
+ * GetLastInputInfo (USER32.@)
+ */
+BOOL WINAPI GetLastInputInfo(PLASTINPUTINFO plii)
+{
+ TRACE("%p\n", plii);
+
+ if (plii->cbSize != sizeof (*plii) )
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
+ plii->dwTime = NtUserGetLastInputTime();
+ return TRUE;
+}
+
+
+/**********************************************************************
+ * VkKeyScanA (USER32.@)
+ *
+ * VkKeyScan translates an ANSI character to a virtual-key and shift code
+ * for the current keyboard.
+ * high-order byte yields :
+ * 0 Unshifted
+ * 1 Shift
+ * 2 Ctrl
+ * 3-5 Shift-key combinations that are not used for characters
+ * 6 Ctrl-Alt
+ * 7 Ctrl-Alt-Shift
+ * I.e. : Shift = 1, Ctrl = 2, Alt = 4.
+ * FIXME : works ok except for dead chars :
+ * VkKeyScan '^'(0x5e, 94) ... got keycode 00 ... returning 00
+ * VkKeyScan '`'(0x60, 96) ... got keycode 00 ... returning 00
+ */
+SHORT WINAPI VkKeyScanA(CHAR cChar)
+{
+ WCHAR wChar;
+
+ if (IsDBCSLeadByte(cChar)) return -1;
+
+ MultiByteToWideChar(CP_ACP, 0, &cChar, 1, &wChar, 1);
+ return VkKeyScanW(wChar);
+}
+
+/******************************************************************************
+ * VkKeyScanW (USER32.@)
+ */
+SHORT WINAPI VkKeyScanW(WCHAR cChar)
+{
+ return NtUserVkKeyScanEx( cChar, NtUserGetKeyboardLayout(0) );
+}
+
+/**********************************************************************
+ * VkKeyScanExA (USER32.@)
+ */
+WORD WINAPI VkKeyScanExA(CHAR cChar, HKL dwhkl)
+{
+ WCHAR wChar;
+
+ if (IsDBCSLeadByte(cChar)) return -1;
+
+ MultiByteToWideChar(CP_ACP, 0, &cChar, 1, &wChar, 1);
+ return NtUserVkKeyScanEx( wChar, dwhkl );
+}
+
+/**********************************************************************
+ * OemKeyScan (USER32.@)
+ */
+DWORD WINAPI OemKeyScan( WORD oem )
+{
+ WCHAR wchr;
+ DWORD vkey, scan;
+ char oem_char = LOBYTE( oem );
+
+ if (!OemToCharBuffW( &oem_char, &wchr, 1 ))
+ return -1;
+
+ vkey = VkKeyScanW( wchr );
+ scan = MapVirtualKeyW( LOBYTE( vkey ), MAPVK_VK_TO_VSC );
+ if (!scan) return -1;
+
+ vkey &= 0xff00;
+ vkey <<= 8;
+ return vkey | scan;
+}
+
+/******************************************************************************
+ * GetKeyboardType (USER32.@)
+ */
+INT WINAPI GetKeyboardType(INT nTypeFlag)
+{
+ TRACE_(keyboard)("(%d)\n", nTypeFlag);
+ if (LOWORD(NtUserGetKeyboardLayout(0)) == MAKELANGID(LANG_JAPANESE,
SUBLANG_JAPANESE_JAPAN))
+ {
+ /* scan code for `_', the key left of r-shift, in Japanese 106 keyboard */
+ const UINT JP106_VSC_USCORE = 0x73;
+
+ switch(nTypeFlag)
+ {
+ case 0: /* Keyboard type */
+ return 7; /* Japanese keyboard */
+ case 1: /* Keyboard Subtype */
+ /* Test keyboard mappings to detect Japanese keyboard */
+ if (MapVirtualKeyW(VK_OEM_102, MAPVK_VK_TO_VSC) == JP106_VSC_USCORE
+ && MapVirtualKeyW(JP106_VSC_USCORE, MAPVK_VSC_TO_VK) ==
VK_OEM_102)
+ return 2; /* Japanese 106 */
+ else
+ return 0; /* AT-101 */
+ case 2: /* Number of F-keys */
+ return 12; /* It has 12 F-keys */
+ }
+ }
+ else
+ {
+ switch(nTypeFlag)
+ {
+ case 0: /* Keyboard type */
+ return 4; /* AT-101 */
+ case 1: /* Keyboard Subtype */
+ return 0; /* There are no defined subtypes */
+ case 2: /* Number of F-keys */
+ return 12; /* We're doing an 101 for now, so return 12 F-keys */
+ }
+ }
+ WARN_(keyboard)("Unknown type\n");
+ return 0; /* The book says 0 here, so 0 */
+}
+
+/******************************************************************************
+ * MapVirtualKeyA (USER32.@)
+ */
+UINT WINAPI MapVirtualKeyA(UINT code, UINT maptype)
+{
+ return MapVirtualKeyExA( code, maptype, NtUserGetKeyboardLayout(0) );
+}
+
+/******************************************************************************
+ * MapVirtualKeyW (USER32.@)
+ */
+UINT WINAPI MapVirtualKeyW(UINT code, UINT maptype)
+{
+ return NtUserMapVirtualKeyEx( code, maptype, NtUserGetKeyboardLayout(0) );
+}
+
+/******************************************************************************
+ * MapVirtualKeyExA (USER32.@)
+ */
+UINT WINAPI MapVirtualKeyExA(UINT code, UINT maptype, HKL hkl)
+{
+ UINT ret;
+
+ ret = NtUserMapVirtualKeyEx( code, maptype, hkl );
+ if (maptype == MAPVK_VK_TO_CHAR)
+ {
+ BYTE ch = 0;
+ WCHAR wch = ret;
+
+ WideCharToMultiByte( CP_ACP, 0, &wch, 1, (LPSTR)&ch, 1, NULL, NULL );
+ ret = ch;
+ }
+ return ret;
+}
+
+/****************************************************************************
+ * GetKBCodePage (USER32.@)
+ */
+UINT WINAPI GetKBCodePage(void)
+{
+ return GetOEMCP();
+}
+
+/****************************************************************************
+ * GetKeyboardLayoutNameA (USER32.@)
+ */
+BOOL WINAPI GetKeyboardLayoutNameA(LPSTR pszKLID)
+{
+ WCHAR buf[KL_NAMELENGTH];
+
+ if (NtUserGetKeyboardLayoutName( buf ))
+ return WideCharToMultiByte( CP_ACP, 0, buf, -1, pszKLID, KL_NAMELENGTH, NULL,
NULL ) != 0;
+ return FALSE;
+}
+
+/****************************************************************************
+ * GetKeyNameTextA (USER32.@)
+ */
+INT WINAPI GetKeyNameTextA(LONG lParam, LPSTR lpBuffer, INT nSize)
+{
+ WCHAR buf[256];
+ INT ret;
+
+ if (!nSize || !NtUserGetKeyNameText( lParam, buf, ARRAYSIZE(buf) ))
+ {
+ lpBuffer[0] = 0;
+ return 0;
+ }
+ ret = WideCharToMultiByte(CP_ACP, 0, buf, -1, lpBuffer, nSize, NULL, NULL);
+ if (!ret && nSize)
+ {
+ ret = nSize - 1;
+ lpBuffer[ret] = 0;
+ }
+ else ret--;
+
+ return ret;
+}
+
+/****************************************************************************
+ * ToUnicode (USER32.@)
+ */
+INT WINAPI ToUnicode( UINT virt, UINT scan, const BYTE *state, LPWSTR str, int size, UINT
flags )
+{
+ return NtUserToUnicodeEx( virt, scan, state, str, size, flags,
NtUserGetKeyboardLayout(0) );
+}
+
+/****************************************************************************
+ * ToAscii (USER32.@)
+ */
+INT WINAPI ToAscii( UINT virtKey, UINT scanCode, const BYTE *lpKeyState,
+ LPWORD lpChar, UINT flags )
+{
+ return ToAsciiEx( virtKey, scanCode, lpKeyState, lpChar, flags,
+ NtUserGetKeyboardLayout(0) );
+}
+
+/****************************************************************************
+ * ToAsciiEx (USER32.@)
+ */
+INT WINAPI ToAsciiEx( UINT virtKey, UINT scanCode, const BYTE *lpKeyState,
+ LPWORD lpChar, UINT flags, HKL dwhkl )
+{
+ WCHAR uni_chars[2];
+ INT ret, n_ret;
+
+ ret = NtUserToUnicodeEx( virtKey, scanCode, lpKeyState, uni_chars, 2, flags, dwhkl );
+ if (ret < 0) n_ret = 1; /* FIXME: make ToUnicode return 2 for dead chars */
+ else n_ret = ret;
+ WideCharToMultiByte(CP_ACP, 0, uni_chars, n_ret, (LPSTR)lpChar, 2, NULL, NULL);
+ return ret;
+}
+
+/**********************************************************************
+ * BlockInput (USER32.@)
+ */
+BOOL WINAPI BlockInput(BOOL fBlockIt)
+{
+ FIXME_(keyboard)("(%d): stub\n", fBlockIt);
+ SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+
+ return FALSE;
+}
+
+
+/***********************************************************************
+ * LoadKeyboardLayoutW (USER32.@)
+ */
+HKL WINAPI LoadKeyboardLayoutW( const WCHAR *name, UINT flags )
+{
+ WCHAR layout_path[MAX_PATH], value[5];
+ LCID locale = GetUserDefaultLCID();
+ DWORD id, value_size, tmp;
+ HKEY hkey;
+ HKL layout;
+
+ FIXME_(keyboard)( "name %s, flags %x, semi-stub!\n", debugstr_w( name ),
flags );
+
+ tmp = wcstoul( name, NULL, 16 );
+ if (HIWORD( tmp )) layout = UlongToHandle( tmp );
+ else layout = UlongToHandle( MAKELONG( LOWORD( tmp ), LOWORD( tmp ) ) );
+
+ if (!((UINT_PTR)layout >> 28)) id = LOWORD( tmp );
+ else id = HIWORD( layout ); /* IME or aliased layout */
+
+ wcscpy( layout_path, L"System\\CurrentControlSet\\Control\\Keyboard
Layouts\\" );
+ wcscat( layout_path, name );
+
+ if (!RegOpenKeyW( HKEY_LOCAL_MACHINE, layout_path, &hkey ))
+ {
+ value_size = sizeof(value);
+ if (!RegGetValueW( hkey, NULL, L"Layout Id", RRF_RT_REG_SZ, NULL, (void
*)&value, &value_size ))
+ id = 0xf000 | (wcstoul( value, NULL, 16 ) & 0xfff);
+
+ RegCloseKey( hkey );
+ }
+
+ layout = UlongToHandle( MAKELONG( locale, id ) );
+ if ((flags & KLF_ACTIVATE) && NtUserActivateKeyboardLayout( layout, 0 ))
return layout;
+
+ /* FIXME: semi-stub: returning default layout */
+ return get_locale_kbd_layout();
+}
+
+/***********************************************************************
+ * LoadKeyboardLayoutA (USER32.@)
+ */
+HKL WINAPI LoadKeyboardLayoutA(LPCSTR pwszKLID, UINT Flags)
+{
+ HKL ret;
+ UNICODE_STRING pwszKLIDW;
+
+ if (pwszKLID) RtlCreateUnicodeStringFromAsciiz(&pwszKLIDW, pwszKLID);
+ else pwszKLIDW.Buffer = NULL;
+
+ ret = LoadKeyboardLayoutW(pwszKLIDW.Buffer, Flags);
+ RtlFreeUnicodeString(&pwszKLIDW);
+ return ret;
+}
+
+
+/***********************************************************************
+ * LoadKeyboardLayoutEx (USER32.@)
+ */
+HKL WINAPI LoadKeyboardLayoutEx( HKL layout, const WCHAR *name, UINT flags )
+{
+ FIXME_(keyboard)( "layout %p, name %s, flags %x, semi-stub!\n", layout,
debugstr_w( name ), flags );
+
+ if (!layout) return NULL;
+ return LoadKeyboardLayoutW( name, flags );
+}
+
+/***********************************************************************
+ * UnloadKeyboardLayout (USER32.@)
+ */
+BOOL WINAPI UnloadKeyboardLayout( HKL layout )
+{
+ FIXME_(keyboard)( "layout %p, stub!\n", layout );
+ SetLastError( ERROR_CALL_NOT_IMPLEMENTED );
+ return FALSE;
+}
+
+
+static DWORD CALLBACK devnotify_window_callbackW(HANDLE handle, DWORD flags,
DEV_BROADCAST_HDR *header)
+{
+ SendMessageTimeoutW(handle, WM_DEVICECHANGE, flags, (LPARAM)header, SMTO_ABORTIFHUNG,
2000, NULL);
+ return 0;
+}
+
+static DWORD CALLBACK devnotify_window_callbackA(HANDLE handle, DWORD flags,
DEV_BROADCAST_HDR *header)
+{
+ if (flags & 0x8000)
+ {
+ switch (header->dbch_devicetype)
+ {
+ case DBT_DEVTYP_DEVICEINTERFACE:
+ {
+ const DEV_BROADCAST_DEVICEINTERFACE_W *ifaceW = (const
DEV_BROADCAST_DEVICEINTERFACE_W *)header;
+ size_t lenW = wcslen( ifaceW->dbcc_name );
+ DEV_BROADCAST_DEVICEINTERFACE_A *ifaceA;
+ DWORD lenA;
+
+ if (!(ifaceA = malloc( offsetof(DEV_BROADCAST_DEVICEINTERFACE_A,
dbcc_name[lenW * 3 + 1]) )))
+ return 0;
+ lenA = WideCharToMultiByte( CP_ACP, 0, ifaceW->dbcc_name, lenW + 1,
+ ifaceA->dbcc_name, lenW * 3 + 1, NULL, NULL );
+
+ ifaceA->dbcc_size = offsetof(DEV_BROADCAST_DEVICEINTERFACE_A,
dbcc_name[lenA + 1]);
+ ifaceA->dbcc_devicetype = ifaceW->dbcc_devicetype;
+ ifaceA->dbcc_reserved = ifaceW->dbcc_reserved;
+ ifaceA->dbcc_classguid = ifaceW->dbcc_classguid;
+ SendMessageTimeoutA( handle, WM_DEVICECHANGE, flags, (LPARAM)ifaceA,
SMTO_ABORTIFHUNG, 2000, NULL );
+ free( ifaceA );
+ return 0;
+ }
+
+ case DBT_DEVTYP_HANDLE:
+ {
+ const DEV_BROADCAST_HANDLE *handleW = (const DEV_BROADCAST_HANDLE *)header;
+ UINT sizeW = handleW->dbch_size - offsetof(DEV_BROADCAST_HANDLE,
dbch_data[0]), len, offset;
+ DEV_BROADCAST_HANDLE *handleA;
+
+ if (!(handleA = malloc( offsetof(DEV_BROADCAST_HANDLE, dbch_data[sizeW * 3 +
1]) ))) return 0;
+ memcpy( handleA, handleW, offsetof(DEV_BROADCAST_HANDLE, dbch_data[0]) );
+ offset = min( sizeW, handleW->dbch_nameoffset );
+
+ memcpy( handleA->dbch_data, handleW->dbch_data, offset );
+ len = WideCharToMultiByte( CP_ACP, 0, (WCHAR *)(handleW->dbch_data +
offset), (sizeW - offset) / sizeof(WCHAR),
+ (char *)handleA->dbch_data + offset, sizeW * 3
+ 1 - offset, NULL, NULL );
+ handleA->dbch_size = offsetof(DEV_BROADCAST_HANDLE, dbch_data[offset + len
+ 1]);
+
+ SendMessageTimeoutA( handle, WM_DEVICECHANGE, flags, (LPARAM)handleA,
SMTO_ABORTIFHUNG, 2000, NULL );
+ free( handleA );
+ return 0;
+ }
+
+ case DBT_DEVTYP_OEM:
+ break;
+ default:
+ FIXME( "unimplemented W to A mapping for %#lx\n",
header->dbch_devicetype );
+ }
+ }
+
+ SendMessageTimeoutA( handle, WM_DEVICECHANGE, flags, (LPARAM)header,
SMTO_ABORTIFHUNG, 2000, NULL );
+ return 0;
+}
+
+static DWORD CALLBACK devnotify_service_callback(HANDLE handle, DWORD flags,
DEV_BROADCAST_HDR *header)
+{
+ FIXME("Support for service handles is not yet implemented!\n");
+ return 0;
+}
+
+/***********************************************************************
+ * RegisterDeviceNotificationA (USER32.@)
+ *
+ * See RegisterDeviceNotificationW.
+ */
+HDEVNOTIFY WINAPI RegisterDeviceNotificationA( HANDLE handle, void *filter, DWORD flags )
+{
+ return RegisterDeviceNotificationW( handle, filter, flags );
+}
+
+/***********************************************************************
+ * RegisterDeviceNotificationW (USER32.@)
+ */
+HDEVNOTIFY WINAPI RegisterDeviceNotificationW( HANDLE handle, void *filter, DWORD flags )
+{
+ DEV_BROADCAST_HDR *header = filter;
+ device_notify_callback callback;
+
+ TRACE("handle %p, filter %p, flags %#lx\n", handle, filter, flags);
+
+ if (flags & ~(DEVICE_NOTIFY_SERVICE_HANDLE |
DEVICE_NOTIFY_ALL_INTERFACE_CLASSES))
+ {
+ SetLastError( ERROR_INVALID_PARAMETER );
+ return NULL;
+ }
+
+ if (!(flags & DEVICE_NOTIFY_SERVICE_HANDLE) && !IsWindow( handle ))
+ {
+ SetLastError( ERROR_INVALID_PARAMETER );
+ return NULL;
+ }
+
+ if (flags & DEVICE_NOTIFY_SERVICE_HANDLE)
+ callback = devnotify_service_callback;
+ else if (IsWindowUnicode( handle ))
+ callback = devnotify_window_callbackW;
+ else
+ callback = devnotify_window_callbackA;
+
+ if (!header)
+ {
+ DEV_BROADCAST_HDR dummy = {0};
+ return I_ScRegisterDeviceNotification( handle, &dummy, callback );
+ }
+ if (header->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE)
+ {
+ DEV_BROADCAST_DEVICEINTERFACE_W iface = *(DEV_BROADCAST_DEVICEINTERFACE_W
*)header;
+
+ if (flags & DEVICE_NOTIFY_ALL_INTERFACE_CLASSES)
+ iface.dbcc_size = offsetof( DEV_BROADCAST_DEVICEINTERFACE_W, dbcc_classguid
);
+ else
+ iface.dbcc_size = offsetof( DEV_BROADCAST_DEVICEINTERFACE_W, dbcc_name );
+
+ return I_ScRegisterDeviceNotification( handle, (DEV_BROADCAST_HDR *)&iface,
callback );
+ }
+ if (header->dbch_devicetype == DBT_DEVTYP_HANDLE)
+ {
+ FIXME( "DBT_DEVTYP_HANDLE not implemented\n" );
+ return I_ScRegisterDeviceNotification( handle, header, callback );
+ }
+
+ FIXME( "type %#lx not implemented\n", header->dbch_devicetype );
+ SetLastError( ERROR_INVALID_DATA );
+ return NULL;
+}
+
+/***********************************************************************
+ * UnregisterDeviceNotification (USER32.@)
+ */
+BOOL WINAPI UnregisterDeviceNotification( HDEVNOTIFY handle )
+{
+ TRACE("%p\n", handle);
+
+ return I_ScUnregisterDeviceNotification( handle );
+}
+
+/***********************************************************************
+ * GetRawInputDeviceInfoA (USER32.@)
+ */
+UINT WINAPI GetRawInputDeviceInfoA( HANDLE device, UINT command, void *data, UINT *size )
+{
+ TRACE( "device %p, command %#x, data %p, size %p.\n", device, command,
data, size );
+
+ /* RIDI_DEVICENAME size is in chars, not bytes */
+ if (command == RIDI_DEVICENAME)
+ {
+ WCHAR *nameW;
+ UINT ret, sizeW;
+
+ if (!size) return ~0U;
+
+ sizeW = *size;
+
+ if (data && sizeW > 0)
+ nameW = HeapAlloc( GetProcessHeap(), 0, sizeof(WCHAR) * sizeW );
+ else
+ nameW = NULL;
+
+ ret = NtUserGetRawInputDeviceInfo( device, command, nameW, &sizeW );
+
+ if (ret && ret != ~0U)
+ WideCharToMultiByte( CP_ACP, 0, nameW, -1, data, *size, NULL, NULL );
+
+ *size = sizeW;
+
+ HeapFree( GetProcessHeap(), 0, nameW );
+
+ return ret;
+ }
+
+ return NtUserGetRawInputDeviceInfo( device, command, data, size );
+}
+
+/***********************************************************************
+ * DefRawInputProc (USER32.@)
+ */
+LRESULT WINAPI DefRawInputProc( RAWINPUT **data, INT data_count, UINT header_size )
+{
+ TRACE( "data %p, data_count %d, header_size %u.\n", data, data_count,
header_size );
+
+ return header_size == sizeof(RAWINPUTHEADER) ? 0 : -1;
+}
+
+/*****************************************************************************
+ * CloseTouchInputHandle (USER32.@)
+ */
+BOOL WINAPI CloseTouchInputHandle( HTOUCHINPUT handle )
+{
+ FIXME( "handle %p stub!\n", handle );
+ SetLastError( ERROR_CALL_NOT_IMPLEMENTED );
+ return FALSE;
+}
+
+/*****************************************************************************
+ * GetTouchInputInfo (USER32.@)
+ */
+BOOL WINAPI GetTouchInputInfo( HTOUCHINPUT handle, UINT count, TOUCHINPUT *ptr, int size
)
+{
+ FIXME( "handle %p, count %u, ptr %p, size %u stub!\n", handle, count, ptr,
size );
+ SetLastError( ERROR_CALL_NOT_IMPLEMENTED );
+ return FALSE;
+}
+
+/**********************************************************************
+ * IsTouchWindow (USER32.@)
+ */
+BOOL WINAPI IsTouchWindow( HWND hwnd, ULONG *flags )
+{
+ FIXME( "hwnd %p, flags %p stub!\n", hwnd, flags );
+ return FALSE;
+}
+
+/*****************************************************************************
+ * RegisterTouchWindow (USER32.@)
+ */
+BOOL WINAPI RegisterTouchWindow( HWND hwnd, ULONG flags )
+{
+ FIXME( "hwnd %p, flags %#lx stub!\n", hwnd, flags );
+ return TRUE;
+}
+
+/*****************************************************************************
+ * UnregisterTouchWindow (USER32.@)
+ */
+BOOL WINAPI UnregisterTouchWindow( HWND hwnd )
+{
+ FIXME( "hwnd %p stub!\n", hwnd );
+ return TRUE;
+}
+
+/*****************************************************************************
+ * GetGestureInfo (USER32.@)
+ */
+BOOL WINAPI CloseGestureInfoHandle( HGESTUREINFO handle )
+{
+ FIXME( "handle %p stub!\n", handle );
+ SetLastError( ERROR_CALL_NOT_IMPLEMENTED );
+ return FALSE;
+}
+
+/*****************************************************************************
+ * GetGestureInfo (USER32.@)
+ */
+BOOL WINAPI GetGestureExtraArgs( HGESTUREINFO handle, UINT count, BYTE *args )
+{
+ FIXME( "handle %p, count %u, args %p stub!\n", handle, count, args );
+ SetLastError( ERROR_CALL_NOT_IMPLEMENTED );
+ return FALSE;
+}
+
+/*****************************************************************************
+ * GetGestureInfo (USER32.@)
+ */
+BOOL WINAPI GetGestureInfo( HGESTUREINFO handle, GESTUREINFO *ptr )
+{
+ FIXME( "handle %p, ptr %p stub!\n", handle, ptr );
+ SetLastError( ERROR_CALL_NOT_IMPLEMENTED );
+ return FALSE;
+}
+
+/*****************************************************************************
+ * GetGestureConfig (USER32.@)
+ */
+BOOL WINAPI GetGestureConfig( HWND hwnd, DWORD reserved, DWORD flags, UINT *count,
+ GESTURECONFIG *config, UINT size )
+{
+ FIXME( "handle %p, reserved %#lx, flags %#lx, count %p, config %p, size %u
stub!\n",
+ hwnd, reserved, flags, count, config, size );
+ SetLastError( ERROR_CALL_NOT_IMPLEMENTED );
+ return FALSE;
+}
+
+/**********************************************************************
+ * SetGestureConfig (USER32.@)
+ */
+BOOL WINAPI SetGestureConfig( HWND hwnd, DWORD reserved, UINT count,
+ GESTURECONFIG *config, UINT size )
+{
+ FIXME( "handle %p, reserved %#lx, count %u, config %p, size %u stub!\n",
+ hwnd, reserved, count, config, size );
+ SetLastError( ERROR_CALL_NOT_IMPLEMENTED );
+ return FALSE;
+}
+
+BOOL WINAPI GetPointerTouchInfo( UINT32 id, POINTER_TOUCH_INFO *info )
+{
+ FIXME( "id %u, info %p stub!\n", id, info );
+ SetLastError( ERROR_CALL_NOT_IMPLEMENTED );
+ return FALSE;
+}
+
+BOOL WINAPI GetPointerTouchInfoHistory( UINT32 id, UINT32 *count, POINTER_TOUCH_INFO
*info )
+{
+ FIXME( "id %u, count %p, info %p stub!\n", id, count, info );
+ SetLastError( ERROR_CALL_NOT_IMPLEMENTED );
+ return FALSE;
+}
+
+
+/*******************************************************************
+ * SetForegroundWindow (USER32.@)
+ */
+BOOL WINAPI SetForegroundWindow( HWND hwnd )
+{
+ return NtUserSetForegroundWindow( hwnd );
+}
+
+
+/*******************************************************************
+ * GetActiveWindow (USER32.@)
+ */
+HWND WINAPI GetActiveWindow(void)
+{
+ GUITHREADINFO info;
+ info.cbSize = sizeof(info);
+ return NtUserGetGUIThreadInfo( GetCurrentThreadId(), &info ) ? info.hwndActive :
0;
+}
+
+
+/*****************************************************************
+ * GetFocus (USER32.@)
+ */
+HWND WINAPI GetFocus(void)
+{
+ GUITHREADINFO info;
+ info.cbSize = sizeof(info);
+ return NtUserGetGUIThreadInfo( GetCurrentThreadId(), &info ) ? info.hwndFocus :
0;
+}
+
+
+/*******************************************************************
+ * SetShellWindow (USER32.@)
+ */
+BOOL WINAPI SetShellWindow( HWND hwnd )
+{
+ return NtUserSetShellWindowEx( hwnd, hwnd );
+}
+
+
+/*******************************************************************
+ * GetShellWindow (USER32.@)
+ */
+HWND WINAPI GetShellWindow(void)
+{
+ return NtUserGetShellWindow();
+}
+
+
+/***********************************************************************
+ * SetProgmanWindow (USER32.@)
+ */
+HWND WINAPI SetProgmanWindow( HWND hwnd )
+{
+ return NtUserSetProgmanWindow( hwnd );
+}
+
+
+/***********************************************************************
+ * GetProgmanWindow (USER32.@)
+ */
+HWND WINAPI GetProgmanWindow(void)
+{
+ return NtUserGetProgmanWindow();
+}
+
+
+/***********************************************************************
+ * SetTaskmanWindow (USER32.@)
+ */
+HWND WINAPI SetTaskmanWindow( HWND hwnd )
+{
+ return NtUserSetTaskmanWindow( hwnd );
+}
+
+/***********************************************************************
+ * GetTaskmanWindow (USER32.@)
+ */
+HWND WINAPI GetTaskmanWindow(void)
+{
+ return NtUserGetTaskmanWindow();
+}
+
+HSYNTHETICPOINTERDEVICE WINAPI CreateSyntheticPointerDevice(POINTER_INPUT_TYPE type,
ULONG max_count, POINTER_FEEDBACK_MODE mode)
+{
+ FIXME( "type %ld, max_count %ld, mode %d stub!\n", type, max_count, mode);
+ SetLastError( ERROR_CALL_NOT_IMPLEMENTED );
+ return NULL;
+}
diff --git a/win32ss/user/user32_vista/wine/misc.c b/win32ss/user/user32_vista/wine/misc.c
new file mode 100644
index 00000000000..6333fcb48b4
--- /dev/null
+++ b/win32ss/user/user32_vista/wine/misc.c
@@ -0,0 +1,545 @@
+/*
+ * Misc USER functions
+ *
+ * Copyright 1995 Thomas Sandford
+ * Copyright 1997 Marcus Meissner
+ * Copyright 1998 Turchanov Sergey
+ * Copyright 2019 Micah N Gorrell for CodeWeavers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <stdarg.h>
+
+#include "windef.h"
+#include "wine/windef16.h"
+#include "winbase.h"
+#include "wingdi.h"
+#include "controls.h"
+#include "imm.h"
+#include "user_private.h"
+
+#include "wine/debug.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(win);
+
+BOOL WINAPI ImmSetActiveContext(HWND, HIMC, BOOL);
+
+#define IMM_INIT_MAGIC 0x19650412
+static LRESULT (WINAPI *imm_ime_wnd_proc)( HWND hwnd, UINT msg, WPARAM wparam, LPARAM
lparam, BOOL ansi);
+
+/* USER signal proc flags and codes */
+/* See UserSignalProc for comments */
+#define USIG_FLAGS_WIN32 0x0001
+#define USIG_FLAGS_GUI 0x0002
+#define USIG_FLAGS_FEEDBACK 0x0004
+#define USIG_FLAGS_FAULT 0x0008
+
+#define USIG_DLL_UNLOAD_WIN16 0x0001
+#define USIG_DLL_UNLOAD_WIN32 0x0002
+#define USIG_FAULT_DIALOG_PUSH 0x0003
+#define USIG_FAULT_DIALOG_POP 0x0004
+#define USIG_DLL_UNLOAD_ORPHANS 0x0005
+#define USIG_THREAD_INIT 0x0010
+#define USIG_THREAD_EXIT 0x0020
+#define USIG_PROCESS_CREATE 0x0100
+#define USIG_PROCESS_INIT 0x0200
+#define USIG_PROCESS_EXIT 0x0300
+#define USIG_PROCESS_DESTROY 0x0400
+#define USIG_PROCESS_RUNNING 0x0500
+#define USIG_PROCESS_LOADED 0x0600
+
+/***********************************************************************
+ * SignalProc32 (USER.391)
+ * UserSignalProc (USER32.@)
+ *
+ * The exact meaning of the USER signals is undocumented, but this
+ * should cover the basic idea:
+ *
+ * USIG_DLL_UNLOAD_WIN16
+ * This is sent when a 16-bit module is unloaded.
+ *
+ * USIG_DLL_UNLOAD_WIN32
+ * This is sent when a 32-bit module is unloaded.
+ *
+ * USIG_DLL_UNLOAD_ORPHANS
+ * This is sent after the last Win3.1 module is unloaded,
+ * to allow removal of orphaned menus.
+ *
+ * USIG_FAULT_DIALOG_PUSH
+ * USIG_FAULT_DIALOG_POP
+ * These are called to allow USER to prepare for displaying a
+ * fault dialog, even though the fault might have happened while
+ * inside a USER critical section.
+ *
+ * USIG_THREAD_INIT
+ * This is called from the context of a new thread, as soon as it
+ * has started to run.
+ *
+ * USIG_THREAD_EXIT
+ * This is called, still in its context, just before a thread is
+ * about to terminate.
+ *
+ * USIG_PROCESS_CREATE
+ * This is called, in the parent process context, after a new process
+ * has been created.
+ *
+ * USIG_PROCESS_INIT
+ * This is called in the new process context, just after the main thread
+ * has started execution (after the main thread's USIG_THREAD_INIT has
+ * been sent).
+ *
+ * USIG_PROCESS_LOADED
+ * This is called after the executable file has been loaded into the
+ * new process context.
+ *
+ * USIG_PROCESS_RUNNING
+ * This is called immediately before the main entry point is called.
+ *
+ * USIG_PROCESS_EXIT
+ * This is called in the context of a process that is about to
+ * terminate (but before the last thread's USIG_THREAD_EXIT has
+ * been sent).
+ *
+ * USIG_PROCESS_DESTROY
+ * This is called after a process has terminated.
+ *
+ *
+ * The meaning of the dwFlags bits is as follows:
+ *
+ * USIG_FLAGS_WIN32
+ * Current process is 32-bit.
+ *
+ * USIG_FLAGS_GUI
+ * Current process is a (Win32) GUI process.
+ *
+ * USIG_FLAGS_FEEDBACK
+ * Current process needs 'feedback' (determined from the STARTUPINFO
+ * flags STARTF_FORCEONFEEDBACK / STARTF_FORCEOFFFEEDBACK).
+ *
+ * USIG_FLAGS_FAULT
+ * The signal is being sent due to a fault.
+ */
+WORD WINAPI UserSignalProc( UINT uCode, DWORD dwThreadOrProcessID,
+ DWORD dwFlags, HMODULE16 hModule )
+{
+ FIXME("(%04x, %08lx, %04lx, %04x)\n",
+ uCode, dwThreadOrProcessID, dwFlags, hModule );
+ /* FIXME: Should chain to GdiSignalProc now. */
+ return 0;
+}
+
+
+/**********************************************************************
+ * SetLastErrorEx [USER32.@]
+ *
+ * Sets the last-error code.
+ *
+ * RETURNS
+ * None.
+ */
+void WINAPI SetLastErrorEx(
+ DWORD error, /* [in] Per-thread error code */
+ DWORD type) /* [in] Error type */
+{
+ TRACE("(0x%08lx, 0x%08lx)\n", error,type);
+ switch(type) {
+ case 0:
+ break;
+ case SLE_ERROR:
+ case SLE_MINORERROR:
+ case SLE_WARNING:
+ /* Fall through for now */
+ default:
+ FIXME("(error=%08lx, type=%08lx): Unhandled type\n", error,type);
+ break;
+ }
+ SetLastError( error );
+}
+
+/******************************************************************************
+ * GetAltTabInfoA [USER32.@]
+ */
+BOOL WINAPI GetAltTabInfoA(HWND hwnd, int iItem, PALTTABINFO pati, LPSTR pszItemText,
UINT cchItemText)
+{
+ FIXME("(%p, 0x%08x, %p, %p, 0x%08x)\n", hwnd, iItem, pati, pszItemText,
cchItemText);
+ return FALSE;
+}
+
+/******************************************************************************
+ * GetAltTabInfoW [USER32.@]
+ */
+BOOL WINAPI GetAltTabInfoW(HWND hwnd, int iItem, PALTTABINFO pati, LPWSTR pszItemText,
UINT cchItemText)
+{
+ FIXME("(%p, 0x%08x, %p, %p, 0x%08x)\n", hwnd, iItem, pati, pszItemText,
cchItemText);
+ return FALSE;
+}
+
+/******************************************************************************
+ * SetDebugErrorLevel [USER32.@]
+ * Sets the minimum error level for generating debugging events
+ *
+ * PARAMS
+ * dwLevel [I] Debugging error level
+ *
+ * RETURNS
+ * Nothing.
+ */
+VOID WINAPI SetDebugErrorLevel( DWORD dwLevel )
+{
+ FIXME("(%ld): stub\n", dwLevel);
+}
+
+
+/***********************************************************************
+ * SetWindowStationUser (USER32.@)
+ */
+DWORD WINAPI SetWindowStationUser(DWORD x1,DWORD x2)
+{
+ FIXME("(0x%08lx,0x%08lx),stub!\n",x1,x2);
+ return 1;
+}
+
+/***********************************************************************
+ * RegisterLogonProcess (USER32.@)
+ */
+DWORD WINAPI RegisterLogonProcess(HANDLE hprocess,BOOL x)
+{
+ FIXME("(%p,%d),stub!\n",hprocess,x);
+ return 1;
+}
+
+/***********************************************************************
+ * SetLogonNotifyWindow (USER32.@)
+ */
+DWORD WINAPI SetLogonNotifyWindow(HWINSTA hwinsta,HWND hwnd)
+{
+ FIXME("(%p,%p),stub!\n",hwinsta,hwnd);
+ return 1;
+}
+
+/***********************************************************************
+ * RegisterSystemThread (USER32.@)
+ */
+void WINAPI RegisterSystemThread(DWORD flags, DWORD reserved)
+{
+ FIXME("(%08lx, %08lx)\n", flags, reserved);
+}
+
+/***********************************************************************
+ * RegisterShellHookWindow [USER32.@]
+ */
+BOOL WINAPI RegisterShellHookWindow(HWND hWnd)
+{
+ FIXME("(%p): stub\n", hWnd);
+ return FALSE;
+}
+
+
+/***********************************************************************
+ * DeregisterShellHookWindow [USER32.@]
+ */
+BOOL WINAPI DeregisterShellHookWindow(HWND hWnd)
+{
+ FIXME("(%p): stub\n", hWnd);
+ return FALSE;
+}
+
+
+/***********************************************************************
+ * RegisterTasklist [USER32.@]
+ */
+DWORD WINAPI RegisterTasklist (DWORD x)
+{
+ FIXME("0x%08lx\n",x);
+ return TRUE;
+}
+
+/***********************************************************************
+ * GetAppCompatFlags (USER32.@)
+ */
+DWORD WINAPI GetAppCompatFlags( HTASK hTask )
+{
+ FIXME("(%p) stub\n", hTask);
+ return 0;
+}
+
+/***********************************************************************
+ * GetAppCompatFlags2 (USER32.@)
+ */
+DWORD WINAPI GetAppCompatFlags2( HTASK hTask )
+{
+ FIXME("(%p) stub\n", hTask);
+ return 0;
+}
+
+
+/***********************************************************************
+ * AlignRects (USER32.@)
+ */
+BOOL WINAPI AlignRects(LPRECT rect, DWORD b, DWORD c, DWORD d)
+{
+ FIXME("(%p, %ld, %ld, %ld): stub\n", rect, b, c, d);
+ if (rect)
+ FIXME("rect: %s\n", wine_dbgstr_rect(rect));
+ /* Calls OffsetRect */
+ return FALSE;
+}
+
+
+/***********************************************************************
+ * LoadLocalFonts (USER32.@)
+ */
+VOID WINAPI LoadLocalFonts(VOID)
+{
+ /* are loaded. */
+ return;
+}
+
+
+/***********************************************************************
+ * User32InitializeImmEntryTable
+ */
+BOOL WINAPI User32InitializeImmEntryTable(DWORD magic)
+{
+ HMODULE imm32 = GetModuleHandleW(L"imm32.dll");
+
+ TRACE("(%lx)\n", magic);
+
+ if (!imm32 || magic != IMM_INIT_MAGIC)
+ return FALSE;
+
+ if (imm_ime_wnd_proc)
+ return TRUE;
+
+ /* this part is not compatible with native imm32.dll */
+ imm_ime_wnd_proc = (void*)GetProcAddress(imm32, "__wine_ime_wnd_proc");
+ if (!imm_ime_wnd_proc)
+ FIXME("native imm32.dll not supported\n");
+ return TRUE;
+}
+
+/**********************************************************************
+ * WINNLSGetIMEHotkey [USER32.@]
+ *
+ */
+UINT WINAPI WINNLSGetIMEHotkey(HWND hwnd)
+{
+ FIXME("hwnd %p: stub!\n", hwnd);
+ return 0; /* unknown */
+}
+
+/**********************************************************************
+ * WINNLSEnableIME [USER32.@]
+ *
+ */
+BOOL WINAPI WINNLSEnableIME(HWND hwnd, BOOL enable)
+{
+ FIXME("hwnd %p enable %d: stub!\n", hwnd, enable);
+ return TRUE; /* success (?) */
+}
+
+/**********************************************************************
+ * WINNLSGetEnableStatus [USER32.@]
+ *
+ */
+BOOL WINAPI WINNLSGetEnableStatus(HWND hwnd)
+{
+ FIXME("hwnd %p: stub!\n", hwnd);
+ return TRUE; /* success (?) */
+}
+
+/**********************************************************************
+ * SendIMEMessageExA [USER32.@]
+ *
+ */
+LRESULT WINAPI SendIMEMessageExA(HWND hwnd, LPARAM lparam)
+{
+ FIXME("(%p,%Ix): stub\n", hwnd, lparam);
+ SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ return 0;
+}
+
+/**********************************************************************
+ * SendIMEMessageExW [USER32.@]
+ *
+ */
+LRESULT WINAPI SendIMEMessageExW(HWND hwnd, LPARAM lparam)
+{
+ FIXME("(%p,%Ix): stub\n", hwnd, lparam);
+ SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ return 0;
+}
+
+/**********************************************************************
+ * DisableProcessWindowsGhosting [USER32.@]
+ *
+ */
+VOID WINAPI DisableProcessWindowsGhosting(VOID)
+{
+ FIXME(": stub\n");
+ SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ return;
+}
+
+/**********************************************************************
+ * UserHandleGrantAccess [USER32.@]
+ *
+ */
+BOOL WINAPI UserHandleGrantAccess(HANDLE handle, HANDLE job, BOOL grant)
+{
+ FIXME("(%p,%p,%d): stub\n", handle, job, grant);
+ return TRUE;
+}
+
+/**********************************************************************
+ * RegisterPowerSettingNotification [USER32.@]
+ */
+HPOWERNOTIFY WINAPI RegisterPowerSettingNotification(HANDLE recipient, const GUID *guid,
DWORD flags)
+{
+ FIXME("(%p,%s,%lx): stub\n", recipient, debugstr_guid(guid), flags);
+ return (HPOWERNOTIFY)0xdeadbeef;
+}
+
+/**********************************************************************
+ * UnregisterPowerSettingNotification [USER32.@]
+ */
+BOOL WINAPI UnregisterPowerSettingNotification(HPOWERNOTIFY handle)
+{
+ FIXME("(%p): stub\n", handle);
+ return TRUE;
+}
+
+/**********************************************************************
+ * RegisterSuspendResumeNotification (USER32.@)
+ */
+HPOWERNOTIFY WINAPI RegisterSuspendResumeNotification(HANDLE recipient, DWORD flags)
+{
+ FIXME("%p, %#lx: stub.\n", recipient, flags);
+ return (HPOWERNOTIFY)0xdeadbeef;
+}
+
+/**********************************************************************
+ * UnregisterSuspendResumeNotification (USER32.@)
+ */
+BOOL WINAPI UnregisterSuspendResumeNotification(HPOWERNOTIFY handle)
+{
+ FIXME("%p: stub.\n", handle);
+ return TRUE;
+}
+
+/**********************************************************************
+ * IsWindowRedirectedForPrint [USER32.@]
+ */
+BOOL WINAPI IsWindowRedirectedForPrint( HWND hwnd )
+{
+ FIXME("(%p): stub\n", hwnd);
+ return FALSE;
+}
+
+/**********************************************************************
+ * RegisterPointerDeviceNotifications [USER32.@]
+ */
+BOOL WINAPI RegisterPointerDeviceNotifications(HWND hwnd, BOOL notifyrange)
+{
+ FIXME("(%p %d): stub\n", hwnd, notifyrange);
+ return TRUE;
+}
+
+/**********************************************************************
+ * GetPointerDevices [USER32.@]
+ */
+BOOL WINAPI GetPointerDevices(UINT32 *device_count, POINTER_DEVICE_INFO *devices)
+{
+ FIXME("(%p %p): partial stub\n", device_count, devices);
+
+ if (!device_count)
+ return FALSE;
+
+ if (devices)
+ return FALSE;
+
+ *device_count = 0;
+ return TRUE;
+}
+
+/**********************************************************************
+ * RegisterTouchHitTestingWindow [USER32.@]
+ */
+BOOL WINAPI RegisterTouchHitTestingWindow(HWND hwnd, ULONG value)
+{
+ FIXME("(%p %ld): stub\n", hwnd, value);
+ return TRUE;
+}
+
+/**********************************************************************
+ * EvaluateProximityToRect [USER32.@]
+ */
+BOOL WINAPI EvaluateProximityToRect(const RECT *box,
+ const TOUCH_HIT_TESTING_INPUT *input,
+ TOUCH_HIT_TESTING_PROXIMITY_EVALUATION *proximity)
+{
+ FIXME("(%p,%p,%p): stub\n", box, input, proximity);
+ SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ return FALSE;
+}
+
+/**********************************************************************
+ * PackTouchHitTestingProximityEvaluation [USER32.@]
+ */
+LRESULT WINAPI PackTouchHitTestingProximityEvaluation(const TOUCH_HIT_TESTING_INPUT
*input,
+ const
TOUCH_HIT_TESTING_PROXIMITY_EVALUATION *proximity)
+{
+ FIXME("(%p,%p): stub\n", input, proximity);
+ SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ return 0;
+}
+
+/**********************************************************************
+ * GetPointerType [USER32.@]
+ */
+BOOL WINAPI GetPointerType(UINT32 id, POINTER_INPUT_TYPE *type)
+{
+ FIXME("(%d %p): stub\n", id, type);
+
+ if(!id || !type)
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
+
+ *type = PT_MOUSE;
+ return TRUE;
+}
+
+BOOL WINAPI GetPointerInfo(UINT32 id, POINTER_INFO *info)
+{
+ FIXME("(%d %p): stub\n", id, info);
+
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return FALSE;
+}
+
+LRESULT WINAPI ImeWndProcA( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
+{
+ if (!imm_ime_wnd_proc) return DefWindowProcA(hwnd, msg, wParam, lParam);
+ return imm_ime_wnd_proc( hwnd, msg, wParam, lParam, TRUE );
+}
+
+LRESULT WINAPI ImeWndProcW( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
+{
+ if (!imm_ime_wnd_proc) return DefWindowProcW(hwnd, msg, wParam, lParam);
+ return imm_ime_wnd_proc( hwnd, msg, wParam, lParam, FALSE );
+}
diff --git a/win32ss/user/user32_vista/wine/win.c b/win32ss/user/user32_vista/wine/win.c
new file mode 100644
index 00000000000..99f681a3f9c
--- /dev/null
+++ b/win32ss/user/user32_vista/wine/win.c
@@ -0,0 +1,1731 @@
+/*
+ * Window related functions
+ *
+ * Copyright 1993, 1994 Alexandre Julliard
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "ntstatus.h"
+#define WIN32_NO_STATUS
+#include "user_private.h"
+#include "controls.h"
+#include "winver.h"
+#include "wine/asm.h"
+#include "wine/exception.h"
+#include "wine/debug.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(win);
+
+
+#ifdef __i386__
+/* Some apps pass a non-stdcall proc to EnumChildWindows,
+ * so we need a small assembly wrapper to call the proc.
+ */
+extern LRESULT enum_callback_wrapper( WNDENUMPROC proc, HWND hwnd, LPARAM lparam );
+__ASM_GLOBAL_FUNC( enum_callback_wrapper,
+ "pushl %ebp\n\t"
+ __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t")
+ __ASM_CFI(".cfi_rel_offset %ebp,0\n\t")
+ "movl %esp,%ebp\n\t"
+ __ASM_CFI(".cfi_def_cfa_register %ebp\n\t")
+ "pushl 16(%ebp)\n\t"
+ "pushl 12(%ebp)\n\t"
+ "call *8(%ebp)\n\t"
+ "leave\n\t"
+ __ASM_CFI(".cfi_def_cfa %esp,4\n\t")
+ __ASM_CFI(".cfi_same_value %ebp\n\t")
+ "ret" )
+#else
+static inline LRESULT enum_callback_wrapper( WNDENUMPROC proc, HWND hwnd, LPARAM lparam )
+{
+ return proc( hwnd, lparam );
+}
+#endif /* __i386__ */
+
+/*******************************************************************
+ * enum_windows
+ */
+static BOOL enum_windows( HDESK desktop, HWND hwnd, DWORD tid, BOOL children,
+ WNDENUMPROC proc, LPARAM param )
+{
+ HWND *list;
+ ULONG i, size = 128;
+ BOOL ret = !children; /* EnumChildWindows returns FALSE on empty list, the others
TRUE */
+ NTSTATUS status;
+
+ for (;;)
+ {
+ if (!(list = HeapAlloc( GetProcessHeap(), 0, size * sizeof(HWND) ))) return
FALSE;
+ status = NtUserBuildHwndList( desktop, hwnd, children, TRUE, tid, size, list,
&size );
+ if (!status) break;
+ HeapFree( GetProcessHeap(), 0, list );
+ if (status != STATUS_BUFFER_TOO_SMALL) return FALSE;
+ }
+ for (i = 0; i < size && list[i] != HWND_BOTTOM; i++)
+ {
+ if (!IsWindow( list[i] )) continue;
+ if (!(ret = enum_callback_wrapper( proc, list[i], param ))) break;
+ }
+ HeapFree( GetProcessHeap(), 0, list );
+ return ret;
+}
+
+
+/*******************************************************************
+ * is_desktop_window
+ *
+ * Check if window is the desktop or the HWND_MESSAGE top parent.
+ */
+BOOL is_desktop_window( HWND hwnd )
+{
+ struct ntuser_thread_info *thread_info = NtUserGetThreadInfo();
+
+ if (!hwnd) return FALSE;
+ if (hwnd == UlongToHandle( thread_info->top_window )) return TRUE;
+ if (hwnd == UlongToHandle( thread_info->msg_window )) return TRUE;
+
+ if (!HIWORD(hwnd) || HIWORD(hwnd) == 0xffff)
+ {
+ if (LOWORD(thread_info->top_window) == LOWORD(hwnd)) return TRUE;
+ if (LOWORD(thread_info->msg_window) == LOWORD(hwnd)) return TRUE;
+ }
+ return FALSE;
+}
+
+
+/* check if hwnd is a broadcast magic handle */
+static inline BOOL is_broadcast( HWND hwnd )
+{
+ return hwnd == HWND_BROADCAST || hwnd == HWND_TOPMOST;
+}
+
+
+/***********************************************************************
+ * WIN_IsCurrentProcess
+ *
+ * Check whether a given window belongs to the current process (and return the full
handle).
+ */
+HWND WIN_IsCurrentProcess( HWND hwnd )
+{
+ return UlongToHandle( NtUserCallHwnd( hwnd, NtUserIsCurrentProcessWindow ));
+}
+
+
+/***********************************************************************
+ * WIN_IsCurrentThread
+ *
+ * Check whether a given window belongs to the current thread (and return the full
handle).
+ */
+HWND WIN_IsCurrentThread( HWND hwnd )
+{
+ return UlongToHandle( NtUserCallHwnd( hwnd, NtUserIsCurrentThreadWindow ));
+}
+
+
+/***********************************************************************
+ * WIN_GetFullHandle
+ *
+ * Convert a possibly truncated window handle to a full 32-bit handle.
+ */
+HWND WIN_GetFullHandle( HWND hwnd )
+{
+ return UlongToHandle( NtUserCallHwnd( hwnd, NtUserGetFullWindowHandle ));
+}
+
+
+/***********************************************************************
+ * WIN_SetStyle
+ *
+ * Change the style of a window.
+ */
+ULONG WIN_SetStyle( HWND hwnd, ULONG set_bits, ULONG clear_bits )
+{
+ /* FIXME: Use SetWindowLong or move callers to win32u instead.
+ * We use STYLESTRUCT to pass params, but meaning of its field does not match our
usage. */
+ STYLESTRUCT style = { .styleNew = set_bits, .styleOld = clear_bits };
+ return NtUserCallHwndParam( hwnd, (UINT_PTR)&style, NtUserSetWindowStyle );
+}
+
+
+/***********************************************************************
+ * dump_window_styles
+ */
+static void dump_window_styles( DWORD style, DWORD exstyle )
+{
+ TRACE( "style:" );
+ if(style & WS_POPUP) TRACE(" WS_POPUP");
+ if(style & WS_CHILD) TRACE(" WS_CHILD");
+ if(style & WS_MINIMIZE) TRACE(" WS_MINIMIZE");
+ if(style & WS_VISIBLE) TRACE(" WS_VISIBLE");
+ if(style & WS_DISABLED) TRACE(" WS_DISABLED");
+ if(style & WS_CLIPSIBLINGS) TRACE(" WS_CLIPSIBLINGS");
+ if(style & WS_CLIPCHILDREN) TRACE(" WS_CLIPCHILDREN");
+ if(style & WS_MAXIMIZE) TRACE(" WS_MAXIMIZE");
+ if((style & WS_CAPTION) == WS_CAPTION) TRACE(" WS_CAPTION");
+ else
+ {
+ if(style & WS_BORDER) TRACE(" WS_BORDER");
+ if(style & WS_DLGFRAME) TRACE(" WS_DLGFRAME");
+ }
+ if(style & WS_VSCROLL) TRACE(" WS_VSCROLL");
+ if(style & WS_HSCROLL) TRACE(" WS_HSCROLL");
+ if(style & WS_SYSMENU) TRACE(" WS_SYSMENU");
+ if(style & WS_THICKFRAME) TRACE(" WS_THICKFRAME");
+ if (style & WS_CHILD)
+ {
+ if(style & WS_GROUP) TRACE(" WS_GROUP");
+ if(style & WS_TABSTOP) TRACE(" WS_TABSTOP");
+ }
+ else
+ {
+ if(style & WS_MINIMIZEBOX) TRACE(" WS_MINIMIZEBOX");
+ if(style & WS_MAXIMIZEBOX) TRACE(" WS_MAXIMIZEBOX");
+ }
+
+ /* FIXME: Add dumping of BS_/ES_/SBS_/LBS_/CBS_/DS_/etc. styles */
+#define DUMPED_STYLES \
+ ((DWORD)(WS_POPUP | \
+ WS_CHILD | \
+ WS_MINIMIZE | \
+ WS_VISIBLE | \
+ WS_DISABLED | \
+ WS_CLIPSIBLINGS | \
+ WS_CLIPCHILDREN | \
+ WS_MAXIMIZE | \
+ WS_BORDER | \
+ WS_DLGFRAME | \
+ WS_VSCROLL | \
+ WS_HSCROLL | \
+ WS_SYSMENU | \
+ WS_THICKFRAME | \
+ WS_GROUP | \
+ WS_TABSTOP | \
+ WS_MINIMIZEBOX | \
+ WS_MAXIMIZEBOX))
+
+ if(style & ~DUMPED_STYLES) TRACE(" %08lx", style & ~DUMPED_STYLES);
+ TRACE("\n");
+#undef DUMPED_STYLES
+
+ TRACE( "exstyle:" );
+ if(exstyle & WS_EX_DLGMODALFRAME) TRACE(" WS_EX_DLGMODALFRAME");
+ if(exstyle & WS_EX_DRAGDETECT) TRACE(" WS_EX_DRAGDETECT");
+ if(exstyle & WS_EX_NOPARENTNOTIFY) TRACE(" WS_EX_NOPARENTNOTIFY");
+ if(exstyle & WS_EX_TOPMOST) TRACE(" WS_EX_TOPMOST");
+ if(exstyle & WS_EX_ACCEPTFILES) TRACE(" WS_EX_ACCEPTFILES");
+ if(exstyle & WS_EX_TRANSPARENT) TRACE(" WS_EX_TRANSPARENT");
+ if(exstyle & WS_EX_MDICHILD) TRACE(" WS_EX_MDICHILD");
+ if(exstyle & WS_EX_TOOLWINDOW) TRACE(" WS_EX_TOOLWINDOW");
+ if(exstyle & WS_EX_WINDOWEDGE) TRACE(" WS_EX_WINDOWEDGE");
+ if(exstyle & WS_EX_CLIENTEDGE) TRACE(" WS_EX_CLIENTEDGE");
+ if(exstyle & WS_EX_CONTEXTHELP) TRACE(" WS_EX_CONTEXTHELP");
+ if(exstyle & WS_EX_RIGHT) TRACE(" WS_EX_RIGHT");
+ if(exstyle & WS_EX_RTLREADING) TRACE(" WS_EX_RTLREADING");
+ if(exstyle & WS_EX_LEFTSCROLLBAR) TRACE(" WS_EX_LEFTSCROLLBAR");
+ if(exstyle & WS_EX_CONTROLPARENT) TRACE(" WS_EX_CONTROLPARENT");
+ if(exstyle & WS_EX_STATICEDGE) TRACE(" WS_EX_STATICEDGE");
+ if(exstyle & WS_EX_APPWINDOW) TRACE(" WS_EX_APPWINDOW");
+ if(exstyle & WS_EX_LAYERED) TRACE(" WS_EX_LAYERED");
+ if(exstyle & WS_EX_NOINHERITLAYOUT) TRACE(" WS_EX_NOINHERITLAYOUT");
+ if(exstyle & WS_EX_LAYOUTRTL) TRACE(" WS_EX_LAYOUTRTL");
+ if(exstyle & WS_EX_COMPOSITED) TRACE(" WS_EX_COMPOSITED");
+ if(exstyle & WS_EX_NOACTIVATE) TRACE(" WS_EX_NOACTIVATE");
+
+#define DUMPED_EX_STYLES \
+ ((DWORD)(WS_EX_DLGMODALFRAME | \
+ WS_EX_DRAGDETECT | \
+ WS_EX_NOPARENTNOTIFY | \
+ WS_EX_TOPMOST | \
+ WS_EX_ACCEPTFILES | \
+ WS_EX_TRANSPARENT | \
+ WS_EX_MDICHILD | \
+ WS_EX_TOOLWINDOW | \
+ WS_EX_WINDOWEDGE | \
+ WS_EX_CLIENTEDGE | \
+ WS_EX_CONTEXTHELP | \
+ WS_EX_RIGHT | \
+ WS_EX_RTLREADING | \
+ WS_EX_LEFTSCROLLBAR | \
+ WS_EX_CONTROLPARENT | \
+ WS_EX_STATICEDGE | \
+ WS_EX_APPWINDOW | \
+ WS_EX_LAYERED | \
+ WS_EX_NOINHERITLAYOUT | \
+ WS_EX_LAYOUTRTL | \
+ WS_EX_COMPOSITED |\
+ WS_EX_NOACTIVATE))
+
+ if(exstyle & ~DUMPED_EX_STYLES) TRACE(" %08lx", exstyle &
~DUMPED_EX_STYLES);
+ TRACE("\n");
+#undef DUMPED_EX_STYLES
+}
+
+static BOOL is_default_coord( int x )
+{
+ return x == CW_USEDEFAULT || x == 0x8000;
+}
+
+/***********************************************************************
+ * WIN_CreateWindowEx
+ *
+ * Implementation of CreateWindowEx().
+ */
+HWND WIN_CreateWindowEx( CREATESTRUCTW *cs, LPCWSTR className, HINSTANCE module, BOOL
unicode )
+{
+ UNICODE_STRING class, window_name = {0};
+ HWND hwnd, top_child = 0;
+ MDICREATESTRUCTW mdi_cs;
+ WNDCLASSEXW info;
+ WCHAR name_buf[8];
+ HMENU menu;
+
+ if (!get_class_info( module, className, &info, &class, FALSE )) return FALSE;
+
+ TRACE("%s %s%s%s ex=%08lx style=%08lx %d,%d %dx%d parent=%p menu=%p inst=%p
params=%p\n",
+ unicode ? debugstr_w(cs->lpszName) : debugstr_a((LPCSTR)cs->lpszName),
+ debugstr_w(className), class.Buffer != className ? "->" :
"",
+ class.Buffer != className ? debugstr_wn(class.Buffer, class.Length /
sizeof(WCHAR)) : "",
+ cs->dwExStyle, cs->style, cs->x, cs->y, cs->cx, cs->cy,
+ cs->hwndParent, cs->hMenu, cs->hInstance, cs->lpCreateParams );
+ if(TRACE_ON(win)) dump_window_styles( cs->style, cs->dwExStyle );
+
+ /* Fix the styles for MDI children */
+ if (cs->dwExStyle & WS_EX_MDICHILD)
+ {
+ POINT pos[2];
+ UINT id = 0;
+
+ if (!NtUserGetMDIClientInfo( cs->hwndParent ))
+ {
+ WARN("WS_EX_MDICHILD, but parent %p is not MDIClient\n",
cs->hwndParent);
+ return 0;
+ }
+
+ /* cs->lpCreateParams of WM_[NC]CREATE is different for MDI children.
+ * MDICREATESTRUCT members have the originally passed values.
+ *
+ * Note: we rely on the fact that MDICREATESTRUCTA and MDICREATESTRUCTW
+ * have the same layout.
+ */
+ mdi_cs.szClass = cs->lpszClass;
+ mdi_cs.szTitle = cs->lpszName;
+ mdi_cs.hOwner = cs->hInstance;
+ mdi_cs.x = cs->x;
+ mdi_cs.y = cs->y;
+ mdi_cs.cx = cs->cx;
+ mdi_cs.cy = cs->cy;
+ mdi_cs.style = cs->style;
+ mdi_cs.lParam = (LPARAM)cs->lpCreateParams;
+
+ cs->lpCreateParams = &mdi_cs;
+
+ if (GetWindowLongW(cs->hwndParent, GWL_STYLE) & MDIS_ALLCHILDSTYLES)
+ {
+ if (cs->style & WS_POPUP)
+ {
+ TRACE("WS_POPUP with MDIS_ALLCHILDSTYLES is not allowed\n");
+ return 0;
+ }
+ cs->style |= WS_CHILD | WS_CLIPSIBLINGS;
+ }
+ else
+ {
+ cs->style &= ~WS_POPUP;
+ cs->style |= WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CAPTION |
+ WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX;
+ }
+
+ top_child = GetWindow(cs->hwndParent, GW_CHILD);
+
+ if (top_child)
+ {
+ /* Restore current maximized child */
+ if((cs->style & WS_VISIBLE) && IsZoomed(top_child))
+ {
+ TRACE("Restoring current maximized child %p\n", top_child);
+ if (cs->style & WS_MAXIMIZE)
+ {
+ /* if the new window is maximized don't bother repainting */
+ SendMessageW( top_child, WM_SETREDRAW, FALSE, 0 );
+ NtUserShowWindow( top_child, SW_SHOWNORMAL );
+ SendMessageW( top_child, WM_SETREDRAW, TRUE, 0 );
+ }
+ else NtUserShowWindow( top_child, SW_SHOWNORMAL );
+ }
+ }
+
+ MDI_CalcDefaultChildPos( cs->hwndParent, -1, pos, 0, &id );
+ if (!(cs->style & WS_POPUP)) cs->hMenu = ULongToHandle(id);
+
+ TRACE( "MDI child id %04x\n", id );
+
+ if (cs->style & (WS_CHILD | WS_POPUP))
+ {
+ if (is_default_coord( cs->x ))
+ {
+ cs->x = pos[0].x;
+ cs->y = pos[0].y;
+ }
+ if (is_default_coord( cs->cx ) || !cs->cx) cs->cx = pos[1].x;
+ if (is_default_coord( cs->cy ) || !cs->cy) cs->cy = pos[1].y;
+ }
+ }
+
+ if (!unicode && cs->lpszName)
+ {
+ const char *nameA = (const char *)cs->lpszName;
+ /* resource ID string is a special case */
+ if (nameA[0] == '\xff')
+ {
+ name_buf[0] = 0xffff;
+ name_buf[1] = MAKEWORD( nameA[1], nameA[2] );
+ name_buf[2] = 0;
+ RtlInitUnicodeString( &window_name, name_buf );
+ }
+ else if (!RtlCreateUnicodeStringFromAsciiz( &window_name, (const char
*)cs->lpszName ))
+ return 0;
+ }
+ else RtlInitUnicodeString( &window_name, cs->lpszName );
+
+ menu = cs->hMenu;
+ if (!menu && info.lpszMenuName && (cs->style & (WS_CHILD |
WS_POPUP)) != WS_CHILD)
+ menu = LoadMenuW( cs->hInstance, info.lpszMenuName );
+
+ hwnd = NtUserCreateWindowEx( cs->dwExStyle, &class, NULL, &window_name,
cs->style,
+ cs->x, cs->y, cs->cx, cs->cy,
cs->hwndParent, menu, module,
+ cs->lpCreateParams, 0, cs->hInstance, 0, !unicode
);
+ if (!hwnd && menu && menu != cs->hMenu) NtUserDestroyMenu( menu );
+ if (!unicode && window_name.Buffer != name_buf) RtlFreeUnicodeString(
&window_name );
+ return hwnd;
+}
+
+
+/***********************************************************************
+ * CreateWindowExA (USER32.@)
+ */
+HWND WINAPI DECLSPEC_HOTPATCH CreateWindowExA( DWORD exStyle, LPCSTR className,
+ LPCSTR windowName, DWORD style, INT x,
+ INT y, INT width, INT height,
+ HWND parent, HMENU menu,
+ HINSTANCE instance, LPVOID data )
+{
+ CREATESTRUCTA cs;
+
+ cs.lpCreateParams = data;
+ cs.hInstance = instance;
+ cs.hMenu = menu;
+ cs.hwndParent = parent;
+ cs.x = x;
+ cs.y = y;
+ cs.cx = width;
+ cs.cy = height;
+ cs.style = style;
+ cs.lpszName = windowName;
+ cs.lpszClass = className;
+ cs.dwExStyle = exStyle;
+
+ if (!IS_INTRESOURCE(className))
+ {
+ WCHAR bufferW[256];
+ if (!MultiByteToWideChar( CP_ACP, 0, className, -1, bufferW, ARRAY_SIZE( bufferW
)))
+ return 0;
+ return wow_handlers.create_window( (CREATESTRUCTW *)&cs, bufferW, instance,
FALSE );
+ }
+ /* Note: we rely on the fact that CREATESTRUCTA and */
+ /* CREATESTRUCTW have the same layout. */
+ return wow_handlers.create_window( (CREATESTRUCTW *)&cs, (LPCWSTR)className,
instance, FALSE );
+}
+
+
+/***********************************************************************
+ * CreateWindowExW (USER32.@)
+ */
+HWND WINAPI DECLSPEC_HOTPATCH CreateWindowExW( DWORD exStyle, LPCWSTR className,
+ LPCWSTR windowName, DWORD style, INT x,
+ INT y, INT width, INT height,
+ HWND parent, HMENU menu,
+ HINSTANCE instance, LPVOID data )
+{
+ CREATESTRUCTW cs;
+
+ cs.lpCreateParams = data;
+ cs.hInstance = instance;
+ cs.hMenu = menu;
+ cs.hwndParent = parent;
+ cs.x = x;
+ cs.y = y;
+ cs.cx = width;
+ cs.cy = height;
+ cs.style = style;
+ cs.lpszName = windowName;
+ cs.lpszClass = className;
+ cs.dwExStyle = exStyle;
+
+ return wow_handlers.create_window( &cs, className, instance, TRUE );
+}
+
+
+/***********************************************************************
+ * CloseWindow (USER32.@)
+ */
+BOOL WINAPI CloseWindow( HWND hwnd )
+{
+ if (GetWindowLongW( hwnd, GWL_STYLE ) & WS_CHILD) return FALSE;
+ NtUserShowWindow( hwnd, SW_MINIMIZE );
+ return TRUE;
+}
+
+
+/***********************************************************************
+ * OpenIcon (USER32.@)
+ */
+BOOL WINAPI OpenIcon( HWND hwnd )
+{
+ if (!IsIconic( hwnd )) return FALSE;
+ NtUserShowWindow( hwnd, SW_SHOWNORMAL );
+ return TRUE;
+}
+
+
+/***********************************************************************
+ * FindWindowExW (USER32.@)
+ */
+HWND WINAPI FindWindowExW( HWND parent, HWND child, const WCHAR *class, const WCHAR
*title )
+{
+ UNICODE_STRING class_str, title_str;
+
+ if (title) RtlInitUnicodeString( &title_str, title );
+
+ if (class)
+ {
+ if (IS_INTRESOURCE(class))
+ {
+ class_str.Buffer = (WCHAR *)class;
+ class_str.Length = class_str.MaximumLength = 0;
+ }
+ else RtlInitUnicodeString( &class_str, class );
+ }
+
+ return NtUserFindWindowEx( parent, child, class ? &class_str : NULL,
+ title ? &title_str : NULL, 0 );
+}
+
+
+
+/***********************************************************************
+ * FindWindowA (USER32.@)
+ */
+HWND WINAPI FindWindowA( LPCSTR className, LPCSTR title )
+{
+ HWND ret = FindWindowExA( 0, 0, className, title );
+ if (!ret) SetLastError (ERROR_CANNOT_FIND_WND_CLASS);
+ return ret;
+}
+
+
+/***********************************************************************
+ * FindWindowExA (USER32.@)
+ */
+HWND WINAPI FindWindowExA( HWND parent, HWND child, LPCSTR className, LPCSTR title )
+{
+ LPWSTR titleW = NULL;
+ HWND hwnd = 0;
+
+ if (title)
+ {
+ DWORD len = MultiByteToWideChar( CP_ACP, 0, title, -1, NULL, 0 );
+ if (!(titleW = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) ))) return 0;
+ MultiByteToWideChar( CP_ACP, 0, title, -1, titleW, len );
+ }
+
+ if (!IS_INTRESOURCE(className))
+ {
+ WCHAR classW[256];
+ if (MultiByteToWideChar( CP_ACP, 0, className, -1, classW, ARRAY_SIZE( classW )))
+ hwnd = FindWindowExW( parent, child, classW, titleW );
+ }
+ else
+ {
+ hwnd = FindWindowExW( parent, child, (LPCWSTR)className, titleW );
+ }
+
+ HeapFree( GetProcessHeap(), 0, titleW );
+ return hwnd;
+}
+
+
+/***********************************************************************
+ * FindWindowW (USER32.@)
+ */
+HWND WINAPI FindWindowW( LPCWSTR className, LPCWSTR title )
+{
+ return FindWindowExW( 0, 0, className, title );
+}
+
+
+/**********************************************************************
+ * GetDesktopWindow (USER32.@)
+ */
+HWND WINAPI GetDesktopWindow(void)
+{
+ struct ntuser_thread_info *thread_info = NtUserGetThreadInfo();
+
+ if (thread_info->top_window) return UlongToHandle( thread_info->top_window );
+ return NtUserGetDesktopWindow();
+}
+
+
+/*******************************************************************
+ * EnableWindow (USER32.@)
+ */
+BOOL WINAPI EnableWindow( HWND hwnd, BOOL enable )
+{
+ return NtUserEnableWindow( hwnd, enable );
+}
+
+
+/***********************************************************************
+ * IsWindowEnabled (USER32.@)
+ */
+BOOL WINAPI IsWindowEnabled( HWND hwnd )
+{
+ return NtUserIsWindowEnabled( hwnd );
+}
+
+/***********************************************************************
+ * IsWindowUnicode (USER32.@)
+ */
+BOOL WINAPI IsWindowUnicode( HWND hwnd )
+{
+ return NtUserIsWindowUnicode( hwnd );
+}
+
+
+/***********************************************************************
+ * GetWindowDpiAwarenessContext (USER32.@)
+ */
+DPI_AWARENESS_CONTEXT WINAPI GetWindowDpiAwarenessContext( HWND hwnd )
+{
+ return LongToHandle( NtUserGetWindowDpiAwarenessContext( hwnd ) );
+}
+
+/***********************************************************************
+ * GetDpiAwarenessContextForProcess (USER32.@)
+ */
+DPI_AWARENESS_CONTEXT WINAPI GetDpiAwarenessContextForProcess(HANDLE process)
+{
+ return LongToHandle( NtUserGetProcessDpiAwarenessContext( process ) );
+}
+
+/***********************************************************************
+ * GetWindowDpiHostingBehavior (USER32.@)
+ */
+DPI_HOSTING_BEHAVIOR WINAPI GetWindowDpiHostingBehavior( HWND hwnd )
+{
+ FIXME("(%p): stub\n", hwnd);
+ return DPI_HOSTING_BEHAVIOR_DEFAULT;
+}
+
+
+static LONG_PTR get_window_long_ptr( HWND hwnd, int offset, LONG_PTR ret, BOOL ansi )
+{
+ if (offset == DWLP_DLGPROC && NtUserGetDialogInfo( hwnd ))
+ {
+ DLGPROC proc = NtUserGetDialogProc( (DLGPROC)ret, ansi );
+ if (proc && proc != WINPROC_PROC16) return (LONG_PTR)proc;
+ }
+ return ret;
+}
+
+
+static LONG_PTR set_dialog_proc( HWND hwnd, LONG_PTR newval, BOOL ansi )
+{
+ DLGPROC proc;
+ LONG_PTR ret;
+ newval = NtUserCallTwoParam( newval, ansi, NtUserAllocWinProc );
+ ret = NtUserSetWindowLongPtr( hwnd, DWLP_DLGPROC, newval, ansi );
+ proc = NtUserGetDialogProc( (DLGPROC)ret, ansi );
+ if (proc) ret = (UINT_PTR)proc;
+ return ret;
+}
+
+
+/***********************************************************************
+ * GetDpiForWindow (USER32.@)
+ */
+UINT WINAPI GetDpiForWindow( HWND hwnd )
+{
+ return NtUserGetDpiForWindow( hwnd );
+}
+
+
+/***********************************************************************
+ * SwitchToThisWindow (USER32.@)
+ */
+void WINAPI SwitchToThisWindow( HWND hwnd, BOOL alt_tab )
+{
+ if (IsIconic( hwnd )) NtUserShowWindow( hwnd, SW_RESTORE );
+ else BringWindowToTop( hwnd );
+}
+
+
+/***********************************************************************
+ * GetWindowRect (USER32.@)
+ */
+BOOL WINAPI GetWindowRect( HWND hwnd, RECT *rect )
+{
+ UINT dpi = NTUSER_DPI_CONTEXT_GET_DPI( (UINT_PTR)GetThreadDpiAwarenessContext() );
+ BOOL ret = NtUserGetWindowRect( hwnd, rect, dpi );
+ if (ret) TRACE( "hwnd %p %s\n", hwnd, wine_dbgstr_rect(rect) );
+ return ret;
+}
+
+
+/***********************************************************************
+ * GetWindowRgn (USER32.@)
+ */
+int WINAPI GetWindowRgn( HWND hwnd, HRGN hrgn )
+{
+ return NtUserGetWindowRgnEx( hwnd, hrgn, 0 );
+}
+
+
+/***********************************************************************
+ * GetWindowRgnBox (USER32.@)
+ */
+int WINAPI GetWindowRgnBox( HWND hwnd, RECT *rect )
+{
+ int ret = ERROR;
+ HRGN hrgn;
+
+ if (!rect)
+ return ERROR;
+
+ if ((hrgn = CreateRectRgn( 0, 0, 0, 0 )))
+ {
+ if ((ret = GetWindowRgn( hwnd, hrgn )) != ERROR )
+ ret = GetRgnBox( hrgn, rect );
+ DeleteObject( hrgn );
+ }
+
+ return ret;
+}
+
+
+/***********************************************************************
+ * GetClientRect (USER32.@)
+ */
+BOOL WINAPI GetClientRect( HWND hwnd, RECT *rect )
+{
+ UINT dpi = NTUSER_DPI_CONTEXT_GET_DPI( (UINT_PTR)GetThreadDpiAwarenessContext() );
+ return NtUserGetClientRect( hwnd, rect, dpi );
+}
+
+
+/*******************************************************************
+ * WindowFromPoint (USER32.@)
+ */
+HWND WINAPI WindowFromPoint( POINT pt )
+{
+ return NtUserWindowFromPoint( pt.x, pt.y );
+}
+
+
+/*******************************************************************
+ * ChildWindowFromPoint (USER32.@)
+ */
+HWND WINAPI ChildWindowFromPoint( HWND parent, POINT pt )
+{
+ return NtUserChildWindowFromPointEx( parent, pt.x, pt.y, CWP_ALL );
+}
+
+/*******************************************************************
+ * RealChildWindowFromPoint (USER32.@)
+ */
+HWND WINAPI RealChildWindowFromPoint( HWND parent, POINT pt )
+{
+ return NtUserRealChildWindowFromPoint( parent, pt.x, pt.y );
+}
+
+/*******************************************************************
+ * ChildWindowFromPointEx (USER32.@)
+ */
+HWND WINAPI ChildWindowFromPointEx( HWND parent, POINT pt, UINT flags )
+{
+ return NtUserChildWindowFromPointEx( parent, pt.x, pt.y, flags );
+}
+
+
+/*******************************************************************
+ * MapWindowPoints (USER32.@)
+ */
+INT WINAPI MapWindowPoints( HWND hwnd_from, HWND hwnd_to, POINT *points, UINT count )
+{
+ UINT dpi = NTUSER_DPI_CONTEXT_GET_DPI( (UINT_PTR)GetThreadDpiAwarenessContext() );
+ return NtUserMapWindowPoints( hwnd_from, hwnd_to, points, count, dpi );
+}
+
+
+/*******************************************************************
+ * ClientToScreen (USER32.@)
+ */
+BOOL WINAPI ClientToScreen( HWND hwnd, POINT *pt )
+{
+ return NtUserClientToScreen( hwnd, pt );
+}
+
+
+/*******************************************************************
+ * ScreenToClient (USER32.@)
+ */
+BOOL WINAPI ScreenToClient( HWND hwnd, POINT *pt )
+{
+ return NtUserScreenToClient( hwnd, pt );
+}
+
+
+/***********************************************************************
+ * IsIconic (USER32.@)
+ */
+BOOL WINAPI IsIconic( HWND hwnd )
+{
+ return (GetWindowLongW( hwnd, GWL_STYLE ) & WS_MINIMIZE) != 0;
+}
+
+
+/***********************************************************************
+ * IsZoomed (USER32.@)
+ */
+BOOL WINAPI IsZoomed( HWND hwnd )
+{
+ return (GetWindowLongW( hwnd, GWL_STYLE ) & WS_MAXIMIZE) != 0;
+}
+
+
+/*******************************************************************
+ * AllowSetForegroundWindow (USER32.@)
+ */
+BOOL WINAPI AllowSetForegroundWindow( DWORD procid )
+{
+ /* FIXME: If Win98/2000 style SetForegroundWindow behavior is
+ * implemented, then fix this function. */
+ return TRUE;
+}
+
+
+/*******************************************************************
+ * LockSetForegroundWindow (USER32.@)
+ */
+BOOL WINAPI LockSetForegroundWindow( UINT lockcode )
+{
+ /* FIXME: If Win98/2000 style SetForegroundWindow behavior is
+ * implemented, then fix this function. */
+ return TRUE;
+}
+
+
+/***********************************************************************
+ * BringWindowToTop (USER32.@)
+ */
+BOOL WINAPI BringWindowToTop( HWND hwnd )
+{
+ return NtUserSetWindowPos( hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE );
+}
+
+
+/***********************************************************************
+ * AnimateWindow (USER32.@)
+ */
+BOOL WINAPI AnimateWindow( HWND hwnd, DWORD time, DWORD flags )
+{
+ FIXME( "partial stub\n" );
+
+ /* If trying to show/hide and it's already shown/hidden or invalid window,
+ * fail with invalid parameter. */
+ if (!IsWindow( hwnd ) || (!(flags & AW_HIDE)) == IsWindowVisible( hwnd ))
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
+
+ NtUserShowWindow( hwnd, (flags & AW_HIDE) ? SW_HIDE : ((flags & AW_ACTIVATE)
? SW_SHOW : SW_SHOWNA) );
+ return TRUE;
+}
+
+
+/***********************************************************************
+ * BeginDeferWindowPos (USER32.@)
+ */
+HDWP WINAPI BeginDeferWindowPos( INT count )
+{
+ return NtUserBeginDeferWindowPos( count );
+}
+
+
+/***********************************************************************
+ * DeferWindowPos (USER32.@)
+ */
+HDWP WINAPI DeferWindowPos( HDWP hdwp, HWND hwnd, HWND after, INT x, INT y,
+ INT cx, INT cy, UINT flags )
+{
+ return NtUserDeferWindowPosAndBand( hdwp, hwnd, after, x, y, cx, cy, flags, 0, 0 );
+}
+
+
+/***********************************************************************
+ * EndDeferWindowPos (USER32.@)
+ */
+BOOL WINAPI EndDeferWindowPos( HDWP hdwp )
+{
+ return NtUserEndDeferWindowPosEx( hdwp, FALSE );
+}
+
+
+/***********************************************************************
+ * ArrangeIconicWindows (USER32.@)
+ */
+UINT WINAPI ArrangeIconicWindows( HWND parent )
+{
+ return NtUserArrangeIconicWindows( parent );
+}
+
+
+/**********************************************************************
+ * GetWindowWord (USER32.@)
+ */
+WORD WINAPI GetWindowWord( HWND hwnd, INT offset )
+{
+ return NtUserGetWindowWord( hwnd, offset );
+}
+
+
+/**********************************************************************
+ * GetWindowLongA (USER32.@)
+ */
+
+#ifdef __i386__
+
+/* This wrapper is here to workaround a ntlea quirk. First of all, ntlea
+ * checks whether GetWindowLongA starts with the Win32 hotpatchable prologue,
+ * if it can find that, it will use a hooking strategy more difficult for us
+ * to deal with. Secondly, it assumes what follows the prologue is a `pushl $-2`,
+ * and will try to skip over this instruction when calling `GetWindowLongA`,
+ * (i.e. it tries to jump to `GetWindowLongA + 7`, 5 bytes for the prologue, 2
+ * bytes for the `pushl`.). We have to anticipate that and make sure the result
+ * of doing this won't be a messed up stack, or a desynced PC.
+ */
+__ASM_STDCALL_FUNC( GetWindowLongA, 8,
+ ".byte 0x8b, 0xff, 0x55, 0x8b, 0xec\n" /* Win32 hotpatchable prologue.
*/
+ "pushl $-2\n"
+ "addl $4, %esp\n"
+ "popl %ebp\n"
+ "jmp " __ASM_STDCALL("get_window_longA", 8) )
+LONG WINAPI get_window_longA( HWND hwnd, INT offset )
+#else
+LONG WINAPI DECLSPEC_HOTPATCH GetWindowLongA( HWND hwnd, INT offset )
+#endif
+{
+ switch (offset)
+ {
+#ifdef _WIN64
+ case GWLP_WNDPROC:
+ case GWLP_HINSTANCE:
+ case GWLP_HWNDPARENT:
+ WARN( "Invalid offset %d\n", offset );
+ SetLastError( ERROR_INVALID_INDEX );
+ return 0;
+#endif
+ default:
+ if (sizeof(void *) == sizeof(LONG))
+ {
+ LONG_PTR ret = NtUserGetWindowLongA( hwnd, offset );
+ return get_window_long_ptr( hwnd, offset, ret, TRUE );
+ }
+ return NtUserGetWindowLongA( hwnd, offset );
+ }
+}
+
+
+/**********************************************************************
+ * GetWindowLongW (USER32.@)
+ */
+LONG WINAPI GetWindowLongW( HWND hwnd, INT offset )
+{
+ switch (offset)
+ {
+#ifdef _WIN64
+ case GWLP_WNDPROC:
+ case GWLP_HINSTANCE:
+ case GWLP_HWNDPARENT:
+ WARN( "Invalid offset %d\n", offset );
+ SetLastError( ERROR_INVALID_INDEX );
+ return 0;
+#endif
+ default:
+ if (sizeof(void *) == sizeof(LONG))
+ {
+ LONG_PTR ret = NtUserGetWindowLongW( hwnd, offset );
+ return get_window_long_ptr( hwnd, offset, ret, FALSE );
+ }
+ return NtUserGetWindowLongW( hwnd, offset );
+ }
+}
+
+
+/**********************************************************************
+ * SetWindowLongA (USER32.@)
+ *
+ * See SetWindowLongW.
+ */
+LONG WINAPI DECLSPEC_HOTPATCH SetWindowLongA( HWND hwnd, INT offset, LONG newval )
+{
+ switch (offset)
+ {
+#ifdef _WIN64
+ case GWLP_WNDPROC:
+ case GWLP_HINSTANCE:
+ case GWLP_HWNDPARENT:
+ WARN( "Invalid offset %d\n", offset );
+ SetLastError( ERROR_INVALID_INDEX );
+ return 0;
+#else
+ case DWLP_DLGPROC:
+ if (NtUserGetDialogInfo( hwnd )) return set_dialog_proc( hwnd, newval, TRUE );
+ /* fall through */
+#endif
+ default:
+ return NtUserSetWindowLong( hwnd, offset, newval, TRUE );
+ }
+}
+
+
+/**********************************************************************
+ * SetWindowLongW (USER32.@) Set window attribute
+ *
+ * SetWindowLong() alters one of a window's attributes or sets a 32-bit (long)
+ * value in a window's extra memory.
+ *
+ * The _hwnd_ parameter specifies the handle to a window that
+ * has extra memory. The _newval_ parameter contains the new
+ * attribute or extra memory value. If positive, the _offset_
+ * parameter is the byte-addressed location in the window's extra
+ * memory to set. If negative, _offset_ specifies the window
+ * attribute to set, and should be one of the following values:
+ *
+ * GWL_EXSTYLE The window's extended window style
+ *
+ * GWL_STYLE The window's window style.
+ *
+ * GWLP_WNDPROC Pointer to the window's window procedure.
+ *
+ * GWLP_HINSTANCE The window's application instance handle.
+ *
+ * GWLP_ID The window's identifier.
+ *
+ * GWLP_USERDATA The window's user-specified data.
+ *
+ * If the window is a dialog box, the _offset_ parameter can be one of
+ * the following values:
+ *
+ * DWLP_DLGPROC The address of the window's dialog box procedure.
+ *
+ * DWLP_MSGRESULT The return value of a message
+ * that the dialog box procedure processed.
+ *
+ * DWLP_USER Application specific information.
+ *
+ * RETURNS
+ *
+ * If successful, returns the previous value located at _offset_. Otherwise,
+ * returns 0.
+ *
+ * NOTES
+ *
+ * Extra memory for a window class is specified by a nonzero cbWndExtra
+ * parameter of the WNDCLASS structure passed to RegisterClass() at the
+ * time of class creation.
+ *
+ * Using GWL_WNDPROC to set a new window procedure effectively creates
+ * a window subclass. Use CallWindowProc() in the new windows procedure
+ * to pass messages to the superclass's window procedure.
+ *
+ * The user data is reserved for use by the application which created
+ * the window.
+ *
+ * Do not use GWL_STYLE to change the window's WS_DISABLED style;
+ * instead, call the EnableWindow() function to change the window's
+ * disabled state.
+ *
+ * Do not use GWL_HWNDPARENT to reset the window's parent, use
+ * SetParent() instead.
+ *
+ * Win95:
+ * When offset is GWL_STYLE and the calling app's ver is 4.0,
+ * it sends WM_STYLECHANGING before changing the settings
+ * and WM_STYLECHANGED afterwards.
+ * App ver 4.0 can't use SetWindowLong to change WS_EX_TOPMOST.
+ */
+LONG WINAPI DECLSPEC_HOTPATCH SetWindowLongW(
+ HWND hwnd, /* [in] window to alter */
+ INT offset, /* [in] offset, in bytes, of location to alter */
+ LONG newval /* [in] new value of location */
+)
+{
+ switch (offset)
+ {
+#ifdef _WIN64
+ case GWLP_WNDPROC:
+ case GWLP_HINSTANCE:
+ case GWLP_HWNDPARENT:
+ WARN("Invalid offset %d\n", offset );
+ SetLastError( ERROR_INVALID_INDEX );
+ return 0;
+#else
+ case DWLP_DLGPROC:
+ if (NtUserGetDialogInfo( hwnd )) return set_dialog_proc( hwnd, newval, FALSE );
+ /* fall through */
+#endif
+ default:
+ return NtUserSetWindowLong( hwnd, offset, newval, FALSE );
+ }
+}
+
+
+/*******************************************************************
+ * GetWindowTextA (USER32.@)
+ */
+INT WINAPI GetWindowTextA( HWND hwnd, LPSTR lpString, INT nMaxCount )
+{
+ WCHAR *buffer;
+ int ret = 0;
+
+ if (!lpString || nMaxCount <= 0) return 0;
+
+ __TRY
+ {
+ lpString[0] = 0;
+
+ if (WIN_IsCurrentProcess( hwnd ))
+ {
+ ret = (INT)SendMessageA( hwnd, WM_GETTEXT, nMaxCount, (LPARAM)lpString );
+ }
+ else if ((buffer = HeapAlloc( GetProcessHeap(), 0, nMaxCount * sizeof(WCHAR) )))
+ {
+ /* when window belongs to other process, don't send a message */
+ NtUserInternalGetWindowText( hwnd, buffer, nMaxCount );
+ if (!WideCharToMultiByte( CP_ACP, 0, buffer, -1, lpString, nMaxCount, NULL,
NULL ))
+ lpString[nMaxCount-1] = 0;
+ HeapFree( GetProcessHeap(), 0, buffer );
+ ret = strlen(lpString);
+ }
+ }
+ __EXCEPT_PAGE_FAULT
+ {
+ ret = 0;
+ }
+ __ENDTRY
+
+ return ret;
+}
+
+
+/*******************************************************************
+ * GetWindowTextW (USER32.@)
+ */
+INT WINAPI GetWindowTextW( HWND hwnd, LPWSTR lpString, INT nMaxCount )
+{
+ int ret;
+
+ if (!lpString || nMaxCount <= 0) return 0;
+
+ __TRY
+ {
+ lpString[0] = 0;
+
+ if (WIN_IsCurrentProcess( hwnd ))
+ {
+ ret = (INT)SendMessageW( hwnd, WM_GETTEXT, nMaxCount, (LPARAM)lpString );
+ }
+ else
+ {
+ /* when window belongs to other process, don't send a message */
+ ret = NtUserInternalGetWindowText( hwnd, lpString, nMaxCount );
+ }
+ }
+ __EXCEPT_PAGE_FAULT
+ {
+ ret = 0;
+ }
+ __ENDTRY
+
+ return ret;
+}
+
+
+/*******************************************************************
+ * SetWindowTextA (USER32.@)
+ * SetWindowText (USER32.@)
+ */
+BOOL WINAPI DECLSPEC_HOTPATCH SetWindowTextA( HWND hwnd, LPCSTR lpString )
+{
+ if (is_broadcast(hwnd))
+ {
+ SetLastError( ERROR_INVALID_PARAMETER );
+ return FALSE;
+ }
+ if (!WIN_IsCurrentProcess( hwnd ))
+ WARN( "setting text %s of other process window %p should not use
SendMessage\n",
+ debugstr_a(lpString), hwnd );
+ return (BOOL)SendMessageA( hwnd, WM_SETTEXT, 0, (LPARAM)lpString );
+}
+
+
+/*******************************************************************
+ * SetWindowTextW (USER32.@)
+ */
+BOOL WINAPI DECLSPEC_HOTPATCH SetWindowTextW( HWND hwnd, LPCWSTR lpString )
+{
+ if (is_broadcast(hwnd))
+ {
+ SetLastError( ERROR_INVALID_PARAMETER );
+ return FALSE;
+ }
+ if (!WIN_IsCurrentProcess( hwnd ))
+ WARN( "setting text %s of other process window %p should not use
SendMessage\n",
+ debugstr_w(lpString), hwnd );
+ return (BOOL)SendMessageW( hwnd, WM_SETTEXT, 0, (LPARAM)lpString );
+}
+
+
+/*******************************************************************
+ * GetWindowTextLengthA (USER32.@)
+ */
+INT WINAPI GetWindowTextLengthA( HWND hwnd )
+{
+ CPINFO info;
+
+ if (WIN_IsCurrentProcess( hwnd )) return SendMessageA( hwnd, WM_GETTEXTLENGTH, 0, 0
);
+
+ /* when window belongs to other process, don't send a message */
+ GetCPInfo( CP_ACP, &info );
+ return NtUserGetWindowTextLength( hwnd ) * info.MaxCharSize;
+}
+
+/*******************************************************************
+ * GetWindowTextLengthW (USER32.@)
+ */
+INT WINAPI GetWindowTextLengthW( HWND hwnd )
+{
+ if (WIN_IsCurrentProcess( hwnd )) return SendMessageW( hwnd, WM_GETTEXTLENGTH, 0, 0
);
+
+ /* when window belongs to other process, don't send a message */
+ return NtUserGetWindowTextLength( hwnd );
+}
+
+
+/*******************************************************************
+ * IsWindow (USER32.@)
+ */
+BOOL WINAPI IsWindow( HWND hwnd )
+{
+ return NtUserIsWindow( hwnd );
+}
+
+
+/***********************************************************************
+ * GetWindowThreadProcessId (USER32.@)
+ */
+DWORD WINAPI GetWindowThreadProcessId( HWND hwnd, LPDWORD process )
+{
+ return NtUserGetWindowThread( hwnd, process );
+}
+
+
+/*****************************************************************
+ * GetParent (USER32.@)
+ */
+HWND WINAPI GetParent( HWND hwnd )
+{
+ return NtUserGetParent( hwnd );
+}
+
+
+/*******************************************************************
+ * IsChild (USER32.@)
+ */
+BOOL WINAPI IsChild( HWND parent, HWND child )
+{
+ return NtUserIsChild( parent, child );
+}
+
+
+/***********************************************************************
+ * IsWindowVisible (USER32.@)
+ */
+BOOL WINAPI IsWindowVisible( HWND hwnd )
+{
+ return NtUserIsWindowVisible( hwnd );
+}
+
+
+/*******************************************************************
+ * GetTopWindow (USER32.@)
+ */
+HWND WINAPI GetTopWindow( HWND hwnd )
+{
+ if (!hwnd) hwnd = GetDesktopWindow();
+ return GetWindow( hwnd, GW_CHILD );
+}
+
+
+/*******************************************************************
+ * GetWindow (USER32.@)
+ */
+HWND WINAPI GetWindow( HWND hwnd, UINT rel )
+{
+ return NtUserGetWindowRelative( hwnd, rel );
+}
+
+
+/*******************************************************************
+ * ShowOwnedPopups (USER32.@)
+ */
+BOOL WINAPI ShowOwnedPopups( HWND owner, BOOL show )
+{
+ return NtUserShowOwnedPopups( owner, show );
+}
+
+
+/*******************************************************************
+ * GetLastActivePopup (USER32.@)
+ */
+HWND WINAPI GetLastActivePopup( HWND hwnd )
+{
+ return NtUserGetLastActivePopup( hwnd );
+}
+
+
+/*******************************************************************
+ * WIN_ListChildren
+ *
+ * Build an array of the children of a given window. The array must be
+ * freed with HeapFree. Returns NULL when no windows are found.
+ */
+HWND *WIN_ListChildren( HWND hwnd )
+{
+ HWND *list;
+ ULONG size = 128;
+ NTSTATUS status;
+
+ if (!(hwnd = GetWindow( hwnd, GW_CHILD ))) return NULL;
+
+ for (;;)
+ {
+ if (!(list = HeapAlloc( GetProcessHeap(), 0, size * sizeof(HWND) ))) return NULL;
+ status = NtUserBuildHwndList( 0, hwnd, FALSE, TRUE, 0, size, list, &size );
+ if (!status && size > 1) break;
+ HeapFree( GetProcessHeap(), 0, list );
+ if (status != STATUS_BUFFER_TOO_SMALL) return NULL;
+ }
+ list[size - 1] = 0;
+ return list;
+}
+
+
+/*******************************************************************
+ * EnumWindows (USER32.@)
+ */
+BOOL WINAPI EnumWindows( WNDENUMPROC lpEnumFunc, LPARAM lParam )
+{
+ return enum_windows( 0, 0, 0, FALSE, lpEnumFunc, lParam );
+}
+
+
+/**********************************************************************
+ * EnumThreadWindows (USER32.@)
+ */
+BOOL WINAPI EnumThreadWindows( DWORD id, WNDENUMPROC func, LPARAM lParam )
+{
+ return enum_windows( 0, 0, id, FALSE, func, lParam );
+}
+
+
+/***********************************************************************
+ * EnumDesktopWindows (USER32.@)
+ */
+BOOL WINAPI EnumDesktopWindows( HDESK desktop, WNDENUMPROC func, LPARAM lparam )
+{
+ return enum_windows( desktop, 0, 0, FALSE, func, lparam );
+}
+
+
+/**********************************************************************
+ * EnumChildWindows (USER32.@)
+ */
+BOOL WINAPI EnumChildWindows( HWND parent, WNDENUMPROC func, LPARAM lParam )
+{
+ return enum_windows( 0, parent, 0, TRUE, func, lParam );
+}
+
+
+/*******************************************************************
+ * AnyPopup (USER32.@)
+ */
+BOOL WINAPI AnyPopup(void)
+{
+ int i;
+ BOOL retvalue;
+ HWND *list = WIN_ListChildren( GetDesktopWindow() );
+
+ if (!list) return FALSE;
+ for (i = 0; list[i]; i++)
+ {
+ if (IsWindowVisible( list[i] ) && GetWindow( list[i], GW_OWNER )) break;
+ }
+ retvalue = (list[i] != 0);
+ HeapFree( GetProcessHeap(), 0, list );
+ return retvalue;
+}
+
+
+/*******************************************************************
+ * FlashWindow (USER32.@)
+ */
+BOOL WINAPI FlashWindow( HWND hWnd, BOOL bInvert )
+{
+ FLASHWINFO finfo;
+
+ finfo.cbSize = sizeof(FLASHWINFO);
+ finfo.dwFlags = bInvert ? FLASHW_ALL : FLASHW_STOP;
+ finfo.uCount = 1;
+ finfo.dwTimeout = 0;
+ finfo.hwnd = hWnd;
+ return NtUserFlashWindowEx( &finfo );
+}
+
+
+/*******************************************************************
+ * GetWindowContextHelpId (USER32.@)
+ */
+DWORD WINAPI GetWindowContextHelpId( HWND hwnd )
+{
+ return NtUserGetWindowContextHelpId( hwnd );
+}
+
+
+/*******************************************************************
+ * SetWindowContextHelpId (USER32.@)
+ */
+BOOL WINAPI SetWindowContextHelpId( HWND hwnd, DWORD id )
+{
+ return NtUserSetWindowContextHelpId( hwnd, id );
+}
+
+
+/*******************************************************************
+ * DragDetect (USER32.@)
+ */
+BOOL WINAPI DragDetect( HWND hwnd, POINT pt )
+{
+ return NtUserDragDetect( hwnd, pt.x, pt.y );
+}
+
+/******************************************************************************
+ * GetWindowModuleFileNameA (USER32.@)
+ */
+UINT WINAPI GetWindowModuleFileNameA( HWND hwnd, LPSTR module, UINT size )
+{
+ HINSTANCE hinst;
+
+ TRACE( "%p, %p, %u\n", hwnd, module, size );
+
+ if (!WIN_IsCurrentProcess( hwnd ))
+ {
+ SetLastError( ERROR_INVALID_WINDOW_HANDLE );
+ return 0;
+ }
+
+ hinst = (HINSTANCE)GetWindowLongPtrA( hwnd, GWLP_HINSTANCE );
+ return GetModuleFileNameA( hinst, module, size );
+}
+
+/******************************************************************************
+ * GetWindowModuleFileNameW (USER32.@)
+ */
+UINT WINAPI GetWindowModuleFileNameW( HWND hwnd, LPWSTR module, UINT size )
+{
+ HINSTANCE hinst;
+
+ TRACE( "%p, %p, %u\n", hwnd, module, size );
+
+ if (!WIN_IsCurrentProcess( hwnd ))
+ {
+ SetLastError( ERROR_INVALID_WINDOW_HANDLE );
+ return 0;
+ }
+
+ hinst = (HINSTANCE)GetWindowLongPtrW( hwnd, GWLP_HINSTANCE );
+ return GetModuleFileNameW( hinst, module, size );
+}
+
+/******************************************************************************
+ * GetWindowInfo (USER32.@)
+ *
+ * Note: tests show that Windows doesn't check cbSize of the structure.
+ */
+BOOL WINAPI DECLSPEC_HOTPATCH GetWindowInfo( HWND hwnd, WINDOWINFO *info )
+{
+ return NtUserGetWindowInfo( hwnd, info );
+}
+
+/*****************************************************************************
+ * UpdateLayeredWindowIndirect (USER32.@)
+ */
+BOOL WINAPI UpdateLayeredWindowIndirect( HWND hwnd, const UPDATELAYEREDWINDOWINFO *info )
+{
+ if (!info || info->cbSize != sizeof(*info))
+ {
+ SetLastError( ERROR_INVALID_PARAMETER );
+ return FALSE;
+ }
+
+ return NtUserUpdateLayeredWindow( hwnd, info->hdcDst, info->pptDst,
info->psize,
+ info->hdcSrc, info->pptSrc, info->crKey,
+ info->pblend, info->dwFlags,
info->prcDirty );
+}
+
+
+/*****************************************************************************
+ * UpdateLayeredWindow (USER32.@)
+ */
+BOOL WINAPI UpdateLayeredWindow( HWND hwnd, HDC hdcDst, POINT *pptDst, SIZE *psize,
+ HDC hdcSrc, POINT *pptSrc, COLORREF crKey, BLENDFUNCTION
*pblend,
+ DWORD flags)
+{
+ UPDATELAYEREDWINDOWINFO info;
+
+ if (flags & ULW_EX_NORESIZE) /* only valid for UpdateLayeredWindowIndirect */
+ {
+ SetLastError( ERROR_INVALID_PARAMETER );
+ return FALSE;
+ }
+ info.cbSize = sizeof(info);
+ info.hdcDst = hdcDst;
+ info.pptDst = pptDst;
+ info.psize = psize;
+ info.hdcSrc = hdcSrc;
+ info.pptSrc = pptSrc;
+ info.crKey = crKey;
+ info.pblend = pblend;
+ info.dwFlags = flags;
+ info.prcDirty = NULL;
+ return UpdateLayeredWindowIndirect( hwnd, &info );
+}
+
+
+/******************************************************************************
+ * GetProcessDefaultLayout [USER32.@]
+ *
+ * Gets the default layout for parentless windows.
+ */
+BOOL WINAPI GetProcessDefaultLayout( DWORD *layout )
+{
+ if (!layout)
+ {
+ SetLastError( ERROR_NOACCESS );
+ return FALSE;
+ }
+ *layout = NtUserGetProcessDefaultLayout();
+ if (*layout == ~0u)
+ {
+ WCHAR *str, buffer[MAX_PATH];
+ DWORD i, version_layout = 0;
+ UINT len;
+ DWORD user_lang = GetUserDefaultLangID();
+ DWORD *languages;
+ void *data = NULL;
+
+ GetModuleFileNameW( 0, buffer, MAX_PATH );
+ if (!(len = GetFileVersionInfoSizeW( buffer, NULL ))) goto done;
+ if (!(data = HeapAlloc( GetProcessHeap(), 0, len ))) goto done;
+ if (!GetFileVersionInfoW( buffer, 0, len, data )) goto done;
+ if (!VerQueryValueW( data, L"\\VarFileInfo\\Translation", (void
**)&languages, &len ) || !len) goto done;
+
+ len /= sizeof(DWORD);
+ for (i = 0; i < len; i++) if (LOWORD(languages[i]) == user_lang) break;
+ if (i == len) /* try neutral language */
+ for (i = 0; i < len; i++)
+ if (LOWORD(languages[i]) == MAKELANGID( PRIMARYLANGID(user_lang),
SUBLANG_NEUTRAL )) break;
+ if (i == len) i = 0; /* default to the first one */
+
+ swprintf( buffer, ARRAY_SIZE(buffer),
L"\\StringFileInfo\\%04x%04x\\FileDescription",
+ LOWORD(languages[i]), HIWORD(languages[i]) );
+ if (!VerQueryValueW( data, buffer, (void **)&str, &len )) goto done;
+ TRACE( "found description %s\n", debugstr_w( str ));
+ if (str[0] == 0x200e && str[1] == 0x200e) version_layout = LAYOUT_RTL;
+
+ done:
+ HeapFree( GetProcessHeap(), 0, data );
+ NtUserSetProcessDefaultLayout( *layout = version_layout );
+ }
+ return TRUE;
+}
+
+
+/******************************************************************************
+ * SetProcessDefaultLayout [USER32.@]
+ *
+ * Sets the default layout for parentless windows.
+ */
+BOOL WINAPI SetProcessDefaultLayout( DWORD layout )
+{
+ return NtUserSetProcessDefaultLayout( layout );
+}
+
+
+/***********************************************************************
+ * UpdateWindow (USER32.@)
+ */
+BOOL WINAPI UpdateWindow( HWND hwnd )
+{
+ if (!hwnd)
+ {
+ SetLastError( ERROR_INVALID_WINDOW_HANDLE );
+ return FALSE;
+ }
+
+ return NtUserRedrawWindow( hwnd, NULL, 0, RDW_UPDATENOW | RDW_ALLCHILDREN );
+}
+
+
+/***********************************************************************
+ * ValidateRgn (USER32.@)
+ */
+BOOL WINAPI ValidateRgn( HWND hwnd, HRGN hrgn )
+{
+ if (!hwnd)
+ {
+ SetLastError( ERROR_INVALID_WINDOW_HANDLE );
+ return FALSE;
+ }
+
+ return NtUserRedrawWindow( hwnd, NULL, hrgn, RDW_VALIDATE );
+}
+
+
+/*************************************************************************
+ * ScrollWindow (USER32.@)
+ */
+BOOL WINAPI ScrollWindow( HWND hwnd, INT dx, INT dy, const RECT *rect, const RECT
*clip_rect )
+{
+ UINT flags = SW_INVALIDATE | SW_ERASE | (rect ? 0 : SW_SCROLLCHILDREN) |
SW_NODCCACHE;
+ return NtUserScrollWindowEx( hwnd, dx, dy, rect, clip_rect, 0, NULL, flags );
+}
+
+#ifdef _WIN64
+
+/* 64bit versions */
+
+#undef GetWindowLongPtrW
+#undef GetWindowLongPtrA
+#undef SetWindowLongPtrW
+#undef SetWindowLongPtrA
+
+/*****************************************************************************
+ * GetWindowLongPtrW (USER32.@)
+ */
+LONG_PTR WINAPI GetWindowLongPtrW( HWND hwnd, INT offset )
+{
+ LONG_PTR ret = NtUserGetWindowLongPtrW( hwnd, offset );
+ return get_window_long_ptr( hwnd, offset, ret, FALSE );
+}
+
+/*****************************************************************************
+ * GetWindowLongPtrA (USER32.@)
+ */
+LONG_PTR WINAPI GetWindowLongPtrA( HWND hwnd, INT offset )
+{
+ LONG_PTR ret = NtUserGetWindowLongPtrA( hwnd, offset );
+ return get_window_long_ptr( hwnd, offset, ret, TRUE );
+}
+
+/*****************************************************************************
+ * SetWindowLongPtrW (USER32.@)
+ */
+LONG_PTR WINAPI SetWindowLongPtrW( HWND hwnd, INT offset, LONG_PTR newval )
+{
+ if (offset == DWLP_DLGPROC && NtUserGetDialogInfo( hwnd ))
+ return set_dialog_proc( hwnd, newval, FALSE );
+
+ return NtUserSetWindowLongPtr( hwnd, offset, newval, FALSE );
+}
+
+/*****************************************************************************
+ * SetWindowLongPtrA (USER32.@)
+ */
+LONG_PTR WINAPI SetWindowLongPtrA( HWND hwnd, INT offset, LONG_PTR newval )
+{
+ if (offset == DWLP_DLGPROC && NtUserGetDialogInfo( hwnd ))
+ return set_dialog_proc( hwnd, newval, TRUE );
+
+ return NtUserSetWindowLongPtr( hwnd, offset, newval, TRUE );
+}
+
+#endif /* _WIN64 */
+
+/*****************************************************************************
+ * GetWindowDisplayAffinity (USER32.@)
+ */
+BOOL WINAPI GetWindowDisplayAffinity(HWND hwnd, DWORD *affinity)
+{
+ FIXME("(%p, %p): stub\n", hwnd, affinity);
+
+ if (!hwnd || !affinity)
+ {
+ SetLastError(hwnd ? ERROR_NOACCESS : ERROR_INVALID_WINDOW_HANDLE);
+ return FALSE;
+ }
+
+ *affinity = WDA_NONE;
+ return TRUE;
+}
+
+/*****************************************************************************
+ * SetWindowDisplayAffinity (USER32.@)
+ */
+BOOL WINAPI SetWindowDisplayAffinity(HWND hwnd, DWORD affinity)
+{
+ FIXME("(%p, %lu): stub\n", hwnd, affinity);
+
+ if (!hwnd)
+ {
+ SetLastError(ERROR_INVALID_WINDOW_HANDLE);
+ return FALSE;
+ }
+
+ SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+ return FALSE;
+}
+
+/**********************************************************************
+ * SetWindowCompositionAttribute (USER32.@)
+ */
+BOOL WINAPI SetWindowCompositionAttribute(HWND hwnd, void *data)
+{
+ FIXME("(%p, %p): stub\n", hwnd, data);
+ SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ return FALSE;
+}