AutoHotkey Homepage AutoHotkey Community
Let's help each other out
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Listview colors for individual lines (e.g. highlighting)
Goto page Previous  1, 2
 
Reply to topic    AutoHotkey Community Forum Index -> Scripts & Functions
View previous topic :: View next topic  
Author Message
almex



Joined: 16 Oct 2007
Posts: 10
Location: Las Vegas, NV, USA

PostPosted: Mon Feb 04, 2008 6:44 pm    Post subject: Reply with quote

Right, I created a function that swaps the Red & Blue values in order to compensate. Since I'm using this in conjunction with your ChooseColor() function (Thanks, BTW!), I was confused as to why it wasn't converting the colors correctly.
Back to top
View user's profile Send private message
tic



Joined: 22 Apr 2007
Posts: 1786

PostPosted: Thu Feb 14, 2008 7:17 am    Post subject: Reply with quote

its a shame this still hasnt been built into ahk...
Back to top
View user's profile Send private message
stomasik



Joined: 29 May 2008
Posts: 4

PostPosted: Mon Jun 16, 2008 1:42 pm    Post subject: Reply with quote

This is really a nice script. I have a question. Is there a way to use a differnt columb for the index?
Back to top
View user's profile Send private message
cyril171080
Guest





PostPosted: Sat Feb 14, 2009 1:09 am    Post subject: Reply with quote

I have a question.
Is there a way to use a differnt listview?
as like that :
http://www.autohotkey.com/forum/topic40956.html&highlight=lvx
Back to top
koro



Joined: 24 Sep 2006
Posts: 61

PostPosted: Sat Jul 11, 2009 11:47 pm    Post subject: Re: Listview colors for individual lines (e.g. highlighting) Reply with quote

evl wrote:
This code allows you to apply colors to a line (or as many as you like) in a listview - both background and text colors can be changed. This allows for effects such as:
- Highlighting alternating lines to make them easier to read.
- Highlighting certain lines to attract a user's attention to them.
- Flashing a line by toggling between colors.

Credit for this code goes to shimanov, I'm just providing a couple of extra little examples. Updated with ideas from toralf.

I think it might be possible to highlight specific "cells" within a listview by using CDRF_NOTIFYSUBITEMDRAW but I haven't been able to figure it out.



I'm confused by how this script works (and I have problems with it).

Particularly, this line:

Code:

LV_GetText(Index, Current_Line)
              If (Line_Color_%Index%_Text != ""){
                  EncodeInteger( Line_Color_%Index%_Text, 4, p_l, 48 )   ; foreground
                  EncodeInteger( Line_Color_%Index%_Back, 4, p_l, 52 )   ; background
                }


It seems like you're using the contents of the listview cell as part of a variable name! This is quite problematic if your cell contains complex stuff (for instance, accented characters, or even spaces).

I get a bunch of errors like "Variable name Line_Color_Configuração_Text contains an invalid character" (yes, one of my cells contains the word "Configuração").

Is this really necessary? Is there a way to avoid this problem?
Back to top
View user's profile Send private message
pajenn



Joined: 07 Feb 2009
Posts: 384

PostPosted: Wed Sep 09, 2009 5:51 pm    Post subject: Reply with quote

I tried to convert this into a TreeView version, but failed. I was hoping to get lucky with the DecodeInteger and EncodeInteger and WM_NOTIFY functions, which are beyond my programming understanding.

If anyone wants to take a shot at converting those to treeview versions, or explain why this couldn't work with treeview, here's my version fwiw. It doesn't work in that nothing happens, no color change:

-I changed the LV functions in the original script to their respective TV counterparts.
-I used tree branch ItemID instead of listview row number; I left in a message box that states those ID just to see that script runs through them.
-The sample tree is from the help file's example, except I set the root directory to A_ScriptDir to keep the build process short -> you need folders in there though.
-The background starts as white with black foreground (text?), and if the script worked those colors would be reversed when a branch was double-clicked.

Code:

Code:

/* struct NMHDR {
    HWND            hwndFrom;       uint4       0
    UINT            idFrom;         uint4       4
    UINT            code;           uint4       8
}                                               12
*/

/* struct NMCUSTOMDRAW {
    NMHDR           hdr;            12          0
    DWORD           dwDrawStage;    uint4       12
    HDC             hdc;            uint4       16
    RECT            rc;             16          20
    DWORD_PTR       dwItemSpec;     uint4       36
    UINT            uItemState;     uint4       40
    LPARAM          lItemlParam;    int4        44
}                                               48
*/

/* struct NMLVCUSTOMDRAW {
    NMCUSTOMDRAW    nmcd;           48          0
    COLORREF        clrText;        uint4       48
    COLORREF        clrTextBk;      uint4       52

    #if (_WIN32_IE >= 0x0400)
        int         iSubItem;       int4        56
    #endif

    #if (_WIN32_IE >= 0x560)
        DWORD       dwItemType;     uint4       60
        COLORREF    clrFace;        uint4       64
        int         iIconEffect;    int4        68
        int         iIconPhase;     int4        72
        int         iPartId;        int4        76
        int         iStateId:       int4        80
        RECT        rcText;         16          84
        UINT        uAlign;         uint4       100
    #endif
}                                               104
*/

TreeRoot := A_ScriptDir
;TreeRoot := A_AppData
Gui, +LastFound
;Gui, Add, ListView, x5 y5 w200 h200 vLV_Sample, index|day
Gui, Add, TreeView, x5 y5 w200 h200 vMyTree gMyTree
AddSubFoldersToTree(TreeRoot)
Gui, Show,, %TreeRoot%  ; Display the source directory (TreeRoot) in the title bar.

TV_ColorInitiate() ; (Gui_Number, Control) - defaults to: (1, SysListView321)

TV_ColorChange()
Loop, % TV_GetCount()
{
    treeIndex := TV_GetNext(treeIndex)
    treeIndices .= treeIndex "`n"
    If (treeIndex == 0)
        Break
    TV_ColorChange(treeIndex, "0x000000", "0xFFFFFF")
}

Return

GuiClose:
GuiEscape:
    Exitapp

MyTree:
If (A_GuiEvent == "S")  ; i.e. do nothing extra on "select new tree item" events.
    return
treeIndices =
Loop, % TV_GetCount()
{
    treeIndex := TV_GetNext(treeIndex)
    treeIndices .= treeIndex "`n"
   
    If (treeIndex == 0)
        Break
    TV_ColorChange(treeIndex, "0xFFFFFF", "0x000000")
}
Msgbox, TV_ColorChange (reversal) was applied to following branches (item IDs):`n%treeIndices%
Return





TV_ColorInitiate(Gui_Number=1, Control="") ; initiate treeview color change procedure
{
  global hw_TV_ColorChange
  If Control =
    Control := "SysTreeView321"
  Gui, %Gui_Number%:+Lastfound
  Gui_ID := WinExist()
  ControlGet, hw_TV_ColorChange, HWND,, %Control%, ahk_id %Gui_ID%
  OnMessage( 0x4E, "WM_NOTIFY" )
}

TV_ColorChange(treeIndex="", TextColor="", BackColor="") ; change specific line's color or reset all lines
{
    global
    If treeIndex =
    {
        Loop, % TV_GetCount()
        {
            treeIndex := TV_GetNext(treeIndex)
            If (treeIndex == 0) ; root
                Break
            TV_ColorChange(treeIndex,TextColor,BackColor)
        }       
    }
    Else
    {
        Line_Color_%treeIndex%_Text := TextColor
        Line_Color_%treeIndex%_Back := BackColor
        WinSet, Redraw,, ahk_id %hw_TV_ColorChange%
    }   
}

WM_NOTIFY( p_w, p_l, p_m )
{
    local  draw_stage, Current_Line, treeIndex
    if ( DecodeInteger( "uint4", p_l, 0 ) = hw_TV_ColorChange )
    {
        if ( DecodeInteger( "int4", p_l, 8 ) = -12 )
        {                            ; NM_CUSTOMDRAW
            draw_stage := DecodeInteger( "uint4", p_l, 12 )
            if ( draw_stage = 1 )                                                 ; CDDS_PREPAINT
                return, 0x20                                                      ; CDRF_NOTIFYITEMDRAW
            else if ( draw_stage = 0x10000|1 )
            {   ; CDDS_ITEM
                Current_Line := DecodeInteger( "uint4", p_l, 36 )+1
                TV_GetText(Current_Line,treeIndex)
                If (Line_Color_%treeIndex%_Text != "")
                {
                    EncodeInteger( Line_Color_%treeIndex%_Text, 4, p_l, 48 )   ; foreground
                    EncodeInteger( Line_Color_%treeIndex%_Back, 4, p_l, 52 )   ; background
                }
            }
        }
    }
}

DecodeInteger( p_type, p_address, p_offset, p_hex = true )
{
  old_FormatInteger := A_FormatInteger
  ifEqual, p_hex, 1, SetFormat, Integer, hex
  else, SetFormat, Integer, dec
  StringRight, size, p_type, 1
  loop, %size%
      value += *( ( p_address+p_offset )+( A_Index-1 ) ) << ( 8*( A_Index-1 ) )
  if ( size <= 4 and InStr( p_type, "u" ) != 1 and *( p_address+p_offset+( size-1 ) ) & 0x80 )
      value := -( ( ~value+1 ) & ( ( 2**( 8*size ) )-1 ) )
  SetFormat, Integer, %old_FormatInteger%
  return, value
}

EncodeInteger( p_value, p_size, p_address, p_offset )
{
  loop, %p_size%
    DllCall( "RtlFillMemory", "uint", p_address+p_offset+A_Index-1, "uint", 1, "uchar", p_value >> ( 8*( A_Index-1 ) ) )
}

AddSubFoldersToTree(Folder, ParentItemID = 0)
{
    ; This function adds to the TreeView all subfolders in the specified folder.
 
 ; It also calls itself recursively to gather nested folders to any depth.
    Loop %Folder%\*.*, 2  ; Retrieve all of Folder's sub-folders.
        AddSubFoldersToTree(A_LoopFileFullPath, TV_Add(A_LoopFileName, ParentItemID))
}

_________________
Hardware: 1.8 GHz laptop with 4 GB ram, Windows XP/SP3
Software: Prevx, Privatefirewall, KeyScrambler.
Back to top
View user's profile Send private message
notbryant



Joined: 20 Feb 2009
Posts: 36

PostPosted: Sat Dec 19, 2009 8:12 am    Post subject: Re: Listview colors for individual lines (e.g. highlighting) Reply with quote

I know this topic is quite old, but I have a few reasons for posting in it.
(1) To thank evl for such a wonderful easy script.
(2) To address a trick I found with the script.
(3) To ask one more quick question about functionality.

1. Thanks so much, evl! I thought of this feature, and I doubted that anyone had come up with an easy way to do it, but I guess I underestimated the AHK community. Very Happy

2. I noticed that there was a noticable....flaw in the initial code, and I only mention it because I see that someone else asked it some time ago, and it has been unanswered.

koro wrote:
It seems like you're using the contents of the listview cell as part of a variable name!


I was confused to this as well, but I fixed it by changing
Code:
        Current_Line := DecodeInteger( "uint4", p_l, 36 )+1
              LV_GetText(Index, Current_Line)
              If (Line_Color_%Index%_Text != ""){
                  EncodeInteger( Line_Color_%Index%_Text, 4, p_l, 48 )   ; foreground
                  EncodeInteger( Line_Color_%Index%_Back, 4, p_l, 52 )   ; background


into this:
Code:
        Index := DecodeInteger( "uint4", p_l, 36 )+1
              If (Line_Color_%Index%_Text != ""){
                  EncodeInteger( Line_Color_%Index%_Text, 4, p_l, 48 )   ; foreground
                  EncodeInteger( Line_Color_%Index%_Back, 4, p_l, 52 )   ; background


And that works regardless of what you have in the first column. Smile

3. As I've used this script the past few days, I've been very impressed. The only thing I can see that is a problem is that the colors don't follow their respective lines if you sort by clicking the column header. Is there any quick, easy way to tell what row is which after a sort? For example, it might go
2
1
3
Is there any way to know that row 2 is first? If so, then it would be relatively easy to keep track of what rows need to be highlighted after a sort (at least in my case).

Anyway, I hope I'm not bringing up a thoroughly dead topic. Just thought I'd share my two cents on the subject.

-he who eats pie
Back to top
View user's profile Send private message
Yook



Joined: 20 Nov 2008
Posts: 70
Location: Thionville, France

PostPosted: Fri Feb 05, 2010 11:42 pm    Post subject: Reply with quote

I take the opportunity to tell that I have rewritten the functions to support multiple listviews here.

@he who eats pie:
for (2), the code was correct, and it is actually what makes (3) possible: to have the colors follow their rows when reordering, the first column of the listview must contain a list of integers.
Back to top
View user's profile Send private message
HighRiseWriter



Joined: 15 Jan 2011
Posts: 35

PostPosted: Sat Aug 06, 2011 3:38 pm    Post subject: Reply with quote

I can't get this code or any of the examples to work. Is this compatible with AHK_L 64bit on Win 7?
Back to top
View user's profile Send private message
[VxE]



Joined: 07 Oct 2006
Posts: 3254
Location: Simi Valley, CA

PostPosted: Sat Aug 06, 2011 5:59 pm    Post subject: Reply with quote

HighRiseWriter wrote:
I can't get this code or any of the examples to work. Is this compatible with AHK_L 64bit on Win 7?

No, the code does not make allowance for the increased size of handles and pointers on x64 systems (not the author's fault, the original code is 5 years old).

Handles and pointers are 4 bytes on 32 bit systems, but are 8 bytes on x64, which means that wherever you see a struct member type that starts with 'H' or 'Lp', or ends with 'ptr', you'll have to increase the offset for each member after it by 4.
_________________
Ternary (a ? b : c) guide     TSV Table Manipulation Library
Post code inside [code][/code] tags!
Back to top
View user's profile Send private message
HighRiseWriter



Joined: 15 Jan 2011
Posts: 35

PostPosted: Sat Aug 06, 2011 6:07 pm    Post subject: Reply with quote

Quote:
No, the code does not make allowance for the increased size of handles and pointers on x64 systems (not the author's fault, the original code is 5 years old).

Handles and pointers are 4 bytes on 32 bit systems, but are 8 bytes on x64, which means that wherever you see a struct member type that starts with 'H' or 'Lp', or ends with 'ptr', you'll have to increase the offset for each member after it by 4.


I was afraid of that. Thanks for the info and the quick reply.
Back to top
View user's profile Send private message
Display posts from previous:   
Reply to topic    AutoHotkey Community Forum Index -> Scripts & Functions All times are GMT
Goto page Previous  1, 2
Page 2 of 2

 
Jump to:  
You can post new topics in this forum
You can reply to topics in this forum


Powered by phpBB © 2001, 2005 phpBB Group