1

我有一个问题要绝对将我的窗口放在前面,但是当我启动一个打印对话框时,我无论如何都找不到将我的窗口放在前面:我必须将我的窗口放在打印对话框上执行 TopMost,但出现任务栏虽然是隐藏的。

我的表单窗口中的代码将其最大化并整体放置:

this.StartPosition = System.Windows.Forms.FormStartPosition.Manual;
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
this.WindowState = System.Windows.Forms.FormWindowState.Maximized;
this.TopMost = true;

启动打印对话框的代码:

PrinterSettings printerSettings = new PrinterSettings();
IntPtr hDevMode = printerSettings.GetHdevmode(printerSettings.DefaultPageSettings);
IntPtr pDevMode = GlobalLock(hDevMode);
int sizeNeeded = DocumentProperties(IntPtr.Zero, IntPtr.Zero, printerSettings.PrinterName, IntPtr.Zero, pDevMode, 0);
IntPtr devModeData = Marshal.AllocHGlobal(sizeNeeded);

DocumentProperties(IntPtr.Zero, IntPtr.Zero, printerSettings.PrinterName, devModeData, pDevMode, 14);
// <--- Here the print dialog appears and the thread stops till I close the dialog

GlobalUnlock(hDevMode);
printerSettings.SetHdevmode(devModeData);
printerSettings.DefaultPageSettings.SetHdevmode(devModeData);
GlobalFree(hDevMode);
Marshal.FreeHGlobal(devModeData);

这是我隐藏任务栏的代码:

public class Taskbar
{
    [System.Runtime.InteropServices.DllImport("user32.dll")]
    private static extern int FindWindow(string className, string windowText);

    [System.Runtime.InteropServices.DllImport("user32.dll")]
    private static extern int ShowWindow(int hwnd, int command);

    private const int SW_HIDE = 0;
    private const int SW_SHOW = 1;

    public Taskbar()
    {
    }

    protected static int Handle
    {
        get
        {
            return FindWindow("Shell_TrayWnd", "");
        }
    }

    public static void Show()
    {
        ShowWindow(Handle, SW_SHOW);
    }

    public static void Hide()
    {
        ShowWindow(Handle, SW_HIDE);
    }
}

我尝试了这段代码,在“this.TopMost = true;”之后也在我的表单中调用了 SetWinFullScreen 最大化形式,但它也不起作用:

public class WinApi
{
    [DllImport("user32.dll", EntryPoint = "GetSystemMetrics")]
    private static extern int GetSystemMetrics(int which);

    [DllImport("user32.dll")]
    private static extern void
        SetWindowPos(IntPtr hwnd, IntPtr hwndInsertAfter,
                     int X, int Y, int width, int height, uint flags);        

    private const int SM_CXSCREEN = 0;
    private const int SM_CYSCREEN = 1;
    private static IntPtr HWND_TOP = IntPtr.Zero;
    private const int SWP_SHOWWINDOW = 64; // 0×0040

    public static int ScreenX
    {
        get { return GetSystemMetrics(SM_CXSCREEN);}
    }

    public static int ScreenY
    {
        get { return GetSystemMetrics(SM_CYSCREEN);}
    }

    public static void SetWinFullScreen(IntPtr hwnd)
    {
        SetWindowPos(hwnd, HWND_TOP, 0, 0, ScreenX, ScreenY, SWP_SHOWWINDOW);
    }
}

在所有情况下,当启动打印对话框时,会出现任务栏并且用户可以单击它,因为它位于所有内容的前面。

有没有办法在后台启动此打印对话框或将我的表单绝对放在最上面(不出现任何任务栏或对话框)?

编辑:问题出在这一行:

DocumentProperties(IntPtr.Zero, IntPtr.Zero, printerSettings.PrinterName, devModeData, pDevMode, 14);

此行启动打印对话框,然后出现任务栏(隐藏或不隐藏)。

4

2 回答 2

0

此链接对于接近解决该问题很有用: Hide Start Orb on Vista / Win 7 in C#

按照链接的步骤,我添加到我的任务栏类:

[System.Runtime.InteropServices.DllImport("user32.dll")]
private static extern IntPtr FindWindowEx(
           IntPtr parentHwnd,
           IntPtr childAfterHwnd,
           IntPtr className,
           string windowText);

public static void Show()
{
        ShowWindow(Handle, SW_SHOW);
        ShowWindow(FindWindowEx(IntPtr.Zero, IntPtr.Zero, (IntPtr)0xC017, null), SW_SHOW);
}

public static void Hide()
{
        ShowWindow(Handle, SW_HIDE);
        ShowWindow(FindWindowEx(IntPtr.Zero, IntPtr.Zero, (IntPtr)0xC017, null), SW_HIDE);
}

并使用 TopMost。然后,当对话框出现时,我控制了这一时刻并将我的应用程序快速集中在“弹出”前面,但这次没有显示任务栏/Windows 图标,用户什么也不能点击。

不是完美的解决方案,但对我有效。

于 2012-08-17T02:19:09.970 回答
0

打印对话框不是表单,它是从表单继承的控件,如文本框和组合框。所以你不应该期望 topmost 申请。下面的重点是我的。

最顶层表单是与所有其他(非最顶层)表单重叠的表单,即使它不是活动表单或前景表单。最顶层的表单始终显示在桌面上窗口 z 顺序的最高点。您可以使用此属性来创建始终显示在应用程序中的表单,例如查找和替换工具窗口。

http://msdn.microsoft.com/en-us/library/system.windows.forms.form.topmost.aspx

于 2012-08-10T14:30:13.420 回答