使用JNA从Win32 ListView检索项目文本

斗篷中的复仇者

我正在尝试从Win32 ListView控件(SysListView32)检索项目信息(文本就足够了)。我正在使用JNA的sendMessage()发送LVM_GETITEMTEXT。SendMessage()使用指向如下所示的LVITEM结构的指针(http://msdn.microsoft.com/zh-cn/library/windows/desktop/bb774760(v=vs.85).aspx):

typedef struct {
  UINT   mask;
  int    iItem;
  int    iSubItem;
  UINT   state;
  UINT   stateMask;
  LPTSTR pszText;
  int    cchTextMax;
  int    iImage;
  LPARAM lParam;
#if (_WIN32_IE >= 0x0300)
  int    iIndent;
#endif 
#if (_WIN32_WINNT >= 0x0501)
  int    iGroupId;
  UINT   cColumns;
  UINT   puColumns;
#endif 
#if (_WIN32_WINNT >= 0x0600)
  int    piColFmt;
  int    iGroup;
#endif 
} LVITEM, *LPLVITEM;

以下是我对LVITEM结构的Java实现:

    public static class LVITEM extends Structure {
        public WinDef.UINT mask;
        public int iItem; 
        public int iSubItem; 
        public WinDef.UINT state; 
        public WinDef.UINT stateMask; 
        public Pointer pszText;
        public int cchTextMax; 
        public int iImage; 
        public WinDef.LPARAM lParam; 
        public int iIndent; 
        public int iGoupId; 
        public WinDef.UINT cColumns; 
        public WinDef.UINT puColumns; 

        @Override
        protected List getFieldOrder() {
            return Arrays.asList(new String[] { 
"mask",  "iItem",  "iSubItem",  "state", "stateMask", "pszText", "cchTextMax",  "iImage", "lParam",  "iIndent", "iGoupId",  "cColumns", "puColumns" });
        }

        //Constructor
        public LVITEM() { 
            Memory m = new Memory(260); 
            mask = new WinDef.UINT((long)1); //code for LVIF_TEXT
            iItem = 0; 
            iSubItem = 0; //no subitem
            pszText = m.getPointer(0); 
            cchTextMax = 260; 
            iImage = 0; 
            lParam = new WinDef.LPARAM(0); 
            iIndent = 0; 
        }
    }

Java结构的大小为52个字节,应与C ++结构的大小匹配。

这是我的User32

public interface User32 extends StdCallLibrary {
            User32 INSTANCE = (User32) Native.loadLibrary("user32", User32.class, W32APIOptions.DEFAULT_OPTIONS);
...
int SendMessage (WinDef.HWND hWnd, int msg, WinDef.WPARAM wparam, LVITEM lvItem);
//Several alternative definitions
//int SendMessage (WinDef.HWND hWnd, int msg, int wparam, Pointer lvItem);
...
}

我这样声明我的结构:

LVITEM lvi = new LVITEM();
lvi.iItem = itemIdx;  // the zero-based index of the ListView item

基于其他两篇文章的建议(请参见下文),我尝试了具有不同结果的SendMessage()的不同实现。例如:

int ret = user32.SendMessage(hWnd, User32.LVM_GETITEMTEXT, 0,lvi);

该程序使ListView使第三方软件崩溃,并且不检索项目的文本。这是结构的转储(设置jna.dump_memory = true):

ListView$LVITEM([email protected] (52 bytes)) {
  WinDef$UINT [email protected]=1
  int [email protected]=0
  int [email protected]=0
  WinDef$UINT [email protected]=0
  WinDef$UINT [email protected]=0
  Pointer [email protected][email protected]
  int [email protected]=104
  int [email protected]=0
  WinDef$LPARAM [email protected]=0
  int [email protected]=0
  int [email protected]=0
  WinDef$UINT [email protected]=0
  WinDef$UINT [email protected]=0
}
memory dump
[01000000]
[00000000]
[00000000]
[00000000]
[00000000]
[38033800]
[04010000]
[00000000]
[00000000]
[00000000]
[00000000]
[00000000]
[00000000]

ret= 0

这意味着我什么也没拿回来

lvi.pszText.getString(0) =  8 8

(奇怪的符号链,此处无法很好地复制)。

例如,如果我这样做:

int ret = user32.SendMessage(hWnd, User32.LVM_GETITEMTEXT, new WPARAM(0),new LPARAM(lvi.getPointer().getLong(0)));

我得到:

ListView$LVITEM([email protected] (52 bytes)) {
  WinDef$UINT [email protected]=1
  int [email protected]=0
  int [email protected]=0
  WinDef$UINT [email protected]=0
  WinDef$UINT [email protected]=0
  Pointer [email protected][email protected]
  int [email protected]=104
  int [email protected]=0
  WinDef$LPARAM [email protected]=0
  int [email protected]=0
  int [email protected]=0
  WinDef$UINT [email protected]=0
  WinDef$UINT [email protected]=0
}
memory dump
[00000000]
[00000000]
[00000000]
[00000000]
[00000000]
[00000000]
[00000000]
[00000000]
[00000000]
[00000000]
[00000000]
[00000000]
[00000000]

(所以结构是空的?)和

ret= 0

lvi.pszText.getString(0) = 05  05  � 8

在这种情况下,具有ListView的第三方软件不会崩溃。

我已经成功地从ListView控件中检索了其他项目信息,例如count(使用LVM_GETITEMCOUNT)或选定的项目(使用LVM_GETSELECTEDCOUNT)。

我已经回顾了几个类似的线程,例如:使用JNA和SendMessage()JNA检索项目文本:将指针作为结构传递给User32.dll的SendMessage函数的LPARAM和网络上的许多其他帖子,并实现了许多建议,但问题仍然存在。

任何帮助我解决此问题的建议将不胜感激。

谢谢

斗篷中的复仇者

如果有人对此感兴趣,我可以使用它(草稿版):

    PointerByReference lngProcID;
    int lngProcHandle;
    LVITEM lvi;
    int strSize = 255;
    int result = 0;
    IntByReference byteIO = new IntByReference();
    Pointer lngVarPtr1 = null;Pointer lngMemVar1 = null;
    Pointer lngVarPtr2 = null;Pointer lngMemVar2 = null;
    Pointer lviVarPtr = null;Pointer lviVar = null;
    int lngMemLen1; int lngMemLen2;

    lngProcID = new PointerByReference();
    int ThreadId = user32.GetWindowThreadProcessId(hWnd, lngProcID);

    lngProcHandle = Kernel32.OpenProcess(Kernel32.PROCESS_VM_OPERATION | Kernel32.PROCESS_VM_WRITE | Kernel32.PROCESS_VM_READ, false, lngProcID.getValue());

    lvi = new LVITEM();
    lngMemLen1 = strSize;
    lngMemLen2 = lvi.size(); 

    lngMemVar2 = Kernel32.VirtualAllocEx(lngProcHandle, 0, lngMemLen2, Kernel32.MEM_RESERVE|Kernel32.MEM_COMMIT, Kernel32.PAGE_READWRITE);        

    lvi.cchTextMax = strSize;
    lvi.iItem = itemIdx;
    lvi.iSubItem = 0;
    lvi.mask = User32.LVIF_TEXT;
    lvi.pszText = lngMemVar1;       

    //result  = Kernel32.WriteProcessMemory(lngProcHandle, lngMemVar1, lngVarPtr1, lngMemLen1, byteswritten1);
    result = Kernel32.WriteProcessMemory(lngProcHandle, lngMemVar2, lvi, lngMemLen2, byteIO);

    result = user32.SendMessage (hWnd, User32.LVM_GETITEM, 0, lngMemVar2);

   lngVarPtr1 = new Memory(strSize + 1);
   result = Kernel32.ReadProcessMemory(lngProcHandle, lngMemVar1, lngVarPtr1, lngMemLen1, byteIO);

    result = Kernel32.VirtualFreeEx (lngProcHandle, lngMemVar1, 0, Kernel32.MEM_RELEASE);
    result = Kernel32.VirtualFreeEx (lngProcHandle, lngMemVar2, 0, Kernel32.MEM_RELEASE);        
    result = Kernel32.CloseHandle(lngProcHandle);

    return lngVarPtr1.getWideString(0);

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

针对Windows 2000的Visual Studio 2012 Win32项目

来自分类Dev

默认的Win32项目具有恒定数量的内存泄漏

来自分类Dev

使用C ++ Win32 GUI在窗口中显示文本

来自分类Dev

Win32 MessageBox切断文本

来自分类Dev

从弹出菜单中选择项目Win32 API Python

来自分类Dev

更改按钮WIN32上的文本颜色

来自分类Dev

使用Perl和Win32 :: OLE,如何将Word文档中的编号列表转换为纯文本?

来自分类Dev

使MSBuild编译具有Win32和Win64平台依赖项的项目

来自分类Dev

是否显示“公共项目对话框”或“ GetOpenFileName”?(Win32 API)

来自分类Dev

Win32虚拟ListView:无法选择整行

来自分类Dev

如何同步选择的ListView复选框?(WIN32)

来自分类Dev

Visual Studio 2005中的空项目和Win32控制台项目之间的差异

来自分类Dev

如何使用WIN32 API for C ++更改文本的颜色和大小?

来自分类Dev

使用自定义绘图在Win32 API中设置按钮文本颜色

来自分类Dev

Win32 C ++ ListView HDN_BEGINTRACK无法正常工作

来自分类Dev

win32列表视图缩写文本

来自分类Dev

C ++如何使用Win32 API通过线程从文本框中获取文本

来自分类Dev

Win32 API GetMenuItemInfo仅返回项目文本的第一个字符

来自分类Dev

Win32滚动条剪辑文本

来自分类Dev

使用Eclipse Paho MQTT编译Visual C ++ Win32项目时出现LNK2019错误

来自分类Dev

编辑Win32组合框项目

来自分类Dev

即使使用cmath include也无法在Win32 C ++项目中找到round函数

来自分类Dev

使用Win32 C ++和钩子从应用程序中的按钮获取文本

来自分类Dev

ListView不显示项目(使用翻新来检索列表)

来自分类Dev

Win32:使用cchTextMax在树形视图中设置文本长度

来自分类Dev

如何同步选择的ListView复选框?(WIN32)

来自分类Dev

在 Win32 API ListView 中添加带换行符的文本

来自分类Dev

为什么在 WIN32 项目中需要 MyRegisterClass() 函数?

来自分类Dev

如何使用来自 UWP 项目的 4 个参数启动 win32 可执行桌面

Related 相关文章

  1. 1

    针对Windows 2000的Visual Studio 2012 Win32项目

  2. 2

    默认的Win32项目具有恒定数量的内存泄漏

  3. 3

    使用C ++ Win32 GUI在窗口中显示文本

  4. 4

    Win32 MessageBox切断文本

  5. 5

    从弹出菜单中选择项目Win32 API Python

  6. 6

    更改按钮WIN32上的文本颜色

  7. 7

    使用Perl和Win32 :: OLE,如何将Word文档中的编号列表转换为纯文本?

  8. 8

    使MSBuild编译具有Win32和Win64平台依赖项的项目

  9. 9

    是否显示“公共项目对话框”或“ GetOpenFileName”?(Win32 API)

  10. 10

    Win32虚拟ListView:无法选择整行

  11. 11

    如何同步选择的ListView复选框?(WIN32)

  12. 12

    Visual Studio 2005中的空项目和Win32控制台项目之间的差异

  13. 13

    如何使用WIN32 API for C ++更改文本的颜色和大小?

  14. 14

    使用自定义绘图在Win32 API中设置按钮文本颜色

  15. 15

    Win32 C ++ ListView HDN_BEGINTRACK无法正常工作

  16. 16

    win32列表视图缩写文本

  17. 17

    C ++如何使用Win32 API通过线程从文本框中获取文本

  18. 18

    Win32 API GetMenuItemInfo仅返回项目文本的第一个字符

  19. 19

    Win32滚动条剪辑文本

  20. 20

    使用Eclipse Paho MQTT编译Visual C ++ Win32项目时出现LNK2019错误

  21. 21

    编辑Win32组合框项目

  22. 22

    即使使用cmath include也无法在Win32 C ++项目中找到round函数

  23. 23

    使用Win32 C ++和钩子从应用程序中的按钮获取文本

  24. 24

    ListView不显示项目(使用翻新来检索列表)

  25. 25

    Win32:使用cchTextMax在树形视图中设置文本长度

  26. 26

    如何同步选择的ListView复选框?(WIN32)

  27. 27

    在 Win32 API ListView 中添加带换行符的文本

  28. 28

    为什么在 WIN32 项目中需要 MyRegisterClass() 函数?

  29. 29

    如何使用来自 UWP 项目的 4 个参数启动 win32 可执行桌面

热门标签

归档