I'm currently working on a Java project involving Eclipse RCP using SWT and was trying to handle graceful shutdown by providing meaningful messages to user in Windows environment when saving. I was supposed to use ShutdownBlockReasonCreate and ShutdownBLockReasonDestroy APIs to achieve this but after some research I had to implement them in C++ native code which I'm very new to. As they are not available in JNA and Eclipse SWT does not provide such capability off-the-shelf (would love to know otherwise)
After going through all the effort I was able to pull together a working C++ code (as follows) to get control of the SWT window (by referencing another implementation https://github.com/seraphy/JavaGracefulShutdownForWin7). However I stumble upon an issue which relates to WindowProc CALLBACK. Coming from Java background these syntax took me a while to understand. But I sort of get what it's trying to do. Because this is where we need to handle WM_QUERYENDSESSION and WM_ENDSESSION messages.
But before getting to that, the problem I want to talk about in this post is specifically related to the windows API SetWindowLongPtr as you can see in the Java_com_app_project_winapi_WindowsAPI_shutdownBlockReasonCreate(JNIEnv *env, jclass cls, jstring title)
function. As you can see I commented it out, simply because my window tends to behave very strange when this method was called after ShutdownBlockReasonCreate(hWnd, SHUTDOWN_REASON)
. For example,
- "File" option when clicked, no longer show menu;
- When resizing the window, half the window become dark when you try to resize it back
- When closing the window, the underlying process still running
Yes I need to use this method in order to activate the control of the window for receiving os messages, but then it started to mess up with the Eclipse SWT window that was already built. Does anyone know if I have implemented this whole thing correctly? Or am I off-track? What does SetWindowLongPtr do exactly? I couldn't find any good reference and I couldn't get much out of reading the Microsoft Doc.
Thanks in advance!
#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;
}