AutoHotkey Community

It is currently May 25th, 2012, 4:15 am

All times are UTC [ DST ]




Post new topic Reply to topic  [ 11 posts ] 
Author Message
PostPosted: May 7th, 2007, 6:51 am 
Offline

Joined: November 27th, 2006, 7:41 am
Posts: 222
Location: Queensland, Australia
I have a gui listview with checkboxes, and I would like to disable the checkboxes from time to time without effecting their checked or unchecked status.
I recall reading something about using a -1 to indicate a disabled check, but I don't think it related to listviews.
Is this possible?


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: May 8th, 2007, 3:49 pm 
Offline

Joined: December 1st, 2006, 9:27 am
Posts: 460
I couldn't find anywhere to just disable listview checkboxes. I came up with this, though:
Code:
;*************from the help file**************
Gui, Add, ListView, r20 w700 Checked vlist1, Name|Size (KB)
; Gather a list of file names from a folder and put them into the ListView:
Loop, %A_MyDocuments%\*.*
    LV_Add("", A_LoopFileName, A_LoopFileSizeKB)
;****************************************
Gui,Add,Button, ggo, go
Gui, Show
return

go:
   toggle := !toggle
   if(toggle)
   {   gosub getLVchecks
      GuiControl,-LV0x4,SysListView321   ;turn off checks
   }
   Else
   {   GuiControl,+LV0x4,SysListView321   ;turn on checks
      gosub setLVchecks
   }
Return

setLVchecks:   ;read setting from LV
   Loop,parse, LV,CSV
   {   If(A_LoopField = A_Index)   ;Weird! Empties return next one that's checked!
      {   LV_Modify(A_Index, "Check")   ; Must make sure it's the right one.
      }
   }
   LV=
Return

getLVchecks:   ;save setting to LV var
   Loop % LV_GetCount()
   {   LV .= LV_GetNext(A_Index-1,"C") . ","
   }
Return

guiClose:
   ExitApp
Return

The big problem with this, however, is that if anything changes between hide/show the values are no longer valid. Once checks are disabled, you couldn't add or remove any rows unless you re-enable the checks before any changes.

_________________
Image


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: May 9th, 2007, 12:59 am 
Offline

Joined: November 27th, 2006, 7:41 am
Posts: 222
Location: Queensland, Australia
Interesting.
That seems to be the same behaviour I have mine doing at the moment with:
GuiControl,-Checked +NoSort,FILEINFORMATION
....
GuiControl,+Checked -NoSort,FILEINFORMATION

In my case the checkbox is always checked, as it's the mechanism by which the user can delete listview entries; removing the check deletes the row.
While the script is running (it posts a constant stream of images to a website) the user can add more files to the bottom of the list, but I wanted to use the checkboxes as disabled to indicate that the associated file/row had already been posted, or was currently being posted, and therefore could not be edited or removed ...until the user paused or aborted the posting stream - which makes it easier for the processing loop, as well as visually to keep track of what's going on.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: May 9th, 2007, 9:27 am 
Offline

Joined: December 1st, 2006, 9:27 am
Posts: 460
Ok, so you needed to enable and disable each checkbox independently. I didn't see anything that made me believe it was possible in ahk. (I know it's possible - that may be an item for the wish list.)

[EDIT]
Kind of a hack, but you could prepend something to the first column of each row that is uploaded, like "Done - ". It wouldn't prevent someone from clicking the check, but you could always disable the click handler during processing.

_________________
Image


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: May 9th, 2007, 10:42 am 
Offline

Joined: November 27th, 2006, 7:41 am
Posts: 222
Location: Queensland, Australia
Micahs wrote:
prepend something to the first column of each row

Excellent point. I already have a couple of row items that would suit this quite well. (initially are empty, and after processing they contain either a number or an error message)
I was also considering going as far as putting a semi-opaque splash over the completed rows. Or changing the colour of the row - but I haven't really looked into that too much. My initial impression (of changing individual row colours, or cell colours) was that it couldn't be done, but now I'm thinking it might be possible, after reading about how to change the colour of a progressbar with :
Gui, +cGreen, MyProgressbar


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: May 9th, 2007, 11:29 am 
Offline

Joined: December 27th, 2005, 1:46 pm
Posts: 6837
Location: France (near Paris)
You can hide each checkbox individually. Problem: this actually changes the image at the start of the row, so it also changes the state of the checkbox, which might not be what you wanted. I give it here for reference, anyway, it might be a starting point, or useful for somebody else.
Based on Micahs' code above.
Code:
LVM_SETITEMSTATE = 4139
/*
typedef struct _LVITEM {
    UINT mask;
    int iItem;
    int iSubItem;
    UINT state;     -> offset 12
    UINT stateMask; -> offset 16
    LPTSTR pszText;
    int cchTextMax;
    int iImage;
    LPARAM lParam;
#if (_WIN32_IE >= 0x0300)
    int iIndent;
#endif
#if (_WIN32_WINNT >= 0x560)
    int iGroupId;
    UINT cColumns; // tile view columns
    PUINT puColumns;
#endif
#if (_WIN32_WINNT >= 0x0600)
    int* piColFmt;
    int iGroup;
#endif
} LVITEM, *LPLVITEM;
*/
VarSetCapacity(LVItem, 36, 0)

;*************from the help file**************
Gui, Add, ListView, r20 w700 Checked vlist1, Name|Size (KB)
; Gather a list of file names from a folder and put them into the ListView:
Loop, %A_MyDocuments%\*.*
    LV_Add("", A_LoopFileName, A_LoopFileSizeKB)
;****************************************
Gui,Add,Button, gGo, Go!
Gui, Show
return

Go:
   SetInteger(LVItem, 0xF000, 16)  ; LVITEM->stateMask = LVIS_STATEIMAGEMASK
   Loop % LV_GetCount()
   {
      m := Mod(A_Index, 3)
      If (m = 0)
      {
         SetInteger(LVItem, 0x0000, 12)  ; LVITEM->state = disabled
      }
      Else If (m = 1)
      {
         SetInteger(LVItem, 0x1000, 12)  ; LVITEM->state = unchecked
      }
      Else If (m = 2)
      {
         SetInteger(LVItem, 0x2000, 12)  ; LVITEM->state = checked
      }
      SendMessage LVM_SETITEMSTATE, A_Index - 1, &LVItem, SysListView321, A
   }
Return

GuiClose:
ExitApp

SetInteger(ByRef @dest, _integer, _offset = 0, _size = 4)
{
   Loop %_size%  ; Copy each byte in the integer into the structure as raw binary data.
   {
      DllCall("RtlFillMemory"
            , "UInt", &@dest + _offset + A_Index-1
            , "UInt", 1
            , "UChar", (_integer >> 8*(A_Index-1)) & 0xFF)
   }
}
Maybe you can play with values above 0x2000 (ie. 0x4000 and more) to store the current state while still displaying an empty space.

_________________
Image vPhiLho := RegExReplace("Philippe Lhoste", "^(\w{3})\w*\s+\b(\w{3})\w*$", "$1$2")


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: May 9th, 2007, 1:30 pm 
Offline

Joined: November 27th, 2006, 7:41 am
Posts: 222
Location: Queensland, Australia
Hmm.... this certainly works... and as you said has the disadvantage of altering the checkbox original state.... but it also allows the 'invisible/disabled' checkbox to be checked/unchecked and made visible again if the user clicks where it should be (even though it's not visible).

As always, I have kept this code in my 'sure to be useful later' box of tricks, but for this script I think I will change the way my UI works, and remove this item entirely... the more i use it, and the more it proves difficult to disable checkboxes the more I see that it's not the best interface either.
I think a selection of focussed rows and a "delete" gui button and/or the DEL key will be far more intuitive in this case.

Thanks Micahs, PhiiLho.
I learn some interesting new things every time I ask a question here.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: May 9th, 2007, 3:16 pm 
Offline

Joined: December 1st, 2006, 9:27 am
Posts: 460
This does not work reliably, but I'll post it 'cause it may be something stupid I did wrong.
It tries to disable the checkboxes in the listview. It works great and then doesn't do anything - very frustrating. When it works it stops the checkbox from changing state. Maybe you guys can do something with it, but there's probably something inherently wrong with the method, though.
Code:
Gui,+LastFound
guiID := WinExist()
SysGet, SM_CXVSCROLL, 2   ;width of vert scrollbar - to fudge the width of the checkbox of listview

;*************from the help file**************
Gui, Add, ListView, r20 w700 Checked vFILEINFORMATION glistClick AltSubmit, Name|Size (KB)   ;AltSubmit
; Gather a list of file names from a folder and put them into the ListView:
Loop, %A_MyDocuments%\*.*
{   LV_Add("", A_LoopFileName, A_LoopFileSizeKB)
}
LV_ModifyCol() 
;****************************************
Gui,Add,Checkbox, vLVdisable gLVdisable, Listbox Disable
Gui, Show
OnMessage(0x201,"WM_LBUTTONDOWN")
return

listClick:
   If(A_GuiEvent = "I")
   {   If(fake=1)   ;try to ignore events we've created
      {   fake=0
         Return
      }
      MouseGetPos,lx
      ControlGetPos,ox,,,,SysListView321,ahk_id %guiID%
      ControlGet, LVf, List, Count Focused, SysListView321
      xc := SM_CXVSCROLL+ox+10   ;guesstimate the width of the check
      ;if the row with focus is the same as in eventinfo and not too far right and disabled
      If((A_EventInfo = LVf) and lx <= xc) and (LVdisable)
      {   LVc := LV_GetNext(LVf-1,"C")
         If(LVc = LVf)
         {   fake=1
            LV_Modify(LVf, "-Check")
         }
         Else
         {   fake=1
            LV_Modify(LVf, "Check")
         }
      }
   }
Return

WM_LBUTTONDOWN()   ;this just selects the row if checkbox clicked
{
   global
   MouseGetPos,lx,ly,outW,outK
   if(outW = guiID) and (outK = "SysListView321")   ;over the listview
   {   ControlGetPos,ox,oy,,,SysListView321,ahk_id %guiID%
      cx := ox + 50
      cy := ly
      fake=1
      ControlClick,x%cx% y%cy%,ahk_id %guiID%
   }
}

LVdisable:
   Gui, Submit, NoHide
Return

guiClose:
   ExitApp
Return

_________________
Image


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: May 10th, 2007, 4:41 am 
Offline

Joined: November 27th, 2006, 7:41 am
Posts: 222
Location: Queensland, Australia
Hmm. Doesn't seem to work at all for me.
It occasionally seems to work for a fraction of a second, but then the checkbox goes and does it's thing anyway.
I assume this is because of in-built assumptions, and how they differ on our respective machines:
Quote:
;if the row with focus is the same as in eventinfo and not too far right and disabled
I had already tried a similar approach to this: where my processing loop set a variable to indicate its A_Index, and the listview click handler simply ignored (and gave info as a traytip about the null response) any clicks on already processed items, and then immediately forced the checkbox to be checked again.
It works, but having a *visually* disabled checkbox (or a greyed out row) was much more preferable.

so:
Last night i decided to use an icon column with IL_Add(), mainly because it will give me the total control I need, but also because I feel very hesitant to use any kind of sendmessage to alter a listview. The help file recommends against it, and as we appear to be seeing in this thread; it can be a bit convoluted and quite unpredictable.
...and of course, i can still get the same visual appearance with an icon of a checkbox with 3 available states (checked, unchecked and *disabled*).
However the wider availability of icons to use is also very appealing, and could greatly simplify my current use of numerous cells....plus be graphically far more intuitive.


Last edited by BETLOG on May 10th, 2007, 4:49 am, edited 1 time in total.

Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: May 10th, 2007, 4:45 am 
Offline

Joined: December 1st, 2006, 9:27 am
Posts: 460
Quote:
Hmm. Doesn't seem to work at all for me.

I'm not surprised in the least!

_________________
Image


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: May 10th, 2007, 9:47 am 
Offline

Joined: November 27th, 2006, 7:41 am
Posts: 222
Location: Queensland, Australia
Hmm, it seems that now that I have looked into imagelists a bit more, that the do not in fact offer much more simplicity as i had asumed. It seems that I'll need to be constantly creating and destroying icon lists.


Report this post
Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 11 posts ] 

All times are UTC [ DST ]


Who is online

Users browsing this forum: Bing [Bot], Google Feedfetcher, poserpro, Yahoo [Bot] and 21 guests


You can post new topics in this forum
You can reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Powered by phpBB® Forum Software © phpBB Group