Почему пользовательская процедура окна прекращает обработку оконных сообщений? - PullRequest
3 голосов
/ 19 июня 2020

Я пытаюсь настроить пользовательскую оконную процедуру, и она работает. Однако через некоторое время окно перестает реагировать на любой ввод. Кажется, что чем больше выполняется рендеринг в сцене, тем быстрее окно будет разбито.

Это даже происходит, если моя настраиваемая оконная процедура просто вызывает окно по умолчанию.

Reproducer:

package com.example;

import com.sun.jna.Native;
import com.sun.jna.Pointer;
import com.sun.jna.platform.win32.BaseTSD;
import com.sun.jna.platform.win32.User32;
import com.sun.jna.platform.win32.WinDef.HWND;
import com.sun.jna.platform.win32.WinUser;
import com.sun.jna.win32.W32APIOptions;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.ProgressIndicator;
import javafx.stage.Stage;

import static com.sun.jna.platform.win32.WinUser.GWL_WNDPROC;

public class CustomWndProc {

  public static void main(String[] args) {
    CustomFrameApplication.launch(CustomFrameApplication.class, args);
  }

  public static class CustomFrameApplication extends Application {

    @Override
    public void start(Stage primaryStage) {
      primaryStage.setScene(new Scene(new ProgressIndicator(ProgressIndicator.INDETERMINATE_PROGRESS)));
      primaryStage.show();

      HWND hwnd = new HWND();
      hwnd.setPointer(User32.INSTANCE.GetActiveWindow().getPointer());

      BaseTSD.LONG_PTR defaultWindowProc = User32.INSTANCE.GetWindowLongPtr(hwnd, GWL_WNDPROC);

      WinUser.WindowProc windowProc = (hwnd1, uMsg, wParam, lParam) ->
        User32Ex.INSTANCE.CallWindowProc(defaultWindowProc, hwnd1, uMsg, wParam, lParam);

      User32Ex.INSTANCE.SetWindowLongPtr(hwnd, GWL_WNDPROC, windowProc);
    }
  }

  public interface User32Ex extends User32 {
    User32Ex INSTANCE = Native.load("user32", User32Ex.class, W32APIOptions.DEFAULT_OPTIONS);

    Pointer SetWindowLongPtr(HWND hWnd, int nIndex, WindowProc wndProc);

    LRESULT CallWindowProc(LONG_PTR proc, HWND hWnd, int uMsg, WPARAM uParam, LPARAM lParam);
  }
}

Дайте ему несколько секунд или минут, и вы больше не сможете перемещать, минимизировать, разворачивать или закрывать окно.

Если вы хотите гарантированное замораживание, используйте WebView вместо a ProgressIndicator:

      WebView webView = new WebView();
      webView.getEngine().load("https://www.google.com");
      primaryStage.setScene(new Scene(webView));

Мне было интересно, есть ли у него что-то делать, чтобы мой код запускался в потоке приложения JavaFX (что приводит к некоторому состоянию гонки), но я предполагаю, что то же самое происходит с оконной процедурой по умолчанию (как можно Подтверждаю?).

Я пытаюсь создать приложение JavaFX, которое использует настраиваемый фрейм .

Используя JNA 5.5.0.

1 Ответ

1 голос
/ 25 июня 2020

Я думаю, что это правильный способ, но, возможно, я ошибаюсь .. Я получил информацию от: Почему мое приложение, использующее JNA, не реагирует правильным образом?

import com.sun.jna.LastErrorException;
import com.sun.jna.Native;
import com.sun.jna.platform.win32.BaseTSD;
import com.sun.jna.platform.win32.User32;
import com.sun.jna.platform.win32.WinDef;
import com.sun.jna.platform.win32.WinDef.HWND;
import com.sun.jna.win32.W32APIOptions;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.ProgressIndicator;
import javafx.stage.Stage;


public class CustomWndProc {

    public static void main(String[] args) {
        CustomFrameApplication.launch(CustomFrameApplication.class, args);
    }

    public static class CustomFrameApplication extends Application {

        private BaseTSD.LONG_PTR baseWndProc;

        public User32Ex.WNDPROC listener = new User32Ex.WNDPROC() {
            public WinDef.LRESULT callback(HWND hWnd, int uMsg, WinDef.WPARAM uParam,
                    WinDef.LPARAM lParam) {
                // TODO handle the window message
                // calling the base WndProc
                return User32Ex.INSTANCE.CallWindowProc(baseWndProc, hWnd, uMsg, uParam, lParam);
            }
        };

        @Override
        public void start(Stage primaryStage) {
            primaryStage.setScene(new Scene(new ProgressIndicator(ProgressIndicator.INDETERMINATE_PROGRESS)));
            primaryStage.show();

            HWND hwnd = new HWND();
            hwnd.setPointer(User32.INSTANCE.GetActiveWindow().getPointer());

            this.baseWndProc = User32Ex.INSTANCE.GetWindowLongPtr(hwnd, User32Ex.GWL_WNDPROC);

            User32Ex.INSTANCE.SetWindowLongPtr(hwnd, User32Ex.GWL_WNDPROC, this.listener);
        }
    }

    public interface User32Ex extends User32 {

        User32Ex INSTANCE = Native.load("user32", User32Ex.class, W32APIOptions.DEFAULT_OPTIONS);

        interface WNDPROC extends StdCallCallback {

            LRESULT callback(HWND hWnd, int uMsg, WPARAM uParam, LPARAM lParam);
        }

        LONG_PTR GetWindowLongPtr(HWND hWnd, int nIndex) throws LastErrorException;

        LRESULT CallWindowProc(LONG_PTR proc, HWND hWnd, int uMsg, WPARAM uParam, WinDef.LPARAM lParam) throws LastErrorException;

        LONG_PTR SetWindowLongPtr(HWND hWnd, int nIndex, WNDPROC wndProc) throws LastErrorException;
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...