Modal operation using IMessageFilter and DoEvents - windows

This is a Windows Forms application. I have a function which captures some mouse events modally till a condition is met. For example, I would like to wait for the user to select a point in the window's client area (or optionally cancel the operation using the Escape key) before the function returns. I am using the following structure:
Application::AddMessageFilter(someFilter);
while(someFilter->HasUserSelectedAPoint_Or_HitEscapeKey()){
Application::DoEvents();
}
Application::RemoveMessageFilter(someFilter);
This works quite nicely except for taking up nearly 100% CPU usage when control enters the while loop. I am looking for an alternative similar to what is shown below:
Application::AddMessageFilter(someFilter);
while(someFilter->HasUserSelectedAPoint_Or_HitEscapeKey()){
// Assuming that ManagedGetMessage() below is a blocking
// call which yields control to the OS
if(ManagedGetMessage())
Application::DoEvents();
}
Application::RemoveMessageFilter(someFilter);
What is the right way to use IMessageFilter and DoEvents? How do I surrender control to the OS till a message is received? Any GetMessage equivalent in the managed world?

You could sleep the thread for 500ms or so between DoEvents() calls. Experiment with different values to see what feels right.

Related

XMaskEvent not returning

I am following this tutorial here: http://www.sbin.org/doc/Xlib/chapt_16.html
Here is the image of the tutorial:
Here is my code: (it is in another thread from which I called XInitThreads - I know using threads and X is bad, I know I should be on the main thread, but just wondering if possible)
var ev = XEvent();
var rez_XMaskEvent = XMaskEvent(cachedXOpenDisplay(), ButtonPressMask | ButtonReleaseMask, ev.address());
console.log('rez_XMaskEvent:', rez_XMaskEvent);
console.log('ev:', ev);
ButtonPressMask is 4
ButtonReleaseMask is 8
So XMaskEvent is blocking, but whenever I press my mouse button it is not catching it. Shouldn't it unblock and get to the console.log line?
Do I need to run an event loop somehow in this thread?
Thanks
I'm not 100% sure here but I feel this could be your problem:
You probably can't do this from JavaScript without some extra precautions. JavaScript in the browser is single-threaded. That means you're holding a lock and no other JavaScript can run. Your problem is a) you're using threads and b) "If the event you requested is not in the queue, XMaskEvent flushes the output buffer and blocks until one is received." (see the man page)
That means XMaskEvent blocks since the button hasn't been pressed, yet. And your browser can't execute JavaScript anymore. If there is an event in the queue which would trigger some JavaScript, the browser will lock up.

X11: How to delay repainting until all events are processed?

I'm writing a program that has an X11/Xlib interface, and my event processing loop looks like this:
while (XNextEvent(display, &ev) >= 0) {
switch (ev.type) {
// Process events
}
}
The problem is when the window is resized, I get a bunch of Expose events telling me which parts of the window to redraw. If I redraw them in direct response to the events, the redraw operation lags terribly because it is so slow (after resizing I get to see all the newly invalidated rectangles refresh one by one.)
What I would like to do is to record the updated window size as it changes, and only run one redraw operation on the entire window (or at least only two rectangles) when there are no more events left to process.
Unfortunately I can't see a way to do this. I tried this:
do {
XPeekEvent(display, &ev);
while (XCheckMaskEvent(display, ExposureMask | StructureNotifyMask, &ev)) {
switch (ev.type) {
// Process events, record but don't process redraw events
}
}
// No more events, do combined redraw here
}
Which does actually work, but it's a little inefficient, and if an event arrives that I am not interested in the XCheckMaskEvent call doesn't remove it from the queue, so it stays there stopping XPeekEvent from blocking, resulting in 100% CPU use.
I was just wondering whether there is a standard way to achieve the delayed/combined redraw that I am after? Many of the Xlib event processing functions seem to block, so they're not really suitable to use if you want to do some processing just before they block, but only if they would block!
EDIT: For the record, this is the solution I used. It's a simplified version of n.m.'s:
while (XNextEvent(display, &ev) >= 0) {
switch (ev.type) {
// Process events, remember any redraws needed later
}
if (!XPending(display)) {
// No more events, redraw if needed
}
}
FWIW a UI toolkit such as GTK+ does it this way:
for each window, maintains a "damage region" (union of all expose events)
when the damage region becomes non-empty, adds an "idle handler" which is a function the event loop will run when it doesn't have anything else to do
the idle handler will run when the event queue is empty AND the X socket has nothing to read (according to poll() on ConnectionNumber(dpy))
the idle handler of course repaints the damage region
In GTK+, they're changing this over to a more modern 3D-engine oriented way (clean up the damage region on vertical sync) in a future version, but it's worked in the fairly simple way above for many years.
When translated to raw Xlib, this looks about like n.m.'s answer: repaint when you have a damage region and !XPending(). So feel free to accept that answer I just figured I'd add a little extra info.
If you wanted things like timers and idles, you could consider something lke libev http://software.schmorp.de/pkg/libev.html it's designed to just drop a couple of source files in your app (it isn't set up to be an external dependency). You would add the display's file descriptor to the event loop.
For tracking damage regions, people often cut-and-paste the file "miregion.c" which is from the "machine independent" code in the X server. Just google for miregion.c or download the X server sources and look for it. A "region" here is simply a list of rectangles which supports operations such as union and intersect. To add damage, union it with the old region, to repair damage, subtract it, etc.
Try something like the following (not actually tested):
while (TRUE) {
if (XPending(display) || !pendingRedraws) {
// if an event is pending, fetch it and process it
// otherwise, we have neither events nor pending redraws, so we can
// safely block on the event queue
XNextEvent (display, &ev);
if (isExposeEvent(&ev)) {
pendingRedraws = TRUE;
}
else {
processEvent(&ev);
}
}
else {
// we must have a pending redraw
redraw();
pendingRedraws = FALSE;
}
}
It could be beneficial to wait for 10 ms or so before doing the redraw. Unfortunately the raw Xlib has no interface for timers. You need a higher-level toolkit for that (all toolkits including Xt have some kind of timer interface), or work directly with the underlying socket of the X11 connection.

MATLAB event and infinite sleeping or checking loop

I need to perform data analysis on files in a directory as they come in.
I'd like to know, if it is better,
to implement an event listener on the directory, and start the analysis process when activated. Then having the program go into sleep forever: while(true), sleep(1e10), end
or to have a loop polling for changes and reacting.
I personally prefer the listeners way, as one is able to start the analysis twice on two new files coming in NEARLY the same time but resulting in two events. While the other solution might just handle the first one and after that finds the second new data.
Additional idea for option 1: Hiding the matlab GUI by calling frames=java.awt.Frame.getFrames and setting frames(index).setVisible(0) on the index matching the com.mathworks.mde.desk.MLMainFrame-frame. (This idea is taken from Yair Altman)
Are there other ways to realize such things?
In this case, (if you are using Windows), the best way is to use the power of .NET.
fileObj = System.IO.FileSystemWatcher('c:\work\temp');
fileObj.Filter = '*.txt';
fileObj.EnableRaisingEvents = true;
addlistener(fileObj,'Changed',#eventhandlerChanged);
There are different event types, you can use the same callback for them, or different ones:
addlistener(fileObj, 'Changed', #eventhandlerChanged );
addlistener(fileObj, 'Deleted', #eventhandlerChanged );
addlistener(fileObj, 'Created', #eventhandlerChanged );
addlistener(fileObj, 'Renamed', #eventhandlerChanged );
Where eventhandlerChanged is your callback function.
function eventhandlerChanged(source,arg)
disp('TXT file changed')
end
There is no need to use sleep or polling. If your program is UI based, then there is nothing else to do, when the user closes the figure, the program has ended. The event callbacks are executed exactly like button clicks. If your program is script-like, you can use an infinite loop.
More info in here: http://www.mathworks.com/help/matlab/matlab_external/working-with-net-events-in-matlab.html

Problem with Boost Asio asynchronous connection using C++ in Windows

Using MS Visual Studio 2008 C++ for Windows 32 (XP brand), I try to construct a POP3 client managed from a modeless dialog box.
Te first step is create a persistent object -say pop3- with all that Boost.asio stuff to do asynchronous connections, in the WM_INITDIALOG message of the dialog-box-procedure. Some like:
case WM_INITDIALOG:
return (iniPop3Dlg (hDlg, lParam));
Here we assume that iniPop3Dlg() create the pop3 heap object -say pointed out by pop3p-. Then connect with the remote server, and a session is initiated with the client’s id and password (USER and PASS commands). Here we assume that the server is in TRANSACTION state.
Then, in response to some user input, the dialog-box-procedure, call the appropriate function. Say:
case IDS_TOTAL: // get how many emails in the server
total (pop3p);
return FALSE;
case IDS_DETAIL: // get date, sender and subject for each email in the server
detail (pop3p);
return FALSE;
Note that total() uses the POP3’s STAT command to get how many emails in the server, while detail() uses two commands consecutively; first STAT to get the total and then a loop with the GET command to retrieve the content of each message.
As an aside: detail() and total() share the same subroutines -the STAT handle routine-, and when finished, both leaves the session as-is. That is, without closing the connection; the socket remains opened an the server in TRANSACTION state.
When any option is selected by the first time, the things run as expected, obtaining the desired results. But when making the second chance, the connection hangs.
A closer inspection show that the first time that the statement
socket_.get_io_service().run();
Is used, never ends.
Note that all asynchronous write and read routines uses the same io_service, and each routine uses socket_.get_io_service().reset() prior to any run()
Not also that all R/W operations also uses the same timer, who is reseted to zero wait after each operation is completed:
dTimer_.expires_from_now (boost::posix_time::seconds(0));
I suspect that the problem is in the io_service or in the timer, and the fact that subsequent executions occurs in a different load of the routine.
As a first approach to my problem, I hope that someone would bring some light in it, prior to a more detailed exposition of the -very few and simple- routines involved.
Have you looked at the asio examples and studied them? There are several asynchronous examples that should help you understand the basic control flow. Pay particular importance to the main event loop started by invoking io_service::run, it's important to understand control is not expected to return to the caller until the io_service has no more remaining work to do.

How to detect inactive user

How to detect inactive (idle) user in Windows application? I'd like to shutdown application when there hasn't been any input (keyboard, mouse) from user for certain period of time.
To track a user's idle time you could hook keyboard and mouse activity. Note, however, that installing a system-wide message hook is a very invasive thing to do and should be avoided if possible, since it will require your hook DLL to be loaded into all processes.
Another solution is to use the GetLastInputInfo API function (if your application is running on Win2000 (and up) machines).
GetLastInputInfo retrieves the time (in milliseconds) of the last input event (when the last detected user activity has been received, be it from keyboard or mouse).
Here's a simple example. The SecondsIdle function returns a number of second with no user activity (called in an OnTimer event of a TTimer component).
~~~~~~~~~~~~~~~~~~~~~~~~~
function SecondsIdle: DWord;
var
liInfo: TLastInputInfo;
begin
liInfo.cbSize := SizeOf(TLastInputInfo) ;
GetLastInputInfo(liInfo) ;
Result := (GetTickCount - liInfo.dwTime) DIV 1000;
end;
procedure TForm1.Timer1Timer(Sender: TObject) ;
begin
Caption := Format('System IDLE last %d seconds', [SecondsIdle]) ;
end;
http://delphi.about.com/od/adptips2004/a/bltip1104_4.htm
You might want to see the answer to this question: How to tell when Windows is inactive [1] it is basically same question the solution suggested is to use the GetLastInputInfo [2] API call.
This post explains some aspects as well: (The Code Project) How to check for user inactivity with and without platform invokes in C# [3]
[1] How to tell when Windows is inactive
[2] http://msdn.microsoft.com/en-us/library/ms646302%28VS.85%29.aspx
[3] http://www.codeproject.com/KB/cs/uim.aspx
Your application will get a WM_SYSCOMMAND message with SC_SCREENSAVE as a command id when the Screen Saver is about to kick in. Would that do? there's also the SC_MONITORPOWER command id when the monitor is about to blank (also a WM_SYSCOMMAND message).
Edit: looking at the comments, it appears that you don't care about whether the user is inative, but rather whether your application is inactive.
This is easy. If your app is minimized, then the user isn't interacting with it. If your app is not the foreground application, that's a good inicator as well.
You could also pay attention to messages in your pump to notice if there have been any user input messages to your app, In C++ adding code to the pump is trivial, in delphi you can use a WH_GETMESSAGE hook to monitor the pump hook into the message loop that TApplication implements. Or GetLastInputInfo
This SecondsIdle doens't work at all.
The way is to use a TTimer combined with a second variable that resets every time user inputs mouse or keyboard.

Resources