views:

79

answers:

2

I'm a Mac user and a Windows user (and once upon a time I used to be an Amiga user). I much prefer the menu-bar-at-the-top-of-the-screen approach that Mac (and Amiga) take (/took), and I'd like to write something for Windows that can provide this functionality (and work with existing applications).

I know this is a little ambitious, especially as it's just an itch-to-scratch type of a project and, thanks to a growing family, I have virtually zero free time. I looked in to this a few years a go and concluded that it was very difficult, but that was before StackOverflow ;)

I presume that I would need to do something like this to achieve the desired outcome:

  • Create application that will be the custom menu bar that sits on top of all other windows. The custom menus would have to provide all functionality to replace the standard Win32 in-window menus. That's OK, it's just an application that behaves like a menu bar.

  • It would continuously enumerate windows to find windows that are being created/destroyed. It would enumerate the child windows collection to find the menu bar.

  • It would build a menu that represents the menu options in the window.

  • It would hide the menu bar in the window and move all direct child windows up by a corresponding pixel amount. It would shorten the window height too.

  • It would capture all messages that an application sends to its menu, to adjust the custom menu accordingly.

  • It would constantly poll for the currently active window, so it can switch menus when necessary.

  • When a menu hit occurs, it would post a message to the window using the hwnd of the real menu child control.

That's it! Easy, eh? No, probably not.

I would really appreciate any advice from Win32 gurus about where to start, ideas, pitfalls, thoughts on if it's even possible. I'm not a Win32 C++ programmer by day, but I've done a bit in my time and I don't mind digging my way through the MSDN platform SDK docs...

(I also have another idea, to create a taskbar for each screen in a multi-monitor setup and show the active windows for the desktop -- but I think I can do that in managed code and save myself a lot of work).

+3  A: 

The real difference between the Mac menu accross the top, and the Windows approach, is not just in the menu :- Its how the menu is used to crack open MDI apps.

In windows, MDI applications - like dev studio and office - have all their document windows hosted inside an application frame window. On the Mac, there are no per-application frame windows, all document windows share the desktop with all other document windows from other applications.

Lacking the ability to do a deep rework of traditional MDI apps to get their document windows out and onto the desktop, an attempt, however noble, to get a desktop menu, seems doomed to be a novelty with no real use or utility.

I am, all things considered, rather depressed by the current state of window managers on both Mac and Windows (and Linux): Things like tabbed paged in browsers are really acts of desperation by application developers who have not been given such things as part of the standard window manager - which is where I believe tabs really belong. Why should notepad++ have a set of tabs, and chrome, and firefox, and internet explorer (yes, I have been known to run all 4), along with dev studios docking view, various paint programs.

Its just a mess of different interpretations of what a modern multi document interface should look like.

Chris Becke
...and your idea for a modern MDI interface is...?
Jon Seigel
something with dockable tabs. like chrome, but managed by the window manager. Its what everyone seems to be trying to make.
Chris Becke
I don't see why MDI applications would not lend themselves to having their menu repositioned to the top of the screen, but maybe I'm missing something -- if you look at Visual Studio, for example, you'll note that there's only ever one menu visible at a time, and that's at the top of the MDI container window. Why not have it at the top of the screen instead of the top of the window? My reason for wanting to do this is just to make the menu bar easier to hit with the mouse, not to change the way MDI/SDI applications work.
Adrian O'Connor
A: 

The menu bar on a typical window is part of the non-client area of the window. It's drawn when the WndProc gets a WM_NCPAINT message and passes it on to DefWindowProc, which is part of User32.dll - the core window manager code.

Other things that are drawn in the same message? The caption, the window borders, the min/max/close boxes. These are all drawn while processing a single message. So in order to hide the menu for an application, you will have to take over handling of this message, which means changing the behavior of user32.dll. Hiding the menu is going to mean that you become responsible for drawing all of the non-client area.

And the appearance of all of these elements - The caption, the borders, etc. changes with every major version of Windows. So you have to chase that as well.

That's just one of about a dozen insurmountable problems with this idea. Even Microsoft probably couldn't pull this off and they have access to the source code of user32.dll!

It would be a far less difficult job to echo the menu for each application at the top of the screen, and even that is a nearly impossible job. When the menu pops there is lots of interaction with the application during which the menu can be (and often is) changed. It is very common for applications to change the state of menu items just before they are drawn. So you will have to replicate not only the appearance of the menus, but their entire message flow interaction with the application.

What you are trying to do is about a dozen impossible jobs all at once, If you try it, you will probably learn a lot, but you will never get it to work.

John Knoeller
That's a good answer, thanks. I'll investigate WM_NCPAINT because I'd quite like to know what happens there, but there's no way I can redraw all of the non-client area, as you say, which does make my task somewhat impossible. Thanks for the feedback.
Adrian O'Connor