quaizywabbit Posted December 10, 2006 Share Posted December 10, 2006 (edited) Ive tried the LBItemfromPt( ) in comctl32.dll as well as _SendMessage($Hlb, $LB_ITEMFROMPOINT, 0, $Point) where $Hlb is the hwnd to the listbox.The $Point structure coordinates used are originally screen coordinates, and ive converted them to client coordinates, as well as window coordinates, but in any case both functions return minus 1 ( not in the client area ) instead of the index.why this is so, Ive no clue whatsoever........... EDIT: got it to return index using SendMessage() Edited December 11, 2006 by quaizywabbit [u]Do more with pre-existing apps![/u]ANYGUIv2.8 Link to comment Share on other sites More sharing options...
Developers Jos Posted December 10, 2006 Developers Share Posted December 10, 2006 Why is this in Bugs Reports? SciTE4AutoIt3 Full installer Download page - Beta files Read before posting How to post scriptsource Forum etiquette Forum Rules Live for the present, Dream of the future, Learn from the past. Link to comment Share on other sites More sharing options...
quaizywabbit Posted December 10, 2006 Author Share Posted December 10, 2006 Why is this in Bugs Reports?I believe the listbox is incorrectly responding to both of these function calls.I am using the lastest Beta, and XPPro service Pack 2 [u]Do more with pre-existing apps![/u]ANYGUIv2.8 Link to comment Share on other sites More sharing options...
Richard Robertson Posted December 10, 2006 Share Posted December 10, 2006 This forum is for AutoIt bugs. You are using the function wrong; this is not a problem with AutoIt.The function expects screen coordinates.pt POINT structure that contains the screen coordinates to check. Link to comment Share on other sites More sharing options...
quaizywabbit Posted December 11, 2006 Author Share Posted December 11, 2006 This forum is for AutoIt bugs. You are using the function wrong; this is not a problem with AutoIt.The function expects screen coordinates.I added the ScreenToClient functon after it failed with the original screen coordinates. In fact, I've tried every possible combination.I'm more than happy to be proved wrong on this. If I did it wrong, please post an example of how you got either function to return an Index instead of -1 everytime. [u]Do more with pre-existing apps![/u]ANYGUIv2.8 Link to comment Share on other sites More sharing options...
jpm Posted December 11, 2006 Share Posted December 11, 2006 You are passing a ptr to POINT not POINT itself. NOBUG. PS Your subject is more and help&support one Link to comment Share on other sites More sharing options...
quaizywabbit Posted December 11, 2006 Author Share Posted December 11, 2006 (edited) You are passing a ptr to POINT not POINT itself.NOBUG. PS Your subject is more and help&support one How do i pass $Point as you describe? I have solved getting SendMessage() to return the index....But I am still interested how to call LBItemFromPt() in Comctl32.dll properly passing the $Point via DllCall() Edited December 11, 2006 by quaizywabbit [u]Do more with pre-existing apps![/u]ANYGUIv2.8 Link to comment Share on other sites More sharing options...
PaulIA Posted December 11, 2006 Share Posted December 11, 2006 How do i pass $Point as you describe? I have solved getting SendMessage() to return the index.... But I am still interested how to call LBItemFromPt() in Comctl32.dll properly passing the $Point via DllCall() From the A3LListBox file in Auto3Lib: ; ================================================================================================= ; Description ..: Retrieves the zero based index of the item nearest the specified point in a list box ; Parameters ...: $hWnd - Handle to control ; $iX - X coordinate, relative to the upper-left corner of the client area ; $iY - Y coordinate, relative to the upper-left corner of the client area ; Return values : The index of the nearest item or -1 if the point is outside of the client area ; ================================================================================================= Func _Listbox_ItemFromPoint($hWnd, $iX, $iY) Local $iResult $iResult = _SendMessage($hWnd, $LB_ITEMFROMPOINT, 0, _MakeLong($iX, $iY)) if _HiWord($iResult) = 0 then Return $iResult else Return -1 endif EndFuncoÝ÷ ØZèØ^r˺گ'âè§ëhܸjëh×6; ================================================================================================= ; Description ..: Returns an longint value from two int values ; Parameters ...: $iLo - Low word ; $iHi - Hi word ; Return values : Longint value ; ================================================================================================= Func _MakeLong($iLo, $iHi) Return BitOR(BitShift($iHi, -16), BitAND($iLo, 0xFFFF)) EndFunc ; ================================================================================================= ; Description ..: Returns the high word of a longword ; Parameters ...: $iLong - Longword value ; Return values : High order word of the longword value ; ================================================================================================= Func _HiWord($iLong) Return BitShift($iLong, 16) EndFunc Auto3Lib: A library of over 1200 functions for AutoIt Link to comment Share on other sites More sharing options...
quaizywabbit Posted December 11, 2006 Author Share Posted December 11, 2006 (edited) Thanks PaulIA, I had already found the MakeLong() function....... Would you happen to know how to call LBItemFromPt() in ComCtl32.dll using DllCall ?? apparently it doesn't use a ptr to the Point Struct, but the struct itself (somehow) Solved SendMessage() returning Index (Updated Script---> see 1st post ) Edited December 11, 2006 by quaizywabbit [u]Do more with pre-existing apps![/u]ANYGUIv2.8 Link to comment Share on other sites More sharing options...
PaulIA Posted December 11, 2006 Share Posted December 11, 2006 Thanks PaulIA, I had already found the MakeLong() function....... Would you happen to know how to call LBItemFromPt() in ComCtl32.dll using DllCall ?? apparently it doesn't use a ptr to the Point Struct, but the struct itself (somehow) Solved SendMessage() returning Index (Updated Script---> see 1st post )Here is your script using the DllCall: CODEexpandcollapse popup#include "guiconstants.au3" #include "guilist.au3" #include <Misc.au3> ;Opt("MouseCoordMode", 2) #region Constants ;'Windows API Constants Global Const $DRAGLISTMSGSTRING = "commctrl_DragListMsg" & Chr(0) Global Const $DL_BEGINDRAG = ($WM_USER + 133) Global Const $DL_DRAGGING = ($WM_USER + 134) Global Const $DL_DROPPED = ($WM_USER + 135) Global Const $DL_CANCELDRAG = ($WM_USER + 136) Global Const $LB_ITEMFROMPOINT = 0x1A9 #endregion #region Vars Dim $Parent; hwnd of parent window where draglist is located Dim $Hlb; handle to list control modified by MakeDraglist() function Dim $nItem; item where to place insert image next to #endregion #region Structs #comments-start typedef struct { UINT uNotification; HWND hWnd; POINT ptCursor; } DRAGLISTINFO, *LPDRAGLISTINFO; #comments-end ;Dim $Point = DllStructCreate("int;int") ;dim $DraglistInfo = DllStructCreate("uint;uint",$Point) #endregion #region Func's Func DrawInsert( $Parent, $Hlb, $nItem) $r = DllCall("comctl32.dll", "int", "DrawInsert", "hwnd", $Parent, "hwnd", $Hlb, "int", $nItem) Return $r[0] EndFunc Func Makedraglist($hwnd) If Not IsHwnd($hwnd) Then $hwnd = Hwnd($hwnd) Local $r = DllCall("comctl32.dll", "int", "MakeDragList","hwnd",$hwnd);$r is 0 if unsucccesful Return $r[0] EndFunc #cs int LBItemFromPt( HWND hLB, POINT pt, BOOL bAutoScroll ); #ce Func LBItemFromPt( $Hlb, $Point, $autoscroll = 0) ;Return _SendMessage($Hlb, $LB_ITEMFROMPOINT, 0, $Point) ;Return Value ;The return value contains the index of the nearest item in the low-order word. ;The high-order word is zero if the specified point is in the client area of the list box, ;or one if it is outside the client area.>>>Note. this call to sendmessage always results in the same number<<< $x=DllStructGetData($Point, 1) $y=DllStructGetData($Point, 2) ; $r = DllCall("comctl32.dll", "int", "LBItemFromPt", "hwnd", $Hlb, "ptr", $Point, "int", $autoscroll) $r = DllCall("comctl32.dll", "int", "LBItemFromPt", "hwnd", $Hlb, "int", $x, "int", $y, "int", $autoscroll) ConsoleWrite("ItemFromPt: x: " & $x & " y: " & $y & " Error: " & @Error & " Result: " & $r[0] & @CR) Return $r[0] EndFunc Func _ResetScreen($TargethWnd) Const $SWP_NOMOVE = 0x0002, $SWP_NOSIZE = 0x0001, $SWP_NOZORDER = 0x0004, $SWP_FRAMECHANGED = 0x0020 ;from Winuser.h DllCall("user32.dll", "long", "SetWindowPos", "hwnd", $TargethWnd, "hwnd", $TargethWnd, "int", 0, "int", 0, "int", 0, "int", 0, _ "long", BitOR($SWP_NOMOVE, $SWP_NOSIZE, $SWP_NOZORDER, $SWP_FRAMECHANGED)) EndFunc #endregion #region Main $Parent = GUICreate("draglist test") $list = GUICtrlCreateList("my draglist", 40, -1, Default, Default) $label = GUICtrlCreateLabel("" ,30, 200,100, 40 ) GUISetState (@SW_SHOW) $Hlb = ControlGetHandle($Parent,"",$list) GUICtrlSetData($list, "you|me|them|us") GUISetState (@SW_SHOW) ; will display an empty dialog box Makedraglist($Hlb) $draglistmessage = DllCall("user32.dll", "int", "RegisterWindowMessage", "str", $DRAGLISTMSGSTRING) ;MsgBox(0, "",($draglistmessage[0])) $x = GUIRegisterMsg(($draglistmessage[0]), "MyDraglistHandler") ;MsgBox(0, "guiregmssge", $x) ; Run the GUI until the dialog is closed While 1 Dim $msg = GUIGetMsg() If $msg = $GUI_EVENT_CLOSE Then ExitLoop Wend #cs from msdn: The wParam parameter of the drag list message is the control identifier for the drag list box. The lParam parameter is the address of a DRAGLISTINFO structure, which contains the notification code for the drag event and other information. The return value of the message depends on the notification #ce Func MyDraglistHandler($hwnd, $msg, $wParam, $lParam) ;Opt("MouseCoordMode", 2) $nID = BitAND($wParam, 0x0000FFFF) If $nID = $list Then Local $DraglistInfo = DllStructCreate("uint;hwnd;int;int",$lParam) $nNotifyCode = (DllStructGetData($DraglistInfo,1)) $Hlb = DllStructGetData($DraglistInfo, 2) ;if not IsHWnd($Hlb) then ConsoleWrite("control hwnd invalid") dim $chwnd = ControlGetHandle($Parent, "", $list) ; $Point = _MakeWord(DllStructGetData($DraglistInfo, 3), DllStructGetData($DraglistInfo, 4)) $Point = DllStructCreate("int;int") DllStructSetData($Point,1, DllStructGetData($DraglistInfo, 3)) DllStructSetData($Point,2, DllStructGetData($DraglistInfo, 4)) ; DllCall("User32.dll", "int", "ScreenToClient", "hwnd", $chwnd, "ptr", DllStructGetPtr($Point)) ; ConsoleWrite("$Point1: " & DllStructGetData($Point,1) & @LF) ; ConsoleWrite("$Point2: " & DllStructGetData($Point,2) & @LF) ; ConsoleWrite($chwnd & " " & "0x"&Hex($Hlb) & @LF) Select Case $nNotifyCode = $DL_BEGINDRAG $dragIdx = LBItemFromPt($chwnd, $Point) ;reset screen here ;return something ; ConsoleWrite("$DRAGIDX =" & $dragIdx & @LF) ; ConsoleWrite("begin drag" & @LF) Return True Case $nNotifyCode = $DL_CANCELDRAG ;reset screen here ;return something ConsoleWrite("drag canceled") Case $nNotifyCode = $DL_DRAGGING $dragIdto = LBItemFromPt($chwnd, $Point) DrawInsert($Parent, $chwnd, $dragIdto) ConsoleWrite("dragging" & @LF & "Dragidto = " & $dragIdto & @LF) ;return something Case $nNotifyCode = $DL_DROPPED ;reset screen here ;If LBItemFromPt($Hlb, $Pointx) <> $dragIdx Then ConsoleWrite("ok Dl_Dropped" & @LF) ;do something with it ;EndIf Case Else Return $GUI_RUNDEFMSG EndSelect $Point = 0 EndIf EndFunc ;==>MyDraglistHandler Func _MakeWord($LoByte, $HiByte) Return BitOR($LoByte, 0x100 * $HiByte) EndFunc ;==>_MakeWord Auto3Lib: A library of over 1200 functions for AutoIt Link to comment Share on other sites More sharing options...
quaizywabbit Posted December 13, 2006 Author Share Posted December 13, 2006 (edited) Here is your script using the DllCall: CODEexpandcollapse popup#include "guiconstants.au3" #include "guilist.au3" #include <Misc.au3> ;Opt("MouseCoordMode", 2) #region Constants ;'Windows API Constants Global Const $DRAGLISTMSGSTRING = "commctrl_DragListMsg" & Chr(0) Global Const $DL_BEGINDRAG = ($WM_USER + 133) Global Const $DL_DRAGGING = ($WM_USER + 134) Global Const $DL_DROPPED = ($WM_USER + 135) Global Const $DL_CANCELDRAG = ($WM_USER + 136) Global Const $LB_ITEMFROMPOINT = 0x1A9 #endregion #region Vars Dim $Parent; hwnd of parent window where draglist is located Dim $Hlb; handle to list control modified by MakeDraglist() function Dim $nItem; item where to place insert image next to #endregion #region Structs #comments-start typedef struct { UINT uNotification; HWND hWnd; POINT ptCursor; } DRAGLISTINFO, *LPDRAGLISTINFO; #comments-end ;Dim $Point = DllStructCreate("int;int") ;dim $DraglistInfo = DllStructCreate("uint;uint",$Point) #endregion #region Func's Func DrawInsert( $Parent, $Hlb, $nItem) $r = DllCall("comctl32.dll", "int", "DrawInsert", "hwnd", $Parent, "hwnd", $Hlb, "int", $nItem) Return $r[0] EndFunc Func Makedraglist($hwnd) If Not IsHwnd($hwnd) Then $hwnd = Hwnd($hwnd) Local $r = DllCall("comctl32.dll", "int", "MakeDragList","hwnd",$hwnd);$r is 0 if unsucccesful Return $r[0] EndFunc #cs int LBItemFromPt( HWND hLB, POINT pt, BOOL bAutoScroll ); #ce Func LBItemFromPt( $Hlb, $Point, $autoscroll = 0) ;Return _SendMessage($Hlb, $LB_ITEMFROMPOINT, 0, $Point) ;Return Value ;The return value contains the index of the nearest item in the low-order word. ;The high-order word is zero if the specified point is in the client area of the list box, ;or one if it is outside the client area.>>>Note. this call to sendmessage always results in the same number<<< $x=DllStructGetData($Point, 1) $y=DllStructGetData($Point, 2) ; $r = DllCall("comctl32.dll", "int", "LBItemFromPt", "hwnd", $Hlb, "ptr", $Point, "int", $autoscroll) $r = DllCall("comctl32.dll", "int", "LBItemFromPt", "hwnd", $Hlb, "int", $x, "int", $y, "int", $autoscroll) ConsoleWrite("ItemFromPt: x: " & $x & " y: " & $y & " Error: " & @Error & " Result: " & $r[0] & @CR) Return $r[0] EndFunc Func _ResetScreen($TargethWnd) Const $SWP_NOMOVE = 0x0002, $SWP_NOSIZE = 0x0001, $SWP_NOZORDER = 0x0004, $SWP_FRAMECHANGED = 0x0020 ;from Winuser.h DllCall("user32.dll", "long", "SetWindowPos", "hwnd", $TargethWnd, "hwnd", $TargethWnd, "int", 0, "int", 0, "int", 0, "int", 0, _ "long", BitOR($SWP_NOMOVE, $SWP_NOSIZE, $SWP_NOZORDER, $SWP_FRAMECHANGED)) EndFunc #endregion #region Main $Parent = GUICreate("draglist test") $list = GUICtrlCreateList("my draglist", 40, -1, Default, Default) $label = GUICtrlCreateLabel("" ,30, 200,100, 40 ) GUISetState (@SW_SHOW) $Hlb = ControlGetHandle($Parent,"",$list) GUICtrlSetData($list, "you|me|them|us") GUISetState (@SW_SHOW) ; will display an empty dialog box Makedraglist($Hlb) $draglistmessage = DllCall("user32.dll", "int", "RegisterWindowMessage", "str", $DRAGLISTMSGSTRING) ;MsgBox(0, "",($draglistmessage[0])) $x = GUIRegisterMsg(($draglistmessage[0]), "MyDraglistHandler") ;MsgBox(0, "guiregmssge", $x) ; Run the GUI until the dialog is closed While 1 Dim $msg = GUIGetMsg() If $msg = $GUI_EVENT_CLOSE Then ExitLoop Wend #cs from msdn: The wParam parameter of the drag list message is the control identifier for the drag list box. The lParam parameter is the address of a DRAGLISTINFO structure, which contains the notification code for the drag event and other information. The return value of the message depends on the notification #ce Func MyDraglistHandler($hwnd, $msg, $wParam, $lParam) ;Opt("MouseCoordMode", 2) $nID = BitAND($wParam, 0x0000FFFF) If $nID = $list Then Local $DraglistInfo = DllStructCreate("uint;hwnd;int;int",$lParam) $nNotifyCode = (DllStructGetData($DraglistInfo,1)) $Hlb = DllStructGetData($DraglistInfo, 2) ;if not IsHWnd($Hlb) then ConsoleWrite("control hwnd invalid") dim $chwnd = ControlGetHandle($Parent, "", $list) ; $Point = _MakeWord(DllStructGetData($DraglistInfo, 3), DllStructGetData($DraglistInfo, 4)) $Point = DllStructCreate("int;int") DllStructSetData($Point,1, DllStructGetData($DraglistInfo, 3)) DllStructSetData($Point,2, DllStructGetData($DraglistInfo, 4)) ; DllCall("User32.dll", "int", "ScreenToClient", "hwnd", $chwnd, "ptr", DllStructGetPtr($Point)) ; ConsoleWrite("$Point1: " & DllStructGetData($Point,1) & @LF) ; ConsoleWrite("$Point2: " & DllStructGetData($Point,2) & @LF) ; ConsoleWrite($chwnd & " " & "0x"&Hex($Hlb) & @LF) Select Case $nNotifyCode = $DL_BEGINDRAG $dragIdx = LBItemFromPt($chwnd, $Point) ;reset screen here ;return something ; ConsoleWrite("$DRAGIDX =" & $dragIdx & @LF) ; ConsoleWrite("begin drag" & @LF) Return True Case $nNotifyCode = $DL_CANCELDRAG ;reset screen here ;return something ConsoleWrite("drag canceled") Case $nNotifyCode = $DL_DRAGGING $dragIdto = LBItemFromPt($chwnd, $Point) DrawInsert($Parent, $chwnd, $dragIdto) ConsoleWrite("dragging" & @LF & "Dragidto = " & $dragIdto & @LF) ;return something Case $nNotifyCode = $DL_DROPPED ;reset screen here ;If LBItemFromPt($Hlb, $Pointx) <> $dragIdx Then ConsoleWrite("ok Dl_Dropped" & @LF) ;do something with it ;EndIf Case Else Return $GUI_RUNDEFMSG EndSelect $Point = 0 EndIf EndFunc ;==>MyDraglistHandler Func _MakeWord($LoByte, $HiByte) Return BitOR($LoByte, 0x100 * $HiByte) EndFunc ;==>_MakeWord Thanks so much Paul! Here's a working version of a DragListBox: still have a few things to add like changing cursors from arrow to hand )and back, as well as to the NOTALLOWED when out of range..... Edited December 13, 2006 by quaizywabbit [u]Do more with pre-existing apps![/u]ANYGUIv2.8 Link to comment Share on other sites More sharing options...
xeroTechnologiesLLC Posted April 11, 2012 Share Posted April 11, 2012 Masterful work! Link to comment Share on other sites More sharing options...
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