/* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
* <p/>
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*/
package org.rzo.yajsw.os.ms.win.w32;
import java.util.Collection;
import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.Semaphore;
import jnacontrib.jna.Options;
import org.apache.commons.collections.BidiMap;
import org.apache.commons.collections.MultiHashMap;
import org.apache.commons.collections.bidimap.DualHashBidiMap;
import org.rzo.yajsw.os.ms.win.w32.DummyWindow.MyUser32.MSG;
import org.rzo.yajsw.os.ms.win.w32.DummyWindow.MyUser32.WNDCLASSEX;
import org.rzo.yajsw.os.ms.win.w32.DummyWindow.MyUser32.WNDPROC;
import com.sun.jna.Callback;
import com.sun.jna.Native;
import com.sun.jna.Pointer;
import com.sun.jna.Structure;
import com.sun.jna.platform.win32.GDI32;
import com.sun.jna.platform.win32.Kernel32;
import com.sun.jna.platform.win32.WinUser.POINT;
import com.sun.jna.ptr.PointerByReference;
// TODO: Auto-generated Javadoc
/**
* The Class DummyWindow.
*/
public class DummyWindow
{
/**
* The Interface MyKernel32.
*/
public interface MyKernel32 extends Kernel32
{
/** The INSTANCE. */
MyKernel32 INSTANCE = (MyKernel32) Native.loadLibrary("Kernel32", MyKernel32.class);
/*
* HMODULE WINAPI GetModuleHandle( __in LPCTSTR lpModuleName );
*/
/**
* Gets the module handle a.
*
* @param lpModuleName
* the lp module name
*
* @return the pointer
*/
Pointer GetModuleHandleA(String lpModuleName);
/*
* BOOL WINAPI GetModuleHandleEx( __in DWORD dwFlags, __in LPCTSTR
* lpModuleName, __out HMODULE phModule );
*/
/**
* Gets the module handle ex a.
*
* @param dwFlags
* the dw flags
* @param lpModuleName
* the lp module name
* @param phModule
* the ph module
*
* @return true, if successful
*/
boolean GetModuleHandleExA(int dwFlags, String lpModuleName, PointerByReference phModule);
/**
* Global add atom a.
*
* @param key
* the key
*
* @return the int
*/
int GlobalAddAtomA(String key);
}// Kernel32
/**
* The Interface MyUser32.
*/
public abstract interface MyUser32 extends com.sun.jna.platform.win32.User32
{
// Method declarations, constant and structure definitions go here
/** The INSTANCE. */
MyUser32 INSTANCE = (MyUser32) Native.loadLibrary("User32", MyUser32.class);
/**
* Register hot key.
*
* @param hWnd
* the h wnd
* @param id
* the id
* @param fsModifiers
* the fs modifiers
* @param vk
* the vk
*
* @return the int
*/
int RegisterHotKey(Pointer hWnd, int id, int fsModifiers, int vk);
/*
* BOOL UnregisterHotKey( HWND hWnd, int id );
*/
/**
* Unregister hot key.
*
* @param hWnd
* the h wnd
* @param id
* the id
*
* @return the int
*/
int UnregisterHotKey(Pointer hWnd, int id);
/*
* LRESULT CALLBACK WindowProc( HWND hwnd, UINT uMsg, WPARAM wParam,
* LPARAM lParam );
*/
/**
* The Interface WNDPROC.
*/
interface WNDPROC extends Callback
{
/**
* Callback.
*
* @param hwnd
* the hwnd
* @param uMsg
* the u msg
* @param wParam
* the w param
* @param lParam
* the l param
*
* @return the int
*/
int callback(Pointer hwnd, int uMsg, int wParam, int lParam);
}
/** The W m_ hotkey. */
int WM_HOTKEY = 786;
/*
* typedef struct { UINT cbSize; UINT style; WNDPROC lpfnWndProc; int
* cbClsExtra; int cbWndExtra; HINSTANCE hInstance; HICON hIcon; HCURSOR
* hCursor; HBRUSH hbrBackground; LPCTSTR lpszMenuName; LPCTSTR
* lpszClassName; HICON hIconSm; } WNDCLASSEX,PWNDCLASSEX;
*/
/** The C s_ hredraw. */
int CS_HREDRAW = 2;
/** The C s_ vredraw. */
int CS_VREDRAW = 1;
/**
* The Class WNDCLASSEX.
*/
static class WNDCLASSEX extends Structure
{
/** The cb size. */
public int cbSize = size();
/** The style. */
public int style = 0;
/** The lpfn wnd proc. */
public WNDPROC lpfnWndProc;
/** The cb cls extra. */
public int cbClsExtra = 0;
/** The cb wnd extra. */
public int cbWndExtra = 0;
/** The h instance. */
public Pointer hInstance;
/** The h icon. */
public Pointer hIcon = null;
/** The h cursor. */
public Pointer hCursor = null;
/** The hbr background. */
public Pointer hbrBackground = null;
/** The lpsz menu name. */
public String lpszMenuName = null;
/** The lpsz class name. */
public String lpszClassName = "JavaDummyWnd";
/** The h icon sm. */
public Pointer hIconSm = null;
}
/*
* ATOM RegisterClassEx( CONST WNDCLASSEXlpwcx );
*/
/**
* Register class ex a.
*
* @param lpwcx
* the lpwcx
*
* @return the int
*/
int RegisterClassExA(WNDCLASSEX lpwcx);
/*
* BOOL UnregisterClass( LPCTSTR lpClassName, HINSTANCE hInstance );
*/
/**
* Unregister class w.
*
* @param lpClassName
* the lp class name
* @param hInstance
* the h instance
*
* @return the int
*/
int UnregisterClassW(String lpClassName, Pointer hInstance);
/*
* HWND CreateWindowEx( DWORD dwExStyle, LPCTSTR lpClassName, LPCTSTR
* lpWindowName, DWORD dwStyle, int x, int y, int nWidth, int nHeight,
* HWND hWndParent, HMENU hMenu, HINSTANCE hInstance, LPVOID lpParam );
*/
/** The W s_ overlappedwindow. */
int WS_OVERLAPPEDWINDOW = 0xcf0000;
/** The W s_ e x_ clientedge. */
int WS_EX_CLIENTEDGE = 512;
/** The W s_ overlapped. */
int WS_OVERLAPPED = 0;
/** The W s_ visible. */
int WS_VISIBLE = 0x10000000;
/**
* Creates the window ex a.
*
* @param dwExStyle
* the dw ex style
* @param lpClassName
* the lp class name
* @param lpWindowName
* the lp window name
* @param dwStyle
* the dw style
* @param x
* the x
* @param y
* the y
* @param nWidth
* the n width
* @param nHeight
* the n height
* @param hWndParent
* the h wnd parent
* @param hMenu
* the h menu
* @param hInstance
* the h instance
* @param lpParam
* the lp param
*
* @return the pointer
*/
Pointer CreateWindowExA(int dwExStyle, String lpClassName, String lpWindowName, int dwStyle, int x, int y, int nWidth, int nHeight,
Pointer hWndParent, Pointer hMenu, Pointer hInstance, Pointer lpParam);
/*
* LONG_PTR SetWindowLongPtr( HWND hWnd, int nIndex, LONG_PTR dwNewLong
* );
*/
/**
* Sets the window long a.
*
* @param hWnd
* the h wnd
* @param nIndex
* the n index
* @param dwNewLong
* the dw new long
*
* @return the pointer
*/
Pointer SetWindowLongA(Pointer hWnd, int nIndex, Pointer dwNewLong);
/*
* LONG_PTR GetWindowLongPtr( HWND hWnd, int nIndex );
*/
/**
* Gets the window long a.
*
* @param hWnd
* the h wnd
* @param nIndex
* the n index
*
* @return the pointer
*/
Pointer GetWindowLongA(Pointer hWnd, int nIndex);
/** The GWL p_ userdata. */
int GWLP_USERDATA = -21;
/*
* LRESULT DefWindowProc( HWND hWnd, UINT Msg, WPARAM wParam, LPARAM
* lParam );
*/
/**
* Def window proc a.
*
* @param hWnd
* the h wnd
* @param Msg
* the msg
* @param wParam
* the w param
* @param lParam
* the l param
*
* @return the int
*/
int DefWindowProcA(Pointer hWnd, int Msg, int wParam, int lParam);
/*
* BOOL ShowWindow( HWND hWnd, int nCmdShow );
*/
/**
* Show window.
*
* @param hWnd
* the h wnd
* @param nCmdShow
* the n cmd show
*
* @return the int
*/
int ShowWindow(Pointer hWnd, int nCmdShow);
/** The S w_ hide. */
int SW_HIDE = 0;
/** The S w_ show. */
int SW_SHOW = 5;
/** The S w_ shownormal. */
int SW_SHOWNORMAL = 1;
/*
* BOOL UpdateWindow( HWND hWnd // handle to window );
*/
/**
* Update window.
*
* @param hWnd
* the h wnd
*
* @return the int
*/
int UpdateWindow(Pointer hWnd // handle to window
);
/*
* typedef struct { HWND hwnd; UINT message; WPARAM wParam; LPARAM
* lParam; DWORD time; POINT pt; } MSG,PMSG;
*/
/**
* The Class MSG.
*/
class MSG extends Structure
{
/** The hwnd. */
public Pointer hwnd;
/** The message. */
public int message;
/** The w param. */
public int wParam;
/** The l param. */
public int lParam;
/** The time. */
public int time;
/** The pt. */
public POINT pt;
}
/*
* BOOL GetMessage( LPMSG lpMsg, HWND hWnd, UINT wMsgFilterMin, UINT
* wMsgFilterMax );
*/
/**
* Gets the message a.
*
* @param lpMsg
* the lp msg
* @param hWnd
* the h wnd
* @param wMsgFilterMin
* the w msg filter min
* @param wMsgFilterMax
* the w msg filter max
*
* @return the int
*/
int GetMessageA(MSG lpMsg, Pointer hWnd, int wMsgFilterMin, int wMsgFilterMax);
/*
* LRESULT DispatchMessage( const MSGlpmsg );
*/
/**
* Dispatch message a.
*
* @param lpmsg
* the lpmsg
*
* @return the int
*/
int DispatchMessageA(MSG lpmsg);
} // user32
/**
* The Interface MyGdi32.
*/
public interface MyGdi32 extends GDI32
{
/** The INSTANCE. */
MyGdi32 INSTANCE = (MyGdi32) Native.loadLibrary("gdi32", MyGdi32.class, Options.UNICODE_OPTIONS);
/*
* HGDIOBJ GetStockObject( int fnObject // stock object type );
*/
/**
* Gets the stock object.
*
* @param fnObject
* the fn object
*
* @return the pointer
*/
Pointer GetStockObject(int fnObject);
/** The BLAC k_ brush. */
int BLACK_BRUSH = 4;
}// Gdi32
/**
* The Class CallbackMessage.
*/
static class CallbackMessage
{
/** The _u msg. */
int _uMsg;
/** The _w param. */
int _wParam;
/** The _l param. */
int _lParam;
/**
* Instantiates a new callback message.
*
* @param uMsg
* the u msg
* @param wParam
* the w param
* @param lParam
* the l param
*/
CallbackMessage(int uMsg, int wParam, int lParam)
{
_uMsg = uMsg;
_wParam = wParam;
_lParam = lParam;
}
}
/** The _instance. */
static DummyWindow _instance;
/** The _listners. */
static Map _listners = new MultiHashMap();
/** The _wnd proc. */
WndProc _wndProc = new WndProc();
/** The _hinstance. */
Pointer _hinstance;
/** The _h wnd. */
Pointer _hWnd;
/** The _wnd class. */
WNDCLASSEX _wndClass = new WNDCLASSEX();
/** The _queue. */
static LinkedBlockingQueue _queue = new LinkedBlockingQueue();
/** The _hot keys. */
static BidiMap _hotKeys = new DualHashBidiMap();
/** The _semaphore. */
Semaphore _semaphore = new Semaphore(0);
/**
* The Class HotKey.
*/
public class HotKey
{
/**
* Instantiates a new hot key.
*
* @param wParam
* the w param
* @param lParam
* the l param
*/
public HotKey(int wParam, int lParam)
{
_wParam = wParam;
_lParam = lParam;
}
/** The _w param. */
int _wParam;
/** The _l param. */
int _lParam;
/*
* (non-Javadoc)
*
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode()
{
return _wParam | _lParam;
}
/*
* (non-Javadoc)
*
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(Object obj)
{
return (obj instanceof HotKey && ((HotKey) obj)._lParam == _lParam && ((HotKey) obj)._lParam == _lParam);
}
}
/**
* Instance.
*
* @return the dummy window
*/
public static synchronized DummyWindow instance()
{
if (_instance == null)
{
_instance = new DummyWindow();
_instance.init();
}
return _instance;
}
/**
* The Class WndProc.
*/
static class WndProc extends Structure implements WNDPROC
{
/*
* (non-Javadoc)
*
* @see
* org.rzo.yajsw.os.ms.win.xp.DummyWindow.MyUser32.WNDPROC#callback(
* com.sun.jna.Pointer, int, int, int)
*/
public int callback(Pointer hWnd, int uMsg, int wParam, int lParam)
{
// System.out.println("callback " + uMsg + " " + wParam + " " +
// lParam + " " + "ptr" + " "+ hWnd);
if (_listners.get(new Integer(uMsg)) != null)
{
CallbackMessage msg = new CallbackMessage(uMsg, wParam, lParam);
_queue.offer(msg);
}
int res = MyUser32.INSTANCE.DefWindowProcA(hWnd, uMsg, wParam, lParam);
// System.out.println(">" + res);
return res;
}
/**
* Instantiates a new wnd proc.
*/
WndProc()
{
super();
allocateMemory(4);
}
}
/**
* The Interface WndListner.
*/
public interface WndListner
{
/**
* Execute.
*
* @param uMsg
* the u msg
* @param wParam
* the w param
* @param lParam
* the l param
*
* @return the int
*/
int execute(int uMsg, int wParam, int lParam);
}
/**
* Adds the listner.
*
* @param uMsg
* the u msg
* @param listner
* the listner
*/
public void addListner(Integer uMsg, WndListner listner)
{
synchronized (_listners)
{
_listners.put(uMsg, listner);
}
}
/**
* Removes the listner.
*
* @param listner
* the listner
*/
public void removeListner(WndListner listner)
{
synchronized (_listners)
{
_listners.remove(listner);
}
}
/**
* Inits the.
*/
private void init()
{
Runnable r = new Runnable()
{
public void run()
{
_hinstance = MyKernel32.INSTANCE.GetModuleHandleA(null);
_wndClass.lpfnWndProc = _wndProc;
_wndClass.hInstance = _hinstance;
if (MyUser32.INSTANCE.RegisterClassExA(_wndClass) == 0)
return;
_hWnd = MyUser32.INSTANCE.CreateWindowExA(0, _wndClass.lpszClassName, _wndClass.lpszClassName, 0, 0, 0, 0, 0, null, null, _hinstance,
null);
MyUser32.INSTANCE.ShowWindow(_hWnd, MyUser32.SW_HIDE);
MyUser32.INSTANCE.UpdateWindow(_hWnd);
MSG msg = new MSG();
msg.size();
int ret;
do
{
ret = MyUser32.INSTANCE.GetMessageA(msg, _hWnd, 0, 0);
// System.out.println("get message "+msg);
if (msg.message == WindowsXPKeyboard.WND_REGISTER_HOTKEY)
{
int id = MyKernel32.INSTANCE.GlobalAddAtomA("JHOTKEY-" + msg.wParam + "-" + msg.lParam);
int ret2 = MyUser32.INSTANCE.RegisterHotKey(_hWnd, id, msg.wParam, msg.lParam);
// System.out.println("register: "+id);
if (ret2 != 0)
_hotKeys.put(new Integer(id), new HotKey(msg.wParam, msg.lParam));
// System.out.println("register "+ret2);
_semaphore.release();
}
else if (msg.message == WindowsXPKeyboard.WND_UNREGISTER_HOTKEY)
{
HotKey k = new HotKey(msg.wParam, msg.lParam);
Integer id = (Integer) _hotKeys.getKey(k);
// System.out.println("unregister: "+id);
if (id != null)
if (MyUser32.INSTANCE.UnregisterHotKey(_hWnd, id.intValue()) != 0)
_hotKeys.remove(id);
_semaphore.release();
}
else
MyUser32.INSTANCE.DispatchMessageA(msg);
}
while (ret != 0);
}
};
Runnable r2 = new Runnable()
{
public void run()
{
CallbackMessage msg;
try
{
while (true)
{
msg = (CallbackMessage) _queue.take();
// System.out.println("Message queue: "+msg._uMsg);
Collection listners = (Collection) _listners.get(new Integer(msg._uMsg));
if (listners != null)
for (Iterator it = listners.iterator(); it.hasNext();)
{
WndListner listner = (WndListner) it.next();
listner.execute(msg._uMsg, msg._wParam, msg._lParam);
}
}
}
catch (Exception e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
new Thread(r2).start();
new Thread(r).start();
_semaphore.release();
}
/**
* Wait termination.
*
* @throws InterruptedException
* the interrupted exception
*/
void waitTermination() throws InterruptedException
{
// System.out.println("+ wait termination "+
// System.currentTimeMillis());
_semaphore.acquire();
// System.out.println("- wait termination "+
// System.currentTimeMillis());
}
}