Hello
I'm experiencing some annoying problem while using my PUM menu which is actually owner-drawn popup menu. So i made few investigations and two test scripts trying to figure out the problem. Hope you can help me out.
The problem is:
When you select any item inside popup menu - it just doesn't work, menu not closing itself. You can click few times before it triggered. Other clues and also why i posted this problem as a bug:
- It happens only with owner-drawn popup menus
- It happens only if few timers are active
- It happens VERY RARELY on AHK_L 1.1.5.3 and below and it almost persistent on 1.1.5.4 - 1.1.5.6
Here the scripts to test it out
First script
creates simple NON owner-drawn popup menu, use ALT+D to show the menu and select any item:
Code:
hMenu := MakeSimpleMenu()
SetTimer, timer1, 1000
SetTimer, timer2, 1500
SetTimer, timer3, 2000
return
timer1:
timer2:
timer3:
return
!d::
OnMessage(0x201, "WM_LBUTTONDOWN")
Gui,99:+LastFound +ToolWIndow +HWNDhParent
Gui,99:Show
DllCall("TrackPopupMenuEx"
, "Ptr", hMenu
, "uint", 0x100
, "int", A_ScreenWidth/3
, "int", A_ScreenHeight/3
, "Ptr", hParent
, "Ptr", 0)
return
WM_LBUTTONDOWN(wParam, lParam)
{
tooltip got
return
}
MakeSimpleMenu()
{
hMenu := DllCall( "CreatePopupMenu", "Ptr" )
loop,5
DllCall("InsertMenuW"
,"Ptr", hMenu
,"uint", -1
,"uint", 0x400 ;MF_BYPOSITION
,"uint", A_Index
, "wstr", "item" A_Index )
return hMenu
}
As you can see by testing it: any item you clicking is ALWAYS selected on first click. Also, the WM_LBUTTONDOWN function is never called when you select item.
Second scriptcreates simple owner-drawn popup menu, use ALT+D to show the menu and select any item:
Code:
hMenu := MakeSimpleODMenu()
SetTimer, timer1, 1000
SetTimer, timer2, 1500
SetTimer, timer3, 2000
return
timer1:
timer2:
timer3:
return
!d::
OnMessage(0x201, "WM_LBUTTONDOWN")
Gui,99:+LastFound +ToolWIndow +HWNDhParent
Gui,99:Show
OnMessage( 0x211, "WM_ENTERMENULOOP")
OnMessage( 0x2C, "WM_MEASUREITEM")
OnMessage( 0x2B, "WM_DRAWITEM")
OnMessage( 0x212, "WM_EXITMENULOOP")
DllCall("TrackPopupMenuEx"
, "Ptr", hMenu
, "uint", 0x100
, "int", A_ScreenWidth/3
, "int", A_ScreenHeight/3
, "Ptr", hParent
, "Ptr", 0)
return
WM_LBUTTONDOWN(wParam, lParam)
{
tooltip got
return
}
MakeSimpleODMenu()
{
hMenu := DllCall( "CreatePopupMenu", "Ptr" )
loop,5
DllCall("InsertMenuW"
,"Ptr", hMenu
,"uint", -1
,"uint", 0x400 | 0x100 ;MF_BYPOSITION | MF_OWNERDRAW
,"uint", A_Index
, "ptr", 0 )
return hMenu
}
WM_ENTERMENULOOP()
{
return 0
}
WM_EXITMENULOOP()
{
return 0
}
WM_MEASUREITEM( wParam, lParam, msg, hwnd )
{
if ( wParam != 0 ) ;not a menu
return
NumPut( 50, lParam+0, 12, "UInt" )
NumPut( 30, lParam+0, 16, "UInt" )
Return True
}
WM_DRAWITEM( wParam, lParam, msg, hwnd )
{
if ( wParam != 0 ) ;means the message not for menu
return
itemAction := NumGet( lParam + 0, 12, "UInt" )
hDC := NumGet( lParam + 0, 16 + 2 * A_PtrSize, "UPtr" )
pRECT := lParam + 16 + 3 * A_PtrSize
if ( itemAction = 1 ) ; ODA_DRAWENTIRE
{
DllCall( "DrawTextExW"
,"Ptr", hDC
, "wstr", "item"
, "Uint", -1
, "Ptr", pRECT
, "Uint", 0x4 | 0x20 | 0x100 ;DT_VCENTER | DT_SINGLELINE | DT_NOCLIP
, "Ptr", 0 )
}
return True
}
By testing this script you will see that clicking an item in the menu sometimes not works and WM_LBUTTONDOWN function called instead.
Also, if you'll comment/delete this timers lines:
Code:
SetTimer, timer1, 1000
SetTimer, timer2, 1500
SetTimer, timer3, 2000
it will works just perfect
Any way it can be solved?