首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用JNA处理WM_QUERYENDSESSION消息

如何使用JNA处理WM_QUERYENDSESSION消息
EN

Stack Overflow用户
提问于 2011-02-05 02:31:37
回答 1查看 2.9K关注 0票数 3

我想用JNA捕获Java中的WM_QUERYENDSESSION消息,这样我就可以执行shutdown方法,因为Runtime#addShutdownHook(线程)在Windows1上不能工作。我知道这是可以做到的,因为我已经看到它是用JNIWrapper实现的,但我希望有一个基于JNA的解决方案。

JNIWrapper解决方案

代码语言:javascript
复制
import java.io.File;
import java.io.RandomAccessFile;

import javax.swing.JFrame;

import com.jniwrapper.win32.Msg;
import com.jniwrapper.win32.ui.WindowMessage;
import com.jniwrapper.win32.ui.WindowMessageListener;
import com.jniwrapper.win32.ui.WindowProc;
import com.jniwrapper.win32.ui.Wnd;

public class ShutdownJNIWrapper {

    public static void main(String[] args) {
        final JFrame frame = new JFrame("Shutdown Test");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);

        Wnd frameHandle = new Wnd(frame);
        WindowProc frameWindowProc = new WindowProc(frameHandle);
        frameWindowProc.addMessageListener(new WindowMessageListener() {
            public boolean canHandle(WindowMessage windowMessage, boolean beforeWindowProc) {
                return windowMessage.getMsg() == Msg.WM_QUERYENDSESSION && beforeWindowProc;
            }

            public int handle(WindowMessage windowMessage) {
                doSomething();

                return 0;
            }

            private void doSomething() {
                final File file = new File("shutdown-jniwrapper.txt");

                try {
                    RandomAccessFile raf = new RandomAccessFile(file, "rw");
                    raf.writeUTF("quit");
                    raf.close();
                } catch (Exception e) {
                }
            }
        });
        frameWindowProc.substitute();
    }
}

我试图用一个WindowProc回调函数和一个接受它作为参数的SetWindowLong方法来创建我自己的User32类,但是我得到了以下异常:

代码语言:javascript
复制
Exception in thread "main" java.lang.UnsatisfiedLinkError: Error looking up function 'SetWindowLong': The specified procedure could not be found.

at com.sun.jna.Function.<init>(Function.java:179)
at com.sun.jna.NativeLibrary.getFunction(NativeLibrary.java:344)
at com.sun.jna.NativeLibrary.getFunction(NativeLibrary.java:324)
at com.sun.jna.Library$Handler.invoke(Library.java:203)
at $Proxy0.SetWindowLong(Unknown Source)
at ShutdownJNA.main(ShutdownJNA.java:34)

下面是我的User32类:

代码语言:javascript
复制
import com.sun.jna.platform.win32.WinDef.HWND;
import com.sun.jna.platform.win32.WinDef.LPARAM;
import com.sun.jna.platform.win32.WinDef.LRESULT;
import com.sun.jna.platform.win32.WinDef.WPARAM;
import com.sun.jna.win32.StdCallLibrary;

public interface MyUser32 extends StdCallLibrary { 

    public static final int WM_QUERYENDSESSION = 0x11;

    public static int GWL_WNDPROC = -4;

    interface WindowProc extends StdCallCallback {
        LRESULT callback(HWND hWnd, int uMsg, WPARAM wParam, LPARAM lParam);
    }

    int SetWindowLong(HWND hWnd, int nIndex, int dwNewLong);

    int SetWindowLong(HWND hWnd, int nIndex, WindowProc dwNewLong);
};

以及尝试将所有东西放在一起的类:

代码语言:javascript
复制
import javax.swing.JFrame;
import javax.swing.JPanel;

import com.sun.jna.Native;
import com.sun.jna.platform.win32.WinDef.HWND;
import com.sun.jna.platform.win32.WinDef.LPARAM;
import com.sun.jna.platform.win32.WinDef.LRESULT;
import com.sun.jna.platform.win32.WinDef.WPARAM;


public class ShutdownJNA extends JPanel {

    public static void main(String[] args) {
        final JFrame frame = new JFrame("Shutdown Test");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);

        try {
            HWND hwnd = new HWND();
            hwnd.setPointer(Native.getComponentPointer(frame));

            MyUser32.WindowProc proc = new MyUser32.WindowProc() {
                public LRESULT callback(HWND wnd, int msg, WPARAM param, LPARAM param2) {
                    if (msg == MyUser32.WM_QUERYENDSESSION) {}

                    return new LRESULT(0);
                }
            };

            MyUser32 user32 = (MyUser32)Native.loadLibrary("user32", MyUser32.class); //$NON-NLS-1$
            user32.SetWindowLong(hwnd, MyUser32.GWL_WNDPROC, proc);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

1

EN

回答 1

Stack Overflow用户

发布于 2012-02-08 02:08:06

确保您的环境中有用于JNA的jar文件。jna.jar和platform.jar必须都在那里,否则引用将失败。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4901609

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档