本文介绍了在JNA中创建本机Windows窗口,并使用GWL_WNDPROC创建一些GetWindowLong的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

美好的一天,

我一直在使用JNA与Windows API进行交互,现在在创建窗口时遇到了麻烦.据我已经做到以下几点:1.已创建现有窗口的子窗口,并为其获取了有效的处理程序.2.理解Windows中的每个窗口都有一个不间断的消息调度循环.3.理解将窗口包含在message-dispatch循环中的最佳方法是使用类似于以下代码的代码(不是我的,但这也是我要做的):

I have been using JNA for a while to interact with the Windows API and now I am stuck when creating a window. As far as I have done the following:1. Have created a child window of an existing window and obtained a valid handler to it.2. Understood that every window in Windows has a non-stop message-dispatch loop.3. Understood that the best way to include my window in the message-dispatch loop is to use something like the following code (not mine, but that is what I would do as well):

final LONG_PTR prevWndProc = new LONG_PTR(User32.INSTANCE.GetWindowLong(hwnd, User32.GWL_WNDPROC));       //this is to obtain a pointer to the WNDPROC of the parent window, which we are going to need later
  wndProcCallbackListener = new WndProcCallbackListener()
   {
      public LRESULT callback(HWND hWnd, int uMsg, WPARAM uParam, LPARAM lParam)
      {
         if (uMsg == WTSAPI.WM_POWERBROADCAST)
         {
           System.out.println("WM_POWERBROADCAST Event: hWnd="+hwnd+", uMsg="+uMsg+", uParam="+uParam+", lParam="+lParam);
         }
         else if (uMsg == WTSAPI.WTS_SESSION_CHANGE)
         {
           System.out.println("WTS_SESSION_CHANGE Event: hWnd="+hwnd+", uMsg="+uMsg+", uParam="+uParam+", lParam="+lParam);
         }

        //Call the window's actual WndProc so the events get processed.
        return User32.INSTANCE.CallWindowProc(prevWndProc, hWnd, uMsg, uParam, lParam);
      }
   };
      //Set the WndProc function to use our callback listener instead of the window's one. 
   int result = User32.INSTANCE.SetWindowLong(hwnd, User32.GWL_WNDPROC, wndProcCallbackListener);

但是,我的问题是当我为父窗口(我的第一行代码)调用GetWindowLong()时,指针的值为0,表示该函数未成功完成.随后调用GetLastError()并快速检查错误代码给了我'拒绝访问'错误.当然,这是合乎逻辑的,因为我正在尝试从自己的线程访问另一个WNDPROC的地址,但是我想知道是否有任何方法(当然应该)规避该问题.

However, my problem is when I call the GetWindowLong() for the parent window (my first line of code) I get a 0 for the pointer which indicated the function did not complete successfully. A subsequent call to GetLastError() and a quick check in the error codes give me an 'Access is denied' error. This, of course, is logical, since I am trying from my own thread to access the address of the WNDPROC of another, but I was wondering if there is any way (there should be, of course) to circumvent that.

有指针吗? (双关语意味)

Any pointers? (pun intended)

推荐答案

在JNA调用之后,请勿使用GetLastError(). JNA& JNI可能会调用其他可能更改上一个错误的API.用子句声明SetWindowLong会引发LastErrorException,如下所示:

Do not use GetLastError() after a JNA call. JNA & JNI may call other APIs that may change the last error. Declare SetWindowLong with the clause throws LastErrorException, like this:

int SetWindowLongA(int hWnd, int nIndex, WndProcCallbackListener dwNewLong)
    throws LastErrorException;

在名称后注意"A".它明确使用了ANSI版本.您也可以使用SetWindowLongW.

Notice the 'A' after the name. It makes explicit use of ANSI version. You could use SetWindowLongW as well.

确保您的回调同时实现Callback和StdCall.我更喜欢尽可能地使用原始类型,因为这使得映射对于JNA而言快速且显而易见:

Make sure your callback implements both Callback and StdCall. I prefer using primitive types as much as possible, because this makes mapping fast and obvious to JNA:

public interface WndProcCallbackListener extends Callback, StdCall {

    int callback(int hWnd, int Msg, int wParam, int lParam);

}

这篇关于在JNA中创建本机Windows窗口,并使用GWL_WNDPROC创建一些GetWindowLong的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-16 20:14