我在.net 2.0上有一个Windows应用程序。在Form1
上,我打开一个PrintDialog
。如何从我的代码中获取该对话框的句柄?
我尝试了很多win32函数:EnumWindows
,EnumChildWindows
,FindWindow
,FindWindowEx
,但是找不到我的PrintDialog
。我所能找到的只是Form1
,它的子项就是它的控件。我无法获得PrintDialog's
句柄。
我尝试过的一些代码:
导入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's
句柄完全相同。有谁能帮助我从其父窗口获取
PrintDialog's
句柄? 最佳答案
问题是在PrintDialog
方法执行期间创建了ShowDialog
的基础窗口。在调用此方法之前它不存在,这就是为什么您无法找到窗口的原因。
因此,您必须将工作注入(inject)PrintDialog
中的ShowDialog
句柄中。这可以通过Control.BeginInvoke
方法来实现:
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
起作用时,该对话框预计将处于事件状态。更可靠的解决方案可能包括枚举顶级窗口并分析其所有者和/或其他 Prop 。这是一种可能的方法,假设“打印”对话框是当前表单所拥有的唯一窗口。先前代码段中的
TweakPrintDialog
方法已修改: 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);
关于c# - 获取PrintDialog的模式对话框句柄,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/22360213/