首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >获取PrintDialog的模态对话框句柄

获取PrintDialog的模态对话框句柄
EN

Stack Overflow用户
提问于 2014-03-12 18:08:14
回答 1查看 3.1K关注 0票数 5

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

我尝试过很多win32函数:EnumWindowsEnumChildWindowsFindWindowFindWindowEx,但它找不到我的PrintDialog。我所能找到的只有Form1,它的子代是对它的控制。我不可能得到PrintDialog's句柄。

我尝试过的一些代码:

导入win32:

代码语言:javascript
复制
    [DllImport("user32.dll", SetLastError = true)]
    public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

调用win32函数:

代码语言:javascript
复制
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's句柄完全相同。

有人能帮我从父窗口获取PrintDialog's句柄吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-03-14 11:10:42

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

代码语言:javascript
复制
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方法:

代码语言:javascript
复制
    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);
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22360213

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档