Running strawberry perl 5.16.2 under XP. I've got a multi-threaded program (parent thread runs the GUI, child is the "worker"). I want the child to send some sort of "wake up" signal to the parent when it has information to pass (via shared variables). The problem is the GUI thread is stuck running Win32::GUI::Dialog(), so it doesn't receive signals and polling isn't possible (not to mention inefficient). Anyway, it occurs to me that really all I have to do is send the parent a Windows message which I've set up to be handled by a custom function which does whatever I want it to do (in this case, it would process the information stored in the shared variables). WM_TIMER seemed to be a good candidate for this message, but I can't for the life of me figure out how to make this work. Here's the test, boiled down to the essentials:
#!perl
use threads;
use Win32::GUI qw( WM_CLOSE WM_TIMER );
$CHILD = threads->create('child', '');
$WinMain = Win32::GUI::Window->new(
-name => 'Main',
-text => 'Task Test',
-width => 300,
-height => 200,
-onTerminate => \&Main_Terminate,
-onTimer => \&DoTimer,
);
$WinMain->Show();
Win32::GUI::Dialog();
$CHILD->detach();
sub Main_Terminate { -1; }
sub child {
sleep 1; # Give parent time to create window
my $parent = Win32::GUI::FindWindow('','Task Test');
Win32::GUI::SendMessage($parent,WM_TIMER,0,0);
threads->exit(0);
}
sub DoTimer {
print "Timer fired\n";
return 0;
}
If I run the above code, I never see the "Timer fired" message. However, if I change the SendMessage() call to use WM_CLOSE instead of WM_TIMER, the gui closes (as expected), which I take to be evidence that the theory is sound. I just can't figure out how to get it to work with WM_TIMER or some other message that I can intercept with my own handler.
Any suggestions?
Oh, and before somebody suggests it, yes I know polling is possible with DoEvents(), however under certain circumstances, DoEvents() can take an indefinite amount of time to return which makes the polling cycle too unpredictable for this particular application.
Update: I believe I've solved it. Thanks to roboticus' prodding, I dug a little deeper into trying to use WM_USER and I eventually figured it out. Set up the handler with $WinMain->Hook(WM_USER, \&coderef); (also you'd need to add WM_USER to the constants imported in "use Win32::GUI qw(...". I'm still not sure why it fails with WM_TIMER, but the end result solves my problem. Thanks all!
-
Are you posting in the right place? Check out Where do I post X? to know for sure.
-
Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
<code> <a> <b> <big>
<blockquote> <br /> <dd>
<dl> <dt> <em> <font>
<h1> <h2> <h3> <h4>
<h5> <h6> <hr /> <i>
<li> <nbsp> <ol> <p>
<small> <strike> <strong>
<sub> <sup> <table>
<td> <th> <tr> <tt>
<u> <ul>
-
Snippets of code should be wrapped in
<code> tags not
<pre> tags. In fact, <pre>
tags should generally be avoided. If they must
be used, extreme care should be
taken to ensure that their contents do not
have long lines (<70 chars), in order to prevent
horizontal scrolling (and possible janitor
intervention).
-
Want more info? How to link
or How to display code and escape characters
are good places to start.