I used SetWinEventHook with the event EVENT_OBJECT_SELECTION.
To paint the delete icon I used either TextOut or DrawIconEx (icon in Win7/8).
Code: Select all
#SingleInstance force
Menu, Tray, Icon, shell32.dll, 3
Menu, Tray, Add, Exit , Close
Menu, Tray, Default, Exit
SetWinDelay, -1
SetControlDelay, -1
global del_ico:=0 ; 0= text "X", 1= icon
global objListIDs:= Object()
global single_ico:=0
global List_id, List_id_2, GuiHwnd
Gui,1: +HWNDGuiHwnd
Gui,1:Font, S10 CDefault , Segoe UI
Gui,1:Font, S10 , Segoe UI
queries:="1note|2note|3note|4note|5note|6note|7note|8note|11note|12note|13note|14note"
Gui,1:Add, ComboBox, x50 y40 +HWNDList_id vqueryList , %queries% ;gCombo
fn := Func("List_Func").Bind(List_id)
GuiControl, +g, % List_id, % fn
Gui,1:Add, ComboBox, x50 y100 +HWNDList_id_2 vqueryList_2 , %queries%|2note|3note|4note|5note ;gCombo
fn := Func("List_Func").Bind(List_id_2)
GuiControl, +g, % List_id_2, % fn
Gui 1:Show, w300 h200 , Test_Drozd
Gosub, Combo_WinEvent
return
;====================================================
List_Func(hwnd, win){
global Win_ID, Gui1_Id, List__
del:=ComboDel(hwnd)
if(del==1)
return
}
ComboDel(hwnd){
VarSetCapacity(POINT,8,0)
DllCall("GetCursorPos","Ptr",&POINT)
DllCall("ScreenToClient","Ptr",hwnd,"Ptr",&POINT)
x:=NumGet(POINT,0,"Int")
y:=NumGet(POINT,4,"Int")
GuiControlGet, Pos, Pos, %hwnd%
GuiControlGet, item_,, %hwnd%
if(PosW-x<20){
MsgBox, 0x00040003, , Do you want to delete this item? `n%item_% ;+100 "No" as default
IfMsgBox, No
return 1
IfMsgBox Cancel
return 1
GuiControl, +AltSubmit, %hwnd%
GuiControlGet, line_,, %hwnd%
Control, Delete, %line_%,, ahk_id %hwnd%
GuiControl, -AltSubmit, %hwnd%
;ToolTip_("Deleted item:" "`n" item_ , 1)
;del_in_ini(item_)
return 1
}
return 0
}
;====================================================
WinProcCallback(hWinEventHook, event, hwnd, idObject, idChild, dwEventThread, dwmsEventTime){
Critical
if !hwnd
return
event:=Format("0x{1:x}",event) ; decimal to hexadecimal
hwnd:=Format("0x{1:x}",hwnd)
;EVENT_OBJECT_REORDER:= 0x8004, EVENT_OBJECT_FOCUS:= 0x8005, EVENT_OBJECT_SELECTION:= 0x8006
if(event=0x8006){ ;EVENT_OBJECT_SELECTION
del_icons(hwnd,del_ico)
return 0
}
}
UnhookWinEvent(hWinEventHook){
DllCall("UnhookWinEvent", "Ptr",hWinEventHook)
DllCall("CoUninitialize")
}
;====================================================
Combo_WinEvent:
EVENT_OBJECT_REORDER:= 0x8004, EVENT_OBJECT_FOCUS:= 0x8005, EVENT_OBJECT_SELECTION:= 0x8006
global CB_EditID , CB_ListID
CtrlHwnd:=List_id
VarSetCapacity(CB_info, 40 + (3 * A_PtrSize), 0)
NumPut(40 + (3 * A_PtrSize), CB_info, 0, "UInt")
DllCall("User32.dll\GetComboBoxInfo", "Ptr", CtrlHwnd, "Ptr", &CB_info)
CB_EditID := NumGet(CB_info, 40 + A_PtrSize, "Ptr") ;48/44
CB_ListID := NumGet(CB_info, 40 + (2 * A_PtrSize), "Ptr") ; 56/48
CB_EditID:=Format("0x{1:x}",CB_EditID) , CB_ListID:=Format("0x{1:x}",CB_ListID)
GuiHwnd_:=CB_ListID
ThreadId := DllCall("GetWindowThreadProcessId", "Int", GuiHwnd_, "UInt*", PID)
EventHook:=DllCall("SetWinEventHook","UInt",0x8006,"UInt",0x8006,"Ptr",0,"Ptr"
,RegisterCallback("WinProcCallback") ,"UInt", PID,"UInt", ThreadId,"UInt", 0)
OnExit(Func("UnhookWinEvent").Bind(EventHook))
objListIDs[CB_ListID]:=List_id
;---
CtrlHwnd:=List_id_2
DllCall("User32.dll\GetComboBoxInfo", "Ptr", CtrlHwnd, "Ptr", &CB_info)
CB_ListID_2 := NumGet(CB_info, 40 + (2 * A_PtrSize), "Ptr") ; 56/48
CB_ListID_2:=Format("0x{1:x}",CB_ListID_2)
GuiHwnd_:=CB_ListID_2
ThreadId_2 := DllCall("GetWindowThreadProcessId", "Int", GuiHwnd_, "UInt*", PID2) ; LPDWORD
EventHook_2:=DllCall("SetWinEventHook","UInt",0x8006,"UInt",0x8006,"Ptr",0,"Ptr"
,RegisterCallback("WinProcCallback"),"UInt", PID2,"UInt", ThreadId_2,"UInt", 0) ; from this
OnExit(Func("UnhookWinEvent").Bind(EventHook_2))
objListIDs[CB_ListID_2]:=List_id_2
return
;====================================================
del_icons(CB_ListID,del_ico:=0){
List_id:=objListIDs[CB_ListID]
SendMessage,0x0146,0,0, ,% "ahk_id " List_id ;CB_GETCOUNT:= 0x0146
len:=ErrorLevel
WinGetPos, ,,, CB_height, ahk_id %CB_ListID%
row_height2:=CB_height/len
SendMessage,0x0154,1,0, ,% "ahk_id " List_id ;CB_GETITEMHEIGHT:= 0x0154
row_height:= ErrorLevel
if(List_id=List_id_2){
iconOnWin(CB_ListID,len,row_height)
}else{
if(del_ico)
iconOnWin(CB_ListID,len,row_height)
else
textOnWin(CB_ListID,len,row_height,"X")
}
}
textOnWin(hwnd, len,row_h,text_:="X"){ ;% Chr(215) × "X"
hDC := DllCall("User32.dll\GetDC", "Ptr", hwnd)
WinGetPos, x, y, W, H, ahk_id %hwnd%
x:=W-12,y:=0
heightF:=12 , weight:=400,fontName:="Arial" ;"Segoe Print"
widthF:=6
hFont:=DllCall("CreateFont", "Int", heightF,"Int",widthF, "Int", 0, "Int", 0,"Int", weight, "Uint", 0,"Uint", 0,"uint", 0, "Uint", 0, "Uint", 0, "Uint", 0, "Uint", 0, "Uint", 0, "str", fontName)
DllCall("SelectObject", "UPtr", hDC, "UPtr", hFont, "UPtr")
colorR:=0x0000BB
colorG:=0xAFAFAF
VarSetCapacity(POINT,8,0)
DllCall("GetCursorPos","Ptr",&POINT)
DllCall("ScreenToClient","Ptr",hwnd,"Ptr",&POINT)
PosX:=NumGet(POINT,0,"Int"), PosY:=NumGet(POINT,4,"Int")
colorR:=0x0000EE
m:=2
y:=m
Loop, % len {
if(PosY>=y-m && PosY<y+row_h-m){
DllCall("SetTextColor", "UPtr", hDC, "UInt",colorR )
DllCall("SetBkMode","Ptr",hDC,"Int",1) ;TRANSPARENT := 1
DllCall("TextOut", "uint",hDC, "int",x, "int",y, "str",text_, "int",StrLen(text_))
}else{
if(!single_ico && !del_ico){
DllCall("SetTextColor", "UPtr", hDC, "UInt",colorG )
DllCall("SetBkMode","Ptr",hDC,"Int",1) ;TRANSPARENT := 1
DllCall("TextOut", "uint",hDC, "int",x, "int",y, "str",text_, "int",StrLen(text_))
}
}
y+=row_h
}
DllCall("DeleteObject", "UPtr", hFont)
DllCall("ReleaseDC", "Uint", hwnd, "Uint", hDC)
}
;==============================================
iconOnWin(hwnd,len,row_h){
;hIcon:=LoadPicture("C:\AutoHotkey Scripts\icons\test\Close_16x16.ico","",ImageType)
;hIcon:=LoadPicture("shell32.dll","Icon132 w16 h-1" ,ImageType) ;
hIcon:=LoadPicture("imageres.dll","Icon162 w16 h-1" ,ImageType) ; Win7,8
hDC := DllCall("User32.dll\GetDC", "Ptr", hwnd)
WinGetPos, x, y, W, H, ahk_id %hwnd%
x:=W-18,y:=0
VarSetCapacity(POINT,8,0)
DllCall("GetCursorPos","Ptr",&POINT)
DllCall("ScreenToClient","Ptr",hwnd,"Ptr",&POINT)
PosX:=NumGet(POINT,0,"Int"), PosY:=NumGet(POINT,4,"Int")
cxWidth:=cyWidth:=0
m:=0
y:=m
Loop, % len {
if(PosY>=y-m && PosY<y+row_h-m){
RC:=DllCall("DrawIconEx","Ptr",hDC,"Int",x ,"Int",y ,"Ptr",hIcon ,"Int",cxWidth ,"Int",cyWidth ,"UInt",0 ,"Ptr",0,"UInt",0x3)
}
y+=row_h
}
DllCall("ReleaseDC", "Uint", CtrlHwnd, "Uint", hDC)
}
;====================================================
GuiClose:
Close:
Esc::
ExitApp