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?
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.
Some code that i have tried:
Import win32:
[DllImport("user32.dll", SetLastError = true)]
public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
calling win32 functions:
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
}
}
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.
Does anyone can help me to get a PrintDialog's
handle from its parent window?
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();
}
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);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With