I've got a C# console application with some pieces of text that represent buttons so for example it looks like this [ D ][ E ][ F ][ G ]
When the user presses the button I want the button to be highlighted which is no problem as what im currently doing is rewriting over the button with Console.BackgroundColor set.
What I want to do is that they key be constantly highlighted while the key is held down but as soon as the key is lifted again the highlighting to be removed, if possible i'd also like multiple keys to be pressed at the same time. This is what I can't figure out how to do?
Hope that makes sense :)
Any help?
Thanks
If you are willing to add a reference to Windows.Forms, call Application.Run() to run a message queue, and call external Windows DLLs, you can do it using this code: http://blogs.msdn.com/b/toub/archive/2006/05/03/589423.aspx
That page will show you how to hook the low-level key-down keyboard event.
To also hook key-up keyboard events, you'll need to add a WM_KEYUP constant:
private const int WM_KEYDOWN = 0x0100;
private const int WM_KEYUP = 0x0101;
And then modify the HookCallback method:
private static IntPtr HookCallback(
int nCode, IntPtr wParam, IntPtr lParam)
{
if (nCode >= 0 && wParam == (IntPtr)WM_KEYDOWN)
{
int vkCode = Marshal.ReadInt32(lParam);
Console.WriteLine("Down:" + (Keys)vkCode);
}
else if (nCode >= 0 && wParam == (IntPtr)WM_KEYUP)
{
int vkCode = Marshal.ReadInt32(lParam);
Console.WriteLine("Up:" + (Keys)vkCode);
}
return CallNextHookEx(_hookID, nCode, wParam, lParam);
}
That will give you "Up" and "Down" messages for every key press. From there you should be able to incorporate it into your app.
Good luck!
Sorry but Console App only has Keyboard event (that too not actually an event unless you are in a loop and check for keypress) No KeyDown. keyPress or KeyUp events. It has no events of the GUI world.
I'm afraid AFAIK that a Console app can't detect multiple simultaneous key presses (that aren't modifier keys such as shift, or ctrl) so that isn't going to work.
With regard to highlighting a key as long as it is pressed you need to have your Console.ReadKey in a loop. Something like the following (you need to implement RemoveHighlight and HighlightKey methods yourself):
ConsoleKeyInfo currentKeyPressed;
ConsoleKeyInfo lastKeyPressed;
do
{
currentKeyPressed = Console.ReadKey();
if (lastKeyPressed.Key == currentKeyPressed.Key)
continue;
RemoveHighlight();
HighlightKey(keyPressed.Key);
lastKeyPressed = currentKeyPressed;
} while ((keyPressed.Key & ConsoleKey.Escape) != ConsoleKey.Escape);
Related
I have tried to make a global mousehotkey with SetWindowsHookEx() so when I press the right mouse button it executes some code. My problem is that when the callback function gets executed, it gives me a weird number for the right button that keeps changing everytime the code gets executed.
private static IntPtr ButtonHookCallback(int nCode, IntPtr wParam, IntPtr lParam)
{
int button = Marshal.ReadInt32(lParam);
if (nCode >= 0 && wParam == (IntPtr)WM_RBUTTONDOWN)
{
if (button == 0x02)
{
_m.rtbLog.AppendText("Test");
}
}
return CallNextHookEx(MainWindow._hookId, nCode, wParam, lParam);
}
When I read lParam it gives me like a number around 600 and changes everytime the code gets executed even though it should be 0x2.
How can I fix this :P.
EDIT: It works perfectly when I do it with keys
0x02 means WM_MOUSEMOVE, which should come from wParam rather lParam. The lParam means MOUSEHOOKSTRUCT, which will frequently change as for containing x- and y-coordinates of the cursor. Just refer to [MouseProc callback function][1] and [MOUSEHOOKSTRUCT structure][2]
[1] https://msdn.microsoft.com/en-us/library/windows/desktop/ms644988(v=vs.85).aspx
[2] https://msdn.microsoft.com/en-us/library/windows/desktop/ms644968(v=vs.85).aspx
Blockquote
Need some help with CustomUI in Word add-in.
I have a
<combobox />
in my custom ui.
How can I handle Enter pressing by user ?
I need to perform some actions when user presses Enter in that ComboBox.
Can I add KeyDown event somehow or maybe cast IRibbonControl to something useful?
UPDATE :
Made decision not to include that functionality. But still interested in solution for that problem.
Even WindowSelectionChange event wont help you. It works for other Key press but not for Enter and Backspace (As I am aware of).
You have to use low level keyboard hook
EDITED**
There is a callback when any of the key been pressed it will be called.
private static IntPtr HookCallback(
int nCode, IntPtr wParam, IntPtr lParam)
{
if (nCode >= 0 && wParam == (IntPtr) WM_KEYDOWN)
{
int vkCode = Marshal.ReadInt32(lParam);
//Check if the enter key is pressed
if (vkCode == (int) Keys.Enter )
// Do here whatever you need
}
return CallNextHookEx(_hookID, nCode, wParam, lParam);
}
I need to capture a keypress sequence from a Windows Mobile device to trigger a duress event. If my application was the only thing running I would use a base form event handler to check the keypress BUT... as the application could launch a browser and also uses SOTI, it must also work outside of the main application.
Is it possible to create a TSR application on a Windows Mobile device that can send web service messages (whilst in comms)?
I have written several keyboard hook 'applications' that invoke different functions. You can also use that to do socket or webservice calls: http://www.hjgode.de/wp/?s=hook and http://www.hjgode.de/wp/?s=keytoggle
// The command below tells the OS that this EXE has an export function so we can use the global hook without a DLL
__declspec(dllexport) LRESULT CALLBACK g_LLKeyboardHookCallback(
int nCode, // The hook code
WPARAM wParam, // The window message (WM_KEYUP, WM_KEYDOWN, etc.)
LPARAM lParam // A pointer to a struct with information about the pressed key
)
{
/* typedef struct {
DWORD vkCode;
DWORD scanCode;
DWORD flags;
DWORD time;
ULONG_PTR dwExtraInfo;
} KBDLLHOOKSTRUCT, *PKBDLLHOOKSTRUCT;*/
// Get out of hooks ASAP; no modal dialogs or CPU-intensive processes!
// UI code really should be elsewhere, but this is just a test/prototype app
// In my limited testing, HC_ACTION is the only value nCode is ever set to in CE
static int iActOn = HC_ACTION;
static bool isShifted=false;
#ifdef DEBUG
static TCHAR str[MAX_PATH];
#endif
PKBDLLHOOKSTRUCT pkbhData = (PKBDLLHOOKSTRUCT)lParam;
//DWORD vKey;
if (nCode == iActOn)
{
//only process unflagged keys
if (pkbhData->flags != 0x00)
return CallNextHookEx(g_hInstalledLLKBDhook, nCode, wParam, lParam);
//check vkCode against forbidden key list
if(pForbiddenKeyList!=NULL)
{
BOOL bForbidden=false;
int j=0;
do{
if(pForbiddenKeyList[j]==(BYTE)pkbhData->vkCode)
{
bForbidden=true;
DEBUGMSG(1, (L"suppressing forbidden key: 0x%0x\n",pkbhData->vkCode));
continue;
}
j++;
}while(!bForbidden && pForbiddenKeyList[j]!=0x00);
if(bForbidden){
return true;
}
}
SHORT sShifted = GetAsyncKeyState(VK_SHIFT);
if((sShifted & 0x800) == 0x800)
isShifted = true;
else
isShifted = false;
//check and toggle for Shft Key
//do not process shift key
if (pkbhData->vkCode == VK_SHIFT){
DEBUGMSG(1, (L"Ignoring VK_SHIFT\n"));
return CallNextHookEx(g_hInstalledLLKBDhook, nCode, wParam, lParam);
}
//################################################################
//check if the actual key is a match key including the shift state
if ((byte)pkbhData->vkCode == (byte)szVKeySeq[iMatched]){
DEBUGMSG(1 , (L"==== char match\n"));
if (bCharShiftSeq[iMatched] == isShifted){
DEBUGMSG(1 , (L"==== shift match\n"));
}
else{
DEBUGMSG(1 , (L"==== shift not match\n"));
}
}
if( wParam == WM_KEYUP ){
DEBUGMSG(1, (L"---> szVKeySeq[iMatched] = 0x%02x\n", (byte)szVKeySeq[iMatched]));
if ( ((byte)pkbhData->vkCode == (byte)szVKeySeq[iMatched]) && (isShifted == bCharShiftSeq[iMatched]) ) {
//the first match?
if(iMatched==0){
//start the timer and lit the LED
LedOn(LEDid,1);
tID=SetTimer(NULL, 0, matchTimeout, (TIMERPROC)Timer2Proc);
}
iMatched++;
DEBUGMSG(1, (L"iMatched is now=%i\n", iMatched));
//are all keys matched
if (iMatched == iKeyCount){
//show modeless dialog
DEBUGMSG(1, (L"FULL MATCH, starting ...\n"));
PostMessage(g_hWnd, WM_SHOWMYDIALOG, 0, 0);
//reset match pos and stop timer
DEBUGMSG(1, (L"FULL MATCH: Reset matching\n"));
LedOn(LEDid,0);
iMatched=0; //reset match pos
KillTimer(NULL, tID);
//return CallNextHookEx(g_hInstalledLLKBDhook, nCode, wParam, lParam);
}
//return -1; //do not forward key?
}
else
{
KillTimer(NULL, tID);
LedOn(LEDid,0);
iMatched=0; //reset match pos
DEBUGMSG(1, (L"FULL MATCH missed. Reseting matching\n"));
}
} //if wParam == WM_KEY..
}
return CallNextHookEx(g_hInstalledLLKBDhook, nCode, wParam, lParam);
}
Looking for a hook example that looks for a key sequence: http://code.google.com/p/keytoggleboot/source/browse/trunk/KeyToggleBoot/ReadMe.txt?spec=svn14&r=14
There are also articles and posts about keyboard hooks in the internet (ie at codeproject).
I recently needed to get a key code from a handheld device and I just created an empty project with 1 textbox, included the following file and add this bit of code:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
HookKeys x = new HookKeys();
x.Start();
x.HookEvent += new HookKeys.HookEventHandler(HookEvent);
}
private void HookEvent(HookEventArgs e, KeyBoardInfo keyBoardInfo)
{
textBox1.Text = "vkCode = " + keyBoardInfo.vkCode + Environment.NewLine + textBox1.Text;
}
}
Worked for a windows mobile 6.5 professional
I am attempting to process the windows messages for keyboard events and pass them into an awesomium webview. The webview has native handling for windows events, but the host program must capture them, and send them on.
I am using .net and the com interop to capture and send on the messages. The key events are passed on to the best of my knowledge, but the input is variable. For example, there are varying numbers of characters being entered in a text box for a single press.
Here is a sample of the code I am using (credit to Sekhat on the awesomium site) :
private void CreateHook()
{
uint threadId = Win32.GetWindowThreadProcessId(hWnd, IntPtr.Zero);
//hHook = Win32.SetWindowsHookEx(Win32.HookType.WH_CALLWNDPROC, wndProcDelegate, IntPtr.Zero, threadId);
hHook = Win32.SetWindowsHookEx(Win32.HookType.WH_GETMESSAGE, wndProcDelegate, IntPtr.Zero, threadId);
}
private int WndProcHook(int nCode, IntPtr wParam, ref Win32.Message lParam)
{
if (nCode >= 0)
{
Win32.TranslateMessage(ref lParam);
WndProc(ref lParam);
}
return Win32.CallNextHookEx(hHook, nCode, wParam, ref lParam);
}
wndProcDelegate = WndProcHook;
Am I handling the events wrong, leading to the variable number of inputs? I beleive the relevant parts are above, but can post the rest if needed.
On a side note, when I use WH_KEYBOARD instead of WH_GETMESSAGE an AccessViolationException is thrown. Is the KEYBOARD event the right one to use? Thank you for any assistance.
EDIT: I have done some further investigation and discovered that multiple messages of type 0x102 (WM_CHAR) are being passed to my program. The number passed matches the number of characters that awesomium is then outputting. Should I limit this to only the first message? While this may work, I would still like to know why this is happening.
I have managed to devise a working fix:
if (message.msg == 256)
{
accept = true;
}
if (accept && message.msg == 258)
{
view.InjectKeyboardEventWin((int)message.msg, (int)message.wparam, (int)message.lparam);
accept = false;
}
if (message.msg != 258)
{
view.InjectKeyboardEventWin((int)message.msg, (int)message.wparam, (int)message.lparam);
}
This code checks for a key down, and if found, set accept to true. The char message is only processed if a key down has been received since the last one. This allows text entry, while preserving other messages. I am still interested in discovering the root cause however.
I'm creating a custom keyboard layout. As the beginning step, I want to have the user press a key, have my keyboard hook intercept it, and output a different key of my choosing.
I found this keyboard hook code, which I'm trying to slightly modify for my purposes:
http://blogs.msdn.com/toub/archive/2006/05/03/589423.aspx
I've changed the relevant method to this:
private static IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam)
{
if (nCode >= 0 && wParam == (IntPtr)WM_KEYDOWN)
{
KBDLLHOOKSTRUCT replacementKey = new KBDLLHOOKSTRUCT();
Marshal.PtrToStructure(lParam, replacementKey);
replacementKey.vkCode = 90; // char 'Z'
Marshal.StructureToPtr(replacementKey, lParam, true);
}
return CallNextHookEx(_hookID, nCode, wParam, lParam);
}
I want it to declare a new KBD structure object, copy the KBD structure supplied by the keyboard hook into it, modify my object's vkCode to use a different character, and then overwrite the supplied object with my modified version. This should hopefully keep everything the same except for the fact that it writes a different character.
Unfortunately, it's not working. The original keyboard character is typed. The Visual Studio output pane also gets a A first chance exception of type 'System.ArgumentException' occurred in MirrorBoard.exe error.
What can I do here to intercept the keyboard hook and replace it with a character of my choosing?
Thanks!
The second parameter for Marshal.PtrToStructure must be a class not a struct and KBDLLHOOKSTRUCT is probably a struct.
Instead you should use it like this:
KBDLLHOOKSTRUCT replacementKey = (KBDLLHOOKSTRUCT)Marshal.PtrToStructure(lParam, typeof(KBDLLHOOKSTRUCT));
replacementKey.vkCode = 90; // char 'Z'
Marshal.StructureToPtr(replacementKey, lParam, false);