如何发送消息使另外一个进程窗口的SysListView32控件的一个item被选中??
谢谢大家,我在网上找了许多资料关于SysListView32的资料比较少
请各位大峡帮忙,谢谢了!!
解决开贴放分!!!

解决方案 »

  1.   

    这个涉及到跨进程的问题了,所以,需要VirtualAllocEx从目标进程申请空间,这样SendMessage发送获取的数据,目标进程才能认识,mfc板块以前好像有这样的帖子,你可以搜索一下
      

  2.   

    首先你需要找到这个SysListView32窗口,找到以后可以通过发送LVM_消息来获得这个窗体的被选中状态。
      

  3.   

    谢谢各位!!
     flyelf(空谷清音) 
    我在mfc中看过,但是我对vc不是懂,我想用vb实现!!
      

  4.   

    TechnoFantasy(冰儿马甲www.applevb.com) 
    我已经找到窗口了,但是我不知道如何发送消息!!!谢谢
      

  5.   

    http://msdn.microsoft.com/library/default.asp?url=/library/en-us/shellcc/platform/commctls/listview/messages/lvm_setitemstate.asp
      

  6.   

    外国网站搞得,由于我没有你说的那个东西,所以不能测试,自己看一下吧。
    选中第一个 item: SendMessage(hwndListView,
                  LVM_GETNEXTITEM,
                  0,
                  MAKELPARAM(LVNI_ALL or LVNI_SELECTED, 0))
    上面返回第一个,要想用其他的,使用同样的语句,不过把第三个参数换成刚返回的index选中全部地用这个:    SendMessage(hwndListView, LVM_GETITEMCOUNT, 0, 0);英文:
    So to get the first
    > selected item:
    >
    > SendMessage(hwndListView,
    >              LVM_GETNEXTITEM,
    >              0,
    >              MAKELPARAM(LVNI_ALL or LVNI_SELECTED, 0));
    >
    > This will return the item index of the first selected item.
    > To get the next selected item, send the same message with
    > the returned index as the 3rd parameter (the start index),
    > and repeat until no more items are returned.
    >
    > To get the total number of items use
    >    SendMessage(hwndListView, LVM_GETITEMCOUNT, 0, 0);
      

  7.   

    高手能不能帮忙找点vb的资料,vc的我看不懂呀!
    谢谢了!!
      

  8.   

    第四个参数,用的是delphi的,自己转化一下,
      

  9.   

    vb里面这个MAKELPARAM没有呀
    这个文章我也看过
      

  10.   

    菜鸟来了,但可能帮你仅仅问题
    使用查找进程,具体见findwindow ,findwindowex两个函数
    找到对应的控件后,调用sendmessage方法,向该控件发送命令
    具体的命令格式查看sendmessage的用法
    函数定义以下,说明,要用到的参数可以用工具(spy++)来查看到
    Private Declare Function FindWindow Lib "user32.dll" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
    '寻找窗口列表中第一个符合指定条件的顶级窗口
    'lpClassName指向包含了窗口类名的空中止(C语言)字串的指针;或设为零,'表示接收任何类
    'lpWindowName指向包含了窗口文本(或标签)的空中止(C语言)字串的指针;'或设为零,表示接收任何窗口标题Private Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" (ByVal hWnd1 As Long, ByVal hWnd2 As Long, ByVal lpsz1 As String, ByVal lpsz2 As String) As Long
    '在窗口列表中寻找与指定条件相符的第一个子窗口
    'hWnd1在其中查找子的父窗口
    'hWnd2从这个窗口后开始查找。这样便可利用对FindWindowEx的多次调用找到符合条件的所有子窗口。如设为零,表示从第一个子窗口开始搜索Private Declare Function SendMessage Lib "user32.dll" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
      

  11.   

    阿门,写这个好麻烦的。这里是个获取其他程序上TreeView或ListView内容的例子,你只要改一下消息就能变成选择指定项了http://210.33.90.250/download/vbsrc/lvtvgettext.rar 
      

  12.   

    LVNI_SELECTED=&h2
    LVNI_ALL =&h0直接换成 (LVNI_SELECTED or LVNI_ALL )就可以了,反正需要一个长整数。我感觉麻烦的地方应该在查找hwnd的过程。我是指编程序,不是自己找。
      

  13.   

    我现在遇到的关键问题是
    发消息给 SysListView32 
    找的话倒是可以找
      

  14.   

    再看这个例子:Option Explicit
    Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
    Private Declare Function SendMessageLong Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wmsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
    Private Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" (ByVal hWnd1 As Long, ByVal hWnd2 As Long, ByVal lpsz1 As String, ByVal lpsz2 As String) As Long
    Private Const LVM_GETTITEMCOUNT& = (&H1000 + 4)
    Private Const LVM_SETITEMPOSITION& = (&H1000 + 15)
    Private Const LVM_FIRST = &H1000
    Private Const LVM_GETITEMPOSITION = (LVM_FIRST + 16)
    Private Const LVM_GETITEMTEXT = LVM_FIRST + 45
    Private Const LVM_GETIMAGELIST = (LVM_FIRST + 2)
    Private Const LVSIL_NORMAL = 0
    Private Const LVM_GETITEM = (LVM_FIRST + 5)
    Private Const LVM_ARRANGE = (LVM_FIRST + 22)
    Private Type POINTAPI
    X As Long
    y As Long
    End Type
    Private Declare Function SystemParametersInfo Lib "user32" Alias "SystemParametersInfoA" (ByVal uAction As Long, ByVal uParam As Long, ByRef lpvParam As Any, ByVal fuWinIni As Long) As Long
    Private Const SPI_GETWORKAREA = 48Public Sub GetDeskIconPosition(ByVal SX As String)
    'Dim hdesk As Long
    Dim WorkArea As RECT
    Dim DeskWidth As Long
    Dim DeskHeight As Long
    Dim Pointx() As POINTAPI
    Dim Hdesk As Long
    Hdesk = GetrDeskIconHandle()
    SystemParametersInfo SPI_GETWORKAREA, 0, WorkArea, 0
    DeskWidth = WorkArea.Right
    DeskHeight = WorkArea.Bottom
    Dim IconCount As Long
    IconCount = SendMessage(Hdesk, LVM_GETTITEMCOUNT, 0, 0)
    Dim TR As Long, J As Long, Ji As Long
    Dim RF As Long, Frt As Boolean, Rf1 As Long, FR As Boolean, LT As Boolean
    Dim Rf2 As Long
    LT = False
    FR = False
    Frt = False
    TR = 0
    J = 0
    ReDim Pointx(IconCount)
    For TR = 0 To IconCount - 1
    Ji = Ji + 1DoEvents
    Ds: Select Case SX
    Case "桌面图标左顶对齐"
    Pointx(TR).y = 77 * (J + 1) - 77
    Pointx(TR).X = 77 * Ji - 50
    If Pointx(TR).X > DeskWidth - 10 Then
    Ji = 1
    J = J + 1
    GoTo Ds
    End If
    Case "桌面图标右顶对齐" '右顶对齐Pointx(TR).y = 77 * (J + 1) - 77
    Pointx(TR).X = DeskWidth - 77 * Ji + 10
    If Pointx(TR).X < 10 Then
    Ji = 1
    J = J + 1
    GoTo Ds
    End If
    Case "桌面图标左对齐" '左对齐
    Pointx(TR).y = 77 * Ji - 77
    Pointx(TR).X = 77 * J + 10If Pointx(TR).y > DeskHeight - 40 Then
    Ji = 1
    J = J + 1
    GoTo Ds
    End IfCase "桌面图标右对齐" '右对齐Pointx(TR).y = 77 * Ji - 77
    Pointx(TR).X = DeskWidth - 77 * J - 77
    If Pointx(TR).y > DeskHeight - 40 Then
    Ji = 1
    J = J + 1
    GoTo Ds
    End If
    Case "桌面图标左右环绕" '环绕
    '左顶对齐
    If ((DeskWidth - 77) > (77 * Ji - 50)) And Frt = False Then
    Pointx(TR).y = 0 '77 * (J + 1) - 77
    Pointx(TR).X = 77 * Ji - 50
    RF = Pointx(TR).X
    Else
    '右对齐
    If Frt = False Then
    Ji = 2
    Frt = True
    End If
    If FR = False And ((DeskHeight - 40) > (77 * Ji - 77)) Then
    Pointx(TR).X = RF
    Pointx(TR).y = 77 * Ji - 77
    Rf1 = Pointx(TR).y
    Else
    '右底对齐
    If FR = False Then
    FR = True
    Ji = 2
    End If
    If LT = False And DeskWidth - 77 * Ji > 10 Then
    Pointx(TR).y = Rf1
    Pointx(TR).X = DeskWidth - 77 * Ji
    Rf2 = Pointx(TR).X
    Else
    '左对齐
    If LT = False Then
    LT = True
    Ji = 2
    End If
    Pointx(TR).X = Rf2
    Pointx(TR).y = DeskHeight - 77 * Ji
    End If
    End If
    End If
    Case "桌面图标右底对齐" '右底对齐
    Pointx(TR).X = DeskWidth - 77 * Ji
    Pointx(TR).y = DeskHeight - 77 * (J + 1)
    If Pointx(TR).X < 10 Then
    Ji = 1
    J = J + 1
    GoTo Ds
    End If
    End Select
    SendMessageLong Hdesk, LVM_SETITEMPOSITION, TR, CLng(Pointx(TR).X + Pointx(TR).y * &H10000)
    Next TR
    Erase Pointx()
    End SubPublic Function GetrDeskIconHandle() As Long
    Dim Wnd As Long
    Wnd = FindWindow("progman", vbNullString)
    Wnd = FindWindowEx(Wnd, 0, "shelldll_defview", vbNullString)
    Wnd = FindWindowEx(Wnd, 0, "syslistview32", vbNullString)
    GetrDeskIconHandle = Wnd
    End Function
      

  15.   

    兄弟,你直接打开文件夹,他就是一个SysListView32,你获得他的句柄,然后向发送消息看看!!!
      

  16.   

    好好看看jiangsheng(蒋晟.MSMVP2004Jan)给的链结(发送消息的话就发送LVM_SETITEMSTATE消息)(最好先在一个进程内调试,然后再解决跨进程问题,跨进程问题可以参考豆子的代码)
      

  17.   

    http://www.sijiqing.com/vbgood/forum/forum_posts.asp?TID=6545&PN=1
    这段代码你可以参考一下(主要看看怎么发送消息)
      

  18.   

    这个看过吗?不出意外的话,就是它啦。http://sunh.hosp.ncku.edu.tw/~cww/html/q00535.html
      

  19.   

    贴出来吧,呵呵, 如何在外部程式配置記憶體 
      
      
     說明 在Win32底下,所有Process的位址都是獨立的,理論上是沒辦法再外部程式上配置記憶體的,但對於某些程式的需求(如共享記憶體,Global Hook),系統還是會在外部程式配置一塊記憶體註:行程間要共享記憶體或是交換資料一定得透過記憶體映射檔去做(包括用SendMessage 使用WM_COPYDATA來傳資料底層都有用記憶體映射檔) 
         記憶體映射檔在9x以及NT環境下有所不同,在9x系統下,記憶體映射檔在每個Process都在相同位址,而且每個Process都可以直接存取該塊記憶體,但在NT下卻不是這樣,NT下當某個Process開啟記憶體映射檔時 該記憶體只映射到呼叫的Process的行程空間中 並不會存在其他Process的行程空間 當另一個行程B也開啟此記憶體映射檔時 系統才會將該記憶體映射到行程B 這和9x系統有相當大的不同 NT底下有更獨立的位址空間因此 如果是在9x的系統 要再外部程式配置記憶體 有2種方式 透過記憶體映射檔(無論對方行程同不同意 都能配置) 
    透過Global Hook去注射行程 然後配置記憶體(這必須透過DLL去做 但VB沒辦法做出標準的DLL檔 這個方法並不是用於VB) 
    同樣的方式在NT底下 透過記憶體映射檔(這必須對方行程同意的情況才能配置) 
    透過Global Hook去注射行程 然後配置記憶體(這必須透過DLL去做 但VB沒辦法做出標準的DLL檔 這個方法並不是用於VB) 
    這下子VB在NT下不就不能神不知鬼不覺得再外部程式配置記一體了對吧?當然不是 在NT下有提供一個API:VirtualAllocEx可以讓你再任一行程上配置記憶體,使用完後再用VirtualFreeEx釋放掉該空間即可此配置程式我已經把他包裝成物件模組 應該蠻容易使用的 程式 '以下程式在物件類別模組
    Option ExplicitPrivate Declare Function VirtualAllocEx Lib "kernel32" (ByVal hProcess As Long, lpAddress As Any, ByVal dwSize As Long, ByVal flAllocationType As Long, ByVal flProtect As Long) As Long 
    Private Declare Function VirtualFreeEx Lib "kernel32" (ByVal hProcess As Long, lpAddress As Any, ByVal dwSize As Long, ByVal dwFreeType As Long) As Long Private Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As Long 
    Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As LongPrivate Type OSVERSIONINFO
            dwOSVersionInfoSize As Long
            dwMajorVersion As Long
            dwMinorVersion As Long
            dwBuildNumber As Long
            dwPlatformId As Long
            szCSDVersion As String * 128      '  Maintenance string for PSS usage
    End TypePrivate Declare Function GetVersionEx Lib "kernel32" Alias "GetVersionExA" _
            (lpVersionInformation As OSVERSIONINFO) As Long 
    Private Const VER_PLATFORM_WIN32_NT = 2
    Private Const VER_PLATFORM_WIN32_WINDOWS = 1
    Private Const VER_PLATFORM_WIN32s = 0Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Long, ByVal Length As Long) 
    Private Declare Function CreateFileMapping Lib "kernel32" Alias "CreateFileMappingA" (ByVal hFile As Long, lpFileMappigAttributes As Any, ByVal flProtect As Long, ByVal dwMaximumSizeHigh As Long, ByVal dwMaximumSizeLow As Long, ByVal lpName As String) As Long 
    Private Declare Function MapViewOfFile Lib "kernel32" (ByVal hFileMappingObject As Long, ByVal dwDesiredAccess As Long, ByVal dwFileOffsetHigh As Long, ByVal dwFileOffsetLow As Long, ByVal dwNumberOfBytesToMap As Long) As Long 
    Private Declare Function UnmapViewOfFile Lib "kernel32" (lpBaseAddress As Any) As Long 
    Private Const GENERIC_READ = &H80000000
    Private Const GENERIC_WRITE = &H40000000
    Private Const OPEN_ALWAYS = 4
    Private Const FILE_ATTRIBUTE_NORMAL = &H80
    Private Const SECTION_MAP_WRITE = &H2
    Private Const FILE_MAP_WRITE = SECTION_MAP_WRITE
    Private Const PAGE_READWRITE As Long = &H4
    Private Const MEM_HANDLE As Long = &HFFFFFFFFPrivate Declare Function CoCreateGuid Lib "ole32.dll" (lpGUID As Any) As Long 
    Private Declare Function StringFromGUID2 Lib "ole32" (lpGUID As Any, ByVal lpStr As String, ByVal lSize As Long) As Long'紀錄物件中所有配置的記憶體 當成是結束時如有未釋放的可自動釋放掉
    Private Type FileMap
        iCount As Integer
        AddressOfFileMap() As Long
        hFileMap() As Long
        tProcessID() As Long
        iIndex As Integer
    End TypeDim UseMap As FileMap'Process 參數
    Private Const STANDARD_RIGHTS_REQUIRED = &HF0000
    Private Const SYNCHRONIZE = &H100000
    Private Const SPECIFIC_RIGHTS_ALL = &HFFFF
    Private Const STANDARD_RIGHTS_ALL = &H1F0000
    Private Const PROCESS_ALL_ACCESS = STANDARD_RIGHTS_REQUIRED Or SYNCHRONIZE Or &HFFF
    Private Const PROCESS_VM_OPERATION = &H8&
    Private Const PROCESS_VM_READ = &H10&
    Private Const PROCESS_VM_WRITE = &H20&
    Private Const PROCESS_QUERY_INFORMATION = 1024'記憶體型態
    Private Const MEM_COMMIT = &H1000
    Private Const MEM_RESERVE = &H2000
    Private Const MEM_DECOMMIT = &H4000
    Private Const MEM_RELEASE = &H8000
    Private Const MEM_FREE = &H10000
    Private Const MEM_PRIVATE = &H20000
    Private Const MEM_MAPPED = &H40000
    Private Const MEM_RESET = &H80000
    Private Const MEM_TOP_DOWN = &H100000
    Private Const MEM_4MB_PAGES = &H80000000
    Private Const SEC_IMAGE = &H1000000
    Private Const MEM_IMAGE = SEC_IMAGE'記憶體保護狀態
    Private Const PAGE_NOACCESS = &H1
    Private Const PAGE_READONLY = &H2
    'Private Const PAGE_READWRITE = &H4
    Private Const PAGE_WRITECOPY = &H8
    Private Const PAGE_EXECUTE = &H10
    Private Const PAGE_EXECUTE_READ = &H20
    Private Const PAGE_EXECUTE_READWRITE = &H40
    Private Const PAGE_EXECUTE_WRITECOPY = &H80
    Private Const PAGE_GUARD = &H100
    Private Const PAGE_NOCACHE = &H200
    Public IsNt As Boolean
      

  20.   

    在我的lvtvgettext程序里面加个下面这个函数'lhWnd为ListView的窗口句柄,lItemIndex为子项的序号,fSelect为是否选择标志
    'lItemIndex从0开始。但可以为-1,表示针对全部子项进行操作
    Function DoItemSelect(ByVal lhWnd As Long, ByVal lItemIndex As Long, Optional ByVal fSelect As Boolean = True) As Long
        Dim mhwnd As Long
        mhwnd = lhWnd
        Dim i As Long, s As String
        Dim dwProcessId As Long, hProcess As Long
        Dim dwBytesRead As Long, dwBytesWrite As Long
        Call GetWindowThreadProcessId(mhwnd, dwProcessId)
        Dim lpListItemRemote As Long
        Dim lvItemLocal As LV_ITEM
        Dim bWriteOK As Long
        
        hProcess = OpenProcess(PROCESS_VM_OPERATION Or PROCESS_VM_READ Or PROCESS_VM_WRITE, 0&, dwProcessId)
        If hProcess <> 0 Then
            lpListItemRemote = VirtualAllocEx(ByVal hProcess, ByVal 0&, Len(lvItemLocal), MEM_COMMIT, PAGE_READWRITE)
            With lvItemLocal
                .mask = LVIF_STATE
                .state = IIf(fSelect, LVIS_SELECTED Or LVIS_FOCUSED, 0)
                .stateMask = LVIS_SELECTED Or LVIS_FOCUSED
            End With
            dwBytesWrite = 0
            bWriteOK = WriteProcessMemory(ByVal hProcess, ByVal lpListItemRemote, ByVal VarPtr(lvItemLocal), Len(lvItemLocal), dwBytesWrite)
            DoItemSelect = SendMessage(lhWnd, LVM_SETITEMSTATE, lItemIndex, ByVal lpListItemRemote)
            Call VirtualFreeEx(hProcess, ByVal lpListItemRemote, 0, MEM_DECOMMIT)
        End If
        CloseHandle hProcess
    End Function
      

  21.   

    万分感谢各位大虾的帮助通过大家的帮助我已经初步实现了遍历另外一个程序中SysListView32控件中的Item元素了但是现在又遇到一个问题,我想实现给指定Item发送鼠标点击动作,可以实现吗,如何实现??谢谢!!谢谢.........
    http://community.csdn.net/Expert/topic/3629/3629274.xml?temp=.3189966
      

  22.   

    思路一:
    设置item为selected,然后发送senkeys "{enter}"思路二:
    取得item的坐标,然后使用模拟鼠标的函数。     Declare Sub mouse_event Lib "user32" _
        ( _
        ByVal dwFlags As Long, _
        ByVal dx As Long, _
        ByVal dy As Long, _
        ByVal cButtons As Long, _
        ByVal dwExtraInfo As Long _
        )
     Declare Function SetCursorPos Lib "user32" (ByVal X As Long, ByVal Y As Long) As LongPublic Const MOUSEEVENTF_LEFTDOWN = &H2
    Public Const MOUSEEVENTF_LEFTUP = &H4
    Public Const MOUSEEVENTF_RIGHTDOWN = &H8
    Public Const MOUSEEVENTF_RIGHTUP = &H10Private Sub MoniMouse(ByVal iMouseX As Integer, ByVal iMouseY As Integer, ByVal iButton As Integer)
            SetCursorPos iMouseX, iMouseY
            If iButton = 1 Then'左键
                    mouse_event MOUSEEVENTF_LEFTDOWN Or MOUSEEVENTF_LEFTUP, 0, 0, 0, 0
            ElseIf iButton = 2 Then‘右键
                    mouse_event MOUSEEVENTF_RIGHTDOWN Or MOUSEEVENTF_RIGHTUP, 0, 0, 0, 0
            End If
    End Sub
    不过都有缺点,必须在前台。
      

  23.   

    无论问题有没有解决,我认为在这个过程中学习到了很多的东西,我真正地去学习api函数,真正去了解了windows控件的消息驱动机制!
    在这里感谢各位了!!
    如果你感觉分不够可以找我要就可以了,我的分还是很多的!!!