the message queue is present in any type of program or Unix is present only in programs written in Windows interface?
For example this programm:
int main()
{
short int n;
while(1)
{
if (n = GetKeyState(VK_UP))
{
cout << n;
}
else
{
cout << n;
}
Sleep(150);
}
return 0;
}
have or not the message queue? If yes, the GetKeyState function retrieves the keyboard messages from the message queue?
Yes, you must call PeekMessage or GetMessage to make GetKeyState return new values, for further reading look here:
http://blogs.msdn.com/b/oldnewthing/archive/2004/11/30/272262.aspx
and here:
http://msdn.microsoft.com/en-us/library/windows/desktop/ms646301%28v=vs.85%29.aspx
If you dont want message loop use GetAsyncKeyState.
GetKeyState is a Windows function that interacts closely with the Windows message queue. The function does not exist in Unix.
As I explained in your previous question, GetKeyState provides information about the key state associated with the most recently retrieved message. Since your console application does not have a message queue, and is not pumping messages, GetKeyState yields no useful information.
Again, as explained in your previous question, you use GetAsyncKeyState to obtain information about the state at the instant that the API call is made.
Finally, again repeating statements from your earlier question, test for a key being pressed by checking for a negative return value. For instance:
if (GetAsyncKeyState(VK_UP) < 0)
....
My most important advice to you is that when you ask a question here on Stack Overflow, you read the answers! If you don't understand them, leave comments asking for clarification.
Related
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 1 year ago.
Improve this question
I am trying to create a console application that works as a messaging app running off of a server. I want to be able to recieve messages from a friend while I am typing my own message or while the console is awaiting my input (essentially I want to be able to cout while I cin). how would I do this? I'm assuming I will have to work on multiple threads but I cant find anything useful online.
Yes, you will have to work with multiple threads. Essentially, one thread creates and sends messages, one thread receives them. So, they work in parallel and whenever a message is received it is simply printed (or written to a log or what have you) from the reader thread, and the writer thread will constantly be waiting for user input, and will allow the user to send a message. In this code, the message is printed as soon as its received. Also, this code is highly simplified since I have no idea how your message implementation is done, so all the message specifics are left out and a generic message is just printed at some interval. This kind of implementation will also result in messages received cutting off input. You would need some kind of input space separate from the output space so they don't intercept eachother visually like this, or you could use mutexes but this defeats the purpose of getting a message instantly.
#include<iostream>
#include<thread>
#include<chrono>
void reader()
{
using namespace std::chrono_literals;
for(int i = 0; i < 10; i++)
{
std::this_thread::sleep_for(1000ms);
std::cout << "This is a message...\n";
}
}
void writer()
{
std::string message;
for(int i = 0; i < 10; i++)
{
getline(std::cin, message);
}
}
int main(void)
{
std::thread reader_thread(reader);
std::thread writer_thread(writer);
reader_thread.join();
writer_thread.join();
std::cout << "done!\n";
}
EDIT: Thought I would give more pointers on cin/cout intercepting each other. Basically, input and output happens in the same line and same place in most console implementations (Unless you use redirection or pipes or something). Most actual messaging apps have separate places for input and output. For example, you input your message somewhere, but the messages you receive show up above that. This kind of implementation means that input/output never stack on top of each other, but is also pretty much impossible to do with cin/cout. So, if you really want to do this kind of messaging application, you could use pipes or files OR you could use some libraries. Pretty much any GUI lib (Gtkmm, Qt) will let you do something like this, but if you are console-bound, ncurses will let you manipulate the console in complex ways like this so you can have one section for receiving messages and one for sending them.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question appears to be off-topic because it lacks sufficient information to diagnose the problem. Describe your problem in more detail or include a minimal example in the question itself.
Closed 9 years ago.
Improve this question
I've seen it once or twice in a few places, but I can't seem to find this pattern while searching. What I want is, while in a loop, pause for a couple of milliseconds for user input, then continue.
so it would look something like this:
int main()
{
while (1)
{
//do stuff
//get user input, continue if there is nothing
//do stuff based off of user input
}
}
I'm using xemacs and g++ on Fedora 18 and I'm looking for a single keyboard keypress.
You'll (almost certainly) want to use the curses library.
If you want to pause to wait for input, you call halfdelay to set the time to wait for input. If the user hasn't entered anything in that time, it'll return ERR (or some error code anyway--been a while so I can't remember for sure what). If memory serves, however, the shortest delay you can specify is 1/10th of a second; there's no way to tell it to just pause for (say) up to 2 ms. Edit: thinking about it, it seems like there is a timeout (or something like that) that lets you set a timeout in milliseconds.
More often, you just want to react to input if there is any, and just continue other processing if here is none. In this case, you'd call nodelay.
Either way, you also want to call cbreak to disable line buffering at the OS level, so any key the user presses will be available to the program immediately instead of waiting for them to press return before you receive the input.
I'd guess you probably also want to call noecho() so the user's input isn't echoed by getch. For the kind of program you seem to be talking about, echoing the input command is rarely desired.
Then inside your loop, you'll call getch() to get the key input data (if any). If you get input, you process it. If it returns the error code to indicate there's no input, you continue your other processing.
So the code would be structured something like:
cbreak();
noecho();
nodelay(mywindow, true);
while (1) {
int ch;
if (ERR != (ch = getch()))
process(ch);
update_screen();
do_other_processing();
}
In the case of wanting a keyboard input, and then firing a trigger only if it is there, your best bet is essentially to use an event handler style system, something akin to how games detect input. What happens is usually something like this:
Event e;
while(Poll for event e) // Basically check if something has been triggered.
{
if(event type == certain key pressed){
// Do related stuff
}
}
You will essentially put this inside your main program loop, and every time that key, or some other trigger you specify is fired, it will call a function or do something else you specified.
I'm stuck on problem were I would like to ask for some help:
I have the task to print some files of different types using ShellExecuteEx with the "print" verb and need to guarantee print order of all files. Therefore I use FindFirstPrinterChangeNotification and FindNextPrinterChangeNotification to monitor the events PRINTER_CHANGE_ADD_JOB and PRINTER_CHANGE_DELETE_JOB using two different threads in the background which I start before calling ShellExecuteEx as I don't know anything about the application which will print the files etc. The only thing I know is that I'm the only one printing and which file I print. My solution seems to work well, my program successfully recognizes the event PRINTER_CHANGE_ADD_JOB for my file, I even verify that this event is issued for my file by checking what is give to me as additional info by specifying JOB_NOTIFY_FIELD_DOCUMENT.
The problem now is with the event PRINTER_CHANGE_DELETE_JOB, where I don't get any addition info about the print job, though my logic is exactly the same for both events: I've written one generic thread function which simply gets executed with the event it is used for. My thread is recognizing the PRINTER_CHANGE_DELETE_JOB event, but on each call to FindNextPrinterChangeNotification whenever this event occured I don't get any addition data in ppPrinterNotifyInfo. This works for the start event, though, I verified using my logs and the debugger. But with PRINTER_CHANGE_DELETE_JOB the only thing I get is NULL.
I already searched the web and there are some similar questions, but most of the time related to VB or simply unanswered. I'm using a C++ project and as my code works for the ADD_JOB-event I don't think I'm doing something completely wrong. But even MSDN doesn't mention this behavior and I would really like to make sure that the DELETE_JOB event is the one for my document, which I can't without any information about the print job. After I get the DELETE_JOB event my code doesn't even recognize other events, which is OK because the print job is done afterwards.
The following is what I think is the relevant notification code:
WORD jobNotifyFields[1] = {JOB_NOTIFY_FIELD_DOCUMENT};
PRINTER_NOTIFY_OPTIONS_TYPE pnot[1] = {JOB_NOTIFY_TYPE, 0, 0, 0, 1, jobNotifyFields};
PRINTER_NOTIFY_OPTIONS pno = {2, 0, 1, pnot};
HANDLE defaultPrinter = PrintWaiter::openDefaultPrinter();
HANDLE changeNotification = FindFirstPrinterChangeNotification( defaultPrinter,
threadArgs->event,
0, &pno);
[...]
DWORD waitResult = WAIT_FAILED;
while ((waitResult = WaitForSingleObject(changeNotification, threadArgs->wfsoTimeout)) == WAIT_OBJECT_0)
{
LOG4CXX_DEBUG(logger, L"Irgendein Druckereignis im Thread zum Warten auf Ereignis " << LogStringConv(threadArgs->event) << L" erkannt.");
[...]
PPRINTER_NOTIFY_INFO notifyInfo = NULL;
DWORD events = 0;
FindNextPrinterChangeNotification(changeNotification, &events, NULL, (LPVOID*) ¬ifyInfo);
if (!(events & threadArgs->event) || !notifyInfo || !notifyInfo->Count)
{
LOG4CXX_DEBUG(logger, L"unpassendes Ereignis " << LogStringConv(events) << L" ignoriert");
FreePrinterNotifyInfo(notifyInfo);
continue;
}
[...]
I would really appreciate if anyone could give some hints on why I don't get any data regarding the print job. Thanks!
https://forums.embarcadero.com/thread.jspa?threadID=86657&stqc=true
Here's what I think is going on:
I observe two events in two different threads for the start and end of each print job. With some debugging and logging I recognized that FindNextPrinterChangeNotification doesn't always return only the two distinct events I've notified for, but some 0-events in general. In those cases FindNextPrinterChangeNotification returns 0 as the events in pdwChange. If I print a simple text file using notepad.exe I only get one event for creation of the print job with value 256 for pdwChange and the data I need in notifyInfo to compare my printed file name against and comparing both succeeds. If I print a pdf file using current Acrobat Reader 11 I get two events, one has pdwChange as 256, but gives something like "local printdatafile" as the name of the print job started, which is obviously not the file I printed. The second event has a pdwChange of 0, but the name of the print job provided in notifyInfo is the file name I used to print. As I use FreePDF for testing pruproses, I think the first printer event is something internal to my special setup.
The notifications for the deletion of a print job create 0 events, too. This time those are sent before FindNextPrinterChangeNotification returns 1024 in pdwChange, and timely very close after the start of the print job. In this case the exactly one generated 0 event contains notifyInfo with a document name which equals the file name I started printing. After the 0 event there's exactly one additional event with pdwChange of 1024, but without any data for notifyInfo.
I think Windows is using some mechanism which provides additional notifications for the same event as 0 events after the initial event has been fired with it's real value the user notified with, e.g. 256 for PRINTER_CHANGE_ADD_JOB. On the other hand it seems that some 0 events are simply fired to provide data for an upcoming event which then gets the real value of e.g. 1024 for PRINTER_CHANGE_DELETE_JOB, but without anymore data because that has already been delivered to the event consumer with a very early 0 event. Something like "Look, there's more for the last events." and "Look, something is going to happen with the data I already provide now." Implementing such an approach my prints now seem to work as expected.
Of course what I wrote doesn't fit to what is documented for FindNextPrinterChangeNotification, but it makes a bit of sense to me. ;-)
You're not checking for overflows or errors.
The documentation for FindNextPrinterChangeNotification says this:
If the PRINTER_NOTIFY_INFO_DISCARDED bit is set in the Flags member of
the PRINTER_NOTIFY_INFO structure, an overflow or error occurred, and
notifications may have been lost. In this case, no additional
notifications will be sent until you make a second
FindNextPrinterChangeNotification call that specifies
PRINTER_NOTIFY_OPTIONS_REFRESH.
You need to check for that flag and do as described above, and you should also be checking the return code from FindNextPrinterChangeNotification.
I have a problem that I think is caused by the wm_keyup message not being sent correctly. I believe that the same problem occurs in Minecraft when you move your character and the input will get 'stuck'. The action of the key continues after you pressed it and doesn't cease until you tap the key again. I heard that it could be an issue between windows and the keyboard but I'm not completely sure. Also, most other mainstream games don't have this problem so there must be a correct way to do it. This is what my windows procedure code looks like:
case WM_KEYDOWN:
for (list<KeyInput>::iterator t = key_inputs.begin(); t != key_inputs.end(); ++t)
(*t).PushKeyDown(ConvertKeyCode(wparam));
return 0;
case WM_KEYUP:
for (list<KeyInput>::iterator t = key_inputs.begin(); t != key_inputs.end(); ++t)
(*t).PushKeyUp(ConvertKeyCode(wparam));
return 0;
Each KeyInput object has a queue that gets filled with key inputs and is emptied as keyboard input is requested. This code is for a multithreaded game and this technique ensures that no input is missed on any thread. I am using mutual exclusion in the KeyInput objects.
I get this problem more in my game than in Minecraft and I have no idea why. I also got it before when I was doing simpler, non-multithreaded code. I don't know how to fix this.
I appreciate any help or suggestions anyone has to offer.
After looking at the documentation for the WM_KEYDOWN message I found out that the 31st bit of lparam tells whether or not the last keydown message was the same as the latest. If you use this info to ignore repeat messages, you can get rid of the problem (but you lose repeat input from the key when it is held down). Here is my code:
case WM_KEYDOWN:
{
union
{
uint lparam;
struct { uint bits:30,_30:1,_31:1; };
} lparam_data;
lparam_data.lparam = lparam;
if (!lparam_data._30)
// key was pushed
return 0;
}
I don't know how to write a good question here, but, basically, does anyone know where I can possibly find some C++ source code using these to actually set keyboard state? For some reason using it the way MSDN does on Windows 7 doesn't do...anything at all.
Basic code:
PBYTE keyState;
GetKeyboardState(keyState);
...
// Later on when I need to set the keyboard state (key pressed etc) back to original:
SetKeyboardState(keyState);
and ... nothing happens :(
From:
http://www.gamedev.net/community/forums/topic.asp?topic_id=43463
First off, GetKeyboardState() would be the wrong function to use because as Windows has a chance to process keyboard messages (whether you want it too or not) it updates the results of the keyboard's state for the next call to GetKeyboardState().
Here's a little function that I use to get the status of the keyboard's keys. Be carefull though, depending on how fast your main loop is, it may cause problems if you aren't expecting it.
You need to keep track of whether or not a specific key was pressed the last time you called the ReadKeyboard() function. If your loop polls the keyboard 30 times a second, then pressing a key once probably causes the key to be flagged 3 or 4 calls in a row. Rather confusing sometimes. Just thought I'd mention it.
void ReadKeyboard( char* keys )
{
for (int x = 0; x < 256; x++)
keys[x] = (char) (GetAsyncKeyState(x) >> 8);
}