So I finally came up with something like the following:
Code: Select all
#NoEnv
#SingleInstance force
#Warn
; Windows 8.1 64 bit - Autohotkey v1.1.30.01 32-bit Unicode
GUI, New, +LastFound
GUI, Add, Edit, w400 h400
GUI, Show, AutoSize
WS_EX_NOACTIVATE := 0x08000000 ; A top-level window created with this style does not become the foreground window when the user clicks it.
WS_EX_WINDOWEDGE := 0x00000100 ; The window has a border with a raised edge.
WS_EX_TOOLWINDOW := 0x00000080 ; A tool window does not appear in the taskbar or in the dialog that appears when the user presses ALT+TAB.
WS_EX_TOPMOST := 0x00000008 ; The window should be placed above all non-topmost windows and should stay above them, even when the window is deactivated.
WS_EX_PALETTEWINDOW := (WS_EX_WINDOWEDGE | WS_EX_TOOLWINDOW | WS_EX_TOPMOST)
GUI New, % "+Owner" . WinExist()
GUI, +HWNDhGUI +LastFound
DetectHiddenWindows, On
WinSet, Transparent, 215
DetectHiddenWindows, Off
GUI, Margin, 0, 0
GUI +E%WS_EX_PALETTEWINDOW% +E%WS_EX_NOACTIVATE%
GUI, -Caption
GUI, Add, ListBox, x0 y0 w110 h140 +HWNDhListbox, a|b|c|d|e|f|g|h|i|j|k|l|m|n
GUI, Show, AutoSize NoActivate,
WM_MOUSEACTIVATE := 0x0021 ; this message is sent when the cursor is in an inactive window and the user presses a mouse button
OnMessage(WM_MOUSEACTIVATE, Func("__WM_MOUSEACTIVATE").bind(hGUI, hListBox))
return
GuiClose:
ExitApp
__WM_MOUSEACTIVATE(_hGUI, _hListBox, _wParam) {
static MA_ACTIVATE := 1
, MA_NOACTIVATE := 3
, MA_NOACTIVATEANDEAT := 4 ; https://docs.microsoft.com/fr-fr/windows/desktop/inputdev/wm-mouseactivate#return-value
static LB_SETCURSEL := 0x0186 ; https://docs.microsoft.com/fr-fr/windows/desktop/Controls/lb-setcursel (https://github.com/AHK-just-me/AHK_Gui_Constants/blob/master/Sources/Const_ListBox.ahk)
local
Critical
if ((_wParam = _hGUI)) { ; if we're talking about our GUI...
_item := LBEX_ItemFromCursor(_hListBox) ; get the zero-based index of the item nearest the cursor in the list box
if (_item > -1) {
PostMessage % LB_SETCURSEL, % _item, 0,, % "ahk_id " . _hListBox ; update the ListBox's selection
return MA_NOACTIVATEANDEAT ; does not activate the window, and discards the mouse message
} else ; with the design with wich we've endowed our GUI here, this means the cursor is currently hovering over the scroll bar
return MA_NOACTIVATE ; does not activate the window, and does not discard the mouse message
} else return MA_ACTIVATE
}
LBEX_ItemFromCursor(_hListBox) { ; LBEX_ItemFromCursor by 'just me' - https://www.autohotkey.com/boards/viewtopic.php?p=66813#profile66885
static LB_ITEMFROMPOINT := 0x01A9
local
VarSetCapacity(_POINT_, 8, 0) ; POINT structure -> msdn.microsoft.com/en-us/library/dd162805(v=vs.85).aspx
DllCall("GetCursorPos", "Ptr", &_POINT_) ; -> msdn.microsoft.com/en-us/library/ms648390(v=vs.85).aspx
DllCall("ScreenToClient", "Ptr", _hListBox, "Ptr", &_POINT_) ; -> msdn.microsoft.com/en-us/library/dd162952(v=vs.85).aspx
_x := NumGet(_POINT_, 0, "UShort") ; only 16 bits are used by LB_ITEMFROMPOINT
_y := NumGet(_POINT_, 4, "UShort") << 16 ; only 16 bits are used by LB_ITEMFROMPOINT
SendMessage % LB_ITEMFROMPOINT, 0, % (_x + _y),, % "ahk_id " . _hListBox ; LB_ITEMFROMPOINT -> msdn.microsoft.com/en-us/library/bb761323(v=vs.85).aspx
if (ErrorLevel & 0xFFFF0000) ; the HIWORD of the return value is one if the cursor is outside the client area.
return -1
return (ErrorLevel & 0xFFFF) ; the return value contains the 0-based index of the item in the LOWORD.
}
Btw, once again this would not have been imaginable and possible for me without the invaluable working tools available upstream on the forum and shared by '
just me'.