|
|
ctl32_contextmenu: work in progress! Introduction The purpose of the ctl32_contextmenu class is to provide a nice and easy to create a shortcut menu in VFP. The menus should look like the standard operating system menus. The Windows API is used, so most of the work is done by the operating system itself. The native VFP shortcut menus have many problems:
It is not the intention of this project to have an object oriented menu framework (yet), but to be able to create shortcut menus quickly and easily in code, and maybe even data-drive the creation of shortcut menus. The second stage will be to provide full menu support for VFP apps. Nothing fancy like Office style menus or anything like that, just menus that look like any other Windows standard menu. We don't even have standard looking menus in our VFP apps, let's focus on getting that, and maybe later we can think about fancy stuff like Office style menus. I must confess I dislike very much the non-standard Office menus introduced around Office 2000 or was it 97?, they totally deviate from the operating system standards, and had every developer on earth wasting it's time trying to emulate them, only because Office had them. Windows and GDI+ and more After spending the last 2-3 weeks trying to understand GDI+, and stumbling upon one bug after another, I have concluded that GDI+ is just a BIg Ball Of Mud, and that GDIPLUSX is a very well done port of a Big Ball Of Mud, that inherits all of the bugs, design errors and horror stories of gdi+ and the .Net GDI+ classes. The bugs in the way the HBMMENU_CALLBACK method works in Windows 2000, XP, Vista, also drove me crazy; can we please have something that works the same way in all operating systems versions? I mean: broken in Windows 2000, fixed in XP, broken AGAIN in Vista? The whole bitmaps in menus implementation in Windows is so sloppy and bug-ridden, I think they just implemented this in a rush so they could get the icons in the start menu items in Windows 95, and latter added some additional capabilities, with no testing at all. For now, I have decided to stop trying to have bitmaps in menu items, it is not worth it, there is no way I can do it in a way that will satisfy me as being right. In the process, I have discovered that the way images in general are handled in Windows... what can I say, they could not make it more complicated that what they have right now, everything is so convoluted, unnatural, messy, overly complex, half the things don't work, I canīt believe the way things are in this area. For starters, do we need bmp, dib, cur, ani, ico, jpg, gif, gfa, tif, exif, png, wmf, emf, and one thousand more image file formats? What' s wrong with these people? Do we need DIBs, DDBs, DCs, and one thousand more objects and classes? Do we need 600+ API functions to draw little pictures on the screen? Spare me from the details! just draw the damn image the way I want, where I want it, don't make me sweat like a pig to have a miserable tiny 16x16 icon drawn in a menu item! I will just post here some examples of things I found: This is how Windows XP displays an icon that has 256 colors and an Alpha channel, this is in Windows Explorer. As you can see, the alpha channel information was lost somewhere.
This is how it should look like, quite a difference. And XP was supposed to bring us icons with alpha channel? And it has THIS bug?
The same thing happens in NET, unless you run thru hoops to get a workaround, check this link: http://dotnetrix.co.uk/misc.html
Same thing happens in Office 2007: More GDI+ links, all talk about bugs, frustration, problems, etc http://groups.google.com.ar/group/microsoft.public.win32.programmer.gdi/msg/fa5de1f2bc9a04d3 http://forums.winstep.net/phpBB2/viewtopic.php?p=4275&sid=e1f5209d169393b87fcaeffc83259ceb http://groups.google.com.ar/group/comp.os.ms-windows.programmer.win32/...5e
Also we have the blue background bug for transparent images, what you see blue in this image should be really white, but guess what? Another "minor" GDI+ bug!
http://groups.google.com.ar/group/microsoft.public.dotnet.framework.windowsforms/...0f So what started as a humble shortcut menu replacement project degenerated into a gdi+ ordeal of three weeks, and I really lost so much energy that I donīt want to proceed any further with this, really. And do you think all this problems are fresh bugs? this problems are 4-5 years old at least! Windows XP menus In XP menus can be either drawn by the operating system, can be drawn partially by the application, or totally bu the application. Even menus drawn by Windows XP itself have some problems. The is part of the Right-Click - File - New menu of Windows XP, you can see this menu by right-clicking in the desktop and choosing "New". This menu does not have the standard height of the rest of the system menus, and the highlighted menu item text remains black instead of turning white. This is a Windows XP menu. The same thing happens to the file context menu "Send To"
Now lets see a detailed zoom of a control menu, the one you get when clicking in the Window menu (formerly known as the system or control menu) that is, the top right icon of a program. As can be seen, the menu items with no images ara shorter than the menu items with images, by a full 4 pixels!
One feature of menus is that a program cannot change the font size of its menus. The font menu is the same for all aplications and is configurable by the user. The only thing that we can change in a program is the menu backcolor. The ability to display images in menu items is a feature that was added later, and is not fully functional. In all the menus with images, the images do not scale when the user changes the font of the menus:
Native VFP menus Lets have a look at the native VFP shortcut menus. This is how a shortcut menu looks like in Visual FoxPro:
In Windows, menus can be drawn by the operating system, or can be drawn by the program that owns the menus. In VFP the menus are owner drawn, and they don't look very nice, my view is that they look awful. The above pictures show a shortcut menu in VFP. What can be said? Look how the menu icon overlaps the highlight, how we can see what it looks like a gray border around the highlighted menu item icon. Also notice the thick border after the last menu item in Vista. Not nice.
Creating a context menu for a textbox, an example. To display a shortcut menu for a textbox, the code in the textbox RightClick would be something like:
The result of this code? Here:
Not so hard was it? Easy to follow and understand, even with the menu item captions in spanish.
Here we have used numeric identifiers for the menus, the class converts them to string values, and returns us the identifier of the chosen option, or the empy string if no option is clicked. ctl32_menu in Windows Vista ctl32_shorcut menus in Windows Vista, with and without themes. I personally prefer the no-themes versions, they look better to me.
The menus are using bitmaps in 13x13, 16x16, 24x24, 32x32, 48x48 and 64x64 sizes. Only one set of 64x64 png files is used, GDI+X does all the resizing on the fly, that is why the 16x16, 32x32 and 64x64 versions look better. If you wanted to the the most flexibility tothe end user with quality, maybe a 64x64 and a 48x48 set of bitmap files could be included in the application. The 13x13 size stems from the fact that it is the default size of bitmaps in Windows XP menus. Default size for bitmaps in Vista menus is 16x16. ctl32_menu in Windows XP
In Windows XP the default menu size is smaller than in Vista, I guess the reason for bigger menus in Vista is that most people now have bigger monitors.
a example of a right-click in form context menu
an editbox context menu
A grid header context menu
Windows XP menus
Minimum Item Height 17 Default bitmap height 13 1 pixel margin around bitmap for owner drawn bitmap. if bitmap canvas is 18, menu item height will be 20 Windows Vista menus: Vista menus, unlike XP menus, are styled. Menu items have a standard height of 22 pixels, menu item bitmaps are 16x16. Vista owner drawn menus default height is 20, bitmap size is 16x16. The ctl32_shorcut menus will be the same size themed or owner drawn: 22 pixels high, 16x16 bitmap. To set bitmaps in menu items in Vista there is no need to do owner-drawn menus any more.
Internet Explorer 7 on Windows Vista, the Favorites menu is owner drawn, so it is not rendered using the visual styles engine, maybe the IE7 folks at MS should read the article at the MS Shell Blog regarding Vista menus.
The right-click on Explorer - New menu has been fixed from XP, where the text stayed black in the highlighted menu item.
The File - Send to menu has also been fixed from XP:
Using Alpha-Blended Menu Bitmaps Windows Vista provides alpha-blended bitmaps, which enables menu items to be shown without using owner-draw menu items. Windows Vista also provides visual style APIs that can be used to render owner-draw menus. For detailed information about owner-draw menus, see Owner-Draw Menus. A common reason for using owner-draw menus is to show icons. It seems logical to add an hIcon field to the MENUITEMINFO structure and then add the code that does the drawing using hIcon, but Windows Vista does not support hIcon. Windows Vista was designed to support alpha-blended menu bitmaps to prevent application compatibility issues. Alpha-blended menu bitmaps allow icons to be displayed and provide more flexibility than simply specifying hIcon. Windows Vista is designed to apply alpha-blend to a menu bitmap that satisfies all the following requirements:
http://msdn2.microsoft.com/en-us/library/bb757020.aspx
Understanding the menu system To better understand how to use this class, lets first present an explanation of how this class considers the menu system of a VFP application. This class just provides for the creation of shortcut or context menus at the moment, but the idea is to extend it to cover the whole menu system. Any menu system consists of basically two types of objects:
There are no more basic types of objects in a menu system. For example the main menu bar of an application is a menu container with menu items, arranged horizontally in the screen. Each drop down menu is a menu container, that contains menu items. Some menu items can be linked to sub menus, that are just menu containers.
In Object oriented menu classes in VFP 6.0, Colin Nicholls defines a menu object model like this:
The menu object model proposed here is a simplified version, where the menu bar is just another menu, and the menu pads are just bars, like this:
But this model still does not fully represent the menu system, since menu containers are not really contained one inside the other, but they are all logically at the same level, only conected by a link stored in some menu items, like this:
The fact that the menu bar is horizontally arranged in the screen, and the dropdown menus are arranged vertically does not prevent us from considering them the same type of objects. (By now you may have realized that this is just like tables with one to many relationships) This abstraction model reflects the fact that a menu container can be linked by more that one menu item. Also that a shortcut menu is just a menu system that is not attached to a form. To follow this model, when creating a menu item that links to a sub menu, the correct procedure would be to create the menu item, the menu container, and then link one to the other, but to simplify things, this class manages two kind of menu items: standard menu items, and menu items with sub menus. There is no need to create the sub menu containers, they get created and linked to the menu item when the menu item is created. From now on menu containers will be refered to as "menus", thah includes menu bars, drop down menus, pop up menus, sub menus and shortcut/context menus. Steps to create a shortcut menu You start by calling deleting any previously defined menus, then the first step is to add the main pop up menu. We have to pass the HWnd of our form, and give the main menu a name:
.Clear .Add(Thisform.HWnd, "popup")
You may use numbers as keys, they will be internally converted to strings. Now we have to start adding menu items:
.MenuAdd("popup", "UNDO", 1, "&Undo") .MenuAdd("popup", "", 1, "-") .MenuAdd("popup", "CUT", 1, "Cu&t") .MenuAdd("popup", "COPY", 1, "&Copy") .MenuAdd("popup", "PASTE", 1, "&Paste") .MenuAdd("popup", "CLEAR", 1, "Cle&ar") .MenuAdd("popup", "", 1, "-") .MenuAdd("popup", "SELECT ALL", 1, "Se&lect All")
Properties, Events, and Methods
Adds a menu
Adds a menu or a menu item ParentKey
Removes all menu and menu items
Specifies the default ItemHeight value for new menu items. Changing this value does not change the ItemHeight of existing menu items.
Specifies the default ItemPictureSize value for new menu items. Changing this value does not change the ItemPictureSize of existing menu items.
Specifies the default menu height value for new menu menus. Changing this value does not change the height of existing menus.
Specifies if the menu item pictures will be drawn by Windows or by the class itself
Removes an existing menus or menu items. MenuPopUp Properties
Specifies the default height for menu items inside this menu
Specifies the default picture height and width for menu items iniside this menu
Specifies the system menu handle
Specifies the maximum height of the menu, default value is 0 (screen height)
Specifies an unique, alphanumeric (character type) expression that represents a key string for the object
MenuItem Properties
Specifies the style of mark for a menu item. 1 Check mark 2 Bullet mark
Type Flags MF_CHECKED 8 Caption Picture MarkStyle MarkGroup Default Reference: Object oriented menu classes in VFP 6.0 by Colin Nicholls Objectify Your Menus by Doug Hennig Themed menus icons, a complete Vista and XP solution Vista Style Menus, Part 1 - Adding icons to standard menus Vista Style Menus Part 2 Custom menu drawing Simple Menus that Display Icons - Minimalistic Approach Adding and using 32 bit alphablended images and icons to the imagelist control Cool Owner Drawn Menus with Bitmaps - Version 3.03 Owner drawn menus in two lines of code SetMenuItemInfo: Custom Application Menu Colours http://msdn2.microsoft.com/en-us/library/system.windows.forms.menu.aspx http://msdn2.microsoft.com/en-us/library/system.windows.forms.menu.menuitemcollection.aspx http://msdn2.microsoft.com/en-us/library/system.windows.forms.menuitem.aspx http://msdn2.microsoft.com/en-us/library/system.windows.forms.mainmenu.aspx http://msdn2.microsoft.com/en-us/library/system.windows.forms.contextmenu.aspx |
|
||||||
|
|