2011-02-04 6 views
3

Runtime # addShutdownHook (Thread)가 Windows [1]에서 작동하지 않기 때문에 JNA를 사용하여 Java에서 WM_QUERYENDSESSION 메시지를 catch하고 싶습니다. JNIWrapper로 구현 한 것을 보았으므로이 작업을 수행 할 수 있지만 JNA 기반 솔루션을 갖고 싶습니다.JNA로 WM_QUERYENDSESSION 메시지를 처리하는 방법

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) 

여기에 : 나는 WindowProc 콜백 및 매개 변수로 받아들이는 SetWindowLong에 방법으로 내 자신의가 User32 클래스를 만들려고

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(); 
    } 
} 

JNIWrapper 솔루션 그러나 나는 다음과 같은 예외가 내 User32 클래스 :

및 입력하려고하는 클래스 모든 것을 함께 :

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] The shutdown hook isn't executed when the application is launched using javaw.exe

답변

1

사용자 환경에서 JNA의 jar 파일이 있는지 확인합니다. jna.jar과 platform.jar가 모두 있어야합니다. 그렇지 않으면 참조가 실패합니다. 다른 점은 JNA를 통해 사용하는 dll 파일은 사용자 환경 (예 : user32.dll)에로드해야하는 경우입니다.

관련 문제