http://bugs.winehq.org/show_bug.cgi?id=17370
Summary: Notepad++ 5.2 crashes when triggering tooltip over macro record toolbar button Product: Wine Version: 1.1.14 Platform: PC URL: http://sourceforge.net/project/showfiles.php?group_id=95 717&package_id=102072&release_id=659500 OS/Version: Linux Status: UNCONFIRMED Severity: normal Priority: P2 Component: -unknown AssignedTo: wine-bugs@winehq.org ReportedBy: arethusa26@gmail.com
Created an attachment (id=19415) --> (http://bugs.winehq.org/attachment.cgi?id=19415) Notepad++ 5.2 first chance exception backtraces
With today's Git (wine-1.1.14-433-g0cc91ab), when placing the mouse over the macro record button, Notepad++ incurs an access violation, eventually leading to a graceful termination. I've attached a winedbg run showing the first-chance exceptions incurred, the first couple being during startup, which did not cause any noticeable problems, and the last few being when the reported access violation occurs. I also rebuilt Notepad++ with MSVC++ 2008 in order to gain symbolic information.
http://bugs.winehq.org/show_bug.cgi?id=17370
--- Comment #1 from Andrew Nguyen arethusa26@gmail.com 2009-02-13 05:50:07 --- Created an attachment (id=19416) --> (http://bugs.winehq.org/attachment.cgi?id=19416) Notepad++ 5.2 problematic toolbar button
Placing the cursor over this particular button should be sufficient to cause a message box reporting the access violation to trigger.
http://bugs.winehq.org/show_bug.cgi?id=17370
Andrew Nguyen arethusa26@gmail.com changed:
What |Removed |Added ---------------------------------------------------------------------------- Keywords| |download
http://bugs.winehq.org/show_bug.cgi?id=17370
Austin English austinenglish@gmail.com changed:
What |Removed |Added ---------------------------------------------------------------------------- Keywords| |source
http://bugs.winehq.org/show_bug.cgi?id=17370
Austin English austinenglish@gmail.com changed:
What |Removed |Added ---------------------------------------------------------------------------- Status|UNCONFIRMED |NEW Ever Confirmed|0 |1
--- Comment #2 from Austin English austinenglish@gmail.com 2010-09-09 01:26:02 CDT --- It's okay now in 5.6.2 / wine-1.3.2-115-gd822555. I retried in 5.2, however, and it still crashes: err:seh:setup_exception_record nested exception on signal stack in thread 000f eip 7dd997be esp 7ffcf924 stack 0x14a2000-0x15a0000
http://bugs.winehq.org/show_bug.cgi?id=17370
Dan Kegel dank@kegel.com changed:
What |Removed |Added ---------------------------------------------------------------------------- CC| |dank@kegel.com
--- Comment #3 from Dan Kegel dank@kegel.com 2010-09-09 09:56:40 CDT --- Tempting to abandon; unless someone really needs the old version, it might not be worth the effort to investigate.
http://bugs.winehq.org/show_bug.cgi?id=17370
Anastasius Focht focht@gmx.net changed:
What |Removed |Added ---------------------------------------------------------------------------- CC| |focht@gmx.net Component|-unknown |user32 Summary|Notepad++ 5.2 crashes when |Notepad++ 5.2 crashes when |triggering tooltip over |triggering tooltip over |macro record toolbar button |macro record toolbar button | |(user32.RealChildWindowFrom | |Point needs to pass | |CWP_SKIPINVISIBLE to skip | |hidden windows)
--- Comment #4 from Anastasius Focht focht@gmx.net 2012-01-15 17:24:07 CST --- Hello,
hmm interesting ... brain damage at its best ;-)
--- snip --- 0024:Call user32.CreateWindowExW(00000010,004b4d20 L"Notepad++",004b6b4c L"Notepad++",02cf0000,00000000,00000000,00000000,00000000,00000000,00000000,00400000,002e574c) ret=00447451 0024:trace:win:WIN_CreateWindowEx L"Notepad++" L"Notepad++" ex=00000010 style=02cf0000 0,0 0x0 parent=(nil) menu=(nil) inst=0x400000 params=0x2e574c 0024:trace:win:dump_window_styles style: WS_CLIPCHILDREN WS_CAPTION WS_SYSMENU WS_THICKFRAME WS_MINIMIZEBOX WS_MAXIMIZEBOX 0024:trace:win:dump_window_styles exstyle: WS_EX_ACCEPTFILES ... 0024:trace:win:WIN_CreateWindowEx hwnd 0x1007a cs 0,0 112x27 ... 0024:trace:tooltips:TOOLTIPS_WindowProc hwnd=0x10020a msg=113 wparam=1 lParam=0 0024:trace:tooltips:TOOLTIPS_Timer timer 1 (0x10020a) expired! ... 0024:Call window proc 0x68267ea8 (hwnd=0x10020a,msg=TTM_WINDOWFROMPOINT,wp=00000000,lp=002e5388) ... 0024:Ret window proc 0x68267ea8 (hwnd=0x10020a,msg=TTM_WINDOWFROMPOINT,wp=00000000,lp=002e5388) retval=000201f2 0024:Ret user32.SendMessageW() retval=000201f2 ret=68264e2f 0024:Call user32.ScreenToClient(000201f2,002e5388) ret=68264e57 0024:Ret user32.ScreenToClient() retval=00000001 ret=68264e57 ... 0024:trace:tooltips:TOOLTIPS_Show Show tooltip pre 30! (0x10020a) 0024:trace:tooltips:TOOLTIPS_GetDispInfoW hdr.idFrom = 56b8 ... 0024:trace:toolbar:ToolbarWindowProc hwnd=0x201f2 msg=4e wparam=56b8 lparam=2e5134 0024:trace:toolbar:TOOLBAR_GetButtonIndex command=22200 index=38 0024:trace:toolbar:TOOLBAR_TTGetDispInfo button index = 38 ... 0024:trace:toolbar:TOOLBAR_SendNotify to window 0x1007a, code=fffffd32, via ANSI ... 0024:trace:msg:WINPROC_CallProcWtoA (hwnd=0x1007a,msg=WM_NOTIFY,wp=00000000,lp=002e4d7c) ... 0024:trace:toolbar:ToolbarWindowProc hwnd=0x201f2 msg=401 wparam=a411 lparam=0 0024:trace:toolbar:TOOLBAR_GetButtonIndex command=42001 index=8 0024:trace:toolbar:TOOLBAR_EnableButton hwnd=0x201f2, btn id=42001, lParam=0x00000000 ... 0024:trace:toolbar:TOOLBAR_TTGetDispInfo Sending tooltip notification to 0x1007a ... 0024:trace:toolbar:ToolbarWindowProc hwnd=0x201f2 msg=401 wparam=a430 lparam=1 0024:trace:toolbar:TOOLBAR_GetButtonIndex command=42032 index=32 0024:trace:toolbar:TOOLBAR_EnableButton hwnd=0x201f2, btn id=42032, lParam=0x00000001 0024:Ret window proc 0x68260e97 (hwnd=0x201f2,msg=TB_ENABLEBUTTON,wp=0000a430,lp=00000001) retval=00000001 0024:Ret user32.SendMessageW() retval=00000001 ret=0042bf24 0024:Call user32.GetCursorPos(002e1ef0) ret=0043ee5b 0024:Ret user32.GetCursorPos() retval=00000001 ret=0043ee5b 0024:Call user32.ScreenToClient(0001007a,002e1ef0) ret=0043ee6a 0024:Ret user32.ScreenToClient() retval=00000001 ret=0043ee6a 0024:Call user32.RealChildWindowFromPoint(0001007a,00000302,0000000b) ret=0043ee7e 0024:Ret user32.RealChildWindowFromPoint() retval=000100ae ret=0043ee7e ... 0024:Call user32.SendMessageW(000100ae,0000133c,000056b8,002e1eb4) ret=0041536b 0024:Call hook proc 0x412cd0 (id=WH_CALLWNDPROC,code=0,wp=00000001,lp=002e1d4c) 0024:Call user32.GetWindowLongW(000100be,ffffffeb) ret=00412cf5 0024:Ret user32.GetWindowLongW() retval=002e5968 ret=00412cf5 0024:Call user32.CallNextHookEx(000100fa,00000000,00000001,002e1d4c) ret=00412dd0 0024:Ret user32.CallNextHookEx() retval=00000000 ret=00412dd0 0024:Ret hook proc 0x412cd0 (id=WH_CALLWNDPROC,code=0,wp=00000001,lp=002e1d4c) retval=00000000 0024:Call window proc 0x473540 (hwnd=0x100ae,msg=TCM_GETITEMW,wp=000056b8,lp=002e1eb4) 0024:Call user32.GetWindowLongW(000100ae,ffffffeb) ret=0047355d 0024:Ret user32.GetWindowLongW() retval=002e5d80 ret=0047355d 0024:Call user32.CallWindowProcW(6824c2e7,000100ae,0000133c,000056b8,002e1eb4) ret=0047321a 0024:Call window proc 0x6824c2e7 (hwnd=0x100ae,msg=TCM_GETITEMW,wp=000056b8,lp=002e1eb4) 0024:Call user32.GetWindowLongW(000100ae,00000000) ret=6824c30c 0024:Ret user32.GetWindowLongW() retval=00147e10 ret=6824c30c 0024:Ret window proc 0x6824c2e7 (hwnd=0x100ae,msg=TCM_GETITEMW,wp=000056b8,lp=002e1eb4) retval=00000000 0024:Ret user32.CallWindowProcW() retval=00000000 ret=0047321a 0024:Ret window proc 0x473540 (hwnd=0x100ae,msg=TCM_GETITEMW,wp=000056b8,lp=002e1eb4) retval=00000000 0024:Ret user32.SendMessageW() retval=00000000 ret=0041536b 0024:trace:seh:raise_exception code=c0000005 flags=0 addr=0x4029d0 ip=004029d0 tid=0024 0024:trace:seh:raise_exception info[0]=00000000 0024:trace:seh:raise_exception info[1]=0000008a 0024:trace:seh:raise_exception eax=0000008a ebx=0010020a ecx=004e3fec edx=00000000 esi=0000008a edi=0000008c 0024:trace:seh:raise_exception ebp=002e574c esp=002e1ec8 cs=0023 ds=002b es=002b fs=0063 gs=006b flags=00010202 0024:trace:seh:call_stack_handlers calling handler at 0x4aca61 code=c0000005 flags=0 --- snip ---
I found the place in Notepad++ 5.2 sources that matches this trace log pretty nicely:
"Notepad_plus.cpp":
--- snip --- BOOL Notepad_plus::notify(SCNotification *notification) { //Important, keep track of which element generated the message bool isFromPrimary = (_mainEditView.getHSelf() == notification->nmhdr.hwndFrom || _mainDocTab.getHSelf() == notification->nmhdr.hwndFrom); bool isFromSecondary = !isFromPrimary && (_subEditView.getHSelf() == notification->nmhdr.hwndFrom || _subDocTab.getHSelf() == notification->nmhdr.hwndFrom); ScintillaEditView * notifyView = isFromPrimary?&_mainEditView:&_subEditView; DocTabView *notifyDocTab = isFromPrimary?&_mainDocTab:&_subDocTab; TBHDR * tabNotification = (TBHDR*) notification; ...
case TTN_GETDISPINFO: { LPTOOLTIPTEXT lpttt;
lpttt = (LPTOOLTIPTEXT)notification; lpttt->hinst = _hInst;
POINT p; ::GetCursorPos(&p); ::ScreenToClient(_hSelf, &p); HWND hWin = ::RealChildWindowFromPoint(_hSelf, p);
static generic_string tip; int id = int(lpttt->hdr.idFrom); if (hWin == _rebarTop.getHSelf()) { getNameStrFromCmd(id, tip); } else if (hWin == _mainDocTab.getHSelf()) { BufferID idd = _mainDocTab.getBufferByIndex(id); Buffer * buf = MainFileManager->getBufferByID(idd); tip = buf->getFullPathName(); } else if (hWin == _subDocTab.getHSelf()) { BufferID idd = _subDocTab.getBufferByIndex(id); Buffer * buf = MainFileManager->getBufferByID(idd); tip = buf->getFullPathName(); } else break;
lpttt->lpszText = (TCHAR *)tip.c_str(); } break; --- snip ---
Notepad++ uses RealChildWindowFromPoint() to retrieve the window handle/object to ask for tooltip text. What basically happens is that the wrong child window is returned from RealChildWindowFromPoint().
If you hover over first two toolbar buttons, "new file" and "open file", the scintilla text editor control HWND is returned (empty editor window). If you hover over third toolbar button "save file" to "formatting" buttons, a splitter container control is returned. If you hover further buttons at the end of toolbar strip, a tab control is returned.
Using the nifty "Winspector" tool (or any other Message Spy tool that can graphically highlight/inspect selected windows at runtime) one can see the problem.
WS_VISIBLE set:
Top level main window "Notepad++ ..": (83,212,1038,871) Rebar/Toolbar strip: (87,254,1034,282)
No WS_VISIBLE set:
Splitter container: (87,254,1034,867) One of the scintilla editor controls: (87,254,187,354) Tab control (hidden, not the one showing editor tab): (568,254,1034,867)
Except the top level main window these are all on same window hierarchy level (child of main) and overlay each other regarding rectangle coordinates.
Code: http://source.winehq.org/git/wine.git/blob/c764210731d4d4b6fda53bf27e2150b70...
--- snip --- 374 /******************************************************************* 375 * RealChildWindowFromPoint (USER32.@) 376 */ 377 HWND WINAPI RealChildWindowFromPoint( HWND hwndParent, POINT pt ) 378 { 379 return ChildWindowFromPointEx( hwndParent, pt, CWP_SKIPTRANSPARENT ); 380 } --- snip ---
Unfortunately WS_VISIBLE is not evaluated until CWP_SKIPINVISIBLE was passed.
Reading the "community" comments section of RealChildWindowFromPoint():
MSDN: http://msdn.microsoft.com/en-us/library/windows/desktop/ms633537.aspx
There is a link to an "The Old New Thing" article: "WindowFromPoint, ChildWindowFromPoint, RealChildWindowFromPoint, when will it all end?"
http://blogs.msdn.com/b/oldnewthing/archive/2010/12/30/10110077.aspx
The table listing the different API functions and their behaviour gives the hint:
It seems RealChildWindowFromPoint() skips "hidden" windows.
Adding CWP_SKIPINVISIBLE to list of flags in RealChildWindowFromPoint() helped. All tooltip texts are now properly shown when hovering mouse over toolbar buttons.
--- quote --- It's okay now in 5.6.2 --- quote ---
DO you really want to know why? Ok, you asked for it ...
They didn't really figure out their problems and used the ultimate hammer: exception handler.
--- snip --- case TTN_GETDISPINFO: { try { LPTOOLTIPTEXT lpttt = (LPTOOLTIPTEXT)notification;
//Joce's fix lpttt->hinst = NULL; POINT p; ::GetCursorPos(&p); ::ScreenToClient(_hSelf, &p); HWND hWin = ::RealChildWindowFromPoint(_hSelf, p); const int tipMaxLen = 1024; static TCHAR docTip[tipMaxLen]; docTip[0] = '\0';
generic_string tipTmp(TEXT("")); int id = int(lpttt->hdr.idFrom);
if (hWin == _rebarTop.getHSelf()) { getNameStrFromCmd(id, tipTmp); if (tipTmp.length() >= 80) return FALSE;
lstrcpy(lpttt->szText, tipTmp.c_str()); return TRUE; } else if (hWin == _mainDocTab.getHSelf()) { BufferID idd = _mainDocTab.getBufferByIndex(id); Buffer * buf = MainFileManager->getBufferByID(idd); tipTmp = buf->getFullPathName();
if (tipTmp.length() >= tipMaxLen) return FALSE; lstrcpy(docTip, tipTmp.c_str()); lpttt->lpszText = docTip; return TRUE; } else if (hWin == _subDocTab.getHSelf()) { BufferID idd = _subDocTab.getBufferByIndex(id); Buffer * buf = MainFileManager->getBufferByID(idd); tipTmp = buf->getFullPathName();
if (tipTmp.length() >= tipMaxLen) return FALSE; lstrcpy(docTip, tipTmp.c_str()); lpttt->lpszText = docTip; return TRUE; } else { return FALSE; } } catch (...) { //printStr(TEXT("ToolTip crash is caught!")); } } break; --- snip ---
It's so bad that my eyes are bleeding.
$ wine --version wine-1.3.37
Regards
http://bugs.winehq.org/show_bug.cgi?id=17370
Anastasius Focht focht@gmx.net changed:
What |Removed |Added ---------------------------------------------------------------------------- Fixed by SHA1| |ea7e9ed2eb7eff90599c578c085 | |f35578c6593f7 Status|NEW |RESOLVED Resolution| |FIXED
--- Comment #5 from Anastasius Focht focht@gmx.net 2012-02-06 15:52:04 CST --- Hello,
this is fixed by commit http://source.winehq.org/git/wine.git/?a=commit;h=ea7e9ed2eb7eff90599c578c08...
Notepad++ unicode now displays tooltips properly ;-) A couple of other apps might be fixed too.
Thanks Dmitry.
Regards
http://bugs.winehq.org/show_bug.cgi?id=17370
Alexandre Julliard julliard@winehq.org changed:
What |Removed |Added ---------------------------------------------------------------------------- Status|RESOLVED |CLOSED
--- Comment #6 from Alexandre Julliard julliard@winehq.org 2012-02-11 13:53:35 CST --- Closing bugs fixed in 1.4-rc3.