Quantcast
Channel: VBForums - CodeBank - Visual Basic 6 and earlier
Viewing all articles
Browse latest Browse all 1512

[VB6] CommandButton with image and text: No UCs, ActiveX, or OwnerDraw/subclassing

$
0
0
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:

Code:

Option Explicit

Private Sub Form_Load()

Call SendMessage(Command1.hWnd, BM_SETIMAGE, IMAGE_ICON, ByVal ResIconTohIcon("ICO_01"))

End Sub

and this is the code for the module:

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

Thanks to Leandro Ascierto for the basis of the code to load an icon from a resource file into memory.
Attached Files

Viewing all articles
Browse latest Browse all 1512

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>