Commit 7686aa86 authored by Frank Richter's avatar Frank Richter Committed by Alexandre Julliard

When doing A->W WM_GETTEXTLENGTH, use WM_GETTEXT behind the scenes to

obtain an exact length.
parent 7886cacb
......@@ -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,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment