Jump to content

Introduction to PM Programming - May 1995: Difference between revisions

From EDM2
mNo edit summary
Ak120 (talk | contribs)
formatting
Line 1: Line 1:
Written by [[Larry Salomon Jr.]]
Written by [[Larry Salomon Jr.]]


<h2>Introduction</h2>
==Introduction==
The purpose of this column is to provide the readers out there who are not familiar with PM application development the information necessary to satisfy their curiosity, educate themselves, and give them an advantage over the documentation supplied by IBM. Of course, much of this stuff could probably be found in one of the many books out there, but the problem
with books in general is that they don't answer the questions you have after you read the book the first time through.


<p>The purpose of this column is to provide the readers out there who are not
I will gladly entertain feedback from the readers about what was "glossed over" or what was detailed well, what tangential topics need to be covered and what superfluous crap should have been removed. This feedback is essential in guaranteeing that you get what you pay for. <grin>
familiar with PM application development the information necessary to
satisfy their curiosity, educate themselves, and give them an advantage
over the documentation supplied by IBM. Of course, much of this stuff
could probably be found in one of the many books out there, but the problem
with books in general is that they don't answer the questions you have
after you read the book the first time through.


<p>I will gladly entertain feedback from the readers about what was "glossed
It should be said that you must not depend solely on this column to teach you how to develop PM applications; instead, this should be viewed as a supplement to your other information storehouses (books, the network conferences, etc.). Because this column must take a general approach, there will be some topics that you would like to see discussed that really do not belong here.  Specific questions can be directed to me via email and I will do my best to answer them in a timely fashion.
over" or what was detailed well, what tangential topics need to be covered
and what superfluous crap should have been removed.  This feedback is
essential in guaranteeing that you get what you pay for. <grin>


<p>It should be said that you must not depend solely on this column to teach
==Last Month==
you how to develop PM applications; instead, this should be viewed as a
Last month we began looking at the menu control, which we will continue with this month.
supplement to your other information storehouses (books, the network
conferences, etc.).  Because this column must take a general approach,
there will be some topics that you would like to see discussed that really
do not belong here.  Specific questions can be directed to me via email and
I will do my best to answer them in a timely fashion.


<h2>Last Month</h2>
==Basic Knowledge Required==
Before we may continue, we should take a brief look at the typical use of a menu control, from the programmer's perspective. This involves the definitions of the manifest constants, the menu template definition, the "loading" of the menu (you'll see why "loading" is in quotes in a minute), and the processing of the user's actions. We're taking this different approach to looking at the window class because - as we stated last month - the menu provides the most widely used functionality of any of the window classes; as such, you'll need to know how to use it because you'll be writing this code more times than any other.


<p>Last month we began looking at the menu control, which we will continue
==Manifest Constants==
with this month.
Manifest constants - a.k.a. #define's - are a convenient language element which allow us to use a "name" in place of something else. For menus, the "something else" is a number which represents an identifier unique to that menu template. You'll find that in larger applications that the file containing these constants can grow quite large, so it would be helpful if,
 
at a glance, you could determine the use of the constant from looking at its name. To accomplish this, I defined a naming convention. You can use this one or your own - it doesn't matter. What does matter is that you spend less time trying to find out how a constant is used and more time on actually using the constant. For menus, I use the following:
<h2>Basic Knowledge Required</h2>
<pre>
 
<p>Before we may continue, we should take a brief look at the typical use of a
menu control, from the programmer's perspective.  This involves the
definitions of the manifest constants, the menu template definition, the
"loading" of the menu (you'll see why "loading" is in quotes in a minute),
and the processing of the user's actions.  We're taking this different
approach to looking at the window class because - as we stated last month -
the menu provides the most widely used functionality of any of the window
classes; as such, you'll need to know how to use it because you'll be
writing this code more times than any other.
 
<h2>Manifest Constants</h2>
 
<p>Manifest constants - a.k.a. #define's - are a convenient language element
which allow us to use a "name" in place of something else. For menus, the
"something else" is a number which represents an identifier unique to that
menu template. You'll find that in larger applications that the file
containing these constants can grow quite large, so it would be helpful if,
at a glance, you could determine the use of the constant from looking at
its name. To accomplish this, I defined a naming convention. You can use
this one or your own - it doesn't matter. What does matter is that you
spend less time trying to find out how a constant is used and more time on
actually using the constant. For menus, I use the following:
 
<pre><small>
Constant form  What it represents
Constant form  What it represents
M_id            Menu or submenu identifier
M_id            Menu or submenu identifier
MI_id          Menuitem identifier
MI_id          Menuitem identifier
</small></pre>
</pre>
 
The constants that are used for resource definitions I keep in a separate file to allow me to make the file a dependancy of all files that use resources. This is simply a suggestion.
<p>The constants that are used for resource definitions I keep in a separate
file to allow me to make the file a dependancy of all files that use
resources. This is simply a suggestion.
 
<h2>Template Definition</h2>


<p>Under Windows, there is App Studio which allows you to define and maintain
==Template Definition==
all of your resources. How come there isn't something like this for OS/2?
Under Windows, there is App Studio which allows you to define and maintain all of your resources. How come there isn't something like this for OS/2?
Regardless, you have to design your menus "blind," meaning that you can't
Regardless, you have to design your menus "blind," meaning that you can't see the result until you actually use the menu you've built.
see the result until you actually use the menu you've built.


<p>As it is with writing applications, designing your menu layout should be
As it is with writing applications, designing your menu layout should be the most important action; a confusing or deep (i.e. many pullrights) menu structure will often confuse the user and turn them away from using your application. Group the items in submenus in a logical fashion so that the user can "take a guess" at where to look when trying to execute a
the most important action; a confusing or deep (i.e. many pullrights) menu
structure will often confuse the user and turn them away from using your
application. Group the items in submenus in a logical fashion so that the
user can "take a guess" at where to look when trying to execute a
particular action.
particular action.


<p>IBM's "Common User Access" (CUA) guidelines define a number of pulldown
IBM's "Common User Access" (CUA) guidelines define a number of pulldown menus and a (non-inclusive) list of what they should contain. I've included a brief list of these (since I cannot find my CUA book <pout>) below:
menus and a (non-inclusive) list of what they should contain. I've
{|class="wikitable"
included a brief list of these (since I cannot find my CUA book <pout>)
!Pulldown name||Menu items contained therein
below:
|-
 
|File||New, Open, Close, Save, Save as, etc.
<pre><small>
|-
Pulldown name   Menu items contained therein
|Edit||Undo, Copy, Cut, Paste, etc.
--------------------------------------------
|-
File           New, Open, Close, Save, Save as, etc.
|Help||Help index, General help, Using help, Keys help
Edit           Undo, Copy, Cut, Paste, etc.
|}
Help           Help index, General help, Using help, Keys help
Another important CUA note is the use of the ellipsis and bang punctuation marks on text. An ellipsis should be appended to menu item text when selecting the menu item results in a dialog being displayed. A bang should be appended to text belonging to items on the action bar (note that this therefore excludes pullrights and any popup menu items) when selecting them
</small></pre>
does not display a pulldown menu (i.e. when it is a leaf-node). These are used as feedback indicators to the user to alert them about the behavior of the application without having them find out "the hard way."
 
<p>Another important CUA note is the use of the ellipsis and bang punctuation
marks on text. An ellipsis should be appended to menu item text when
selecting the menu item results in a dialog being displayed. A bang should
be appended to text belonging to items on the action bar (note that this
therefore excludes pullrights and any popup menu items) when selecting them
does not display a pulldown menu (i.e. when it is a leaf-node). These are
used as feedback indicators to the user to alert them about the behavior of
the application without having them find out "the hard way."
 
<h2>Loading a Menu</h2>
 
<p>Loading a menu usually involves the setting of a flag only.  No explicit
loading is usually performed by the application code.  (Popup menus are the
exception to this rule, since the current CUA specification eliminates
action bars.)  In the call to WinCreateStdWindow(), simply include FCF_MENU
on the set of flags passed (by reference) as the third parameter.


<pre><small>
==Loading a Menu==
Loading a menu usually involves the setting of a flag only. No explicit loading is usually performed by the application code. (Popup menus are the exception to this rule, since the current CUA specification eliminates action bars.) In the call to WinCreateStdWindow(), simply include FCF_MENU on the set of flags passed (by reference) as the third parameter.
<pre>
   #define RES_CLIENT      256
   #define RES_CLIENT      256


Line 125: Line 64:
RES_CLIENT,
RES_CLIENT,
&hwndClient);
&hwndClient);
</small></pre>
</pre>
 
It has been stated before in this column (I hope) that, when using FCF_MENU, FCF_ICON, or FCF_ACCELTABLE that the eighth parameter must specify the resource identifier of the resources corresponding to these flags. Since we specified FCF_MENU, we should have a menu template defined that begins with:
<p>It has been stated before in this column (I hope) that, when using
FCF_MENU, FCF_ICON, or FCF_ACCELTABLE that the eighth parameter must
specify the resource identifier of the resources corresponding to these
flags. Since we specified FCF_MENU, we should have a menu template defined
that begins with:
 
<pre><small>
     MENU RES_CLIENT
     MENU RES_CLIENT
       :
       :
</small></pre>
If we do not have this defined, the WinCreateStdWindow() function will fail. A useful note here is that, as each component of the window specified in ulCreate is successfully created, the corresponding bit in ulCreate is set to 0. So, the components that were not created successfully can be determined by examining ulCreate after the function fails.
 
<p>If we do not have this defined, the WinCreateStdWindow() function will
fail. A useful note here is that, as each component of the window
specified in ulCreate is successfully created, the corresponding bit in
ulCreate is set to 0. So, the components that were not created successfully
can be determined by examining ulCreate after the function fails.
 
<h2<Processing the User's Requests</H2>


<p>Now we learn how to utilize the menu in our application code. There are
==Processing the User's Requests==
usually two messages that we will be interested in when coding our
Now we learn how to utilize the menu in our application code. There are usually two messages that we will be interested in when coding our application: WM_INITMENU and WM_COMMAND. Note that, if any MENUITEMs have the MIS_SYSCOMMAND or MIS_HELP style, we will need to add the WM_SYSCOMMAND and WM_HELP messages to this list, but for the moment we'll assume that we
application: WM_INITMENU and WM_COMMAND. Note that, if any MENUITEMs have
the MIS_SYSCOMMAND or MIS_HELP style, we will need to add the WM_SYSCOMMAND
and WM_HELP messages to this list, but for the moment we'll assume that we
have none with these menu item styles.
have none with these menu item styles.


<p>WM_INITMENU is sent to the client window whenever a menu or submenu is
WM_INITMENU is sent to the client window whenever a menu or submenu is about to be used by the user, e.g. when the user presses F10 to get to the action bar, when the user clicks on a pulldown menu to display the pulldown, etc. Intercepting this message allows us to dynamically enable or disable menu items according to the state of our application. For example, if the user selects the "Print" menuitem, you might want to disable the "Exit" menuitem until printing is completed. We will see later how to change menuitem attributes.
about to be used by the user, e.g. when the user presses F10 to get to the
action bar, when the user clicks on a pulldown menu to display the
pulldown, etc. Intercepting this message allows us to dynamically enable
or disable menu items according to the state of our application. For
example, if the user selects the "Print" menuitem, you might want to
disable the "Exit" menuitem until printing is completed. We will see later
how to change menuitem attributes.
 
<p>SHORT1FROMMP(mpParm1) specifies the identifier of the menu.  If the
actionbar is the cause of the message, this will be FID_MENU; otherwise, it
will be the identifier you specified on the SUBMENU statement in the menu
template.


<p>HWNDFROMMP(mpParm2) is the handle of the window corresponding to the
SHORT1FROMMP(mpParm1) specifies the identifier of the menu. If the actionbar is the cause of the message, this will be FID_MENU; otherwise, it will be the identifier you specified on the SUBMENU statement in the menu template.
identifier.  You should know that pulldown and pullright menus are actually
separate windows which belong to something called an "object" window when
not in use.  When you click on a pulldown, the appropriate window is
retrieved from the object window and displayed on the desktop.  This window
handle is needed to send messages to the menu.


<p>WM_COMMAND, WM_SYSCOMMAND, and WM_HELP are all sent whenever the user
HWNDFROMMP(mpParm2) is the handle of the window corresponding to the identifier. You should know that pulldown and pullright menus are actually separate windows which belong to something called an "object" window when not in use. When you click on a pulldown, the appropriate window is retrieved from the object window and displayed on the desktop. This window handle is needed to send messages to the menu.
selects a menuitem with the corresponding style. This is your indicator
that the user wants something done and that you are to process this
request.


<p>SHORT1FROMMP(mpParm1) specifies the identifier of the menuitem selected.
WM_COMMAND, WM_SYSCOMMAND, and WM_HELP are all sent whenever the user selects a menuitem with the corresponding style. This is your indicator that the user wants something done and that you are to process this request.


<p>SHORT1FROMMP(mpParm2) specifies the source of the message and will always
SHORT1FROMMP(mpParm1) specifies the identifier of the menuitem selected.
be CMDSRC_MENU when this message is sent via a menu control.


<p>SHORT2FROMMP(mpParm2) is TRUE if this message was sent as the result of a
SHORT1FROMMP(mpParm2) specifies the source of the message and will always be CMDSRC_MENU when this message is sent via a menu control.
mouse action or FALSE if sent as the result of a keyboard action.


<h2>Next Month </h2>
SHORT2FROMMP(mpParm2) is TRUE if this message was sent as the result of a mouse action or FALSE if sent as the result of a keyboard action.


<p>Next month we'll start to look at a sample application that uses the menu control, and we'll begin to look at the MM_ message family which allows you to interact with the menu control.  As always, feedback will be enjoyed immensely; send any comments, suggestions, etc. to os2man@panix.com.
==Next Month==
Next month we'll start to look at a sample application that uses the menu control, and we'll begin to look at the MM_ message family which allows you to interact with the menu control.  As always, feedback will be enjoyed immensely; send any comments, suggestions, etc. to os2man@panix.com.


[[Category: PM Articles]]
[[Category: PM Articles]]

Revision as of 18:49, 28 September 2016

Written by Larry Salomon Jr.

Introduction

The purpose of this column is to provide the readers out there who are not familiar with PM application development the information necessary to satisfy their curiosity, educate themselves, and give them an advantage over the documentation supplied by IBM. Of course, much of this stuff could probably be found in one of the many books out there, but the problem with books in general is that they don't answer the questions you have after you read the book the first time through.

I will gladly entertain feedback from the readers about what was "glossed over" or what was detailed well, what tangential topics need to be covered and what superfluous crap should have been removed. This feedback is essential in guaranteeing that you get what you pay for. <grin>

It should be said that you must not depend solely on this column to teach you how to develop PM applications; instead, this should be viewed as a supplement to your other information storehouses (books, the network conferences, etc.). Because this column must take a general approach, there will be some topics that you would like to see discussed that really do not belong here. Specific questions can be directed to me via email and I will do my best to answer them in a timely fashion.

Last Month

Last month we began looking at the menu control, which we will continue with this month.

Basic Knowledge Required

Before we may continue, we should take a brief look at the typical use of a menu control, from the programmer's perspective. This involves the definitions of the manifest constants, the menu template definition, the "loading" of the menu (you'll see why "loading" is in quotes in a minute), and the processing of the user's actions. We're taking this different approach to looking at the window class because - as we stated last month - the menu provides the most widely used functionality of any of the window classes; as such, you'll need to know how to use it because you'll be writing this code more times than any other.

Manifest Constants

Manifest constants - a.k.a. #define's - are a convenient language element which allow us to use a "name" in place of something else. For menus, the "something else" is a number which represents an identifier unique to that menu template. You'll find that in larger applications that the file containing these constants can grow quite large, so it would be helpful if, at a glance, you could determine the use of the constant from looking at its name. To accomplish this, I defined a naming convention. You can use this one or your own - it doesn't matter. What does matter is that you spend less time trying to find out how a constant is used and more time on actually using the constant. For menus, I use the following:

Constant form   What it represents
M_id            Menu or submenu identifier
MI_id           Menuitem identifier

The constants that are used for resource definitions I keep in a separate file to allow me to make the file a dependancy of all files that use resources. This is simply a suggestion.

Template Definition

Under Windows, there is App Studio which allows you to define and maintain all of your resources. How come there isn't something like this for OS/2? Regardless, you have to design your menus "blind," meaning that you can't see the result until you actually use the menu you've built.

As it is with writing applications, designing your menu layout should be the most important action; a confusing or deep (i.e. many pullrights) menu structure will often confuse the user and turn them away from using your application. Group the items in submenus in a logical fashion so that the user can "take a guess" at where to look when trying to execute a particular action.

IBM's "Common User Access" (CUA) guidelines define a number of pulldown menus and a (non-inclusive) list of what they should contain. I've included a brief list of these (since I cannot find my CUA book <pout>) below:

Pulldown name Menu items contained therein
File New, Open, Close, Save, Save as, etc.
Edit Undo, Copy, Cut, Paste, etc.
Help Help index, General help, Using help, Keys help

Another important CUA note is the use of the ellipsis and bang punctuation marks on text. An ellipsis should be appended to menu item text when selecting the menu item results in a dialog being displayed. A bang should be appended to text belonging to items on the action bar (note that this therefore excludes pullrights and any popup menu items) when selecting them does not display a pulldown menu (i.e. when it is a leaf-node). These are used as feedback indicators to the user to alert them about the behavior of the application without having them find out "the hard way."

Loading a Menu

Loading a menu usually involves the setting of a flag only. No explicit loading is usually performed by the application code. (Popup menus are the exception to this rule, since the current CUA specification eliminates action bars.) In the call to WinCreateStdWindow(), simply include FCF_MENU on the set of flags passed (by reference) as the third parameter.

   #define RES_CLIENT      256

   HWND hwndFrame;
   HWND hwndClient;
   ULONG ulCreate=FCF_SYSMENU | FCF_TITLEBAR | FCF_MINMAX |
		     FCF_MENU | FCF_SHELLPOSITION | FCF_TASKLIST;

   hwndFrame=WinCreateStdWindow(HWND_DESKTOP,
				WS_VISIBLE,
				&ulCreate,
				CLS_CLIENT,
				"Test application"
				0,
				NULLHANDLE,
				RES_CLIENT,
				&hwndClient);

It has been stated before in this column (I hope) that, when using FCF_MENU, FCF_ICON, or FCF_ACCELTABLE that the eighth parameter must specify the resource identifier of the resources corresponding to these flags. Since we specified FCF_MENU, we should have a menu template defined that begins with:

    MENU RES_CLIENT
      :

If we do not have this defined, the WinCreateStdWindow() function will fail. A useful note here is that, as each component of the window specified in ulCreate is successfully created, the corresponding bit in ulCreate is set to 0. So, the components that were not created successfully can be determined by examining ulCreate after the function fails.

Processing the User's Requests

Now we learn how to utilize the menu in our application code. There are usually two messages that we will be interested in when coding our application: WM_INITMENU and WM_COMMAND. Note that, if any MENUITEMs have the MIS_SYSCOMMAND or MIS_HELP style, we will need to add the WM_SYSCOMMAND and WM_HELP messages to this list, but for the moment we'll assume that we have none with these menu item styles.

WM_INITMENU is sent to the client window whenever a menu or submenu is about to be used by the user, e.g. when the user presses F10 to get to the action bar, when the user clicks on a pulldown menu to display the pulldown, etc. Intercepting this message allows us to dynamically enable or disable menu items according to the state of our application. For example, if the user selects the "Print" menuitem, you might want to disable the "Exit" menuitem until printing is completed. We will see later how to change menuitem attributes.

SHORT1FROMMP(mpParm1) specifies the identifier of the menu. If the actionbar is the cause of the message, this will be FID_MENU; otherwise, it will be the identifier you specified on the SUBMENU statement in the menu template.

HWNDFROMMP(mpParm2) is the handle of the window corresponding to the identifier. You should know that pulldown and pullright menus are actually separate windows which belong to something called an "object" window when not in use. When you click on a pulldown, the appropriate window is retrieved from the object window and displayed on the desktop. This window handle is needed to send messages to the menu.

WM_COMMAND, WM_SYSCOMMAND, and WM_HELP are all sent whenever the user selects a menuitem with the corresponding style. This is your indicator that the user wants something done and that you are to process this request.

SHORT1FROMMP(mpParm1) specifies the identifier of the menuitem selected.

SHORT1FROMMP(mpParm2) specifies the source of the message and will always be CMDSRC_MENU when this message is sent via a menu control.

SHORT2FROMMP(mpParm2) is TRUE if this message was sent as the result of a mouse action or FALSE if sent as the result of a keyboard action.

Next Month

Next month we'll start to look at a sample application that uses the menu control, and we'll begin to look at the MM_ message family which allows you to interact with the menu control. As always, feedback will be enjoyed immensely; send any comments, suggestions, etc. to os2man@panix.com.