Как узнать, сколько времени мне нужно ждать PrintDialog после отправки команд на печать (чтобы нажать кнопку «Ctrl + P»)? - PullRequest
1 голос
/ 29 июля 2011

Я пишу консольное приложение, используя C #, в котором я запускаю задания на печать через код.Моя проблема в том, что я не знаю, сколько времени мне нужно ждать, пока Print Dialog после отправки команд в Print.В настоящее время я использую Thread sleep 1000 миллисекунд.

//Sending Commands to Print(to press "Ctrl+P" button).
 SendKeys.SendWait("^(p)");

 Thread.Sleep(1000);

 //Sending Commands to Print(to press "Enter" Button).
 SendKeys.SendWait("{ENTER}");

Может кто-нибудь помочь мне решить эту проблему, пожалуйста.Любая помощь будет оценена.

Заранее спасибо

Обновление:

Вот весь мой код:

//Launch the file from the location specified in.
White.Core.Application application =White.Core.Application.Launch(@path);

Console.WriteLine("launch is done");

Thread.Sleep(_delayOfPrint);

//Sending Commands to Print(to press "Ctrl+P" button).
SendKeys.SendWait("^(p)");

Thread.Sleep(1000);

//Sending Commands to Print(to press "Enter" Button).
SendKeys.SendWait("{ENTER}");

//Get the current time as the document fired for print job.
_printedTime = DateTime.Now;

Thread.Sleep(1500);

//Closing the window.
SendKeys.SendWait("%{F4}");

1 Ответ

4 голосов
/ 29 июля 2011

У меня было бы максимальное ожидание в несколько секунд, но в течение этого времени я периодически использовал бы функцию Win32 FindWindowEx, чтобы увидеть, действительно ли открывается диалоговое окно печати, и если это так, продолжайте.Вы можете получить главное окно процесса с кодом, подобным следующему:

Process[] processes = Process.GetProcessesByName(appName);
foreach (Process p in processes)
{
     IntPtr pFoundWindow = p.MainWindowHandle;
}

Затем вы можете передать дескриптор найденного главного окна в FindWindowEx, чтобы просмотреть дочерние окна для проверки на наличие диалога печати.FindWindowEx имеет подписи PInvoke, такие как:

[DllImport("user32.dll", SetLastError = true)]
static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);

[DllImport("user32.dll", SetLastError = true)]
public static extern IntPtr FindWindowEx(IntPtr parentHandle, IntPtr childAfter, string className,  IntPtr windowTitle);

Edit 2: Так как OP кажется требовательным, я даю отлично работающую функцию, я написал общую, которая выполняет трюк, и протестировалЭто.Вот он, рабочий общий код для ожидания любого дочернего окна.Вызовите как WaitForChildWindow ("myApp", "Print", 5000) для этого случая:

/// <summary>
/// Wait for a child window of an application to appear
/// </summary>
/// <param name="appName">Application name to check (will check all instances)</param>
/// <param name="childWindowName">Name of child window to look for (titlebar)</param>
/// <param name="timeout">Maximum time, in milliseconds, to wait</param>
/// <returns>True if the window was found; false if it wasn't.</returns>
public static bool WaitForChildWindow(string appName, string childWindowName, int timeout)
{
    int sleepTime = timeout;
    while (sleepTime > 0)
    {
        Process[] processes = Process.GetProcessesByName(appName);
        foreach (Process p in processes)
        {
            IntPtr pMainWindow = p.MainWindowHandle;
            IntPtr pFoundWindow = FindWindowEx(pMainWindow, IntPtr.Zero, null, childWindowName);
            if (pFoundWindow != IntPtr.Zero)
                return true;
        }
        Thread.Sleep(100);
        sleepTime -= 100;
    }

    // Timed out!
    return false;
}

Редактировать 3: Вот еще один способ сделать это для окон, находящихся в простой собственности, которые неесть дочерние отношения:

[DllImport("user32.dll", SetLastError = true)]
static extern uint GetWindowThreadProcessId(IntPtr hwnd, IntPtr processId);
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool EnumThreadWindows(uint dwThreadId, EnumThreadDelegate lpfn, IntPtr lParam);
[DllImport("user32", SetLastError = true, CharSet = CharSet.Auto)]
private extern static int GetWindowText(IntPtr hWnd, StringBuilder text, int maxCount);

public delegate bool EnumThreadDelegate(IntPtr hwnd, IntPtr lParam);

static bool EnumThreadCallback(IntPtr hWnd, IntPtr lParam)
{
    StringBuilder text = new StringBuilder(500);
    GetWindowText(hWnd, text, 500);
    if (text.ToString() == "Print")
        return false;
    return true;
}

public static bool FindThreadPrintWindow(uint threadId)
{
    return !EnumThreadWindows(threadId, EnumThreadCallback, IntPtr.Zero);
}

public static bool WaitForOwnedPrintWindow(string appName, int timeout)
{
    int sleepTime = timeout;
    while (sleepTime > 0)
    {
        Process[] processes = Process.GetProcessesByName(appName);
        foreach (Process p in processes)
        {
            IntPtr pMainWindow = p.MainWindowHandle;
            uint threadId = GetWindowThreadProcessId(pMainWindow, IntPtr.Zero);
            if (FindThreadPrintWindow(threadId))
                return true;
        }
        Thread.Sleep(100);
        sleepTime -= 100;
    }

    // Timed out!
    return false;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...