When doing A->W WM_GETTEXTLENGTH, use WM_GETTEXT behind the scenes to
obtain an exact length.
This commit is contained in:
parent
7886cacbf5
commit
7686aa86e6
|
@ -2410,7 +2410,7 @@ LRESULT WINAPI SendMessageTimeoutA( HWND hwnd, UINT msg, WPARAM wparam, LPARAM l
|
|||
return 0;
|
||||
ret = send_inter_thread_message( dest_tid, &info, &result );
|
||||
result = WINPROC_UnmapMsg32ATo32W( info.hwnd, info.msg, info.wparam,
|
||||
info.lparam, result );
|
||||
info.lparam, result, NULL );
|
||||
}
|
||||
else ret = send_inter_thread_message( dest_tid, &info, &result );
|
||||
}
|
||||
|
|
|
@ -75,7 +75,8 @@ LRESULT WINAPI SendMessage16( HWND16 hwnd16, UINT16 msg, WPARAM16 wparam, LPARAM
|
|||
if (WINPROC_MapMsg16To32W( hwnd, msg, wparam, &msg32, &wparam32, &lparam ) == -1)
|
||||
return 0;
|
||||
result = WINPROC_UnmapMsg16To32W( hwnd, msg32, wparam32, lparam,
|
||||
SendMessageW( hwnd, msg32, wparam32, lparam ) );
|
||||
SendMessageW( hwnd, msg32, wparam32, lparam ),
|
||||
NULL );
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include "winbase.h"
|
||||
#include "wingdi.h"
|
||||
#include "winuser.h"
|
||||
#include "winnls.h"
|
||||
|
||||
#include "wine/test.h"
|
||||
|
||||
|
@ -4535,7 +4536,8 @@ static void test_accelerators(void)
|
|||
|
||||
/************* window procedures ********************/
|
||||
|
||||
static LRESULT WINAPI MsgCheckProcA(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
static LRESULT MsgCheckProc (BOOL unicode, HWND hwnd, UINT message,
|
||||
WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
static long defwndproc_counter = 0;
|
||||
static long beginpaint_counter = 0;
|
||||
|
@ -4672,12 +4674,23 @@ static LRESULT WINAPI MsgCheckProcA(HWND hwnd, UINT message, WPARAM wParam, LPAR
|
|||
}
|
||||
|
||||
defwndproc_counter++;
|
||||
ret = DefWindowProcA(hwnd, message, wParam, lParam);
|
||||
ret = unicode ? DefWindowProcW(hwnd, message, wParam, lParam)
|
||||
: DefWindowProcA(hwnd, message, wParam, lParam);
|
||||
defwndproc_counter--;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static LRESULT WINAPI MsgCheckProcA(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
return MsgCheckProc (FALSE, hwnd, message, wParam, lParam);
|
||||
}
|
||||
|
||||
static LRESULT WINAPI MsgCheckProcW(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
return MsgCheckProc (TRUE, hwnd, message, wParam, lParam);
|
||||
}
|
||||
|
||||
static LRESULT WINAPI PopupMsgCheckProcA(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
static long defwndproc_counter = 0;
|
||||
|
@ -5020,6 +5033,32 @@ static LRESULT CALLBACK MsgConversionProcW(HWND hwnd, UINT uMsg, WPARAM wParam,
|
|||
return DefWindowProcW(hwnd, uMsg, wParam, lParam);
|
||||
}
|
||||
|
||||
static const struct message WmGetTextLengthAfromW[] = {
|
||||
{ WM_GETTEXTLENGTH, sent },
|
||||
{ WM_GETTEXT, sent },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static const WCHAR testWindowClassW[] =
|
||||
{ 'T','e','s','t','W','i','n','d','o','w','C','l','a','s','s','W',0 };
|
||||
|
||||
static const WCHAR dummy_window_text[] = {'d','u','m','m','y',' ','t','e','x','t',0};
|
||||
|
||||
/* dummy window proc for WM_GETTEXTLENGTH test */
|
||||
static LRESULT CALLBACK get_text_len_proc( HWND hwnd, UINT msg, WPARAM wp, LPARAM lp )
|
||||
{
|
||||
switch(msg)
|
||||
{
|
||||
case WM_GETTEXTLENGTH:
|
||||
return lstrlenW(dummy_window_text) + 37; /* some random length */
|
||||
case WM_GETTEXT:
|
||||
lstrcpynW( (LPWSTR)lp, dummy_window_text, wp );
|
||||
return lstrlenW( (LPWSTR)lp );
|
||||
default:
|
||||
return DefWindowProcW( hwnd, msg, wp, lp );
|
||||
}
|
||||
}
|
||||
|
||||
static void test_message_conversion(void)
|
||||
{
|
||||
static const WCHAR wszMsgConversionClass[] =
|
||||
|
@ -5027,7 +5066,8 @@ static void test_message_conversion(void)
|
|||
WNDCLASSW cls;
|
||||
LRESULT lRes;
|
||||
HWND hwnd;
|
||||
WNDPROC wndproc;
|
||||
WNDPROC wndproc, newproc;
|
||||
BOOL ret;
|
||||
|
||||
cls.style = 0;
|
||||
cls.lpfnWndProc = MsgConversionProcW;
|
||||
|
@ -5043,6 +5083,18 @@ static void test_message_conversion(void)
|
|||
* meaningless on those platforms */
|
||||
if(!RegisterClassW(&cls)) return;
|
||||
|
||||
cls.style = 0;
|
||||
cls.lpfnWndProc = MsgCheckProcW;
|
||||
cls.cbClsExtra = 0;
|
||||
cls.cbWndExtra = 0;
|
||||
cls.hInstance = GetModuleHandleW(0);
|
||||
cls.hIcon = 0;
|
||||
cls.hCursor = LoadCursorW(0, (LPWSTR)IDC_ARROW);
|
||||
cls.hbrBackground = GetStockObject(WHITE_BRUSH);
|
||||
cls.lpszMenuName = NULL;
|
||||
cls.lpszClassName = testWindowClassW;
|
||||
if(!RegisterClassW(&cls)) return;
|
||||
|
||||
hwnd = CreateWindowExW(0, wszMsgConversionClass, NULL, WS_OVERLAPPED,
|
||||
100, 100, 200, 200, 0, 0, 0, NULL);
|
||||
ok(hwnd != NULL, "Window creation failed\n");
|
||||
|
@ -5104,6 +5156,41 @@ static void test_message_conversion(void)
|
|||
lRes = SendMessageCallbackW(hwnd, CB_FINDSTRINGEXACT, 0, (LPARAM)wszUnicode, NULL, 0);
|
||||
ok(lRes == 0 && (GetLastError() == ERROR_MESSAGE_SYNC_ONLY || GetLastError() == ERROR_INVALID_PARAMETER),
|
||||
"SendMessageCallback on sync only message returned %ld, last error %ld\n", lRes, GetLastError());
|
||||
|
||||
/* Check WM_GETTEXTLENGTH A->W behaviour, whether WM_GETTEXT is also sent or not */
|
||||
|
||||
hwnd = CreateWindowW (testWindowClassW, wszUnicode,
|
||||
WS_OVERLAPPEDWINDOW,
|
||||
100, 100, 200, 200, 0, 0, 0, NULL);
|
||||
assert(hwnd);
|
||||
flush_sequence();
|
||||
lRes = SendMessageA (hwnd, WM_GETTEXTLENGTH, 0, 0);
|
||||
ok_sequence(WmGetTextLengthAfromW, "ANSI WM_GETTEXTLENGTH to Unicode window", FALSE);
|
||||
ok( lRes == WideCharToMultiByte( CP_ACP, 0, wszUnicode, lstrlenW(wszUnicode), NULL, 0, NULL, NULL ),
|
||||
"got bad length %ld\n", lRes );
|
||||
|
||||
flush_sequence();
|
||||
lRes = CallWindowProcA( (WNDPROC)GetWindowLongPtrA( hwnd, GWLP_WNDPROC ),
|
||||
hwnd, WM_GETTEXTLENGTH, 0, 0);
|
||||
ok_sequence(WmGetTextLengthAfromW, "ANSI WM_GETTEXTLENGTH to Unicode window", FALSE);
|
||||
ok( lRes == WideCharToMultiByte( CP_ACP, 0, wszUnicode, lstrlenW(wszUnicode), NULL, 0, NULL, NULL ),
|
||||
"got bad length %ld\n", lRes );
|
||||
|
||||
wndproc = (WNDPROC)SetWindowLongPtrW( hwnd, GWLP_WNDPROC, (LONG_PTR)get_text_len_proc );
|
||||
newproc = (WNDPROC)GetWindowLongPtrA( hwnd, GWLP_WNDPROC );
|
||||
lRes = CallWindowProcA( newproc, hwnd, WM_GETTEXTLENGTH, 0, 0 );
|
||||
ok( lRes == WideCharToMultiByte( CP_ACP, 0, dummy_window_text, lstrlenW(dummy_window_text),
|
||||
NULL, 0, NULL, NULL ),
|
||||
"got bad length %ld\n", lRes );
|
||||
|
||||
SetWindowLongPtrW( hwnd, GWLP_WNDPROC, (LONG_PTR)wndproc ); /* restore old wnd proc */
|
||||
lRes = CallWindowProcA( newproc, hwnd, WM_GETTEXTLENGTH, 0, 0 );
|
||||
ok( lRes == WideCharToMultiByte( CP_ACP, 0, dummy_window_text, lstrlenW(dummy_window_text),
|
||||
NULL, 0, NULL, NULL ),
|
||||
"got bad length %ld\n", lRes );
|
||||
|
||||
ret = DestroyWindow(hwnd);
|
||||
ok( ret, "DestroyWindow() error %ld\n", GetLastError());
|
||||
}
|
||||
|
||||
typedef struct _thread_info
|
||||
|
|
|
@ -846,7 +846,7 @@ INT WINPROC_MapMsg32ATo32W( HWND hwnd, UINT msg, WPARAM *pwparam, LPARAM *plpara
|
|||
* Unmap a message that was mapped from Ansi to Unicode.
|
||||
*/
|
||||
LRESULT WINPROC_UnmapMsg32ATo32W( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam,
|
||||
LRESULT result )
|
||||
LRESULT result, WNDPROC dispatch )
|
||||
{
|
||||
switch(msg)
|
||||
{
|
||||
|
@ -868,8 +868,31 @@ LRESULT WINPROC_UnmapMsg32ATo32W( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lPa
|
|||
case WM_GETTEXTLENGTH:
|
||||
case CB_GETLBTEXTLEN:
|
||||
case LB_GETTEXTLEN:
|
||||
/* there may be one DBCS char for each Unicode char */
|
||||
return result * 2;
|
||||
if (result >= 0)
|
||||
{
|
||||
/* Determine respective GETTEXT message */
|
||||
UINT msgGetText =
|
||||
(msg == WM_GETTEXTLENGTH) ? WM_GETTEXT :
|
||||
((msg == CB_GETLBTEXTLEN) ? CB_GETLBTEXT : LB_GETTEXT);
|
||||
/* wParam differs between the messages */
|
||||
WPARAM wp = (msg == WM_GETTEXTLENGTH) ? (WPARAM)(result + 1) : wParam;
|
||||
|
||||
WCHAR* p = HeapAlloc (GetProcessHeap(), 0, (result + 1) * sizeof(WCHAR));
|
||||
|
||||
if (p)
|
||||
{
|
||||
LRESULT n;
|
||||
|
||||
if (dispatch)
|
||||
n = WINPROC_CallWndProc(dispatch, hwnd, msgGetText, wp, (LPARAM)p);
|
||||
else
|
||||
n = SendMessageW (hwnd, msgGetText, wp, (LPARAM)p);
|
||||
|
||||
result = WideCharToMultiByte( CP_ACP, 0, p, n, NULL, 0, 0, NULL );
|
||||
HeapFree (GetProcessHeap(), 0, p);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case WM_NCCREATE:
|
||||
case WM_CREATE:
|
||||
{
|
||||
|
@ -1854,7 +1877,7 @@ INT WINPROC_MapMsg16To32W( HWND hwnd, UINT16 msg16, WPARAM16 wParam16, UINT *pms
|
|||
* Unmap a message that was mapped from 16- to 32-bit Unicode.
|
||||
*/
|
||||
LRESULT WINPROC_UnmapMsg16To32W( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam,
|
||||
LRESULT result )
|
||||
LRESULT result, WNDPROC dispatch )
|
||||
{
|
||||
switch(msg)
|
||||
{
|
||||
|
@ -1864,7 +1887,7 @@ LRESULT WINPROC_UnmapMsg16To32W( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lPar
|
|||
case CB_GETLBTEXTLEN:
|
||||
case LB_GETTEXTLEN:
|
||||
case WM_ASKCBFORMATNAME:
|
||||
return WINPROC_UnmapMsg32ATo32W( hwnd, msg, wParam, lParam, result );
|
||||
return WINPROC_UnmapMsg32ATo32W( hwnd, msg, wParam, lParam, result, dispatch );
|
||||
case WM_NCCREATE:
|
||||
case WM_CREATE:
|
||||
{
|
||||
|
@ -1900,7 +1923,7 @@ LRESULT WINPROC_UnmapMsg16To32W( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lPar
|
|||
LPMSG msg32 = (LPMSG)lParam;
|
||||
|
||||
WINPROC_UnmapMsg16To32W( hwnd, msg32->message, msg32->wParam, msg32->lParam,
|
||||
result);
|
||||
result, dispatch );
|
||||
HeapFree( GetProcessHeap(), 0, msg32 );
|
||||
}
|
||||
break;
|
||||
|
@ -2955,7 +2978,7 @@ static LRESULT WINPROC_CallProc32ATo32W( WNDPROC func, HWND hwnd,
|
|||
return 0;
|
||||
}
|
||||
result = WINPROC_CallWndProc( func, hwnd, msg, wParam, lParam );
|
||||
if (unmap) result = WINPROC_UnmapMsg32ATo32W( hwnd, msg, wParam, lParam, result );
|
||||
if (unmap) result = WINPROC_UnmapMsg32ATo32W( hwnd, msg, wParam, lParam, result, func );
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -3099,7 +3122,8 @@ LRESULT WINAPI __wine_call_wndproc_32W( HWND16 hwnd, UINT16 msg, WPARAM16 wPara
|
|||
if (WINPROC_MapMsg16To32W( hwnd32, msg, wParam, &msg32, &wParam32, &lParam ) == -1)
|
||||
return 0;
|
||||
result = WINPROC_CallWndProc( func, hwnd32, msg32, wParam32, lParam );
|
||||
return WINPROC_UnmapMsg16To32W( hwnd32, msg32, wParam32, lParam, result );
|
||||
return WINPROC_UnmapMsg16To32W( hwnd32, msg32, wParam32, lParam, result,
|
||||
func );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -71,11 +71,13 @@ extern INT WINPROC_MapMsg32WTo16( HWND hwnd, UINT msg32,
|
|||
WPARAM wParam32, UINT16 *pmsg16,
|
||||
WPARAM16 *pwparam16, LPARAM *plparam );
|
||||
extern LRESULT WINPROC_UnmapMsg32ATo32W( HWND hwnd, UINT msg, WPARAM wParam,
|
||||
LPARAM lParam, LRESULT result );
|
||||
LPARAM lParam, LRESULT result,
|
||||
WNDPROC dispatch );
|
||||
extern LRESULT WINPROC_UnmapMsg16To32A( HWND hwnd, UINT msg, WPARAM wParam,
|
||||
LPARAM lParam, LRESULT result );
|
||||
extern LRESULT WINPROC_UnmapMsg16To32W( HWND hwnd, UINT msg, WPARAM wParam,
|
||||
LPARAM lParam, LRESULT result );
|
||||
LPARAM lParam, LRESULT result,
|
||||
WNDPROC dispatch );
|
||||
extern void WINPROC_UnmapMsg32ATo16( HWND hwnd, UINT msg, WPARAM wParam,
|
||||
LPARAM lParam, MSGPARAM16* pm16 );
|
||||
extern void WINPROC_UnmapMsg32WTo16( HWND hwnd, UINT msg, WPARAM wParam,
|
||||
|
|
Loading…
Reference in New Issue