From: Paul Gofman pgofman@codeweavers.com
And use it in user32.dll. --- dlls/user32/message.c | 4 ++-- dlls/win32u/main.c | 5 +++++ dlls/win32u/message.c | 23 ++++++++++++++++++++++ dlls/win32u/tests/win32u.c | 40 ++++++++++++++++++++++++++++++++++++++ dlls/win32u/win32u.spec | 2 +- dlls/wow64win/user.c | 7 +++++++ include/ntuser.h | 5 +++++ 7 files changed, 83 insertions(+), 3 deletions(-)
diff --git a/dlls/user32/message.c b/dlls/user32/message.c index 73b41820adc..a4a1acd9e9e 100644 --- a/dlls/user32/message.c +++ b/dlls/user32/message.c @@ -970,7 +970,7 @@ DWORD WINAPI GetMessagePos(void) */ LONG WINAPI GetMessageTime(void) { - return NtUserGetThreadInfo()->message_time; + return NtUserGetThreadState( USER_GET_THREAD_STATE_MSGTIME ); }
@@ -980,7 +980,7 @@ LONG WINAPI GetMessageTime(void) */ LPARAM WINAPI GetMessageExtraInfo(void) { - return NtUserGetThreadInfo()->message_extra; + return NtUserGetThreadState( USER_GET_THREAD_STATE_MSGEXTRAINFO ); }
diff --git a/dlls/win32u/main.c b/dlls/win32u/main.c index 11628dcccca..e862e53048f 100644 --- a/dlls/win32u/main.c +++ b/dlls/win32u/main.c @@ -1694,6 +1694,11 @@ HDESK SYSCALL_API NtUserGetThreadDesktop( DWORD thread ) SYSCALL_FUNC( NtUserGetThreadDesktop ); }
+ULONG_PTR SYSCALL_API NtUserGetThreadState( DWORD request ) +{ + SYSCALL_FUNC( NtUserGetThreadState ); +} + BOOL SYSCALL_API NtUserGetTitleBarInfo( HWND hwnd, TITLEBARINFO *info ) { SYSCALL_FUNC( NtUserGetTitleBarInfo ); diff --git a/dlls/win32u/message.c b/dlls/win32u/message.c index 2f1e14c82c8..57b5b95ac09 100644 --- a/dlls/win32u/message.c +++ b/dlls/win32u/message.c @@ -4581,3 +4581,26 @@ BOOL WINAPI NtUserTranslateMessage( const MSG *msg, UINT flags ) } return TRUE; } + +/*********************************************************************** + * NtUserGetThreadState (win32u.@) + */ +ULONG_PTR WINAPI NtUserGetThreadState( ULONG request ) +{ + TRACE( "request %d.\n", (int)request ); + + switch(request) + { + case USER_GET_THREAD_STATE_MSGEXTRAINFO: + return NtUserGetThreadInfo()->message_extra; + + case USER_GET_THREAD_STATE_MSGTIME: + return NtUserGetThreadInfo()->message_time; + + default: + FIXME( "request %d is not supported.\n", (int)request ); + break; + } + + return 0; +} diff --git a/dlls/win32u/tests/win32u.c b/dlls/win32u/tests/win32u.c index 8e1b56f6501..d4d27628124 100644 --- a/dlls/win32u/tests/win32u.c +++ b/dlls/win32u/tests/win32u.c @@ -2515,6 +2515,45 @@ static void test_NtUserSetProcessDpiAwarenessContext( ULONG context ) winetest_pop_context(); }
+static LRESULT CALLBACK test_window_proc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam ) +{ + return DefWindowProcA( hwnd, msg, wparam, lparam ); +} + +static void test_message_info(void) +{ + DWORD_PTR ret, expected; + HWND hwnd; + WNDCLASSA cls; + MSG msg; + + memset(&cls, 0, sizeof(cls)); + cls.lpfnWndProc = test_window_proc; + cls.hInstance = GetModuleHandleA(NULL); + cls.hCursor = LoadCursorA(0, (LPCSTR)IDC_ARROW); + cls.lpszClassName = "Test class"; + RegisterClassA( &cls ); + hwnd = CreateWindowExA( 0, "Test class", NULL, WS_OVERLAPPEDWINDOW, 0, 0, 640, 480, 0, 0, 0, NULL ); + ShowWindow( hwnd, SW_SHOW ); + while (PeekMessageA( &msg, NULL, 0, 0, PM_NOREMOVE )) + { + GetMessageA( &msg, NULL, 0, 0 ); + expected = GetMessageTime(); + ret = NtUserGetThreadState( USER_GET_THREAD_STATE_MSGTIME ); + ok( ret == expected || broken( !ret ) /* Before Win10 1709 */, "got %#Ix, expected %#Ix.\n", ret, expected ); + SetMessageExtraInfo( 0xdeadbeef ); + expected = GetMessageExtraInfo(); + ret = NtUserGetThreadState( USER_GET_THREAD_STATE_MSGEXTRAINFO ); + ok( expected == 0xdeadbeef, "got %#Ix.\n", expected ); + ok( ret == expected || broken( !ret ) /* Before Win10 1709 */, "got %#Ix, expected %#Ix.\n", ret, expected ); + TranslateMessage( &msg ); + DispatchMessageA( &msg ); + } + + DestroyWindow( hwnd ); + UnregisterClassA( "Test class", cls.hInstance ); +} + START_TEST(win32u) { char **argv; @@ -2563,6 +2602,7 @@ START_TEST(win32u) test_NtUserCloseWindowStation(); test_NtUserDisplayConfigGetDeviceInfo(); test_NtUserQueryWindow(); + test_message_info();
run_in_process( argv, "NtUserEnableMouseInPointer 0" ); run_in_process( argv, "NtUserEnableMouseInPointer 1" ); diff --git a/dlls/win32u/win32u.spec b/dlls/win32u/win32u.spec index 08f27ad6671..899b2d815d3 100644 --- a/dlls/win32u/win32u.spec +++ b/dlls/win32u/win32u.spec @@ -1101,7 +1101,7 @@ @ stdcall -syscall NtUserGetSystemDpiForProcess(long) @ stdcall -syscall NtUserGetSystemMenu(long long) @ stdcall -syscall NtUserGetThreadDesktop(long) -@ stub NtUserGetThreadState +@ stdcall -syscall NtUserGetThreadState(long) @ stdcall -syscall NtUserGetTitleBarInfo(long ptr) @ stub NtUserGetTopLevelWindow @ stub NtUserGetTouchInputInfo diff --git a/dlls/wow64win/user.c b/dlls/wow64win/user.c index 28944f15d07..487c2e56072 100644 --- a/dlls/wow64win/user.c +++ b/dlls/wow64win/user.c @@ -3100,6 +3100,13 @@ NTSTATUS WINAPI wow64_NtUserGetThreadDesktop( UINT *args ) return HandleToUlong( NtUserGetThreadDesktop( thread )); }
+NTSTATUS WINAPI wow64_NtUserGetThreadState( UINT *args ) +{ + DWORD request = get_ulong( &args ); + + return NtUserGetThreadState( request ); +} + NTSTATUS WINAPI wow64_NtUserGetTitleBarInfo( UINT *args ) { HWND hwnd = get_handle( &args ); diff --git a/include/ntuser.h b/include/ntuser.h index 01fdd4b17e4..565a884afea 100644 --- a/include/ntuser.h +++ b/include/ntuser.h @@ -700,6 +700,10 @@ typedef enum _WINDOWINFOCLASS WindowDefaultInputContext, } WINDOWINFOCLASS;
+/* NtUserGetThreadState requests */ +#define USER_GET_THREAD_STATE_MSGEXTRAINFO 7 +#define USER_GET_THREAD_STATE_MSGTIME 9 + W32KAPI HKL WINAPI NtUserActivateKeyboardLayout( HKL layout, UINT flags ); W32KAPI BOOL WINAPI NtUserAddClipboardFormatListener( HWND hwnd ); W32KAPI UINT WINAPI NtUserAssociateInputContext( HWND hwnd, HIMC ctx, ULONG flags ); @@ -838,6 +842,7 @@ W32KAPI BOOL WINAPI NtUserGetScrollBarInfo( HWND hwnd, LONG id, SCROLLBARINFO W32KAPI ULONG WINAPI NtUserGetSystemDpiForProcess( HANDLE process ); W32KAPI HMENU WINAPI NtUserGetSystemMenu( HWND hwnd, BOOL revert ); W32KAPI HDESK WINAPI NtUserGetThreadDesktop( DWORD thread ); +W32KAPI ULONG_PTR WINAPI NtUserGetThreadState( ULONG request ); W32KAPI BOOL WINAPI NtUserGetTitleBarInfo( HWND hwnd, TITLEBARINFO *info ); W32KAPI INT WINAPI NtUserGetUpdateRgn( HWND hwnd, HRGN hrgn, BOOL erase ); W32KAPI BOOL WINAPI NtUserGetUpdatedClipboardFormats( UINT *formats, UINT size, UINT *out_size );