1

I am trying to intercept the "Save Print Output As" dialog in Revit so I can programmatically insert a path and file name. This dialog pops up every time for every view or sheet that is printed when printed separately or only once if a combined document is printed once.

So far, I have assembled the viewset however when it comes time to print, I do not have access to the window because it opens and closes too soon. I am hoping there is a more "hacky" way to intercept it.

In Revit, the event handler: a.ControlledApplication.DocumentPrinting += new EventHandler<Autodesk.Revit.DB.Events.DocumentPrintingEventArgs>(AppDocumentPrinting); only activates after the name/destination has been selected but before the document has printed so it doesnt quite help.

I have found this post which explains how to cycle through the windows which I am able to do but I don't know how to listen for the window to be opened and I can't find anything on it. The SO post also mentions something about p/invoke but I haven't found much documentation on it.

I have looked at subscribing to events but I haven't found anything on being able to subscribe to listen to a window opening.

My printer setup is currently Microsoft print to pdf which doesn't seem to allow the PrintToFile option. Regardless though, I would still like to be able to handle the dialog if it pops up if it is possible.

Any and all help/direction is appreciated.

My code:

EnumWindows(new EnumWindowsProc(EnumTheWindows), IntPtr.Zero); // cant find window because it doesnt exist

printManager.SubmitPrint(); // Window opens for user input here and then closes
// doc.Print(pdfviewSet); //  option B: Window opens for user input here and then closes

EnumWindows(new EnumWindowsProc(EnumTheWindows), IntPtr.Zero); // cant find window because it doesnt exist

code adapted from other SO post

// P/Invoke declarations <--- suspect the answer might lie here?
protected delegate bool EnumWindowsProc(IntPtr hWnd, IntPtr lParam);
[DllImport("user32.dll", CharSet = CharSet.Unicode)]
protected static extern int GetWindowText(IntPtr hWnd, StringBuilder strText, int maxCount);
[DllImport("user32.dll", CharSet = CharSet.Unicode)]
protected static extern int GetWindowTextLength(IntPtr hWnd);
[DllImport("user32.dll")]
protected static extern bool EnumWindows(EnumWindowsProc enumProc, IntPtr lParam);
[DllImport("user32.dll")]
protected static extern bool IsWindowVisible(IntPtr hWnd);
[DllImport("user32.dll", SetLastError = true)]
static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint processId);

// Callback for examining the window
protected static bool EnumTheWindows(IntPtr hWnd, IntPtr lParam)
{
    int size = GetWindowTextLength(hWnd);
    if (size++ > 0 && IsWindowVisible(hWnd))
{
StringBuilder sb = new StringBuilder(size);
GetWindowText(hWnd, sb, size);
if (sb.ToString().Equals("Save Print Output As", StringComparison.Ordinal))
{
    uint procId = 0;
    GetWindowThreadProcessId(hWnd, out procId);
    Debug.WriteLine($"Found it! ProcID: {procId}");

    FlaUI.Core.Application application = FlaUI.Core.Application.Attach(Process.GetCurrentProcess());
    string appName = application.Name;
    Window mainWindow = application.GetMainWindow(new UIA3Automation());
    ConditionFactory cf = new ConditionFactory(new UIA3PropertyLibrary());
mainWindow.FindFirstDescendant(cf.ByProcessId(int.Parse(procId.ToString()))).AsTextBox().Enter("test"); // try to enter info here but returns null because window has closed.
                    
    }
 }
 return true;
}

Dialog I am trying to intercept: enter image description here

Other info I have looked at: p/invoke - not too sure how to implement this.

tried this but printed a blank page

How to subscribe to events

Tim Corry's Youtube video on subscribing to events

Cflux
  • 1,423
  • 3
  • 19
  • 39
  • 1
    [WindowPattern.WindowOpenedEvent](https://learn.microsoft.com/en-us/dotnet/api/system.windows.automation.windowpattern.windowopenedevent) -- Similar: [Capture button click inside a messagebox in another application](https://stackoverflow.com/a/58233065/7444103) – Jimi Jun 30 '21 at 23:06
  • 1
    There is a similar answer here https://stackoverflow.com/a/67199236/403671 using UI Automation: https://learn.microsoft.com/en-us/dotnet/framework/ui-automation/ui-automation-overview – Simon Mourier Jul 01 '21 at 05:31

0 Answers0