Ebenezer Posted May 25, 2006 Posted May 25, 2006 Hi everyone.I'm trying to create a program to store links. To keep the stored links organized I would like to have the option to create groups and drag links to them just like you can drag files to folders in the windows explorer.My GUI:Unfortunately I can't find a way for autoit to recognize the listview entry the mouse is hovering over when the button is released.-@Drag_id etc only recognize the listview control, not the individual entries.-Hottracking does recognize them but does not work during a drag&drop operation-Calculating the entry from the mouse x/y coordinates is rather error-prone at ca 13 pixels height per group and gets worse if the program should be usable on different resolutions.I found the following code that seems to be close to what I'm lookin for but lack the C++ knowledge to costumize the code to my needs.expandcollapse popup#include <GuiConstants.au3> ;by wiredbits ;Treeview HitTest ;mostly beginer stuff, I need to go and read all of Autoit functions now:P ;using beta version 1.99 ;few examples (simple) of Treeview Hittest ;right mouse button (secondary) selection of Treeview item ;drag and drop child items between parents ;drag file onto treeview and if a hit add to treeview ;context menu cut, copy, paste, and delete a treeview item ;********************************************************************************************** Const $TVGN_NEXT = 0x1 CONST $TVGN_PREVIOUS= 2 Const $TVGN_CHILD = 0x4 CONST $TVGN_FIRSTVISIBLE = 0x0005 Const $TVGN_CARET = 0x9 Const $TVGN_ROOT= 0 Const $TV_FIRST = 0x1100 Const $TVM_DELETEITEM = ($TV_FIRST + 1) CONST $TVM_GETNEXTITEM = ($TV_FIRST + 10) Const $TVM_SORTCHILDREN = ($TV_FIRST + 19) CONST $TVM_SELECTITEM = ($TV_FIRST + 11) CONST $TVM_SETINSERTMARK= ($TV_FIRST + 26) CONST $TVM_HITTEST= ($TV_FIRST+17) CONST $TVM_CREATEDRAGIMAGE= ($TV_FIRST+18);i really need to read up on this, might be better than draging a control CONST $TVGN_DROPHILITE= 8 CONST $TVM_GETBKCOLOR =($TV_FIRST+31) CONST $TVM_GETTEXTCOLOR= ($TV_FIRST+32) Const $TVM_SETITEM= ($TV_FIRST+13) CONST $TVGN_PARENT= 3 ;********************************************************************************************* CONST $TVHT_NOWHERE=1 CONST $TVHT_ONITEMICON=2 CONST $TVHT_ONITEMLABEL=4 CONST $TVHT_ONITEMINDENT=8 CONST $TVHT_ONITEMBUTTON=16 CONST $TVHT_ONITEMRIGHT=32 CONST $TVHT_ONITEMSTATEICON=64 CONST $TVHT_ABOVE= 256 CONST $TVHT_BELOW=512 CONST $TVHT_TORIGHT= 1024 CONST $TVHT_TOLEFT= 2048 CONST $TEST=BitOR($TVHT_ONITEMICON,$TVHT_ONITEMLABEL,$TVHT_ONITEMSTATEICON,$TVHT_ONITEMINDENT,$TVHT_ONITEMBUTTON,$TVHT_ONITEMRIGHT) ;********************************************************************************************** CONST $WM_VSCROLL =277 CONST $WM_HSCROLL= 276 CONST $SBM_GETPOS= 225 CONST $SB_LINEUP=0 CONST $SB_LINEDOWN=1 CONST $SB_LINELEFT= 0 CONST $SB_LINERIGHT= 1 CONST $SB_LEFT=6 CONST $SB_RIGHT= 7 ;*************************************************************************************************** *** CONST $NUM_PARS=6 CONST $NUM_KIDS=6 CONST $PAR_NUMPARS= 0 CONST $PAR_CTRLID= 1 CONST $PAR_NAME = 2 CONST $KID_NUMKIDS= 0 CONST $KID_PARID= 1 CONST $KID_PARINDEX=2 CONST $KID_CTRLID= 3 CONST $KID_NAME= 4 ;*************************************************************************************************** ******** CONST $DR_MONITORDRAG= 1 CONST $DR_ISDRAG= 2 CONST $DR_CHECKSCROLL= 4 CONST $ED_CUT=1 CONST $ED_COPY=2 ;*************************************************************************************************** ******** Dim $parents[$NUM_PARS][3] Dim $kids[$NUM_KIDS*$NUM_PARS][5] $winHandle = GuiCreate("Treeview Hitest Examples", 348, 450, 200, 5, $WS_OVERLAPPEDWINDOW,$WS_EX_ACCEPTFILES) GUISetFont(10,400) $ClassTreeview = GUICtrlCreateTreeView(24, 40, 300, 385) GUICtrlSetState(-1,$GUI_DROPACCEPTED); to allow drag and dropping ;i remember when i first saw the dummy control...thought i would never use them ;then i saw some examples and thought..dummy...LOL $killdrag= GUICtrlCreateDummy() $kidDummy= GUICtrlCreateDummy() $parDummy= GUICtrlCreateDummy() $parmenu = GUICtrlCreateContextMenu ($parDummy) $contexPDelete=GUICtrlCreateMenuitem ("Delete", $parmenu) $contexPPaste=GUICtrlCreateMenuitem ("Paste Item", $parmenu) $kidMenu = GUICtrlCreateContextMenu ($kidDummy) $contexCut=GUICtrlCreateMenuitem ("Cut", $kidMenu) $contexCopy=GUICtrlCreateMenuitem ("Copy", $kidMenu) $contexPaste=GUICtrlCreateMenuitem ("Paste", $kidMenu) GUICtrlSetState(-1,$GUI_DISABLE) $contextDeleteItem=GUICtrlCreateMenuitem ("Delete", $kidMenu) GuiSetState(@SW_SHOW ,$winhandle) ;should make the following local $savex=0 $savey=0 $droptime=0 $dropflag=0 $hfromparent=-1 $fromkidID=-1 $editflag=0 SetUpTreeview() Main() Exit Func Main() Local $admsg,$msg,$hitem,$x While 1 $admsg = GuiGetMsg(1) $msg=$admsg[0] Select Case $msg=$killdrag $droptime=0 $dropflag=0 ;secondary mouse selection Case $msg=$GUI_EVENT_SECONDARYDOWN $savex=$admsg[3] $savey=$admsg[4];save mouse positions ;force user to click on a treeview item label to get context menu...could give an optional menu if no hit $hitem=TV_Hittest($ClassTreeview,$savex,$savey,$TVHT_ONITEMRIGHT,0) If $hitem Then $x=GUICtrlSendMsg($ClassTreeView,$TVM_GETNEXTITEM,$TVGN_CARET,0);get current If $x<>$hitem Then GUICtrlSendMsg($ClassTreeView,$TVM_SELECTITEM,$TVGN_CARET,$hitem);select hit item if not already TV_DoContextMenu($ClassTreeView,$hitem) EndIf Case $msg=$GUI_EVENT_MOUSEMOVE If BitAND($dropflag,$DR_MONITORDRAG) Then If TV_CheckIfDrag($ClassTreeview) Then $hitem=GUICtrlSendMsg($ClassTreeView,$TVM_GETNEXTITEM,$TVGN_CARET,0);on return focus is always on child...in this example $hitem=GUICtrlSendMsg($ClassTreeView,$TVM_GETNEXTITEM,$TVGN_PARENT,$hitem) GUICtrlSendMsg($ClassTreeView,$TVM_SORTCHILDREN ,0,$hitem);wParam (3rd parameter) a bool to recurse or not GUICtrlSendMsg($ClassTreeView,$WM_HSCROLL,$SB_LEFT ,0);force treeview to left EndIf EndIf Case $msg=$contexCut TV_Cut($ClassTreeView) Case $msg=$contexCopy TV_Copy($ClassTreeView) Case $msg=$contexPaste Or $msg=$contexPPaste TV_Paste($ClassTreeView,$savex,$savey) Case $msg=$contextDeleteItem Or $msg=$contexPDelete TV_DeleteItem($ClassTreeview) case $msg=$GUI_EVENT_DROPPED TV_DropFIle($ClassTreeview) Case $msg=$GUI_EVENT_CLOSE ExitLoop Case $msg>$parents[0][$PAR_CTRLID];could check if a child ID then set flag $dropflag=BitOR($dropflag,$DR_MONITORDRAG) EndSelect WEnd EndFunc Func TV_DoContextMenu($Treeview,$hitem) Local $hpar $hpar=GUICtrlSendMsg($TreeView,$TVM_GETNEXTITEM,$TVGN_PARENT,$hitem) If $hitem Then If $fromkidID=-1 Or $hpar=$hfromparent Or $hitem=$hfromparent Then GUICtrlSetState($contexPaste,$GUI_DISABLE) GUICtrlSetState($contexPPaste,$GUI_DISABLE) Else GUICtrlSetState($contexPaste,$GUI_ENABLE) GUICtrlSetState($contexPPaste,$GUI_ENABLE) EndIf If $hpar Then ShowMenu($winHandle,$kidMenu,$Treeview) Else ShowMenu($winHandle,$parMenu,$Treeview) EndIf EndIf EndFunc Func TV_CheckIfDrag($TreeView) Local $id,$hitem,$droplabel=0 CONST $DRAGBUTTON=2;primary button CONST $CTRLID=4 $mouse = GUIGetCursorInfo($winHandle) If NOT @error then If $mouse[$DRAGBUTTON] And $mouse[$CTRLID] = $TreeView Then if $droptime=0 Then $droptime=TimerInit() ElseIf TimerDiff($droptime)>70 Then $hitem=GUICtrlSendMsg($TreeView,$TVM_GETNEXTITEM,$TVGN_CARET,0) $hitem=GUICtrlSendMsg($TreeView,$TVM_GETNEXTITEM,$TVGN_PARENT,$hitem);returns 0 if hitem is a parent If $hitem Then;only move a kid $ctrlmsg=GUICtrlRead($TreeView,1) $droplabel= GuiCtrlCreateLabel($ctrlmsg[0],$mouse[0],$mouse[1],200,16,-1) ; $droplabel= GUICtrlCreateIcon("shell32.dll",175,$mouse[0],$mouse[1]) $id=TV_DoDrag($TreeView,$droplabel) GUICtrlDelete($droplabel) GUICtrlSendToDummy ($killdrag);msg comes after any select item from drag Return $id EndIf EndIf EndIf EndIf EndFunc ;drag a control around treeview until primary mouse button is released, if child was draged into ;different parrent group then create new child and delete old child. ;orginally in a msg loop....trying it this way for now ;On Entry: Treeview control ID, control ID to drag ;On Exit: new child control ID else 0 Func TV_DoDrag($TreeView,$dragctrl) Local $msg,$i,$x,$curkid,$hscroll,$vscroll,$hparent,$hitem,$hpar Local $left,$top,$width,$height,$dtime,$isdrag CONST $DRAGFINISHED=2;$GUI_EVENT_PRIMARYUP;could use varables instead then use either button to drag $hitem=GUICtrlSendMsg($TreeView,$TVM_GETNEXTITEM,$TVGN_CARET,0) $hparent=GUICtrlSendMsg($TreeView,$TVM_GETNEXTITEM,$TVGN_PARENT,$hitem);returns 0 if hitem is a parent MsgBox(0, "", $hitem) If NOT $hparent Then $hparent=$hitem $hitem=0 $x=ControlGetPos("","",$TreeView) If NOT @error Then $left=$x[0] $top=$x[1] $width=$x[2] $height=$x[3] $curkid=GUICtrlRead($TreeView,1) GUISetState(@SW_LOCK,$winhandle) $isdrag=1 Do $amsg=GUIGetMsg() ;cuts down on cpu cycles $msg = GUIGetCursorInfo($winHandle) If NOT @error Then If $dtime=0 And $msg[$DRAGFINISHED]=0 Then $dtime=TimerInit();button release wait time $vscroll=-1 $hscroll=-1 Select Case $msg[1]<$top $msg[1]=$top $vscroll=$SB_LINEUP Case $msg[1]>$top+$height $msg[1]=$top+$height $vscroll=$SB_LINEDOWN EndSelect Select Case $msg[0]<$left;x $hscroll=$SB_LINELEFT $msg[0]=$left Case $msg[0]>$left+$width $hscroll=$SB_LINERIGHT $msg[0]=$left+$width EndSelect GUISetState(@SW_UNLOCK,$winhandle) If $hscroll<>-1 or $vscroll<>-1 Then GUICtrlSetState($dragctrl,$GUI_HIDE) If $hscroll<>-1 Then GUICtrlSendMsg($TreeView,$WM_HSCROLL,$hscroll,0) If $vscroll<>-1 Then GUICtrlSendMsg($TreeView,$WM_VSCROLL,$vscroll,0) GUICtrlSetState($dragctrl,$GUI_SHOW) EndIf GuiCtrlSetPos( $dragctrl, $msg[0], $msg[1]) GUISetState(@SW_LOCK,$winhandle);windows updates scroll values during this unlock $hitem=TV_Hittest($Treeview, $msg[0], $msg[1],$TVHT_ONITEMRIGHT,0) If $hitem Then GUICtrlSendMsg($Treeview,$TVM_SELECTITEM ,$TVGN_DROPHILITE,$hitem) Else GUICtrlSendMsg($Treeview,$TVM_SELECTITEM ,$TVGN_DROPHILITE,0) EndIf $isdrag= $msg[$DRAGFINISHED] If NOT $isdrag And $droptime=0 then $droptime=TimerInit() EndIf Until NOT $isdrag And TimerDiff($dtime)>30 GUISetState(@SW_UNLOCK,$winhandle) GUICtrlSendMsg($Treeview,$TVM_SELECTITEM ,$TVGN_DROPHILITE,0) GUICtrlSetState($dragctrl,$GUI_HIDE) $hitem=TV_Hittest($Treeview, $msg[0], $msg[1],$TVHT_ONITEMRIGHT,0) If $hitem=0 Then Return 0; not a hit ;the folowing does not support sub items...accurately, might play with this later $hpar=GUICtrlSendMsg($TreeView,$TVM_GETNEXTITEM,$TVGN_PARENT,$hitem) If $hpar=0 Then $hpar=$hitem If $hpar=$hparent Then Return 0;dropped on current parent group If ($curkid[1])=$fromkidID Then $fromkidID=-1;kill paste GUICtrlDelete($curkid[1]) If $hpar Then GUICtrlSendMsg($TreeView,$TVM_SELECTITEM,$TVGN_CARET,$hpar);focus so can get control ID $hpar=GUICtrlRead($TreeView);get control id ; $hpar=GetparentID($hpar);get parent ID without useing above two lines of code ;housekeeping: if you are using arrays to track kids and parents adjust here ;as in...delete/add or update arrays $hitem=GUICtrlCreateTreeViewItem($curkid[0],$hpar) If $hitem Then GUICtrlSetState($hitem,$GUI_FOCUS) EndIf Return $hitem;return new child's control id if any EndFunc ;On Entry: Treeview control ID ;On Exit: new control ID else 0 Func TV_DropFIle($Treeview) Local $mouse,$hitem,$hpar,$id $tmp=@GUI_DRAGFILE ;just playing here, do not want path in treeview $tmp=Stringmid($tmp, StringInStr($tmp, '\',0, -1)+1,-1) If $tmp="" Then $tmp=@GUI_DRAGFILE;drive was dropped ; $id=0 GUISetState(@SW_RESTORE ,$winhandle);make sure GUI has focus or will get an error $mouse = GUIGetCursorInfo($winHandle) If NOT @error Then $hitem=TV_Hittest($Treeview,$mouse[0],$mouse[1],$TVHT_ONITEMRIGHT,0) If $hitem Then $hpar=GUICtrlSendMsg($TreeView,$TVM_GETNEXTITEM,$TVGN_PARENT,$hitem) If $hpar=0 Then $hpar=$hitem GUICtrlSendMsg($TreeView,$TVM_SELECTITEM,$TVGN_CARET,$hpar) $id=GUICtrlRead($Treeview) $id=GUICtrlCreateTreeViewItem($tmp,$id) If $id Then GUICtrlSetState($id,$GUI_FOCUS);show new kid and expand parent if not GUICtrlSendMsg($TreeView,$TVM_SORTCHILDREN ,0,$hpar);wParam (3rd parameter) a bool to recurse or not GUICtrlSendMsg($TreeView,$WM_HSCROLL,$SB_LEFT ,0) EndIf EndIf EndIf Return $id EndFunc Func TV_Cut($Treeview) TV_SetEdit($Treeview,$ED_CUT) EndFunc Func TV_Copy($Treeview) TV_SetEdit($Treeview,$ED_COPY) EndFunc Func TV_SetEdit($Treeview,$edflag) Local $hitem,$hpar $fromkidID=-1 $editflag=0 $hitem=GUICtrlSendMsg($TreeView,$TVM_GETNEXTITEM,$TVGN_CARET,0) $hpar=GUICtrlSendMsg($TreeView,$TVM_GETNEXTITEM,$TVGN_PARENT,$hitem);returns 0 if hitem is a parent If $hpar Then; if a parent then hitem is a child...no cut or copying a parent $hitem=GUICtrlRead($TreeView) $fromkidID=$hitem $hfromparent=$hpar $editflag=$edflag EndIf EndFunc ;paste item into current parent group ;On Entry: Treeviw control ;On Exit new item contril ID else 0 Func TV_Paste($Treeview,$x,$y) Local $hitem,$hpar,$curkid,$parid,$id $id=0 If $fromkidID=-1 Then Return 0 $hitem=TV_Hittest($Treeview,$x,$y,$TVHT_ONITEMRIGHT,0) If NOT $hitem Then return 0 $hpar=GUICtrlSendMsg($TreeView,$TVM_GETNEXTITEM,$TVGN_PARENT,$hitem) If NOT $hpar Then $hpar=$hitem If $hpar=$hfromparent Then Return 0 GUICtrlSendMsg($TreeView,$TVM_SELECTITEM,$TVGN_CARET,$hpar) $parid=GUICtrlRead($TreeView);get control id $curkid=GUICtrlRead($fromkidID,1);kid info $id=GUICtrlCreateTreeViewItem($curkid[0],$parid) If $id Then GUICtrlSetState($id,$GUI_FOCUS) GUICtrlSendMsg($TreeView,$TVM_SORTCHILDREN ,0,$hpar) If $editflag=$ED_CUT Then GUICtrlDelete($fromkidID) $editflag=0 $fromkidID=-1 EndIf Return $id EndFunc ;delete current item Func TV_DeleteItem($Treeview) Local $id $id=GUICtrlRead($TreeView,1) If NOT @error Then If MsgBox(36,"Delete Item","Delete " &$id[0]&" ?")=7 Then Return ;if tracking with arrays then update here If $id[1]=$fromkidID Then $fromkidID=-1 GUICtrlSetState($contexPaste,$GUI_DISABLE); to allow drag and dropping EndIf GUICtrlDelete($id[1]);if a parent really should loop through all childern and delete them first:P EndIf EndFunc ;just test to see if mouse positions passed will hit a treeview item if it does then set focus ;On Entry: control id of treeview, mouse x and y positions to test, and optional exclude hit area and no foucs ;on Eixt: handle to control if a hit...else 0 ;should be easy to modify and use with listviews, which i have yet to play with Func TV_Hittest($TreeView,$x,$y,$nohit=0,$focus=1) Local $i,$hitinfo,$hit,$tpos $i=0 ;get top and left positions of treeview control $tpos=ControlGetPos("","",$TreeView) If NOT @error Then $x=$x-$tpos[0] ;left offset $y=$y-$tpos[1];$top offset $hitinfo=DllStructCreate("int;int;uint;uint");not sure if uint or ptr should go here...will look it up..32 bits is 32 bits If NOT @error Then DllStructSetData($hitinfo,1,$x) DllStructSetData($hitinfo,2,$y) DllStructSetData($hitinfo,3,0) DllStructSetData($hitinfo,4,0) GUICtrlSendMsg($TreeView,$TVM_HITTEST,0,DllStructGetPtr($hitinfo)) $hit=DllStructGetData ($hitinfo,3);flags returned $i= DllStructGetData ($hitinfo,4);handle $hitinfo=0;DllStructDelete($hitinfo); seems no DllStructDelete in beta version 1.99 If BitAND($hit,$nohit) Then Return 0 If BitAND($hit,$TEST)=0 Then return 0 If $i And $focus<>0 Then MsgBox(0, "", $hit) ;~ GUICtrlSendMsg($TreeView,$TVM_SELECTITEM,$TVGN_CARET,$i) EndIf EndIf Return $i;return control handle if any EndFunc ;return parent control ID that matches handle passed ;On Enry: handle to parent treeviewitem control ;on Exit: control ID else 0 Func GetparentID($hpar) Local $i,$hitem For $i=0 To $parents[0][0]-1 $hitem=GUICtrlGetHandle($parents[$i][$PAR_CTRLID]);could use kid array If $hitem=$hpar Then Return $parents[$i][$PAR_CTRLID] Next;i Return 0 EndFunc ;fill arrays in case someone wants to play with code Func SetUpTreeview() Local $i,$x,$parent,$kid,$parid,$cnt=0,$y $parent="Parent-" $kid="Kid-" For $i=0 To $NUM_PARS-1 $parents[$i][$PAR_NAME]=$parent &$i+1 $parid=GUICtrlCreateTreeViewItem($parents[$i][$PAR_NAME], $ClassTreeview) $parents[$i][$PAR_CTRLID]=$parid For $x=0 To $NUM_KIDS-1 $kids[$cnt][$KID_NAME]=$parent&$i+1 & "-" &$kid &$x+1 $kids[$cnt][$KID_CTRLID]=GUICtrlCreateTreeViewItem($kids[$cnt][$KID_NAME],$parid) $kids[$cnt][$KID_PARID]=$parid $kids[$cnt][$KID_PARINDEX]=$i $cnt=$cnt+1 Next;x GUICtrlSetState($parid,$GUI_EXPAND) Next;i $parents[0][0]=$i $kids[0][0]=$cnt EndFunc ;*************************************************************************************************** *** ;copied from help file, who ever wrote these thanks much! ;modified to suit my needs ;*************************************************************************************************** ** ;Show a menu in a given GUI window which belongs to a given GUI ctrl ;On Entry: window handle, context menu ID and ;optional control ID this menu belongs to, if control is not under cursor then exit without calling menu popup ;On Exit: nada Func ShowMenu($hWnd,$nContextID,$ifunderID=0) Local $hMenu = GUICtrlGetHandle($nContextID) CONST $TPM_RIGHTBUTTON= 2 CONST $TPM_NONOTIFY= 128 CONST $TPM_RETURNCMD =256;returns menu selection (if any) and does not send msg evenet GUISetState(@SW_RESTORE,$winhandle);in case called then user went outside menu or window area $arPos =GUIGetCursorInfo($hWnd) If NOT @error Then If $ifunderID And $arpos[4]<>$ifunderID Then Return Local $x = $arPos[0]+8 Local $y = $arPos[1]+8 ClientToScreen($hWnd, $x, $y) GUISetState(@SW_LOCK,$winhandle) DllCall("user32.dll", "int", "TrackPopupMenuEx", "hwnd", $hMenu, "int",$TPM_RIGHTBUTTON, "int", $x, "int", $y, "hwnd", $hWnd, "ptr", 0) GUISetState(@SW_UNLOCK,$winhandle) EndIf EndFunc ; Convert the client (GUI) coordinates to screen (desktop) coordinates Func ClientToScreen($hWnd, ByRef $x, ByRef $y) Local $stPoint = DllStructCreate("int;int") DllStructSetData($stPoint, 1, $x) DllStructSetData($stPoint, 2, $y) DllCall("user32.dll", "int", "ClientToScreen", "hwnd", $hWnd, "ptr", DllStructGetPtr($stPoint)) $x = DllStructGetData($stPoint, 1) $y = DllStructGetData($stPoint, 2) ; release Struct not really needed as it is a local $stPoint = 0 EndFuncI would be thankful for nudges in the right direction .Thanks in advance, E.
TheSaint Posted May 25, 2006 Posted May 25, 2006 Once again - Hi Ebenezer,When you say links, you are talking shortcuts right - not Html links?One of my programs Context Options has an unusual ability with .lnk files, which I think unique and may be of some help to you. Other than that, I'm not very versed in C++, so can't help you there!Hope this may help, and once again thanks for the other help!I'll keep pondering what you ask ... you never know, I might surprise myself! Make sure brain is in gear before opening mouth! Remember, what is not said, can be just as important as what is said. Spoiler What is the Secret Key? Life is like a Donut If I put effort into communication, I expect you to read properly & fully, or just not comment. Ignoring those who try to divert conversation with irrelevancies. If I'm intent on insulting you or being rude, I will be obvious, not ambiguous about it. I'm only big and bad, to those who have an over-active imagination. I may have the Artistic Liesense to disagree with you. TheSaint's Toolbox (be advised many downloads are not working due to ISP screwup with my storage)
Ebenezer Posted May 25, 2006 Author Posted May 25, 2006 Thanks for the hint.Unfortunately I was somewhat vague. The program is essentially a hash filter. It does not store links as such.I just created two panes - in the right listview there is the hash and filename data. To the left is a listview with the possible categories.What I would like to do is to drag an entry from the right pane to the left pane. When this happens, autoit should write the hash and filename to an inifile under the section [selected category].Then, when someone selects an category autioit will get the hashes from the ini-file and write them back to the right listview.Sounds rather simplicistic, but I can't figure out a way to see on what category the hash was dropped (well short of creating a button for every category which would be a real design and portability nightmare ).Still hoping for some inspiration Intended GUI:My code so far:expandcollapse popup#include <constants.au3> #include <GUIConstants.au3> #include <GuiListView.au3> Opt("GUIOnEventMode", 1) Opt( "TrayOnEventMode", 1) Opt("TrayAutoPause", 0) Opt("TrayMenuMode", 1) $Inifile = "Config.Ini" $Datadump = "Hashesarchive.Ini" #region - GUI $MainWindow = GUICreate("Testing222", (@DesktopWidth-40), (@DesktopHeight-105), 20, 20, -1, $WS_EX_TOPMOST) #region - Link Storage ; Context Menu Dim $vCategories_Array[3] $Storage_Categories = GUICtrlCreateListView("Categories", 30, 50, 100, (@DesktopHeight-185)) GUICtrlSetStyle(-1, BitOr($LVS_REPORT, $LVS_SINGLESEL, $LVS_SHOWSELALWAYS), $LVS_EX_FULLROWSELECT) $vCategories_Array[0] = GUICtrlCreateListViewItem("- Show Clipboard", $Storage_Categories) $vCategories_Array[1] = GUICtrlCreateListViewItem("- Show All Saved", $Storage_Categories) $vCategories_Array[2] = GUICtrlCreateListViewItem("General", $Storage_Categories) $vCategories_Names_Array = IniReadSection($Inifile, "Categories") If @error <> 1 Then ReDim $vCategories_Array[(3+$vCategories_Names_Array[0][0])] For $i = 3 To $vCategories_Names_Array[0][0]+2 $vCategories_Array[$i] = GUICtrlCreateListViewItem($vCategories_Names_Array[($i-2)][0], $Storage_Categories) Next EndIf ;Categories Context Menu $Con_Storage_Categories = GUICtrlCreateContextMenu($Storage_Categories) $Con_Storage_Categories_Create = GUICtrlCreateMenuitem("New Group", $Con_Storage_Categories) $Con_Storage_Categories_Delete = GUICtrlCreateMenuitem("Delete Group", $Con_Storage_Categories) ;Main Linklist $NewItems_Storage = GUICtrlCreateListView("Filename|Filesize|Hash", 150, 50, (@DesktopWidth-220), (@DesktopHeight-185), $LVS_SHOWSELALWAYS) _GUICtrlListViewSetColumnWidth($NewItems_Storage, 1, 85) _GUICtrlListViewSetColumnWidth($NewItems_Storage, 2, 200) _GUICtrlListViewSetColumnWidth($NewItems_Storage, 0, (@DesktopWidth-585)) ;Linklist ContextMenu $Context_NewItems = GUICtrlCreateContextMenu($NewItems_Storage) $Con_NewItems_Download = GUICtrlCreateMenuitem("Download Selected", $Context_NewItems) $Con_NewItems_Filter = GUICtrlCreateMenuitem("Filter Selected", $Context_NewItems) #endregion #endregion #region - Event Triggers GUISetOnEvent($GUI_EVENT_MINIMIZE, "trayLClick") TraySetOnEvent($TRAY_EVENT_PRIMARYDOUBLE, "trayLClick") GUISetOnEvent($GUI_EVENT_CLOSE, "CLOSEClicked") GUICtrlSetOnEvent($Con_NewItems_Download, "DownloadMultiple") GUICtrlSetOnEvent($Con_NewItems_Filter, "FilterMultiple") GUICtrlSetOnEvent($Con_Storage_Categories_Create, "CreateGroup") GUICtrlSetOnEvent($Con_Storage_Categories_Delete, "GetSelectedCategory") #endregion #region - Clipboard Hook Global Const $WM_DRAWCLIPBOARD = 0x0308 Global Const $WM_CHANGECBCHAIN = 0x030D Global $origHWND $origHWND = DLLCall("user32.dll","hwnd","SetClipboardViewer","hwnd",$MainWindow) $origHWND = $origHWND[0] GUIRegisterMsg($WM_DRAWCLIPBOARD,"OnClipBoardChange") GUIRegisterMsg($WM_CHANGECBCHAIN,"OnClipBoardViewerChange") #endregion While 1 Sleep(50) WEnd #region - Transfer to Edonkey Func ListView_DoubleClick() $vItem = _GUICtrlListViewGetSelectedIndices($NewItems_Storage) If $vItem <> -1 Then $Name = _GUICtrlListViewGetItemText($NewItems_Storage, $vItem, 0) $Size = _GUICtrlListViewGetItemText($NewItems_Storage, $vItem, 1) $Hash = _GUICtrlListViewGetItemText($NewItems_Storage, $vItem, 2) $Link = "ed2k://|file|"&$Name&"|"&$Size&"|"&$Hash&"|" RunWait("rundll32.exe url.dll,FileProtocolHandler " & $Link, @WorkingDir) IniWrite($Datadump, "Filters", $Hash, $Size) _GUICtrlListViewDeleteItemsSelected($NewItems_Storage) EndIf EndFunc ;==>ListView_DoubleClick Func DownloadMultiple() $vNumberOfSelected = _GUICtrlListViewGetSelectedCount($NewItems_Storage) If $vNumberOfSelected <> 0 AND $vNumberOfSelected <> -1 Then WinSetState($MainWindow, -1, @SW_HIDE) ToolTip("Transferring Links", (@DesktopWidth/2), (@DesktopHeight/2), "Please Wait", 1, 2) Dim $vIndex[$vNumberOfSelected] Dim $vDowns[$vNumberOfSelected][3] $vIndex = _GUICtrlListViewGetSelectedIndices($NewItems_Storage, 1, $MainWindow) ;erst holen For $i = 1 To $vNumberOfSelected $Name = _GUICtrlListViewGetItemText($NewItems_Storage, $vIndex[$i], 0, $MainWindow) $Size = _GUICtrlListViewGetItemText($NewItems_Storage, $vIndex[$i], 1, $MainWindow) $Hash = _GUICtrlListViewGetItemText($NewItems_Storage, $vIndex[$i], 2, $MainWindow) $Link = "ed2k://|file|"&$Name&"|"&$Size&"|"&$Hash&"|" $vDowns[($i-1)][0] = $Link $vDowns[($i-1)][1] = $Hash $vDowns[($i-1)][2] = $Size Next EndIf ;dann übertragen For $i = 1 To $vNumberOfSelected RunWait("rundll32.exe url.dll,FileProtocolHandler " & $vDowns[($i-1)][0], @WorkingDir) Sleep(1000) IniWrite($Datadump, "Filters", $vDowns[($i-1)][1], $vDowns[($i-1)][2]) Next _GUICtrlListViewDeleteItemsSelected($NewItems_Storage, $MainWindow) ToolTip("") WinSetState($MainWindow, "", @SW_SHOW) WinActivate($MainWindow) WinWaitActive($MainWindow) EndFunc #endregion #region - Management Functions func trayLClick() If BitAND(WinGetState($MainWindow), 2) Then guiSetState( @SW_HIDE, $MainWindow) Else guiSetState( @SW_SHOW, $MainWindow) EndIf endfunc Func CLOSEClicked() ; send notification that we no longer will be in clipboard hook queue DLLCall("user32.dll","int","ChangeClipboardChain","hwnd",$MainWindow,"hwnd",$origHWND) Exit EndFunc Func FilterMultiple() $vNumberOfSelected = _GUICtrlListViewGetSelectedCount($NewItems_Storage) If $vNumberOfSelected <> 0 AND $vNumberOfSelected <> -1 Then Dim $vIndex[$vNumberOfSelected] $vIndex = _GUICtrlListViewGetSelectedIndices($NewItems_Storage, 1) For $i = 1 To UBound($vIndex)-1 $Name = _GUICtrlListViewGetItemText($NewItems_Storage, $vIndex[$i], 0) $Size = _GUICtrlListViewGetItemText($NewItems_Storage, $vIndex[$i], 1) $Hash = _GUICtrlListViewGetItemText($NewItems_Storage, $vIndex[$i], 2) IniWrite($Datadump, "Filters", $Hash, $Size) Next _GUICtrlListViewDeleteItemsSelected($NewItems_Storage) EndIf EndFunc #endregion #region - Clipboard Management Func OnClipBoardChange($hWnd, $Msg, $wParam, $lParam) ; do what you need when clipboard changes ProcessClipboard() ; send notification about clipboard change to next clipviewer dllcall("user32.dll","int","SendMessage","hWnd",$origHWND,"int",$WM_DRAWCLIPBOARD,"int",$wParam,"int",$lParam) EndFunc Func ProcessClipboard() $Temp = ClipGet() $NumberofItems = NumberOfResults($Temp, "ed2k://") If $NumberofItems > 0 Then _GUICtrlListViewDeleteAllItems($NewItems_Storage) For $i = 1 To $NumberofItems $ItemStart = StringInStr($Temp, "ed2k://", 1, $i) $Name = SucheBegriff($Temp, $ItemStart, "|", 2, "|", 1) $Size = SucheBegriff($Temp, $ItemStart, "|", 3, "|", 1) $Hash = SucheBegriff($Temp, $ItemStart, "|", 4, "|", 1) $Link = "ed2k://|file|"&$Name&"|"&$Size&"|"&$Hash&"|" If IniRead($Datadump, "Filters", $Hash, -1) = -1 Then GUICtrlCreateListViewItem($Name & "|" & $Size & "|" & $Hash, $NewItems_Storage) EndIf Next trayLClick() EndIf EndFunc Func OnClipBoardViewerChange($hWnd, $Msg, $wParam, $lParam) ; if our remembered previous clipviewer is removed then we must remember new next clipviewer ; else send notification about clipviewr change to next clipviewer If $wParam = $origHWND Then $origHWND = $lParam Else dllcall("user32.dll","int","SendMessage","hWnd",$origHWND,"int",$WM_CHANGECBCHAIN,"hwnd",$wParam,"hwnd",$lParam) EndIf EndFunc #endregion #region - Category Management for Tab1 Func ProcessDropEvent() MsgBox(0, "From", @GUI_DragId) MsgBox(0, "To", @GUI_DropId) MsgBox(0, "To", @GUI_DragFile) EndFunc Func GetSelectedCategory() $vTemp = GuiGetCursorInfo($MainWindow) MsgBox(0, "", $vTemp[4]) ;~ $vCoordinatesMain = ControlGetPos("", "", $MainWindow) ;~ $vCoordinates = ControlGetPos("", "", $MainWindow) EndFunc Func CreateGroup() $vName = InputBox("Create New Group", "Please enter a name for the new group") If $vName <> "" Then ReDim $vCategories_Array[(UBound($vCategories_Array)+1)] $vCategories_Array[(UBound($vCategories_Array)-1)] = GUICtrlCreateListViewItem($vName, $Storage_Categories) IniWrite($Inifile, "Categories", $vName, -1) EndIf EndFunc #endregion #region - Search Functions Func NumberOfResults($StringToSearch, $vSuchbegriff_Start) ;Wie viele Items auf der Seite. Wird unten gebraucht, damit der Array in seinen Grenzen arbeitet For $y = 1 to 2500 $pos = StringInStr ($StringToSearch, $vSuchbegriff_Start, 1, $y) If $pos = 0 Then ; StringInStr() failed ExitLoop EndIf Next Return($y-1) EndFunc Func SucheBegriff($Searchedstring_Temp, $vStartpos, $vSuchbegriff_Start, $StartCount, $vSuchbegriff_Stopp, $StoppCount) #CS Suchen nach dem xten ($count) jeweiligen Wert im String (Searchedstring) #CE $Grenze_links = _Searchfromplace($Searchedstring_Temp, $vSuchbegriff_Start, $vStartpos, $StartCount) + StringLen($vSuchbegriff_Start) $Grenze_rechts = _Searchfromplace($Searchedstring_Temp, $vSuchbegriff_Stopp, $Grenze_links, $StoppCount) $Lenghtcount = $Grenze_rechts - $Grenze_links Return(StringMid($Searchedstring_Temp, $Grenze_links, $Lenghtcount)) EndFunc Func _Searchfromplace($Searchedstring_Temp, $Searchstring, $start, $Count) #CS Sucht das xte Auftreten eines Terms nach der angegebenen Position und gibt die Position im Gesamtstring aus. OK #CE $Searchedstring_Temp_Lenght = StringLen($Searchedstring_Temp) $Searchedstring_Temp = StringTrimLeft ( $Searchedstring_Temp, $start ) $Add_to_count = ($Searchedstring_Temp_Lenght - (StringLen($Searchedstring_Temp))) $Position_Searchstring = StringInStr($Searchedstring_Temp, $Searchstring, 1, $Count) Return($Position_Searchstring + $Add_to_count) EndFunc #endregion
QA Stooge Posted September 12, 2006 Posted September 12, 2006 Unfortunately I was somewhat vague. The program is essentially a hash filter. It does not store links as such. I just created two panes - in the right listview there is the hash and filename data. To the left is a listview with the possible categories. What I would like to do is to drag an entry from the right pane to the left pane. When this happens, autoit should write the hash and filename to an inifile under the section [selected category]. Then, when someone selects an category autioit will get the hashes from the ini-file and write them back to the right listview. Sounds rather simplicistic, but I can't figure out a way to see on what category the hash was dropped (well short of creating a button for every category which would be a real design and portability nightmare ). Still hoping for some inspiration I'm in the same boat. So far, I can now make an infinite tree from scratch by using Drag & Drop, but can't determine the TreeViewItem under the mouse cursor at any given time. I need to figure out how to get the Location of a TreeViewItem
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now