简体   繁体   中英

JNA ClientToScreen?

Having issues figuring out how to use the ClientToScreen winapi function with JNA.

I'm still getting 0, 0 output for the coordinates of the window handle. Am referencing this but im sure im not doing it right https://msdn.microsoft.com/en-us/library/windows/desktop/dd183434(v=vs.85).aspx

    public interface User32Ex extends W32APIOptions {
    User32Ex instance = (User32Ex) Native.loadLibrary("user32", User32Ex.class, DEFAULT_OPTIONS);
    boolean GetCursorPos(long[] lpPoint);
    WinDef.HWND WindowFromPoint(long point);
    boolean GetClientRect(WinDef.HWND hWnd, WinDef.RECT rect);
    boolean ClientToScreen(WinDef.HWND hWnd, int pt);
}



public void debug() throws InterruptedException {
    while (true) {
        long[] getPos = new long[1];
        User32Ex.instance.GetCursorPos(getPos);
        WinDef.HWND hwnd = User32Ex.instance.WindowFromPoint(getPos[0]);

        WinDef.RECT rect = new WinDef.RECT();
        User32Ex.instance.GetClientRect(hwnd, rect);
        User32Ex.instance.ClientToScreen(hwnd, rect.left);
        User32Ex.instance.ClientToScreen(hwnd, rect.right);

        System.out.println(rect.toRectangle().toString());
        Thread.sleep(1500);
    }
}

@technomage is right. You need to use WinDef.POINT instead of int in your ClientToScreen() rect parameter.

If anyone looking for a working solution for the question, it's below. In every 3rd sec, it's logging the window inner client coordinates desktop position.

Explanation.

In the User32ForClientRect interface, we load user32.dll with JNA and define a few methods. The reason behind we not using the already implemented User32 methods from the JNA interface is simple. The methods that we need in our case are not implemented in JNA.

Methods:

  • FindWindow - it's included in JNA

    Retreives the window handle HWND


  • GetClientRect

    Retreives the window widht, height. to rect.right, rect.bottom


  • ClientToScreen

    Retreives the window inner client desktop position. Left/Top corner coordinates


Example:

package application.playground;

import com.sun.jna.Native;
import com.sun.jna.platform.win32.WinDef;
import com.sun.jna.win32.StdCallLibrary;
import com.sun.jna.win32.W32APIOptions;

import java.awt.*;

public class ClientRectExample {
    interface User32ForClientRect extends StdCallLibrary {
        User32ForClientRect INSTANCE = Native.loadLibrary("user32", User32ForClientRect.class,
                W32APIOptions.DEFAULT_OPTIONS);
        WinDef.HWND FindWindow(String lpClassName, String lpWindowName);
        boolean GetClientRect(WinDef.HWND hWnd, WinDef.RECT rect);
        boolean ClientToScreen(WinDef.HWND hWnd, WinDef.POINT lpPoint);
    }

    public static void main(String[] args) {
        while (true) {
            try {
                Rectangle rectangle = ClientRectExample.getClientRect("WindowName");
                System.out.println(rectangle);
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public static Rectangle getClientRect(String startOfWindowName) {
        WinDef.HWND hWnd = User32ForClientRect.INSTANCE.FindWindow(null, startOfWindowName);
        WinDef.POINT getPos = new WinDef.POINT();
        WinDef.RECT rect = new WinDef.RECT();
        User32ForClientRect.INSTANCE.GetClientRect(hWnd, rect);
        User32ForClientRect.INSTANCE.ClientToScreen(hWnd, getPos);

        return new Rectangle(getPos.x, getPos.y, rect.right, rect.bottom);
    }
}

您需要将LPPOINT传递给ClientToScreen() ,而不是int ,或者更具体地说是一个指向POINT结构的指针(JNA 中的WinDef.POINT )。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM