【问题标题】:Using JNA for accessing tooltip from windows使用 JNA 从 Windows 访问工具提示
【发布时间】:2013-09-01 10:23:36
【问题描述】:

我开始尝试使用 JNA 从 Windows 访问每个工具提示。为此,我将 TTM_GETTOOLINFO 消息连续发送到窗口。下面是我的代码...

public class Test {

     public interface User32 extends StdCallLibrary {
     User32 INSTANCE = (User32) Native.loadLibrary("user32", User32.class);
     HWND GetForegroundWindow();  // add this
     int SendMessageA(HWND hwnd, int msg, int num1, TOOLINFO f );
    // int SendMessageW(HWND hwnd, int msg, int num1, TOOLINFO f );
   }


    public class TOOLINFO extends Structure
    {
        public int      cbSize;
        public int      uFlags;
        public HWND      hwnd;
        public UINT_PTR  uId;
        public RECT      rect;
        public HINSTANCE hinst;
        public char []    lpszText;

        TOOLINFO()
        {
            lpszText = new char[512];
        }
    }

    public static void main(String[] args)
    {
        new Test().go();
    }

    public void go()
    {
        TOOLINFO tt = new TOOLINFO();
        int WM_USER = 0x0400;
        HWND hwnd ;
        int i=0;
        while(true)
        {
            hwnd= User32.INSTANCE.GetForegroundWindow();
            try
            {
                i=User32.INSTANCE.SendMessageA(hwnd,WM_USER+8, 0, tt);
            }
            catch(Exception ex)
            {
               ex.printStackTrace();
            }
        if(i!=0)
            System.out.println("Tooltip :"+tt.lpszText);
                }
    }
}

但它不起作用。我正在使用窗口 8。我在网上找到了 commctrl.h 的两个版本。一个显示 TTM_GETTOOLINFOA= WM_USER+8 TTM_GETTOOLINFOW= WM_USER+53,另一个显示 TTM_GETTOOLINFOA= WM_USER+9 TTM_GETTOOLINFOW= WM_USER+54。但是,我尝试了 SendMessageA 和 W 的每种组合。所以我认为存在一些基本错误。所以任何人都可以帮助我。从 JNA 访问工具提示。

public class JnaTest2 {

      public interface User32 extends StdCallLibrary {
      User32 INSTANCE = (User32) Native.loadLibrary("user32", User32.class);
      HWND GetForegroundWindow();  // add this
      int SendMessageW(HWND hwnd,int msg ,WPARAM w,TOOLINFOW lparam);
  }
    public class TOOLINFOW extends Structure
    {
        public int      cbSize;
        public int      uFlags;
        public HWND      hwnd;
        public UINT_PTR  uId;
        public RECT      rect;
        public HINSTANCE hinst;
        public Pointer pszText = new Memory(512);
        LPARAM l;
        Pointer lpReserved=null;
    }
public static void main(String[] args)
{

    new JnaTest2().go();
}
public void go()
{
    int WM_USER = 0x0400;
    TOOLINFOW tt = new TOOLINFOW();
    tt.cbSize=tt.size();
    System.out.println(tt.size());
    HWND hwnd ;
    int j=0;
    while(true)
    {
        hwnd=User32.INSTANCE.GetForegroundWindow();
        tt.hwnd=hwnd;
        try
        {
            j=User32.INSTANCE.SendMessageW(hwnd,WM_USER+53,new WPARAM(0),tt);
        }
        catch(Exception ex)
        {
           ex.printStackTrace();
        }
        if(j!=0)
            System.out.println("Tooltip :"+tt.pszText.getString(0));

    }
}

}

【问题讨论】:

  • 在我的电脑上我搜索了 Commctrl.h,发现 TTM_GETTOOLINFOA= WM_USER+8 和 TTM_GETTOOLINFOW= WM_USER+53。 9 和 54 用于 TTM_SETTOOLINFO。这就是我在上面的代码中使用 8 的原因。
  • 任何人请...一些方向将节省我的一周...
  • 您需要不同的TOOLINFO 定义,具体取决于您使用的是-A 还是-Wbyte[] 用于 ascii,char[] 用于 unicode)。
  • 我不知道正常使用应该是什么样子,但是你不需要初始化TOOLINFO中的数据吗?
  • 感谢您的回复。正如我所说,我已经尝试过每种组合......使用字节数组也是其中的一部分。你说的初始化是什么意思……!!我正在初始化 char 数组,我认为我不必初始化其他公共成员。因为我是 JNA 的新手,所以我对我的代码的整个模式感到非常困惑,所以你真的认为实际的错误在于那部分,我的意思是初始化或其他什么......!和其他部分的代码是对的...?

标签: java winapi tooltip jna


【解决方案1】:
  • 使用TTM_GETTOOLINFOW
  • 使用SendMessageW
  • 初始化TOOLINFOhWndcbSize 字段。 lpszText 必须是指针类型,而不是内联数组。您可以使用Memory,字段类型为Pointer。确保它足够大。
  • 您缺少lParam(输入LPARAM)和lpReserved(输入Pointer)字段。

编辑您的问题以显示您如何实现这些内容以及相应的结果。

编辑

检查Native.getLastError() 以查看方法调用是否导致错误。它不会抛出异常。

【讨论】:

  • 请查看已编辑的问题。我不确定你的第四点。在 jna 的一些帖子上,我读到我可以在方法签名中直接使用我的结构名称。所以不使用 LPARAM 和 MSDN 说 lpReserved 应该始终为空。但是代码仍然无法正常工作,甚至没有给出任何异常。
  • 我也尝试过使用 SendMessageA TOOLINFOA TTM_GETTOOLINFOA ...只是不知道我错在哪里。没有任何异常或错误,我完全没有希望。只是一遍又一遍地看我的代码。还尝试使用不同的内存大小更改分配内存的大小。
  • 最后两个参数需要为public。您确定SencMessage 调用和结构应该使用相同的hwnd 值吗?
  • 使用 Pointer.getWideString(0) 提取本机字符串,因为您使用的是 unicode 版本。
  • 是的,我认为...link 它是拥有工具提示控件的所有者窗口的句柄。我们必须在 sendMessage() 和 TOOLINFO 结构 link 中使用它。当鼠标指针不在工具上时,native.getLastError() 给出 0。当我将鼠标指针移动到任何工具提示控件时,它会给出 1400。我在 MSDN 上发现 1400 错误代码表示“无效的窗口句柄”,但我给出了正确的窗口句柄。有什么建议吗?
猜你喜欢
  • 1970-01-01
  • 2011-01-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-06-27
  • 2023-01-26
  • 1970-01-01
相关资源
最近更新 更多