Winapi-ShutdownBlockReasonCreate / Destroy JNI本机代码的实现中的SetWindowLongPtr

问题描述 投票:0回答:1

我目前正在使用SWT进行涉及Eclipse RCP的Java项目,并试图通过在保存时向Windows环境中的用户提供有意义的消息来处理正常关闭。我应该使用ShutdownBlockReasonCreateShutdownBLockReasonDestroy API来实现此目的,但是经过一番研究,我不得不用我刚接触的C ++本机代码来实现它们。由于它们在JNA中不可用,因此Eclipse SWT不提供这种功能(不希望知道)。

经过所有的努力,我能够整理一个有效的C ++代码(如下所示)以控制SWT窗口(通过引用另一种实现https://github.com/seraphy/JavaGracefulShutdownForWin7)。但是,我偶然发现了与WindowProc CALLBACK有关的问题。这些语法来自Java背景,花了我一段时间才能理解。但是我有点理解它正在尝试做的事情。因为这是我们需要处理WM_QUERYENDSESSION和WM_ENDSESSION消息的地方。

但是在开始之前,我想在这篇文章中讨论的问题与Windows API SetWindowLongPtr

特别相关,正如您在Java_com_app_project_winapi_WindowsAPI_shutdownBlockReasonCreate(JNIEnv *env, jclass cls, jstring title)函数中看到的那样。如您所见,我将其注释掉了,仅仅是因为在ShutdownBlockReasonCreate(hWnd, SHUTDOWN_REASON)之后调用此方法时,我的窗口的行为非常奇怪。例如,>
  • “文件”选项,当单击时,不再显示菜单;
  • 调整窗口大小时,当您尝试调整大小
  • 关闭窗口时,基础进程仍在运行
  • 是,我需要使用此方法来激活用于接收OS消息的窗口的控件,但是随后它开始与已经构建的Eclipse SWT窗口混淆。有谁知道我是否正确地完成了整个工作?还是我偏离了轨道? SetWindowLongPtr到底能做什么?我找不到任何好的参考资料,也无法从阅读Microsoft文档中受益匪浅。

提前感谢!

#include <jni.h>

#include <iostream>
#include "com_app_project_winapi_WindowsAPI.h"
#include <windows.h>

using namespace std;

namespace {

    LPCWSTR SHUTDOWN_REASON = L"Application is still saving ...";

    LRESULT CALLBACK AppWndProc(
        _In_ HWND hWnd,
        _In_ UINT message,
        _In_ WPARAM wParam,
        _In_ LPARAM lParam
    ) {


        switch (message) {
            // Not doing anything yet
        }

        return DefWindowProc(hWnd, message, wParam, lParam);
    }
}


JNIEXPORT void JNICALL Java_com_app_project_winapi_WindowsAPI_shutdownBlockReasonCreate(JNIEnv *env, jclass cls, jstring title) {
    cout << "shutdownblockreason create" << endl;

    const char *str = NULL;

    str = (env)->GetStringUTFChars(title, 0);
    HWND hWnd = FindWindow(NULL, str);
    (env)->ReleaseStringUTFChars(title, str);
    if (hWnd == NULL) {
        return;
    }

    ShutdownBlockReasonCreate(hWnd, SHUTDOWN_REASON);


    //SetWindowLongPtr(hWnd, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(AppWndProc));

    return;
}

JNIEXPORT void JNICALL Java_com_app_project_winapi_WindowsAPI_shutdownBlockReasonDestroy(JNIEnv *env, jclass cls, jstring title) {
    cout << "shutdownblockreason destroy" << endl;

    const char *str = NULL;

    str = (env)->GetStringUTFChars(title, 0);
    HWND hWnd = FindWindow(NULL, str);
    (env)->ReleaseStringUTFChars(title, str);
    if (hWnd == NULL) {
        return;
    }

    ShutdownBlockReasonDestroy(hWnd);

    return;
}

我目前正在使用SWT进行涉及Eclipse RCP的Java项目,并试图通过在保存时向Windows环境中的用户提供有意义的消息来处理正常关闭。我是...

c++ winapi java-native-interface save shutdown
1个回答
0
投票

首先,您正在调用ANSI version of FindWindow(),它不接受UTF-8字符串。请改用FindWindow(),它接受UTF-16字符串。 Java字符串本身是UTF-16。

第二,您的窗口在调用Unicode version之后无法正确运行,因为您的SetWindowLongPtr()需要使用SetWindowLongPtr()而不是AppWndProc()来调用您替换的上一个窗口过程。另外,使用CallWindowProc()完成操作后,您将不还原以前的窗口过程。

© www.soinside.com 2019 - 2024. All rights reserved.