Overview
Examples
Screenshots
Comparisons
Applications
Download
Documentation
Tutorials
Bazaar
Status & Roadmap
FAQ
Authors & License
Forums
Funding Ultimate++
Search on this site
Search in forums












SourceForge.net Logo
Home » U++ Library support » U++ Library : Other (not classified elsewhere) » How to set a global (system) keyboard hook?
How to set a global (system) keyboard hook? [message #23132] Fri, 18 September 2009 00:37 Go to next message
midra is currently offline  midra
Messages: 1
Registered: September 2009
Junior Member
Hi!
I'm new to U++ Sad
My problem is: how can I set a global (system) keyboard hook?

I want my dialog to appear on top of other windows when user presses some combination of keys (e.g. Control+Alt+C)

My program is supposed to run in Windows.

Thanks in advance for any help!
Best regards,
midra
Re: How to set a global (system) keyboard hook? [message #23134 is a reply to message #23132] Fri, 18 September 2009 05:55 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 14112
Registered: November 2005
Ultimate Member
midra wrote on Thu, 17 September 2009 18:37

Hi!
I'm new to U++ Sad
My problem is: how can I set a global (system) keyboard hook?

I want my dialog to appear on top of other windows when user presses some combination of keys (e.g. Control+Alt+C)

My program is supposed to run in Windows.

Thanks in advance for any help!
Best regards,
midra



You have to use host platform API (Win32).

I guess this one is what you need:

http://msdn.microsoft.com/en-us/library/ms646309%28VS.85%29. aspx?ppud=4

Then put GetHWND of some of your TopWindows in there and override

virtual LRESULT Ctrl::WindowProc(UINT message, WPARAM wParam, LPARAM lParam);


(Do not forget to call TopWindow::WindowProc at the end).

Mirek
Re: How to set a global (system) keyboard hook? [message #23135 is a reply to message #23134] Fri, 18 September 2009 08:01 Go to previous messageGo to next message
tojocky is currently offline  tojocky
Messages: 607
Registered: April 2008
Location: UK
Contributor

luzr wrote on Fri, 18 September 2009 06:55



You have to use host platform API (Win32).

I guess this one is what you need:

http://msdn.microsoft.com/en-us/library/ms646309%28VS.85%29. aspx?ppud=4

Then put GetHWND of some of your TopWindows in there and override

virtual LRESULT Ctrl::WindowProc(UINT message, WPARAM wParam, LPARAM lParam);


(Do not forget to call TopWindow::WindowProc at the end).

Mirek


I'm interested in global(system)keyboard too.
but in linux how it can be realized? Is the standard method?
For X11 I found here:
int XGrabKey(Display *display, int keycode, unsigned int
modifiers, Window grab_window, Bool owner_events, int pointer_mode, int keyboard_mode);
int XUngrabKey(Display *display, int keycode, unsigned int
modifiers, Window grab_window);

Maybe it is time to add cross method in u++?

[Updated on: Fri, 18 September 2009 08:10]

Report message to a moderator

Re: How to set a global (system) keyboard hook? [message #23146 is a reply to message #23135] Fri, 18 September 2009 16:03 Go to previous messageGo to next message
tojocky is currently offline  tojocky
Messages: 607
Registered: April 2008
Location: UK
Contributor

About global hotkey!

FOR WIN32:

acourding by simple example from

http://msdn.microsoft.com/en-us/library/ms646309(VS.85).aspx?ppud=4

first we need to register hot key by calling:
BOOL RegisterHotKey(      
    HWND hWnd,
    int id,
    UINT fsModifiers,
    UINT vk
);


and in U++ is already created a thread that execute function DWORD WINAPI Ctrl::Win32OverwatchThread(LPVOID). In this function is:
DWORD WINAPI Ctrl::Win32OverwatchThread(LPVOID)
{
    ............
	MSG Msg;
=>>HERE	while(GetMessage(&Msg, NULL, 0, 0) > 0) {
        TranslateMessage(&Msg);
==>>HERE we can process our keyboard event
	if(IsWindowUnicode(Msg.hwnd))
		DispatchMessageW(&Msg); // send to aprpopiate phread
	else
		DispatchMessage(&Msg);
    }
   .....................
}


The problem is that I do not get keycode property from Msg. From where can I get it?

for linux X11:

acording by documentation from:
1. http://www.xfree.org/current/XGrabKey.3.html#toc2

The simple code like this:
Window root;
XEvent ev;
    
Display * dpy = XOpenDisplay(0);

if(!dpy) return 1;

root = DefaultRootWindow(dpy);


char * key_string = "F3";

KeyCode key = XKeysymToKeycode(dpy, XStringToKeysym(key_string));

XGrabKey(dpy, key , AnyModifier, root,
    True, GrabModeAsync, GrabModeAsync);

for(;;)
{
	XNextEvent(dpy, &ev);
	if(ev.type == KeyPress && ev.xkey.keycode == key){
==>> Do our action
	}
}


First we need register global hotkey by calling:
nt XGrabKey(Display *display, int keycode, unsigned int
modifiers, Window grab_window, Bool owner_events, int pointer_mode, int keyboard_mode);


In u++ we can get message from void Ctrl::EventLoop0(Ctrl *ctrl)

which call void Ctrl::ProcessEvent(XEvent *event)

The good news is that I have keycode from the returned message. like this "ev.xkey.keycode".

The Question:

2. Is possible to add in u++ cros-os method for register global hotkey event?

For first I propouse like this:

static bool Ctrl::AddGlobalHotkey(Key p_key, callback 
p_func)


2. If is possible for register global hotkey event, maybe it is possible to unregister global hotkey event.

Maybe I was not understandable.

UPDATE:

Fro linux I found interesting example:
void
xstuff_grab_key_on_all_screens (int      keycode,
				guint    modifiers,
				gboolean grab)
	
{
	GdkDisplay *display;
	int         n_screens;
	int         i;

	display   = gdk_display_get_default ();
	n_screens = gdk_display_get_n_screens (display);

	for (i = 0; i < n_screens; i++) {
		GdkWindow *root;

		root = gdk_screen_get_root_window (
				gdk_display_get_screen (display, i));

		if (grab)
			XGrabKey (gdk_x11_display_get_xdisplay (display),
				  keycode, modifiers,
				  gdk_x11_drawable_get_xid (root),
				  True, GrabModeAsync, GrabModeAsync);
		else
			XUngrabKey (gdk_x11_display_get_xdisplay (display),
				    keycode, modifiers,
				    gdk_x11_drawable_get_xid (root));
	}
}


UPDATE 2:

Good news is for win32 too. It returns keycode in Mgs->lParam.


Ion Lupascu (tojocky).

[Updated on: Fri, 18 September 2009 17:05]

Report message to a moderator

Re: How to set a global (system) keyboard hook? [message #23158 is a reply to message #23146] Sun, 20 September 2009 09:18 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 14112
Registered: November 2005
Ultimate Member
Good work tojocky.

Mirek
Re: How to set a global (system) keyboard hook? [message #23194 is a reply to message #23158] Thu, 24 September 2009 23:05 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 14112
Registered: November 2005
Ultimate Member
Implemented.

See reference/HotKey

Mirek
Re: How to set a global (system) keyboard hook? [message #23196 is a reply to message #23194] Fri, 25 September 2009 09:55 Go to previous messageGo to next message
tojocky is currently offline  tojocky
Messages: 607
Registered: April 2008
Location: UK
Contributor

luzr wrote on Fri, 25 September 2009 00:05

Implemented.

See reference/HotKey

Mirek


VERY NICE!

TESTED FOR WIN32 XP SP3 AND UBUNTU 9.04

BUT:

fro UBUNTU when I try to hint key: Ctrl + Alt + F11 then my gnome resets.
May be it is reserved hotkey for gnome?

I have another question: how can I hint CTRL+C+C?
I can do this when i get double CTRL+C CTRL+C and verifing interval from it to not be greater than 1 second.

Thank you Mirek, great job!

[Updated on: Fri, 25 September 2009 10:03]

Report message to a moderator

Re: How to set a global (system) keyboard hook? [message #23199 is a reply to message #23132] Fri, 25 September 2009 11:21 Go to previous messageGo to next message
cocob is currently offline  cocob
Messages: 156
Registered: January 2008
Experienced Member
With X11 ctrl+alt+F.. is reserved for terminal switching, usually F1,F2,F3,... are text terminals and F7 is the graphical one.

cocob
Re: How to set a global (system) keyboard hook? [message #23230 is a reply to message #23199] Thu, 01 October 2009 14:11 Go to previous messageGo to next message
tojocky is currently offline  tojocky
Messages: 607
Registered: April 2008
Location: UK
Contributor

Hello Mirek!

I found the interesting situation about Global Hotekey:

I want to register global hotkey for Ctrl+C+C and get from clickboard copied data.
I did so:
1. Register system hotkey Ctrl+C
TranslateHotKeyId = Ctrl::RegisterSystemHotKey(K_CTRL_C, THISBACK(GlobalShortCutHandle));

2. in my callback I wrote:

void GoogleTranslatorDemo::GlobalShortCutHandle(){
	if(!AtomicRead(test_test)){
		AtomicWrite(test_test,1);
		
		bool need_translate = false;
		
		if(shortcut_stage==0){
			shortcut_stage = 1; // first Ctrl+C
			time_stop_shortcut.Reset();
		}
		else if (time_stop_shortcut.Elapsed()<600){
			need_translate = true;
			shortcut_stage = 0;
		}
		else {
			shortcut_stage = 1; // first Ctrl+C
			time_stop_shortcut.Reset();
		}
		
		if(need_translate){
			WString cur_text = ReadClipboardUnicodeText();
			
			if(cur_text.GetLength()){
				inputwindow.textedit.Set(cur_text);
				TranslateTextInBaloon();
			}
		}
		AtomicWrite(test_test,0);
	}
}

On the second press Ctrl+C start translating.

The problem:
When I press Ctrl+C from the other application the standard command (copy text) do not react. In other words did not coping the selected text.

How can I do this?

[Updated on: Thu, 01 October 2009 14:12]

Report message to a moderator

Re: How to set a global (system) keyboard hook? [message #23231 is a reply to message #23230] Thu, 01 October 2009 20:55 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 14112
Registered: November 2005
Ultimate Member
tojocky wrote on Thu, 01 October 2009 08:11

Hello Mirek!

I found the interesting situation about Global Hotekey:

I want to register global hotkey for Ctrl+C+C and get from clickboard copied data.
I did so:
1. Register system hotkey Ctrl+C
TranslateHotKeyId = Ctrl::RegisterSystemHotKey(K_CTRL_C, THISBACK(GlobalShortCutHandle));

2. in my callback I wrote:

void GoogleTranslatorDemo::GlobalShortCutHandle(){
	if(!AtomicRead(test_test)){
		AtomicWrite(test_test,1);
		
		bool need_translate = false;
		
		if(shortcut_stage==0){
			shortcut_stage = 1; // first Ctrl+C
			time_stop_shortcut.Reset();
		}
		else if (time_stop_shortcut.Elapsed()<600){
			need_translate = true;
			shortcut_stage = 0;
		}
		else {
			shortcut_stage = 1; // first Ctrl+C
			time_stop_shortcut.Reset();
		}
		
		if(need_translate){
			WString cur_text = ReadClipboardUnicodeText();
			
			if(cur_text.GetLength()){
				inputwindow.textedit.Set(cur_text);
				TranslateTextInBaloon();
			}
		}
		AtomicWrite(test_test,0);
	}
}

On the second press Ctrl+C start translating.

The problem:
When I press Ctrl+C from the other application the standard command (copy text) do not react. In other words did not coping the selected text.

How can I do this?


This cannot work. Once you register system hotkey, it gets "captured" by your application - that is the feature of both win32 and X11.

I suggest to use a little bit more exotic combos, like K_ALT|K_CTRL|K_SHIFT|K_C.

Mirek
Re: How to set a global (system) keyboard hook? [message #23235 is a reply to message #23231] Fri, 02 October 2009 08:03 Go to previous messageGo to next message
tojocky is currently offline  tojocky
Messages: 607
Registered: April 2008
Location: UK
Contributor

luzr wrote on Thu, 01 October 2009 21:55



This cannot work. Once you register system hotkey, it gets "captured" by your application - that is the feature of both win32 and X11.

I suggest to use a little bit more exotic combos, like K_ALT|K_CTRL|K_SHIFT|K_C.

Mirek


First Ctrl+C I need for copy in clipboard and the second Ctrl+C for processing copied text from clipboard (in my case is process translating).

Question:

Is not possible the given message to send follow to the other application?
Re: How to set a global (system) keyboard hook? [message #23237 is a reply to message #23235] Fri, 02 October 2009 10:06 Go to previous message
mirek is currently offline  mirek
Messages: 14112
Registered: November 2005
Ultimate Member
tojocky wrote on Fri, 02 October 2009 02:03

luzr wrote on Thu, 01 October 2009 21:55



This cannot work. Once you register system hotkey, it gets "captured" by your application - that is the feature of both win32 and X11.

I suggest to use a little bit more exotic combos, like K_ALT|K_CTRL|K_SHIFT|K_C.

Mirek


First Ctrl+C I need for copy in clipboard and the second Ctrl+C for processing copied text from clipboard (in my case is process translating).

Question:

Is not possible the given message to send follow to the other application?



AFAIK, no.

Mirek
Previous Topic: Segfaults with One container?
Next Topic: Add maximize and reduce to icon
Goto Forum:
  


Current Time: Sun Nov 10 20:41:56 CET 2024

Total time taken to generate the page: 0.02687 seconds