本文介绍了获取PrintDialog的模式对话框句柄的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在.net 2.0上有一个Windows应用程序.在 Form1 上,我打开一个 PrintDialog .如何从我的代码中获取该对话框的句柄?

I have an windows app on .net 2.0. On Form1, I open a PrintDialog. How can I get that dialog's handle from my code?

我尝试了很多win32函数: EnumWindows EnumChildWindows FindWindow FindWindowEx ,但是它不能找到我的 PrintDialog .我所能找到的只是 Form1 ,它的子级就是它的控件.我无法获得 PrintDialog的句柄.

I have tried a lot of win32 functions: EnumWindows, EnumChildWindows, FindWindow, FindWindowEx but it cannot find my PrintDialog. All I can find is just Form1 and its children are controls on it. There's no way I can get PrintDialog's handle.

我尝试过的一些代码:

导入win32:

    [DllImport("user32.dll", SetLastError = true)]
    public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

调用win32函数:

using (PrintDialog dlg = new PrintDialog
                                 {
                                     AllowCurrentPage = false,
                                     AllowSomePages = true,
                                     AllowSelection = false
                                 })
{
      IntPtr printHandle = CustomPrintDialog.FindWindow("#32770", "Print");
      // some logic with printHandle go here
      if (dlg.ShowDialog(this)==DialogResult.OK){
          // some logic go here
      }
}

我已经检查过Spy ++,仍然有一个 PrintDialog 窗口.该 PrintDialog 窗口的父窗口的句柄与 Form1的句柄完全相同.

I have checked with Spy++, there is still a PrintDialog window. That PrintDialog window has Parent Window's handle exactly same as Form1's handle.

有人可以帮助我从其父窗口获取 PrintDialog的句柄吗?

Does anyone can help me to get a PrintDialog's handle from its parent window?

推荐答案

问题是 ShowDialog 方法的执行期间创建了 PrintDialog 的基础窗口.在调用此方法之前它不存在,这就是为什么您无法找到窗口的原因.因此,您必须将工作注入到 ShowDialog 中的 PrintDialog 句柄上.这可以通过 Control.BeginInvoke 方法的帮助来实现:

The problem is that underlying window for the PrintDialog is created during the execution of the ShowDialog method. It does not exist before this method's invocation, that's why you cannot find the window.So you must inject your work on PrintDialog handle inside ShowDialog. This can be achieved with the help of Control.BeginInvoke method:

public partial class Form1 : Form
{
    ...

    private ShowPrintDialog()
    {
        using (var pd = new PrintDialog())
        {
            BeginInvoke(new MethodInvoker(TweakPrintDialog));
            if (pd.ShowDialog(this) == DialogResult.OK)
            {
                // printing
            }
        }
    }

    private void TweakPrintDialog()
    {
        var printDialogHandle = GetActiveWindow();
        // do your tweaking here
    }

    [DllImport("user32.dll", SetLastError = true)]
    private static extern IntPtr GetActiveWindow();
}

另一个问题是找到 PrintDialog 窗口. GetActiveWindow 实际上是完成此操作的一种直接方法,因为该对话框预计在 ShowDialog 处于活动状态时处于活动状态.更可靠的解决方案可能包括枚举顶级窗口并分析其所有者和/或其他道具.这是一种可能的方法,假设打印"对话框是当前表单所拥有的唯一窗口.上一个代码段中的 TweakPrintDialog 方法已被修改:

Another problem is to find PrintDialog window. GetActiveWindow is really a straightforward way to accomplish this, because the dialog is expected to be active while ShowDialog is in action.The more reliable solution may include enumerating top-level windows and analyzing their owners and/or other props. Here is one possible approach, assuming that print dialog is the only window at the moment that is owned by the form. The TweakPrintDialog method from the previous snippet is modified:

    private void TweakPrintDialog()
    {
        uint processId;
        var threadId = GetWindowThreadProcessId(this.Handle, out processId);
        EnumThreadWindows(threadId, FindPrintDialog, IntPtr.Zero);
        // printDialogHandle field now contains the found handle
        // do your tweaking here
    }

    private IntPtr printDialogHandle;

    private bool FindPrintDialog(IntPtr handle, IntPtr lParam)
    {
        if (GetWindow(handle, GW_OWNER) == this.Handle)
        {
            printDialogHandle = handle;
            return false;
        }
        else
        {
            return true;
        }
    }

    [DllImport("user32.dll", SetLastError = true)]
    private static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);

    private delegate bool EnumWindowProc(IntPtr handle, IntPtr lParam);

    [DllImport("user32.dll", SetLastError = true)]
    private static extern bool EnumThreadWindows(uint threadId, EnumWindowProc enumProc, IntPtr lParam);

    private const uint GW_OWNER = 4;

    [DllImport("user32.dll", SetLastError = true)]
    private static extern IntPtr GetWindow(IntPtr handle, uint cmd);

这篇关于获取PrintDialog的模式对话框句柄的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-19 14:44
查看更多