2023-01-19 391
我目前正在从事一个Java项目,该项目涉及Eclipse RCP使用SWT,并试图通过在保存时向Windows环境中的用户提供有意义的消息来处理优雅的关闭.我本来应该使用 ShutDownBlockReasonCreate 和 shutdowndowndowndowndownblockreasondestroy apis来实现这一目标,但是经过一项研究,我不得不在我非常陌生的C ++本机代码中实施它们.因为它们在JNA和Eclipse SWT中不可用,因此无法提供此类功能(愿意知道否则)
经过所有的努力,我能够将工作的C ++代码(如下)组合在一起以控制SWT窗口(通过引用另一个实现 https://github.com/seraphy/javagracefulshutdownforwin7 ).但是,我偶然发现了与WindowProc回调有关的问题.来自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;
}
首先,您是在调用 FindWindow() 的ANSI版本,不接受UTF-8字符串.使用 unicode版本接受UTF-16字符串. Java字符串本地使用UTF-16进行公共界面,因此您无需浪费时间将它们不必要地转换为UTF-8.
第二,打电话后您的窗口无法正常操作, SetWindowLongPtr() 因为您的AppWndProc()需要使用 CallWindowProc() 而不是 DefWindowProc() 调用您替换的先前窗口过程.另外,使用AppWndProc()完成后,您不会还原以前的窗口过程.
第三,您应该使用 而不是SetWindowLongPtr(). See Disadvantages旧的子分类方法和 Safer safer子分类.
话虽如此,请尝试更多类似的东西:
#include <jni.h>
#include <iostream>
#include "com_app_project_winapi_WindowsAPI.h"
#include <windows.h>
#include <commctrl.h>
namespace {
LPCWSTR SHUTDOWN_REASON = L"Application is still saving ...";
/*
WNDPROC PrevWndProc = NULL;
LRESULT CALLBACK AppWndProc(
_In_ HWND hWnd,
_In_ UINT message,
_In_ WPARAM wParam,
_In_ LPARAM lParam
) {
*/
LRESULT CALLBACK AppWndProc(
_In_ HWND hWnd,
_In_ UINT message,
_In_ WPARAM wParam,
_In_ LPARAM lParam,
_In_ UINT_PTR uIdSubclass,
_In_ DWORD_PTR dwRefData
) {
switch (message) {
case WM_NCDESTROY:
RemoveWindowSubclass(hWnd, AppWndProc, uIdSubclass);
break;
//...
}
//return CallWindowProc(PrevWndProc, hWnd, message, wParam, lParam);
return DefSubclassProc(hWnd, message, wParam, lParam);
}
}
JNIEXPORT void JNICALL Java_com_app_project_winapi_WindowsAPI_shutdownBlockReasonCreate(JNIEnv *env, jclass cls, jstring title) {
std::cout << "shutdownblockreason create" << std::endl;
const jchar *str = env->GetStringChars(title, NULL);
HWND hWnd = FindWindowW(NULL, (LPCWSTR) str);
env->ReleaseStringChars(title, str);
if (!hWnd) {
return;
}
ShutdownBlockReasonCreate(hWnd, SHUTDOWN_REASON);
//PrevWndProc = (WNDPROC) SetWindowLongPtr(hWnd, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(AppWndProc));
SetWindowSubclass(hWnd, &AppWndProc, 1, 0);
}
JNIEXPORT void JNICALL Java_com_app_project_winapi_WindowsAPI_shutdownBlockReasonDestroy(JNIEnv *env, jclass cls, jstring title) {
std::cout << "shutdownblockreason destroy" << std::endl;
const jchar *str = env->GetStringChars(title, NULL);
HWND hWnd = FindWindowW(NULL, (LPCWSTR) str);
env->ReleaseStringChars(title, str);
if (!hWnd) {
return;
}
//SetWindowLongPtr(hWnd, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(PrevWndProc));
RemoveWindowSubclass(hWnd, &AppWndProc, 1);
ShutdownBlockReasonDestroy(hWnd);
}
以上所述是小编给大家介绍的Winapi SetWindowLongPtr在ShutdownBlockReasonCreate/Destroy中实现JNI本机代码,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对77isp云服务器技术网的支持!
原文链接:https://77isp.com/post/25811.html
=========================================
https://77isp.com/ 为 “云服务器技术网” 唯一官方服务平台,请勿相信其他任何渠道。
数据库技术 2022-03-28
网站技术 2022-11-26
网站技术 2023-01-07
网站技术 2022-11-17
Windows相关 2022-02-23
网站技术 2023-01-14
Windows相关 2022-02-16
Windows相关 2022-02-16
Linux相关 2022-02-27
数据库技术 2022-02-20
抠敌 2023年10月23日
嚼餐 2023年10月23日
男忌 2023年10月22日
瓮仆 2023年10月22日
簿偌 2023年10月22日
扫码二维码
获取最新动态