Beefy Boxes and Bandwidth Generously Provided by pair Networks
"be consistent"
 
PerlMonks  

Show a msgbox and do not wait (Win32)

by Jenda (Abbot)
on Feb 19, 2003 at 00:04 UTC ( [id://236455]=perlquestion: print w/replies, xml ) Need Help??

Jenda has asked for the wisdom of the Perl Monks concerning the following question:

In several scripts I use Win32::MsgBox() to display a short message to the user. This works fine even for scripts that do not have a console (are run by wperl.exe). The problem is that the scripts stop executing until the user clicks the OK. I would need the script to continue and even end no matter whether the msgbox is still displayed. (This means that using threads would not be enough.)

I thought about starting a separate script that would just display the message and end when the user clicks OK. But this takes up a lot of memory. So I tried to create such an app in C# (just came from a training). That was even worse! And in VB ... slightly better but still huge. I failed doing this in plain old C. (I've never been a C programmer.)

The best I can do at the moment is to send the currently logged user a message via Win32::Message/system("net send ...").

Does anyone have a better idea? Or knows of a "tiny utility" that would call the MessageBoxA() Win32 API function with the caption and message I give it? No need to get the result, no need to show any other buttons but the OK, etc ...

Thanks, Jenda

Replies are listed 'Best First'.
Re: Show a msgbox and do not wait (Win32)
by tachyon (Chancellor) on Feb 19, 2003 at 00:30 UTC

    What is wrong with fork?

    use Win32; my $pid = fork(); die "Could not fork Fork!" unless defined $pid; if ( $pid ) { # Parent makes whoopee while kids are away do {print $come_to_momma_honey++ . "\n"; sleep 1 } while 1; } else { # kid so do the MsgBox Win32::MsgBox("My parent's are getting up to mischief while I am w +aiting for you to press OK!"); die "You killed me. Your own flesh and blood!\n"; }

    I am on Win2K and this works fine. The count goes on while the message box waits. Parent continues after you press OK while the kid exits. See some other fork examples at My children are driving me crazy Forked off! and Forked up with a bit of explanation.

    cheers

    tachyon

    s&&rsenoyhcatreve&&&s&n.+t&"$'$`$\"$\&"&ee&&y&srve&&d&&print

      fork() could be a solution if I were running a Unix. I said I need the script to be able to exit even though the message still sits on the screen. And since fork() creates threads, not processes this will not work. Even if the main thread would end the whole processes will still be alive and the program that started it will wait.

      Jenda

        Fair enough

        cheers

        tachyon

        s&&rsenoyhcatreve&&&s&n.+t&"$'$`$\"$\&"&ee&&y&srve&&d&&print

        Here is one way that appears to fulfill your requirements.

        use Win32::Process; my $user = $ENV{USERNAME}; my $message = "$0 has a message for $user"; send_message($message); sub send_message { my ($message) = @_; my $Process; my $program = 'C:/WINNT/system32/net.exe'; Win32::Process::Create($Process, "$program", "net send $user $message", 0, DETACHED_PROCESS, ".") or die "Create: $!"; }

        --
        Regards,
        Helgi Briem
        helgi AT decode DOT is

Re: Show a msgbox and do not wait (Win32)
by Solo (Deacon) on Feb 19, 2003 at 01:27 UTC
    Creating another process is (I think) the only way this is possible without creating a full-blown dialog or window--the messagebox API is inherently modal, methinks.

    Here is the workaround code I came up with:

    Main file:

    use Win32::Process; Win32::Process::Create($ProcessObj, "C:\\perl\\bin\\perl.exe", qq[perl -MWin32 -e "Win32::MsgBox('Test')"], 0, NORMAL_PRIORITY_CLASS, ".")|| die ErrorReport(); Win32::Process::Create($ProcessObj, "C:\\perl\\bin\\perl.exe", "perl messagebox.pl", 0, NORMAL_PRIORITY_CLASS, ".")|| die ErrorReport(); for (1..60) { print "$_\n"; sleep(1); }

    And if you really want to know how to directly call the MessageBox API from Perl, here's messagebox.pl

    use Win32::API::Prototype; # von die infamous Dave Roth ApiLink( 'user32.dll', 'DWORD MessageBox( DWORD hwnd, LPTSTR lpText, LPTSTR lpCaptio +n, DWORD wType)' ) || die; $lpText = NewString("The text in the message box."); $lpCaption = NewString("The Caption"); MessageBox(0,$lpText,$lpCaption,0);
    --Solo
    --
    You said you wanted to be around when I made a mistake; well, this could be it, sweetheart.
Re: Show a msgbox and do not wait (Win32)
by Cabrion (Friar) on Feb 19, 2003 at 01:19 UTC
    a "tiny utility" that would call the MessageBoxA() Win32 API function with the caption and message I give it?

    See rundll32.exe to do that. Is a "standard" MS app and you can find details on it's use on their web site.

    Another method would be to create a "regular" window (i.e. not a dialog) that does what you want. In VB you just show a form with a label & and OK button in it, and set the label's value to your string. You can set various properties of the form at design time to simulate a dialog box. Change your compile settings to start the app with a "main" function instead of a form. Otherwise, the application will just exit when the form is dismissed. Sorry, I don't do GUI programming with perl, so i can't give you a perl-centric answer.

      Thanks for the ideas. I forgot about rundll32, thanks. It wount work though anyway. Rundll32 supports only functions with prototype

      void CALLBACK EntryPoint(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdSh +ow);
      and MessageBoxA is too different.

      I've tried the VB way, with Sub Main and MsgBox function, but the resulting EXE wasted about 4MB of memory when run.

      Jenda

        Code it in Delphi to avoid the large overhead. It's way better than VB anyway.

        However, you might also consider exploring windows scripting host.

Re: Show a msgbox and do not wait (Win32)
by dragonchild (Archbishop) on Feb 19, 2003 at 00:14 UTC
    I don't have the answer the your question. However, this sounds like a problem in design - why do you want to do this? I don't program on Win32 at all, but if I ran into a problem like this, I'd attempt to re-engineer my app to avoid this. Problems like this will often show problems with design (or even requirements) that will be bigger issues later on down the road.

    ------
    We are the carpenters and bricklayers of the Information Age.

    Don't go borrowing trouble. For programmers, this means Worry only about what you need to implement.

      Well ... I need it for a script I use to get/check out files from PVCS. I use it (yes, actually I am the only used :-) mainly from two places. From a macro in my editor (SciTE) ... where I'd like to show the message and reload the file. Currently I have to click the message off to finish the macro.

      Second place is a code generation tool. I have to check out several files before I can start the generation and currently I have to sit here and click off the messages. Of course I could add just another option to the script so that suppress the msgboxes in this case, but I'd like to see whis ones it had to check ont and which ones I already had.

      Anyway ... I should have done my homework first. I Googled around and found a tiny EXE that does what I wanted (http://claudiosoft.online.fr/).

      Thanks, Jenda

Re: (nrd) Show a msgbox and do not wait (Win32)
by newrisedesigns (Curate) on Feb 19, 2003 at 00:29 UTC

    Perhaps there is a different method you could use.

    You could use a Tk window with a scrolling textarea to display the messages (as well as the previous messages). I'm just learning the basics of Tk, so I regrettably can't offer you help in the form of code.
    Just a thought.

    John J Reiser
    newrisedesigns.com

Re: Show a msgbox and do not wait (Win32)
by tall_man (Parson) on Feb 19, 2003 at 00:33 UTC
    It seems like you are using Win32::MsgBox to report a tracing log instead of for error conditions, etc. I picture the user having to click on 100 pop-up messages after your program ends (or do you really show only one message box per run?). Perhaps instead you could have a side window with a scrolling text box and append your messages there as the program runs.

      I should have given more info about where do I want to use this. Normaly the script only shows one msgbox, but needs to exit for the parent process to continue on (the parent is not Perl). At times it may show several, but the number will always be small.

      It's just a "wrapper" to PVCS command line interface used from an editor, form other scripts, from an automated code generation tool etc. And all I want is to show a "done" message and exit so that I do not block the parent. Or myself from getting/checking out/checking in the next file.

      Jenda

        Win32::Daemon would be one possible solution. Write a short service script that checks a log file, pops a message box if there is text in there, then unlinks the file.

        Then just write to the log file when you want to pop up a message and continue on in your main program. Have the service read the log every X seconds and send any pending messages. Use the fork in the service so the parent can continue 'listening' to the log while the kid(s) hang on the MsgBox(s).

        If you want to get a little more elegant and complex have the service create and listen to a named pipe rather than using a text file for IPC. Win32::Pipe will let you create a named pipe with ease. All the clien has to do is open the pipe like you would open a file using the UNC syntax

        open PIPE, ">\\\\server\\pipe\\MyNamedPipe" or die $! print PIPE $message CLOSE PIPE
        and then print to it and close the pipe.

        Hope this solves your problem.

        cheers

        tachyon

        s&&rsenoyhcatreve&&&s&n.+t&"$'$`$\"$\&"&ee&&y&srve&&d&&print

Re: Show a msgbox and do not wait (Win32)
by BrowserUk (Patriarch) on Feb 19, 2003 at 12:52 UTC

    Try this. I could have zipped it but its only 3k so it didn't seem worth it.

    It takes two quoted CLI parameters

    popup "Your dialog title" "Your text to display"


    Examine what is said, not who speaks.

    The 7th Rule of perl club is -- pearl clubs are easily damaged. Use a diamond club instead.

      Sweet :-) This is even smaller than the MsgBox.exe I found before. Thanks!

      Jenda

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://236455]
Approved by Enlil
Front-paged by Enlil
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others having an uproarious good time at the Monastery: (5)
As of 2024-04-24 09:11 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found