Row BackColor in inactive BROWSE control

General Help regarding HMG, Compilation, Linking, Samples

Moderator: Rathinagiri

User avatar
mol
Posts: 3825
Joined: Thu Sep 11, 2008 5:31 am
Location: Myszków, Poland
Contact:

Row BackColor in inactive BROWSE control

Post by mol »

Hi guys!
We have function CellNavigationColor which can set colors of GRID control.
But, anybody knows the way to change active row colors in BROWSE, especially when focus is out of this control (in this situation active row is backlighted by default window backgroud color, default light grey)?
Red2
Posts: 282
Joined: Sat May 18, 2019 2:11 pm
DBs Used: Visual FoxPro, FoxPro
Location: United States of America

Re: Row BackColor in inactive BROWSE control

Post by Red2 »

Hi Mol,

Might this example from my BROWSE be helpful?

Code: Select all

// In my Main.PRG:
public bkItemType := ;
	{ || iif( alltrim( Items->Type_Item ) == "Short" ;
			, {255,215,215} ;
	,	 iif( alltrim( Items->Type_Item ) == "Medium" ;
			, {230,225,130} ;
	,	 iif( alltrim( Items->Type_Item ) == "Long" ;
			, {180,220,235} ;

// In my Browse's DynamicBackColor:
{ bkItemType, bkItemType, bkItemType, bkItemType, bkItemType, bkItemType, bkItemType }
Kind regards,

Red2
User avatar
mol
Posts: 3825
Joined: Thu Sep 11, 2008 5:31 am
Location: Myszków, Poland
Contact:

Re: Row BackColor in inactive BROWSE control

Post by mol »

I don't want to use DynamicBackColor.
I want to change row highlight color when Browse is not active - in this situation selected row background is grey - on almost LCD monitors it's hard to see the difference between white
franco
Posts: 921
Joined: Sat Nov 02, 2013 5:42 am
DBs Used: DBF
Location: Canada

Re: Row BackColor in inactive BROWSE control

Post by franco »

Hi Mol
You can change the backcolor and current row is normal. I can not figure how to change current row.

DEFINE BROWSE brwItems

BACKCOLOR {200,200,200} // { 255, 255, 255}
FONTCOLOR { 0, 0, 0 }
All The Best,
Franco
Canada
User avatar
mol
Posts: 3825
Joined: Thu Sep 11, 2008 5:31 am
Location: Myszków, Poland
Contact:

Re: Row BackColor in inactive BROWSE control

Post by mol »

I want to change color in the state when browse is inactive
edk
Posts: 999
Joined: Thu Oct 16, 2014 11:35 am
Location: Poland

Re: Row BackColor in inactive BROWSE control

Post by edk »

Marku, nie jestem biegły w C i nie pomogę w zmianie koloru wybranego wiersza, ale aby zrobić go bardziej czytelnym, może spróbuj w inną mańkę, np. zmienić kolor tła Browse przy utracie fokusa i przywrócić kolor tła przy uzyskaniu fokusa:
ON GOTFOCUS ( This.BackColor := {255,255,255} );
ON LOSTFOCUS ( This.BackColor := {215,215,215} );
User avatar
mol
Posts: 3825
Joined: Thu Sep 11, 2008 5:31 am
Location: Myszków, Poland
Contact:

Re: Row BackColor in inactive BROWSE control

Post by mol »

I found solution, but it's written in basic.
I don't know how to adapt it to BROWSE control.
Maybe someone is able to do it?

https://www.vbforums.com/showthread.php ... ost5438543

and some code from this page:

Code: Select all

Private Function ListViewStayBlue_Proc(ByVal hWnd As Long, ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long, ByVal uIdSubclass As Long, ByVal dwRefData As Long) As Long
    If uMsg = WM_DESTROY Then
        UnSubclassSomeWindow hWnd, AddressOf_ListViewStayBlue_Proc, uIdSubclass
        ListViewStayBlue_Proc = NextSubclassProcOnChain(hWnd, uMsg, wParam, lParam)
        Exit Function
    End If
    If IdeStopButtonClicked Then ' Protect the IDE.  Don't execute any specific stuff if we're stopping.  We may run into COM objects or other variables that no longer exist.
        ListViewStayBlue_Proc = NextSubclassProcOnChain(hWnd, uMsg, wParam, lParam)
        Exit Function
    End If
    '
    Dim LVI As LVITEM
    '
    Const GWL_STYLE             As Long = &HFFFFFFF0
    Const WM_SETFOCUS           As Long = &H7&
    Const WM_KILLFOCUS          As Long = &H8&
    Const LVS_SHOWSELALWAYS     As Long = &H8&
    Const LVM_FIRST             As Long = &H1000&
    Const LVM_GETNEXTITEM       As Long = (LVM_FIRST + 12&)
    Const LVM_SETITEMSTATE      As Long = (LVM_FIRST + 43&)
    Const LVIS_FOCUSED          As Long = &H1&
    Const LVNI_FOCUSED          As Long = &H1&
    Const LVNI_SELECTED         As Long = &H2&
    '
    Select Case uMsg
    Case WM_KILLFOCUS
        If GetWindowLongW(hWnd, GWL_STYLE) And LVS_SHOWSELALWAYS Then                                   ' If Not ListView.HideSelection Then...
            Set m_ListView1_SelectedItem = ListView1.SelectedItem                                       ' Set a reference to the currently selected item before SelectedItem is set to Nothing
            dwRefData = SendMessageW(hWnd, LVM_GETNEXTITEM, -1&, ByVal LVNI_FOCUSED Or LVNI_SELECTED)   ' Get ListView.SelectedItem.Index, if any.
            SubclassSomeWindow hWnd, AddressOf_ListViewStayBlue_Proc, dwRefData                         ' Update dwRefData/Index
           'SubclassSomeWindow is moved out of the following If block to fix an unrelated bug
            If dwRefData <> LV_INVALID_INDEX Then                                                       ' If Not ListView.SelectedItem Is Nothing Then...
                LVI.StateMask = LVIS_FOCUSED                                                            ' Bit flag already 0, so no need to do anything; LVI.State = LVI.State And Not LVIS_FOCUSED
                SendMessageW hWnd, LVM_SETITEMSTATE, dwRefData, LVI                                     ' Remove the focus rectangle from the currently focused item.
            End If
            Exit Function                                                                               ' Consume the message so that the ListView doesn't remove the highlight from the selected item(s).
        End If
    Case WM_SETFOCUS
        If dwRefData <> LV_INVALID_INDEX Then
            LVI.State = LVIS_FOCUSED
            LVI.StateMask = LVIS_FOCUSED
            SendMessageW hWnd, LVM_SETITEMSTATE, dwRefData, LVI                                         ' Reinstate the focus rectangle.
        End If
    End Select
    '
    ' Give control to other procs, if they exist.
    ' Notice that we don't get to here if uMsg = WM_KILLFOCUS.
    ListViewStayBlue_Proc = NextSubclassProcOnChain(hWnd, uMsg, wParam, lParam)
End Function

Code: Select all

Public Sub SubclassToKeepListViewBlue(lsv As ListView, bLeaveFocusRect As Boolean)
    '
    ' This one just makes the ListView work a bit more like the ListBox.
    ' When ListView doesn't have the focus, the selected item goes gray, which is hard to see.
    ' This just makes it stay blue (like the ListBox).
    '
    ' NOTICE:   If bLeaveFocusRect=FALSE then lsv___.SelectedItem... can NOT be used as it gets deselected.  We must use bLeaveFocusRect=TRUE if we wish to use lsv___.SelectedItem...
    '           We use the sign bit of dwRefData to track this.
    '
    SubclassSomeWindow lsv.hWnd, AddressOf ListViewStayBlue_Proc, &H7FFFFFFF Or (&H80000000 And CLng(bLeaveFocusRect)) ' LV_INVALID_INDEX = -1, but we use the sign bit for tracking bLeaveFocusRect.
End Sub

Private Function ListViewStayBlue_Proc(ByVal hWnd As Long, ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long, ByVal uIdSubclass As Long, ByVal dwRefData As Long) As Long
    If uMsg = WM_DESTROY Then
        UnSubclassSomeWindow hWnd, AddressOf_ListViewStayBlue_Proc, uIdSubclass
        ListViewStayBlue_Proc = NextSubclassProcOnChain(hWnd, uMsg, wParam, lParam)
        Exit Function
    End If
    If IdeStopButtonClicked Then ' Protect the IDE.  Don't execute any specific stuff if we're stopping.  We may run into COM objects or other variables that no longer exist.
        ListViewStayBlue_Proc = NextSubclassProcOnChain(hWnd, uMsg, wParam, lParam)
        Exit Function
    End If
    '
    Dim LVI                     As LVITEM
    Dim iLeaveFocusRect         As Long                     ' Just the sign bit is used.
    Dim iSelIndex               As Long                     ' Sign bit is masked off, even when it's LV_INVALID_INDEX.  That's why we use LV_INVALID_INDEX_ALT.
    '
    Const LV_INVALID_INDEX_ALT  As Long = &H7FFFFFFF        ' LV_INVALID_INDEX = -1, but we use the sign bit for tracking bLeaveFocusRect.
    Const GWL_STYLE             As Long = &HFFFFFFF0
    Const WM_SETFOCUS           As Long = &H7&
    Const WM_KILLFOCUS          As Long = &H8&
    Const LVS_SHOWSELALWAYS     As Long = &H8&
    Const LVM_FIRST             As Long = &H1000&
    Const LVM_GETNEXTITEM       As Long = (LVM_FIRST + 12&)
    Const LVM_SETITEMSTATE      As Long = (LVM_FIRST + 43&)
    Const LVIS_FOCUSED          As Long = &H1&
    Const LVNI_FOCUSED          As Long = &H1&
    Const LVNI_SELECTED         As Long = &H2&
    '
    Select Case uMsg
    Case WM_KILLFOCUS
        If GetWindowLongW(hWnd, GWL_STYLE) And LVS_SHOWSELALWAYS Then                                   ' If Not ListView.HideSelection Then...
            iSelIndex = SendMessageW(hWnd, LVM_GETNEXTITEM, -1&, ByVal LVNI_FOCUSED Or LVNI_SELECTED)   ' Get ListView.SelectedItem.Index, if any.
            iSelIndex = iSelIndex And LV_INVALID_INDEX_ALT                                              ' Mask off the sign bit.
            iLeaveFocusRect = dwRefData And &H80000000                                                  ' Get our bLeaveFocusRect (but not as true boolean).
            If iSelIndex <> LV_INVALID_INDEX_ALT Then                                                   ' If Not ListView.SelectedItem Is Nothing Then...
                SubclassSomeWindow hWnd, AddressOf_ListViewStayBlue_Proc, iSelIndex Or iLeaveFocusRect  ' Update dwRefData.
                LVI.StateMask = LVIS_FOCUSED                                                            ' Bit flag already 0, so no need to do anything; LVI.State = LVI.State And Not LVIS_FOCUSED
                If iLeaveFocusRect Then LVI.State = LVIS_FOCUSED                                        ' Keep the focus rectangle if so directed.
                SendMessageW hWnd, LVM_SETITEMSTATE, iSelIndex, LVI                                     ' Remove the focus rectangle from the currently focused item (if that's what we want).
            End If
            Exit Function                                                                               ' Consume the message so that the ListView doesn't remove the highlight from the selected item(s).
        End If
    Case WM_SETFOCUS
        iSelIndex = dwRefData And LV_INVALID_INDEX_ALT
        If iSelIndex <> LV_INVALID_INDEX_ALT Then
            LVI.StateMask = LVIS_FOCUSED
            LVI.State = LVIS_FOCUSED
            SendMessageW hWnd, LVM_SETITEMSTATE, iSelIndex, LVI                                         ' Reinstate the focus rectangle.
        End If
    End Select
    '
    ' Give control to other procs, if they exist.
    ' Notice that we don't get to here if uMsg = WM_KILLFOCUS.
    ListViewStayBlue_Proc = NextSubclassProcOnChain(hWnd, uMsg, wParam, lParam)
End Function

Private Function AddressOf_ListViewStayBlue_Proc() As Long
    AddressOf_ListViewStayBlue_Proc = ProcedureAddress(AddressOf ListViewStayBlue_Proc)
End Function

User avatar
andyglezl
Posts: 1461
Joined: Fri Oct 26, 2012 7:58 pm
Location: Guadalajara Jalisco, MX
Contact:

Re: Row BackColor in inactive BROWSE control

Post by andyglezl »

imagen_2022-03-11_120335.png
imagen_2022-03-11_120335.png (127.76 KiB) Viewed 4058 times

En el GRID funciona esto.
Tal vez estudiandolo y entendiendolo, funcione para el BROWSE.
*------------------------------------------------------------------------------------
In the GRID this works.
Maybe studying and understanding it will work for the BROWSE.

Code: Select all

	CellNavigationColor( _SELECTEDCELL_FORECOLOR, YELLOW )	// CAMBIA COLOR DE CELDA-COLUMNA
	CellNavigationColor( _SELECTEDCELL_BACKCOLOR, GREEN )		// CAMBIA COLOR DE CELDA-COLUMNA
	CellNavigationColor( _SELECTEDCELL_DISPLAYCOLOR, .T. )
	CellNavigationColor( _SELECTEDROW_FORECOLOR, WHITE )		// CAMBIA COLOR DEL RENGLON
	CellNavigationColor( _SELECTEDROW_BACKCOLOR, BLUE )		// CAMBIA COLOR DEL RENGLON
	CellNavigationColor( _SELECTEDROW_DISPLAYCOLOR, .T. )




***  i_grid.ch

// CONSTANTS --> GridCellNavigationColor (nIndex) // only for cell navigation = .T.
**********************************************************************************
#define _SELECTEDROW_DISPLAYCOLOR   1
#define _SELECTEDCELL_DISPLAYCOLOR  2
#define _SELECTEDROW_FORECOLOR      348
#define _SELECTEDROW_BACKCOLOR      349
#define _SELECTEDCELL_FORECOLOR     350 
#define _SELECTEDCELL_BACKCOLOR     351
**********************************************************************************


***  h_GridEx.prg
*----------------------------------------------------------------------------------------------*
FUNCTION CellNavigationColor (nIndex, xData)
*----------------------------------------------------------------------------------------------*
MEMVAR _HMG_GRID_SELECTEDROW_DISPLAYCOLOR
MEMVAR _HMG_GRID_SELECTEDCELL_DISPLAYCOLOR
LOCAL  aRGB_old, aRGB

   IF nIndex == _SELECTEDROW_DISPLAYCOLOR .AND. ValType (xData) == "L" 
      _HMG_GRID_SELECTEDROW_DISPLAYCOLOR := xData
      RETURN NIL
   ENDIF
   
   IF nIndex == _SELECTEDCELL_DISPLAYCOLOR .AND. ValType (xData) == "L" 
      _HMG_GRID_SELECTEDCELL_DISPLAYCOLOR := xData
      RETURN NIL
   ENDIF

   IF nIndex >= 348 .AND. nIndex <= 351
      aRGB := xData
      aRGB_old := _HMG_SYSDATA [ nIndex ]
      IF ValType (aRGB) == "A" .AND. HMG_LEN (aRGB) == 3
         _HMG_SYSDATA [ nIndex ] := aRGB
      ELSEIF ValType (aRGB) <> "U"
         MsgHMGError ("Grid Cell Navigation Color: Invalid parameter aRGB color. Program Terminated")
      ENDIF
   ELSE
      MsgHMGError ("Grid Cell Navigation Color: Invalid parameters. Program Terminated")
   ENDIF
RETURN aRGB_old
Andrés González López
Desde Guadalajara, Jalisco. México.
Post Reply