Most of the solutions to place an image on a button either use a control or owner drawing. If all you want is a simple image button, with the image on the left and text on the right, it turns out all you need to do is call BM_SETIMAGE. Don't even need to set the style to graphical, or change the style with API. Transparency is preserved, and the button style doesn't change like it does if you set it to 'graphical' in vb6; so if you're using xp style manifests the button still stays that style.
A bonus with this sample, it shows how the icon you use can be stored in a resource file, as a custom resource, which bypasses VB's limitations. You can use any valid Windows icon, with any size (or multiple sizes) and any color depth, and even more, this sample will load the size closest to what you requested.
To use this sample, create a project with a form with a command button, and a module. Add a new resource file, then choose add custom resource (NOT icon or bitmap), and name it something like "ICO_01" as the id.
Then, this code is for the form, and all you need is this one line for any command button:
and this is the code for the module:
Thanks to Leandro Ascierto for the basis of the code to load an icon from a resource file into memory.
A bonus with this sample, it shows how the icon you use can be stored in a resource file, as a custom resource, which bypasses VB's limitations. You can use any valid Windows icon, with any size (or multiple sizes) and any color depth, and even more, this sample will load the size closest to what you requested.
To use this sample, create a project with a form with a command button, and a module. Add a new resource file, then choose add custom resource (NOT icon or bitmap), and name it something like "ICO_01" as the id.
Then, this code is for the form, and all you need is this one line for any command button:
Code:
Option Explicit
Private Sub Form_Load()
Call SendMessage(Command1.hWnd, BM_SETIMAGE, IMAGE_ICON, ByVal ResIconTohIcon("ICO_01"))
End Sub
Code:
Option Explicit
Public Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, _
Source As Any, _
ByVal Length As Long)
Public Declare Function CreateIconFromResourceEx Lib "user32.dll" (ByRef presbits As Any, _
ByVal dwResSize As Long, _
ByVal fIcon As Long, _
ByVal dwVer As Long, _
ByVal cxDesired As Long, _
ByVal cyDesired As Long, _
ByVal flags As Long) As Long
Public Declare Function SendMessage Lib "User32" Alias "SendMessageA" (ByVal hWnd As Long, _
ByVal wMsg As Long, _
ByVal wParam As Long, _
lParam As Any) As Long
Private Type IconHeader
ihReserved As Integer
ihType As Integer
ihCount As Integer
End Type
Private Type IconEntry
ieWidth As Byte
ieHeight As Byte
ieColorCount As Byte
ieReserved As Byte
iePlanes As Integer
ieBitCount As Integer
ieBytesInRes As Long
ieImageOffset As Long
End Type
Public Const BM_SETIMAGE = &HF7
Public Const IMAGE_BITMAP = 0
Public Const IMAGE_ICON = 1
Public Function ResIconTohIcon(id As String, Optional cx As Long = 24, Optional cy As Long = 24) As Long
'returns an hIcon from an icon in the resource file
'For unknown reasons, this will not work with the 'Icon' group in the res file
'Icons must be added as a custom resource
Dim tIconHeader As IconHeader
Dim tIconEntry() As IconEntry
Dim MaxBitCount As Long
Dim MaxSize As Long
Dim Aproximate As Long
Dim IconID As Long
Dim hIcon As Long
Dim I As Long
Dim bytIcoData() As Byte
On Error GoTo e0
bytIcoData = LoadResData(id, "CUSTOM")
Call CopyMemory(tIconHeader, bytIcoData(0), Len(tIconHeader))
If tIconHeader.ihCount >= 1 Then
ReDim tIconEntry(tIconHeader.ihCount - 1)
Call CopyMemory(tIconEntry(0), bytIcoData(Len(tIconHeader)), Len(tIconEntry(0)) * tIconHeader.ihCount)
IconID = -1
For I = 0 To tIconHeader.ihCount - 1
If tIconEntry(I).ieBitCount > MaxBitCount Then MaxBitCount = tIconEntry(I).ieBitCount
Next
For I = 0 To tIconHeader.ihCount - 1
If MaxBitCount = tIconEntry(I).ieBitCount Then
MaxSize = CLng(tIconEntry(I).ieWidth) + CLng(tIconEntry(I).ieHeight)
If MaxSize > Aproximate And MaxSize <= (cx + cy) Then
Aproximate = MaxSize
IconID = I
End If
End If
Next
If IconID = -1 Then Exit Function
With tIconEntry(IconID)
hIcon = CreateIconFromResourceEx(bytIcoData(.ieImageOffset), .ieBytesInRes, 1, &H30000, cx, cy, &H0)
If hIcon <> 0 Then
ResIconTohIcon = hIcon
End If
End With
End If
On Error GoTo 0
Exit Function
e0:
Debug.Print "ResIconTohIcon.Error->" & Err.Description & " (" & Err.Number & ")"
End Function