|

Win32/ FPC - Chapter 11 - by Delax
This chapter is about Windows menus. You know - the menus on top of the window, that you can control with the ALT-key, usually something like "File", "Edit" or "About"/ "Help" or something like that. Those menus ar quite essential. The contain the functions and features of your Windows application. All users will expect some kind of menu to work with the application.
Because these menus are so essential they are quite easy to implement in your application. All you need is to define the content of the menu inside your resource script and tell Windows in your Window Class to use this menu. Of course you also have to code some stuff that has to de done if a menu item was clicked - otherwise it would be pretty pointless.
Let's start out with the definitions inside your resource script. As we learned in the last chapters, the resource script works like this: first the ID of the resource, followed by the type and the content. This time we use "MENU" as the type. Then we have to define the content of the menu. Blocks of code in resource scripts are much like in Pascal. They have to be nested into BEGIN and END (Pascal style) or you may use { .. } (which is used by many other programming languages). So an empty menu would look something like this.
10 MENU BEGIN
// .. content of the menu goes here
END
Now we have to add some items. First you have to define a group of items. This is the top level element and will be shown in the menu. You define this groups of items with "POPUP". Here is an example of a menu class. I'm sure it will seem familiar.
POPUP "&File"
BEGIN
MENUITEM "&New", 11
MENUITEM "&Open", 12
MENUITEM "Close", 13
MENUITEM "Close All", 14
MENUITEM SEPARATOR
MENUITEM "&Save", 20
MENUITEM "Save As", 21
MENUITEM "Save All", 22
MENUITEM SEPARATOR
MENUITEM "&Print", 30
MENUITEM "Print Preview", 31
MENUITEM SEPARATOR
MENUITEM "Save and Exit", 41
MENUITEM "&Exit", 42
END
This is a normal item list for the "File" element. You have some file operations like "open file" or "close file", something to save, something to print and then items to exit the application. You should have seen this a couple of times while working with different Windows applications.
It all starts with the defintion of the top level element, which is called "File" in this example. This is not a menu item but the name of this group of icons. When you click on it, the group items will appear. Now take a close look. There is an "&" in front of it. This tells Windows that this is the shortcut key for this group. So if the user presses ALT+F it will open this group. It takes the first sign after the "&" as the shortcut. It does not need to be the first charakter, something like 'POPUP "Fil&e"' would work as well. But think about the user and give your groups somewhat logical shortcuts.
Following the group name are the items of the group. Every group has to be in a logical block as well. Individual items are defined with "MENUITEM", followed by the name of the item and the ID of the item. Every item needs to have its own ID as this is the number that Windows sends to your application as "Item-Number-x-was-pressed" message. Then you would react to this message by doing whatever the user has clicked
Items inside a group can also have shortcuts. But these won't be accessible from the application straight away, but only if you opened the group first. So you would have to press "ALT+F" first and then you could use the shortcuts inside that group.
There is also a menu item called "SEPERATOR". It's a simple line to seperate some items in a group from others in the same group. Users may find it helpfull if some blocks of logical connected items are seperated from others.
For our example we will use a far simpler menu. Here it is.
10 MENU // main window menu
BEGIN
POPUP "&File"
BEGIN
MENUITEM "Message 1", 11
MENUITEM "Message 2", 12
MENUITEM SEPARATOR
MENUITEM "&Exit", 19
END
POPUP "&About"
BEGIN
MENUITEM "About", 21
END
END
As you can see I defined 2 groups. The first group is "File" and contains 3 items. The second one is "About" and it contains just one item. Right now we don't have anything connected with these items. You have to plan in advance what items you need and what they should do in your application. These items should be well planned as they define the work-flow of your application. If they are not clear and intuitive your application is doomed.
Now we will include this new resource script into the example source. Get the new resource script here and compile it as you have learned it in the last chapters. Then let's have a look at our source from last time. Up until now we did not have a menu and used the line " WinClass.lpszMenuName := nil;". Now we have one and we use the ID of the menu to register it: " WinClass.lpszMenuName := 10;". And that is all to bind a menu to a window of an application. Our complete Window Class now looks like this.
WinClass.cbSize := Sizeof(WndClassEx);
WinClass.Style := cs_hRedraw OR cs_vRedraw;
WinClass.lpfnWndProc := WndProc(@WindowProc);
WinClass.cbClsExtra := 0;
WinClass.cbWndExtra := 0;
WinClass.hInstance := system.MainInstance;
WinClass.hIcon := LoadIcon(system.MainInstance, makeintresource(1));
WinClass.hCursor := LoadCursor(0, idc_Arrow);
WinClass.hbrBackground := GetStockObject(LTGRAY_BRUSH);
WinClass.lpszMenuName := 10;
WinClass.lpszClassName := 'WindowClass';
WinClass.hIconSm := LoadIcon(system.MainInstance, makeintresource(1));
If we would compile this, our apllication would have a menu. But nothing else. We haven't told our program what to do if any item was chosen from this menu. As I said earlier, Windows will create a message if an item from the menu was clicked by the user. This message is put into the normal message queue. And this means we can handle it in the WinProc just like any other message from Windows.
Windows has a special message, that is created when something like a menu or a dialog is clicked or changed. This message is "WM_COMMAND". In the case of a menu, WM_COMMAND contains the ID of the item that was clicked as the loword of wParam. I'll just post the new part of the WinProc.
WM_COMMAND : begin
case (LOWORD(wParam)) of
11 : begin // message 1
MessageBox(0, 'This is message 1.', 'Message', MB_OK);
end;
12 : begin // message 2
MessageBox(0, 'This is message 2.', 'Message', MB_OK);
end;
19 : begin // exit application
active := false;
end;
21 : begin // about
MessageBox(0, 'This is a simple example to show you
how menus work.', 'About', MB_OK);
end;
end; // case
end; // wm_command
It's pretty straight forward. If the command is 11 (Message 1) or 12 (Message 2) or 21 (About) I'll pop up a Message Box. If it is 19, I'll set the active flag to false, thus ending the application. And that's it. Of course real applications would do real work here, but this should be enough to give you the idea how it works.
And that's it for now. Get the source code here and if you haven't downloaded it so far here is the resource script. As usual, compile the script first and then compile the source. Have fun.
Delax/ Sundancer Inc.
[delax@sundancerinc.de]
Back to previous page
|