Jump to content

How to detect when Print dialog closed?


Recommended Posts

I've been writing a script that uses the open-source Evince document viewer to print PDF files "silently" to the default printer(nothing visible occurs on screen), with the option turned on that selects the printer tray according to the PDF page size. I have "silent" printing working correctly, but I want to add an option that lets the user select a printer. (I should explain that this is designed to be used with PDFs that have no "title", only a filename, and the filename appears in the Evince titlebar.)

To do this, I hide the Evince main window with @SW_HIDE, then I open the Print dialog (which appears, whether or not the main window is hidden). Then I set some options in the Print dialog, and wait for the user to select a printer and click Print or Cancel. Here is where I have trouble. I am trying to use WinWaitClose to detect when the Print dialog is closed, but the script never detects that the Print dialog closes.

What am I doing wrong here? I've included the whole script here, with the problem area marked.

#include <File.au3>
Dim $dir, $drv, $extname, $exepath, $filename
Dim $pdffile, $pth, $scrpt, $select
Global $pdftitle


Opt("WinTextMatchMode", 2)
$pth = @ScriptDir
$exepath = $pth & "\evince\bin\evince.exe"
$scrpt = @ScriptName
$select = 0

; Get filename as parameter
If $CmdLine[0] = 0 Then
    MsgBox(0, "", "PDF filename required.")
    Exit
EndIf
$pdffile = $CmdLine[$CmdLine[0]]

; test for -s in command line; if present, let user select printer
If StringLower($CmdLine[1]) = "-s" Then
    $select = 1
    If $CmdLine[0] = 1 Then
        MsgBox(0, "", "PDF filename required as parameter")
        Exit
    EndIf
EndIf

; test file exists
If FileExists($pdffile) Then
Else
    MsgBox(0, "", "File not found.")
    Exit
EndIf

; if script/app name includes "s" then let user select printer
If (StringInStr(StringLower($scrpt), "s")) Then
    $select = 1
EndIf

; parse filepath to get name that appears as Evince window title
If (StringInStr($pdffile, "\")) Then
    $testPath = _PathSplit($pdffile, $drv, $dir, $filename, $extname)
    $pdftitle = $filename & $extname
Else
    $pdftitle = $pdffile
EndIf

; run Evince, hide main window
Run($exepath & " " & $pdffile, "", @SW_HIDE)
WinWait($pdftitle, "", 2)
If WinExists($pdftitle) Then
    WinActivate($pdftitle)
    Send("^p")  ; send Print command
    If $select = 0 Then ; hide Print dialog by moving it offscreen
        WinMove("Print", "", @DesktopWidth + 1, @DesktopHeight + 1)
        Send("^{TAB}") ; Ctrl-Tab to Page Handling page
        Send("{Tab 3}") ; move down to "Select page size" option
        Send("{SPACE}") ; turn on that option
        Send("!p")      ; print
        Sleep(1000)
        WinClose($pdftitle)  ; close Evince window
        Exit
    Else  ; when select printer option is on, don't hide dialog
        Send("^{TAB}") ; Ctrl-Tab to Page Handling page
        Send("{Tab 3}") ; move down to "Select page size" option
        Send("{SPACE}") ; turn on that option
        Sleep(100)
        Send("^{TAB}")  ; Ctrl-Tab back to General page

        ;; here user can select a printer and press Print, or Cancel;
        ;; either one closes the Print dialog
        ;; but the next command never produces any result!

        WinWaitClose("Print")

        If WinExists($pdftitle) Then
            WinClose($pdftitle)
        EndIf
        Exit
    EndIf
Else
    MsgBox(0, "", "Error")
EndIf
Exit
Edited by Edward Mendelson
Link to comment
Share on other sites

I've been writing a script that uses the open-source Evince document viewer to print PDF files "silently" to the default printer(nothing visible occurs on screen), with the option turned on that selects the printer tray according to the PDF page size. I have "silent" printing working correctly, but I want to add an option that lets the user select a printer. (I should explain that this is designed to be used with PDFs that have no "title", only a filename, and the filename appears in the Evince titlebar.)

To do this, I hide the Evince main window with @SW_HIDE, then I open the Print dialog (which appears, whether or not the main window is hidden). Then I set some options in the Print dialog, and wait for the user to select a printer and click Print or Cancel. Here is where I have trouble. I am trying to use WinWaitClose to detect when the Print dialog is closed, but the script never detects that the Print dialog closes.

What am I doing wrong here? I've included the whole script here, with the problem area marked.

#include <File.au3>
Dim $dir, $drv, $extname, $exepath, $filename
Dim $pdffile, $pth, $scrpt, $select
Global $pdftitle


Opt("WinTextMatchMode", 2)
$pth = @ScriptDir
$exepath = $pth & "\evince\bin\evince.exe"
$scrpt = @ScriptName
$select = 0

; Get filename as parameter
If $CmdLine[0] = 0 Then
    MsgBox(0, "", "PDF filename required.")
    Exit
EndIf
$pdffile = $CmdLine[$CmdLine[0]]

; test for -s in command line; if present, let user select printer
If StringLower($CmdLine[1]) = "-s" Then
    $select = 1
    If $CmdLine[0] = 1 Then
        MsgBox(0, "", "PDF filename required as parameter")
        Exit
    EndIf
EndIf

; test file exists
If FileExists($pdffile) Then
Else
    MsgBox(0, "", "File not found.")
    Exit
EndIf

; if script/app name includes "s" then let user select printer
If (StringInStr(StringLower($scrpt), "s")) Then
    $select = 1
EndIf

; parse filepath to get name that appears as Evince window title
If (StringInStr($pdffile, "\")) Then
    $testPath = _PathSplit($pdffile, $drv, $dir, $filename, $extname)
    $pdftitle = $filename & $extname
Else
    $pdftitle = $pdffile
EndIf

; run Evince, hide main window
Run($exepath & " " & $pdffile, "", @SW_HIDE)
WinWait($pdftitle, "", 2)
If WinExists($pdftitle) Then
    WinActivate($pdftitle)
    Send("^p")  ; send Print command
    If $select = 0 Then ; hide Print dialog by moving it offscreen
        WinMove("Print", "", @DesktopWidth + 1, @DesktopHeight + 1)
        Send("^{TAB}") ; Ctrl-Tab to Page Handling page
        Send("{Tab 3}") ; move down to "Select page size" option
        Send("{SPACE}") ; turn on that option
        Send("!p")      ; print
        Sleep(1000)
        WinClose($pdftitle)  ; close Evince window
        Exit
    Else  ; when select printer option is on, don't hide dialog
        Send("^{TAB}") ; Ctrl-Tab to Page Handling page
        Send("{Tab 3}") ; move down to "Select page size" option
        Send("{SPACE}") ; turn on that option
        Sleep(100)
        Send("^{TAB}")  ; Ctrl-Tab back to General page

        ;; here user can select a printer and press Print, or Cancel;
        ;; either one closes the Print dialog
        ;; but the next command never produces any result!

        WinWaitClose("Print")

        If WinExists($pdftitle) Then
            WinClose($pdftitle)
        EndIf
        Exit
    EndIf
Else
    MsgBox(0, "", "Error")
EndIf
Exit

When I try it the Print window gets closed ok, although I commented out the start of your script and simply set the $pdffile and $pdftitle variables by hard code. It worked whether I used @SE_HIDE or not.

I'm using XP SP3.

Strange program Evince. I used a pdf of a cad drawing. The title in the Evince window is the title of the CAD drawing not the title of the pdf file which surprised me because I didn't think it would know what th ecad file was called. I think that was the document name when the pdf was created maybe.

BTW, that's a good idea you had, - a useful trick which I will try to remember.

Edited by martin
Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.
Link to comment
Share on other sites

When I try it the Print window gets closed ok, although I commented out the start of your script and simply set the $pdffile and $pdftitle variables by hard code. It worked whether I used @SE_HIDE or not.

I'm using XP SP3.

Strange program Evince. I used a pdf of a cad drawing. The title in the Evince window is the title of the CAD drawing not the title of the pdf file which surprised me because I didn't think it would know what th ecad file was called. I think that was the document name when the pdf was created maybe.

BTW, that's a good idea you had, - a useful trick which I will try to remember.

Thank you for testing this!

When I try it (with the -s or selection option turned ON - the option under the Else command where I've marked the problem), the Print dialog closes, but the script doesn't detect that it closes, and so the script continues to run in the system tray, and Evince is still running in the background.

When you run it, does Evince actually close down as it should in the part of the code that looks like this:

;; here user can select a printer and press Print, or Cancel;
        ;; either one closes the Print dialog
        ;; but the next command never produces any result!

        WinWaitClose("Print")

        If WinExists($pdftitle) Then
            WinClose($pdftitle)
        EndIf
        Exit

If it closes when you run it, then I'm going to have to figure out why it doesn't close when I try it.

While on the subject, I figured out that the only way to make this script work with PDFs that have titles is to use WinWait with the "title" set as [CLASS:gdkWindowToplevel] - as that seems to be the only reliable way to identify the Evince main window. Unfortunately, there might be other programs running with the same "title", and I can't figure out how to narrow it down to the Evince window (maybe with some combination of process name and CLASS:, but I don't know how it might work). But probably that's a question for a different thread.

Thanks again for looking into this.

Link to comment
Share on other sites

Thank you for testing this!

When I try it (with the -s or selection option turned ON - the option under the Else command where I've marked the problem), the Print dialog closes, but the script doesn't detect that it closes, and so the script continues to run in the system tray, and Evince is still running in the background.

When you run it, does Evince actually close down as it should in the part of the code that looks like this:

;; here user can select a printer and press Print, or Cancel;
        ;; either one closes the Print dialog
        ;; but the next command never produces any result!

        WinWaitClose("Print")

        If WinExists($pdftitle) Then
            WinClose($pdftitle)
        EndIf
        Exit

If it closes when you run it, then I'm going to have to figure out why it doesn't close when I try it.

While on the subject, I figured out that the only way to make this script work with PDFs that have titles is to use WinWait with the "title" set as [CLASS:gdkWindowToplevel] - as that seems to be the only reliable way to identify the Evince main window. Unfortunately, there might be other programs running with the same "title", and I can't figure out how to narrow it down to the Evince window (maybe with some combination of process name and CLASS:, but I don't know how it might work). But probably that's a question for a different thread.

Thanks again for looking into this.

Yes, it closes when I run it. I set

$select = 1

in the script before I ran it.

Maybe when $select is 1 you can wait for the window where you search for a printer to close and then, if the Print window is still there do something to close it.

Your [CLASS:gdkWin.... looks like the best way to me.

Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.
Link to comment
Share on other sites

Well, the problem I was having with closing the Print dialog was simply a case of user stupidity. I hadn't set the WinTitleMatch option correctly (it should be 3 for an exact match) and then I had a window named "PrintPDF" open when I was testing to see if the "Print" window was open - and the script correctly reported that a window was open whose name partly matched "Print". After I changed that option to what it should have been, it worked perfectly. Thank you for rightly insisting that the script was basically working.

So here's the finished script. On my slower laptop system, I can't make it completely silent, because I had to insert a WinWait("Print") command before moving the Print window offscreen. This was not necessary on my faster desktop. So it's almost working as it should, and may be close enough for practical purposes.

Here is the current script for silently printing a PDF using Evince, with Evince installed into the directory specified in the code:

Dim $dir, $drv, $exepath, $ext, $programtitle, $procname
Dim $pdffile, $pth, $scrpt, $select

$programtitle = "[CLASS:gdkWindowToplevel]"
$procname = "Evince.exe"

Opt("WinTitleMatchMode", 3)
$pth = @ScriptDir
$exepath = $pth & "\evince\bin\evince.exe"
$scrpt = @ScriptName
$select = 0

; Get filename as parameter
If $CmdLine[0] = 0 Then
    MsgBox(0, "", "PDF filename required.")
    Exit
EndIf
$pdffile = $CmdLine[$CmdLine[0]]

; test for -s in command line; if present, let user select printer
If StringLower($CmdLine[1]) = "-s" Then
    $select = 1
    If $CmdLine[0] = 1 Then
        MsgBox(0, "", "PDF filename required as parameter")
        Exit
    EndIf
EndIf

; pdf files only
$ext = StringLower(StringRight($pdffile, 4))
If $ext = ".pdf" Then
Else
    MsgBox(0, "", "PDF files only.")
    Exit
EndIf

; test file exists
If Not FileExists($pdffile) Then
    MsgBox(0, "", "File not found.")
    Exit
EndIf

; if script/app name includes "s" then let user select printer
If (StringInStr(StringLower($scrpt), "s")) Then
    $select = 1
EndIf

; run Evince, hide main window
Run($exepath & " " & $pdffile, "", @SW_HIDE)
WinWait($programtitle, "", 2)

If ProcessExists($procname) Then
    If WinExists($programtitle) Then
        WinActivate($programtitle)
        Send("^p") ; send Print command
        If $select = 0 Then ; hide Print dialog by moving it offscreen
            WinWait("Print")
            WinMove("Print", "", @DesktopWidth + 1, @DesktopHeight + 1)
            Sleep(200)
            Send("^{TAB}") ; Ctrl-Tab to Page Handling page
            Send("{Tab 3}") ; move down to "Select page size" option
            Send("{SPACE}") ; turn on that option
            Send("!p") ; print
            Sleep(200)
            WinClose($programtitle) ; close Evince window
            If ProcessExists($procname) Then
                ProcessClose($procname)
            EndIf
            Exit
        Else ; when select printer option is 1, don't hide dialog
            WinWait("Print")
            Sleep(200)
            Send("^{TAB}") ; Ctrl-Tab to Page Handling page
            Send("{Tab 3}") ; move down to "Select page size" option
            Send("{SPACE}") ; turn on that option
            Sleep(200)
            Send("^{TAB}") ; Ctrl-Tab back to General page
                        ; wait for user input
            WinWaitClose("Print")
            If WinExists($programtitle) Then
                WinClose($programtitle)
            EndIf
            Sleep(100)
            If ProcessExists($procname) Then
                ProcessClose($procname)
            EndIf
            Exit
        EndIf
    Else
        MsgBox(0, "", "Error")
        Exit
    EndIf
Else
    MsgBox(0, "", "Error launching Evince.")
    Exit
EndIf
Exit
Link to comment
Share on other sites

  • 5 months later...

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...