views:

699

answers:

5

I am trying to pin a form to the desktop, like the gadget sidebar.

It should not be affected by Win+D and Show desktop buttons.

Which is the best methode for this?

I can find the Progman and set the parent of my form to this, but I read it's not the best way.

+1  A: 

I could be wrong but, may be Win+D probably sends a global minimize message to all open windows

So Try making your form immune to window minimize message. using hooks

Heres a related article.

Hooking

Vivek Bernard
Win+M sends a minimize message to all windows, which you wouldn't need any sort of hook to intercept. Regular WndProc message handling is sufficient. Win+D forces windows minimized.
P Daddy
+3  A: 

Disclaimer : just because you can do something a certain way in WinForms without API calls or "hooking," doesn't mean that you should use that technique. The API calls for making a Form/Window immovable, topmost, etc. are really very simple. Note that the usual API "simple technique" will have the same problem as the technique demonstrated below of appearing over file and folder icons on the desktop.

Note that by "interfering" with the designed behaviors of the Windows-D key combination and the "Show Desktop" icon-hickey in the TaskBar, you are engaging in non-standard configuration of the user's machine : common "wisdom" indicates it's not a good idea to do this !

A "pseudo-sidebar" can be emulated in Vista in C# WinForms ... impervious to being hidden by Windows-D or use of the "Show Desktop" icon-hickey in the System Tray ... without API calls or "hooking" : but there's a catch : the Form/Window is going to appear on top of items on the Desktop (folders, files), and, by virtue of its being immovable, you won't be able to access the items "under it." If you're willing to "put up" with that limitation : read on :) Another "smaller weirdness" noted at the end of this.

Example :

  1. create a new Form solution in Visual Studio :

    a. set the Form's size, background color, etc. to taste

    b. add your controls, or user controls.

    c. set the Form's 'TopMost property to 'true if you want to always appear in front of other application's windows, 'false if you want other application's windows to be able to appear in front of it.

  2. set the 'ControlBox, 'MinimizeBox, and 'MaximizeBox properties of the Form to 'false.

  3. set the 'FormBorderStyle to one of the 'fixed styles shown in the Property Explorer drop-down. as you may know using FormBorderStyle = FixedToolWindow with the Text property of the Form an "empty string" : you'll have a window with no TitleBar and Caption. Discussion : yes, you could allow it to be resized if you wish : just write some code in the SizeChanged handler, and leave the Form unlocked.

  4. these event handlers should give you an idea of what's required to make the Form unclosable, unmovable, un-minimizable, etc.

......... rough sketch code p.o.c. follows : obviously you can refactor, improve ...

private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
    e.Cancel = true;
}

// set your Form's 'Top here ...
private void Form1_LocationChanged(object sender, EventArgs e)
{
    this.Top = 100;
    this.Left = Screen.PrimaryScreen.Bounds.Width - this.Width;
}

private void Form1_VisibleChanged(object sender, EventArgs e)
{
    if (this.WindowState == FormWindowState.Minimized) this.WindowState = FormWindowState.Normal;
}

private void Form1_Deactivate(object sender, EventArgs e)
{
    this.Activate();
}

private void Form1_SizeChanged(object sender, EventArgs e)
{
    if (this.WindowState == FormWindowState.Minimized) this.WindowState = FormWindowState.Normal;
}

private void button1_Click(object sender, EventArgs e)
{
    MessageBox.Show("button1 is alive");
}

What's that 'Click event handler for 'button1 doing in there ? Just to verify in my test that the Form was usable.

It's the re-activation of the Form in the 'Deactivate Event handler above that makes the Form immune to Windows-D and "Show Desktop" : but that also has a strange side-effect in Vista : when you switch focus away from the Form's window (by, for example, clicking on a folder on the Desktop) : the TaskBar will bounce-up, stay up, (if it's hidden) and blink on and off a while : I guess to show you it's yearning to be active.

Putting up with a stuck-open TaskBar may be yet another price of using this "ersatz sidebar," and not using API's.

Note : don't forget : you want 'Opacity : you got 'Opacity :)

[1] Note : You do want to think about giving the user a way to hide the Form or close it ? [/1]

BillW
Thanks, but the big problem here is that it does not stick to the desktop.It is vital, as the Vista/W7 sidebar, that it keeps sticking on the desktop, and should never go on top of other windows.
Rogier21
+1  A: 

It sounds like what you're after is an Application Desktop Toolbar.

P Daddy
A: 

Thanks all for the answers,

I had this methode at first:

    [DllImport("User32.dll")]
    static extern IntPtr FindWindow(String lpClassName, String lpWindowName);
    [DllImport("user32.dll", SetLastError = true)]
    static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);
    [DllImport("user32.dll")]
    static extern int SetParent(IntPtr hWndChild, IntPtr hWndNewParent);

        IntPtr pWnd = FindWindow("Progman", null);
        pWnd = FindWindowEx(pWnd, IntPtr.Zero, "SHELLDLL_DefVIew", null);
        pWnd = FindWindowEx(pWnd, IntPtr.Zero, "SysListView32", null);
        IntPtr tWnd = this.Handle;
        SetParent(tWnd, pWnd);

But the marjor issue is that child windows are also parented to the deskop, and you cannot use any form of opacity or transparency.

Rogier21
A: 

use the following code and pass the window handle to the function while form load hope fully this resolves your problem

public void SetFormOnDesktop(IntPtr hwnd) {      
IntPtr hwndf = hwnd;
IntPtr hwndParent = FindWindow("ProgMan", null);
SetParent(hwndf, hwndParent);
}
JKS