Mombu the Microsoft Forum sponsored links

Go Back   Mombu the Microsoft Forum > Microsoft > WINDOWS PROGRAMMING (NNTP) > Reading ALT keys in a Win32 console application. How
User Name
Password
REGISTER NOW! Mark Forums Read

sponsored links


Reply
 
1 11th July 15:37
peter c chapin
External User
 
Posts: 1
Default Reading ALT keys in a Win32 console application. How


Hello everyone.

I'm in the process of porting an old MS-DOS program to Win32. I'm not
trying to change the look and feel of the program and thus I'm leaving
it as a console mode application.

The program uses getch() to get keystrokes from the input and it uses
certain "ALT" key combinations as commands. For example ALT+X is used to
exit the program. There are quite a few commands bound to ALT keys so
I'm not inclined to want to change that. However, the getch() function
in VC++'s library (I'm using the new VC++ v8) doesn't appear to
acknowledge the ALT key combinations.

able to use getch() to read function keys, PgUp, PgDn, arrow keys, and
so forth. It only appears to be the ALT keys that are a problem.

I'm thinking that maybe there some console API function I need to call
first to "turn on" the ALT key handling. However, I don't see anything
like that in the docs I've looked at so far.

Thoughts?

Peter
  Reply With Quote


  sponsored links


2 11th July 15:37
tc
External User
 
Posts: 1
Default Reading ALT keys in a Win32 console application. How


A google groups search on "alt getch" (without the quotes) gives lots
of likely-looking hits. Have you checked those?

HTH,
TC
  Reply With Quote
3 11th July 15:37
peter c chapin
External User
 
Posts: 1
Default Reading ALT keys in a Win32 console application. How


I did do some Google searching, yes. Although I didn't try that
particular query. The hits I saw in response to "alt getch" seem to
mostly pertain to the curses library under Unix. In that environment
ALT+A returns the two character sequence ESC followed by 'a'. Win32 does
not appear to do this, based on the behavior of my sample program.

The getch() function returns special keys as two character sequences
(getch() must be called twice) with the first character either 0x00 or
0xE0 depending on the special key. Yet when I press 'ALT+letter' there
is an immediate return of the letter's ASCII code; no prefix byte is
provided. In other words 'ALT+letter' seems indistinguishable from just
'letter'.

Peter
  Reply With Quote
4 11th July 15:37
tc
External User
 
Posts: 1
Default Reading ALT keys in a Win32 console application. How


Then try again with: "alt getch win32" (without the quotes). This
gives at least one thread where they discuss your problem.
Unfortunately, they did not seem to have a solution. But I did not
check every thread returned by that search, so you should still do
that.

HTH,
TC
  Reply With Quote
5 11th July 15:37
james brown dont_bother
External User
 
Posts: 1
Default Reading ALT keys in a Win32 console application. How


I did not read the google'd thread in question. However, one possible
solution:

install a low-level keyboard hook and monitor keypresses for
your particular console window. This *will* work - you can get pretty
much any key combinations you want with a "low level" hook.

A console program can install this one variety of hook "locally" without
requiring a separate DLL. But you must use a separate thread which
acts as a "message pump" otherwise your console app will lock up:

e.g. install the hook from your "main" thread:

//
// LowLevel keyboard hook demo for console apps
//
// JBrown 21/11/2005
// http://www.catch22.net // #define _WIN32_WINNT 0x500
#include <windows.h>
#include <stdio.h>

DWORD CALLBACK KeyboardThread(PVOID param);
LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM
lParam);

HHOOK g_hKeyboardHook;
HWND g_hConsoleWnd;
DWORD g_nKBHookThreadId;
HANDLE g_hKBHookThread;

// install LowLevel keyboard hook
void InstallKBHook()
{
g_hConsoleWnd = GetConsoleWindow();
g_hKBHookThread = CreateThread(0, 0, KeyboardThread, 0, 0,
&g_nKBHookThreadId);
}

// remove the hook when app exits
void RemoveKBHook()
{
// tell hook thread to exit
PostThreadMessage(g_nKBHookThreadId, WM_QUIT, 0, 0);

WaitForSingleObject(g_hKBHookThread, INFINITE);
CloseHandle(g_hKBHookThread);
}

// your keyboard hook thread looks like this:
DWORD CALLBACK KeyboardThread(PVOID param)
{
MSG msg;

// set low-level keyboard hook
if(!IsDebuggerPresent())
{
// install the hook for *this* thread, even though it is a
systemwide/global hook
g_hKeyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardProc,
GetModuleHandle(0), 0);
}

// pump messages to stop console from locking up
while(GetMessage(&msg, 0, 0, 0) > 0)
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}

// remove the hook just before we exit
UnhookWindowsHookEx(g_hKeyboardHook);
return 0;
}

// Your hook function looks like this:
LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM
lParam)
{
if(nCode < 0)
{
return CallNextHookEx(g_hKeyboardHook, nCode, wParam, lParam);
}
else if(nCode == HC_ACTION)
{
KBDLLHOOKSTRUCT *kbhs = (KBDLLHOOKSTRUCT *)lParam;

// keypress data is in the "kbhs" structure
if(g_hConsoleWnd == GetForegroundWindow()) {
printf("virtual key = %d, scancode = %d\n", kbhs->vkCode,
kbhs->scanCode);

// look in "context code" flag to check if ALT is pressed
if(kbhs->flags & 0x20) {
if(kbhs->vkCode == (ULONG)VkKeyScan('x'))
{
printf("ALT+X\n");
}
}
// check for other control-keys
else if(0x8000 & GetAsyncKeyState(VK_CONTROL))
{
}
}
}
return CallNextHookEx(g_hKeyboardHook, nCode, wParam, lParam);
}


int main()
{
char buf[200];

InstallKBHook();

// do stuff
while(fgets(buf, 200, stdin))
{
}

RemoveKBHook();
return 0;
}


be very careful about debugging your hook-function. It is very easy to lock
up your system
doing this with a lowlevel keyboard hook - that's why I put the
"IsDebuggerPresent"
call in before installing the hook.

I've used this code many times and it works great - but requires Windows
2000
and above (or NT4 and above if you can create a suitable replacement for
the GetConsoleWindow API).

You will also need to decide how to "tell" your main application code about
your
keypresses that you are catching in the keyboard hook.....

James

--
http://www.catch22.net
Free win32 software, sourcecode and tutorials
  Reply With Quote
6 11th July 15:38
devnull@localhostld
External User
 
Posts: 1
Default Reading ALT keys in a Win32 console application. How


GetAsyncKeyState(VK_MENU);

To distinguish between letf/right alt adequatly VK_LMENU/VK_RMENU.
  Reply With Quote
7 11th July 15:38
peter c chapin
External User
 
Posts: 1
Default Reading ALT keys in a Win32 console application. How


Okay, thanks for the suggestion. I'll take a look at it, although I was
hoping to avoid such a low level approach since that makes more work in
my porting project.

It seems odd to me that the getch() in the VC++ library is compatible
with the ancient getch()s from MS-DOS days with respect to its handling
of function keys (including ALT+Fn combinations), arrow keys, etc, and
yet *not* compatible with respect to ALT+letter keys. It's hard to
imagine a rationale for introducing such an incompatibility. I could
understand it if the key combinations were being intercepted by Windows
for Windows commands, but that doesn't appear to be the case either.
They seem to be simply ignored (by getch() anyway).

Peter
  Reply With Quote
8 11th July 15:38
james brown dont_bother
External User
 
Posts: 1
Default Reading ALT keys in a Win32 console application. How


It's just the way Windows works - it uses the ALT key for itself such as
Menus, accelerators, shortcuts etc..

If you are already using getch then the GetAsyncKeyState(VK_MENU)
method mentioned in another post may be simpler...i.e. whenever you get
your 'x' key pressed just call GetAsyncKeyState to see if ALT is down
at the same time.

James

--
http://www.catch22.net
Free win32 software, sourcecode and tutorials
  Reply With Quote
9 11th July 15:38
peter c chapin
External User
 
Posts: 1
Default Reading ALT keys in a Win32 console application. How


Yes, I'll look at that too. Thanks (and to the other poster as well).
I'm not familiar with these API facilities and I want to understand them
better before I commit myself. In any case, it looks like a solution is
possible.

Peter
  Reply With Quote
10 11th July 15:38
scott moore
External User
 
Posts: 1
Default Reading ALT keys in a Win32 console application. How


You are trying to do this the hard way. Just use:

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/base/readconsole.asp

This gives you access to everything the keyboard can do. getch() is a Unix
compatible call.
  Reply With Quote
Reply


Thread Tools
Display Modes




Copyright 2006 SmartyDevil.com - Dies Mies Jeschet Boenedoesef Douvema Enitemaus -
666