Page 1 of 1

Messagebox with custom icon from any EXE or DLL (Windows)

Posted: Sat Dec 03, 2016 3:47 pm
by RASHAD
PB x86 & x64

Code: Select all

#MB_USERICON = $00000080
Global NewList IconGroupID(),msg.MSGBOXPARAMS,LibHandle,LibName$

Procedure EnumResNameProc(ResHandle, ResType, ResName, AppParam)
  AddElement(IconGroupID())
  IconGroupID() = ResName
  ProcedureReturn #True
EndProcedure

Procedure EnumResTypeProc(ResHandle, ResType, AppParam)
  If ResType = #RT_GROUP_ICON
      EnumResourceNames_(ResHandle, ResType, @EnumResNameProc(), 0)
  EndIf
  ProcedureReturn #True
EndProcedure

Procedure Icon_index(LibName$)
  LibHandle = LoadLibraryEx_(@LibName$, 0, #LOAD_LIBRARY_AS_DATAFILE)
  If LibHandle = 0
      MessageRequester("Error", "Unable to load library " + LibName$, #MB_ICONERROR)
      End
  EndIf
  EnumResourceTypes_(LibHandle, @EnumResTypeProc(), 0)
  ForEach IconGroupID()
      *GrpIconDir = LoadResource_(LibHandle, FindResource_(LibHandle, IconGroupID(), #RT_GROUP_ICON))
      Debug " Index "+Str(item)+" = "+Str(IconGroupID())
      item + 1
  Next
EndProcedure

LibName$ = "regedit.exe"
Icon_index(LibName$)

Lastindex = ListSize(IconGroupID()) - 1
SelectElement(IconGroupID(), 0)  ;Select any available index (from 0 to Lastindex)

With msg
  \cbSize = SizeOf(MSGBOXPARAMS)
  \hwndOwner = GetForegroundWindow_()
  \hInstance = LibHandle
  \lpszText = @"Text"
  \lpszCaption = @"Title"
  \dwStyle = #MB_USERICON | #MB_YESNO
  \lpszIcon = IconGroupID()
EndWith
MessageBoxIndirect_(@msg)
FreeLibrary_(LibHandle)

Re: Messagebox with custom icon from any EXE or DLL (Window

Posted: Sat Dec 03, 2016 5:38 pm
by kvitaliy
Thank you, useful code!

Re: Messagebox with custom icon from any EXE or DLL (Window

Posted: Sat Dec 03, 2016 9:28 pm
by Kwai chang caine
Cool, works great on W10
Thanks rashad 8)

Re: Messagebox with custom icon from any EXE or DLL (Window

Posted: Sun Dec 04, 2016 1:31 am
by RASHAD
@kvitaliy
Thanks mate and it is a good opportunity to say thank you for the imitation coal drawing effect

@KCC
Thanks mate

Using Array instead of List
Much faster and easy to use

Code: Select all

#MB_USERICON = $00000080
Global Dim IconGroupID(0),msg.MSGBOXPARAMS,LibHandle,LibName$,item

Procedure EnumResNameProc(ResHandle, ResType, ResName, AppParam)
  IconGroupID(item) = ResName
  item + 1
  ReDim IconGroupID(item)
  ProcedureReturn #True
EndProcedure

Procedure EnumResTypeProc(ResHandle, ResType, AppParam)
  If ResType = #RT_GROUP_ICON
      EnumResourceNames_(ResHandle, ResType, @EnumResNameProc(), 0)
  EndIf
  ProcedureReturn #True
EndProcedure

Procedure Icon_index(LibName$)
  LibHandle = LoadLibraryEx_(@LibName$, 0, #LOAD_LIBRARY_AS_DATAFILE)
  If LibHandle = 0
      MessageRequester("Error", "Unable to load library " + LibName$, #MB_ICONERROR)
      End
  EndIf
  EnumResourceTypes_(LibHandle, @EnumResTypeProc(), 0)
  For item = 0 To ArraySize(IconGroupID())-1
      *GrpIconDir = LoadResource_(LibHandle, FindResource_(LibHandle, IconGroupID(item), #RT_GROUP_ICON))
      Debug " Index "+Str(item)+" = "+Str(IconGroupID(item))
  Next
EndProcedure

LibName$ = "explorer.exe"
Icon_index(LibName$)

With msg
  \cbSize = SizeOf(msg)
  \hwndOwner = GetForegroundWindow_()
  \hInstance = LibHandle
  \lpszText = @"Text"
  \lpszCaption = @"Title"
  \dwStyle = #MB_USERICON | #MB_YESNO
  \lpszIcon = IconGroupID(0)
EndWith
MessageBoxIndirect_(@msg)
FreeLibrary_(LibHandle)

Re: Messagebox with custom icon from any EXE or DLL (Window

Posted: Sun Dec 04, 2016 8:49 am
by uweb
Thank you RASHAD!
But with explorer.exe only icons above Index 0 are visible here (Win7 x64 PB 5.5).
Index 0 = 5471848
Index 1 = 101
Index 2 = 102
Index 3 = 103
Index 4 = 104
Index 5 = 107
Index 6 = 108
Index 7 = 109
Index 8 = 110
Index 9 = 111
Index 10 = 205
Index 11 = 250
Index 12 = 251
Index 13 = 252
Index 14 = 253
Index 15 = 254
Index 16 = 256
Index 17 = 257
Index 18 = 258
Index 19 = 259
Index 20 = 260
Index 21 = 261
Index 22 = 262
Index 23 = 500
Index 24 = 501

Re: Messagebox with custom icon from any EXE or DLL (Window

Posted: Sun Dec 04, 2016 11:53 am
by RASHAD
@uweb
Hi
Thanks for pointing out this bug
Please check
Edit : Compile in Unicode mode (ex PB 5.50)

Code: Select all

#MB_USERICON = $00000080
Global Dim IconGroupID.s(0),msg.MSGBOXPARAMS,LibHandle,LibName$,item

Procedure EnumResNameProc(ResHandle, ResType, ResName, AppParam)
  If ResName & $FFFF0000
    IconGroupID(item) = PeekS(ResName)
  Else 
    IconGroupID(item) = Str(ResName)
  EndIf
  item + 1
  ReDim IconGroupID(item)
  ProcedureReturn #True
EndProcedure

Procedure EnumResTypeProc(ResHandle, ResType, AppParam)
  If ResType = #RT_GROUP_ICON
      EnumResourceNames_(ResHandle, ResType, @EnumResNameProc(), 0)
  EndIf
  ProcedureReturn #True
EndProcedure

Procedure Icon_index(LibName$)
  LibHandle = LoadLibraryEx_(@LibName$, 0, #LOAD_LIBRARY_AS_DATAFILE)
  If LibHandle = 0
      MessageRequester("Error", "Unable to load library " + LibName$, #MB_ICONERROR)
      End
  EndIf
  EnumResourceTypes_(LibHandle, @EnumResTypeProc(), 0)
  For item = 0 To ArraySize(IconGroupID())-1
      *GrpIconDir = LoadResource_(LibHandle, FindResource_(LibHandle, IconGroupID(item), #RT_GROUP_ICON))
      Debug " Index "+Str(item)+" = "+ IconGroupID(item)
  Next
EndProcedure

LibName$ = "Explorer.exe"

Icon_index(LibName$)

;***************** Change the displayed icon index here ***************

ico.s = IconGroupID(0)

;***************************************************************
If ico = ""
  MessageRequester("Error","No such icon !",#MB_OK|#MB_ICONINFORMATION)
  End
Else
  iico = 0
  For i = 1 To Len(ico)
    If Asc(Mid(ico, i ,1)) > 57
       iico = 1
       Break
    EndIf
  Next
EndIf

With msg
  \cbSize = SizeOf(msg)
  \hwndOwner = GetForegroundWindow_()
  \hInstance = LibHandle
  \lpszText = @"Text"
  \lpszCaption = @"Title"
  \dwStyle = #MB_USERICON | #MB_YESNO
  If iico = 1
    \lpszIcon = @ico
  Else
    \lpszIcon = ValD(ico)
  EndIf
EndWith
MessageBoxIndirect_(@msg)
FreeLibrary_(LibHandle)
Edit :Modified for better performance

Re: Messagebox with custom icon from any EXE or DLL (Window

Posted: Sun Dec 04, 2016 5:53 pm
by uweb
Now it works fine. Thank you!