|
Hello,
Thank you for posting this information and offering it for our consumption.
Do you have any terms of use for what you have provided here? I did see that it is mentioned that no explicit license has been identified for your contribution here.
Thank you,
-Chris
|
|
|
|
|
Hi Alexander,
I made an application with the hotkey CTRL + F10, I execute it, but when it is running don't power off or restart the computer.
If I close the application then yes the PC power off.
KrIEgSMaR
|
|
|
|
|
Vista beeps when the hotkey is pressed using this code. XP and Win2K3 don't beep and work fine.
|
|
|
|
|
Funny thing.. Microsoft really doesn't want you to make any WIN + shortcuts aside from their own. You see this because RegisterHotkey will allow you to put it in there, but if you wanted to do a realtime bind, the way I see it, you're stuck with their eventhandling API which does not treat LWIN and RWIN as modifiers.
|
|
|
|
|
The post "Update to RegisterHotKey method" is correct but has not been corrected in the posted code. Please correct.
Thanks.
John
|
|
|
|
|
I would like to see event KeyDown and KeyUp and change ShortCut to Keys cause Keys more powerful than ShortCut.
Thanks so much for this component.
|
|
|
|
|
I am working on my own version with Keys, but to comment on your other request... It's not possible using RegisterHotkey... you'd have to do a low level keyboard hook, which is slightly more of a pain in the neck.
|
|
|
|
|
I am trying to adapt the component to include support for {mod}+NumPad(0 through 9). I have done this before with GetAsyncKeyState, which used virtual keycodes. I have that listing, but even converting from the hex that they are declared in to an integer or long, the numbers do not come close.
The constants I have are here (declared in VB6 format):
Const VK_NUMPAD0 = &H60
Const VK_NUMPAD1 = &H61
Const VK_NUMPAD2 = &H62
Const VK_NUMPAD3 = &H63
Const VK_NUMPAD4 = &H64
Const VK_NUMPAD5 = &H65
Const VK_NUMPAD6 = &H66
Const VK_NUMPAD7 = &H67
Const VK_NUMPAD8 = &H68
Const VK_NUMPAD9 = &H69
Is there any way to adapt these to Shortcut type variables so I can register them?
|
|
|
|
|
hi!
Try the System.Windows.Forms.Keys enum.
|
|
|
|
|
How can you bind a key in realtime? I'm thinking of creating an interface so the user can choose what to use as a hotkey. Do I have to list every combination for the user and then have a case statement for each case and set the property to "System.Windows.Forms.Shortcut.XXXX"?
|
|
|
|
|
You could do that, or you could have your interface listen for the key presses. When a key is held down, have the key name appear in a textbox (Ctrl). If another key is held, while the last one is still being held, add its name to the textbox (Ctrl+A). This can go upto 4 keys (Ctrl+Alt+Shift+A), maybe 5 (Ctrl+Alt+Shift+Win+A; not sure why you would wan that many modifiers, or if that many modifiers is possible, or if the Win key is even allowed). Once the user has let go of the keys, the combination remains in the textbox, but if the user presses any keys again, the new combo is placed in the box. The textbox is for the user, while inside the app a variable is keeping track of the enumerated keys or'd together. This variable is what is used to set the hotkey.
---------------------------------------------------------------------------
Skoobie Du, programming and web developing since I was 12. ^_^ I might not be very good, but I don't care what you think.
|
|
|
|
|
Hi,
While this library can intercept any key as system hotkey, is it also
capable of performing the default functionality of the intercepted hotkey?
For example, CtrlC for copy to clipboard, it seems the data that's supposed
to go to clipboard is lost. Do you have any suggestion on how to retrieve
that data or do the default functionality of the key?
Thanks.
Carpe Diem!
|
|
|
|
|
In short, no. That data was never copied, so it couldn't get lost in the first place.
Hotkeys like Ctrl+C (Copy), Ctrl+V (Paste), Ctrl+X (Cut), Ctrl+A (Select All), etc. are standardized hotkeys, but their functionality are decided by the programmer(s). I could use Ctrl+C to close my application if I wanted to. So, to repeat, those hotkeys are not system-wide hotkeys (not defined by the system).
System-wide hotkeys include Ctrl+Print Screen (Copy Screen Capture to the Clipboard), Alt+Tab (Rotate Forward Through Open Windows), Win+R (Open Run Dialog), Print Screen (Screen Capture), Alt+Shift+Tab (Rotate Backward Through Open Windows), etc. These are registered by Windows, and cannot be used by any application (that I know of).
So, to do what you're wanting to do, you need to access the functions/methods that copy the data to the clipboard while in that application. The application that is intercepting the system-wide hotkey(s) is grabbing the messages before they get the data-holding application, so the data-holding application doesn't know that you want to copy the intended data. You would need to have the intercepting app "connect" to the data-holding app, and use the functions/methods it has defined to copy the intended data. Good luck.
---------------------------------------------------------------------------
Skoobie Du, programming and web developing since I was 12. ^_^ I might not be very good, but I don't care what you think.
|
|
|
|
|
Hi
As we know, the hotkey component remains active until the application is active. Now, if I create hotkeys for CtrlA, CtrlC and CtrlV, etc. in an application, then I cannot use the declared keys for other application, eg simulataneously working in WordDocument, etc.
Is it possible to build a functionality, such that whenever I change focus from the WinForm to some other application like MS Word, the hotkeys should get disabled. And as soon as I change the focus to .NET WinForm, the hotkeys defined gets enabled.
I tried following code -
private void Form1_Activated(object sender, System.EventArgs e)
{
this.hkText = new CodeProject.SystemHotkey.SystemHotkey(this.components);
}
private void Form1_Deactivate(object sender, System.EventArgs e)
{
this.hkText.Dispose();
}
This doesn't work because Form1_Deactivate always get fired after Form1_Activated And thus the key gets disposed.
I also tried wndProc method, but I am unable to get the right order of Form GetGocus and LostFocus type of events.
Please help me to find the solution as soon as possible.
Regards
AC
|
|
|
|
|
Hi,
you can also try to use the Enter/Leave events. But I think you don't really need a system-wide hotkey. You can use e.g. the shortcut property of a MenuItem.
|
|
|
|
|
Hi,
Thanks for immediate reply.
I tried Form1_Enter, Form1_Leave events, but it didn't work. I even tried
protected override void OnEnter and OnLeave, but in vain.
I am not using the hotkeys for menu items. Instead using it to focus on textbox, drop down list, checkbox or button click.
Hence, the shortcut is also not a solution. Please let me know any other solution, if possible.
|
|
|
|
|
Hey,
if any body is having the similar problem/requirement then please find the solution below.
Actually I was doing some mistake in the form activated and deactivate events.
Following code will work (hkText is the hotkey used)-
private void Form1_Activated(object sender, System.EventArgs e)
{
this.hkText.Dispose();
this.hkText = new CodeProject.SystemHotkey.SystemHotkey(this.components);
this.hkText.Shortcut = System.Windows.Forms.Shortcut.CtrlC;
this.hkText.Pressed += new System.EventHandler(this.hkText_Pressed);
}
private void Form1_Deactivate(object sender, System.EventArgs e)
{
this.hkText.Dispose();
}
|
|
|
|
|
Quick note, if I sound rude I apologize ahead of time.
You don't understand the purpose of a system-wide hotkey. The purpose of a system-wide hotkey, is to be able to use a hotkey regardless of which application has focus.
You want a localized hotkey, so use a hidden menu item. Assign the hotkey to the menu item, and use the menu item's clicked event to do what you want. Using a system-wide hotkey is beyond the scope of your application. I know that your message is two years old, but when I read it I thought you were an idiot, no offense.
Not all UI elements need to be visible to the user, so using a hidden menu item achieves what you want, without needing to make explicit calls to system-level functions, and needing to place needless menu items (if you're even using a menu).
(Noted system-level calls will be made, but it's through the Framework)
This may be late, but it could be useful to anybody running across this and trying the same thing.
---------------------------------------------------------------------------
Skoobie Du, programming and web developing since I was 12. ^_^ I might not be very good, but I don't care what you think.
|
|
|
|
|
Thanks! This helped me
|
|
|
|
|
Hi,
Nice article and class library.
I think that there is a problem with the RegisterHotKey method when there are multiple modifiers:
Keys k2=Keys.None;
if (((int)key & (int)Keys.Alt)==(int)Keys.Alt) {mod+=(int)Win32.Modifiers.MOD_ALT;k2=Keys.Alt;}
if (((int)key & (int)Keys.Shift)==(int)Keys.Shift) {mod+=(int)Win32.Modifiers.MOD_SHIFT;k2=Keys.Shift;}
if (((int)key & (int)Keys.Control)==(int)Keys.Control) {mod+=(int)Win32.Modifiers.MOD_CONTROL;k2=Keys.Control;}
Because you are doing k2=... and then using that in the following code:
((int)key)-((int)k2)
If there are multiple modifiers the key that is registered will be incorrect. Can i suggest this as an updated RegisterHotKey method which should handle multiple modifiers:
protected bool RegisterHotkey(Shortcut key)
{ //register hotkey
int mod=0;
Keys k2=Keys.None;
if (((int)key & (int)Keys.Alt)==(int)Keys.Alt)
{
mod |= (int)Win32.Modifiers.MOD_ALT;
k2 |= Keys.Alt;
}
if (((int)key & (int)Keys.Shift)==(int)Keys.Shift)
{
mod |= (int)Win32.Modifiers.MOD_SHIFT;
k2 |= Keys.Shift;
}
if (((int)key & (int)Keys.Control)==(int)Keys.Control)
{
mod |= (int)Win32.Modifiers.MOD_CONTROL;
k2 |= Keys.Control;
}
int nonModifiedKey = (int)key - (int)k2;
return Win32.User32.RegisterHotKey(m_Window.Handle,this.GetType().GetHashCode(),(int)mod, nonModifiedKey);
}
Kind regards,
Rick
|
|
|
|
|
I tried both implementation and they both works.
In Form1.cs
1) Add an instance instance of SystemHotkey.
private CodeProject.SystemHotkey.SystemHotkey systemHotkey1;
private CodeProject.SystemHotkey.SystemHotkey systemHotkey2;
Note : You can also copy and paste in the designer.
------------------------------------------------------------
2. Add an event handler for the new hotkey.
private void systemHotkey1_Pressed(object sender, System.EventArgs e)
{
label1.Text="Hotkey Pressed 1!";
this.Activate();
this.BringToFront();
}
private void systemHotkey2_Pressed(object sender, System.EventArgs e)
{
label1.Text="Hotkey Pressed 2!";
this.Activate();
this.BringToFront();
}
------------------------------------------------------------
3)Link with a second event handler in the method InitializeComponent()
...
// systemHotkey1
//
this.systemHotkey1.Shortcut = System.Windows.Forms.Shortcut.AltF6;
this.systemHotkey1.Pressed += new System.EventHandler(this.systemHotkey1_Pressed);
....
//
// systemHotkey2
//
this.systemHotkey2.Shortcut = System.Windows.Forms.Shortcut.AltF7;
this.systemHotkey2.Pressed += new System.EventHandler(this.systemHotkey2_Pressed);
------------------------------------------------------------
Thanks for the good article
|
|
|
|
|
there is also a new in the beginning on the initializeComponent.
...
systemHotkey1 = new CodeProject.SystemHotkey.SystemHotkey();
...
systemHotkey2 = new CodeProject.SystemHotkey.SystemHotkey();
...
|
|
|
|
|
also a note, the 'id' field of the RegisterHotkey API call is an id which will be returned by the WndMsg if pressed, by toying with that and giving multiple hotkeys different ids you can bind more than 1 hotkey per class
Parameters
hWnd
[in] Handle to the window that will receive WM_HOTKEY messages generated by the hot key. If this parameter is NULL, WM_HOTKEY messages are posted to the message queue of the calling thread and must be processed in the message loop.
id
[in] Specifies the identifier of the hot key. No other hot key in the calling thread should have the same identifier. An application must specify a value in the range 0x0000 through 0xBFFF. A shared dynamic-link library (DLL) must specify a value in the range 0xC000 through 0xFFFF (the range returned by the GlobalAddAtom function). To avoid conflicts with hot-key identifiers defined by other shared DLLs, a DLL should use the GlobalAddAtom function to obtain the hot-key identifier.
fsModifiers
[in] Specifies keys that must be pressed in combination with the key specified by the uVirtKey parameter in order to generate the WM_HOTKEY message. The fsModifiers parameter can be a combination of the following values.
MOD_ALT
Either ALT key must be held down.
MOD_CONTROL
Either CTRL key must be held down.
MOD_SHIFT
Either SHIFT key must be held down.
MOD_WIN
Either WINDOWS key was held down. These keys are labeled with the Microsoft Windows logo.
vk
[in] Specifies the virtual-key code of the hot key.
|
|
|
|
|
The original post is correct. He is referring to items like CntlShift1, etc. Where Cntl and Shift (or any other combination of keys are selected). In this case the posted code does not work.
I have fixed it in my copy, but posting the fix would be good.
John
|
|
|
|
|
Hello, you fixed this in your copy? How did you do it? I want to include the control, windows and some alphanumeric key combination as my hotkey (ctrl+Lwin+R). Thanks for your help!
I currently use the following, but would like to implement the ctrl+Lwin+(R,P,etc..):
private CodeProject.SystemHotkey.SystemHotkey systemHotkey1;
private CodeProject.SystemHotkey.SystemHotkey systemHotkey2;
private void InitializeComponent()
...
this.systemHotkey1 = new CodeProject.SystemHotkey.SystemHotkey(this.components);
this.systemHotkey2 = new CodeProject.SystemHotkey.SystemHotkey(this.components);
this.systemHotkey1.Shortcut = System.Windows.Forms.Shortcut.AltF6;
this.systemHotkey2.Shortcut = System.Windows.Forms.Shortcut.AltF7;
//this.systemHotkey2.Shortcut = System.Windows.Forms.Keys.LControlKey & System.Windows.Forms.Keys.LWin & System.Windows.Forms.Keys.R;
this.systemHotkey1.Pressed += new System.EventHandler(this.systemHotkey1_Pressed);
this.systemHotkey2.Pressed += new System.EventHandler(this.systemHotkey2_Pressed);
private void systemHotkey1_Pressed(object sender, System.EventArgs e)
{
this.Activate();
MessageBox.Show("Alt F6");
//label1.Text = "Hotkey Pressed";
//this.BringToFront();
}
private void systemHotkey2_Pressed(object sender, System.EventArgs e)
{
this.Activate();
MessageBox.Show("Alt F7");
//label1.Text = "Hotkey Pressed";
//this.BringToFront();
}
|
|
|
|
|