Change window icon (via ExtractIconA) using Incbin?

Started by chalky, September 30, 2018, 13:42:13

Previous topic - Next topic

chalky

I am using ExtractIconA and SendMessageA to change several window icons at runtime. Although this is working fine, the icons seem to have to be on disk as ExtractIconA doesn't have any effect if I specify an IncBin'd icon file. Is there a way round this or do I have to write all my IncBin'd icons to a temp location for ExtractIconA each time my application runs?

GW

Do you need to change the icon at runtime or do you want to embed the icon in the application?

chalky

#2
Both. I have multiple windows in a large desktop application - all of which need to have their own window icon. Ideally I would embed them all (i.e. Incbin them) into the exe then use ExtractIconA to add them to each window at runtime. Unfortunately ExtractIconA works with files on disk, but fails if I target Incbin'd ones, so it looks like I need to write the icons to disk first, then ExtractIconA them from there - although not having to do that would be preferrable...


chalky

Thanks for the link. I already know how to change a window icon and had previously found the example you posted - but it seems to be for the 'main' application icon only and I could not figure out how to modify it for multiple icons/windows.

I have now worked out a way to do what I want from Incbin'd icon files by writing them to disk before calling ExtractIconA using the following (posted in case anyone else might find it useful):

SuperStrict

Import maxgui.Drivers
Import maxgui.xpmanifest

Incbin "Icons/Icon1.ico"
Incbin "Icons/Icon2.ico"

Extern "win32"
  Function ExtractIconA:Int(hWnd:Int,File$z,Index:Int)
End Extern

Function SetWindowIcon(fIn:String,tPath:String,wHandle:Int) 
  Local fOut:String
  Local fOD:TStream
  ' extract IncBin'd iconfile to disk
  Local iPtr:Byte Ptr=IncbinPtr(fIn)
  Local iLen:Long=IncbinLen(fIn)
  Local iDat:String=String.FromBytes(iPtr,iLen)
  If iDat Then
    fOut=tPath+"/"+StripDir(fIn)
    fOD=WriteFile(fOut)
    If fOD Then
      WriteString(fOD,iDat)
      CloseStream(fOD)
    EndIf
    ' attach saved iconfile to window
    Local Icon:Int=ExtractIconA(wHandle,fOut,0)
    Local WM_SETICON:Int=$80
    Local ICON_SMALL:Int=0
    Local ICON_BIG:Int=1
    SendMessageA(wHandle,WM_SETICON,ICON_BIG,Icon)
    DeleteFile(fOut)
  EndIf
End Function

'---------------------------------------------------------------

Local window1:TGadget=CreateWindow("Window 1",0,0,640,480,Null,WINDOW_TITLEBAR|WINDOW_CENTER)
Local window2:TGadget=CreateWindow("Window 2",0,0,640,480,Null,WINDOW_TITLEBAR|WINDOW_CENTER)

SetWindowIcon("Icons/Icon1.ico",AppDir,QueryGadget(window1,QUERY_HWND))
SetWindowIcon("Icons/Icon2.ico",AppDir,QueryGadget(window2,QUERY_HWND))

Repeat
  PollEvent()
  If EventID() Then
    Select EventID()
      Case EVENT_WINDOWCLOSE
        Exit
    EndSelect
  EndIf
  Delay 1
Forever