• 外部sysListView32内容获取及设置选中状态


    public void SetLisSelected(IntPtr listView,List<string> fcusers)
            {
                //该listview总行数
                int rowcnt = API.SendMessage(listView, API.LVM_GETITEMCOUNT, 0, 0);

                //listview的列头句柄
                int lvHeader = API.SendMessage(listView, API.LVM_GETHEADER, 0, 0);

                uint hProcessId = 0; //列头的processid
                API.GetWindowThreadProcessId((IntPtr)lvHeader, out hProcessId);    //lvHeader是SysListView的子窗SysHeader32的句柄,lvParent是SysListView的句柄
                IntPtr hProcess = API.OpenProcess(API.PROCESS_VM_OPERATION | API.PROCESS_VM_READ | API.PROCESS_VM_WRITE, false, hProcessId);
                IntPtr hPointer = API.VirtualAllocEx(hProcess, IntPtr.Zero, 4096, API.MEM_RESERVE | API.MEM_COMMIT, API.PAGE_READWRITE);
               
                uint processId; //进程pid 
                API.GetWindowThreadProcessId(listView, out processId);

                //获取Listview的process句柄
                IntPtr process = API.OpenProcess(API.PROCESS_VM_OPERATION | API.PROCESS_VM_READ | API.PROCESS_VM_WRITE, false, processId);
                //申请代码的内存区,返回申请到的虚拟内存首地址
                IntPtr pointer = API.VirtualAllocEx(process, IntPtr.Zero, 4096, API.MEM_RESERVE | API.MEM_COMMIT, API.PAGE_READWRITE);

                //取出每行第一列,判断是否满足条件
                for (int i = 0; i < rowcnt; i++)
                {
                    //如果要返回ListView所有内容,这里加上加上 for (int j = 0; j < cols; j++) 并将下面的 vItem[0].iSubItem = 0 改为=j;
                    byte[] vBuffer = new byte[256];//定义一个临时缓冲区
                    API.LVITEM[] vItem = new API.LVITEM[1];
                    vItem[0].mask = API.LVIF_TEXT;//说明pszText是有效的
                    vItem[0].iItem = i;     //行号
                    vItem[0].iSubItem = 0;  //列号
                    vItem[0].cchTextMax = vBuffer.Length;//所能存储的最大的文本为256字节
                    vItem[0].pszText = (IntPtr)((int)pointer + Marshal.SizeOf(typeof(API.LVITEM)));
                    uint vNumberOfBytesRead = 0;

                    //把数据写到vItem中
                    //pointer为申请到的内存的首地址
                    //UnsafeAddrOfPinnedArrayElement:获取指定数组中指定索引处的元素的地址
                    API.WriteProcessMemory(process, pointer, Marshal.UnsafeAddrOfPinnedArrayElement(vItem, 0), Marshal.SizeOf(typeof(API.LVITEM)), ref vNumberOfBytesRead);

                    //发送LVM_GETITEMW消息给hwnd,将返回的结果写入pointer指向的内存空间
                    API.SendMessage(listView, API.LVM_GETITEMW, i, (int)pointer);

                    //从pointer指向的内存地址开始读取数据,写入缓冲区vBuffer中
                    API.ReadProcessMemory(process, (IntPtr)((int)pointer + Marshal.SizeOf(typeof(API.LVITEM))), Marshal.UnsafeAddrOfPinnedArrayElement(vBuffer, 0), vBuffer.Length, ref vNumberOfBytesRead);

                    //string vText = Encoding.Unicode.GetString(vBuffer, 0, (int)vNumberOfBytesRead); //此方法获取的内容是乱码                   
                    string vText = Marshal.PtrToStringUni(Marshal.UnsafeAddrOfPinnedArrayElement(vBuffer, 0)); //不能用Marshal.PtrToStringAnsi等其他方法,否则内容是乱码

                    string userName = vText;

                    if (fcusers.Any(c=>c==userName)) //第一列内容在目标列表中,选中该行
                    {
                        int iItem = i; //行号
                        vItem[0].state = API.LVIS_SELECTED;
                        vItem[0].stateMask = API.LVIS_SELECTED;      

                        uint vNumberOfBytesRead0 = 0;
                        API.WriteProcessMemory(hProcess, hPointer, Marshal.UnsafeAddrOfPinnedArrayElement(vItem, 0), Marshal.SizeOf(typeof(API.LVITEM)), ref vNumberOfBytesRead0);
                        API.SendMessage(listView, (uint)API.LVM_SETITEMSTATE, iItem, hPointer.ToInt32());//此处发送消息使得该item被选中
                        //System.Threading.Thread.Sleep(100);
                    }
                }

                API.VirtualFreeEx(hProcess, hPointer, 0, API.MEM_RELEASE);
                API.CloseHandle(hProcess);

                API.VirtualFreeEx(process, pointer, 0, API.MEM_RELEASE);//在其它进程中释放申请的虚拟内存空间,MEM_RELEASE方式很彻底,完全回收
                API.CloseHandle(process);//关闭打开的进程对象
            }

  • 相关阅读:
    【CI】系列一:总体环境规划
    【原】Ubuntu下使用teamviewer
    [Android] android:visibility属性应用
    Android 软键盘
    android EditText inputType 及 android:imeOptions=”actionDone”
    【Android】The application has stopped unexpectedly.Please try again.
    【IntelliJ IDEA 12使用】导入外部包
    [转载]Android开发者必须深入学习的10个应用开源项目
    【android相关】【问题解决】R.java文件丢失
    1月1日起,我市交通事故快速理赔上限提高至1万元!
  • 原文地址:https://www.cnblogs.com/mol1995/p/12270175.html
Copyright © 2020-2023  润新知