Я могу сделать снимок экрана с изображением переднего плана, используя приведенный ниже код.
void startScreencapture(){
RECT dimensionsOfWindow = new RECT();
User32.INSTANCE.GetWindowRect(User32.INSTANCE.GetForegroundWindow(), dimensionsOfWindow );//now in the dimensionsOfWindow you have the dimensions
Robot robot = new Robot();
buf = robot.createScreenCapture( dimensionsOfWindow.toRectangle() );
}
public interface User32 extends StdCallLibrary {
User32 INSTANCE = (User32) Native.loadLibrary("user32", User32.class);
HWND GetForegroundWindow(); // add this
int GetWindowTextA(PointerType hWnd, byte[] lpString, int nMaxCount);
public boolean GetWindowRect(HWND hWnd, RECT rect);
}
Я получаю скриншоты переднего плана, как показано ниже

Если вы заметили, на скриншоте есть дополнительное изображение на границе окна.
Мне не нужна дополнительная часть изображения с моим скриншотом.
Можно ли как-то манипулировать
User32.INSTANCE.GetForegroundWindow()
чтобы я получил скриншот без лишней части?
Я чувствую, что ответ в этой ссылке должен работать. В чем разница между GetClientRect и GetWindowRect в WinApi?
Но когда я заменяю GetWindowRect на GetClientRect, я получаю скриншот ниже:

В идеале я должен был получить скриншот только приложения переднего плана.
Редактировать: Даниэль Виддис любезно нашел для меня похожий вопрос: getwindowrect-возвращает-размер-включая-невидимые-границы
У этого есть возможный ответ, т. Е. Получите толщину границы в Windows 10 и отрегулируйте эту толщину, чтобы получить снимок экрана, который я хочу. Но этот ответ использует
DwmGetWindowAttribute(hwnd, DWMWA_EXTENDED_FRAME_BOUNDS, &frame, sizeof(RECT)); который, возможно, является кодом C.
Если я смогу найти, как найти толщину границы в Java, это решит мою проблему.
Вся цель JNA — сделать C-код доступным! :) Если функция еще не встроена в JNA, вы можете добавить интерфейс для ее объявления.




The client coordinates specify the upper-left and lower-right corners of the client area. Because client coordinates are relative to the upper-left corner of a window's client area, the coordinates of the upper-left corner are (0,0).
Это относительная система координат.
Вы также должны вызвать КлиентТоЭкран, чтобы преобразовать координату клиента в координату экрана.
Обратите внимание, что ClientToScreen получает только параметр POINT (не RECT), и вы можете найти класс POINTздесь.
Обновлено:
GetWindowRect получит «дополнительный» размер. Однако GetClientRect точно не включает его (и другую дополнительную информацию, такую как строка заголовка, граница окна и т. д.).
Это не отвечает на вопрос пользователя, как избавиться от (прозрачной) границы.
Я пробовал с ClientToScreen, но для этого требуется int POINT. Я попытался передать его RECT.LEFT и RECT.RIGHT. Но результаты были такими же.
@Daniel Widdis, GetClientRect точно не включает (невидимые) границы и строку заголовка, границу окна и т. д.
@Promod, вам нужны новые 2 POINTs: {слева, сверху} и {справа, снизу}, чтобы перейти от координат клиента к координатам экрана. но не только прохождение int. Кстати, Двмжетвиндоватрибуте, о котором вы говорили, является win32api.
@DrakeWu-MSFT Пробовал, как вы упомянули, но все равно не работает. пример кода: User32.INSTANCE.ClientToScreen(hwnd, dimensionsOfWindow.left); User32.INSTANCE.ClientToScreen(hwnd, dimensionsOfWindow.right); User32.INSTANCE.ClientToScreen(hwnd, dimensionsOfWindow.top); User32.INSTANCE.ClientToScreen(hwnd, dimensionsOfWindow.bottom);
Нет, вы должны POINT pt1 = new Point (RECT.LEFT, RECT.TOP);, а затем User32.INSTANCE.ClientToScreen(hwnd, pt1); то же, что и pt2 (ПРЯМО.ПРАВО, ПРЯМО.НИЗ). Наконец, сбросьте значение RECT dimensionsOfWindow в соответствии с POINT.
Это сделало это. Я благодарю вас за ваше время и смирение за ответ на мой вопрос.
@DrakeWu-MSFT спасибо за разъяснения. Я думаю, что, должно быть, пропустил различие между клиентом и окном при первом чтении.
Спасибо @DrakeWu-MSFT. Но использование DwmGetWindowAttribute не решило мою проблему. Используя ClientToScreen, как вы предложили. Не могли бы вы добавить это в ответ. Я не нашел ответа, в котором упоминалось бы, как использовать POINT в своих ответах. В принципе, я не смог использовать DwmGetWindowAttribute .
@Promod Вы тестировали образец в этом связь? используя класс ТОЧКА в com.sun.jna.platform.win32.WinDef.POINT
@DrakeWu-MSFT Да. Я использовал то же самое в своем коде, и это сработало.
@Promod изменил это. А у вас не получается получить функцию DwmGetWindowAttribute или она не работает?
@DrakeWu-MSFT Я могу получить эту функцию. Я попытался создать для него абстрактный метод в интерфейсе, но не мог придумать, какой параметр я должен передать, например DwmGetWindowAttribute(hwnd, DWMWA_EXTENDED_FRAME_BOUNDS, &frame, sizeof(RECT)); Что я должен передать вместо DWMWA_EXTENDED_FRAME_BOUNDS и `sizeof(RECT)` в Java?
@Promod DWMWA_EXTENDED_FRAME_BOUNDS = 9 и sizeof(RECT) = 16, Вы можете попробовать пройти 9 и 16 напрямую.
@DrakeWu-MSFT хорошо. Спасибо за помощь. Мой текущий код работает, поэтому я не буду его трогать. Но это весьма полезно для людей с такими же проблемами.
Возможный дубликат GetWindowRect возвращает размер, включая «невидимые» границы