Hi Mistrel,
the right way is to enumerate resource.
Here a quick try, but be carrefull using API CreateIconFromResource_() wich use API CreateIconFromResourceEx()
The CreateIconFromResource function calls CreateIconFromResourceEx passing LR_DEFAULTSIZE|LR_SHARED as flags.
May be it could erase system icon.
following use 2 callback, the first one to count Icon and the second to load the correct icon using its position (not Icon ID)
ddores.dll has 147 Icon groups and 1066 icons.
Code: Select all
EnableExplicit
;- Enumeration
Enumeration
#GadgetButtonImage
EndEnumeration
#StartOfErrors = 1
Enumeration #StartOfErrors
#ErrorCode_No_Error
; Callback error
#error_BadCallbackParameter
#error_FindResource_Fails
#error_LoadResource_Fails
#error_BadIconIndex
#error_sizeOfResource_Fails
#error_CreateIconFromResource_Fails
;
#error_100
#error_101
EndEnumeration
#Stop_Enumeration = #False
#Continue_Enumeration = #True
#Return_Error = 0
#Return_No_Error = 1
#IntegerIdentifier = 0
Declare SetlastError(Error_Code)
;-' Macros
Macro _StopEnumeration_With_Error(Error_Code)
SetlastError(Error_Code)
ProcedureReturn #Stop_Enumeration
EndMacro
Macro _StopEnumeration_With_No_Error()
SetlastError(#ErrorCode_No_Error)
ProcedureReturn #Stop_Enumeration
EndMacro
Macro _ContinueEnumeration__With__No_Error()
ProcedureReturn #Continue_Enumeration
EndMacro
Macro _ExitProcedure_With_Error(Error_Code)
SetlastError(Error_Code)
ProcedureReturn #Return_Error
EndMacro
Macro _Reset_ErrorCode()
SetlastError(#ErrorCode_No_Error)
EndMacro
;- Structures
Structure iconGroupsNumber
;// nombre d'icônes pour le comptage courant/Icon number for the current count
iconNumber.i
EndStructure
Structure GetIcon
;// Numéro de l'icône à trouver/Icon number to find
iconPositionToFind.i
;// Numéro de l'icône courrante/current Icon number
currentIconPosition.i
;// Id de l'icône/Icon id
*icon
EndStructure
;- Global var
;// erreur courante/current error
Global g_LastErrorCode
;-
Procedure.i Callback_CountIcon(*hModule, resType, ResName, *resourceInfos.iconGroupsNumber)
; https://docs.microsoft.com/fr-fr/previous-versions/windows/desktop/legacy/ms648034(v=vs.85)
; EnumResNameProc callback function
; BOOL CALLBACK EnumResNameProc(
; _In_opt_ HMODULE hModule,
; _In_ LPCTSTR lpszType,
; _In_ LPTSTR lpszName,
; _In_ LONG_PTR lParam
; )
;// l'adresse de la ressource d'icônes identifiée par ResName
;// ResName est donné par le système et est l'identifiant numérique ou alpahanumérique de l'icône
;// icon resource address identified by ResName,
;// ResName is put by the system and is an Icon ID, numerical or alphanumerical
Protected *FindResource_RT_ICON
If Not(*hModule And *resourceInfos And (resType = #RT_ICON))
_StopEnumeration_With_Error(#error_BadCallbackParameter)
EndIf
*FindResource_RT_ICON = FindResource_(*hModule, ResName, resType)
If *FindResource_RT_ICON
If LoadResource_(*hModule, *FindResource_RT_ICON)
*resourceInfos\IconNumber + 1
_ContinueEnumeration__With__No_Error()
Else
_StopEnumeration_With_Error(#error_LoadResource_Fails)
EndIf
Else
_StopEnumeration_With_Error(#error_FindResource_Fails)
EndIf
EndProcedure
Procedure.i Callback_GetIcon(*hModule, resType, ResName, *resourceInfos.GetIcon)
; https://docs.microsoft.com/fr-fr/previous-versions/windows/desktop/legacy/ms648034(v=vs.85)
; EnumResNameProc callback function
; BOOL CALLBACK EnumResNameProc(
; _In_opt_ HMODULE hModule,
; _In_ LPCTSTR lpszType,
; _In_ LPTSTR lpszName,
; _In_ LONG_PTR lParam
; )
;// l'adresse de la ressource groupe d'icônes identifiée par ResName
;// ResName est donné par le stème et est l'identifiant numérique ou alpahanumérique du groupe
;// address of resource icon group identified by ResName,
;// ResName is put by the system And is Group ID, numerical Or alphanumerical
Protected *FindResource_RT_ICON
;// le handle du bloc d'information des données de la ressource chargée
Protected *LoadResource_RT_ICON
;// Taille de la ressource/resource size
Protected sizeOfResource_RT_ICON
If Not(*hModule And *resourceInfos And (resType = #RT_ICON))
_StopEnumeration_With_Error(#error_BadCallbackParameter)
EndIf
;// Numéro du group courrant/current group number
*resourceInfos\currentIconPosition + 1
If *resourceInfos\currentIconPosition = *resourceInfos\iconPositionToFind
;// Group position Ok
*FindResource_RT_ICON = FindResource_(*hModule, ResName, resType)
If *FindResource_RT_ICON
*LoadResource_RT_ICON = LoadResource_(*hModule, *FindResource_RT_ICON)
If *LoadResource_RT_ICON
sizeOfResource_RT_ICON = SizeofResource_(*hModule, *FindResource_RT_ICON)
If sizeOfResource_RT_ICON
*resourceInfos\icon = CreateIconFromResource_(*LoadResource_RT_ICON, sizeOfResource_RT_ICON, 1, $00030000)
If *resourceInfos\icon = #Null
_StopEnumeration_With_Error(#error_CreateIconFromResource_Fails)
Else
;// It's OK, Icon loaded
_StopEnumeration_With_No_Error()
EndIf
Else
_StopEnumeration_With_Error(#error_sizeOfResource_Fails)
EndIf
Else
_StopEnumeration_With_Error(#error_LoadResource_Fails)
EndIf
Else
_StopEnumeration_With_Error(#error_FindResource_Fails)
EndIf
ElseIf *resourceInfos\currentIconPosition > *resourceInfos\iconPositionToFind
_StopEnumeration_With_Error(#error_BadIconIndex)
Else
_ContinueEnumeration__With__No_Error()
EndIf
EndProcedure
Procedure.i GetLastError()
ProcedureReturn g_LastErrorCode
EndProcedure
Procedure SetlastError(Error_Code)
g_LastErrorCode = Error_Code
EndProcedure
;-
Procedure Programme()
Protected Window, Event, Index, IconCount
Protected resourceInfos.iconGroupsNumber
Protected resourceIcon.GetIcon
Protected *hModule
*hModule = LoadLibraryEx_("ddores.dll", 0,#LOAD_LIBRARY_AS_DATAFILE)
If Not(*hModule)
MessageRequester("Erreur/Error", "Impossible de charger la dll"+#LF$+"Unable to load dll")
End
EndIf
Window=OpenWindow(#PB_Any,0,0,130,70,"",#PB_Window_SystemMenu|#PB_Window_ScreenCentered)
;// on énumère les icônes pour en retrouver le nombre
;// enumerates icons to find the number
Select EnumResourceNames_(*hModule, #RT_ICON, @Callback_CountIcon(), @resourceInfos)
Case #Stop_Enumeration
If GetLastError() <> #ErrorCode_No_Error
MessageRequester("Erreur/Error", "Impossible d'énumérer les icônes"+#LF$+"Unable to enumerate icons")
FreeLibrary_(*hModule)
End
EndIf
EndSelect
IconCount = resourceInfos\iconNumber
ButtonImageGadget(#GadgetButtonImage,38,10,48,48,0)
;// display the first Icon
PostEvent(#PB_Event_Gadget, Window, #GadgetButtonImage, #PB_EventType_LeftClick)
Repeat
Event=WaitWindowEvent()
Select Event
Case #PB_Event_Gadget
If EventGadget()=#GadgetButtonImage And EventType()=#PB_EventType_LeftClick
Index+1
If Index = IconCount+1
Index = 1
EndIf
resourceIcon\iconPositionToFind = Index
resourceIcon\currentIconPosition = 0
If resourceIcon\icon
DestroyIcon_(resourceIcon\icon)
resourceIcon\icon = 0
EndIf
_Reset_ErrorCode()
Select EnumResourceNames_(*hModule, #RT_ICON, @Callback_GetIcon(), @resourceIcon)
Case #Stop_Enumeration
If GetLastError() = #ErrorCode_No_Error
PostMessage_(WindowID(Window),#WM_SETICON,1, resourceIcon\icon)
SetGadgetAttribute(#GadgetButtonImage,#PB_Button_Image, resourceIcon\icon)
SetWindowTitle(Window, Str(Index)+"/"+Str(IconCount))
Else
MessageRequester("","")
EndIf
EndSelect
EndIf
EndSelect
Until Event=#PB_Event_CloseWindow
If resourceIcon\icon
DestroyIcon_(resourceIcon\icon)
resourceIcon\icon = 0
EndIf
FreeLibrary_(*hModule)
EndProcedure
Programme()