[Bug 7512] Problem with unicode comboboxes

Wine Bugs wine-bugs at winehq.org
Wed Feb 21 21:42:11 CST 2007


http://bugs.winehq.org/show_bug.cgi?id=7512





------- Additional Comments From focht at gmx.net  2007-21-02 21:42 -------
Created an attachment (id=5046)
 --> (http://bugs.winehq.org/attachment.cgi?id=5046&action=view)
log showing its not a wine bug (i think)

Hello,

i took the setup from here:

http://download.imgburn.com/SetupImgBurn_2.2.0.0.exe

It does not only have unicode problems ...
Sorry if my analysis got too long but it's worth read :)

Ok, Unicode stuff first

################### Part 1 ###################

Attached is a log that shows the problem.
In short: the ansi version of edit control window proc is called.

--- relevant log extract ---
trace:listbox:LISTBOX_GetText index 1 (0x0001) L"z:\\mnt\\data1"
trace:edit:EditWndProc_common hwnd=0x100a6 msg=c (WM_SETTEXT) wparam=0
lparam=1a33d8
trace:edit:EDIT_WM_SetText L"z"
trace:edit:EDIT_EM_ReplaceSel L"z", can_undo 0, send_update 0
trace:edit:EDIT_EM_ReplaceSel inserting stuff (tl 0, strl 1, selstart 0 (L""),
text L"")
--- relevant log extract ---

unicode=FALSE and text != "" exhibits the seen behaviour:

--- snip ---
static void EDIT_WM_SetText(EDITSTATE *es, LPCWSTR text, BOOL unicode)
{
    LPWSTR textW = NULL;
    if (!unicode && text)
    {
	LPCSTR textA = (LPCSTR)text;
	INT countW = MultiByteToWideChar(CP_ACP, 0, textA, -1, NULL, 0);
	textW = HeapAlloc(GetProcessHeap(), 0, countW * sizeof(WCHAR));
	if (textW)
	    MultiByteToWideChar(CP_ACP, 0, textA, -1, textW, countW);
	text = textW;
    }

    ...
	
--- snip ---

How it comes that ansi window proc is called in a UNICODE created control?
Let's dig deeper...

My "custom" trace with unicode flag dump:

--- relevant log extract ---
trace:edit:EditWndProcW hwnd=0x100a6 msg=c5 (EM_LIMITTEXT) wparam=0 lparam=0,
unicode=true
trace:edit:EditWndProc_common hwnd=0x100a6 msg=c5 (EM_LIMITTEXT) wparam=0
lparam=0, unicode=1
trace:edit:EditWndProc_common hwnd=0x100a6 msg=c5 (EM_LIMITTEXT) -- 0x00000000
unicode=1
0009:Ret  window proc 0x603ff580
(hwnd=0x100a6,msg=EM_LIMITTEXT,wp=00000000,lp=00000000) retval=00000000
0009:Ret  window proc 0x603d94d0
(hwnd=0x100a2,msg=CB_LIMITTEXT,wp=00000000,lp=00000000) retval=00000000
0009:Ret  user32.CallWindowProcW() retval=00000000 ret=006b13e1
0009:Ret  window proc 0x380135
(hwnd=0x100a2,msg=CB_LIMITTEXT,wp=00000000,lp=00000000) retval=00000000
0009:Ret  user32.CallWindowProcA() retval=00000000 ret=0061f37c
0009:Ret  window proc 0x38014f
(hwnd=0x100a2,msg=CB_LIMITTEXT,wp=00000000,lp=00000000) retval=00000000
0009:Ret  user32.CallWindowProcW() retval=00000000 ret=006b11d9
0009:Ret  window proc 0x380142
(hwnd=0x100a2,msg=CB_LIMITTEXT,wp=00000000,lp=00000000) retval=00000000
0009:Ret  user32.SendMessageA() retval=00000000 ret=005e5751
0009:Call user32.GetWindow(000100a2,00000005) ret=005e5c35
0009:Ret  user32.GetWindow() retval=000100a6 ret=005e5c35
0009:Call user32.GetWindowLongA(000100a6,fffffffc) ret=005e5c89
0009:Ret  user32.GetWindowLongA() retval=603ff4d0 ret=005e5c89
0009:Call user32.SetWindowLongA(000100a6,fffffffc,0038081d) ret=005e5ca4
trace:win:WIN_SetWindowLong 0x100a6 -4 38081d A
trace:win:alloc_winproc allocated 0xffff0059 for 0x38081d/(nil) (90/8192 used)
0009:Ret  user32.SetWindowLongA() retval=603ff4d0 ret=005e5ca4
0009:Call user32.SendMessageA(000100a6,000000d3,00000003,00000000) ret=005e5ccc

0009:Call window proc 0x38081d
(hwnd=0x100a6,msg=EM_SETMARGINS,wp=00000003,lp=00000000)
0009:Call user32.IsWindowUnicode(000100a6) ret=006a8bc8
0009:Ret  user32.IsWindowUnicode() retval=00000000 ret=006a8bc8
0009:Call user32.CallWindowProcA(603ff4d0,000100a6,000000d3,00000003,00000000)
ret=005e529f
0009:Call window proc 0x603ff4d0
(hwnd=0x100a6,msg=EM_SETMARGINS,wp=00000003,lp=00000000)
trace:edit:EditWndProcA hwnd=0x100a6 msg=d3 (EM_SETMARGINS) wparam=3 lparam=0
unicode=false
trace:edit:EditWndProc_common hwnd=0x100a6 msg=d3 (EM_SETMARGINS) wparam=3
lparam=0, unicode=0
--- relevant log extract ---

Did you spot it?
Unicode flag changes ... someone switched edit window proc to ansi version on
purpose!
But thats only half of the story...

--- relevant log extract ---
trace:edit:EDIT_SetCaretPos 0 - 0x0
trace:win:RedrawWindow 0x100a6 whole window flags: RDW_INVALIDATE RDW_ERASE
trace:edit:EDIT_EM_SetMargins left=0, right=0
trace:edit:EditWndProc_common hwnd=0x100a6 msg=d3 (EM_SETMARGINS) -- 0x00000000
unicode=0
0009:Ret  window proc 0x603ff4d0
(hwnd=0x100a6,msg=EM_SETMARGINS,wp=00000003,lp=00000000) retval=00000000
0009:Ret  user32.CallWindowProcA() retval=00000000 ret=005e529f
0009:Ret  window proc 0x38081d
(hwnd=0x100a6,msg=EM_SETMARGINS,wp=00000003,lp=00000000) retval=00000000
0009:Ret  user32.SendMessageA() retval=00000000 ret=005e5ccc
0009:Call user32.GetWindowLongA(000100a6,fffffffc) ret=006a883a
0009:Ret  user32.GetWindowLongA() retval=0038081d ret=006a883a
0009:Call user32.SetWindowLongW(000100a6,fffffffc,0038081d) ret=006a8843
trace:win:WIN_SetWindowLong 0x100a6 -4 38081d W
trace:win:alloc_winproc allocated 0xffff005a for (nil)/0x38081d (91/8192 used)
0009:Ret  user32.SetWindowLongW() retval=ffff0059 ret=006a8843
0009:Call user32.SendMessageA(000100a2,0000000e,00000000,00000000) ret=006b1568

trace:msg:WINPROC_CallProcAtoW
(hwnd=0x100a2,msg=WM_GETTEXTLENGTH,wp=00000000,lp=00000000)
0009:Call window proc 0x380142
(hwnd=0x100a2,msg=WM_GETTEXTLENGTH,wp=00000000,lp=00000000)
0009:Call user32.CallWindowProcW(0038014f,000100a2,0000000e,00000000,00000000)
ret=006b11d9
0009:Call window proc 0x38014f
(hwnd=0x100a2,msg=WM_GETTEXTLENGTH,wp=00000000,lp=00000000)
0009:Call user32.CallWindowProcA(00380135,000100a2,0000000e,00000000,00000000)
ret=0061f37c
0009:Call window proc 0x380135
(hwnd=0x100a2,msg=WM_GETTEXTLENGTH,wp=00000000,lp=00000000)
0009:Call user32.CallWindowProcW(603d94d0,000100a2,0000000e,00000000,00000000)
ret=006b13e1
0009:Call window proc 0x603d94d0
(hwnd=0x100a2,msg=WM_GETTEXTLENGTH,wp=00000000,lp=00000000)
trace:combo:ComboWndProc_common [0x100a2]: msg WM_GETTEXTLENGTH wp 00000000 lp
00000000 unicode=1
0009:Call window proc 0x38081d
(hwnd=0x100a6,msg=WM_GETTEXTLENGTH,wp=00000000,lp=00000000)
0009:Call user32.IsWindowUnicode(000100a6) ret=006a8bc8
0009:Ret  user32.IsWindowUnicode() retval=00000001 ret=006a8bc8
0009:Call user32.IsWindowUnicode(000100a6) ret=006a8a0b
0009:Ret  user32.IsWindowUnicode() retval=00000001 ret=006a8a0b
0009:Call user32.CallWindowProcW(603ff4d0,000100a6,0000000e,00000000,00000000)
ret=006a8a3f
0009:Call window proc 0x603ff4d0
(hwnd=0x100a6,msg=WM_GETTEXTLENGTH,wp=00000000,lp=00000000)
trace:edit:EditWndProcA hwnd=0x100a6 msg=e (WM_GETTEXTLENGTH) wparam=0 lparam=0
unicode=false
trace:edit:EditWndProc_common hwnd=0x100a6 msg=e (WM_GETTEXTLENGTH) wparam=0
lparam=0, unicode=0
trace:edit:EditWndProc_common hwnd=0x100a6 msg=e (WM_GETTEXTLENGTH) --
0x00000000 unicode=0
0009:Ret  window proc 0x603ff4d0
(hwnd=0x100a6,msg=WM_GETTEXTLENGTH,wp=00000000,lp=00000000) retval=00000000
0009:Ret  user32.CallWindowProcW() retval=00000000 ret=006a8a3f
--- relevant log extract ---

The unicode callback is accidentally switched to ansi window proc of edit
control.
Thats why the ansi version of edit control window proc is called!

I did not look very hard at those (delphi) TNTUnicodeControls the software uses
but i found a code piece like this:

--------------------
if ListHandle <> 0 then
begin
	// re-extract FDefListProc as a Unicode proc
	SetWindowLongA(ListHandle, GWL_WNDPROC, Integer(FDefListProc));
	FDefListProc := Pointer(GetWindowLongW(ListHandle, GWL_WNDPROC));
	// override with FListInstance as a Unicode proc
	SetWindowLongW(ListHandle, GWL_WNDPROC, Integer(FListInstance));
end;
 SetWindowLongW(EditHandle, GWL_WNDPROC, GetWindowLong(EditHandle,
GWL_WNDPROC));
--------------------

Last line has a bug .. can you spot it? :)

################### Part 2 ###################

>From what i've seen there are other errors too, mostly related to transparent
bitmaps (png's).

Install went fine.
Had to unpack the .exe for analysis because it's UPXed.

If you start this thing under winedbg or any other debugger you will notice
lot's of 0xC0000005 (first chance).
Pass them on but they appear every time.

I tracked the origin of exceptions down to this signature:

; __fastcall Pngimage::TPNGObject::DrawPartialTrans(unsigned int, Types::TRect
const &)

Seems some open source png library implemented in delphi:

http://jabberstudio.org/cgi-bin/viewcvs.cgi/exodus/trunk/jopl/png/pngimage.pas?rev=2269&view=auto


--- snip from source ---

{Draws using partial transparency}
procedure TPngObject.DrawPartialTrans(DC: HDC; Rect: TRect);
...

{Structure used to create the bitmap}
  BitmapInfoHeader: TBitmapInfoHeader =
    (biSize: sizeof(TBitmapInfoHeader);
     biWidth: 100;
     biHeight: 100;
     biPlanes: 1;
     biBitCount: 32;
     biCompression: BI_RGB;
     biSizeImage: 0;
     biXPelsPerMeter: 0;
     biYPelsPerMeter: 0;
     biClrUsed: 0;
     biClrImportant: 0);

....
 {Prepare to create the bitmap}
  Fillchar(BitmapInfo, sizeof(BitmapInfo), #0);
  BitmapInfoHeader.biWidth := Header.Width;
  BitmapInfoHeader.biHeight := -1 * Header.Height;
  BitmapInfo.bmiHeader := BitmapInfoHeader;

...

 BufferBitmap := CreateDIBSection(BufferDC, BitmapInfo, DIB_RGB_COLORS,
    BufferBits, 0, 0);

--- snip from source ---

This results in console messages like this:

err:x11drv:X11DRV_CreateBitmap Trying to make bitmap with planes=1, bpp=32

But it gets worse ...
Accessing the pixel data results in exceptions thrown all the time.

Run "WINEDEBUG=+seh ...." and see what i mean.
Move over an icon or some bitmap -> first chance exception.

These are not "programmed" ones like RaiseError( exception_type,
exception_text) but access violations due to incorrect memory access
They are handled somewhere but i'm not sure if the default exception handler is
located "too high".
That might introduce subtle bugs as unwanted/unexpected exceptions lead to
skipped code blocks and break normal progam flow.

Would be nice to see this type of error resolved.
It's hard to debug with a filter to 0xC0000005's - you might miss the real ones
(not caused by png stuff).

Regards


-- 
Configure bugmail: http://bugs.winehq.org/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are the assignee for the bug, or are watching the assignee.



More information about the wine-bugs mailing list