Link to home
Start Free TrialLog in
Avatar of DarrinE
DarrinE

asked on

Minimize All Windows

I am trying to write a C function that will minimize all open windows - this in itself is not a problem - but the function is slow and cumbersome ( I enumerate all windows, check to see if they are the parent window and minimize it)

I have the address to access the code for the function I need - but lack the experience to convert this to be used in a program written in C

If someone were to look at the following and see if they could help I would be greatful <s>

http://msdn.microsoft.com/library/psdk/shellcc/shell/Objects/Shell/MinimizeAll.htm
 
Avatar of MichaelS
MichaelS

As you can see there are some

Requirements
  Version 4.71 and later of Shell32.dll

  Windows NT/2000: Requires Windows 2000 (or Windows NT 4.0 with Internet Explorer 4.0 or later)..
  Windows 95/98: Requires Windows 98 (or Windows 95 with Internet Explorer 4.0 or later)..
  Windows CE: Unsupported.
  Header: Declared in shldisp.h.
In some way you need to get a pointer to a class named "Shell" and call its member function . I don't understand really how you will get the pointer ( except if u manually open SHELL32.DLL and get an address in this object )
..

In all cases I do believe that enumerating will work with C , w/o messing with classes or Shell Objects .
Avatar of jkr
Use 'SendMessage()' to broadcast a minimize message to all top level windows, e.g.:

SendMessage ( HWND_BROADCAST, WM_SYSCOMMAND, SC_MINIMIZE, 0);

This should be sufficiant...
SendMessage is good , but minimizing or not is then up to the program and not up to the caller .
Avatar of DarrinE

ASKER

The SendMessage function is not adequate because it does not determine if the toplevel window is a parent - for example a dropdown list of a combo is actually a toplevel window and it tries to (does) minimize it

I can post the code for minimizing all windows if someone wants to see it -
the most important part of the routine (other than enumerating the windows) is this  :
                        if( (! GetWindowLong(hwnd, GWL_HWNDPARENT)) && IsWindowVisible(hwnd)  )
                        {
                              /* if it matches our criteria - minimize it */
//                              ShowWindow(hwnd, SW_HIDE);
                              CloseWindow(hwnd);
                              hHidden[nHideIndex++] = hwnd;
                        }
We test the window to see if it is a parent with the getWindowLong API and if it is then we minimize it

What I am trying to do is get access to the API to "minimize all windows" which is in the taskbar menu (right click on the task bar and you'll see it) - alternatively if you press the "Windows button" and M all windows will minimize - the function resides in the Shell so it must be able to be accessed - the only pointer I can find is the listing at

http://msdn.microsoft.com/library/psdk/shellcc/shell/Objects/Shell/MinimizeAll.htm 
 
on MSDN

Thanks for your attempt at answering the query -


Well, the effect should be the same - did you try my suggestion?
Avatar of DarrinE

ASKER

Yes - I tried it - and what I said is what happened - ALL TOPLEVEL Windows minimized like they should - but so did all non parent toplevel windows (like the dropdown list on the combo) - it also affects the hidden windows on the desktop and makes them visible (as minimized windows with no caption)

I know that the function must be able to be accessed through desk.cpl or one of the main CPL's as most other UNDOCUMENTED functions are there for example :

      CreateProcess( NULL, // No module name (use command line).
            "rundll32.exe shell32.dll,Control_RunDLL user,,tilechildwindows, // Command line.
            NULL,             // Process handle not inheritable.
            NULL,             // Thread handle not inheritable.
            FALSE,            // Set handle inheritance to FALSE.
            0,                // No creation flags.
            NULL,             // Use parent’s environment block.
            NULL,             // Use parent’s starting directory.
            &si,              // Pointer to STARTUPINFO structure.
            &pi);             // Pointer to PROCESS_INFORMATION structure.

This will cascade all windows using windows resources



Strange, but it seems that this "Shell" object is only accessible via Windows Scripting Host or via Visual Basic, and NOT via C++ or Delphi or ...
Perhaps you can create a temporary Windows-Scripting-Host-File, execute it and delete it again? But don't ask me how this scripting works...

Regards, Madshi.
Hi DarrinE,

To minimize all open windows you can also simulate a WINDOWSKEY+<M>, i.e. with:

keybd_event(VK_LWIN, 0, 0, 0);
keybd_event('M', 0, 0, 0);
keybd_event(VK_LWIN, 0, KEYEVENTF_KEYUP, 0);

hope that helps,

ZOPPO
ASKER CERTIFIED SOLUTION
Avatar of chensu
chensu
Flag of Canada image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
To minimize all Windows, you can simply simulate the menu on the Taskbar :

SendMessage(FindWindow("Shell_TrayWnd", NULL), WM_COMMAND, 419, 0);

(or 415)
Avatar of DarrinE

ASKER

Chensu - thanks for the answer - it looks great - I am using VC++ Professional on WIN98 - my compiler returns the error

D:\Projects\Saver\minimize.c(294) : error C2065: 'IShellDispatch' : undeclared identifier

I have included the headers (your code exactly) and the other shell headers and the error still appears - can you tell me why please ?

MTIA


What version of Visual C++ are you using? It compiles with Visual C++ 6.0 Service Pack 3.
Avatar of DarrinE

ASKER

VC++ 5.0 (is there a place I can download the service packs ?)
You may download the latest Platform SDK. It is huge. You don't have to install everything. You just need the header files and library files. Or you can install it from MSDN CDs if you have.

http://msdn.microsoft.com/developer/sdk/platform.asp
Avatar of DarrinE

ASKER

Excellent - I can use what you have shown to me to make other "shell" objects as well

Many thanks for the assistance
Avatar of DarrinE

ASKER

Castorix - for the record your answer is the one I am using for the moment because I dont have the updated SDK - I'll have to get it soon anyway.

So you know (if you dont already) the code

SendMessage(FindWindow("Shell_TrayWnd", NULL), WM_COMMAND, 415, 0);

is the most efficient and 416 is to be used to Undo Minimize All.

Can you tell me how you found the reference to the menu item ? Please ?

>Can you tell me how you found the reference to the menu item?

Use Spy++.
>Can you tell me how you found the reference to the menu item ?

I usually use Spy++, but in this case I got nothing.

So I have simply used a loop on the wParam.

This way you can find many other values.
(403 : Arrange Cascade,  404 : Vertical Mosaïc, 405 : Horizontal Mosaïc,  408 : Date/Hour Properties, ... etc...)