es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

¿Cómo puedo obtener el identificador de ventana “nativo” en Java para pasarlo a través de JNI a una DLL escrita en C++?

Tengo que forzar una aplicación existente de JavaFX para que esté siempre en segundo plano, pero no pude encontrar esa funcionalidad de manera nativa en JavaFX (solo existe siempre en primer plano), por lo tanto, pensé en usar la API de Win32 desde una DLL JNI externa para llamar a la función SetWindowPos().

Pude vincular Java con C++, pero no sé cómo obtener el identificador de ventana (HWND) necesario para la función desde el entorno Java.

Mi llamada de ejemplo (desde la DLL):

#define X0 0
#define Y0 0
#define W 1920
#define H 1080
#define FLAGS 0
#define ALWAYS_ON_BOTTOM HWND_BOTTOM
#define I_DONT_KNOW_WHAT nullptr

JNIEXPORT void JNICALL Java_libreria_WindowsHandlerWrapper_SetAlwaysOnBottom
(JNIEnv* env, jobject obj) {

    HWND hWnd = I_DONT_KNOW_WHAT; /* aquí es donde necesito ayuda */

    SetWindowPos(
        hWnd,
        ALWAYS_ON_BOTTOM,
        X0,
        Y0,
        W,
        H,
        FLAGS
    );
}

Lo que no sé es cómo obtener el identificador hWnd.

Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    Para obtener el identificador nativo de ventana (hWnd), se puede utilizar el método getWindow() de un objeto Stage en JavaFX.

    Así es como se puede modificar el método JNIEXPORT para obtener el hWnd:

    “`c++
    JNIEXPORT void JNICALL Java_libreria_WindowsHandlerWrapper_SetAlwaysOnBottom
    (JNIEnv* env, jobject obj, jlong stagePtr) {

        // Convertir el puntero de la etapa en un objeto etapa
        jclass stageClass = env->GetObjectClass(obj);
        jfieldID stageField = env->GetFieldID(stageClass, "stagePtr", "J");
        jlong ptr = env->GetLongField(obj, stageField);
        Stage* stage = reinterpret_cast<stage*>(ptr);
    
        // Obtener el identificador de ventana nativo (hWnd)
        HWND hWnd = static_cast<hwnd>(stage->getWindow()->impl_getNativeWindow());
    
        // Llamar a SetWindowPos() con HWND_BOTTOM
        SetWindowPos(
            hWnd,
            HWND_BOTTOM,
            0,
            0,
            0,
            0,
            SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE
        );
    }
    

    “`

    En este ejemplo, se supone que hay un campo jlong llamado stagePtr en la clase libreria.WindowsHandlerWrapper. Este campo contiene el puntero al objeto Stage que se necesita crear y se pasa como argumento al método JNIEXPORT.

    Luego, el puntero se convierte en un objeto Stage, y se utiliza el método getWindow() para obtener el objeto Window. El método impl_getNativeWindow() del objeto Window devuelve el identificador nativo de ventana (HWND).

    Por último, se llama a SetWindowPos() con HWND_BOTTOM para que la ventana siempre permanezca en segundo plano. Se utilizan las banderas SWP_NOMOVE, SWP_NOSIZE y SWP_NOACTIVATE para evitar que la ventana se mueva o cambie de tamaño, y para evitar que se active (es decir, que se traiga al primer plano) al hacer clic en ella.</stage*>

Comments are closed.