Retrieving Another Windows Icon For MenuItem Icon...

Just starting out? Need help? Post your questions and find answers here.
User avatar
Teddy Rogers
User
User
Posts: 98
Joined: Sun Feb 23, 2014 2:05 am
Location: Australia
Contact:

Retrieving Another Windows Icon For MenuItem Icon...

Post 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.
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8451
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Re: Retrieving Another Windows Icon For MenuItem Icon...

Post 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
Image
BERESHEIT
User avatar
Teddy Rogers
User
User
Posts: 98
Joined: Sun Feb 23, 2014 2:05 am
Location: Australia
Contact:

Re: Retrieving Another Windows Icon For MenuItem Icon...

Post 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 :oops:

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.
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4954
Joined: Sun Apr 12, 2009 6:27 am

Re: Retrieving Another Windows Icon For MenuItem Icon...

Post 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  
Egypt my love
User avatar
Teddy Rogers
User
User
Posts: 98
Joined: Sun Feb 23, 2014 2:05 am
Location: Australia
Contact:

Re: Retrieving Another Windows Icon For MenuItem Icon...

Post 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.
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8451
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Re: Retrieving Another Windows Icon For MenuItem Icon...

Post by netmaestro »

#ICON_SMALL2 = 2 so just define the constant yourself if PureBasic doesn't know it, then you can try again.
BERESHEIT
User avatar
Teddy Rogers
User
User
Posts: 98
Joined: Sun Feb 23, 2014 2:05 am
Location: Australia
Contact:

Re: Retrieving Another Windows Icon For MenuItem Icon...

Post 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.
Post Reply