Jump to content
Sign in to follow this  
Xenobiologist

Listview sort column 0 (numbers) column 1 (strings)

Recommended Posts

Xenobiologist

Hi,

just a short question. 
I 've got a lisitview with a few columns and I want to register a different sort for two kinds of columns.
I 've got a solution, but I don't think it is a good one. 

Example : 
Col A = Names (Strings)
Col B = Age (Integers)

Right now I'm doing this:
1. _GUICtrlListView_RegisterSortCallBack
2. In my WM_NOTIFY 
Case GUICtrlGetHandle($search_LV)
            Switch $iCode
                Case $LVN_COLUMNCLICK ; A column was clicked
                    Local $tInfo = DllStructCreate($tagNMLISTVIEW, $iLparam)
                    ; Kick off the sort callback
;~                  ConsoleWrite('SEARCH_LV Column geklickt' & @LF)
                    ConsoleWrite("Sort: " & DllStructGetData($tInfo, 'SubItem'))
                    If $ColumnSorted <> DllStructGetData($tInfo, 'SubItem') Then
                        _GUICtrlListView_UnRegisterSortCallBack($search_LV)
                        ConsoleWrite('NEU' & @CRLF)
                    EndIf
                    $ColumnSorted = DllStructGetData($tInfo, 'SubItem')
                    If DllStructGetData($tInfo, 'SubItem') = 9 Or DllStructGetData($tInfo, 'SubItem') = 10 Then
                        ConsoleWrite('True: ' & _GUICtrlListView_RegisterSortCallBack($search_LV, True) & @CRLF)
                    Else
                        ConsoleWrite('False ' & _GUICtrlListView_RegisterSortCallBack($search_LV, False) & @CRLF)
                    EndIf
                    _GUICtrlListView_SortItems($search_LV, DllStructGetData($tInfo, 'SubItem'))

So, I store the column clicked in a global variable. If the column is clicked again (sort asc or desc) then all is fine, if another column then the one before is clicked, I unregister the callback and create a new one.

The new callback (in the if) depends on the column clicked because of the content to sort (strings or numbers).

Is there an easier / better way?

Do I have to use my own sorting function with GuiCtrlRegisterListViewSort?

Edit: It still doesn't work in every case (just noticed).

Thanks

Mega

Edited by Xenobiologist

Scripts & functions Organize Includes Let Scite organize the include files

Yahtzee The game "Yahtzee" (Kniffel, DiceLion)

LoginWrapper Secure scripts by adding a query (authentication)

_RunOnlyOnThis UDF Make sure that a script can only be executed on ... (Windows / HD / ...)

Internet-Café Server/Client Application Open CD, Start Browser, Lock remote client, etc.

MultipleFuncsWithOneHotkey Start different funcs by hitting one hotkey different times

Share this post


Link to post
Share on other sites
Xenobiologist

Okay, maybe it is a little bit different to understand what I want.

Here is an example script.

Whats needs to be changed to get all comlums sortable correctly (literal,numeric and asc,desc)?

#include <GuiListView.au3>
#include <ListViewConstants.au3>
#include <WindowsConstants.au3>
#include <GuiConstantsEx.au3>
#include <StructureConstants.au3>

Opt('MustDeclareVars', 1)

Global $search_LV, $B_DESCENDING
GUICreate("ListView Sort by Column Click", 400, 300)
$search_LV = GUICtrlCreateListView("String|Number|String", 2, 2, 394, 268)
GUICtrlSendMsg($search_LV, $LVM_SETEXTENDEDLISTVIEWSTYLE, $LVS_EX_GRIDLINES, $LVS_EX_GRIDLINES)
GUICtrlSendMsg($search_LV, $LVM_SETEXTENDEDLISTVIEWSTYLE, $LVS_EX_FULLROWSELECT, $LVS_EX_FULLROWSELECT)
GUICtrlCreateListViewItem("line4|5|1A", $search_LV)
GUICtrlCreateListViewItem("line5|4.50 |1B", $search_LV)
GUICtrlCreateListViewItem("line5|4.0 |2C", $search_LV)
GUICtrlCreateListViewItem("line3|23|01", $search_LV)
GUICtrlCreateListViewItem("line2|0.34560 |09", $search_LV)
GUICtrlCreateListViewItem("line1|1.0 |7A", $search_LV)
GUICtrlCreateListViewItem("line1|0.1 |8C", $search_LV)
GUICtrlCreateListViewItem("line1|97|5B", $search_LV)
GUICtrlCreateListViewItem("line1|910|9B", $search_LV)
GUICtrlCreateListViewItem("line1|99|11", $search_LV)
GUICtrlCreateListViewItem("line1|990.99|06", $search_LV)
_GUICtrlListView_SetColumnWidth($search_LV, 0, 75)
_GUICtrlListView_SetColumnWidth($search_LV, 1, 75)
_GUICtrlListView_SetColumnWidth($search_LV, 2, 75)
GUISetState()

GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")
;~ _GUICtrlListView_RegisterSortCallBack($search_LV, False)

While 1
    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE
            ExitLoop
        Case $search_LV
            ; Kick off the sort callback
;~          _GUICtrlListView_SortItems($search_LV, GUICtrlGetState($search_LV))
;~          _GUICtrlListView_UnRegisterSortCallBack($search_LV)
    EndSwitch
WEnd

Func WM_NOTIFY($hWnd, $iMsg, $iwParam, $ilParam)
    #forceref $hWnd, $iMsg, $iwParam
    Local $hWndFrom, $iIDFrom, $iCode, $tNMHDR, $hWndListView, $tInfo
    $hWndListView = $search_LV
;~  If Not IsHWnd($search_LV) Then $hWndListView = GUICtrlGetHandle($search_LV)

    $tNMHDR = DllStructCreate($tagNMHDR, $ilParam)
    $hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom"))
    $iIDFrom = DllStructGetData($tNMHDR, "IDFrom")
    $iCode = DllStructGetData($tNMHDR, "Code")

    Switch $hWndFrom
;~      Case $search_LV
        Case GUICtrlGetHandle($search_LV)
            Switch $iCode
                Case $LVN_COLUMNCLICK ; A column was clicked
                    ConsoleWrite("Header geklickt" & @CRLF)
                    Local $tInfo = DllStructCreate($tagNMLISTVIEW, $iLparam)
                    _GUICtrlListView_UnRegisterSortCallBack($search_LV)
                    Local $ColumnSorted = DllStructGetData($tInfo, 'SubItem')
                    If $ColumnSorted = 1 Then
                        ConsoleWrite('Numeric: ' & _GUICtrlListView_RegisterSortCallBack($search_LV, True) & @CRLF)
                    Else
                        ConsoleWrite('Literal: ' & _GUICtrlListView_RegisterSortCallBack($search_LV, False) & @CRLF)
                    EndIf
                    _GUICtrlListView_SortItems($search_LV, DllStructGetData($tInfo, 'SubItem'))
            EndSwitch
    EndSwitch
EndFunc   ;==>WM_NOTIFY

Scripts & functions Organize Includes Let Scite organize the include files

Yahtzee The game "Yahtzee" (Kniffel, DiceLion)

LoginWrapper Secure scripts by adding a query (authentication)

_RunOnlyOnThis UDF Make sure that a script can only be executed on ... (Windows / HD / ...)

Internet-Café Server/Client Application Open CD, Start Browser, Lock remote client, etc.

MultipleFuncsWithOneHotkey Start different funcs by hitting one hotkey different times

Share this post


Link to post
Share on other sites
Xenobiologist

I don't what the problem is with this question, but maybe many people think: "oh, it is an MVP who asked, then it has to be a very difficult question."

Anyhow, I found a solution but wasn't able to figure out how to do it with the RegisterCallBack funtion.

Here ist what I have so far (Still missing are the little arrows in the column  header, but I think I can handle that later)

#include <GuiListView.au3>
#include <ListViewConstants.au3>
#include <WindowsConstants.au3>
#include <GuiConstantsEx.au3>
#include <StructureConstants.au3>
#include <GUIConstantsEx.au3>
#include <ListViewConstants.au3>

Opt('MustDeclareVars', 1)

Global $g_iCurCol = -1
Global $g_iSortDir = 1
Global $g_bSet = False
Global $g_iCol = -1

Global $search_LV
GUICreate("ListView Sort by Column Click", 400, 300)
$search_LV = GUICtrlCreateListView("String|Number|String", 2, 2, 394, 268)
GUICtrlRegisterListViewSort(-1, "LVSort") ; Register the function "SortLV" for the sorting callback
GUICtrlSendMsg($search_LV, $LVM_SETEXTENDEDLISTVIEWSTYLE, $LVS_EX_GRIDLINES, $LVS_EX_GRIDLINES)
GUICtrlSendMsg($search_LV, $LVM_SETEXTENDEDLISTVIEWSTYLE, $LVS_EX_FULLROWSELECT, $LVS_EX_FULLROWSELECT)
GUICtrlCreateListViewItem("line4|5|1A", $search_LV)
GUICtrlCreateListViewItem("line5|4.50 |1B", $search_LV)
GUICtrlCreateListViewItem("line5|4.0 |2C", $search_LV)
GUICtrlCreateListViewItem("line3|23|01", $search_LV)
GUICtrlCreateListViewItem("line2|0.34560 |09", $search_LV)
GUICtrlCreateListViewItem("line1|1.0 |7A", $search_LV)
GUICtrlCreateListViewItem("line1|0.1 |8C", $search_LV)
GUICtrlCreateListViewItem("line1|97|5B", $search_LV)
GUICtrlCreateListViewItem("line1|910|9B", $search_LV)
GUICtrlCreateListViewItem("line1|99|11", $search_LV)
GUICtrlCreateListViewItem("line1|990.99|06", $search_LV)
_GUICtrlListView_SetColumnWidth($search_LV, 0, 75)
_GUICtrlListView_SetColumnWidth($search_LV, 1, 75)
_GUICtrlListView_SetColumnWidth($search_LV, 2, 75)
GUISetState()

Global $ColumnOLD, $ColumnNew

While 1
    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE
            ExitLoop
        Case $search_LV
            ; Kick off the sort callback
            $g_bSet = False
            $g_iCurCol = $g_iCol
            GUICtrlSendMsg($search_LV, '', GUICtrlGetState($search_LV), 0)
    EndSwitch
WEnd

; Our sorting callback funtion
Func LVSort($hWnd, $nItem1, $nItem2, $iColumn)
    Local $sVal1, $sVal2, $iResult

    ; Switch the sorting direction
    If $iColumn = $g_iCurCol Then
        If Not $g_bSet Then
            $g_iSortDir = $g_iSortDir * -1
            $g_bSet = True
        EndIf
    Else
        $g_iSortDir = 1
    EndIf
    $g_iCol = $iColumn

    $sVal1 = GetSubItemText($hWnd, $nItem1, $iColumn)
    $sVal2 = GetSubItemText($hWnd, $nItem2, $iColumn)

    If $iColumn = 1 Then
        $sVal1 = Number($sVal1)
        $sVal2 = Number($sVal2)
    EndIf

    $iResult = 0 ; No change of item1 and item2 positions

    If $sVal1 < $sVal2 Then
        $iResult = -1 ; Put item2 before item1
    ElseIf $sVal1 > $sVal2 Then
        $iResult = 1 ; Put item2 behind item1
    EndIf

    $iResult = $iResult * $g_iSortDir

    Return $iResult
EndFunc   ;==>LVSort

; Retrieve the text of a listview item in a specified column
Func GetSubItemText($idCtrl, $idItem, $iColumn)
    Local $tLvfi = DllStructCreate("uint;ptr;int;int[2];int")

    DllStructSetData($tLvfi, 1, $LVFI_PARAM)
    DllStructSetData($tLvfi, 3, $idItem)

    Local $tBuffer = DllStructCreate("char[260]")

    Local $nIndex = GUICtrlSendMsg($idCtrl, $LVM_FINDITEM, -1, DllStructGetPtr($tLvfi));

    Local $tLvi = DllStructCreate("uint;int;int;uint;uint;ptr;int;int;int;int")

    DllStructSetData($tLvi, 1, $LVIF_TEXT)
    DllStructSetData($tLvi, 2, $nIndex)
    DllStructSetData($tLvi, 3, $iColumn)
    DllStructSetData($tLvi, 6, DllStructGetPtr($tBuffer))
    DllStructSetData($tLvi, 7, 260)

    GUICtrlSendMsg($idCtrl, $LVM_GETITEMA, 0, DllStructGetPtr($tLvi));

    Local $sItemText = DllStructGetData($tBuffer, 1)

    Return $sItemText
EndFunc   ;==>GetSubItemText

If somebody has an exmaple how to sort two columns differently with UDF_Callback_functions or at least shows the concept how to do, I'm still interested. THANKS!

Mega


Scripts & functions Organize Includes Let Scite organize the include files

Yahtzee The game "Yahtzee" (Kniffel, DiceLion)

LoginWrapper Secure scripts by adding a query (authentication)

_RunOnlyOnThis UDF Make sure that a script can only be executed on ... (Windows / HD / ...)

Internet-Café Server/Client Application Open CD, Start Browser, Lock remote client, etc.

MultipleFuncsWithOneHotkey Start different funcs by hitting one hotkey different times

Share this post


Link to post
Share on other sites
LarsJ

You should not unregister/register the sort function after every sort. Only when you sort by another column.

This is the code in post 2:

#include <GuiListView.au3>
#include <ListViewConstants.au3>
#include <WindowsConstants.au3>
#include <GuiConstantsEx.au3>
#include <StructureConstants.au3>

Opt('MustDeclareVars', 1)

Global $search_LV, $B_DESCENDING
GUICreate("ListView Sort by Column Click", 400, 300)
$search_LV = GUICtrlCreateListView("String|Number|String", 2, 2, 394, 268)
GUICtrlSendMsg($search_LV, $LVM_SETEXTENDEDLISTVIEWSTYLE, $LVS_EX_GRIDLINES, $LVS_EX_GRIDLINES)
GUICtrlSendMsg($search_LV, $LVM_SETEXTENDEDLISTVIEWSTYLE, $LVS_EX_FULLROWSELECT, $LVS_EX_FULLROWSELECT)
GUICtrlCreateListViewItem("line4|5|1A", $search_LV)
GUICtrlCreateListViewItem("line5|4.50 |1B", $search_LV)
GUICtrlCreateListViewItem("line5|4.0 |2C", $search_LV)
GUICtrlCreateListViewItem("line3|23|01", $search_LV)
GUICtrlCreateListViewItem("line2|0.34560 |09", $search_LV)
GUICtrlCreateListViewItem("line1|1.0 |7A", $search_LV)
GUICtrlCreateListViewItem("line1|0.1 |8C", $search_LV)
GUICtrlCreateListViewItem("line1|97|5B", $search_LV)
GUICtrlCreateListViewItem("line1|910|9B", $search_LV)
GUICtrlCreateListViewItem("line1|99|11", $search_LV)
GUICtrlCreateListViewItem("line1|990.99|06", $search_LV)
_GUICtrlListView_SetColumnWidth($search_LV, 0, 75)
_GUICtrlListView_SetColumnWidth($search_LV, 1, 75)
_GUICtrlListView_SetColumnWidth($search_LV, 2, 75)
GUISetState()

GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")
;~ _GUICtrlListView_RegisterSortCallBack($search_LV, False)

While 1
    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE
            ExitLoop
        Case $search_LV
            ; Kick off the sort callback
;~          _GUICtrlListView_SortItems($search_LV, GUICtrlGetState($search_LV))
;~          _GUICtrlListView_UnRegisterSortCallBack($search_LV)
    EndSwitch
WEnd

Func WM_NOTIFY($hWnd, $iMsg, $iwParam, $ilParam)
    Local Static $ColumnSortedPrev = -1
    #forceref $hWnd, $iMsg, $iwParam
    Local $hWndFrom, $iIDFrom, $iCode, $tNMHDR, $hWndListView, $tInfo
    $hWndListView = $search_LV
;~  If Not IsHWnd($search_LV) Then $hWndListView = GUICtrlGetHandle($search_LV)

    $tNMHDR = DllStructCreate($tagNMHDR, $ilParam)
    $hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom"))
    $iIDFrom = DllStructGetData($tNMHDR, "IDFrom")
    $iCode = DllStructGetData($tNMHDR, "Code")

    Switch $hWndFrom
;~      Case $search_LV
        Case GUICtrlGetHandle($search_LV)
            Switch $iCode
                Case $LVN_COLUMNCLICK ; A column was clicked
                    ConsoleWrite("Header geklickt" & @CRLF)
                    Local $tInfo = DllStructCreate($tagNMLISTVIEW, $iLparam)
                    Local $ColumnSorted = DllStructGetData($tInfo, 'SubItem')
                    If $ColumnSortedPrev <> $ColumnSorted Then
                      If $ColumnSortedPrev > -1 Then _GUICtrlListView_UnRegisterSortCallBack($search_LV)
                      If $ColumnSorted = 1 Then
                          ConsoleWrite('Numeric: ' & _GUICtrlListView_RegisterSortCallBack($search_LV, True) & @CRLF)
                      Else
                          ConsoleWrite('Literal: ' & _GUICtrlListView_RegisterSortCallBack($search_LV, False) & @CRLF)
                      EndIf
                      $ColumnSortedPrev = $ColumnSorted
                    EndIf
                    _GUICtrlListView_SortItems($search_LV, DllStructGetData($tInfo, 'SubItem'))
            EndSwitch
    EndSwitch
EndFunc   ;==>WM_NOTIFY

Share this post


Link to post
Share on other sites
Xenobiologist

Thanks!  :thumbsup: 

Now I've got two working solutions.


Scripts & functions Organize Includes Let Scite organize the include files

Yahtzee The game "Yahtzee" (Kniffel, DiceLion)

LoginWrapper Secure scripts by adding a query (authentication)

_RunOnlyOnThis UDF Make sure that a script can only be executed on ... (Windows / HD / ...)

Internet-Café Server/Client Application Open CD, Start Browser, Lock remote client, etc.

MultipleFuncsWithOneHotkey Start different funcs by hitting one hotkey different times

Share this post


Link to post
Share on other sites

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

  • Similar Content

    • TimRude
      By TimRude
      The help text for the _ArrayDisplay function says: "Clicking on a column header sort it."
      I'm wondering why the sorting of hex numbers (specifically window handles like 0x12345678) is so wonky.
      Sample script:
      #include <Array.au3> Local $aList = WinList() _ArrayDisplay($aList) Clicking on the Col1 header to sort by window handle doesn't properly sort the list.
      As a workaround, I'm sorting the array by window handle before displaying it using _ArraySort. But I still wonder what's up with the ListView sorting.
      Workaround:
      #include <Array.au3> Local $aList = WinList() _ArraySort($aList, 0, 1, 0, 1) _ArrayDisplay($aList)  
    • Skysnake
      By Skysnake
      I am tracking this topic by @LarsJ.  It is very advanced and overkill for what I am currently trying to do.
       
      Problem is this.
      Listview contains columns, one of which is right aligned and gets populated by float values, such as 123.99.  Some do not have decimals ie 124.00 and on sort gets truncated to 124.  Its obviously still the same value, but the display has reset.
      ; line below is for list VIEW ;..................................0.........1......2............ $cListView = GUICtrlCreateListView("CUSTOMER|AMOUNT|DESCRIPTION", 8, 152, 764, 279) GUICtrlSetBkColor($cListView, $GUI_BKCOLOR_LV_ALTERNATE) ; alternate between the listview background color and the listview item background color GUICtrlSetBkColor($cListView, $LVStdClr) ; Set the background color for the listview _GUICtrlListView_SetColumnWidth($cListView, 0, 120) ; -- the client name _GUICtrlListView_SetColumnWidth($cListView, 1, 90) ;-- the amount _GUICtrlListView_JustifyColumn($cListView, 1, 1) ; 1 - Text is right aligned _GUICtrlListView_SetColumnWidth($cListView, 2, 200) ; the description What I am looking for is something native and simple like a 
          _GUICtrlListView_SetColumnFormat($cListView, 1, "%.2f") ;  1 - column is stringformatted to "%.2f"
      So that after each sort it will appear as it was in the original rendering.
      Is there something like this? I have not been able to find a simple solution.

      Thanks.
      Skysnake
    • Ambient
      By Ambient
      I have tried several way sto get this to work to no avail. Any help would be appreciated. #include <ListViewConstants.au3> #include <GuiListView.au3> #include "GuiListViewEx.au3" $idItem = GUICtrlCreateListViewItem($r & " | " & $c & $adoRs.Fields("TransactionAmount").value & " | " & $Timestamp & " | " & _StringProper($adoRs.Fields("Tillid").value) & @CRLF & @CRLF & "Card Number : " & $cardnum & " " , $idListView) ConsoleWrite( "IDITEM" & $idItem) If STRINGLEFT($adoRs.Fields("TransactionAmount").value,1)= "-" Then Consolewrite(" String is Negative" & @CRLF) ;Drops in Here as expected ;GUICtrlSetColor(-1, $COLOR_RED) ; Colour line if item is negative this didn' work $TxC= _GUICtrlListView_SetTextColor($hListView, $CLR_RED) ; I also tried $TxC= _GUICtrlListView_SetTextColor(-1, 0xFF0000) CONSOLEWRITE("TEXTCOLOUR RETURNED " & $TxC & @crlf) ; This is returning True ELSE Consolewrite(" String is NOT Negative" & @CRLF) EndIf  
    • Bilgus
      By Bilgus
      Example of Subclassing listviews using setwindowSubclass in order to intercept WM_KEYUP events
      Also pops context menu on  Shift + F10
      #include <Misc.au3> #include <ListViewConstants.au3> #include <GUIConstants.au3> #include <GuiMenu.au3> #include <WinAPIShellEx.au3> Global $g_hCB, $g_pCB, $g_ahProc[2][2] ;Stores the Data for subclassing listview Global $g_LVKEYUP = 0xFE00, $g_LVKEYDN = 0xFD00 ;Our Own Custom messages (Key Up/Dn) Global $g_iDummyData Global $g_hGui = GUICreate("test") Global $g_hList1 = GUICtrlCreateListView("#|x|y", 5, 24, 161, 70, $LVS_SHOWSELALWAYS Or $LVS_SINGLESEL) GUICtrlCreateListViewItem("text", $g_hList1) Global $g_hList1_LVN = GUICtrlCreateDummy() ;Recieves Messages from the callback Global $g_hContext1 = GUICtrlCreateContextMenu($g_hList1) GUICtrlCreateMenuItem("1", $g_hContext1) GUICtrlCreateMenuItem("2", $g_hContext1) Global $g_hList2 = GUICtrlCreateListView("#|x|y", 5, 100, 161, 70, $LVS_SHOWSELALWAYS Or $LVS_SINGLESEL) GUICtrlCreateListViewItem("text", $g_hList2) Global $g_hList2_LVN = GUICtrlCreateDummy() ;Recieves Messages from the callback Global $g_hContext2 = GUICtrlCreateContextMenu($g_hList2) GUICtrlCreateMenuItem("3", $g_hContext2) GUICtrlCreateMenuItem("4", $g_hContext2) GUISetState(@SW_SHOW) SubClassListView() ;Creates our subclass Func SubClassListView() OnAutoItExitRegister("Cleanup") ;to remove our subclass $g_hCB = DllCallbackRegister('_SubclassProc', 'lresult', 'hwnd;uint;wparam;lparam;uint_ptr;dword_ptr') $g_pCB = DllCallbackGetPtr($g_hCB) $g_ahProc[0][0] = $g_hList1 ;Add the Ids of the controls we'd like to subclass $g_ahProc[1][0] = $g_hList2 ;Set up the subclass _WinAPI_SetWindowSubclass ( $hWnd, $pSubclassProc, $idSubClass [, $pData = 0] ) $g_ahProc[0][1] = _WinAPI_SetWindowSubclass(GUICtrlGetHandle($g_ahProc[0][0]), $g_pCB, $g_ahProc[0][0], $g_hList1_LVN) $g_ahProc[1][1] = _WinAPI_SetWindowSubclass(GUICtrlGetHandle($g_ahProc[1][0]), $g_pCB, $g_ahProc[1][0], $g_hList2_LVN) EndFunc ;==>SubClassListView Func _SubclassProc($hWnd, $iMsg, $wParam, $lParam, $iID, $pData) #forceref $iID Local $iRtnMsg = 0 ;Events we'd like to intercept If $iMsg = $WM_KEYUP Or $iMsg = $WM_SYSKEYUP Then $iRtnMsg = $g_LVKEYUP ElseIf $iMsg = $WM_KEYDOWN Or $iMsg = $WM_SYSKEYDOWN Then $iRtnMsg = $g_LVKEYDN EndIf ;We Recieve the Id of the dummy through $pData and pass our RtnMsg to the dummy control If $iRtnMsg Then GUICtrlSendToDummy($pData, BitOR($iRtnMsg, $wParam)) ;Pass messages on to the default handler Return _WinAPI_DefSubclassProc($hWnd, $iMsg, $wParam, $lParam) EndFunc ;==>_SubclassProc Func Cleanup() For $i = 0 To UBound($g_ahProc) - 1 ;Remove Our Subclass' by setting it back to the original proc _WinAPI_RemoveWindowSubclass(GUICtrlGetHandle($g_ahProc[$i][0]), DllCallbackGetPtr($g_ahProc[$i][1]), $g_ahProc[$i][0]) Next DllCallbackFree($g_hCB) EndFunc ;==>Cleanup While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE Exit Case $g_hList1_LVN ;This is just a dummy it only recieves events ConsoleWrite("LV1 EVENT 0x" & Hex($g_iDummyData, 4) & @CRLF) $g_iDummyData = GUICtrlRead($g_hList1_LVN) ;Retrieve the code that was sent Switch BitAND($g_iDummyData, 0xFF00) ;Get the keyup/dn status Case $g_LVKEYDN If BitAND($g_iDummyData, 0x00FF) = 0x79 And (_IsPressed("A0") Or _IsPressed("A1")) Then ;Right/ Left Shift & F10 ShowMenu($g_hGui, $g_hList1, $g_hContext1) Else ConsoleWrite("Lv1 KeyDn Vk: 0x" & Hex(BitAND($g_iDummyData, 0x00FF), 2) & @CRLF) ;Get the Virtual keycode EndIf Case $g_LVKEYUP ConsoleWrite("Lv1 KeyUp Vk: 0x" & Hex(BitAND($g_iDummyData, 0x00FF), 2) & @CRLF) ;Get the Virtual keycode EndSwitch Case $g_hList2_LVN $g_iDummyData = GUICtrlRead($g_hList2_LVN) ;Retrieve the code that was sent ConsoleWrite("LV2 EVENT 0x" & Hex($g_iDummyData, 4) & @CRLF) Switch BitAND($g_iDummyData, 0xFF00) ;Get the keyup/dn status Case $g_LVKEYDN ConsoleWrite("Lv2 KeyDn Vk: 0x" & Hex(BitAND($g_iDummyData, 0x00FF), 2) & @CRLF) ;Get the Virtual keycode Case $g_LVKEYUP ConsoleWrite("Lv2 KeyUp Vk: 0x" & Hex(BitAND($g_iDummyData, 0x00FF), 2) & @CRLF) ;Get the Virtual keycode EndSwitch EndSwitch WEnd Func ShowMenu($hWnd, $idCtrl, $idContext) Local $aPos, $iX, $iY Local $hMenu = GUICtrlGetHandle($idContext) $aPos = ControlGetPos($hWnd, "", $idCtrl) $iX = $aPos[0] $iY = $aPos[1] + $aPos[3] ClientToScreen($hWnd, $iX, $iY) ; Show at the given coordinates (x, y) the popup menu (hMenu) which belongs to a given GUI window (hWnd) _GUICtrlMenu_TrackPopupMenu($hMenu, $hWnd, $iX, $iY) EndFunc ;==>ShowMenu ; Convert the client (GUI) coordinates to screen (desktop) coordinates Func ClientToScreen($hWnd, ByRef $iX, ByRef $iY) Local $tPoint = DllStructCreate("int;int") DllStructSetData($tPoint, 1, $iX) DllStructSetData($tPoint, 2, $iY) DllCall("user32.dll", "int", "ClientToScreen", "hwnd", $hWnd, "struct*", $tPoint) $iX = DllStructGetData($tPoint, 1) $iY = DllStructGetData($tPoint, 2) ; release Struct not really needed as it is a local $tPoint = 0 EndFunc ;==>ClientToScreen  
      Old Code Using setWindowLong
       
×