views:

2238

answers:

5

I saw this C++ code on a forum which minimizes all open windows

#define MIN_ALL        419
#define MIN_ALL_UNDO   416

int main(int argc, char* argv[])
{
    HWND lHwnd = FindWindow("Shell_TrayWnd",NULL);
    SendMessage(lHwnd,WM_COMMAND,MIN_ALL,0);
    Sleep(2000);
    SendMessage(lHwnd,WM_COMMAND,MIN_ALL_UNDO,0);
    return 0;
}

How can I access the FindWindow and SendMessage API function and the HWND type in C#.net?

+2  A: 

The site www.pinvoke.net has a lot of the information you require. For instance, this article on SendMessage and FindWindow:

http://www.pinvoke.net/default.aspx/user32.SendMessage http://www.pinvoke.net/default.aspx/user32.FindWindow

It's rather technical - of course - but basically you use p/invoke to call on the FindWindow and SendMessage API functions to accomplish what you want. =)

J. Steen
When I try adding the import code to my existing code, Visual C# 2008 Express tells me that it expects either "class, delegate, interface or struct" instead of IntPtr.
Charlie Somerville
My bad, solved that problem :)
Charlie Somerville
Awesome. Do tell if you get it to work! =)
J. Steen
+1  A: 

Not exactly the easiest way, but the manual way is to call the C++ implementation. http://pinvoke.net helps:

findwindow search results: http://pinvoke.net/search.aspx?search=findwindow&namespace=[All]

approximately the fourth result down helps in your case.

DNeoMatrix
+1  A: 

I've previously blogged on how to minimize & maximize using P/Invoke from C#: http://www.improve.dk/blog/2007/04/10/minimizing-and-maximizing-windows

Mark S. Rasmussen
+4  A: 

PInvoke.net is your friend :-)

using System;
using System.Runtime.InteropServices;

namespace ConsoleApplication1 {
class Program {
    [DllImport("user32.dll", EntryPoint = "FindWindow", SetLastError = true)]
    static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
    [DllImport("user32.dll", EntryPoint = "SendMessage", SetLastError = true)]
    static extern IntPtr SendMessage(IntPtr hWnd, Int32 Msg, IntPtr wParam, IntPtr lParam);

    const int WM_COMMAND = 0x111;
    const int MIN_ALL = 419;
    const int MIN_ALL_UNDO = 416;

    static void Main(string[] args) {
        IntPtr lHwnd = FindWindow("Shell_TrayWnd", null);
        SendMessage(lHwnd, WM_COMMAND, (IntPtr)MIN_ALL, IntPtr.Zero); 
        System.Threading.Thread.Sleep(2000);
        SendMessage(lHwnd, WM_COMMAND, (IntPtr)MIN_ALL_UNDO, IntPtr.Zero);
    }
}
}
Stanislav Kniazev
Thanks!This one works like a charm!
Charlie Somerville
+1  A: 

A similar result can be achieved by sending these keyboard events to bring the Taskbar popup menu and send it the letter "M":

public class DesktopHelper
{
    [DllImport("user32.dll")]
    static extern void keybd_event(byte bVk, byte bScan, uint dwFlags, int dwExtraInfo);

    /// <summary>
    /// Shows the desktop.
    /// </summary>
    public static void ShowDesktop()
    {
        keybd_event(0x5B, 0, 0, 0);
        keybd_event(0x4D, 0, 0, 0);
        keybd_event(0x5B, 0, 0x2, 0);
    }
}
Groo
Not really the most... secure and straight forward solution, but inspiring! ;)
J. Steen
:) It's a silly way to do it, but, after all: http://support.microsoft.com/kb/194914.
Groo