c++ ReadConsoleInput and context menu.

Home built / K9a2 cf-f
September 13, 2009 at 02:51:02
Specs: Windows XP, Athlon xp x2 64 5600 / 2gb
I'm using dev-cpp 4.9.9.2 with the standard compiler.

I have truged along and finally written my first c++ program, a very simple windows 2000 and up console label printing program. Now I'm basically at the stage of fixing the last couple of issues, but I'm a bit stuck.

The first issue is that the whole program revolves around ReadConsoleInput and it works fine except I want to attach the standard console(non quick edit) context menu (mark, edit, paste, ect) to right clicks.

Since I'm using ReadConsoleInput it's catching right clicks and the menu doesn't appear, I have tried WriteConsoleInput with the right click event record but ReadConsoleInput catches it again(it's enclosed in a while loop) and causes an infinite loop.

The second issue is that since the program is linked to functions introduced in windows 2000 I want to find a way to gracefully exit on prior versions of windows. I have tried VerifyVersionInfo to no avail(probably because it's also a win2000 function). Even still on testing on windows 98 it didn't even get a chance to execute before a dialogue warned that it was linked to GetConsoleWindow.

The third and final issue I'm having is a focus issue on a GetOpenFileName dialogue, I am already passing the console window handle to the dialogue, but still it's out of focus the first time it is called after program start.


Any help or insight on these issue will be much appreciated. Here is a link to the whole project(spoiler: Over 3000 lines of noob un-commented code) including an executable.

If anyone happens to test it on non XP(and 2000 or above) systems I would be happy to here if it runs or if there are any problems.


See More: c++ ReadConsoleInput and context menu.

Report •


#1
September 14, 2009 at 05:45:43
This is about Win32 api : you can see on Win32 api ng http://tinyurl.com/cmhb5g (C/Win32, MS)

Report •

#2
September 14, 2009 at 06:40:05
Thanks for the link, I might go and post over there in a week or so when this thread is well and truly dead.

I'm starting to think I'll just leave things as the are, works perfectly fine as is, no need for huge amounts of coping/pasting and can use the nested menus if needed. The file dialog won't be used much and it looks as though older versions of windows already refuse to run it(albeit it isn't a graceful exit).

Thanks to anyone that gave it a look into.


Report •

#3
September 18, 2009 at 15:30:32
Problem 2: You want to use dynamic/run-time DLL loading. It's messy to do, but there are plenty of C++ object wrappers out there.

Problem 1 & 3: I think your main problem is that you're trying to mix Win32 GUI and the Console in ways MS never intended. This sounds like a non-solution to me, so if you do figure out how to get the popup menu working, let me know.


Report •

Related Solutions

#4
September 18, 2009 at 16:43:55
Thanks for the input Razor.

I guess you right about mixing console/gui. I'll look into dynamic
dll loading, but at this stage I doubt I'll implement it in this project.

I have found a solution to #1 #3 all that was needed was a
simple hook procedure for GetOpenFileName:

UINT_PTR CALLBACK OFNHookProc(HWND hdlg, UINT uiMsg, WPARAM wParam, LPARAM lParam)
{
    SetForegroundWindow(hdlg);
    return 0;
}

I think that #3 may have something to do with the semi-documented
MENU_EVENT_RECORD, but still have to look into it further.
It seems to me that some of the components in the event record
are dual purpose as I noticed what seemed to be screen coordinates
(not console coordinates).


Report •

#5
September 24, 2009 at 16:51:14
I found a way to make it work!!

WriteConsoleInput was indeed the way to go, I just needed to
use SetConsoleMode to disable mouse input first. I have only just
started playing with it and it's a little unreliable at present (takes
a long right click to work) but it is something that I should be able
to fix. Here is a code snippet:

if (human.Event.MouseEvent.dwButtonState == RIGHTMOST_BUTTON_PRESSED)
{
    SetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), 0x0020|0x0080);
    WriteConsoleInput(GetStdHandle(STD_INPUT_HANDLE), &human, 1, &input);
    human.Event.KeyEvent.bKeyDown = 0;
    WriteConsoleInput(GetStdHandle(STD_INPUT_HANDLE), &human, 1, &input);
    SetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), 0x0020|0x0080|0x0010);
    continue;
}


Report •

#6
September 24, 2009 at 18:10:47
This is what I have ended up with, it's not the best because it assumes
that bring up the menu will throw back 3 events, if there is a better way
I'd like to hear it:

 if (human.Event.MouseEvent.dwButtonState == RIGHTMOST_BUTTON_PRESSED)
 {
     SetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), 0x0020|0x0080);
    FlushConsoleInputBuffer(GetStdHandle(STD_INPUT_HANDLE));
     WriteConsoleInput(GetStdHandle(STD_INPUT_HANDLE), &human, 1, &input);
     human.Event.KeyEvent.bKeyDown = 0;
     human.Event.KeyEvent.wRepeatCount = 0;
     WriteConsoleInput(GetStdHandle(STD_INPUT_HANDLE), &human, 1, &input);
     human.Event.KeyEvent.dwControlKeyState = 1;
     human.Event.MouseEvent.dwEventFlags = 1;
     WriteConsoleInput(GetStdHandle(STD_INPUT_HANDLE), &human, 1, &input);
     for (int a=0; a<4; a++) { 
         ReadConsoleInput(GetStdHandle(STD_INPUT_HANDLE), &human, 1, &input);
     }
     FlushConsoleInputBuffer(GetStdHandle(STD_INPUT_HANDLE));
     SetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), 0x0020|0x0080|0x0010);
     continue;
 }


Report •


Ask Question