Re: How to correctly pop a modeless dialog from console using MFC
Vertilka wrote:
I need to create a console application that has a main() function and
pop a modeless dialog, so the console can still work in parallel to
the modeless dialog (do other work, like communicating with the
modeless dialog).
void main()
{
AfxWinMain(GetModuleHandle(NULL), NULL, GetCommandLine(),
SW_SHOW);
// just to see if the modeless dialog responses
Sleep(10000);
}
In all cases the modeless dialog freeze.
I believe this is a one line solution.
Well, not one line :)
A GUI requires a message pump. All GUI applications start with 1
thread called the main process thread and the pump is assigned to this
thread.
A console application also has 1 thread, the main thread so when you
do the SLEEP() it is blocked and nothing else happens.
So you have two solutions:
1) You can create a 2nd thread with a window and give it is own
message pump. The thread will run on its own independent on the main
thread.
2) Instead of blocking in the main thread, you yield with a message
pump dispatch, like so:
while (1) {
MSG msg;
while (::PeekMessage(&msg,NULL,0,0,PM_REMOVE)){
::TranslateMessage(&msg);
::DispatchMessage(&msg);
}
}
However, there is one problem with that.
You are a console, the keyboard is your input. So unless the Thread
with the WINDOW has a BUTTON to send the EXIT message or set a global
flag, where in the loop you will detect the message or global flag,
and break out of the loop, without that, the only way to break out is
to put a keyboard monitor, like so:
#include <conio.h>
....
_cprint("* Press ESC to exit\n");
while (1) {
if (_kbhit() && _getch() == 27) break;
Sleep(75); // <<-- BE FRIENDLY WITH WINDOWS!
MSG msg;
while (::PeekMessage(&msg,NULL,0,0,PM_REMOVE)){
::TranslateMessage(&msg);
::DispatchMessage(&msg);
}
}
The low Sleep() is good because without it, the loop is very fast and
there is a lot of "context switching" (look up what that means). It
otherwise it is CPU expensive. You might see a few CPU % without the
sleep because the kbhit checking actually promotes an interrupt so
there is some CPU context switching with it. But with the Sleep(75),
you will see 0% CPU!!!!!!! You can probably go as high with good
sensitivity around 200-400 ms. DO NOT USE SLEEP(0).
Have fun.
--
HLS