DickG

Setting color in cell using rasim's code

7 posts in this topic

I am using rasim's code, which works pretty well. But if I change the color from 0xFF4466 to 0xFF0000, it still shows as 0xFF4466. Yet other colors work. Any idea why it doesn't like 0xFF0000?

#include <GuiConstantsEx.au3>
#include <WindowsConstants.au3>
#include <GuiListView.au3>
#include <FontConstants.au3>
#include <WinAPI.au3>

Global $Font1 = _WinAPI_CreateFont(14, 6, 0, 0, $FW_BOLD)
Global $Font2 = _WinAPI_CreateFont(14, 6, 0, 0, $FW_BOLD, True)

$hGUI = GUICreate("Test", 300, 200)

$hListView = _GUICtrlListView_Create($hGUI, "Items|SubItems", 10, 10, 280, 180, $LVS_REPORT, $WS_EX_CLIENTEDGE)

_GUICtrlListView_SetExtendedListViewStyle($hListView, BitOR($LVS_EX_GRIDLINES, $LVS_EX_FULLROWSELECT))

For $i = 1 To 10
    _GUICtrlListView_AddItem($hListView, "Item" & $i)
    _GUICtrlListView_AddSubItem($hListView, $i - 1, "SubItem" & $i, 1)
Next

GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")

GUISetState()

Do
Until GUIGetMsg() = $GUI_EVENT_CLOSE

_WinAPI_DeleteObject($Font1)
_WinAPI_DeleteObject($Font2)

Func WM_NOTIFY($hWnd, $Msg, $wParam, $lParam)
    Local $tNMHDR, $hWndFrom, $iCode
    
    $tNMHDR = DllStructCreate($tagNMHDR, $lParam)
    $hWndFrom = DllStructGetData($tNMHDR, "hWndFrom")
    $iCode = DllStructGetData($tNMHDR, "Code")
    
    Switch $hWndFrom
        Case $hListView
            Switch $iCode
                Case $NM_CUSTOMDRAW
                    Local $tCustDraw = DllStructCreate($tagNMLVCUSTOMDRAW, $lParam)
                    
                    Local $iDrawStage = DllStructGetData($tCustDraw, "dwDrawStage")
                    
                    If $iDrawStage = $CDDS_PREPAINT Then Return $CDRF_NOTIFYITEMDRAW
                    If $iDrawStage = $CDDS_ITEMPREPAINT Then Return $CDRF_NOTIFYSUBITEMDRAW
                    
                    Local $iSubItem = DllStructGetData($tCustDraw, "iSubItem")
                    
                    Local $iItem = DllStructGetData($tCustDraw, "dwItemSpec")
                    
                    Local $iColor, $hDC
                    
                    Switch $iItem
                        Case 5
                            $hDC = DllStructGetData($tCustDraw, "hdc")
                            
                            If $iSubItem = 0 Then
                                $iColor = 0xFF4466
                                _WinAPI_SelectObject($hDC, $Font1)
                            Else
                                $iColor = 0x5555DD
                                _WinAPI_SelectObject($hDC, $Font2)
                            EndIf
                            
                            DllStructSetData($tCustDraw, "clrText", $iColor)
                            
                            Return $CDRF_NEWFONT
                    EndSwitch
            EndSwitch
    EndSwitch
    
    Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_NOTIFY

 

Share this post


Link to post
Share on other sites



The code is correct and so is the displayed color (blue)

But ...  :)

If you meant red , you have to convert the RGB color to BGR

$iColor = RGB2BGR(0xFF0000)  ; red

;.....

Func RGB2BGR($iColor)
     Return BitAND(BitShift(String(Binary($iColor)), 8), 0xFFFFFF)
EndFunc   ;==>RGB2BGR()

 

Share this post


Link to post
Share on other sites
10 hours ago, mikell said:

The code is correct and so is the displayed color (blue)

But ...  :)

If you meant red , you have to convert the RGB color to BGR

$iColor = RGB2BGR(0xFF0000)  ; red

;.....

Func RGB2BGR($iColor)
     Return BitAND(BitShift(String(Binary($iColor)), 8), 0xFFFFFF)
EndFunc   ;==>RGB2BGR()

 

Aha! I would have never thought of that!

Thanks much!

PS: So why does $iColor = 0xFF4466 or $iColor = 0x5555DD work without this conversion?

Share this post


Link to post
Share on other sites

I'm sorry, but I still don't get it. When I run your example, 0xFF4466 shows as dark pink, and 0x5555DD shows as dark purple. But if I use RGB2BGR() on those colors, I get dark purple for 0xFF4466  and dark pink for 0x5555DD.

I'm not a classically trained programmer, so I don't get the bit shifting and bit ANDing that's needed.

Here is a modified version of your test GUI to show that I get difference results when I use or don't use RGB2BGR(). I'd be grateful for a simple explanation. For example, how do I know when to use RGB2BGR() and when to not use it? I have to use it in the script I need to set a cell color in a Listview, but don't need it for setting other colors.

#Include <GuiConstantsEx.au3>
#Include <WindowsConstants.au3>

GuiCreate("Color Test")
GuiSetState()

Local $Hex_graphic_A = GUICtrlCreateGraphic(20, 20, 150, 150)
GUICtrlSetGraphic($Hex_graphic_A, $GUI_GR_RECT, 0, 0, 150, 150)
GUICtrlSetGraphic($Hex_graphic_A, $GUI_GR_COLOR)
GUICtrlSetBkColor($Hex_graphic_A, 0xFF4466)
GUICtrlCreateLabel("0xFF4466 w/o RGB2BGR()", 30, 50, 120, 50)

Local $Hex_graphic_B = GUICtrlCreateGraphic(200, 20, 150, 150)
GUICtrlSetGraphic($Hex_graphic_B, $GUI_GR_RECT, 0, 0, 150, 150)
GUICtrlSetGraphic($Hex_graphic_B, $GUI_GR_COLOR)
GUICtrlSetBkColor($Hex_graphic_B, RGB2BGR(0xFF4466))
GUICtrlCreateLabel("0xFF4466 with RGB2BGR()", 210, 50, 120, 50)

Local $Hex_graphic_C = GUICtrlCreateGraphic(20, 200, 150, 150)
GUICtrlSetGraphic($Hex_graphic_C, $GUI_GR_RECT, 0, 0, 150, 150)
GUICtrlSetGraphic($Hex_graphic_C, $GUI_GR_COLOR)
GUICtrlSetBkColor($Hex_graphic_C, 0xFF0000)
GUICtrlCreateLabel("0xFF0000 w/o RGB2BGR()", 30, 250, 120, 50)

Local $Hex_graphic_D = GUICtrlCreateGraphic(200, 200, 150, 150)
GUICtrlSetGraphic($Hex_graphic_D, $GUI_GR_RECT, 0, 0, 150, 150)
GUICtrlSetGraphic($Hex_graphic_D, $GUI_GR_COLOR)
GUICtrlSetBkColor($Hex_graphic_D, RGB2BGR(0xFF0000))
GUICtrlCreateLabel("0xFF0000 with RGB2BGR()", 210, 250, 120, 50)

While GuiGetMsg()<>-3
Wend

Func RGB2BGR($iColor)
    Return BitAND(BitShift(String(Binary($iColor)), 8), 0xFFFFFF)
EndFunc

 

Share this post


Link to post
Share on other sites

The WM_NOTIFY uses the  $tagNMLVCUSTOMDRAW structure (c.f. helpfile)  . Please note this :
clrText : COLORREF value representing the color that will be used to display text foreground in the list-view control.
Microsoft says :
" The COLORREF value is used to specify an color.
When specifying an explicit RGB color, the COLORREF value has the following hexadecimal form: 0x00bbggrr "

reason why our usual 0xrrggbb color needs to be converted with RGB2BGR()  before use in the wm_notify

1 person likes this

Share this post


Link to post
Share on other sites

Aha, that clears it up! Thanks much!!! Now I understand!

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now