Code:
Option Explicit
'---------------------------------------------------------------------
' Declaration needed for GetLastSystemError Function
Private Declare Function FormatMessage Lib "kernel32" Alias "FormatMessageA" (ByVal dwFlags As Long, lpSource As Long, ByVal dwMessageId As Long, ByVal dwLanguageId As Long, ByVal lpBuffer As String, ByVal nSize As Long, Args As Any) As Long
Private Const MAX_PATH As Long = 260
Private Const LB_SETTABSTOPS As Long = &H192
Private Const FORMAT_MESSAGE_FROM_SYSTEM As Long = &H1000
Private Const FORMAT_MESSAGE_IGNORE_INSERTS As Long = &H200
Private Const FORMAT_MESSAGE_MAX_WIDTH_MASK As Long = &HFF
Private Const FORMAT_MESSAGE_ARGUMENT_ARRAY As Long = &H2000
'---------------------------------------------------------------------
' Declarations needed for the SetIcon Function
Private Declare Function GetSystemMetrics Lib "user32" (ByVal nIndex As Long) As Long
Private Const SM_CXICON = 11
Private Const SM_CYICON = 12
Private Const SM_CXSMICON = 49
Private Const SM_CYSMICON = 50
Private Declare Function LoadImageAsString Lib "user32" Alias "LoadImageA" (ByVal hInst As Long, ByVal lpsz As String, ByVal uType As Long, ByVal cxDesired As Long, ByVal cyDesired As Long, ByVal fuLoad As Long) As Long
Private Const LR_DEFAULTCOLOR = &H0
Private Const LR_MONOCHROME = &H1
Private Const LR_COLOR = &H2
Private Const LR_COPYRETURNORG = &H4
Private Const LR_COPYDELETEORG = &H8
Private Const LR_LOADFROMFILE = &H10
Private Const LR_LOADTRANSPARENT = &H20
Private Const LR_DEFAULTSIZE = &H40
Private Const LR_VGACOLOR = &H80
Private Const LR_LOADMAP3DCOLORS = &H1000
Private Const LR_CREATEDIBSECTION = &H2000
Private Const LR_COPYFROMRESOURCE = &H4000
Private Const LR_SHARED = &H8000&
Private Const IMAGE_ICON = 1
Private Declare Function SendMessageLong Lib "user32" Alias "SendMessageA" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Private Const WM_SETICON = &H80
Private Const ICON_SMALL = 0
Private Const ICON_BIG = 1
Private Declare Function GetWindow Lib "user32" (ByVal hWnd As Long, ByVal wCmd As Long) As Long
Private Const GW_OWNER = 4
Private Declare Function GetWindowLongA Lib "user32" (ByVal hWnd As Long, ByVal nIndex As Long) As Long
Private Const GWL_HWNDPARENT As Long = -8&
Public Sub SetIcon(ByVal hWnd As Long, ByVal sIconResName As String, Optional ByVal bSetAsAppIcon As Boolean = True)
Dim i&, lhWndTop&, lres&, cx&, cy&, hIconLarge&, hIconSmall&
' LoadImage will not load application resoures in the IDE, as in IDE mode App.hInstance returns the hMod of the VB IDE itself.
' Thus hIconLarge will return 0 and report the error 1813, "The specified resource type cannot be found in the image file" in the IDE.
' However they will work properly in the compiled exe.
If InIDE = True Then Exit Sub ' Exit as unable to LoadImage if running in the IDE
' Find VB's hidden top level window
lhWndTop = hWnd
Do
i = i + 1
lres = GetWindow(lhWndTop, GW_OWNER) ' this will return the handle to the parent window, or 0 if it is a top level window
If lres <> 0 Then lhWndTop = lres
Loop Until lres = 0 Or i = 40
' get the dimensions of the system icons in pixels
cx = GetSystemMetrics(SM_CXICON)
cy = GetSystemMetrics(SM_CYICON)
hIconLarge = LoadImageAsString(App.hInstance, sIconResName, IMAGE_ICON, cx, cy, LR_LOADTRANSPARENT) ' load image from resource (sIconResName = name used in rc.exe script)
If hIconLarge = 0 Then MsgBox "Error in SetIcon calling LoadImage for large icon, " & GetLastSystemError ' must replace msgbox with proper error loging
SendMessageLong hWnd, WM_SETICON, ICON_BIG, hIconLarge ' set big icon for the form
If bSetAsAppIcon = True Then SendMessageLong lhWndTop, WM_SETICON, ICON_BIG, hIconLarge ' set the big icon for the app's parent window (ALT + TAB)
' get the dimensions of the small system icons in pixels
cx = GetSystemMetrics(SM_CXSMICON)
cy = GetSystemMetrics(SM_CYSMICON)
hIconSmall = LoadImageAsString(App.hInstance, sIconResName, IMAGE_ICON, cx, cy, LR_LOADTRANSPARENT) ' load image from resource (sIconResName = name used in rc.exe script)
If hIconSmall = 0 Then MsgBox "Error in SetIcon calling LoadImage for large icon, " & GetLastSystemError ' must replace msgbox with proper error loging
SendMessageLong hWnd, WM_SETICON, ICON_SMALL, hIconSmall ' set the small icon of the form
If bSetAsAppIcon = True Then SendMessageLong lhWndTop, WM_SETICON, ICON_SMALL, hIconSmall ' set the small icon for the app's parent window (taskbar)
End Sub
Private Function InIDE() As Boolean
On Error Resume Next
Debug.Print 1 / 0 ' error in IDE, however no debug in compiled exe thus no error in a compiled app.
If Err.Number <> 0 Then InIDE = True
On Error GoTo 0 ' necessary as there is a blue in VB6 which stops the error number from being reset to zero at the end of the function.
End Function
Private Function GetLastSystemError() As String
' Returns the API error if successful or a zero length string
Dim sError As String * MAX_PATH, lErrNum&, ret&
lErrNum = Err.LastDllError
ret = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM Or FORMAT_MESSAGE_IGNORE_INSERTS, ByVal 0&, lErrNum, 0&, sError, Len(sError), 0)
If ret > 0 Then GetLastSystemError = "Error Number: " & lErrNum & vbCrLf & "Error Description: " & Left$(sError, ret)
End Function
7. Add code to the load events of the application's forms