Page 1 of 1

How to turn the ListIconGadget into a program launcher

Posted: Mon Mar 17, 2025 9:35 am
by firace
Here's a little program launcher in just a few lines of code.
Select a program using keyboard arrows (or the mouse) and hit Return to launch.

(Obviously this code is just a starting point, with all entries launching winver.exe. Adapt as needed)

Image

Code: Select all

;;; v0.2 - for Windows

genericProgramIcon = ExtractIcon_(#Null, "shell32.dll", 43) ;; 2  

OpenWindow(0, 0, 0, 730, 450, "QuickLauncher", #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_ScreenCentered)

LoadFont(1, "Segoe UI", 16) : SetGadgetFont(-1, FontID(1))

ListIconGadget(1,  10, 20, 710, 410, " ", 54)   
SetGadgetAttribute(1, #PB_ListIcon_DisplayMode , #PB_ListIcon_LargeIcon)
SetGadgetColor(1, #PB_Gadget_BackColor, $FAE6E6) ;; $D9B9B9
SetWindowTheme_(GadgetID(1), @"Explorer", 0)

AddGadgetColumn(1, 1, "Program Path", 0)
SendMessage_(GadgetID(1), #LVM_SETICONSPACING, #Null, 210) ; 

For b = 0 To 15
  AddGadgetItem(1, b, "Program " + b + Chr(10) + "winver.exe", genericProgramIcon)
Next

SetActiveGadget(1) : SetGadgetState(1, 0)

AddKeyboardShortcut(0, #PB_Shortcut_Return, 123)

Procedure LaunchSelected()
  RunProgram(GetGadgetItemText(1, GetGadgetState(1), 1))
EndProcedure   

BindGadgetEvent(1, @LaunchSelected(), #PB_EventType_LeftDoubleClick)
BindEvent(#PB_Event_Menu, @LaunchSelected(), 0, 123)

Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow 

Re: Tiny Program Launchpad

Posted: Mon Mar 17, 2025 11:07 am
by Axolotl
Hi firace,
thanks for sharing.

BTW: Maybe you know this as well: QSel
Unfortunately, Horst no longer seems to be active here or in the german forum.

Re: How to turn the ListIconGadget into a program launcher

Posted: Mon Mar 17, 2025 12:51 pm
by AZJIO
you can take the settings here

Code: Select all

Global hicon = 0
ExtractIconEx_("Shell32.dll", 43, 0, @hicon, 1)
#LIG = 0

OpenWindow(0, 0, 0, 160, 400, "QuickLauncher", #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_ScreenCentered)

ListIconGadget(#LIG,  10, 10, 140, 380, " ", 54)   
SetGadgetAttribute(#LIG, #PB_ListIcon_DisplayMode , #PB_ListIcon_List)
SetGadgetColor(#LIG, #PB_Gadget_BackColor, $FAE6E6) ;; $D9B9B9

AddGadgetColumn(#LIG, 1, "Program Path", 0)

Structure param
	name.s
	path.s
	arg.s
	icon.s
EndStructure

Global NewList exe.param()

For i = 0 To 15
	If AddElement(exe())
		exe()\name = "winver" ; ReadPreferenceString()
		exe()\path = "winver.exe"
		exe()\icon = "winver.exe"
		exe()\arg = ""
	EndIf
Next
i = 0
ForEach exe()
	AddGadgetItem(#LIG, i, exe()\name, hicon)
	SetGadgetItemData(#LIG, i , @exe())
	i + 1
Next


SetActiveGadget(#LIG) : SetGadgetState(#LIG, 0)

AddKeyboardShortcut(0, #PB_Shortcut_Return, 123)

Procedure LaunchSelected()
	Protected *p.param
	ind = GetGadgetState(#LIG)
	If ind <> -1
		*p = GetGadgetItemData(#LIG, ind)
		RunProgram(*p\path)
	EndIf
EndProcedure   

BindGadgetEvent(#LIG, @LaunchSelected(), #PB_EventType_LeftDoubleClick)
BindEvent(#PB_Event_Menu, @LaunchSelected(), 0, 123)

Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow 

Re: How to turn the ListIconGadget into a program launcher

Posted: Mon Mar 17, 2025 2:22 pm
by firace
Thanks AZJIO that's great 8)

Thanks Axolotl, yes I am a big fan of Horst's tools.

Re: How to turn the ListIconGadget into a program launcher

Posted: Mon Mar 17, 2025 4:24 pm
by Axolotl
maybe this would be a nice addition (showing the associated icon instead of the star)

Code: Select all

; ---------------------------------------------------------------------------------------------------------------------

Procedure ExtractIcon(FileName.s, IconIndex, bSmallIcon = #False)  ; HANDLE  // returns > 0 .. valid hIcon 
  Protected ret, hIcon 

  If bSmallIcon = #False 
    ret = ExtractIconEx_(FileName, IconIndex, 0, @hIcon, 1)  ; extract one small Icon, ret should be 1  
  Else 
    ret = ExtractIconEx_(FileName, IconIndex, @hIcon, 0, 1)  ; extract one normal Icon, ret should be 1 
  EndIf 

  If Not ret  ; the return value is the number of icons successfully extracted from the file. 
    Debug #LF$ + #PB_Compiler_Procedure + "(" + FileName + ") - Error: No Icon included.", 9 
    hIcon = 0 
  EndIf 

  ProcedureReturn hIcon  ; return hIcon or ZERO 
EndProcedure 

; ---------------------------------------------------------------------------------------------------------------------

Procedure FreeIcon(hIcon)  ; VOID 
  ;// MSDN: You must destroy all icons extracted by ExtractIconEx by calling the DestroyIcon function. 
  If hIcon <> 0 
    DestroyIcon_(hIcon) 
  EndIf 
EndProcedure 

; ---------------------------------------------------------------------------------------------------------------------

Procedure GetFileAssociatedIcon(ExeName.s, DefaultIcon=0, bSmallIcon=#False)  ; returns hIcon (must be destroyed by DestroyIcon_())  
  Protected flags, shInfo.SHFILEINFO 

  flags = #SHGFI_USEFILEATTRIBUTES | #SHGFI_ICON 
  If bSmallIcon = #False : flags | #SHGFI_LARGEICON 
  Else                   : flags | #SHGFI_SMALLICON 
  EndIf 

  If SHGetFileInfo_(ExeName, #FILE_ATTRIBUTE_NORMAL, @shInfo, SizeOf(SHFILEINFO), flags) 
    ProcedureReturn shInfo\hIcon 
  EndIf 

  ProcedureReturn DefaultIcon  ; failure, defined return value !!! 
EndProcedure 


Re: How to turn the ListIconGadget into a program launcher

Posted: Mon Mar 17, 2025 4:39 pm
by AZJIO
This is my structure for a single executed command.

Code: Select all

Structure btn
	grup.s
	exe.s
	arg.s
	hotkey.s
	url.s
	id.i
	warn.i
	exit.i
	bhide.i
	admin.i
	hide.i
	hicon.i
	himgList.i
EndStructure
As you can see, there are hotkeys, messages, hidden, exit after Enter, and an associated link that can be accessed by holding down a key to find a file on the Internet. There is also an administrator rights flag and a redirect ban flag.

I had the idea to write an analog on ListViewGadget(), but I understand that this is a long job.

I use the list to free up the icons. Since there are a lot of them, you need to add an icon for each button, and then release them in the loop.

Code: Select all

	ForEach BtnLst()
		If BtnLst()\himgList
			ImageList_Destroy_(BtnLst()\himgList)
		EndIf
		If BtnLst()\hicon
			DestroyIcon_(BtnLst()\hicon)
		EndIf
	Next

Re: How to turn the ListIconGadget into a program launcher

Posted: Wed Mar 19, 2025 10:03 am
by firace
Thanks for all the suggestions.
I will leave the original post unchanged (as it is just a prototype) and so users are free to add any extra features as they wish.

Re: How to turn the ListIconGadget into a program launcher

Posted: Wed Mar 19, 2025 10:03 am
by firace
Also working on a dark mode:

Image

Re: How to turn the ListIconGadget into a program launcher

Posted: Wed Mar 19, 2025 1:06 pm
by Axolotl
The original code did not work on my computer.
So I figured out the following hint:
Acc. to MSDN, the LVM_SETICONSPACING message explains this for lParam:
The LOWORD specifies the distance, in pixels, to set between icons on the x-axis. The HIWORD specifies the distance, in pixels, to set between icons on the y-axis.
So I changed your code with this small. (I tried this with different values for Y and X and it worked.)

Code: Select all

Macro MAKELONG(wHiValue, wLoValue) 
  ((wHiValue & $FFFF) << 16) | ((wLoValue) & $FFFF) 
EndMacro 
; .....
;   SendMessage_(GadgetID(1), #LVM_SETICONSPACING, #Null, 210) ; 
    SendMessage_(GadgetID(1), #LVM_SETICONSPACING, #Null, MAKELONG(160, 210)) ;  Y == 80, X == 210 
; .....
;  and to reset to the default spacing use this: 
;   SendMessage_(GadgetID(1), #LVM_SETICONSPACING, #Null, -1)  
; .....