我目前正在处理一个涉及使用 SWT 的 Eclipse RCP 的 Java 项目,并试图通过在保存时向 Windows 环境中的用户提供有意义的消息来处理正常关闭。我应该使用ShutdownBlockReasonCreate和ShutdownBLockReasonDestroy 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)。例如,
- 单击“文件”选项,不再显示菜单;
- 调整窗口大小时,当您尝试调整窗口大小时,一半窗口变暗
- 关闭窗口时,底层进程仍在运行
是的,我需要使用此方法来激活窗口控制以接收操作系统消息,但随后它开始与已经构建的 Eclipse SWT 窗口混淆。有谁知道我是否正确实施了这整件事?还是我跑偏了?SetWindowLongPtr究竟做了什么?我找不到任何好的参考资料,也无法从阅读 Microsoft Doc 中得到太多。
提前致谢!
#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;
}