Page 1 of 1
Retrieving Another Windows Icon For MenuItem Icon...
Posted: Sat Mar 01, 2014 8:05 am
by Teddy Rogers
Pretty much as the title describes, I am trying to get #GCL_HICON from a specific window and reuse it as a MenuItem icon. I was hoping it would be as simple as something like this snipped section of code...
Code: Select all
hIcon1=GetClassLong_(hWnd,#GCL_HICON)
hIcon2=LoadIcon_(0,#IDI_QUESTION)
temp=CopyImage_(hIcon1,#IMAGE_ICON,0,0,#LR_COPYFROMRESOURCE)
MenuItem(4, "Test1", hIcon2)
MenuItem(5, "Test2", temp)
...but it does not work. I've tried multiple methods all failed. I can retrieve an icon from any other window and redraw it in my own window but I can't get it as a MenuItem icon. I also tried #GCL_HICONSM without any joy. Any guidance would be greatly appreciated...
Ted.
Re: Retrieving Another Windows Icon For MenuItem Icon...
Posted: Sat Mar 01, 2014 8:50 am
by netmaestro
This is working here, you might have to change the search text for FindWindow:
Code: Select all
hwnd = FindWindow_(0, "PureBasic 5.22 LTS (x86)")
hIcon = GetClassLongPtr_(hwnd, #GCL_HICON)
CreateImage(0, 32,32, 32, #PB_Image_Transparent)
hdc = StartDrawing(ImageOutput(0))
DrawIconEx_(hdc,0,0,hIcon,32,32,0,0,#DI_COMPAT|#DI_NORMAL)
StopDrawing()
OpenWindow(0,0,0,320,240,"",#PB_Window_SystemMenu|#PB_Window_ScreenCentered)
ImageGadget(0,45,30,0,0,ImageID(0))
CreatePopupImageMenu(0)
MenuItem(1, "PureBasic 5.22 LTS", hIcon)
Repeat
ev=WaitWindowEvent()
Select ev
Case #PB_Event_RightClick
DisplayPopupMenu(0, WindowID(0))
EndSelect
Until ev = #PB_Event_CloseWindow

Re: Retrieving Another Windows Icon For MenuItem Icon...
Posted: Sat Mar 01, 2014 9:20 am
by Teddy Rogers
Ha! I figured where I was going wrong. I was calling a procedure for finding the window handle and strings I wanted and lost the handle for that window in proceeding code. I should have tested it really simply before posting
Code: Select all
hwnd = FindWindow_(0, "PureBasic 5.21 LTS (x64)")
hIcon = GetClassLong_(hwnd, #GCL_HICON)
MenuItem(5, "Test", hIcon)
Works perfectly fine like that. What a waste of hours, been trying all sorts of methods! Thank you for the help...
Ted.
Re: Retrieving Another Windows Icon For MenuItem Icon...
Posted: Sat Mar 01, 2014 9:22 am
by RASHAD
Hi
Code: Select all
Result = RunProgram("notepad","","",#PB_Program_Open)
Repeat
hWnd = FindWindow_(0,"Untitled - Notepad")
Until hWnd
If hWnd
hIcon = GetClassLong_(hWnd,#GCL_HICON)
EndIf
CreateImage(0,32,32,32)
StartDrawing(ImageOutput(0))
DrawingMode(#PB_2DDrawing_AllChannels)
DrawImage(hIcon,0,0,32,32)
StopDrawing()
KillProgram(Result)
If OpenWindow(0, 100, 150, 195, 260, "PureBasic - Menu")
If CreateMenu(0, WindowID(0))
MenuTitle("File")
MenuItem( 1, "&Load...")
MenuItem( 2, "Save")
MenuItem( 3, "Save As...")
MenuBar()
OpenSubMenu("Recents")
MenuItem( 5, "Pure.png")
MenuItem( 6, "Basic.jpg")
OpenSubMenu("Even more !")
MenuItem( 12, "Yeah")
CloseSubMenu()
MenuItem( 13, "Rocks.tga")
CloseSubMenu()
MenuBar()
MenuItem( 7, "&Quit")
MenuTitle("Edition")
MenuItem( 8, "Cut")
MenuItem( 9, "Copy")
MenuItem(10, "Paste")
MenuTitle("?")
MenuItem(11, "About")
EndIf
SetMenuItemBitmaps_(MenuID(0), 1 , #MF_BYCOMMAND, ImageID(0), 0)
SetMenuItemBitmaps_(MenuID(0), 3 , #MF_BYCOMMAND, ImageID(0), 0)
Repeat
Select WaitWindowEvent()
Case #PB_Event_Menu
Select EventMenu() ; To see which menu has been selected
Case 11 ; About
MessageRequester("About", "Cool Menu example", 0)
Default
MessageRequester("Info", "MenuItem: "+Str(EventMenu()), 0)
EndSelect
Case #PB_Event_CloseWindow
Quit = 1
EndSelect
Until Quit = 1
EndIf
End
Re: Retrieving Another Windows Icon For MenuItem Icon...
Posted: Sat Mar 01, 2014 5:34 pm
by Teddy Rogers
I have been experimenting different methods with PureBasic for retrieving a windows icon as not all icons can be obtained using
GetClassLongPtr_. I tried using
SendMessge_ but parameter
#ICON_SMALL2 is not recognised. Does anyone know if its supported in some manner?
Code: Select all
hIcon = SendMessage_(hWnd, #WM_GETICON, #ICON_SMALL2, 0)
http://msdn.microsoft.com/en-us/library ... 85%29.aspx
For whatever reason I've also not had much joy using...
Code: Select all
hIcon = SendMessageTimeout_(hWnd, #WM_GETICON, 0, 0, #SMTO_ABORTIFHUNG, 1000, dwError)
Ted.
Re: Retrieving Another Windows Icon For MenuItem Icon...
Posted: Sat Mar 01, 2014 6:14 pm
by netmaestro
#ICON_SMALL2 = 2 so just define the constant yourself if PureBasic doesn't know it, then you can try again.
Re: Retrieving Another Windows Icon For MenuItem Icon...
Posted: Sun Mar 02, 2014 2:32 pm
by Teddy Rogers
I tried using a constant like this but didn't have any success in getting this to return any results...
Code: Select all
hIcon = SendMessage_(hWnd, #WM_GETICON, 2, 0)
However I made some more changes, possibly the code below will be useful to someone else. If the window icon is returning null, as is the case for µTorrent 3.3.2, using
GetClassLongPtr_(hWnd, #GCL_HICON) then I have retrieved the filename icon instead. I borrowed some of this code from Rescator, from the following link, thank you!
http://www.purebasic.fr/english/viewtop ... 12&t=35655&
Code: Select all
Declare Main()
Main()
; Retrieve the icon from the file path
Procedure.l ExtractIconFile(IconPath.s)
hImageList = SHGetFileInfo_(IconPath, 0, @FileInfo.SHFILEINFO, SizeOf(SHFILEINFO), #SHGFI_ICON | #SHGFI_SMALLICON | #SHGFI_USEFILEATTRIBUTES)
ProcedureReturn FileInfo\hIcon
EndProcedure
; Retrieve the filename and path from the window handle (IMPORTANT! Set in compiler options to unicode executable)
Procedure.s ProcessNameFromHwnd(hWnd)
Protected processid.l,psapilib.l,processname$,GetModuleFileNameEx,hprocess.l
psapilib=OpenLibrary(#PB_Any,"psapi.dll")
If psapilib
GetModuleFileNameEx=GetFunction(psapilib,"GetModuleFileNameExW") ; Unicode path names only!
If GetModuleFileNameEx
If GetWindowThreadProcessId_(hwnd,@processid)
hprocess=OpenProcess_(#PROCESS_QUERY_INFORMATION|#PROCESS_VM_READ,#Null,processid)
If hprocess
processname$=Space(#MAX_PATH)
If Not CallFunctionFast(GetModuleFileNameEx,hprocess,#Null,@processname$,#MAX_PATH)
processname$=""
EndIf
CloseHandle_(hprocess)
EndIf
EndIf
EndIf
CloseLibrary(psapilib)
EndIf
ProcedureReturn processname$
EndProcedure
; Our main routine; open window, find the window (by title), get the file path, extract icon, update window with the new icon
Procedure Main()
OpenWindow(0, 0, 0, 100, 100, "Test", #PB_Window_ScreenCentered | #PB_Window_SystemMenu)
UseGadgetList(WindowID(0))
Define hwnd.i,processname$
hWnd=FindWindow_(0,"µTorrent 3.3.2")
processname$=ProcessNameFromHwnd(hWnd)
; This is here just to display what actual path and filename is retrieved...
If processname$<>""
Debug "Filename: "+#DQUOTE$+processname$+#DQUOTE$
EndIf
; Get file icon from the directory path and update window
Icon = ExtractIconFile(processname$) ; 3944 (+2568 Arg)
ImageGadget(0, 0, 0, 32, 32, Icon) ; 3984
SendMessage_(WindowID(0), #WM_SETICON, 1, Icon)
DestroyIcon_(Icon)
Repeat
Event = WaitWindowEvent()
Until Event = #PB_Event_CloseWindow
EndProcedure
Ted.