使用 FillRect 作为 MenuItem 的位图会绘制一个黑色正方形。

huangapple go评论181阅读模式
英文:

Using FillRect as a bitmap for a MenuItem draws a black square

问题

I'm using VB6 (old legacy code... don't ask) and trying to draw colored squares inside menu items - but I'm getting black squares instead. What am I doing wrong?

Public Function AddMenuItem(hMenu As Long, _
                            lItemID As Long, _
                            Optional fExType As Long = 0, _
                            Optional fState As Long = 0, _
                            Optional pzsText As String = "", _
                            Optional hSubMenu As Long = 0, _
                            Optional dwData As Long = 0, _
                            Optional iconHandle As Long = 0, _
                            Optional ByRef hMenuResult As Long = 0, _
                            Optional ByVal colorSquare As OLE_COLOR = -1) As Boolean
    On Error GoTo errHandle
    
    Dim mii         As MENUITEMINFO
    Dim lItemCount  As Long
    
    With mii
        .cbSize = Len(mii)
        .fMask = MIIM_FTYPE
        If hSubMenu Then
            .fMask = .fMask Or MIIM_SUBMENU
            .hSubMenu = hSubMenu
        Else
            .hSubMenu = 0
        End If
        If dwData Then
            .fMask = .fMask Or MIIM_DATA
            .dwItemData = dwData
        End If
        .fType = fExType Or MFT_RightORDER Or MFT_RightJUSTIFY Or MFT_STRING
        .fState = fState
        .wID = lItemID
        .dwTypeData = pzsText
        .cch = Len(.dwTypeData)
        
        If colorSquare = -1 Then
            .fMask = .fMask Or MIIM_STATE Or MIIM_ID Or MIIM_FTYPE Or MIIM_STRING
        Else
            Dim hBrush As Long
            hBrush = CreateSolidBrush(TranslateColor(colorSquare))
            .hbmpItem = CreateSquareBitmap(hBrush, 16, 16)
            DeleteObject hBrush
            
            .fMask = .fMask Or MIIM_ID Or MIIM_BITMAP Or MIIM_STATE Or MIIM_FTYPE Or MIIM_STRING
        End If
        
        lItemCount = Menu_GetItemCount(hMenu)
        Menu_InsertItem 0&, hMenu, lItemCount + 1, 1&, mii
    End With
    
    hMenuResult = DrawMenuBar(0&)
    
    Exit Function
    
errHandle:
    AddMenuItem = True
    DrawMenuBar 0&
End Function

Private Function CreateSquareBitmap(ByVal hBrush As Long, ByVal width As Long, ByVal height As Long) As Long
    Dim hdc         As Long
    Dim hBitmap     As Long
    Dim hOldBitmap  As Long
    Dim rc          As RECT

    rc.top = 0
    rc.left = 0
    rc.right = width
    rc.bottom = height
    
    hdc = CreateCompatibleDC(0&)
    hBitmap = CreateCompatibleBitmap(hdc, width, height)
    hOldBitmap = SelectObject(hdc, hBitmap)
    FillRect hdc, rc, hBrush
   
    ' Restore the old bitmap and delete the device context
    SelectObject hdc, hOldBitmap
    DeleteDC hdc
    
    ' Return the handle of the new bitmap
    CreateSquareBitmap = hBitmap
End Function
英文:

I'm using VB6 (old legacy code... don't ask) and trying to draw colored squares inside menu items - but I'm getting black squares instead. What am I doing wrong?

Public Function AddMenuItem(hMenu As Long, _
                            lItemID As Long, _
                            Optional fExType As Long = 0, _
                            Optional fState As Long = 0, _
                            Optional pzsText As String = "", _
                            Optional hSubMenu As Long = 0, _
                            Optional dwData As Long = 0, _
                            Optional iconHandle As Long = 0, _
                            Optional ByRef hMenuResult As Long = 0, _
                            Optional ByVal colorSquare As OLE_COLOR = -1) As Boolean
    On Error GoTo errHandle
    
    Dim mii         As MENUITEMINFO
    Dim lItemCount  As Long
    
    With mii
        .cbSize = Len(mii)
        .fMask = MIIM_FTYPE
        If hSubMenu Then
            .fMask = .fMask Or MIIM_SUBMENU
            .hSubMenu = hSubMenu
        Else
            .hSubMenu = 0
        End If
        If dwData Then
            .fMask = .fMask Or MIIM_DATA
            .dwItemData = dwData
        End If
        .fType = fExType Or MFT_RightORDER Or MFT_RightJUSTIFY Or MFT_STRING
        .fState = fState
        .wID = lItemID
        .dwTypeData = pzsText
        .cch = Len(.dwTypeData)
        
        If colorSquare = -1 Then
            .fMask = .fMask Or MIIM_STATE Or MIIM_ID Or MIIM_FTYPE Or MIIM_STRING
        Else
            Dim hBrush As Long
            hBrush = CreateSolidBrush(TranslateColor(colorSquare))
            .hbmpItem = CreateSquareBitmap(hBrush, 16, 16)
            DeleteObject hBrush
            
            .fMask = .fMask Or MIIM_ID Or MIIM_BITMAP Or MIIM_STATE Or MIIM_FTYPE Or MIIM_STRING
        End If
        
        lItemCount = Menu_GetItemCount(hMenu)
        Menu_InsertItem 0&, hMenu, lItemCount + 1, 1&, mii
    End With
    
    hMenuResult = DrawMenuBar(0&)
    
    Exit Function
    
errHandle:
    AddMenuItem = True
    DrawMenuBar 0&
End Function

Private Function CreateSquareBitmap(ByVal hBrush As Long, ByVal width As Long, ByVal height As Long) As Long
    Dim hdc         As Long
    Dim hBitmap     As Long
    Dim hOldBitmap  As Long
    Dim rc          As RECT

    rc.top = 0
    rc.left = 0
    rc.right = width
    rc.bottom = height
    
    hdc = CreateCompatibleDC(0&)
    hBitmap = CreateCompatibleBitmap(hdc, width, height)
    hOldBitmap = SelectObject(hdc, hBitmap)
    FillRect hdc, rc, hBrush
   
    ' Restore the old bitmap and delete the device context
    SelectObject hdc, hOldBitmap
    DeleteDC hdc
    
    ' Return the handle of the new bitmap
    CreateSquareBitmap = hBitmap
End Function

答案1

得分: 1

正如 @IInspectable 指出的,并且 CreateCompatibleBitmap 的备注部分提到,

> 注意:当创建内存设备上下文时,它最初选择了一个1x1的单色位图。如果在CreateCompatibleBitmap中使用此内存设备上下文,创建的位图将是单色位图。要创建彩色位图,请使用用于创建内存设备上下文的HDC,如下所示:

> HDC memDC = CreateCompatibleDC(hDC);
> HBITMAP memBM = CreateCompatibleBitmap(hDC, nWidth, nHeight);
> SelectObject(memDC, memBM);

一个完整的示例:捕获图像

英文:

As @IInspectable pointed out and the remarks section of the CreateCompatibleBitmap said,

> Note: When a memory device context is created, it initially has a
> 1-by-1 monochrome bitmap selected into it. If this memory device
> context is used in CreateCompatibleBitmap, the bitmap that is created
> is a monochrome bitmap. To create a color bitmap, use the HDC that was
> used to create the memory device context, as shown in the following
> code:
>
> HDC memDC = CreateCompatibleDC ( hDC );
> HBITMAP memBM = CreateCompatibleBitmap ( hDC, nWidth, nHeight );
> SelectObject ( memDC, memBM );

A complete sample: Capturing an Image.

答案2

得分: 1

感谢 @IInspectable 和 @YangXiaoPo-MSFT。 如果将来有人遇到这个问题,解决方案(对我而言)是在从创建菜单的窗口句柄获取的DC中创建位图,因此:

hdc = CreateCompatibleDC(0&)
hBitmap = CreateCompatibleBitmap(GetDC(windowHwnd), width, height)
hOldBitmap = SelectObject(hdc, hBitmap)
FillRect hdc, rc, hBrush
英文:

Thanks @IInspectable and @YangXiaoPo-MSFT. If anyone stumbles upon this in the future, the solution (for me) was to create the bitmap in a DC obtained from the handle of the window where the menu is created, so:

hdc = CreateCompatibleDC(0&)
hBitmap = CreateCompatibleBitmap(GetDC(windowHwnd), width, height)
hOldBitmap = SelectObject(hdc, hBitmap)
FillRect hdc, rc, hBrush

huangapple
  • 本文由 发表于 2023年3月7日 21:50:32
  • 转载请务必保留本文链接:https://go.coder-hub.com/75662839.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定