C # Захват Microsoft Печать в PDF диалог - PullRequest
0 голосов
/ 04 сентября 2018

Я хотел бы захватить и отключить Savefiledialog, который отображается при использовании драйвера Microsoft Print to PDF из приложения, которое не является офисным. Затем программно введите путь к файлу, возможно, с помощью System.Windows.Automation.

Я не могу найти дескриптор SaveFileDialog, когда он отображается. Я полагаю, что могу справиться с частью Windows.Automation.

Я хотел бы использовать драйвер Microsoft, поскольку он поставляется со всеми окнами 10.

Существуют ли другие способы захвата / подавления этого диалога? В настоящее время я делаю это с другим драйвером PDF на моем локальном компьютере через реестр. Но я бы хотел перейти на Microsoft PDF, поскольку он является стандартным.

Тема: Как программно печатать в файл PDF без запроса имени файла в C # с помощью принтера Microsoft Print To PDF, который поставляется с Windows 10 - Не решает мою проблему и печатает пустую страницу при запуске из Revit API. Autodesk Revit должен начать печать (и выполняется через его API).

Код для поиска диалога от user32.dll

public static List<IntPtr>GetChildWindows( IntPtr parent) {
  List<IntPtr>result=new List<IntPtr>();
  GCHandle listHandle=GCHandle.Alloc(result);
  try {
    EnumWindowProc childProc=new EnumWindowProc(EnumWindow);
    EnumChildWindows(parent, childProc, GCHandle.ToIntPtr(listHandle));
  }
  finally {
    if (listHandle.IsAllocated) listHandle.Free();
  }
  return result;
}

public static string GetText(IntPtr hWnd) {
  int length=GetWindowTextLength(hWnd);
  StringBuilder sb=new StringBuilder(length + 1);
  GetWindowText(hWnd, sb, sb.Capacity);
  return sb.ToString();
}

private void Test() {
  Process[] revits=Process.GetProcessesByName( "Revit");
  List<IntPtr>children=GetChildWindows( revits[0].MainWindowHandle);
  var names=new List<string>();
  foreach (var child in children) {
    names.Add(GetText(child));
  }
}

1 Ответ

0 голосов
/ 05 сентября 2018

Я провел несколько тестов на своей собственной системе, и кажется, что при перечислении окон верхнего уровня будет найдено диалоговое окно «Сохранить файл». Я пробовал печатать на принтере MS PDF из нескольких программ, и результаты были одинаковыми. Ниже приведен код, адаптированный из примера перечисления окна MS Docs . Я добавил код, чтобы получить идентификатор процесса, чтобы вы могли убедиться, что это ваше окно.

// P/Invoke declarations
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);
            Console.WriteLine($"Found it! ProcID: {procId}");
        }
    }
    return true;
}

void Main()
{
   EnumWindows(new EnumWindowsProc(EnumTheWindows), IntPtr.Zero);
}
...