Modify

#4041 closed Bug (Fixed)

_GUICtrlStatusBar_SetIcon

Reported by: Nine Owned by: J-Paul Mesnage
Milestone: 3.3.17.0 Component: AutoIt
Version: 3.3.16.1 Severity: None
Keywords: Cc:

Description

Destroying the icon at the end of the function prevents the icon from being shown.

#include <GUIConstants.au3>
#include <GuiStatusBar.au3>

Example()

Func Example()
  Local $aPartRightSide[3] = [100, 100, -1]

  Local $hGUI = GUICreate("Test", 400, 300)
  Local $hStatusBar = _GUICtrlStatusBar_Create($hGUI, $aPartRightSide)
  _GUICtrlStatusBar_SetText($hStatusBar, "Part 1")
  _GUICtrlStatusBar_SetText($hStatusBar, "Part 2", 1)

  _GUICtrlStatusBar_SetIcon($hStatusBar, 0, 23, "shell32.dll") ; not working
  _GUICtrlStatusBar_SetIconEx($hStatusBar, 1, 23, "shell32.dll") ; working
  GUISetState(@SW_SHOW)

  Do
  Until GUIGetMsg() = $GUI_EVENT_CLOSE
EndFunc   ;==>Example

Func _GUICtrlStatusBar_SetIconEx($hWnd, $iPart, $hIcon = -1, $sIconFile = "")
  If $hIcon = -1 Then Return _SendMessage($hWnd, $SB_SETICON, $iPart, $hIcon, 0, "wparam", "handle") <> 0 ; Remove Icon
  If StringLen($sIconFile) <= 0 Then Return _SendMessage($hWnd, $SB_SETICON, $iPart, $hIcon) <> 0 ; set icon from icon handle

  ; set icon from file
  Local $tIcon = DllStructCreate("handle")
  Local $vResult = DllCall("shell32.dll", "uint", "ExtractIconExW", "wstr", $sIconFile, "int", $hIcon, "ptr", 0, "struct*", $tIcon, "uint", 1)
  If @error Then Return SetError(@error, @extended, False)
  $vResult = $vResult[0]
  If $vResult > 0 Then $vResult = _SendMessage($hWnd, $SB_SETICON, $iPart, DllStructGetData($tIcon, 1), 0, "wparam", "handle")
  ;DllCall("user32.dll", "bool", "DestroyIcon", "handle", DllStructGetData($tIcon, 1)) ; this needs to be removed

  Return $vResult
EndFunc   ;==>_GUICtrlStatusBar_SetIconEx

Attachments (0)

Change History (6)

comment:1 by J-Paul Mesnage, 11 months ago

In fact your solution will create an non delete icon for ever
I don't really know but the second example of _GUICtrlStatuBar_GetIcon() is working
I will try to find out why

comment:2 by anonymous, 11 months ago

It is because the GUISetState(@SW_SHOW) appears before the SetIcon calls. But it is not a viable solution.

comment:3 by Nine, 11 months ago

If you minimize or hide the GUI afterward, the icons disappear. You simply cannot destroy the icons until you delete the GUI. One solution would be to return the hIcon, so programmer can destroy it at the end of their script

comment:4 by Nine, 11 months ago

Here my take on it :

; #AutoIt3Wrapper_UseX64=y ; works both x86 and x64

#include <GUIConstants.au3>
#include <GuiStatusBar.au3>
#include <WinAPIIcons.au3>

Example()

Func Example()
  Local $aPartRightSide[3] = [100, 200, -1]

  Local $hGUI = GUICreate("Test", 400, 300)
  Local $hStatusBar = _GUICtrlStatusBar_Create($hGUI)
  _GUICtrlStatusBar_SetParts($hStatusBar, $aPartRightSide)
  _GUICtrlStatusBar_SetText($hStatusBar, "Part 1")
  _GUICtrlStatusBar_SetText($hStatusBar, "Part 2", 1)

  GUISetState(@SW_SHOW)

  Local $hIcon = _GUICtrlStatusBar_SetIconEx($hStatusBar, 1, 23, "shell32.dll") ; working
  If Not $hIcon Then Exit MsgBox($MB_OK, "Unable to set icon", "@error = " & @error)

  GUISetState()

  Do
  Until GUIGetMsg() = $GUI_EVENT_CLOSE

  ConsoleWrite(_WinAPI_DestroyIcon($hIcon) & @CRLF)
EndFunc   ;==>Example

; Not changing too much the original code, but solving all issues
; return false if any error
; return true if success or hIcon when $sIconFile is specified
; return @error for additional information when failure with $sIconFile specified
Func _GUICtrlStatusBar_SetIconEx($hWnd, $iPart, $hIcon = -1, $sIconFile = "") ; by Nine
  If $hIcon = -1 Then Return _SendMessage($hWnd, $SB_SETICON, $iPart, $hIcon, 0, "wparam", "handle") <> 0 ; Remove Icon
  If StringLen($sIconFile) <= 0 Then Return _SendMessage($hWnd, $SB_SETICON, $iPart, $hIcon) <> 0 ; set icon from icon handle

  Local $tIcon = DllStructCreate("handle")
  Local $vResult = DllCall("shell32.dll", "uint", "ExtractIconExW", "wstr", $sIconFile, "int", $hIcon, "ptr", 0, "struct*", $tIcon, "uint", 1)
  If @error Then Return SetError(@error, 0, False)
  If Hex($vResult[0], 8) = "FFFFFFFF" Then ; UINT_MAX error (based on MSDN)
    $vResult = _WinAPI_GetLastError()
    Return SetError(10 + $vResult, 0, False) ; to differentiate from the @error of DllCall
  EndIf
  If Not $vResult[0] Then Return SetError(-1, 0, False) ; no icon returned
  $vResult = _SendMessage($hWnd, $SB_SETICON, $iPart, DllStructGetData($tIcon, 1), 0, "wparam", "handle")
  If Not $vResult Then Return SetError(-2, 0, False)
  Return DllStructGetData($tIcon, 1)
EndFunc   ;==>_GUICtrlStatusBar_SetIconEx

comment:5 by Nine, 11 months ago

Forgot to erase first GuiSetState

comment:6 by J-Paul Mesnage, 10 months ago

Milestone: 3.3.17.0
Owner: set to J-Paul Mesnage
Resolution: Fixed
Status: newclosed

Fixed by revision [13105] in version: 3.3.17.0

Modify Ticket

Action
as closed The owner will remain J-Paul Mesnage.

Add Comment


E-mail address and name can be saved in the Preferences .
 
Note: See TracTickets for help on using tickets.