找回密码
 加入
搜索
查看: 17436|回复: 80

[AU3基础] 如何使用左键单点击达成LISTVIEW连续选中状态??

  [复制链接]
发表于 2017-7-30 03:01:29 | 显示全部楼层 |阅读模式
如何使用左键单点击达成可以达成LISTVIEW 如同 被
_GUICtrlListView_SetItemSelected 选中后的状态

标准的模式 是 我单点击 ITEM1  就会选中 ITEM1
再单点击 一次 ITEM2 就会把 ITEM1 的状态取消 变成选中
ITEM2

我需要的是 可以不按 CTRL 键 可以达成 如同按下 CTRL键一样的效果

P.S 不使用 Send ( "按键" [, 标志] ) 方法 发送 CTRL按键






#include <GUIConstantsEx.au3>
#include <GuiListView.au3>
#include <GuiImageList.au3>
#include <WindowsConstants.au3>

$Debug_LV = False ; ?查??到 ListView 函?的?名, ?置 True,并使用一?句柄到另一?控件查看它的工作
GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")

   Local $hListView

    GUICreate("ListView 列表?? UDF 函?演示", 400, 300)
    $hListView = GUICtrlCreateListView("", 2, 2, 394, 268, $LVS_SHOWSELALWAYS , $LVS_EX_GRIDLINES + $LVS_EX_FULLROWSELECT + $LVS_EX_DOUBLEBUFFER)
    GUISetState()

    ; 添加列
    _GUICtrlListView_AddColumn($hListView, "數據", 100)

    ; 添加?据?
    GUICtrlCreateListViewItem("ITEN 1", $hListView)
    GUICtrlCreateListViewItem("ITEM 2", $hListView)
    GUICtrlCreateListViewItem("ITEM 3", $hListView)
    GUICtrlCreateListViewItem("ITEN 4", $hListView)
    GUICtrlCreateListViewItem("ITEM 5", $hListView)
    GUICtrlCreateListViewItem("ITEM 6", $hListView)
    GUICtrlCreateListViewItem("ITEN 7", $hListView)
    GUICtrlCreateListViewItem("ITEM 8", $hListView)
    GUICtrlCreateListViewItem("ITEM 9", $hListView)

    ; 循?到用?退出
    Do
    Until GUIGetMsg() = $GUI_EVENT_CLOSE
    GUIDelete()


Func WM_NOTIFY($hWnd, $iMsg, $iwParam, $ilParam)
        #forceref $hWnd, $iMsg, $iwParam
        Local $hWndFrom, $iIDFrom, $iCode, $tNMHDR, $tInfo, $s
 
        $tNMHDR = DllStructCreate($tagNMHDR, $ilParam)
        $hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom"))
        $iIDFrom = DllStructGetData($tNMHDR, "IDFrom")
        $iCode = DllStructGetData($tNMHDR, "Code")
                Switch $iCode
                                                        
                        Case $NM_CLICK ;左點擊  按一下
                        ConsoleWrite("A")

                EndSwitch

        Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_NOTIFY

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?加入

×
发表于 2017-7-30 15:06:56 | 显示全部楼层
本帖最后由 yamakawa 于 2017-7-30 15:13 编辑

首先, _GUICtrlListView_GetSelectedColumn读取出当前选择的项的索引,保存到数组
然后,循环读取数组,_GUICtrlListView_SetSelectedColumn设置。应该是这个过程,没测试,这几天折腾sqlite。懒得写代码了


不对,,应该是第一次选择的时候,_GUICtrlListView_GetSelectedIndices保存索引到数组
第二次选择的时候,添加当前选择索引到数组,然后循环读取数组,, _GUICtrlListView_SetItemSelected
发表于 2017-7-30 16:13:19 | 显示全部楼层
本帖最后由 yamakawa 于 2017-7-30 18:14 编辑

刚刚再看发现你要求 再次点击取消   所以修改代码

未精简,仅供测试
Func WM_NOTIFY($hWnd, $iMsg, $iwParam, $ilParam)
        #forceref $hWnd, $iMsg, $iwParam
        Local $hWndFrom, $iIDFrom, $iCode, $tNMHDR, $tInfo, $index

        $tNMHDR = DllStructCreate($tagNMHDR, $ilParam)
        $hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom"))
        $iIDFrom = DllStructGetData($tNMHDR, "IDFrom")
        $iCode = DllStructGetData($tNMHDR, "Code")
                Switch $iCode
                                                        
                                        Case $NM_CLICK ;左點擊  按一下
                                                ;====>特别说明,需要增加一个全局变量 Global $sResult[0]
                                                                 $tInfo = DllStructCreate($tagNMITEMACTIVATE, $ilParam)
                                $index = DllStructGetData($tInfo, "Index")
                                                                ConsoleWrite( $index & @CRLF)
                                                                If $index = -1 Then 
                                                                        ReDim $sResult[0]
                                                                        Return
                                                                EndIf
                                                                
                                                                $tindex = _ArraySearch($sResult,$index)
                               If  $tindex  = -1 Then 
                                                                   _ArrayAdd($sResult,$index)
                                                           Else
                                                                   _ArrayDelete($sResult,$tindex)
                                                                     _GUICtrlListView_SetItemSelected($hListView,$tindex,False)

                                                           EndIf
                                                           
                                                                
                                                        
                                ConsoleWrite(_ArrayToString($sResult) & @CRLF)
                                                                If IsArray($sResult) Then 
                                                                        _GUICtrlListView_BeginUpdate($hListView)
                                                                        _GUICtrlListView_SetItemSelected($hListView,-1,False)

                                                                        For $i = 0 To UBound($sResult) -1
                                                                                _GUICtrlListView_SetItemSelected($hListView,$sResult[$i])
                                                                        Next
                                                                        _GUICtrlListView_EndUpdate($hListView)
                                                                EndIf
                                EndSwitch

 
        Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_NOTIFY
 楼主| 发表于 2017-7-30 18:14:24 | 显示全部楼层
本帖最后由 kk_lee69 于 2017-7-30 18:16 编辑

回复 3# yamakawa


這個方法我試過...最大的缺點就是 會閃爍  畫面很不協調

因為你每點擊 一次  就會 從頭到尾 將數組內的 資訊 再重新選擇一次

你可以點選看看效果  跟你 是著按下 CTRL 然後點選看看 的效果 有差異的

因此 上來尋找更好的解決方法
发表于 2017-8-16 12:05:19 | 显示全部楼层
回复 4# kk_lee69


    今天没事做,突然想到你这问题解决方法。。。
                Case $NM_CLICK ;左點擊  按一下
                        _WinAPI_Keybd_Event(0xA2, Default)
没有加判断,比如点击空白怎么样,,你自己加吧


退出部分记得加
If _IsPressed("A2") Then
        ConsoleWrite("LContrl is pressed!" & @CRLF)
        _WinAPI_Keybd_Event(0xA2, $KEYEVENTF_KEYUP)
EndIf
GUIDelete()
释放ctrl按下状态。。。不然。。嘿嘿
 楼主| 发表于 2017-8-27 02:50:21 | 显示全部楼层
回复 5# yamakawa

官方 已經有人回覆 有範例在

可是 老實說 我大概懂他在幹嘛  但是我無法改成 可以融入我的 程式
又不好意思 跟 老外問太多  所以只好上來這 找你幫忙  我覺得 你的程式功力應該比我好
呵呵

大概看得出來 他是
  ; Subclass ListView to receive keyboard/mouse messages
  Local $pListViewFunc = DllCallbackGetPtr( DllCallbackRegister( "ListViewFunc", "lresult", "hwnd;uint;wparam;lparam;uint_ptr;dword_ptr" ) )
  _WinAPI_SetWindowSubclass( $hListView, $pListViewFunc, 0, 0 ) ; $iSubclassId = 0, $pData = 0
註冊了一個子消息之類的  然後再利用那個 ListViewFunc  去控制

我常用的是 3.3.8 的程式

這個範例我改用 v3.3.8 的主程式   V3.3.14 的API 功能  .... 無法執行成功  畫面會不見  整個程式GUI 都出不來....

也就是說 我如果要用這個方法就得 改用新版的主程式
但是 我的東西太多了  不想改主程式版本
但是要把下面的範例改成 V3.3.8 可以用的 我又改不出來...
所以無法測試 ..........

不知道您是否可以幫忙  改成 3.38 可以RUN   我在測試看看怎麼融入我的程式裡面

唉  一堆的想法  想用英文表達 還真是困難~~~


#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <WinAPIShellEx.au3>
;#include <WinAPI.au3>
#include <GuiListView.au3>

Opt( "MustDeclareVars", 1 )

Global $idListView, $idAddSingleSel, $idDelSingleSel

Example()

Func Example()
  ; Create GUI
  GUICreate( "ctrl+single-click --> single-click", 420, 200 )

  ; Create ListView
  $idListView = GUICtrlCreateListView( "", 10, 10, 400, 180, $GUI_SS_DEFAULT_LISTVIEW-$LVS_SINGLESEL, $WS_EX_CLIENTEDGE )
  _GUICtrlListView_SetExtendedListViewStyle( $idListView, $LVS_EX_DOUBLEBUFFER+$LVS_EX_FULLROWSELECT )
  Local $hListView = GUICtrlGetHandle( $idListView )

  ; Add columns to ListView
  _GUICtrlListView_InsertColumn( $idListView, 0, "Column 1", 94 )
  _GUICtrlListView_InsertColumn( $idListView, 1, "Column 2", 94 )
  _GUICtrlListView_InsertColumn( $idListView, 2, "Column 3", 94 )
  _GUICtrlListView_InsertColumn( $idListView, 3, "Column 4", 94 )

  ; Fill ListView
  Local $iItems = 100
  For $i = 0 To $iItems - 1
    GUICtrlCreateListViewItem( $i & "/Column 1|" & $i & "/Column 2|" & $i & "/Column 3|" & $i & "/Column 4", $idListView )
  Next

  ; Subclass ListView to receive keyboard/mouse messages
  Local $pListViewFunc = DllCallbackGetPtr( DllCallbackRegister( "ListViewFunc", "lresult", "hwnd;uint;wparam;lparam;uint_ptr;dword_ptr" ) )
  _WinAPI_SetWindowSubclass( $hListView, $pListViewFunc, 0, 0 ) ; $iSubclassId = 0, $pData = 0

  ; Add/del single selection
  $idAddSingleSel = GUICtrlCreateDummy()
  $idDelSingleSel = GUICtrlCreateDummy()
  Local $iItem

  ; Show GUI
  GUISetState( @SW_SHOW )

  ; Message loop
  While 1
    Switch GUIGetMsg()
      Case $idAddSingleSel
        $iItem = GUICtrlRead( $idAddSingleSel )
        _GUICtrlListView_SetItemSelected( $idListView, $iItem, True )
        _GUICtrlListView_SetItemFocused( $idListView, $iItem )
      Case $idDelSingleSel
        $iItem = GUICtrlRead( $idDelSingleSel )
        _GUICtrlListView_SetItemSelected( $idListView, $iItem, False )
        _GUICtrlListView_SetItemFocused( $idListView, $iItem )
      Case $GUI_EVENT_CLOSE
        ExitLoop
    EndSwitch
  WEnd

  ; Cleanup
  _WinAPI_RemoveWindowSubclass( $hListView, $pListViewFunc, 0 )
  GUIDelete()
EndFunc

Func ListViewFunc( $hWnd, $iMsg, $wParam, $lParam, $iSubclassId, $pData )
  If $iMsg <> $WM_LBUTTONDOWN Then Return DllCall( "comctl32.dll", "lresult", "DefSubclassProc", "hwnd", $hWnd, "uint", $iMsg, "wparam", $wParam, "lparam", $lParam )[0]

  Switch $wParam
    Case 0x0001  ; 0x0001 = MK_LBUTTON (LButton down)
      If _GUICtrlListView_GetSelectedCount( $idListView ) Then
        Local $aHit = _GUICtrlListView_HitTest( GUICtrlGetHandle( $idListView ), BitAND( $lParam, 0xFFFF ), BitShift( $lParam, 16 ) )
        If Not ( @error Or $aHit[0] = -1 ) Then
          If _GUICtrlListView_GetItemSelected( $idListView, $aHit[0] ) Then
            GUICtrlSendToDummy( $idDelSingleSel, $aHit[0] )
          Else
            GUICtrlSendToDummy( $idAddSingleSel, $aHit[0] )
          EndIf
        EndIf
        Return 0 ; Disable single-click in ListView to prevent resetting selections
      EndIf

    Case 0x0009  ; 0x0009 = MK_LBUTTON (LButton down) + MK_CONTROL (Ctrl down)
      Return 0   ; Disable single selections in ListView with ctrl+single-click
  EndSwitch

  Return DllCall( "comctl32.dll", "lresult", "DefSubclassProc", "hwnd", $hWnd, "uint", $iMsg, "wparam", $wParam, "lparam", $lParam )[0]
  ; Call next function in subclass chain (this forwards messages to main GUI)
  #forceref $iSubclassId, $pData
EndFunc
发表于 2017-8-27 09:29:27 | 显示全部楼层
scite错误代码是怎样的??
因为我也是3.3.14版本的,,,,,,要测试旧版得想办法先去下载
发表于 2017-8-27 09:52:49 | 显示全部楼层
回复 6# kk_lee69


在3.3.9.4测试没问题呀

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?加入

×
 楼主| 发表于 2017-8-27 11:59:31 | 显示全部楼层
回复 8# chzj589
我的是 3.3.8

呵呵
 楼主| 发表于 2017-8-27 12:01:15 | 显示全部楼层
回复 7# yamakawa

沒有錯誤代碼 就是這個方法在 3.3.8 版本   連 GUI 都跑不出來
但是 程式有在 工作管理員中 執行
发表于 2017-8-27 12:59:21 | 显示全部楼层
没有错误代码?scite下面信息输出那里什么都没有?
发表于 2017-8-27 14:14:21 | 显示全部楼层
回复 10# kk_lee69


    你有旧版安装包么?没地方找了。。论坛的几个链接都失效了。。。。有的话你给我个。我试试看。。。繁中的也ok
发表于 2017-8-27 16:35:38 | 显示全部楼层
这个位置。。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?加入

×
发表于 2017-8-27 17:05:15 | 显示全部楼层
回复 13# yamakawa

刚用3.3.6.1测试,
        If $iMsg <> $WM_LBUTTONDOWN Then Return DllCall("comctl32.dll", "lresult", "DefSubclassProc", "hwnd", $hWnd, "uint", $iMsg, "wparam", $wParam, "lparam", $lParam)[0] 
Return DllCall("comctl32.dll", "lresult", "DefSubclassProc", "hwnd", $hWnd, "uint", $iMsg, "wparam", $wParam, "lparam", $lParam)[0]

问题出在这里:[0]
发表于 2017-8-27 17:25:01 | 显示全部楼层
本帖最后由 yamakawa 于 2017-8-27 17:28 编辑

回复 14# chzj589


    那就试着分句写。。
If $iMsg <> $WM_LBUTTONDOWN Then
        Local $result = DllCall("comctl32.dll", "lresult", "DefSubclassProc", "hwnd", $hWnd, "uint", $iMsg, "wparam", $wParam, "lparam", $lParam)
        If Not @error Then
                Return $result[0]  
        Else
                ConsoleWrite("Error is " & @error & @CRLF)
        EndIf
EndIf
Local $result = DllCall("comctl32.dll", "lresult", "DefSubclassProc", "hwnd", $hWnd, "uint", $iMsg, "wparam", $wParam, "lparam", $lParam)
If Not @error Then
        Return $result[0]  
Else
        ConsoleWrite("Error is " & @error & @CRLF)
EndIf
看看行不行
您需要登录后才可以回帖 登录 | 加入

本版积分规则

QQ|手机版|小黑屋|AUTOIT CN ( 鲁ICP备19019924号-1 )谷歌 百度

GMT+8, 2024-3-29 21:26 , Processed in 0.082202 second(s), 20 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表