⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 win32sessionmanager.java

📁 一个开源的组件
💻 JAVA
字号:
package org.xvolks.jnative.util.win32session;

import java.awt.Dialog;
import java.awt.Frame;
import java.awt.TextField;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.xvolks.jnative.JNative;
import org.xvolks.jnative.exceptions.NativeException;
import org.xvolks.jnative.misc.MSG;
import org.xvolks.jnative.misc.MSG.WindowsConstants;
import org.xvolks.jnative.misc.basicStructures.HWND;
import org.xvolks.jnative.misc.basicStructures.LPARAM;
import org.xvolks.jnative.misc.basicStructures.LRESULT;
import org.xvolks.jnative.misc.basicStructures.UINT;
import org.xvolks.jnative.misc.basicStructures.WPARAM;
import org.xvolks.jnative.util.Callback;
import org.xvolks.jnative.util.Kernel32;
import org.xvolks.jnative.util.User32;
import org.xvolks.jnative.util.WindowProc;
import org.xvolks.jnative.util.constants.winuser.WM;

/**
 * 
 */

/**
 * @author Marc DENTY (mdt) - 14 nov. 06 $Id: Win32SessionManager.java,v 1.4 2007/04/25 11:46:54 thubby Exp $
 * 
 */
public class Win32SessionManager {

	public interface EndSessionListener {
		public enum Origin {
			CONSOLE,
			WINDOW,
			;
		}
		/** 
		 * Called when a EndSession event is detected
		 * @param org
		 * @return true to let the session to close, false to stop that process
		 */
		public boolean queryEndSessionOccured(Origin org);
		
		/**
		 * This event is only avaliable if launched with javaw.exe (windows)
		 * @param org
		 */
		public void endSessionOccured(Origin org);
		
		/**
		 * This event is only avaliable if launched with java.exe (console)
		 * @param org
		 */
		public void shutdownOccured(Origin org);
	}
	
	private static final CallBackWindowProc console_proc = new CallBackWindowProc();
	
	private static List<EndSessionListener> listeners = new ArrayList<EndSessionListener>();

	
	public static void addEndSessionListener(EndSessionListener listener) {
		if(!listeners.contains(listener)){
			listeners.add(listener);
		}
	}
	public static boolean removeEndSessionListener(EndSessionListener listener) {
		return listeners.remove(listener);
	}
	
	public static boolean fireQueryEndSessionOccured(EndSessionListener.Origin origin) {
		boolean ret = true;
		for(EndSessionListener l : listeners) {
			ret &= l.queryEndSessionOccured(origin);
		}
		return ret;
	}
	
	public static void fireEndSessionOccured(EndSessionListener.Origin origin) {
		for(EndSessionListener l : listeners) {
			l.endSessionOccured(origin);
		}
	}
	
	public static void fireShutdownOccured(EndSessionListener.Origin origin) {
		for(EndSessionListener l : listeners) {
			l.shutdownOccured(origin);
		}
	}
	
	static class CallBackWindowProc implements Callback { 
		public int HandlerRoutine(int msg) {
			switch (msg) {
				/*
				 * CTRL_C_EVENT 0 A CTRL+C signal was received, either from
				 * keyboard input or from a signal generated by the
				 * GenerateConsoleCtrlEvent function. CTRL_BREAK_EVENT 1 A
				 * CTRL+BREAK signal was received, either from keyboard input or
				 * from a signal generated by GenerateConsoleCtrlEvent.
				 * CTRL_CLOSE_EVENT 2 A signal that the system sends to all
				 * processes attached to a console when the user closes the
				 * console (either by clicking Close on the console window's
				 * window menu, or by clicking the End Task button command from
				 * Task Manager). CTRL_LOGOFF_EVENT 5 A signal that the system
				 * sends to all console processes when a user is logging off.
				 * This signal does not indicate which user is logging off, so
				 * no assumptions can be made.
				 * 
				 * Note that this signal is received only by services.
				 * Interactive applications are terminated at logoff, so they
				 * are not present when the system sends this signal.
				 * CTRL_SHUTDOWN_EVENT 6 A signal that the system sends when the
				 * system is shutting down. Interactive applications are not
				 * present by the time the system sends this signal, therefore
				 * it can be received only be services in this situation.
				 * Services also have their own notification mechanism for
				 * shutdown events. For more information, see Handler.
				 */
	            case 5:
		            return fireQueryEndSessionOccured(EndSessionListener.Origin.CONSOLE) ? 0 : 1;
	            case 6:
		            fireShutdownOccured(EndSessionListener.Origin.CONSOLE);
		            break;

	            default:
            }
			return 1;
			
		}
		
		public int callback(long[] values) {
			return HandlerRoutine(
					(int) values[0]);
		}

		private int instance=0;
		public int getCallbackAddress() throws NativeException {
			if (instance==0) {
				instance=JNative.createCallback(1, this);
			}
			return instance;
			
		}
		public boolean releaseCallbackAddress() throws NativeException {
			if(instance != 0 && JNative.releaseCallback(this)) {
				instance = 0;
				return true;
			} else {
				return false;
			}
			
		}
	}

	
	private static HWND	_hwnd	= null;
	private static int oldWindowProc;
	
	/**
	 * 
	 * @throws NativeException
	 * @throws IllegalAccessException
	 */
	public static boolean unregisterEndSessionHook() throws NativeException, IllegalAccessException {
		boolean ret = Kernel32.SetConsoleCtrlHandler(console_proc, false);
        if(JNative.isLogginEnabled()) 
        	System.err.println("RemoveConsoleHandler : " + ret);
        if(ret) {
        	console_proc.releaseCallbackAddress();
        }
		
        if(oldWindowProc != 0) {
        	LRESULT result = User32.SendMessage(_hwnd, new UINT(WM.WM_CLOSE.getValue()), new WPARAM(0), new LPARAM(0));
        	if(JNative.isLogginEnabled()) {
        		System.err.println("SendMessage WM_CLOSE returned " + result.getValue());
        	}
        	ret &= result.getValue() == 0;
        }
        
        return ret;
	}
	
	/**
	 * Be aware that calling this method <i>eats</i> one callback and the registerWindowProc slot !<br>
	 * This also prevents the app to close.
	 * 
	 * @throws IllegalAccessException 
	 * @throws NativeException 
	 */
	public static void registerEndSessionHook(final String windowName) throws NativeException, IllegalAccessException {
        if(JNative.isLogginEnabled()) 
        	System.err.println("SetConsoleHandler : " + Kernel32.SetConsoleCtrlHandler(console_proc, true));
        else 
        	Kernel32.SetConsoleCtrlHandler(console_proc, true);

		new Thread() {
		{
			setDaemon(true);
			setName("EndSessionListener");
		}
		public void run() {

			WindowProc proc = new WindowProc() {
				public int windowProc(int hwnd, int uMsg, int wParam, int lParam) {
					writeLog("log "+uMsg);
					if (_hwnd != null || hwnd == _hwnd.getValue()) {
						
						if(uMsg == WM.WM_QUERYENDSESSION.getValue()) {
								return fireQueryEndSessionOccured(EndSessionListener.Origin.WINDOW) ? -1 : 0;
						} else if(uMsg == WM.WM_ENDSESSION.getValue()) {
								fireEndSessionOccured(EndSessionListener.Origin.WINDOW);
								return -1;
						} else {
								try {
									int ret = User32.DefWindowProc(new HWND(hwnd), new UINT(uMsg), new WPARAM(wParam),
									        new LPARAM(lParam)).getValue();
									return ret;
								} catch (Exception ex) {
									return 0;
								}
						}
					} else {
						System.err.println("Je ne gere pas 鏰 !");
						
						return -1;
					}
				}

			};

			
			try {
				// Pointer p = new
				// Pointer(MemoryBlockFactory.createMemoryBlock(20));
				// p.setStringAt(0, "Invisible");
				_hwnd = new HWND(User32.CreateWindowEx(0,
				        "Message", windowName==null?"":windowName, 0, 0, 0, 100, 100, 0, 0, JNative.getCurrentModule(), 0));
				if(0==_hwnd.getValue()) {
					System.err.println("Failed to create the message listener window");
				}
			} catch (Exception ex) {
				ex.printStackTrace();
				System.err.println("Can't create the message listener window.");
			}
			try {
				oldWindowProc = JNative.registerWindowProc(_hwnd, proc);
				// User32.SetWindowLong(_hwnd, WindowsConstants.GWL_WNDPROC, new
				// LONG(test));
			} catch (Exception e1) {
				e1.printStackTrace();
			}
	
	
			try {
				User32.ShowWindow(_hwnd, WindowsConstants.SW_HIDE);
				User32.UpdateWindow(_hwnd);
			} catch (Exception e) {
				e.printStackTrace();
			}
	
	
				MSG msg = null;
				try {
					msg = new MSG();
				} catch (NativeException e) {
					e.printStackTrace();
				}


				boolean lQuit = false;
				try {
					while (!lQuit) {

						switch (User32.GetMessage(msg, new HWND(0), 0, 0)) {
							case -1:
								int error = Kernel32.getLastError();
								System.err.println("Error occured: " + error);
								lQuit = true;
								break;
							case 0:
								System.err.println("WM_QUIT received");
								lQuit = true;
								break;
						}

						User32.TranslateMessage(msg);
						User32.DispatchMessage(msg);
					}
				} catch (Exception ex) {
					ex.printStackTrace();
				}
			}
		}.start();
		
	}
	
	private static PrintWriter log=null;
	private static FileOutputStream fLog=null;
	
	public static void writeLog(String message) {
		if (fLog==null) {
			try {
				fLog=new FileOutputStream("./Win32SessionManager.log");
				log=new PrintWriter(fLog);
				Runtime.getRuntime().addShutdownHook(new Thread() {
					public void run() {
						writeLog("Closing log");
						log.close();
					}
				});
			} catch (Exception e) {
				return;
			}
		}
		
		log.println("["+new Date()+"] "+message);
		log.flush();
		try {
			fLog.getChannel().force(false);
		} catch (IOException e) {	
		}
	}
	
	public static void main(String[] args) throws NativeException, IllegalAccessException {
		
		writeLog("Running");
		addEndSessionListener(new EndSessionListener() {
			public void endSessionOccured(Origin org) {
				writeLog("Fin de session par "+org);
	            
            }

			public boolean queryEndSessionOccured(Origin org) {
				writeLog("Demande de fin de session par "+org);
	            return true;
            }

			public void shutdownOccured(Origin org) {
				writeLog("Shutdown captured from "+org);	            
            }
			
		});
		
		writeLog("Registring hook");
		registerEndSessionHook("Noone");
		final Dialog d = new Dialog(new Frame());
		
		d.setModal(true);
		d.add(new TextField("Testing, please close session"));
		d.pack();
		d.addWindowListener(new WindowAdapter() {

			/* (non-Javadoc)
             * @see java.awt.event.WindowAdapter#windowClosing(java.awt.event.WindowEvent)
             */
            @Override
            public void windowClosing(WindowEvent e) {
            	d.dispose();
            }
			
		});
		d.setVisible(true);
		
		writeLog("Exiting");
		System.exit(0);
	    
    }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -