1

I have a question to put my window in front of all absolutely, but when I launch a print dialog I cant found anyway to hold my window in front: I got to hold my window over the print dialog doing the TopMost, but the taskbar appears although is hidden.

The code in my form window to maximize it and put it overall:

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

The code that launch the print dialog:

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);

Here the code where I hide the taskbar:

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);
    }
}

I tried this code also calling SetWinFullScreen in my form after "this.TopMost = true;" to maximize the form but it doesn't work either:

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);
    }
}

In all cases, when the print dialog is launched, the taskbar appears and the user can click it because is it in front of everything.

Is there a way to launch this print dialog in the background or put my form topmost absolutely (without any taskbar or dialog appearing) ?

Edited: The problem is in this line:

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

This line launch the print dialog and then taskbar appears (hide or not).

Eldoran
  • 51
  • 6
  • 4
    Taking a page from Raymond Chen here but, Have you considered what would happen if two programs tried to do this at the same time? – asawyer Aug 10 '12 at 13:27
  • Are you trying to write a kiosk application? – Jodrell Aug 10 '12 at 13:29
  • 2
    @asawyer for reference: http://blogs.msdn.com/b/oldnewthing/archive/2005/06/07/426294.aspx – rene Aug 10 '12 at 13:32
  • 2
    Bunch of code but the real troublemaker isn't visible. Do *not* mess with the taskbar, *never* display a dialog on a worker thread, *always* use the ShowDialog(owner) overload. Which will now throw an InvalidOperationException when you do it wrong. – Hans Passant Aug 10 '12 at 13:46
  • Why bother having a print dialog if you don't want it to have focus (be the most prominent)??? :-( – GrayFox374 Aug 10 '12 at 14:23
  • I want to do that because I want the print dialog in background, really is not the best solution because I want to get the information of the print dialog but I didnt find how to get this information (in each printer is different, and in my printer MITSUBISHI there is "remain pages", I didnt find any way to get the remaining pages to control it, then I thought in launch print dialog in background, get a print screen (I have the methods now to do this) and extract the information in the window recognizing the values graphically. It seems hard, but I dont know other way... – Eldoran Aug 10 '12 at 15:23
  • Also from Raymond Chen : http://blogs.msdn.com/b/oldnewthing/archive/2011/03/10/10138969.aspx – Guillaume Aug 10 '12 at 15:24
  • Hans Passant: is not a normal print dialog, is the print dialog of preferences, where appears the remaining pages of my printer (not in the normal print dialog of the form). Searching in the web, I found this way to launch this special dialog with DocumentProperties – Eldoran Aug 10 '12 at 15:27
  • The dialog is this: http://imageshack.us/photo/my-images/837/imagegu.png/ I have a window maximized and I want to take a capture of this window but when I launch the dialog, taskbar appears over my maximized, topmost, ..., window. (See the code the things I use) – Eldoran Aug 10 '12 at 15:35
  • rene: very philosophical but in my case, I only have one program "fighting" for the first place and never will install other that fight with it. Im sure that it is possible one of two: launch dialog underground or get the remaining pages information of this dialog programmatically. I was searching for the second but when I didnt find anything, I thought in find another way: launch the dialog, capture the image of the dialog, close the dialog, recognize the image values. – Eldoran Aug 10 '12 at 16:02
  • Jodrell: more or less, is an application that will be always in topscreen without taskbar to use it with touch screen. – Eldoran Aug 10 '12 at 16:53

2 Answers2

0

A print dialog is not a form, it is a control that inherits from form, like textbox and combobox. So you shouldn't expect topmost to apply. The emphasis below is mine.

A topmost form is a form that overlaps all the other (non-topmost) forms even if it is not the active or foreground form. Topmost forms are always displayed at the highest point in the z-order of the windows on the desktop. You can use this property to create a form that is always displayed in your application, such as a Find and Replace tool window.

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

GrayFox374
  • 1,742
  • 9
  • 13
  • TopMost is not the unique thing I tried, you can see the code, what can I do to make my form over all windows/popups/etc... then? Thanks for your answer. – Eldoran Aug 10 '12 at 15:13
  • That's it. The Dialogs all work this way. If you can't accept that as part of your solution, handle all of the print dialog stuff through the main form, and be done with it. Think of what you are asking for. You want a popup, but as soon as it pops up, you suppress it so that the main form is on top. How then would you ever give control to the popup long enough to let it do what you need it to do? – GrayFox374 Aug 10 '12 at 17:10
0

This link was useful to get near solution to the problem: Hide Start Orb on Vista / Win 7 in C#

Following the steps of the link, I Adding to my Taskbar class:

[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);
}

And using the TopMost. Then when the dialog box appears I control the moment and focus my application fastly to put in front of the 'popup' but this time no show taskbar/windows icon and the user cant click nothing.

Is not the perfect solution but it is valid for me.

Community
  • 1
  • 1
Eldoran
  • 51
  • 6