 |
AutoHotkey Community Let's help each other out
|
| View previous topic :: View next topic |
| Author |
Message |
almex
Joined: 16 Oct 2007 Posts: 10 Location: Las Vegas, NV, USA
|
Posted: Mon Feb 04, 2008 6:44 pm Post subject: |
|
|
| 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 |
|
 |
tic
Joined: 22 Apr 2007 Posts: 1786
|
Posted: Thu Feb 14, 2008 7:17 am Post subject: |
|
|
| its a shame this still hasnt been built into ahk... |
|
| Back to top |
|
 |
stomasik
Joined: 29 May 2008 Posts: 4
|
Posted: Mon Jun 16, 2008 1:42 pm Post subject: |
|
|
| 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 |
|
 |
cyril171080 Guest
|
|
| Back to top |
|
 |
koro
Joined: 24 Sep 2006 Posts: 61
|
Posted: Sat Jul 11, 2009 11:47 pm Post subject: Re: Listview colors for individual lines (e.g. highlighting) |
|
|
| 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 |
|
 |
pajenn
Joined: 07 Feb 2009 Posts: 384
|
Posted: Wed Sep 09, 2009 5:51 pm Post subject: |
|
|
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 |
|
 |
notbryant
Joined: 20 Feb 2009 Posts: 36
|
Posted: Sat Dec 19, 2009 8:12 am Post subject: Re: Listview colors for individual lines (e.g. highlighting) |
|
|
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.
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.
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 |
|
 |
Yook
Joined: 20 Nov 2008 Posts: 70 Location: Thionville, France
|
Posted: Fri Feb 05, 2010 11:42 pm Post subject: |
|
|
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 |
|
 |
HighRiseWriter
Joined: 15 Jan 2011 Posts: 35
|
Posted: Sat Aug 06, 2011 3:38 pm Post subject: |
|
|
| 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 |
|
 |
[VxE]
Joined: 07 Oct 2006 Posts: 3254 Location: Simi Valley, CA
|
Posted: Sat Aug 06, 2011 5:59 pm Post subject: |
|
|
| 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 |
|
 |
HighRiseWriter
Joined: 15 Jan 2011 Posts: 35
|
Posted: Sat Aug 06, 2011 6:07 pm Post subject: |
|
|
| 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 |
|
 |
|
|
You can post new topics in this forum You can reply to topics in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|