Try this. (I have not tried it)
#Include <GUIConstantsEx.au3>
#Include <GuiButton.au3>
#Include <WindowsConstants.au3>
GUICreate("Buttons", 300, 300)
GUISetState()
$btn = GUICtrlCreateButton("Button1", 10, 10, 64, 64, $BS_ICON)
_GUICtrlButton_SetIcon($btn, @DesktopDir & "\106.ico", 0, 48, 48)
While 1
$Msg = GUIGetMsg()
If $Msg = $GUI_EVENT_CLOSE Then ExitLoop
WEnd
Func _GUICtrlButton_SetIcon($hWnd, $sIcon, $iIndex, $iWidth, $iHeight)
If Not IsHWnd($hWnd) Then
$hWnd = GUICtrlGetHandle($hWnd)
If $hWnd = 0 Then
Return False
EndIf
EndIf
Local $hIcon = _WinAPI_PrivateExtractIcon($sIcon, $iIndex, $iWidth, $iHeight)
If @error Then
Return False
EndIf
Local $hPrev = _SendMessage($hWnd, 0xF7, 1, $hIcon)
If $hPrev Then
If Not _WinAPI_DeleteObject($hPrev) Then
_WinAPI_DestroyIcon($hPrev)
EndIf
EndIf
_WinAPI_UpdateWindow($hWnd)
Return True
EndFunc ;==>_GUICtrlButton_SetIcon
Func _WinAPI_PrivateExtractIcon($sIcon, $iIndex, $iWidth, $iHeight)
Local $hIcon, $tIcon = DllStructCreate('hwnd'), $tID = DllStructCreate('hwnd')
Local $Ret = DllCall('user32.dll', 'int', 'PrivateExtractIcons', 'str', $sIcon, 'int', $iIndex, 'int', $iWidth, 'int', $iHeight, 'ptr', DllStructGetPtr($tIcon), 'ptr', DllStructGetPtr($tID), 'int', 1, 'int', 0)
If (@error) Or ($Ret[0] = 0) Then
Return SetError(1, 0, 0)
EndIf
$hIcon = DllStructGetData($tIcon, 1)
If ($hIcon = Ptr(0)) Or (Not IsPtr($hIcon)) Then
Return SetError(1, 0, 0)
EndIf
Return $hIcon
EndFunc ;==>_WinAPI_PrivateExtractIcon