home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
PMHINTS1.ZIP
/
PMHINTS.INF
(
.txt
)
< prev
next >
Wrap
OS/2 Help File
|
1991-05-03
|
144KB
|
6,944 lines
ΓòÉΓòÉΓòÉ 1. Introduction ΓòÉΓòÉΓòÉ
This volume, the first of five on OS/2, is not intended to be a guide on how to
write Presentation Manager programs, but is a compilation of the solutions to
most of the common problems encountered by many in IBM, including myself,
whilst writing their own code.
Where applicable I have provided code, and a sample program, to show how to
overcome the problems. You can use the clipboard to copy and paste the code
directly to your program or to a separate file. In addition you will find the
complete source and executables for all the sample programs on the diskette on
which this volume was supplied. Please note however, that these programs do not
have any great function and only serve to confirm that the tips covered in this
volume do work. For this reason I have ignored such things as error checking
and cleaning up on exit except where relevant. Also, please note that these
tips apply to Version 1.2 upwards. In fact all the code I wrote verifying these
tips was written using the 1.2 Toolkit on OS/2 Version 1.3. However, you may
find that some hints, e.g. WinSetPresParam, do not work completely
satisfactorily on Version 1.2.
Note: This volume is not yet complete. Further versions will be released at
regular intervals.
Send any comments to -
Bryan Goodyer
Personal Systems, Europe
IBM UK
Mountbatten House
Basingstoke
Hampshire
UK
VNET (GOODYER @ WINVMB)
ΓòÉΓòÉΓòÉ 2. Dialog Boxes and their Controls ΓòÉΓòÉΓòÉ
This section covers the following topics -
Action Bar
Disabling Controls
Entry Fields
Errors
Focus
Icons
Listboxes
Main Window
Menus
Mnemonics
Multi-line Entry Fields
Position
Push Buttons
Radio Buttons
Size
Status
Styles
Tab Stops
Text
Window ID
Sample Programs
ΓòÉΓòÉΓòÉ 2.1. Action Bar ΓòÉΓòÉΓòÉ
ΓòÉΓòÉΓòÉ 2.1.1. Action Bar in a Dialog Box ΓòÉΓòÉΓòÉ
To add an action bar to your dialog box, first define the menu layout and add
it to your resource file. You will then need to add a call to WinLoadMenu and
send a WM_UPDATEFRAME message to the frame to tell it to update. If you omit
to update the frame then the menu will not appear until you minimize and
restore the box. You should put this in your WM_INITDLG case statement.
ΓòÉΓòÉΓòÉ 2.2. Disabling Controls ΓòÉΓòÉΓòÉ
ΓòÉΓòÉΓòÉ 2.2.1. General ΓòÉΓòÉΓòÉ
To disable a control use WinEnableWindow with the second parameter set to
FALSE. To enable the control call it again with TRUE.
This is a useful technique to use when you don't want your user to activate a
control until he has completed any prerequisites. For example, if you have a
delete pushbutton in your dialog you don't want the user pressing it until he
has selected an item to delete. Using this technique can save you a lot of
validation code.
ΓòÉΓòÉΓòÉ 2.2.2. Entry Fields ΓòÉΓòÉΓòÉ
If you need to disable an entry field which is the first control in the dialog
box then use WinEnableWindow as usual in your WM_INITDLG case statement but
alter the focus to another control. Failure to do this will allow the user to
enter data into the field until he tabs out to another control. It will only be
now that the entry field will become disabled.
It is also important when changing focus in a WM_INITDLG to return TRUE
otherwise focus will not be changed.
ΓòÉΓòÉΓòÉ 2.3. Entry Fields ΓòÉΓòÉΓòÉ
ΓòÉΓòÉΓòÉ 2.3.1. Changing the Default Length ΓòÉΓòÉΓòÉ
To change the default length of 32 for a text entry field send it an
EM_SETTEXTLIMIT message.
Alternatively, you can modify your DLG file by adding control data to the
control(s) on which you want the length set. The example shows how to set the
entry field length to 5 bytes.
The format of CTLDATA is
CTLDATA size, length, minsel, maxsel
where -
size = 8 for 8 bytes of control data
length = number of characters allowed to be entered
minsel = 0 (minsel defines the first char to be initially selected)
maxsel = 0 (maxsel defines the last char to be initially selected)
Note: If you use this latter approach beware if you use the Dialog Box Editor
as you will lose any changes you have made to the DLG file.
ΓòÉΓòÉΓòÉ 2.3.2. Cursor Not Appearing at Edge of Field ΓòÉΓòÉΓòÉ
The usual cause of this problem is a static field defined immediately to the
left of an entry field so that it overlaps it. This has the effect of the
system pointer not changing into the I-beam cursor when it moves into the
field, but as it is moved to the right it changes, if and when it reaches the
end of the static field.
ΓòÉΓòÉΓòÉ 2.3.3. Cursor Position ΓòÉΓòÉΓòÉ
To position the cursor in an entry field send the control an EM_SETSEL message.
The third parameter MPFROM2SHORT(m, n) specifies where the cursor is to be
positioned and what part of the field needs to be selected, if any.
m specifies the offset of the first character in the selection
n specifies the offset of the first character after the selection
If m = n there is no selection but the cursor is positioned at offset m.
If m = 0, n >= text limit the entire text is selected.
ΓòÉΓòÉΓòÉ 2.3.4. Invisible ΓòÉΓòÉΓòÉ
To make an entry field invisible so that it can be used for entering passwords
use the style ES_UNREADABLE. You must add this style manually to your entry
field in your DLG file so be careful if you use the Dialog Box Editor after
making this change as it does not support this style.
You cannot change this style for an entry field in your program, i.e. the code
-
hPwd = WinWindowFromID(hwndDlg, ID_PASSWORD);
WinSetWindowULong(hPwd, QWL_STYLE,
(WinQueryWindowULong(hPwd, QWL_STYLE) | ES_UNREADABLE));
WILL NOT work. The reason is that if changing this style flag meant that the
window changed from being unreadable to readable, or vice versa, anyone could
write a small program to flip the state of password entry fields and read them
making this a very insecure method of password protection.
ΓòÉΓòÉΓòÉ 2.3.5. Reading Data ΓòÉΓòÉΓòÉ
To read data from an entry field use WinQueryWindowText or WinQueryDlgItemText
for character data, or WinQueryDlgItemShort to convert the text to an integer
value.
ΓòÉΓòÉΓòÉ 2.3.6. Numeric Data Only ΓòÉΓòÉΓòÉ
To limit an entry field to numeric data you must subclass the entry field
window and throw away those keystrokes not required. Don't forget that you
will probably need to keep some non-numeric keystrokes, for example -
o Backspace
o Tab
o Minus sign
o Enter
ΓòÉΓòÉΓòÉ 2.3.7. Read-only ΓòÉΓòÉΓòÉ
If you require a read-only entry field then send the control an EM_SETREADONLY
message or add the style ES_READONLY to the control in your DLG file.
Alternatively, you can make the control static and use WinSetWindowText or
WinSetDlgItemText to change the text.
ΓòÉΓòÉΓòÉ 2.3.8. Writing Data ΓòÉΓòÉΓòÉ
To write character data to an entry field use WinSetWindowText or
WinSetDlgItemText.
Use WinSetDlgItemShort to convert an integer value directly to text.
To clear data from an entry field just write null to it.
ΓòÉΓòÉΓòÉ 2.4. Errors ΓòÉΓòÉΓòÉ
ΓòÉΓòÉΓòÉ 2.4.1. Dialog Box Causes Program to Abend ΓòÉΓòÉΓòÉ
If a dialog box causes your program to abend try increasing the stack size
defined in your DEF file.
ΓòÉΓòÉΓòÉ 2.5. Focus ΓòÉΓòÉΓòÉ
ΓòÉΓòÉΓòÉ 2.5.1. Setting Focus ΓòÉΓòÉΓòÉ
The default dialog procedure sets the focus to the first control defined in the
dialog box's DLG file. To override this use WinSetFocus in your WM_INITDLG case
statement. However, you must return TRUE from WM_INITDLG to tell it that the
focus has changed, otherwise the WinSetFocus call will be overridden and the
focus will revert to the first control.
ΓòÉΓòÉΓòÉ 2.6. Icons ΓòÉΓòÉΓòÉ
ΓòÉΓòÉΓòÉ 2.6.1. System Icon in a Dialog Box ΓòÉΓòÉΓòÉ
To include a system icon in a dialog box just add a CONTROL statement directly
into your DLG file. But, be careful if you use the Dialog Box Editor afterwards
as it will not handle it correctly and you will lose it.
For all the "#n" and SPTR_xxx values see the PMWIN.H include file in the
\TOOLKTnn\C\INCLUDE directory.
ΓòÉΓòÉΓòÉ 2.6.2. User Icon in a Dialog Box ΓòÉΓòÉΓòÉ
To include your own icon in a dialog box use the Dialog Box Editor to define
and position the icon on the window and then add an ICON statement to your
resource file specifying which icon filename you want associated with the icon
ID, for example -
ICON ID_DLGICON hints.ico
The associated CONTROL statement generated by the Dialog Box Editor for this is
-
CONTROL ID_DLGICON, ID_DLGICON, 5, 35, 20, 16, WC_STATIC,
SS_ICON | WS_GROUP | WS_VISIBLE
ΓòÉΓòÉΓòÉ 2.7. Listboxes ΓòÉΓòÉΓòÉ
ΓòÉΓòÉΓòÉ 2.7.1. Columns Using Presentation Parameters ΓòÉΓòÉΓòÉ
The easiest way to have columns in listboxes is to use presentation parameters
to change the font to a non-proportional type, for example, Courier.
ΓòÉΓòÉΓòÉ 2.7.2. Columns Using Proportional Fonts ΓòÉΓòÉΓòÉ
If your columns are purely numeric, that also means no leading blanks, then it
doesn't matter what font you use. Numbers take up the same space so they will
line up even using a non-proportional font. See the MLE/Radio Button program
for confirmation of this.
However, if you need to display text in columns then you need to use a
ownerdraw listbox and do the drawing of items yourself.
A very quick and easy way of putting your data into columns is to split your
item rectangle into separate rectangles, treating each rectangle as a column.
Each time you insert an item a WM_DRAWITEM message is sent so that you can
draw the text the way you want it. You must, of course, make sure you have
enough room in each column for the data. If you require horizontal scrolling
then you will need to change the start positions of the second and successive
columns.
When an item is selected then you can decode the text in your LN_SELECT case
statement.
ΓòÉΓòÉΓòÉ 2.7.3. Deleting Items ΓòÉΓòÉΓòÉ
To delete an item from a listbox send it an LM_DELETEITEM message. Remember
that the item's index is zero-based.
If you need to delete all items then send it an LM_DELETEALL message.
ΓòÉΓòÉΓòÉ 2.7.4. Deselecting Items ΓòÉΓòÉΓòÉ
To deselect an item in a listbox send it an LM_SELECTITEM message with the
second parameter set to FALSE. Remember that the item's index is zero-based.
If you wish to deselect all items in a multiple selection listbox then you must
loop through the listbox deselecting each one separately. LIT_NONE for this
type of listbox is ignored since what you are saying is, select another item in
a multiple selection listbox, and of course this does not deselect any
previously selected item.
ΓòÉΓòÉΓòÉ 2.7.5. Inserting Items ΓòÉΓòÉΓòÉ
To insert items into a listbox send it an LM_INSERTITEM message. The first
parameter of this message indicates where the item is to be inserted. It can
either be at the end, in ascending or descending sequence, or at any position.
One of the most common uses of listboxes is to display data extracted from a
database. In such cases it is often useful to store the key of each item so
that you can retrieve any extra data for that item later. A useful technique
for doing this is to use the item handle.
ΓòÉΓòÉΓòÉ 2.7.6. LS_NOADJUSTPOS Style ΓòÉΓòÉΓòÉ
If this style is included then the listbox control is drawn at the size
specified. This can cause parts of an item to be shown at the bottom of the
box. This is very evident if you change to a large font in a listbox. If you do
not specify this style then the listbox is sized according to whatever font it
will be using once initialised so that only complete lines will be drawn. This
may make the box considerably smaller than intended. You should therefore bear
this in mind if you intend using a different font in a listbox.
Furthermore, if you intend allowing the user to change the font at runtime then
if this style is not used then the listbox size will vary quite drastically
according to what font changes are taking place, so much so that eventually it
will be too small to read any items.
ΓòÉΓòÉΓòÉ 2.7.7. LS_NOVERTSCROLL Style ΓòÉΓòÉΓòÉ
This style, which causes a listbox not to have a vertical scroll bar, is
documented on page 16-1 of the Presentation Manager Programming Reference
Manual. However, it was never implemented in the product and so is not
available for use.
If you do not want a vertical scroll bar in your listbox then see Removing
Scroll Bars.
ΓòÉΓòÉΓòÉ 2.7.8. Non-selectable Items ΓòÉΓòÉΓòÉ
If you have a requirement to prohibit selection of certain items in a listbox
then you must use an ownerdraw listbox and handle the selection yourself. In
the ownerdraw code for the listbox sample program you will notice that Finland
is not selectable. This is handled in the WM_DRAWITEM case statement where the
hilighting is handled. You must still code a trap for it in the LN_SELECT
statement, in this case just a warning beep.
This can easily be extended to exclude all entries if desired.
ΓòÉΓòÉΓòÉ 2.7.9. Ownerdraw ΓòÉΓòÉΓòÉ
This topic has probably caused more problems than any other in Presentation
Manager. Briefly, if you want to do anything out of the ordinary with a listbox
the chances are you will have to resort to an ownerdraw listbox. What this
means is that you are responsible for drawing the items in the box so it gives
you complete freedom to do as you please. Probably the most common use of
ownerdraw listboxes is to arrange the data in columns, but their use is really
unlimited.
As a simple introduction we will look at a listbox that centralises the data
and uses our own colours for hilighting. Although this is a very simple
example it does show the basic steps that can be built on to produce something
more complex.
So, to start with you must define your listbox with the style LS_OWNERDRAW,
this can be done manually or by using the Dialog Box Editor. Now, when you have
an ownerdraw listbox your application receives two messages, WM_MEASUREITEM and
WM_DRAWITEM. The purpose of the WM_MEASUREITEM message is to establish the
height and width of the item to be drawn in the listbox, and the WM_DRAWITEM
message is sent whenever the item needs to be drawn.
Looking at the WM_MEASUREITEM message first, all we need to do here is query
the font metrics to get the maximum vertical distance from one character
baseline to the next character baseline, lMaxBaselineExt, for the current
logical font. Once we have this value we return it to the system. Since we
don't have a horizontal scroll bar we are not interested in the width so just
return 0 for its value. However, if you do need to have a horizontal scroll bar
then you must return the width of the item. You can get this by using
GpiQueryTextBox. One point worth remembering when you have a horizontal scroll
bar is that this message is sent every time an item is inserted or deleted for
each item in the listbox. This means that when you insert the first 3 items,
for example, 6 messages are sent (1+2+3). This is so the system can determine
the height and width of every item. For this reason care should be taken not
to code lengthy calculations here.
We get a WM_DRAWITEM message whenever the listbox needs to be redrawn, for
example when an item is inserted or selected. On entry the second parameter,
mp2, is a pointer to an OWNERITEM structure which gives us information about
the item to be drawn, such as the size of the rectangle it is to be drawn in,
its select state, a handle to its presentation space and others, but for this
simple example that's all we are interested in.
If the state is 0 then the item is not selected so we set the normal colours,
in this case yellow on dark green, if it's 1 then it is selected so we reverse
the colours. All that needs to be done now is draw the text and exit. The
important points to note here though are -
1. Current and old states must be set to 0 else Presentation Manager will
take over hilighting and change what we have done.
2. We must return TRUE to prevent Presentation Manager from doing the
drawing. If we don't then the text will be left justified and in system
colours.
This is obviously a trivial example but should be sufficient to get you
started in this area.
Note: If all you want to do with your listbox is change the font or
foreground and background colours then there is no need to resort to an
ownerdraw listbox as from OS/2 Version 1.2 onwards you can do this with
presentation parameters. However, if you do need to use a different font in an
ownerdraw listbox then you can use presentation parameters, but you must put
the call to WinSetPresParam in your WM_MEASUREITEM statement otherwise the
item height will not be set correctly, so if you use a font larger than the
system font, it will be clipped. Not only that, but it must only be executed
once otherwise the program will get a trap 000C -
SYS1942 A program attempted to reference storage outside the limits
of a stack segment.
You therefore need a first-time flag to overcome this.
Note: This only really applies if you have horizontal scrolling since the
WM_MEASUREITEM message is only sent once.
ΓòÉΓòÉΓòÉ 2.7.10. Processing Multiple Items ΓòÉΓòÉΓòÉ
To process the selected items in a multiple selection listbox, first send a
LM_QUERYSELECTION message with the first parameter set to LIT_FIRST, this will
return the index of the first selected item. You can then process this item
and then send another LM_QUERYSELECTION message with the first parameter set
to the index previously returned. Continue this until LIT_NONE is returned.
If this process is going to take some time, and it may well do, since many
items are going to be processed, then you should consider putting it in another
thread. If you don't want the user interacting with your application whilst
this thread is running then you can disable any relevant controls until the
thread has completed.
Note: To deselect items send each one an LM_SELECTITEM message.
ΓòÉΓòÉΓòÉ 2.7.11. Removing Scroll Bars ΓòÉΓòÉΓòÉ
There is no clean method for removing a scroll bar from a listbox. The best
that can be done is to get the handle of the scroll bar and use
WinDestroyWindow to destroy it. However, this leaves a blank space so looks
untidy. Note that removing a vertical scroll bar does not prevent scrolling up
and down, whereas removing a horizontal scroll bar does prevent sideways
scrolling.
ΓòÉΓòÉΓòÉ 2.7.12. Retrieving Data Associated with Items ΓòÉΓòÉΓòÉ
After saving data in an item handle you can retrieve it again by sending the
listbox an LM_QUERYITEMHANDLE message.
ΓòÉΓòÉΓòÉ 2.7.13. Retrieving the Text of a Selected Item ΓòÉΓòÉΓòÉ
To get the text of a selected item you must first send the listbox an
LM_QUERYSELECTION message to get the index of the selected item, the first
entry in a listbox having an index of 0. Once you have this value you send it
an LM_QUERYITEMTEXT message to get the actual text.
Listboxes generate a WM_CONTROL message, so to process it for a listbox check
the low word of the mp1 parameter using the SHORT1FROMMP macro and then the
high word of the mp1 parameter using the SHORT2FROMMP macro for the LN_
notification code. In this case LN_SELECT.
ΓòÉΓòÉΓòÉ 2.7.14. Saving Data Associated with Items ΓòÉΓòÉΓòÉ
When inserting items into a listbox it is often useful to save data associated
with each item, for example, the key field to a database row. To do this, after
inserting the item send the listbox an LM_SETITEMHANDLE message. At its
simplest this could be just the key field, but you may need to store more data
in which case you can define the necessary structure and store a pointer to it
in the handle.
To retrieve the data send the listbox an LM_QUERYITEMHANDLE.
Note: Since it is necessary to allocate memory in order to save the data then
when deleting items you should free any necessary memory, and when removing the
listbox you should free all memory associated with it. Another point worth
mentioning is when allocating memory under OS/2 Version 2 the minimum amount
allocated will be one page, i.e. 4KB, so you should take this into account
when allocating memory for your application if it is to run under this version.
ΓòÉΓòÉΓòÉ 2.7.15. Selecting Items ΓòÉΓòÉΓòÉ
To select an item in a listbox send it an LM_SELECTITEM message. Remember that
the item's index is zero-based.
ΓòÉΓòÉΓòÉ 2.8. Main Window ΓòÉΓòÉΓòÉ
ΓòÉΓòÉΓòÉ 2.8.1. Dialog Box as a Main Window ΓòÉΓòÉΓòÉ
It is sometimes very convenient to use the Dialog Box Editor to create a window
and have this window your main, or only, window. The easiest way to do this is
to create a modal dialog box in your main routine. You will not need any
get/dispatch message loop as this is part of the WinDlgBox call. When this
call returns it means your dialog box no longer exists and you can terminate
your application.
Alternatively, instead of using WinDlgBox you can use WinLoadDlg/WinProcessDlg.
ΓòÉΓòÉΓòÉ 2.8.2. Starting Minimized ΓòÉΓòÉΓòÉ
To create a dialog in its minimized state use SWP_MINIMIZE in your
WinSetWindowPos call.
ΓòÉΓòÉΓòÉ 2.9. Menus ΓòÉΓòÉΓòÉ
ΓòÉΓòÉΓòÉ 2.9.1. Pop-up Menus ΓòÉΓòÉΓòÉ
This is very similar to pop-ups for client windows, but because a dialog box is
really just a frame window there are some subtle differences.
In your WM_INITDLG processing you still need to do the WinQuerySysValue and
WinLoadMenu, but you must be careful where you put it as it is very likely that
your dialog box will already have a conventional menu. This means you will have
a WinLoadMenu and a WM_UPDATEFRAME for the action bar, so if you place the
WinLoadMenu for your pop-up before the WM_UPDATEFRAME then you will find that
when the menu pops up so will its action bar. As this is undesirable place it
after.
The WM_BUTTON2DOWN message processing is identical to that for client windows
but what must be added is a case for WM_NEXTMENU to prevent your application
hanging if the pop-up menu is displayed and the user presses button 1 in the
dialog box area outside the menu. All that's needed is to return FALSE from
this message.
Unfortunately, another problem exists if you minimize the dialog box. When you
restore it the system sends the frame a WM_UPDATEFRAME message causing the
pop-up menu's action bar to be displayed and any options on the main action
bar to disappear. Now to overcome this you must reload the main menu again
when the box is restored. This causes the options to reappear on the action bar
and the desired absence of the pop-up menu's action bar. But obviously you must
destroy the original action bar, with WinDestroyWindow, when minimizing
otherwise each time you minimize/restore an extra action bar will be created.
ΓòÉΓòÉΓòÉ 2.10. Mnemonics ΓòÉΓòÉΓòÉ
ΓòÉΓòÉΓòÉ 2.10.1. Mnemonics for Controls ΓòÉΓòÉΓòÉ
If you want to use mnemonics in a dialog box then define a static text field
with the DT_MNEMONIC style, either manually or by using the Dialog Box Editor,
and place this immediately before the control you want the mnemonic to act
upon. This creates a mnemonic based on the position of the static text control
in the resource, and underlines the letter with the tilde.
CONTROL "~Single Selection", 101, 10, 155, 71, 8, WC_STATIC, SS_TEXT |
DT_LEFT | DT_TOP | DT_MNEMONIC | WS_GROUP | WS_VISIBLE
CONTROL "", ID_SLISTBOX, 8, 71, 80, 80, WC_LISTBOX, WS_TABSTOP |
WS_VISIBLE
In the above example when the user presses Alt-S from anywhere in the dialog,
or S from a non-text entry field, it will automatically set the focus to the
listbox control.
ΓòÉΓòÉΓòÉ 2.11. Multi-line Entry Fields ΓòÉΓòÉΓòÉ
ΓòÉΓòÉΓòÉ 2.11.1. Changing Font ΓòÉΓòÉΓòÉ
The simplest method of changing the font, or colour, of a control is to use
presentation parameters. This method works fine for all controls in a dialog
box except Multi-line Entry fields (MLE) in which only the following fonts
appear to work -
8 point Courier
10 point Courier
12 point Courier
8 point Helvetica
10 point Helvetica
12 point Helvetica
14 point Helvetica
18 point Helvetica
24 point Helvetica
To effect this font change use WinSetPresParam. If you need to use a different
font in an MLE then you must use the traditional approach, an example of which
may be found in the OS/2 Toolkit sample program FONTTEST.
Note: The above restriction may change with later levels of OS/2. This is
applicable to the initial release of Version 1.3 so if you have a later
version then I suggest you try this method first.
ΓòÉΓòÉΓòÉ 2.11.2. Clearing the MLE ΓòÉΓòÉΓòÉ
To clear the text from an MLE use WinSetDlgItemText or WinSetWindowText.
ΓòÉΓòÉΓòÉ 2.11.3. Importing a File ΓòÉΓòÉΓòÉ
To import a file to an MLE you must first allocate a buffer into which you read
the file, or part of the file, and then set this buffer as the current transfer
buffer for the MLE. You can then import the file. If you require the file to
be inserted at the current cursor position then set the insertion point to -1.
The sample code reads in the CONFIG.SYS file and imports it at the current
cursor position.
ΓòÉΓòÉΓòÉ 2.12. Position ΓòÉΓòÉΓòÉ
ΓòÉΓòÉΓòÉ 2.12.1. Positioning a Dialog Box on the Desktop ΓòÉΓòÉΓòÉ
To position a dialog box on the desktop use WinSetWindowPos without the
SWP_SIZE option in your WM_INITDLG code.
ΓòÉΓòÉΓòÉ 2.13. Push Buttons ΓòÉΓòÉΓòÉ
ΓòÉΓòÉΓòÉ 2.13.1. Default ΓòÉΓòÉΓòÉ
To determine which push button is the default use WinQueryWindowULong.
To remove the default style send the button a BM_SETDEFAULT message set to
FALSE and to make it the default again send the same message set to TRUE.
Alternatively, to set/remove the default state you can also use
WinSetWindowBits, but you must call WinInvalidateRect to force a repaint of the
button afterwards to ensure the default border is added/removed as appropriate.
Note: From OS/2 Version 1.3 onwards setting another push button to be the
default will cause the current default button to lose its default state.
ΓòÉΓòÉΓòÉ 2.13.2. User Button ΓòÉΓòÉΓòÉ
If you need to display a bitmap in a push button, for example the system bitmap
for a drive, then you must use a push button with the style BS_USERBUTTON.
Using this causes a BN_PAINT message to be sent to your window procedure.
If you wish to display a non-system bitmap in a push button then you must
define it in your resource file and load it in your paint procedure prior to
display.
The user button code shows both methods. It makes use of the DBM_STRETCH option
so that the bitmap is stretched to the full size of the button.
ΓòÉΓòÉΓòÉ 2.14. Radio Buttons ΓòÉΓòÉΓòÉ
ΓòÉΓòÉΓòÉ 2.14.1. Setting at Initialisation ΓòÉΓòÉΓòÉ
This is probably the most common problem of all with radio buttons. If you have
a group of radio buttons and you want to check one other than the first when
starting your dialog, then
case WM_INITDLG:
WinSendDlgItemMsg(hwnd, BUTTON_ID, BM_SETCHECK,
MPFROM2SHORT(TRUE, 0), NULL);
will usually work.
However, if the group of buttons is the first control in the dialog box then
the first button will be checked, irrespective of whatever button ID you
specified on the WinSendDlgItemMsg. To overcome this, check the required
button as shown above but make sure you return TRUE from the WM_INITDLG.
ΓòÉΓòÉΓòÉ 2.15. Size ΓòÉΓòÉΓòÉ
ΓòÉΓòÉΓòÉ 2.15.1. Minimizing a Dialog Box ΓòÉΓòÉΓòÉ
The most common problem encountered when minimizing dialog boxes is the
disappearance of your icon. Instead, Presentation Manager paints over the icon
with the bottom left corner of your dialog box. To overcome this you must
first load your icon using WinLoadPointer and then send a WM_SETICON message
to the dialog box. You should do this in your WM_INITDLG code. You must then
trap your WM_ADJUSTWINDOWPOS message and if minimizing, hide the control(s) at
the bottom left corner of the box. Conversely, when restoring you must show
the control(s) again. Finally, pass control back to the default dialog
procedure so that it can do any default processing.
You should also add a WinDestroyPointer call during your exit processing.
ΓòÉΓòÉΓòÉ 2.16. Status ΓòÉΓòÉΓòÉ
ΓòÉΓòÉΓòÉ 2.16.1. Status Bar ΓòÉΓòÉΓòÉ
If you have ever run the AVIOSAMP sample program from the Toolkit you will have
noticed that it has a status bar. This bar gives the user the current
application status, for example whether he is in insert mode or not.
Here are two ways this can be implemented in dialog boxes, the first makes use
of the WM_PAINT message and WinDrawText to display the status. But perhaps the
easier method is to define a static text field in your dialog box and use
WinSetPresParam in your WM_INITDLG to initialise the colours. In this case
you use WinSetWindowText to display the status as and when necessary.
ΓòÉΓòÉΓòÉ 2.17. Styles ΓòÉΓòÉΓòÉ
ΓòÉΓòÉΓòÉ 2.17.1. Changing a Control's Style ΓòÉΓòÉΓòÉ
To change a control's style, for example, to change an entry field's style of
left align to centred, use WinSetWindowULong.
ΓòÉΓòÉΓòÉ 2.18. Tab Stops ΓòÉΓòÉΓòÉ
ΓòÉΓòÉΓòÉ 2.18.1. Removing and Adding ΓòÉΓòÉΓòÉ
If you need to remove/add the TABSTOP from a dialog box control, a push button
for example, then use WinSetWindowULong.
ΓòÉΓòÉΓòÉ 2.19. Text ΓòÉΓòÉΓòÉ
ΓòÉΓòÉΓòÉ 2.19.1. Backslash in a Static Text Window ΓòÉΓòÉΓòÉ
If you require a \ in a static text window then, like C, you must code a double
slash, i.e. \\.
ΓòÉΓòÉΓòÉ 2.19.2. Changing the Dialog Box Title ΓòÉΓòÉΓòÉ
To change the title of the dialog box use WinSetWindowText with the window
handle set to the actual dialog box handle, i.e. the frame handle.
Alternatively, use WinSetDlgItemText.
ΓòÉΓòÉΓòÉ 2.19.3. Changing the Text in a Dialog Box Control ΓòÉΓòÉΓòÉ
To change the text in a dialog box control use WinSetWindowText with the window
handle set to the handle of the control you wish to change. You can use
WinWindowFromID to get this value.
ΓòÉΓòÉΓòÉ 2.19.4. Forcing a Line Break in Static Text Windows ΓòÉΓòÉΓòÉ
If you have a static text window with word wrap defined in your dialog box and
you wish to force a line break, then use \012 at the point you wish to break.
For example, in your DLG file -
CONTROL "Line one\012Line two\012Line three", ...etc
will produce -
Line one
Line two
Line three
You can do this either by modifying your DLG file manually or by using
WinSetWindowText within your program.
Unfortunately, if you use the Dialog Box Editor the \012s are replaced by line
breaks in the DLG file and the Resource Compiler fails with a syntax error.
ΓòÉΓòÉΓòÉ 2.20. Window ID ΓòÉΓòÉΓòÉ
ΓòÉΓòÉΓòÉ 2.20.1. Window ID of a Control ΓòÉΓòÉΓòÉ
To retrieve the window identity of a control within a dialog box use
WinQueryWindowUShort with a value of QWS_ID.
ΓòÉΓòÉΓòÉ 2.21. Sample Programs ΓòÉΓòÉΓòÉ
ΓòÉΓòÉΓòÉ 2.21.1. General Dialog Box ΓòÉΓòÉΓòÉ
This sample program does not have any real function but was written to test
that most of the tips in this section do work. You will find many areas
commented out, this was done to check that any alternative methods also
functioned correctly.
If you run the program and press OK most of the features described in this
section and the section on pop-up menus for dialog boxes are actioned.
Pressing button 2 causes the pop-up menu to appear.
See the following sample programs for verification of all other tips.
Listbox
MLE and Radio Buttons
HINTS.C - C source file
HINTS.H - Header file
HINTS.L - Link control file
HINTS.DEF - Module definition file
HINTS.RC - Resource file
HINTS.DLG - Dialog template
HINTS - Make file
Run program (Launch doesn't work in 1.3 yet!)
ΓòÉΓòÉΓòÉ 2.21.2. MLE and Radio Buttons ΓòÉΓòÉΓòÉ
This program was written to verify that the multi-line entry field and radio
button tips function correctly. See the following sample programs for
verification of all other tips.
General Dialog Box
Listbox
Note: This program also makes use of Presentation Parameters.
HINTS.C - C source file
HINTS.H - Header file
HINTS.L - Link control file
HINTS.DEF - Module definition file
HINTS.RC - Resource file
HINTS.DLG - Dialog template
HINTS - Make file
Run program (Launch doesn't work in 1.3 yet!)
ΓòÉΓòÉΓòÉ 2.21.3. Listbox ΓòÉΓòÉΓòÉ
This program was written to verify that the Listbox tips function correctly.
See the following sample programs for verification of all other tips.
General Dialog Box
MLE and Radio Buttons
This program displays three listboxes, single and multiple selection, and an
ownerdraw, with the first item selected in the single selection box on entry.
Items can be deselected from the single and ownerdraw boxes by pressing
Deselect, and can be deleted from the single selection box by pressing Delete.
If you select items in the multiple selection box and press Process MultSel
then each one is processed sequentially and beeps when complete. Notice that
this option uses DosSleep to do this which is not recommended. It is done
here merely to slow down the process so that you can see what is happening.
The ownerdraw box is a simple implementation of columnar data with Finland
non-selectable (I've nothing against Finland, I just happened to pick it at
random, my apologies to all those Finns using this package). Finally, pressing
Alt-S, Alt-M or Alt-O will switch focus to the relevant listbox.
HINTS.C - C source file
HINTS.H - Header file
HINTS.L - Link control file
HINTS.DEF - Module definition file
HINTS.RC - Resource file
HINTS.DLG - Dialog template
HINTS - Make file
Run program (Launch doesn't work in 1.3 yet!)
ΓòÉΓòÉΓòÉ 3. Fonts ΓòÉΓòÉΓòÉ
This section covers the following topics -
Point Sizes and Face Names
ΓòÉΓòÉΓòÉ 3.1. Point Sizes and Face Names ΓòÉΓòÉΓòÉ
The following list represents the point sizes and face names of all the
standard fonts in the system. You may use all of them with WinSetPresParam
unless you wish to use it for changing the font of a Multi-line Entry field, in
which case there are limitations.
8.Courier
10.Courier
12.Courier
8.Helv
10.Helv
12.Helv
14.Helv
18.Helv
24.Helv
10.System Monospaced
12.System Monospaced
12.System Proportional
8.Tms Rmn
10.Tms Rmn
12.Tms Rmn
14.Tms Rmn
18.Tms Rmn
24.Tms Rmn
ΓòÉΓòÉΓòÉ 4. Menus ΓòÉΓòÉΓòÉ
This section covers the following topics -
Add Items to the System Menu
Change a Window's Menu
Check Menu Item
Delete Items from the System Menu
Delete Separator from the System Menu
Disable Action Bar
Disable Items in an Application Menu
Disable Items in the System Menu
Dismiss 'MIA_NODISMISS' Menu
Pop-up Menus for Client Windows
Pop-up Menus for Dialog Boxes
Pop-up Sample Program (Dialog Box)
Sample Program
ΓòÉΓòÉΓòÉ 4.1. Add Items to the System Menu ΓòÉΓòÉΓòÉ
Perhaps one of the most common queries regarding menus is 'How can I alter the
system menu?', usually to add an About option, so let's look at how this is
done.
The first thing to do is get the handle of the system menu by calling
WinWindowFromID with the identifier FID_SYSMENU. We then send it an
MM_ITEMIDFROMPOSITION to get the ID of the actual menu list. Once we have this
we can get the characteristics of the menu by sending it an MM_QUERYITEM
message. The important item returned in the SysMenu structure is the actual
handle of the submenu. Armed with this we can insert our items into it by
sending the submenu an MM_INSERTITEM message. If you look at the declaration
of Item you will see that we are adding a separator and some text, the actual
text being defined in Text.
This code would normally be executed at window creation time, i.e. in your
WM_CREATE statement, so don't forget that you cannot use hwndFrame at this
point.
Clicking on About... will cause a WM_COMMAND message with the low short of mp1
set to ID_ABOUT. On receiving this we display a message box giving details
about the program. This information could alternatively be displayed in a
dialog box.
ΓòÉΓòÉΓòÉ 4.2. Change a Window's Menu ΓòÉΓòÉΓòÉ
There may be times when it is convenient for you to have two or more menus
defined in your resource file for a window, and have any one loaded at any
given time depending on circumstances. An easy way to do this is to destroy
the current menu and use WinLoadMenu to load the next. You must then follow
this with a WM_UPDATEFRAME message.
ΓòÉΓòÉΓòÉ 4.3. Check Menu Item ΓòÉΓòÉΓòÉ
Whenever a menu is about to be activated the system sends your application a
WM_INITMENU message. The purpose being that you can make any changes to the
submenu before it is displayed. For example, you may need to add a check mark
to an item, or to toggle the item on/off depending on the current state of the
application. The sample code shows this by setting up a flag, initially FALSE,
and sending an MM_SETITEMATTR message to the menu. Because we are sending the
message to the top-level menu rather than the submenu we must specify TRUE to
ensure the submenu is searched for the item. Because we want to check an item
we use the MIA_CHECKED attribute. The data associated with this is dependent on
the flag, and since it is initially FALSE the item is not checked. However, if
we now select the item the flag changes state and next time the menu is
displayed the item will be checked.
Note: This also applies to disabling items using the MIA_DISABLED attribute.
ΓòÉΓòÉΓòÉ 4.4. Delete Items from the System Menu ΓòÉΓòÉΓòÉ
To delete items you must first obtain the handle of the system menu and then
send it an MM_DELETEITEM message.
ΓòÉΓòÉΓòÉ 4.5. Delete Separator from the System Menu ΓòÉΓòÉΓòÉ
If you want to remove Close from the system menu you will also need to remove
the separator following it. The problem with deleting menu separators is that
their IDs vary. For example, the first separator will have an ID of -2, and the
next -3 etc. so you cannot supply a fixed value for a separator ID as you
don't know its position.
To do this then you must first get the handle of the system menu submenu, i.e.
the actual menu displaying the items, and send an MM_ITEMPOSITIONFROMID
message to get the position of Close in the menu, you can then add 1 to this to
get the position of the separator. Sending an MM_ITEMIDFROMPOSITION message
for this value now gives the actual item ID for the separator which can now be
used in the MM_DELETEITEM message. The Close option can be deleted in the
normal manner, i.e. use (SC_CLOSE, TRUE) with the system menu handle.
ΓòÉΓòÉΓòÉ 4.6. Disable/Enable Action Bar ΓòÉΓòÉΓòÉ
To disable the action bar, and thus all its pull-down menus, use
WinEnableWindow.
ΓòÉΓòÉΓòÉ 4.7. Disable/Enable Items in an Application Menu ΓòÉΓòÉΓòÉ
To disable, or enable, items in your application menu you must first obtain its
handle and then send it an MM_SETITEMATTR message to change the attribute of
the item. This would normally be done in your WM_INITMENU statement depending
on the setting of a flag. See also Check Menu Item.
ΓòÉΓòÉΓòÉ 4.8. Disable/Enable Items in the System Menu ΓòÉΓòÉΓòÉ
To disable, or enable, items you must first obtain the handle of the system
menu and then send it an MM_SETITEMATTR message to change the attribute of the
item. However, you can only disable Close and Switch to... using this method.
If you need to disable Move then using WinEnableWindow to disable the title
bar will cause Move to be greyed as a result.
Note: There are no such restrictions in deleting items from the system menu.
ΓòÉΓòÉΓòÉ 4.9. Dismiss 'MIA_NODISMISS' Menu ΓòÉΓòÉΓòÉ
If you have a menu in which one or more items are defined with the
MIA_NODISMISS attribute and you select one of these items, then the menu does
not disappear. This may be what you need in your application, but, the problem
comes when you want to dismiss it, say by pressing a mouse button. You will not
be able to do it by sending an MM_DISMISSMENU message as the menu is no longer
in menu mode. Instead, you must post MM_STARTMENUMODE and MM_ENDMENUMODE
messages. Notice that the MM_ENDMENUMODE message is posted. The documentation
states that this message should be sent. However, the MM_STARTMENUMODE
message MUST be posted, so if the START was posted, and the END was sent, then
the END would be processed first. This is why both must be posted.
ΓòÉΓòÉΓòÉ 4.10. Pop-up ΓòÉΓòÉΓòÉ
ΓòÉΓòÉΓòÉ 4.10.1. For Client Windows ΓòÉΓòÉΓòÉ
It can sometimes be useful for your user to be able to pop up a menu by
pressing mouse button 2, for example, rather than have to move to the action
bar. To do this, first define your menu in the usual way in your resource file,
and then trap the WM_CREATE and WM_BUTTON2DOWN messages in your window
procedure.
In the WM_CREATE case you need to get the handle of the menu by using
WinLoadMenu and the action bar height by using WinQuerySysValue with
SV_CYMENU, i.e. the height of a single line menu. This is needed so that you
can position the pop-up so that the first menu item lines up with the pointer.
Without doing this you will find that the menu items are an action bar's height
below the pointer.
To complete the implementation you need to get the position of the mouse
pointer by using the macro MOUSEMSG, making sure you adjust the Y coordinate by
adding the action bar height to it. Finally you must POST an MM_STARTMENUMODE
message to the menu handle and position the menu using WinSetWindowPos. You
can, of course, use a push button or any other method to initiate the pop-up,
but pressing button 2 is probably the best method.
You must then add the relevant case statements for the menu items in your
WM_COMMAND message processing.
ΓòÉΓòÉΓòÉ 4.10.2. For Dialog Boxes ΓòÉΓòÉΓòÉ
This is very similar to pop-ups for client windows, but because a dialog box is
really just a frame window there are some subtle differences.
In your WM_INITDLG processing you still need to do the WinQuerySysValue and
WinLoadMenu, but you must be careful where you put it as it is very likely that
your dialog box will already have a conventional menu. This means you will have
a WinLoadMenu and a WM_UPDATEFRAME for the action bar, so if you place the
WinLoadMenu for your pop-up before the WM_UPDATEFRAME then you will find that
when the menu pops up so will its action bar. As this is undesirable place it
after.
The WM_BUTTON2DOWN message processing is identical to that for client windows
but what must be added is a case for WM_NEXTMENU to prevent your application
hanging if the pop-up menu is displayed and the user presses button 1 in the
dialog box area outside the menu. All that's needed is to return FALSE from
this message.
Unfortunately, another problem exists if you minimize the dialog box. When you
restore it the system sends the frame a WM_UPDATEFRAME message causing the
pop-up menu's action bar to be displayed and any options on the main action
bar to disappear. Now to overcome this you must reload the main menu again
when the box is restored. This causes the options to reappear on the action bar
and the desired absence of the pop-up menu's action bar. But obviously you must
destroy the original action bar, with WinDestroyWindow, when minimizing
otherwise each time you minimize/restore an extra action bar will be created.
ΓòÉΓòÉΓòÉ 4.10.3. Sample Program (Dialog Box) ΓòÉΓòÉΓòÉ
See General Dialog Box sample program.
ΓòÉΓòÉΓòÉ 4.11. Sample Program - Menus and Task Manager ΓòÉΓòÉΓòÉ
This sample program was written to confirm the hints and tips given in the
Menus and Task Manager sections and shows the following -
Starting in background
Adding/removing from the task list
Changing the task list
Querying the task list
Disable 'End Task' button in the task list
Disable 'Close' and 'Switch to...' in the system menu
Delete 'Size' and 'Move' from the system menu
Prohibiting exit from the task list and system menu
Adding an 'About...' option to the system menu
Disable all menu items
Make application system modal
Toggle menu item checked/unchecked
Force dismissal of MIA_NODISMISS menu
Delete 'Close' and its separator from the system menu
Changing menus
Initially, 'Close' and 'Switch to...' in the system menu and 'End Task' in
the task list are greyed out and the action bar is disabled. Pressing button
1 enables the action bar, 'Close' and 'End Task' but doesn't allow closure
from these options. Exit is via the action bar only. The title is also changed
in the task list. Pressing button 2 removes 'Close' from the system menu.
Pressing 'Switch Menus' causes a different menu to be loaded which has two
options with two items under 'Option 1'. The first is 'checkable' and and the
second is 'NODISMISS', until button 1 is clicked.
HINTS.C - C source file
HINTS.H - Header file
HINTS.L - Link control file
HINTS.DEF - Module definition file
HINTS.RC - Resource file
HINTS - Make file
Run program (Launch doesn't work in 1.3 yet!)
ΓòÉΓòÉΓòÉ 5. Mouse and Pointer Control ΓòÉΓòÉΓòÉ
This section covers the following topics -
Changing the Pointer in a Window
Mouse Pointer Position
Sample Program
ΓòÉΓòÉΓòÉ 5.1. Changing the Pointer in a Window ΓòÉΓòÉΓòÉ
If your application needs to do some lengthy processing in a separate thread,
it is a good idea to change the pointer to the hourglass to give the user some
visual feedback telling him that he must wait before he is able to continue
with the application. It is also a good idea to change the pointer back to the
arrow when it is moved outside your window so that he knows he can continue
with another application. You will, of course, have to disable all the
controls in your application you don't want used whilst the other thread is
being processed, as just changing the pointer doesn't stop you using it. So, to
do this, trap the WM_CONTROLPOINTER and WM_MOUSEMOVE messages. Whenever the
pointer moves into a new window a WM_CONTROLPOINTER message is sent to a
control's owner window allowing you to change the pointer. You also need to
set the pointer during WM_MOUSEMOVE messages otherwise it will revert to the
system arrow pointer.
If you have dialog boxes in your application then you may not need to trap both
messages, WM_CONTROLPOINTER may suffice, so try this first. If you find that
the hourglass reverts to the arrow then you will have to subclass the
particular control concerned. For example, in this section's sample program
you will find a dialog box with an entry field and listbox. Without subclassing
I found that if the entry field was disabled then the hourglass reverted if it
moved over it, and moving the pointer to the listbox scrollbar also caused the
same reversion. Subclassing the entry field and trapping the WM_MOUSEMOVE
messages stopped the reversion for the entry field, and subclassing the listbox
and trapping the WM_CONTROLPOINTER messages stopped the scrollbar reverting
the pointer. If you use other controls then you may find similar peculiarities
so try subclassing and trapping either, or both messages.
Note: The above technique also works if you wish to change the pointer to an
icon, provided you load it first using WinLoadPointer.
ΓòÉΓòÉΓòÉ 5.2. Mouse Pointer Position ΓòÉΓòÉΓòÉ
To retrieve the position of the mouse pointer use WinQueryPointerPos. This will
return the co-ordinates in screen units. If you want the co-ordinates relative
to your window then use WinMapWindowPoints.
ΓòÉΓòÉΓòÉ 5.3. Sample Program ΓòÉΓòÉΓòÉ
This program shows the following -
Changing the pointer in a window
Mouse pointer position
When the program first starts it is in a busy state, i.e. the pointer
changes to the hourglass whenever it moves into the window. If you click on
the Test DLG button a dialog box is displayed with an entry field and listbox.
The purpose of this is to show that the controls must be subclassed to
maintain the hourglass. In the case of the entry field this is only necessary
if it has been disabled, and in the case of the listbox it is necessary to
maintain the hourglass in the scrollbar region. Try changing the program by
removing the subclassing to see the effect.
If you use other controls, notably MLEs, then you will also have to use
subclassing to maintain the hourglass fully.
To remove the hourglass, i.e. revert to not busy press the Remove Hourglass
button.
You will also notice that the mouse position is displayed in screen
co-ordinates and window co-ordinates whenever the mouse is moved over the
window. If you press, and hold down, button 2 then the mouse will be captured
and its position will be displayed wherever it is on the desktop. Releasing
the button releases the capture.
HINTS.C - C source file
HINTS.H - Header file
HINTS.L - Link control file
HINTS.DEF - Module definition file
HINTS.RC - Resource file
HINTS.DLG - Dialog template
HINTS - Make file
Run program (Launch doesn't work in 1.3 yet!)
ΓòÉΓòÉΓòÉ 6. Presentation Parameters ΓòÉΓòÉΓòÉ
This section covers the following topics -
Changing Colour
Changing Font
Using it on a Frame Window
Sample Program
ΓòÉΓòÉΓòÉ 6.1. Changing Colour ΓòÉΓòÉΓòÉ
To change a control's colour you can either do it at runtime using
WinSetPresParam or by presetting it in the DLG file using the PRESPARAMS
statement.
Note: If you use the latter approach you must add
#define INCL_WINSYS
to your resource file otherwise you will get the error message Undefined
keyword or name from the Resource Compiler. Also, if you subsequently edit the
DLG file by using the Dialog Box Editor the CLR_RED etc will be replaced by
their numeric values, i.e.
PRESPARAMS PP_BACKGROUNDCOLORINDEX, CLR_RED
PRESPARAMS PP_FOREGROUNDCOLORINDEX, CLR_YELLOW
becomes
PRESPARAMS PP_BACKGROUNDCOLORINDEX, 0x00000002L
PRESPARAMS PP_FOREGROUNDCOLORINDEX, 0x00000006L
ΓòÉΓòÉΓòÉ 6.2. Changing Font ΓòÉΓòÉΓòÉ
To change the font of a dialog control or window you can either do it at
runtime using WinSetPresParam or, for a dialog control, by presetting it in
the DLG file using the PRESPARAMS statement.
Note: If you use the latter approach you must add
#define INCL_WINSYS
to your resource file otherwise you will get the error message Undefined
keyword or name from the Resource Compiler. Also, if you subsequently edit the
DLG file by using the Dialog Box Editor the 10.Courier will be replaced by its
meaningless numeric equivalent, i.e.
PRESPARAMS PP_FONTNAMESIZE, "10.Courier"
becomes
PRESPARAMS PP_FONTNAMESIZE, 0x432E3031L, 0x6972756FL, 0x00007265L
Although this is a very simple way of changing the font care must be exercised
when using this method for Multi-line Entry fields as many fonts cannot be set
using WinSetPresParam.
Similarly, if you intend to change the font in a listbox at runtime using this
method then ensure it has the style LS_NOADJUSTPOS otherwise the listbox will
adjust its size according to what font you use and may render the listbox
illegible. Also, if you are using an ownerdraw listbox care should be taken
where you place the WinSetPresParam call. See the ownerdraw listbox reference
for details.
Note: You cannot use this method to change the font style, e.g. italic or
bold.
ΓòÉΓòÉΓòÉ 6.3. Using it on a Frame Window ΓòÉΓòÉΓòÉ
If you use WinSetPresParam on a frame handle then it affects all the controls
within that frame, except perhaps the font for any Multi-line Entry fields you
may have created.
ΓòÉΓòÉΓòÉ 6.4. Sample Program ΓòÉΓòÉΓòÉ
See the MLE/Radio Button program for sample calls to WinSetPresParam.
ΓòÉΓòÉΓòÉ 7. Task Manager ΓòÉΓòÉΓòÉ
This section covers the following topics -
Add Program Title to the Task List
Change Program Title in the Task List
Disable 'End Task' Button
Prevent Shutdown
Query Program Title in the Task List
SWL_GRAYED
SWL_NONJUMPABLE
Sample Program
ΓòÉΓòÉΓòÉ 7.1. Add Program Title to the Task List ΓòÉΓòÉΓòÉ
If you use the window style FCF_STANDARD, then your program's name will appear
in the task list, and your title bar, concatenated with any text you may have
defined for your application's title bar. For example, if your program was
called 'XYZ.EXE' and its title was 'Test Program', then in the task list it
would appear as 'XYZ.EXETest Program'.
To overcome this do not use the style FCF_TASKLIST, which is included in
FCF_STANDARD, but manually add it using WinAddSwitchEntry.
On exit from the program's message loop use WinRemoveSwitchEntry to remove the
entry. Ensure that you declare hwndEntry as static otherwise you will have an
invalid handle. Alternatively, use WinQuerySwitchHandle to get the switch list
handle first.
ΓòÉΓòÉΓòÉ 7.2. Change Program Title in the Task List ΓòÉΓòÉΓòÉ
To change the title of your application in the task list use
WinChangeSwitchEntry.
Alternatively, for an easier method use WinSetTitle, but beware, this is
undocumented and so should be used with caution.
ΓòÉΓòÉΓòÉ 7.3. Disable 'End Task' Button ΓòÉΓòÉΓòÉ
WARNING - Undocumented, use with caution.
If you have a requirement to disable the End Task button on the task list then
use WinNoShutdown.
See also Prevent Shutdown.
ΓòÉΓòÉΓòÉ 7.4. Prevent Shutdown ΓòÉΓòÉΓòÉ
When the 'End Task' button on the task list is pressed an application receives
a WM_QUIT message causing the message loop to end, thus closing the program.
However, in this case mp1 contains the frame handle, in all other cases it is
NULL. It is therefore possible to use this fact to either ignore shutdown
completely, or to put up a message box asking confirmation of closure. This
also applies to the Close option on the system menu. To implement this put your
message loop in a separate loop and on exit from the message loop test mp1, if
not NULL then cancel shutdown.
ΓòÉΓòÉΓòÉ 7.5. Query Program Title in the Task List ΓòÉΓòÉΓòÉ
In order to query the task list for an application use WinQuerySwitchHandle to
get the switch list handle followed by WinQuerySwitchEntry.
ΓòÉΓòÉΓòÉ 7.6. Task List Options ΓòÉΓòÉΓòÉ
ΓòÉΓòÉΓòÉ 7.6.1. SWL_GRAYED ΓòÉΓòÉΓòÉ
Use this value for PgmEntry.uchVisibility when adding your program to the Task
List to prohibit switching to it from the Task List.
ΓòÉΓòÉΓòÉ 7.6.2. SWL_NONJUMPABLE ΓòÉΓòÉΓòÉ
Use this value for PgmEntry.fbJump when adding your program to the Task List to
prohibit switching to it using the Alt_Esc key sequence.
ΓòÉΓòÉΓòÉ 7.7. Sample Program - Menus and Task Manager ΓòÉΓòÉΓòÉ
This sample program was written to confirm the hints and tips given in the
Menus and Task Manager sections and shows the following -
Starting in background
Adding/removing from the task list
Changing the task list
Querying the task list
Disable 'End Task' button in the task list
Disable 'Close' and 'Switch to...' in the system menu
Delete 'Size' and 'Move' from the system menu
Prohibiting exit from the task list and system menu
Adding an 'About...' option to the system menu
Disable all menu items
Make application system modal
Toggle menu item checked/unchecked
Force dismissal of MIA_NODISMISS menu
Delete 'Close' and its separator from the system menu
Changing menus
Initially, 'Close' and 'Switch to...' in the system menu and 'End Task' in
the task list are greyed out and the action bar is disabled. Pressing button
1 enables the action bar, 'Close' and 'End Task' but doesn't allow closure
from these options. Exit is via the action bar only. The title is also changed
in the task list. Pressing button 2 removes 'Close' from the system menu.
Pressing 'Switch Menus' causes a different menu to be loaded which has two
options with two items under 'Option 1'. The first is 'checkable' and and the
second is 'NODISMISS', until button 1 is clicked.
HINTS.C - C source file
HINTS.H - Header file
HINTS.L - Link control file
HINTS.DEF - Module definition file
HINTS.RC - Resource file
HINTS - Make file
Run program (Launch doesn't work in 1.3 yet!)
ΓòÉΓòÉΓòÉ 8. Windows ΓòÉΓòÉΓòÉ
This section covers the following topics -
Active
Errors
Modality
Movement
Parent
Position
Saving State
Size
Subclassing
Title
Sample Program
ΓòÉΓòÉΓòÉ 8.1. Active ΓòÉΓòÉΓòÉ
ΓòÉΓòÉΓòÉ 8.1.1. Active Window and its Process ID ΓòÉΓòÉΓòÉ
To determine the active window and get its process ID, first call
WinQueryActiveWindow which returns the handle of the active window, and then
call WinQueryWindowProcess to get the process ID of that window. For a VIO
window or full screen icon this will be the process ID of the shell.
The sample code gets the active window's process ID and displays it.
ΓòÉΓòÉΓòÉ 8.2. Errors ΓòÉΓòÉΓòÉ
ΓòÉΓòÉΓòÉ 8.2.1. Don't Use hwndFrame During WM_CREATE ΓòÉΓòÉΓòÉ
Don't use hwndFrame during WM_CREATE as it is not assigned until WM_CREATE
processing is complete. Instead, use WinQueryWindow to get the client's parent,
i.e. the frame handle.
ΓòÉΓòÉΓòÉ 8.2.2. Window Not Being Displayed ΓòÉΓòÉΓòÉ
Sometimes when you attempt to create a window it does not display and the
return code from WinCreateStdWindow is NULL. The most common cause of this
problem is the fact that you have used the frame creation flag of FCF_STANDARD
which includes a menu, icon and accelerator resource. If you have not defined
one of these then your window does not get created.
You should also check that all resources belonging to a frame have the same
ID, so check your RC file to ensure, for example, that your menu does not have
a different ID to your icon, else the create will fail. See the RC file
extract.
One other area to look at is your WM_CREATE message. If you return TRUE from
this then window creation is discontinued.
If, however, the create does not fail, i.e. you receive a valid handle, then
the most likely cause is that you do not have the WS_VISIBLE style specified
for the window. The default is, in fact, NOT visible. It is also possible
that if you are not using WinSetWindowPos you may have omitted the frame
creation flag FCF_SHELLPOSITION for the window.
ΓòÉΓòÉΓòÉ 8.3. Modality ΓòÉΓòÉΓòÉ
ΓòÉΓòÉΓòÉ 8.3.1. System Modal Window ΓòÉΓòÉΓòÉ
A simple way to trap Alt-Esc and Ctrl-Esc is to make your window system modal,
i.e. the user can only interact with your application. This renders the hot
keys unusable until you remove system modality for that window. To do this use
WinSetSysModalWindow in your WM_CREATE statement. Don't forget that you
cannot use hwndFrame at this point.
ΓòÉΓòÉΓòÉ 8.4. Movement ΓòÉΓòÉΓòÉ
ΓòÉΓòÉΓòÉ 8.4.1. Prohibiting Window Movement ΓòÉΓòÉΓòÉ
There may be occasions when it is required to prohibit the movement of your
main window during the course of your normal processing. This could be
achieved by subclassing the frame window, but an easier way of doing it is to
call WinEnableWindow. This also greys out Move from the window's system menu.
To prohibit movement
To restore movement
ΓòÉΓòÉΓòÉ 8.5. Parent ΓòÉΓòÉΓòÉ
ΓòÉΓòÉΓòÉ 8.5.1. Parent Window ΓòÉΓòÉΓòÉ
To find a window's parent, for example, your client window's parent, i.e. frame
window, call WinQueryWindow.
ΓòÉΓòÉΓòÉ 8.6. Position ΓòÉΓòÉΓòÉ
ΓòÉΓòÉΓòÉ 8.6.1. Centralising your Window ΓòÉΓòÉΓòÉ
To centralise your window use WinQuerySysValue to get the screen resolution,
calculate the appropriate co-ordinates and call WinSetWindowPos. However, be
aware of the prerequisites for starting with a predetermined size.
ΓòÉΓòÉΓòÉ 8.6.2. Keeping your Child Window on Top ΓòÉΓòÉΓòÉ
If you have a requirement to keep your child window visible whilst you use your
main window, maybe in order to keep your application's status in view or for a
tool palette, then make the child window's parent HWND_DESKTOP, and then use
WinSetOwner to make the child's owner the application's main window.
ΓòÉΓòÉΓòÉ 8.6.3. Keeping your Main Window on Top ΓòÉΓòÉΓòÉ
Sometimes it may be necessary to keep your window in view at all times, i.e. on
top of all other windows. A very simple way of doing this is to start a timer
and in your WM_TIMER message processing for your client window make a call to
WinSetWindowPos using the SWP_ZORDER option.
Use WinStopTimer to stop the timer when you close down your application, or
before if it is no longer required.
ΓòÉΓòÉΓòÉ 8.6.4. Positioning on Screens with Different Resolution ΓòÉΓòÉΓòÉ
If you use absolute values when initialising the size of your window and then
run your application on a machine which has a screen of different resolution,
you may find that your window overlaps the screen, or appears in an otherwise
unexpected position. To overcome this you should not use absolute values but
ask the system for the screen dimensions first by using WinQuerySysValue. This
will give you back the correct number of pels for the screen you are running
under. You can then use these values in WinSetWindowPos to set your window's
size and position correctly.
As an example, if you wanted your window to occupy the entire screen use the
sample code, but make sure you include a frame creation flag of FCF_NOBYTEALIGN
when you create your window otherwise it will align on eight pel boundaries and
not fit the screen exactly. If you do not wish your window to be this large
then of course you can set the ScrWidth and ScrHeight variables to any suitable
values and, if necessary centralise it.
ΓòÉΓòÉΓòÉ 8.6.5. Restoring to a Fixed Size or Position ΓòÉΓòÉΓòÉ
If you always want your window to be set to a particular size and/or position
when it is restored then you can use the WinSetWindowUShort function with the
relevant QWS_*RESTORE value(s) in your WM_MINMAXFRAME case statement.
o QWS_XRESTORE - The X coordinate of the position to which the window is
restored
o QWS_YRESTORE - The Y coordinate of the position to which the window is
restored
o QWS_CXRESTORE - The width to which the window is restored
o QWS_CYRESTORE - The height to which the window is restored
ΓòÉΓòÉΓòÉ 8.6.6. Starting in the Background ΓòÉΓòÉΓòÉ
To start with your window in the background so that it doesn't take the focus
away from you use WinSetWindowPos with Behind set to HWND_BOTTOM and SWP_ZORDER
as one of the options.
ΓòÉΓòÉΓòÉ 8.6.7. Starting with a Predetermined Window Size and Position ΓòÉΓòÉΓòÉ
If you do not wish your window size and position to be set by Presentation
Manager then in your WinCreateStdWindow call do not specify the style
WS_VISIBLE, and do not specify the frame creation flag FCF_SHELLPOSITION.
Instead, follow your WinCreateStdWindow call with a call to WinSetWindowPos.
Ensure that you always use SWP_SIZE | SWP_MOVE on the WinSetWindowPos call
otherwise your size and start position will not be honoured. Also, use
SWP_ACTIVATE to give your window the focus.
Note: A common mistake in this area is to use FCF_SHELLPOSITION, which is
included with FCF_STANDARD, and trap the WM_CREATE message with the aim
of resizing the window. But, Presentation Manager acts on the
FCF_SHELLPOSITION after the WM_CREATE message and so your size and
position is overwritten.
ΓòÉΓòÉΓòÉ 8.7. Saving State ΓòÉΓòÉΓòÉ
ΓòÉΓòÉΓòÉ 8.7.1. Saving your Application's Current State ΓòÉΓòÉΓòÉ
If you have a requirement to save your application's current state of execution
then you can make use of the WM_SAVEAPPLICATION message. This message gets
dispatched to your client window procedure when the user requests Save... from
the Desktop Manager. You may want to save several different types of data but
probably the most common is the window's size and position on the desktop.
The sample code shows how to save the application's size and position in
OS2.INI and restore next time it starts.
ΓòÉΓòÉΓòÉ 8.8. Size ΓòÉΓòÉΓòÉ
ΓòÉΓòÉΓòÉ 8.8.1. Controlling Window Size ΓòÉΓòÉΓòÉ
Presentation Manager will not allow the user to size a window smaller than
about 3.5 centimetres wide (using 8514/A). If you have a requirement to do
this then you must subclass the frame of the standard window and process the
WM_QUERYTRACKINFO message.
You can, of course, extend this to ensure that your window is always square, or
never smaller or greater than a certain size.
ΓòÉΓòÉΓòÉ 8.8.2. Detecting Minimize/Maximize ΓòÉΓòÉΓòÉ
To check if your window is about to be minimized or maximized then trap your
WM_MINMAXFRAME message.
ΓòÉΓòÉΓòÉ 8.8.3. Minimizing your Window ΓòÉΓòÉΓòÉ
If you need to minimize your window automatically from your client's window
procedure call WinSetWindowPos.
ΓòÉΓòÉΓòÉ 8.8.4. Obtaining Window Size ΓòÉΓòÉΓòÉ
To obtain the size of a window use the WinQueryWindowRect function. For
top-level windows this will return the values in screen coordinates. For child
windows the coordinates will be in parent coordinates. If you need to query
the screen coordinates of child windows, which your client area is (child of
FRAME), follow the WinQueryWindowRect call with a call to WinMapWindowPoints.
ΓòÉΓòÉΓòÉ 8.8.5. Prohibiting Window Minimization/Maximization ΓòÉΓòÉΓòÉ
To prevent the user from minimizing or maximizing your window, assuming you
have FCF_MINMAX defined for the window, use WinEnableWindow with FALSE. To
allow it again use TRUE.
ΓòÉΓòÉΓòÉ 8.8.6. Prohibiting Window Sizing ΓòÉΓòÉΓòÉ
There may be occasions when it is required to prohibit the sizing of your main
window during the course of your normal processing. This can be achieved by
changing the window's style from FS_SIZEBORDER to FS_DLGBORDER using
WinSetWindowULong. This also greys out Size from the window's system menu.
Another way of doing this is to use WinSetWindowBits.
You will also need a call to WinInvalidateRect to ensure the frame is updated
immediately.
To prohibit sizing using WinSetWindowULong
To restore sizing using WinSetWindowULong
To prohibit sizing using WinSetWindowBits
To restore sizing using WinSetWindowBits
ΓòÉΓòÉΓòÉ 8.8.7. Restoring to a Fixed Size or Position ΓòÉΓòÉΓòÉ
If you always want your window to be set to a particular size and/or position
when it is restored then you can use the WinSetWindowUShort function with the
relevant QWS_*RESTORE value(s) in your WM_MINMAXFRAME case statement.
o QWS_XRESTORE - The X coordinate of the position to which the window is
restored
o QWS_YRESTORE - The Y coordinate of the position to which the window is
restored
o QWS_CXRESTORE - The width to which the window is restored
o QWS_CYRESTORE - The height to which the window is restored
ΓòÉΓòÉΓòÉ 8.8.8. Starting Minimized or Maximized ΓòÉΓòÉΓòÉ
To create a window in its minimized or maximized state use SWP_MINIMIZE or
SWP_MAXIMIZE respectively in your WinSetWindowPos call.
ΓòÉΓòÉΓòÉ 8.8.9. Starting with a Predetermined Window Size and Position ΓòÉΓòÉΓòÉ
If you do not wish your window size and position to be set by Presentation
Manager then in your WinCreateStdWindow call do not specify the style
WS_VISIBLE, and do not specify the frame creation flag FCF_SHELLPOSITION.
Instead, follow your WinCreateStdWindow call with a call to WinSetWindowPos.
Ensure that you always use SWP_SIZE | SWP_MOVE on the WinSetWindowPos call
otherwise your size and start position will not be honoured. Also, use
SWP_ACTIVATE to give your window the focus.
Note: A common mistake in this area is to use FCF_SHELLPOSITION, which is
included with FCF_STANDARD, and trap the WM_CREATE message with the aim
of resizing the window. But, Presentation Manager acts on the
FCF_SHELLPOSITION after the WM_CREATE message and so your size and
position is overwritten.
ΓòÉΓòÉΓòÉ 8.9. Subclassing ΓòÉΓòÉΓòÉ
For examples of subclassing see -
Controlling Window Size
Numeric Data Only
ΓòÉΓòÉΓòÉ 8.10. Title ΓòÉΓòÉΓòÉ
ΓòÉΓòÉΓòÉ 8.10.1. Changing the Window Title ΓòÉΓòÉΓòÉ
To change the window title use WinSetWindowText.
ΓòÉΓòÉΓòÉ 8.10.2. EXE Name Appearing in Title Bar ΓòÉΓòÉΓòÉ
This happens because you have specified FCF_TASKLIST for your window. See
Adding Program Title to the Task List.
ΓòÉΓòÉΓòÉ 8.11. Sample Programs ΓòÉΓòÉΓòÉ
ΓòÉΓòÉΓòÉ 8.11.1. Skeleton Program ΓòÉΓòÉΓòÉ
This skeleton program builds a small sizable client window and centralises it
on the desktop. It contains an action bar with an Exit option, minimize,
maximize and the system menu. I have used this as the base for all the other
sample programs.
HINTS.C - C source file
HINTS.H - Header file
HINTS.L - Link control file
HINTS.DEF - Module definition file
HINTS.RC - Resource file
HINTS - Make file
Run program (Launch doesn't work in 1.3 yet!)
ΓòÉΓòÉΓòÉ 8.11.2. Sample Program - Windows ΓòÉΓòÉΓòÉ
The sample program does not have any real function but was written just to test
that all the tips in this section do work. However, as it currently stands it
does not incorporate all the tips as some are obviously mutually exclusive.
Having said that though, it does open the main client window at the restored
position and the child window to its right. The main window displays the
process ID of the active window and the child window just displays a text
string.
If you press button 1 in the main window it becomes fixed, i.e. you cannot move
or size it, the minimize and maximize buttons are disabled and the title text
is changed. Pressing button 2 returns it to its moveable state.
HINTS.C - C source file
HINTS.H - Header file
HINTS.L - Link control file
HINTS.DEF - Module definition file
HINTS.RC - Resource file
HINTS - Make file
Run program (Launch doesn't work in 1.3 yet!)
ΓòÉΓòÉΓòÉ 9. Sample Programs ΓòÉΓòÉΓòÉ
The following programs were written purely to verify all the tips given in this
volume. The programs themselves do not have any function other than to perform
this verification, usually by pressing a mouse button or push button.
Skeleton Program
General Window Processing
General Dialog Box Processing
MLE and Radio Buttons
Listboxes
Menus and Task Manager
Mouse and Pointer Control
Presentation Parameters
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
CONTROL "", ID_ENTRY2, 67, 57, 36, 8, WC_ENTRYFIELD, ES_LEFT |
ES_MARGIN | WS_TABSTOP | WS_VISIBLE
CTLDATA 8, 5, 0, 0
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
/*---------------------------*/
/* Change focus to ID_ENTRY2 */
/*---------------------------*/
WinSetFocus(HWND_DESKTOP, WinWindowFromID(hwndDlg, ID_ENTRY2));
/*------------------------------------------------*/
/* Position cursor between 1st and 2nd characters */
/*------------------------------------------------*/
WinSendMsg(WinWindowFromID(hwndDlg, ID_ENTRY2), EM_SETSEL,
MPFROM2SHORT(1, 1), 0L);
/*------------------------------------------------*/
/* Position cursor between 1st and 2nd characters */
/* but mark 2nd and 3rd characters only */
/*------------------------------------------------*/
WinSendMsg(WinWindowFromID(hwndDlg, ID_ENTRY2), EM_SETSEL,
MPFROM2SHORT(1, 3), 0L);
/*---------------------------------------------------------*/
/* Position cursor at start of field but mark entire field */
/*---------------------------------------------------------*/
WinSendMsg(WinWindowFromID(hwndDlg, ID_ENTRY2), EM_SETSEL,
MPFROM2SHORT(0, 5), 0L);
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
CONTROL "", ID_PASSWORD, 77, 37, 45, 8, WC_ENTRYFIELD, ES_LEFT |
ES_UNREADABLE | ES_MARGIN | WS_TABSTOP | WS_VISIBLE
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
/*-----------------------------------------------*/
/* This code sets the password length to 8 bytes */
/*-----------------------------------------------*/
WinSendMsg(WinWindowFromID(hwndDlg, ID_PASSWORD),
EM_SETTEXTLIMIT,
MRFROMSHORT(8),
NULL);
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
/*---------------------------------------------*/
/* First define your numeric procedure and a */
/* pointer to the public entry field procedure */
/*---------------------------------------------*/
typedef struct _CHARMSG *PCHARMSG; // Not defined in PMWIN.H
MRESULT EXPENTRY NumericProc( HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2);
PFNWP EntryFieldProc; // Public Entry Field procedure
/*---------------------------------------------*/
/* In your WM_INITDLG case statement save the */
/* address of the public entry field procedure */
/*---------------------------------------------*/
case WM_INITDLG:
EntryFieldProc = WinSubclassWindow(WinWindowFromID(hwndDlg, ID_ENTRY2),
NumericProc);
/*----------------------------------------------*/
/* The following is the actual window procedure */
/*----------------------------------------------*/
MRESULT EXPENTRY NumericProc( HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2 )
{
PCHARMSG p;
if (msg == WM_CHAR) // If this is a char msg
{
p = CHARMSG(&msg); // Address char structure
if ((p->fs & (KC_KEYUP|KC_CHAR)) == KC_CHAR) // ONLY key down transitions */
{
if ((p->chr < 0x30 || p->chr > 0x39) && // Not numeric
(p->chr != 8) && // Not backspace
(p->chr != 9) && // Not tab
(p->chr != 0x2D) && // Not -
(p->chr != 13)) // Not enter
{
WinAlarm(HWND_DESKTOP, WA_WARNING);
return (MRESULT)TRUE;
}
}
}
// Call public entry field procedure
return ((*EntryFieldProc)(hwnd, msg, mp1, mp2));
}
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
/*----------------------------------*/
/* Get password and store in szPswd */
/*----------------------------------*/
WinQueryWindowText(WinWindowFromID(hwndDlg, ID_PASSWORD),
sizeof(szPswd), szPswd);
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
/*----------------------------------*/
/* Get password and store in szPswd */
/*----------------------------------*/
WinQueryDlgItemText(hwndDlg, ID_PASSWORD,
sizeof(szPswd), szPswd);
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
/*----------------------------------*/
/* Get window ID and store in id */
/* FALSE for unsigned value */
/* TRUE for possible signed value */
/*----------------------------------*/
WinQueryDlgItemShort(hwndDlg, ID_ENTRY1, &id, FALSE);
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
WinSendMsg(WinWindowFromID(hwndDlg, ID_ENTRY1),
EM_SETREADONLY,
(MPARAM)TRUE,
NULL);
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
CONTROL "", ID_ENTRY1, 77, 25, 100, 16, WC_ENTRYFIELD, ES_CENTER |
ES_AUTOSCROLL | ES_MARGIN | ES_READONLY | WS_VISIBLE
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
WinSetWindowText(WinWindowFromID(hwndDlg, ID_ENTRY1), "Text");
/*---------------------------------------------------*/
/* To clear an entry field write a null string to it */
/*---------------------------------------------------*/
WinSetWindowText(WinWindowFromID(hwndDlg, ID_ENTRY1), "");
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
WinSetDlgItemText(hwndDlg, ID_ENTRY1, "Text");
/*---------------------------------------------------*/
/* To clear an entry field write a null string to it */
/*---------------------------------------------------*/
WinSetDlgItemText(hwndDlg, ID_ENTRY1, "");
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
WinSetDlgItemShort(hwndDlg, ID_ENTRY1, id, FALSE);
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
CHAR *Country,
*Capital;
case WM_CONTROL:
switch(SHORT1FROMMP(mp1))
{
case ID_OLISTBOX:
switch(SHORT2FROMMP(mp1))
{
case LN_SELECT:
Oidx = (SHORT)WinSendDlgItemMsg(hwndDlg, ID_OLISTBOX,
LM_QUERYSELECTION, 0L, 0L);
WinSendDlgItemMsg(hwndDlg, ID_OLISTBOX, LM_QUERYITEMTEXT,
MPFROM2SHORT(Oidx, sizeof(szListBuff)),
MPFROMP(szListBuff));
Country = strtok(szListBuff, "\t");
Capital = strtok(NULL, "\t");
WinSetDlgItemText(hwndDlg, ID_ENTRY1, Capital);
WinSetDlgItemText(hwndDlg, ID_ENTRY2, "");
WinSetDlgItemText(hwndDlg, ID_ENTRY3, Country);
break;
default:
break;
}
break;
}
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
hwndList = WinWindowFromID(hwndDlg, ID_SLISTBOX);
WinDestroyWindow(WinWindowFromID(hwndList, 0xC001));
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
case WM_MEASUREITEM:
if (first)
{
strcpy(font, "24.Helv");
WinSetPresParam(WinWindowFromID(hwndDlg, ID_OLISTBOX),
PP_FONTNAMESIZE, (ULONG)sizeof(font), font);
first = FALSE;
}
hps = WinGetPS(WinWindowFromID(hwndDlg, ID_OLISTBOX));
;
;
;
WinReleasePS(hps);
return MRFROM2SHORT(cyText, cxText);
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
pDB_Data = (PDBDATA)WinSendDlgItemMsg(hwndDlg, ID_SLISTBOX,
LM_QUERYITEMHANDLE,
MPFROMSHORT(Idx), NULL);
DosFreeSeg(SELECTOROF(pDB_Data));
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
/*----------------------------------------------------------*/
/* By default the start position for drawing in the item */
/* rectangle is 1 so if we have been scrolled then xLeft on */
/* input will be some other value depending on how much we */
/* have been scrolled. All we need to do to allow scrolling */
/* is adjust xLeft by the scrolled amount. */
/*----------------------------------------------------------*/
if (pOwner->rclItem.xLeft != 1)
rc.xLeft = rc.xRight + pOwner->rclItem.xLeft - 1;
else
rc.xLeft = rc.xRight;
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
ULONG KeyValue;
/*------------------------------------------------*/
/* If all we want to do is store the key value... */
/*------------------------------------------------*/
for (Idx = 0; Idx < 26; Idx++)
{
WinSendDlgItemMsg(hwndDlg, ID_SLISTBOX, LM_INSERTITEM,
MPFROMSHORT(LIT_END),
MPFROMP(szCountry[Idx]));
/*----------------------------------------*/
/* szCountry and KeyValue would normally */
KeyValue = Idx + 1; /* be obtained from a database. */
/* In this case give a key value of 1->26 */
/*----------------------------------------*/
WinSendDlgItemMsg(hwndDlg, ID_SLISTBOX, LM_SETITEMHANDLE,
(MPARAM)Idx, (MPARAM)KeyValue);
}
/*------------------------------------------------*/
/* If we need to save a pointer to a structure... */
/*------------------------------------------------*/
SEL sel;
typedef struct _DBDATA
{
USHORT Key;
CHAR Capital[20];
} DBDATA, FAR *PDBDATA;
PDBDATA pDB_Data;
for (Idx = 0; Idx < 26; Idx++)
{
WinSendDlgItemMsg(hwndDlg, ID_SLISTBOX, LM_INSERTITEM,
MPFROMSHORT(LIT_END),
MPFROMP(szCountry[Idx]));
DosAllocSeg(22, &sel, 0);
pDB_Data = MAKEP(sel, 0);
pDB_Data->Key = Idx + 1;
strcpy(pDB_Data->Capital, szCapital[Idx]);
WinSendDlgItemMsg(hwndDlg, ID_SLISTBOX, LM_SETITEMHANDLE,
(MPARAM)Idx, MPFROMP(pDB_Data));
}
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
/*--------------------------------------------*/
/* If we are just retrieving the key value... */
/*--------------------------------------------*/
case LN_SELECT:
Idx = (SHORT)WinSendDlgItemMsg(hwndDlg, ID_SLISTBOX,
LM_QUERYSELECTION, 0L, 0L);
/*---------------------------------*/
if (Idx != LIT_NONE) /* If nothing selected then ignore */
{ /*---------------------------------*/
KeyValue = (ULONG)WinSendDlgItemMsg(hwndDlg, ID_SLISTBOX,
LM_QUERYITEMHANDLE,
MPFROMSHORT(Idx), NULL);
WinSetDlgItemShort(hwndDlg, ID_ENTRY2, (SHORT)KeyValue, FALSE);
;
;
;
}
break;
/*--------------------------------------------------------------*/
/* Or, to retrieve all data associated with the listbox item... */
/*--------------------------------------------------------------*/
case LN_SELECT:
Idx = (SHORT)WinSendDlgItemMsg(hwndDlg, ID_SLISTBOX,
LM_QUERYSELECTION, 0L, 0L);
/*---------------------------------*/
if (Idx != LIT_NONE) /* If nothing selected then ignore */
{ /*---------------------------------*/
pDB_Data = (PDBDATA)WinSendDlgItemMsg(hwndDlg, ID_SLISTBOX,
LM_QUERYITEMHANDLE,
MPFROMSHORT(Idx), NULL);
WinSetDlgItemText(hwndDlg, ID_ENTRY1, pDB_Data->Capital);
WinSetDlgItemShort(hwndDlg, ID_ENTRY2, (SHORT)pDB_Data->Key, FALSE);
;
;
;
}
break;
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
SHORT Idx;
/*----------------------*/
/* Delete selected item */
/*----------------------*/
WinSendDlgItemMsg(hwndDlg, ID_SLISTBOX, LM_DELETEITEM,
MPFROMSHORT(Idx), NULL);
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
/*------------------*/
/* Delete all items */
/*------------------*/
WinSendDlgItemMsg(hwndDlg, ID_SLISTBOX, LM_DELETEALL, NULL, NULL);
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
/*------------------*/
/* Deselect an item */
/*------------------*/
WinSendDlgItemMsg(hwndDlg, ID_SLISTBOX, LM_SELECTITEM,
MPFROMSHORT(Idx), (MPARAM)FALSE);
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
SHORT Idx;
static PSZ szCountry[] = {"Austria", "Belgium", "Canada",
"Denmark", "Egypt", "Finland",
"Greece", "Hungary", "India",
"Japan", "Kenya", "Libya",
"Morocco", "Nigeria", "Oman",
"Peru", "Qatar", "Romania",
"Spain", "Turkey", "Uruguay",
"Venezuela", "Wales", "Xanxere",
"Yemen", "Zambia"};
for (Idx = 0; Idx < 26; Idx++)
{
WinSendDlgItemMsg(hwndDlg, ID_SLISTBOX, LM_INSERTITEM,
MPFROMSHORT(LIT_END),
MPFROMP(szCountry[Idx]));
}
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
SHORT Midx;
case ID_PROCMULT:
Midx = (SHORT)WinSendDlgItemMsg(hwndDlg, ID_MLISTBOX, //Get first
LM_QUERYSELECTION,
(MPARAM)LIT_FIRST, 0L);
while(Midx != LIT_NONE)
{
WinSendDlgItemMsg(hwndDlg, ID_MLISTBOX, LM_QUERYITEMTEXT, // Get its text
MPFROM2SHORT(Midx, sizeof(szCtry)),
MPFROMP(szCtry));
WinSetDlgItemText(hwndDlg, ID_ENTRY3, szCtry); // Display it
WinSendDlgItemMsg(hwndDlg, ID_MLISTBOX, LM_SELECTITEM, // Deselect it
MPFROMSHORT(Midx), (MPARAM)FALSE);
/*----------------------------------*/
/* Slow down so we can see it happen*/
/* */
DosSleep(1000L); /* DON'T DO THIS IN PM PROGRAMS */
/* AFFECTS PERFORMANCE SEVERELY */
/*----------------------------------*/
Midx = (SHORT)WinSendDlgItemMsg(hwndDlg, ID_MLISTBOX, // Get next
LM_QUERYSELECTION,
(MPARAM)Midx, 0L);
}
WinSetDlgItemText(hwndDlg, ID_ENTRY3, "Done"); // All done
return FALSE;
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
/*-------------------*/
/* Select first item */
/*-------------------*/
WinSendDlgItemMsg(hwndDlg, ID_SLISTBOX, LM_SELECTITEM,
MPFROMSHORT(0), (MPARAM)TRUE);
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
SHORT Idx;
CHAR szCtry[10];
case WM_CONTROL:
switch(SHORT1FROMMP(mp1))
{
case ID_SLISTBOX:
switch(SHORT2FROMMP(mp1))
{
case LN_SELECT:
Idx = (SHORT)WinSendDlgItemMsg(hwndDlg, ID_SLISTBOX,
LM_QUERYSELECTION, 0L, 0L);
WinSendDlgItemMsg(hwndDlg, ID_SLISTBOX, LM_QUERYITEMTEXT,
MPFROM2SHORT(Idx, sizeof(szCtry)),
MPFROMP(szCtry));
;
;
;
break;
default:
break;
}
break;
}
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
case WM_DRAWITEM:
;
;
;
if ((!pOwner->fsState) || // Unselected
(pOwner->idItem == 5)) // Don't allow Finland
{
GpiSetBackColor(pOwner->hps, CLR_DARKGREEN);
GpiSetColor(pOwner->hps, CLR_YELLOW);
}
else // Selected
{
GpiSetBackColor(pOwner->hps, CLR_YELLOW);
GpiSetColor(pOwner->hps, CLR_DARKGREEN);
}
;
;
;
pOwner->fsStateOld = pOwner->fsState = 0; // Don't let PM hilite
return (MRESULT)TRUE; // Don't let PM draw
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
/*-----------------------------------------------------------------*/
/* The scroll bar ID for a listbox's vertical scroll bar is 0xC001 */
/* and for a horizontal scroll bar is 0xC002. */
/* This is, however, undocumented so use with caution. */
/*-----------------------------------------------------------------*/
hwndVbar = WinWindowFromID(hwndListbox, 0xC001);
hwndHbar = WinWindowFromID(hwndListbox, 0xC002);
/*-----------------------------------------------------------------*/
/* Alternatively, enumerate the listbox's windows. This way it */
/* doesn't matter if the scroll bar IDs change in a later release. */
/*-----------------------------------------------------------------*/
hwndListbox = WinWindowFromID(hwndDlg, ID_SLISTBOX);
hEnum = WinBeginEnumWindows(hwndListbox);
while (hwndChild = WinGetNextWindow(hEnum))
{ /*------------------------------*/
/* SBS_VERT = 1L, SBS_HORZ = 0L */
/*------------------------------*/
if (WinQueryWindowULong(hwndChild, QWL_STYLE) & SBS_VERT)
hwndVbar = hwndChild;
else
hwndHbar = hwndChild;
}
WinEndEnumWindows(hEnum);
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
CHAR *Country,
*Capital;
case WM_INITDLG:
;
;
for (Idx = 0; Idx < 26; Idx++)
{
strcpy(szListBuff, szCountry[Idx]);
strcat(szListBuff, "\t"); // Insert a TAB character
strcat(szListBuff, szCapital[Idx]);
WinSendDlgItemMsg(hwndDlg, ID_OLISTBOX, LM_INSERTITEM,
MPFROMSHORT(LIT_END),
MPFROMP(szListBuff));
}
;
;
break;
case WM_DRAWITEM:
pOwner = (POWNERITEM)mp2;
rc.xRight = pOwner->rclItem.xRight/2; // Split into two and draw
rc.xLeft = pOwner->rclItem.xLeft; // item in left rectangle
rc.yTop = pOwner->rclItem.yTop;
rc.yBottom = pOwner->rclItem.yBottom;
GpiSetBackMix(pOwner->hps, BM_OVERPAINT);
if (!pOwner->fsState) // Unselected
{
GpiSetBackColor(pOwner->hps, CLR_DARKGREEN);
GpiSetColor(pOwner->hps, CLR_YELLOW);
}
else // Selected
{
GpiSetBackColor(pOwner->hps, CLR_YELLOW);
GpiSetColor(pOwner->hps, CLR_DARKGREEN);
}
WinSendDlgItemMsg(hwndDlg, ID_OLISTBOX, LM_QUERYITEMTEXT,
MPFROM2SHORT(pOwner->idItem, sizeof(szListBuff)),
MPFROMP(szListBuff));
Country = strtok(szListBuff, "\t");
Capital = strtok(NULL, "\t");
WinDrawText(pOwner->hps, strlen(Country),
Country, &rc, 0L, 0L,
DT_LEFT | DT_TEXTATTRS | DT_ERASERECT);
rc.xLeft = rc.xRight; // Draw next item in right rectangle
rc.xRight = pOwner->rclItem.xRight;
WinDrawText(pOwner->hps, strlen(Capital),
Capital, &rc, 0L, 0L,
DT_LEFT | DT_TEXTATTRS | DT_ERASERECT);
;
;
;
break;
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
POINTL points[TXTBOX_COUNT];
case WM_MEASUREITEM:
;
;
;
WinSendDlgItemMsg(hwndDlg, ID_OLISTBOX, LM_QUERYITEMTEXT,
MPFROM2SHORT(Idx, sizeof(szListBuff)),
MPFROMP(szListBuff));
GpiQueryTextBox(hps, (LONG)strlen(szListBuff), szListBuff,
TXTBOX_COUNT, points);
/*-------------------------------------------------*/
/* May need to add on a bit to cxText to ensure */
/* the entire item can be read when fully scrolled */
/*-------------------------------------------------*/
cxText = (USHORT)points[TXTBOX_TOPRIGHT].x + 20;
;
;
;
return MRFROM2SHORT(cyText, cxText);
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
POWNERITEM pOwner;
RECTL rc;
case WM_DRAWITEM:
pOwner = (POWNERITEM)mp2;
rc.xRight = pOwner->rclItem.xRight;
rc.xLeft = pOwner->rclItem.xLeft;
rc.yTop = pOwner->rclItem.yTop;
rc.yBottom = pOwner->rclItem.yBottom;
GpiSetBackMix(pOwner->hps, BM_OVERPAINT);
if (!pOwner->fsState) // Unselected
{
GpiSetBackColor(pOwner->hps, CLR_DARKGREEN);
GpiSetColor(pOwner->hps, CLR_YELLOW);
}
else // Selected
{
GpiSetBackColor(pOwner->hps, CLR_YELLOW);
GpiSetColor(pOwner->hps, CLR_DARKGREEN);
}
WinSendDlgItemMsg(hwndDlg, ID_OLISTBOX, LM_QUERYITEMTEXT,
MPFROM2SHORT(pOwner->idItem, sizeof(szListBuff)),
MPFROMP(szListBuff));
WinDrawText(pOwner->hps, strlen(szListBuff),
szListBuff, &rc, 0L, 0L,
DT_CENTER | DT_TEXTATTRS | DT_ERASERECT);
pOwner->fsStateOld = pOwner->fsState = 0; // Don't let PM hilite
return (MRESULT)TRUE; // Don't let PM draw
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
HPS hps;
FONTMETRICS fm;
SHORT cxText,
cyText;
case WM_MEASUREITEM:
hps = WinGetPS(WinWindowFromID(hwndDlg, ID_OLISTBOX));
GpiQueryFontMetrics(hps, (LONG)sizeof(FONTMETRICS), &fm);
cyText = (SHORT)fm.lMaxBaselineExt;
cxText = 0;
WinReleasePS(hps);
return MRFROM2SHORT(cyText, cxText);
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
WinSetDlgItemText(hwndDlg, ID_MULTILINE, "");
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
WinSetWindowText(WinWindowFromID(hwndDlg, ID_MULTILINE), "");
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
DosAllocSeg(0, &Selector, SEG_GETTABLE); // Allocate 64K segment
Buffer = MAKEP(Selector, 0); // Get pointer to segment
DosOpen("C:\\CONFIG.SYS", &hFile, &Action,
(ULONG)NULL,
(USHORT)NULL,
OPEN_ACTION_OPEN_IF_EXISTS,
OPEN_FLAGS_SEQUENTIAL |
OPEN_SHARE_DENYNONE |
OPEN_ACCESS_READONLY,
(ULONG)NULL);
DosRead(hFile, Buffer, 65535L, &BytesRead);
DosClose(hFile);
WinSendMsg(WinWindowFromID(hwndDlg, ID_MULTILINE),
MLM_SETIMPORTEXPORT, (MPARAM)Buffer,
MPFROMLONG(65535L));
ipt = -1; // Set insertion point for current cursor position
WinSendMsg(WinWindowFromID(hwndDlg, ID_MULTILINE),
MLM_IMPORT, (MPARAM)&ipt,
MPFROMLONG((LONG)BytesRead));
DosFreeSeg(Selector);
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
CHAR font[11];
/*-------------------------*/
/* To set 12 point Courier */
/*-------------------------*/
strcpy(font, "12.Courier");
WinSetPresParam(WinWindowFromID(hwndDlg, ID_MULTILINE),
PP_FONTNAMESIZE, (ULONG)sizeof(font), font);
/*--------------------------*/
/* To set 8 point Helvetica */
/*--------------------------*/
strcpy(font, "8.Helv");
WinSetPresParam(WinWindowFromID(hwndDlg, ID_MULTILINE),
PP_FONTNAMESIZE, (ULONG)sizeof(font), font);
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
BITMAP ID_LOCK lock.bmp
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
/*-------------------------------*/
/* Define button paint procedure */
/*-------------------------------*/
VOID Button_Paint(HWND, HPS, USHORT);
/*------------------------------------*/
/* Define pointer to button structure */
/*------------------------------------*/
USERBUTTON *ubtn;
/*-----------------------------*/
/* Handle the BN_PAINT message */
/*-----------------------------*/
case WM_CONTROL:
switch(HIUSHORT(mp1))
{
case BN_PAINT:
switch(LOUSHORT(mp1)) /* Which Button? */
{
case ID_USERBUTTON:
ubtn = (USERBUTTON *)mp2;
Button_Paint(ubtn->hwnd, ubtn->hps, ubtn->fsState);
return (MRESULT)TRUE;
default:
break;
}
}
break;
/*------------------------*/
/* Handle the button push */
/*------------------------*/
case WM_COMMAND:
switch(SHORT1FROMMP(mp1))
{
;
;
;
case ID_USERBUTTON:
DosBeep(500, 100);
return FALSE;
;
;
;
/*------------------------*/
/* Button paint procedure */
/*------------------------*/
VOID Button_Paint(HWND hwnd, HPS hps, USHORT Status)
{
RECTL DestPt;
HBITMAP hbm;
/*------------------------------------------------------------------------*/
/* Display the disk drive bitmap */
/* */
/* hbm = WinGetSysBitmap(HWND_DESKTOP, SBMP_DRIVE); */
/* WinQueryWindowRect(hwnd, &DestPt); */
/* WinDrawBitmap(hps, hbm, NULL, (PPOINTL)&DestPt, CLR_YELLOW, CLR_BLACK, */
/* (Status ? DBM_INVERT : DBM_NORMAL) | DBM_STRETCH); */
/*------------------------------------------------------------------------*/
/*---------------------------------*/
/* Load and display our own bitmap */
/*---------------------------------*/
hbm = GpiLoadBitmap(hps, NULL, ID_LOCK, 0L, 0L);
WinQueryWindowRect(hwnd, &DestPt);
WinDrawBitmap(hps, hbm, NULL, (PPOINTL)&DestPt, 0L, 0L,
(Status ? DBM_INVERT : DBM_NORMAL) | DBM_STRETCH);
}
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
ULONG lStyle;
lStyle = WinQueryWindowULong(WinWindowFromID(hwndDlg, ID_OK), QWL_STYLE);
if (lStyle & BS_DEFAULT)
{
/*-----------------------*/
/* Button is the default */
/*-----------------------*/
}
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
/*----------------------*/
/* Remove default style */
/*----------------------*/
WinSendMsg(WinWindowFromID(hwndDlg, ID_OK), BM_SETDEFAULT,
(MPARAM)FALSE, NULL);
/*-------------------*/
/* Set default style */
/*-------------------*/
WinSendMsg(WinWindowFromID(hwndDlg, ID_OK), BM_SETDEFAULT,
(MPARAM)TRUE, NULL);
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
/*----------------------*/
/* Remove default style */
/*----------------------*/
WinSetWindowBits(WinWindowFromID(hwndDlg, ID_OK), QWL_STYLE,
0L, BS_DEFAULT);
WinInvalidateRect(WinWindowFromID(hwndDlg, ID_OK), NULL, FALSE);
/*-------------------*/
/* Set default style */
/*-------------------*/
WinSetWindowBits(WinWindowFromID(hwndDlg, ID_OK), QWL_STYLE,
BS_DEFAULT, BS_DEFAULT);
WinInvalidateRect(WinWindowFromID(hwndDlg, ID_OK), NULL, FALSE);
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
/*-----------------------------*/
/* Change the dialog box title */
/*-----------------------------*/
WinSetWindowText(hwndDlg, "New Title");
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
/*-----------------------------*/
/* Change the dialog box title */
/*-----------------------------*/
WinSetDlgItemText(hwndDlg, FID_TITLEBAR, "New Title");
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
/*----------------------------------------*/
/* Change the text of push button ID_EXIT */
/*----------------------------------------*/
WinSetWindowText(WinWindowFromID(hwndDlg, ID_EXIT), "Quit");
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
/*---------------*/
/* To disable... */
/*---------------*/
WinEnableWindow(WinWindowFromID(hwndDlg, ID_DELETE), FALSE);
/*--------------*/
/* To enable... */
/*--------------*/
WinEnableWindow(WinWindowFromID(hwndDlg, ID_DELETE), TRUE);
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
USHORT id;
/*---------------------------------*/
/* Find ID of the control ID_ENTRY */
/*---------------------------------*/
id = WinQueryWindowUShort(WinWindowFromID(hwndDlg, ID_ENTRY), QWS_ID);
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
/*-------------------------------------------------------*/
/* For the information icon (white 'i' in a blue circle) */
/*-------------------------------------------------------*/
CONTROL "#11", SPTR_ICONINFORMATION, 5, 35, 22, 16, WC_STATIC,
SS_SYSICON | WS_VISIBLE
/*------------------------------------------------------------------*/
/* For the warning icon (black exclamation mark in a yellow circle) */
/*------------------------------------------------------------------*/
CONTROL "#14", SPTR_ICONWARNING, 5, 35, 22, 16, WC_STATIC,
SS_SYSICON | WS_VISIBLE
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
static HWND hABar;
case WM_INITDLG:
;
;
;
hABar = WinLoadMenu(hwndDlg, NULL, ID_MENU);
WinSendMsg(hwndDlg, WM_UPDATEFRAME, (MPARAM)FID_MENU, (MPARAM)NULL);
;
return (MRESULT)TRUE; /* Needed if we have changed focus */
break;
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
WinSetWindowText(WinWindowFromID(hwndDlg, ID_LBREAK),
"Line 1\012Line 2\012Line 3");
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
hDlg = WinLoadDlg(HWND_DESKTOP, HWND_DESKTOP, DlgProc, NULL,
DLG_HINTS, NULL);
WinProcessDlg(hDlg);
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
hab = WinInitialize(NULL);
hmq = WinCreateMsgQueue(hab, 0);
WinDlgBox(HWND_DESKTOP, HWND_DESKTOP, DlgProc, NULL, DLG_HINTS, NULL);
WinDestroyMsgQueue(hmq);
WinTerminate(hab);
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
static HWND hDlgBoxIcon;
case WM_INITDLG:
hDlgBoxIcon = WinLoadPointer(HWND_DESKTOP, NULL, ID_ICON);
WinDefDlgProc(hwndDlg, WM_SETICON, (MPARAM)hDlgBoxIcon, (MPARAM)0);
;
;
;
return (MRESULT)TRUE; /* Needed if we have changed focus */
break;
case WM_ADJUSTWINDOWPOS:
if (((PSWP)mp1)->fs & SWP_MINIMIZE) // Being minimized
{
WinShowWindow(WinWindowFromID(hwndDlg, ID_OK), FALSE);
}
else
if (((PSWP)mp1)->fs & SWP_RESTORE) // Being restored
{
WinShowWindow(WinWindowFromID(hwndDlg, ID_OK), TRUE);
}
return WinDefDlgProc(hwndDlg, msg, mp1, mp2);
break;
case ID_EXIT:
WinDestroyPointer(hDlgBoxIcon);
;
;
;
break;
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
SHORT X_Left,
Y_Bot;
LONG ScreenHeight,
ScreenWidth;
case WM_INITDLG:
/*----------------------------------------*/
/* This code will ensure that your dialog */
/* box is centred on the desktop. */
/*----------------------------------------*/
ScreenWidth = WinQuerySysValue(HWND_DESKTOP, SV_CXSCREEN);
ScreenHeight = WinQuerySysValue(HWND_DESKTOP, SV_CYSCREEN);
WinQueryWindowRect(hwndDlg, &rc);
X_Left = (SHORT)(ScreenWidth - rc.xRight) / 2;
Y_Bot = (SHORT)(ScreenHeight - rc.yTop) / 2;
WinSetWindowPos(hwndDlg, HWND_TOP, X_Left, Y_Bot, 0, 0,
SWP_MOVE | SWP_SHOW | SWP_ACTIVATE);
/*---------------------------------------------------------------------*/
/* If you want to start minimized, then use the following */
/* */
/* WinSetWindowPos(hwndDlg, HWND_TOP, X_Left, Y_Bot, 0, 0, */
/* SWP_MOVE | SWP_SHOW | SWP_ACTIVATE | SWP_MINIMIZE); */
/*---------------------------------------------------------------------*/
;
;
return (MRESULT)TRUE; /* Needed if we have changed focus */
break;
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
MENU ID_MENU PRELOAD
BEGIN
SUBMENU "~Options", ID_OPTIONS
BEGIN
MENUITEM "Test ~1", ID_TEST1
MENUITEM "Test ~2", ID_TEST2
MENUITEM "Test ~3", ID_TEST3
END
END
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
/*---------------------------------------*/
/* Set the focus to entry field ID_ENTRY */
/*---------------------------------------*/
case WM_INITDLG:
WinSetFocus(HWND_DESKTOP, WinWindowFromID(hwndDlg, ID_ENTRY));
;
;
;
return (MRESULT)TRUE; /* Needed if we have changed focus */
break;
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
CONTROL "This is a status line", ID_STATUS, 0, 0, 185, 8, WC_STATIC,
SS_TEXT | DT_CENTER | DT_TOP | WS_GROUP | WS_VISIBLE
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
WinSetWindowText(WinWindowFromID(hwndDlg, ID_STATUS), szNewStatus);
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
HPS hps;
RECTL rc;
case WM_PAINT:
WinDefDlgProc(hwndDlg, msg, mp1, mp2);
hps = WinGetPS(hwndDlg);
WinQueryWindowRect(hwndDlg, &rc);
WinCalcFrameRect(hwndDlg, &rc, TRUE);
rc.yTop = rc.yBottom + WinQuerySysValue(HWND_DESKTOP, SV_CYMENU);
WinDrawText(hps, -1, "Status = OK", &rc, CLR_YELLOW, CLR_DARKGREEN,
DT_CENTER | DT_VCENTER | DT_ERASERECT);
WinReleasePS(hps);
break;
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
ULONG Colour;
case WM_INITDLG:
Colour = CLR_DARKGREEN;
WinSetPresParam(WinWindowFromID( hwndDlg, ID_STATUS ),
PP_BACKGROUNDCOLORINDEX,
(ULONG)sizeof(Colour), &Colour);
Colour = CLR_YELLOW;
WinSetPresParam(WinWindowFromID( hwndDlg, ID_STATUS ),
PP_FOREGROUNDCOLORINDEX,
(ULONG)sizeof(Colour), &Colour);
;
;
;
return (MRESULT)TRUE; /* If changing focus during initialisation */
break;
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
/*---------------------------*/
/* Get handle of entry field */
/*---------------------------*/
hEntry = WinWindowFromID(hwndDlg, ID_ENTRY2);
/*-----------------------------*/
/* Change its style to centred */
/*-----------------------------*/
WinSetWindowULong(hEntry, QWL_STYLE,
WinQueryWindowULong(hEntry, QWL_STYLE ) | ES_CENTER);
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
/*----------------------*/
/* To remove WS_TABSTOP */
/*----------------------*/
hButton = WinWindowFromID(hwndDlg, ID_EXIT);
WinSetWindowULong(hButton, QWL_STYLE,
WinQueryWindowULong(hButton, QWL_STYLE ) & ~WS_TABSTOP);
/*-------------------*/
/* To add WS_TABSTOP */
/*-------------------*/
hButton = WinWindowFromID(hwndDlg, ID_EXIT);
WinSetWindowULong(hButton, QWL_STYLE,
WinQueryWindowULong(hButton, QWL_STYLE ) | WS_TABSTOP);
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
#define INCL_WIN
#include <os2.h>
#include <string.h>
#include "hints.h"
typedef struct _CHARMSG *PCHARMSG;
MRESULT EXPENTRY DlgProc(HWND, USHORT, MPARAM, MPARAM);
MRESULT EXPENTRY NumericProc( HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2);
VOID Button_Paint(HWND, HPS, USHORT);
PFNWP EntryFieldProc; // Public Entry Field procedure
/******************************************************************************/
VOID cdecl main()
{
HAB hab;
HMQ hmq;
HWND hDlg;
hab = WinInitialize(NULL);
hmq = WinCreateMsgQueue(hab, 0);
WinDlgBox(HWND_DESKTOP, HWND_DESKTOP, DlgProc, NULL, DLG_HINTS, NULL);
/*--------------------------------------------------------------*/
/* hDlg = WinLoadDlg(HWND_DESKTOP, HWND_DESKTOP, DlgProc, NULL, */
/* DLG_HINTS, NULL); */
/* WinProcessDlg(hDlg); */
/*--------------------------------------------------------------*/
WinDestroyMsgQueue(hmq);
WinTerminate(hab);
}
/******************************************************************************/
MRESULT EXPENTRY DlgProc(HWND hwndDlg, USHORT msg, MPARAM mp1, MPARAM mp2)
{
static HWND hDlgBoxIcon,
hwndEntry,
hABar,
hMenu;
HWND hButton,
hEntry,
hPwd;
static BOOL NewTitle = FALSE;
static ULONG MenuHt;
ULONG Colour,
val,
lStyle;
SWCNTRL PgmEntry;
POINTL Pt;
USHORT id;
HPS hps;
RECTL rc;
SHORT X_Left,
Y_Bot;
LONG ScreenHeight,
ScreenWidth;
CHAR szPswd[9];
USERBUTTON *ubtn;
//=============================================================================
switch (msg)
{
case WM_INITDLG:
EntryFieldProc = WinSubclassWindow(WinWindowFromID(hwndDlg, ID_ENTRY2),
NumericProc);
WinSendMsg(WinWindowFromID(hwndDlg, ID_PASSWORD),
EM_SETTEXTLIMIT,
MRFROMSHORT(8),
NULL);
WinSendMsg(WinWindowFromID(hwndDlg, ID_ENTRY1),
EM_SETREADONLY,
(MPARAM)TRUE,
NULL);
hDlgBoxIcon = WinLoadPointer(HWND_DESKTOP, NULL, ID_ICON);
WinDefDlgProc(hwndDlg, WM_SETICON, (MPARAM)hDlgBoxIcon, (MPARAM)0);
WinSetFocus(HWND_DESKTOP, WinWindowFromID(hwndDlg, ID_ENTRY2));
hABar = WinLoadMenu(hwndDlg, NULL, ID_MENU);
WinSendMsg(hwndDlg, WM_UPDATEFRAME, (MPARAM)FID_MENU, (MPARAM)NULL);
hMenu = WinLoadMenu(hwndDlg, NULL, ID_MENU2);
MenuHt = WinQuerySysValue(HWND_DESKTOP, SV_CYMENU);
Colour = CLR_DARKGREEN;
WinSetPresParam(WinWindowFromID( hwndDlg, ID_STATUS ),
PP_BACKGROUNDCOLORINDEX,
(ULONG)sizeof(Colour), &Colour);
Colour = CLR_YELLOW;
WinSetPresParam(WinWindowFromID( hwndDlg, ID_STATUS ),
PP_FOREGROUNDCOLORINDEX,
(ULONG)sizeof(Colour), &Colour);
ScreenWidth = WinQuerySysValue(HWND_DESKTOP, SV_CXSCREEN);
ScreenHeight = WinQuerySysValue(HWND_DESKTOP, SV_CYSCREEN);
WinQueryWindowRect(hwndDlg, &rc); /*---------------*/
X_Left = (SHORT)(ScreenWidth - rc.xRight) / 2; /* Centre window */
Y_Bot = (SHORT)(ScreenHeight - rc.yTop) / 2; /*---------------*/
WinSetWindowPos(hwndDlg, HWND_TOP, X_Left, Y_Bot, 0, 0,
SWP_MOVE | SWP_SHOW | SWP_ACTIVATE);
PgmEntry.hwnd = hwndDlg;
PgmEntry.hwndIcon = hDlgBoxIcon;
PgmEntry.hprog = NULL;
PgmEntry.idProcess = NULL;
PgmEntry.idSession = NULL;
PgmEntry.uchVisibility = SWL_VISIBLE;
PgmEntry.fbJump = SWL_JUMPABLE;
strcpy(PgmEntry.szSwtitle, "Hints & Tips");
hwndEntry = WinAddSwitchEntry(&PgmEntry);
return (MRESULT)TRUE;
break;
/*-----------------------------------------------------------------------*/
/* case WM_PAINT: */
/* WinDefDlgProc(hwndDlg, msg, mp1, mp2); */
/* hps = WinGetPS(hwndDlg); */
/* WinQueryWindowRect(hwndDlg, &rc); */
/* WinCalcFrameRect(hwndDlg, &rc, TRUE); */
/* rc.yTop = rc.yBottom + WinQuerySysValue(HWND_DESKTOP, SV_CYMENU); */
/* WinDrawText(hps, -1, "Status = OK", &rc, CLR_YELLOW, CLR_DARKGREEN, */
/* DT_CENTER | DT_VCENTER | DT_ERASERECT); */
/* WinReleasePS(hps); */
/* break; */
/*-----------------------------------------------------------------------*/
case WM_BUTTON2DOWN:
Pt.x = MOUSEMSG(&msg)->x;
Pt.y = MOUSEMSG(&msg)->y + MenuHt;
WinPostMsg(hMenu, MM_STARTMENUMODE, MPFROM2SHORT(TRUE, TRUE), NULL);
WinSetWindowPos(hMenu, HWND_TOP, (USHORT)Pt.x, (USHORT)Pt.y, 0, 0,
SWP_MOVE | SWP_SHOW);
break;
case WM_NEXTMENU:
return (MRESULT)NULL;
case WM_ADJUSTWINDOWPOS:
if (((PSWP)mp1)->fs & SWP_MINIMIZE)
{
WinShowWindow(WinWindowFromID(hwndDlg, ID_OK), FALSE);
WinShowWindow(WinWindowFromID(hwndDlg, ID_STATUS), FALSE);
WinDestroyWindow(hABar);
}
else
if (((PSWP)mp1)->fs & SWP_RESTORE)
{
WinShowWindow(WinWindowFromID(hwndDlg, ID_OK), TRUE);
WinShowWindow(WinWindowFromID(hwndDlg, ID_STATUS), TRUE);
hABar = WinLoadMenu(hwndDlg, NULL, ID_MENU);
WinSendMsg(hwndDlg, WM_UPDATEFRAME, (MPARAM)FID_MENU, (MPARAM)NULL);
}
return WinDefDlgProc(hwndDlg, msg, mp1, mp2);
break;
case WM_CONTROL:
switch(HIUSHORT(mp1))
{
case BN_PAINT:
switch(LOUSHORT(mp1)) /* Which Button? */
{
case ID_USERBUTTON:
ubtn = (USERBUTTON *)mp2;
Button_Paint(ubtn->hwnd, ubtn->hps, ubtn->fsState);
return (MRESULT)TRUE;
default:
break;
}
}
break;
case WM_COMMAND:
switch(SHORT1FROMMP(mp1))
{
case ID_TEST1:
DosBeep(500, 100);
return FALSE;
case ID_TEST2:
DosBeep(1000, 100);
return FALSE;
case ID_TEST3:
DosBeep(1500, 100);
return FALSE;
case ID_ITEM1:
DosBeep(500, 100);
return FALSE;
case ID_ITEM2:
DosBeep(1000, 100);
return FALSE;
case ID_ITEM3:
DosBeep(1500, 100);
return FALSE;
case ID_ITEM4:
DosBeep(2000, 100);
return FALSE;
case ID_ITEM5:
DosBeep(2500, 100);
return FALSE;
case ID_USERBUTTON:
DosBeep(1000, 100);
DosBeep(500, 100);
return FALSE;
case ID_OK:
WinSetWindowText(WinWindowFromID(hwndDlg, ID_LBREAK),
"Line 1\012Line 2\012Line 3");
if (NewTitle)
NewTitle = FALSE;
else
NewTitle = TRUE;
if (NewTitle)
{
WinSetWindowText(hwndDlg, "Sample Dialog Box with New Title");
/*--------------------------------------------------------*/
/* WinSetDlgItemText(hwndDlg, FID_TITLEBAR, "New Title"); */
/*--------------------------------------------------------*/
WinSetWindowText(WinWindowFromID(hwndDlg, ID_EXIT), "Quit");
WinSetWindowText(WinWindowFromID(hwndDlg, ID_STATUS), "New Status");
hButton = WinWindowFromID(hwndDlg, ID_EXIT);
WinSetWindowULong(hButton, QWL_STYLE,
WinQueryWindowULong(hButton, QWL_STYLE ) &
~WS_TABSTOP);
}
else
{
WinSetWindowText(hwndDlg, "Sample Dialog Box");
WinSetWindowText(WinWindowFromID(hwndDlg, ID_EXIT), "Exit");
WinSetWindowText(WinWindowFromID(hwndDlg, ID_STATUS), "Old Status");
hButton = WinWindowFromID(hwndDlg, ID_EXIT);
WinSetWindowULong(hButton, QWL_STYLE,
WinQueryWindowULong(hButton, QWL_STYLE ) |
WS_TABSTOP);
}
hEntry = WinWindowFromID(hwndDlg, ID_ENTRY2);
WinSetWindowULong(hEntry, QWL_STYLE,
WinQueryWindowULong(hEntry, QWL_STYLE ) |
ES_CENTER);
id = WinQueryWindowUShort(WinWindowFromID(hwndDlg, ID_ENTRY1),
QWS_ID);
WinSetDlgItemShort(hwndDlg, ID_ENTRY1, id, FALSE);
id = WinQueryWindowUShort(WinWindowFromID(hwndDlg, ID_ENTRY2),
QWS_ID);
WinSetDlgItemShort(hwndDlg, ID_ENTRY2, id, FALSE);
WinQueryWindowText(WinWindowFromID(hwndDlg, ID_PASSWORD),
sizeof(szPswd), szPswd);
WinQueryDlgItemText(hwndDlg, ID_PASSWORD,
sizeof(szPswd), szPswd);
WinQueryDlgItemShort(hwndDlg, ID_ENTRY1, &id, FALSE); // Unsigned
WinSetFocus(HWND_DESKTOP, WinWindowFromID(hwndDlg, ID_ENTRY2));
/*------------------------------------------------*/
/* Position cursor between 1st and 2nd characters */
/*------------------------------------------------*/
WinSendMsg(WinWindowFromID(hwndDlg, ID_ENTRY2), EM_SETSEL,
MPFROM2SHORT(1, 1), 0L);
/*------------------------------------------------*/
/* Position cursor between 1st and 2nd characters */
/* and mark 2nd and 3rd */
/*------------------------------------------------*/
WinSendMsg(WinWindowFromID(hwndDlg, ID_ENTRY2), EM_SETSEL,
MPFROM2SHORT(1, 3), 0L);
/*---------------------------------------------------------*/
/* Position cursor at start of field and mark entire field */
/*---------------------------------------------------------*/
WinSendMsg(WinWindowFromID(hwndDlg, ID_ENTRY2), EM_SETSEL,
MPFROM2SHORT(0, 5), 0L);
lStyle = WinQueryWindowULong(WinWindowFromID(hwndDlg, ID_OK),
QWL_STYLE);
if (lStyle & BS_DEFAULT) // Default
{
DosBeep(100, 200);
/*------------------------------------------------------------*/
/* WinSendMsg(WinWindowFromID(hwndDlg, ID_OK), BM_SETDEFAULT, */
/* (MPARAM)FALSE, NULL); */
/*------------------------------------------------------------*/
/*--------------------------------------------------------------*/
/* WinSendMsg(WinWindowFromID(hwndDlg, ID_EXIT), BM_SETDEFAULT, */
/* (MPARAM)TRUE, NULL); */
/*--------------------------------------------------------------*/
WinSetWindowBits(WinWindowFromID(hwndDlg, ID_OK), QWL_STYLE,
0L, BS_DEFAULT);
WinInvalidateRect(WinWindowFromID(hwndDlg, ID_OK), NULL, FALSE);
}
else // Not default
{
DosBeep(1000, 200);
/*-----------------------------------------------------------*/
/*WinSendMsg(WinWindowFromID(hwndDlg, ID_OK), BM_SETDEFAULT, */
/* (MPARAM)TRUE, NULL); */
/*-----------------------------------------------------------*/
WinSetWindowBits(WinWindowFromID(hwndDlg, ID_OK), QWL_STYLE,
BS_DEFAULT, BS_DEFAULT);
WinInvalidateRect(WinWindowFromID(hwndDlg, ID_OK), NULL, FALSE);
}
return FALSE;
case ID_EXIT:
WinDestroyPointer(hDlgBoxIcon);
WinRemoveSwitchEntry(hwndEntry);
WinPostMsg(hwndDlg, WM_QUIT, 0L, 0L);
break;
default:
return FALSE;
}
WinDismissDlg(hwndDlg, TRUE); /* Removes the dialog box */
break;
default:
return WinDefDlgProc(hwndDlg, msg, mp1, mp2);
}
return FALSE;
}
MRESULT EXPENTRY NumericProc( HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2 )
{
PCHARMSG p;
if (msg == WM_CHAR) // If this is a char msg
{
p = CHARMSG(&msg); // Address char structure
if ((p->fs & (KC_KEYUP|KC_CHAR)) == KC_CHAR) // ONLY key down transitions */
{
if ((p->chr < 0x30 || p->chr > 0x39) && // Not numeric
(p->chr != 8) && // Not backspace
(p->chr != 9) && // Not tab
(p->chr != 0x2D) && // Not -
(p->chr != 13)) // Not enter
{
WinAlarm(HWND_DESKTOP, WA_WARNING);
return (MRESULT)TRUE;
}
}
} /* Call public entry field procedure */
return ((*EntryFieldProc)(hwnd, msg, mp1, mp2));
}
VOID Button_Paint(HWND hwnd, HPS hps, USHORT Status)
{
RECTL DestPt;
HBITMAP hbm;
/*------------------------------------------------------------------------*/
/* hbm = WinGetSysBitmap(HWND_DESKTOP, SBMP_DRIVE); */
/* WinQueryWindowRect(hwnd, &DestPt); */
/* WinDrawBitmap(hps, hbm, NULL, (PPOINTL)&DestPt, CLR_YELLOW, CLR_BLACK, */
/* (Status ? DBM_INVERT : DBM_NORMAL) | DBM_STRETCH); */
/*------------------------------------------------------------------------*/
hbm = GpiLoadBitmap(hps, NULL, ID_LOCK, 0L, 0L);
WinQueryWindowRect(hwnd, &DestPt);
WinDrawBitmap(hps, hbm, NULL, (PPOINTL)&DestPt, 0L, 0L,
(Status ? DBM_INVERT : DBM_NORMAL) | DBM_STRETCH);
}
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
#define ID_LOCK 279
#define ID_USERBUTTON 278
#define ID_PASSWORD 277
#define ID_LBREAK 276
#define ID_DLGICON 275
#define ID_STATUS 274
#define ID_OPTIONS2 273
#define ID_ITEM5 272
#define ID_ITEM4 271
#define ID_ITEM3 270
#define ID_ITEM2 269
#define ID_ITEM1 268
#define ID_MENU2 267
#define ID_TEST3 266
#define ID_TEST2 265
#define ID_TEST1 264
#define ID_OPTIONS 263
#define ID_MENU 262
#define ID_ENTRY2 261
#define ID_ENTRY1 260
#define ID_ICON 259
#define ID_EXIT 258
#define ID_OK 257
#define DLG_HINTS 256
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
hints +
/A:16 /CO
hints.exe
hints.map /NOD
llibce.lib+
os2.lib
hints.def
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
NAME Hints WINDOWAPI
DESCRIPTION 'Test program for OS/2 Hints and Tips'
STUB 'OS2STUB.EXE'
DATA MULTIPLE
HEAPSIZE 8192
STACKSIZE 8192
PROTMODE
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
#include <os2.h>
#include "hints.h"
ICON ID_ICON hints.ico
ICON ID_DLGICON hints.ico
BITMAP ID_LOCK lock.bmp
MENU ID_MENU PRELOAD
BEGIN
SUBMENU "~Options", ID_OPTIONS
BEGIN
MENUITEM "Test ~1", ID_TEST1
MENUITEM "Test ~2", ID_TEST2
MENUITEM "Test ~3", ID_TEST3
END
END
MENU ID_MENU2 PRELOAD
BEGIN
SUBMENU "", ID_OPTIONS2
BEGIN
MENUITEM "Menu Item ~1", ID_ITEM1
MENUITEM "Menu Item ~2", ID_ITEM2
MENUITEM "Menu Item ~3", ID_ITEM3
MENUITEM SEPARATOR
MENUITEM "Menu Item ~4", ID_ITEM4
MENUITEM "Menu Item ~5", ID_ITEM5
END
END
rcinclude hints.dlg
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
DLGINCLUDE 1 "HINTS.H"
DLGTEMPLATE DLG_HINTS LOADONCALL MOVEABLE DISCARDABLE
BEGIN
DIALOG "Sample Dialog Box", DLG_HINTS, 105, 56, 195, 101, FS_NOBYTEALIGN |
FS_DLGBORDER | WS_VISIBLE | WS_CLIPSIBLINGS | WS_SAVEBITS,
FCF_SYSMENU | FCF_TITLEBAR | FCF_MINBUTTON
BEGIN
CONTROL "", ID_ENTRY1, 67, 72, 36, 8, WC_ENTRYFIELD, ES_LEFT |
ES_MARGIN | WS_TABSTOP | WS_VISIBLE
CONTROL "", ID_ENTRY2, 67, 57, 36, 8, WC_ENTRYFIELD, ES_LEFT |
ES_MARGIN | WS_TABSTOP | WS_VISIBLE
CTLDATA 8, 5, 0, 0
CONTROL "", ID_PASSWORD, 77, 37, 45, 8, WC_ENTRYFIELD, ES_LEFT |
ES_MARGIN | ES_UNREADABLE | WS_TABSTOP | WS_VISIBLE
CONTROL "OK", ID_OK, 5, 15, 29, 13, WC_BUTTON, BS_PUSHBUTTON |
BS_DEFAULT | WS_TABSTOP | WS_VISIBLE
CONTROL "Exit", ID_EXIT, 45, 15, 29, 13, WC_BUTTON, BS_PUSHBUTTON |
WS_TABSTOP | WS_VISIBLE
CONTROL "", ID_USERBUTTON, 150, 12, 32, 25, WC_BUTTON, BS_USERBUTTON |
WS_TABSTOP | WS_VISIBLE
CONTROL "Entry Field 1", 100, 5, 70, 55, 8, WC_STATIC, SS_TEXT |
DT_LEFT | DT_TOP | WS_GROUP | WS_VISIBLE
CONTROL "Entry Field 2", 101, 5, 55, 55, 8, WC_STATIC, SS_TEXT |
DT_LEFT | DT_TOP | WS_GROUP | WS_VISIBLE
CONTROL "This is a status line", ID_STATUS, 0, 0, 195, 8, WC_STATIC,
SS_TEXT | DT_CENTER | DT_TOP | WS_GROUP | WS_VISIBLE
CONTROL ID_DLGICON, ID_DLGICON, 5, 35, 20, 16, WC_STATIC, SS_ICON |
WS_GROUP | WS_VISIBLE
CONTROL "Line one\012Line two\012Line three", ID_LBREAK, 115, 53, 70, 28, WC_STATIC, SS_TEXT |
DT_LEFT | DT_TOP | DT_WORDBREAK | WS_GROUP | WS_VISIBLE
CONTROL "Password", 102, 30, 35, 44, 8, WC_STATIC, SS_TEXT | DT_LEFT |
DT_TOP | WS_GROUP | WS_VISIBLE
END
END
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
hints.exe: hints.obj \
hints.def hints.res
link @hints.l
rc hints.res
hints.obj: hints.c hints.h
cl /c /Alfu /W2 /Gs /Gc /Zi /Od hints.c
hints.res: hints.h hints.rc hints.dlg hints.ico
rc -r hints.rc
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
#define INCL_WIN
#include <os2.h>
#include <string.h>
#include "hints.h"
MRESULT EXPENTRY DlgProc(HWND, USHORT, MPARAM, MPARAM);
/******************************************************************************/
VOID cdecl main()
{
HAB hab;
HMQ hmq;
HWND hDlg;
hab = WinInitialize(NULL);
hmq = WinCreateMsgQueue(hab, 0);
WinDlgBox(HWND_DESKTOP, HWND_DESKTOP, DlgProc, NULL, DLG_HINTS, NULL);
WinDestroyMsgQueue(hmq);
WinTerminate(hab);
}
/******************************************************************************/
MRESULT EXPENTRY DlgProc(HWND hwndDlg, USHORT msg, MPARAM mp1, MPARAM mp2)
{
static HWND hDlgBoxIcon,
hwndEntry;
SWCNTRL PgmEntry;
RECTL rc;
SHORT X_Left,
Y_Bot;
LONG ScreenHeight,
ScreenWidth;
CHAR font[25];
SEL Selector;
PBYTE Buffer;
IPT ipt;
HFILE hFile;
USHORT Action,
BytesRead;
ULONG Colour;
static SHORT Idx = 0;
static PSZ Columns[] = {
"001 002 003 004 005 006",
"010 011 012 013 014 015",
"101 102 103 104 105 106"};
static PSZ FontTable[] = {
"8.Courier",
"10.Courier",
"12.Courier",
"8.Helv",
"10.Helv",
"12.Helv",
"14.Helv",
"18.Helv",
"24.Helv",
"10.System Monospaced",
"12.System Monospaced",
"12.System Proportional",
"8.Tms Rmn",
"10.Tms Rmn",
"12.Tms Rmn",
"14.Tms Rmn",
"18.Tms Rmn",
"24.Tms Rmn"};
//=============================================================================
switch (msg)
{
case WM_INITDLG:
hDlgBoxIcon = WinLoadPointer(HWND_DESKTOP, NULL, ID_ICON);
WinDefDlgProc(hwndDlg, WM_SETICON, (MPARAM)hDlgBoxIcon, (MPARAM)0);
ScreenWidth = WinQuerySysValue(HWND_DESKTOP, SV_CXSCREEN);
ScreenHeight = WinQuerySysValue(HWND_DESKTOP, SV_CYSCREEN);
WinQueryWindowRect(hwndDlg, &rc); /*---------------*/
X_Left = (SHORT)(ScreenWidth - rc.xRight) / 2; /* Centre window */
Y_Bot = (SHORT)(ScreenHeight - rc.yTop) / 2; /*---------------*/
WinSetWindowPos(hwndDlg, HWND_TOP, X_Left, Y_Bot, 0, 0,
SWP_MOVE | SWP_SHOW | SWP_ACTIVATE);
PgmEntry.hwnd = hwndDlg;
PgmEntry.hwndIcon = hDlgBoxIcon;
PgmEntry.hprog = NULL;
PgmEntry.idProcess = NULL;
PgmEntry.idSession = NULL;
PgmEntry.uchVisibility = SWL_VISIBLE;
PgmEntry.fbJump = SWL_JUMPABLE;
strcpy(PgmEntry.szSwtitle, "Hints & Tips");
hwndEntry = WinAddSwitchEntry(&PgmEntry);
WinSendDlgItemMsg(hwndDlg, ID_RADIO3, BM_SETCHECK,
MPFROM2SHORT(TRUE, 0), NULL);
strcpy(font, "12.Courier");
WinSetPresParam(WinWindowFromID(hwndDlg, ID_ENTRY1),
PP_FONTNAMESIZE, (ULONG)sizeof(font), font);
WinSetPresParam(WinWindowFromID(hwndDlg, ID_MULTILINE),
PP_FONTNAMESIZE, (ULONG)sizeof(font), font);
WinSetPresParam(WinWindowFromID(hwndDlg, ID_LISTBOX),
PP_FONTNAMESIZE, (ULONG)sizeof(font), font);
WinSetDlgItemText(hwndDlg, ID_ENTRY1, "12.Courier");
WinSetDlgItemText(hwndDlg, ID_MULTILINE, "12.Courier");
for (Idx = 0; Idx < 3; Idx++)
{
WinSendMsg(WinWindowFromID(hwndDlg, ID_LISTBOX), LM_INSERTITEM,
MRFROMSHORT(LIT_END),
MRFROMP(Columns[Idx]));
}
for (Idx = 0; Idx < 18; Idx++)
{
WinSendMsg(WinWindowFromID(hwndDlg, ID_LISTBOX), LM_INSERTITEM,
MRFROMSHORT(LIT_END),
MRFROMP(FontTable[Idx]));
}
Idx = 0;
return (MRESULT)TRUE;
break;
case WM_ADJUSTWINDOWPOS:
if (((PSWP)mp1)->fs & SWP_MINIMIZE)
{
WinShowWindow(WinWindowFromID(hwndDlg, ID_OK), FALSE);
}
else
if (((PSWP)mp1)->fs & SWP_RESTORE)
{
WinShowWindow(WinWindowFromID(hwndDlg, ID_OK), TRUE);
}
return WinDefDlgProc(hwndDlg, msg, mp1, mp2);
break;
case WM_CONTROL:
switch( SHORT1FROMMP( mp1 ) )
{
case ID_RADIO1:
switch( SHORT2FROMMP( mp1 ) )
{
case BN_CLICKED:
strcpy(font, "8.Courier");
WinSetDlgItemText(hwndDlg, ID_ENTRY1, "8.Courier");
WinSetDlgItemText(hwndDlg, ID_MULTILINE, "8.Courier");
WinSetPresParam(WinWindowFromID(hwndDlg, ID_ENTRY1),
PP_FONTNAMESIZE, (ULONG)sizeof(font), font);
WinSetPresParam(WinWindowFromID(hwndDlg, ID_MULTILINE),
PP_FONTNAMESIZE, (ULONG)sizeof(font), font);
WinSetPresParam(WinWindowFromID(hwndDlg, ID_LISTBOX),
PP_FONTNAMESIZE, (ULONG)sizeof(font), font);
Colour = CLR_RED;
WinSetPresParam(WinWindowFromID(hwndDlg, ID_MULTILINE),
PP_BACKGROUNDCOLORINDEX,
(ULONG)sizeof(Colour), &Colour);
Colour = CLR_YELLOW;
WinSetPresParam(WinWindowFromID(hwndDlg, ID_MULTILINE),
PP_FOREGROUNDCOLORINDEX,
(ULONG)sizeof(Colour), &Colour);
break;
default:
break;
}
break;
case ID_RADIO2:
switch( SHORT2FROMMP( mp1 ) )
{
case BN_CLICKED:
strcpy(font, "10.Courier");
WinSetDlgItemText(hwndDlg, ID_ENTRY1, "10.Courier");
WinSetDlgItemText(hwndDlg, ID_MULTILINE, "10.Courier");
WinSetPresParam(WinWindowFromID(hwndDlg, ID_ENTRY1),
PP_FONTNAMESIZE, (ULONG)sizeof(font), font);
WinSetPresParam(WinWindowFromID(hwndDlg, ID_MULTILINE),
PP_FONTNAMESIZE, (ULONG)sizeof(font), font);
WinSetPresParam(WinWindowFromID(hwndDlg, ID_LISTBOX),
PP_FONTNAMESIZE, (ULONG)sizeof(font), font);
break;
default:
break;
}
break;
case ID_RADIO3:
switch( SHORT2FROMMP( mp1 ) )
{
case BN_CLICKED:
strcpy(font, "12.Courier");
WinSetDlgItemText(hwndDlg, ID_ENTRY1, "12.Courier");
WinSetDlgItemText(hwndDlg, ID_MULTILINE, "12.Courier");
WinSetPresParam(WinWindowFromID(hwndDlg, ID_ENTRY1),
PP_FONTNAMESIZE, (ULONG)sizeof(font), font);
WinSetPresParam(WinWindowFromID(hwndDlg, ID_MULTILINE),
PP_FONTNAMESIZE, (ULONG)sizeof(font), font);
WinSetPresParam(WinWindowFromID(hwndDlg, ID_LISTBOX),
PP_FONTNAMESIZE, (ULONG)sizeof(font), font);
break;
default:
break;
}
break;
case ID_RADIO4:
switch( SHORT2FROMMP( mp1 ) )
{
case BN_CLICKED:
strcpy(font, "8.Helv");
WinSetDlgItemText(hwndDlg, ID_ENTRY1, "8.Helv");
WinSetDlgItemText(hwndDlg, ID_MULTILINE, "8.Helv");
WinSetPresParam(WinWindowFromID(hwndDlg, ID_ENTRY1),
PP_FONTNAMESIZE, (ULONG)sizeof(font), font);
WinSetPresParam(WinWindowFromID(hwndDlg, ID_MULTILINE),
PP_FONTNAMESIZE, (ULONG)sizeof(font), font);
WinSetPresParam(WinWindowFromID(hwndDlg, ID_LISTBOX),
PP_FONTNAMESIZE, (ULONG)sizeof(font), font);
break;
default:
break;
}
break;
}
case WM_COMMAND:
switch(SHORT1FROMMP(mp1))
{
case ID_OK:
DosAllocSeg(0, &Selector, SEG_GETTABLE); // Allocate 64K segment
Buffer = MAKEP(Selector, 0); // Get pointer to segment
DosOpen("C:\\CONFIG.SYS", &hFile, &Action,
(ULONG)NULL,
(USHORT)NULL,
OPEN_ACTION_OPEN_IF_EXISTS,
OPEN_FLAGS_SEQUENTIAL |
OPEN_SHARE_DENYNONE |
OPEN_ACCESS_READONLY,
(ULONG)NULL);
DosRead(hFile, Buffer, 65535L, &BytesRead);
DosClose(hFile);
WinSendMsg(WinWindowFromID(hwndDlg, ID_MULTILINE),
MLM_SETIMPORTEXPORT, (MPARAM)Buffer,
MPFROMLONG(65535L));
ipt = -1;
WinSendMsg(WinWindowFromID(hwndDlg, ID_MULTILINE),
MLM_IMPORT, (MPARAM)&ipt,
MPFROMLONG((LONG)BytesRead));
DosFreeSeg(Selector);
return FALSE;
case ID_CLEAR:
/*-----------------------------------------------*/
/* WinSetDlgItemText(hwndDlg, ID_MULTILINE, ""); */
/*-----------------------------------------------*/
WinSetWindowText(WinWindowFromID(hwndDlg, ID_MULTILINE), "");
return FALSE;
case ID_FONT:
strcpy(font, FontTable[Idx]);
WinSetPresParam(WinWindowFromID(hwndDlg, ID_LISTBOX),
PP_FONTNAMESIZE, (ULONG)sizeof(font), font);
WinSetPresParam(WinWindowFromID(hwndDlg, ID_ENTRY1),
PP_FONTNAMESIZE, (ULONG)sizeof(font), font);
WinSetPresParam(WinWindowFromID(hwndDlg, ID_MULTILINE),
PP_FONTNAMESIZE, (ULONG)sizeof(font), font);
WinSetWindowText(WinWindowFromID(hwndDlg, ID_ENTRY1), "");
WinSetWindowText(WinWindowFromID(hwndDlg, ID_ENTRY1),
FontTable[Idx++]);
if (Idx == 18)
Idx = 0;
return FALSE;
case ID_EXIT:
WinDestroyPointer(hDlgBoxIcon);
WinRemoveSwitchEntry(hwndEntry);
WinPostMsg(hwndDlg, WM_QUIT, 0L, 0L);
break;
default:
return FALSE;
}
WinDismissDlg(hwndDlg, TRUE); /* Removes the dialog box */
break;
default:
return WinDefDlgProc(hwndDlg, msg, mp1, mp2);
}
return FALSE;
}
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
#define DLG_HINTS 256
#define ID_OK 257
#define ID_EXIT 258
#define ID_ICON 259
#define ID_MULTILINE 260
#define ID_RADIO1 261
#define ID_RADIO2 262
#define ID_RADIO3 263
#define ID_ENTRY1 264
#define ID_RADIO4 265
#define ID_CLEAR 266
#define ID_FONT 267
#define ID_LISTBOX 268
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
#define INCL_WINSYS
#include <os2.h>
#include "hints.h"
ICON ID_ICON hints.ico
rcinclude hints.dlg
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
DLGINCLUDE 1 "HINTS.H"
DLGTEMPLATE DLG_HINTS LOADONCALL MOVEABLE DISCARDABLE
BEGIN
DIALOG "Sample Dialog Box", DLG_HINTS, 68, 30, 276, 159, FS_NOBYTEALIGN |
FS_DLGBORDER | WS_VISIBLE | WS_CLIPSIBLINGS | WS_SAVEBITS,
FCF_SYSMENU | FCF_TITLEBAR | FCF_MINBUTTON
BEGIN
CONTROL "Group 1", 100, 8, 76, 84, 77, WC_STATIC, SS_GROUPBOX |
WS_GROUP | WS_VISIBLE
CONTROL "8.Courier", ID_RADIO1, 16, 128, 65, 10, WC_BUTTON, BS_AUTORADIOBUTTON |
WS_TABSTOP | WS_VISIBLE
CONTROL "10.Courier", ID_RADIO2, 16, 113, 65, 10, WC_BUTTON, BS_AUTORADIOBUTTON |
WS_TABSTOP | WS_VISIBLE
CONTROL "12.Courier", ID_RADIO3, 16, 98, 65, 10, WC_BUTTON, BS_AUTORADIOBUTTON |
WS_TABSTOP | WS_VISIBLE
CONTROL "8.Helv", ID_RADIO4, 16, 83, 65, 10, WC_BUTTON, BS_AUTORADIOBUTTON |
WS_TABSTOP | WS_VISIBLE
CONTROL "", ID_ENTRY1, 105, 119, 158, 28, WC_ENTRYFIELD, ES_CENTER |
ES_MARGIN | WS_GROUP | WS_TABSTOP | WS_VISIBLE
CONTROL "", ID_LISTBOX, 103, 80, 162, 32, WC_LISTBOX, LS_NOADJUSTPOS |
WS_TABSTOP | WS_VISIBLE
CONTROL "", ID_MULTILINE, 8, 20, 259, 54, WC_MLE, MLS_BORDER |
MLS_HSCROLL | MLS_VSCROLL | WS_TABSTOP | WS_VISIBLE
CONTROL "Read File", ID_OK, 6, 5, 70, 13, WC_BUTTON, BS_PUSHBUTTON |
WS_TABSTOP | WS_VISIBLE
CONTROL "Clear MLE", ID_CLEAR, 85, 5, 70, 13, WC_BUTTON, BS_PUSHBUTTON |
WS_TABSTOP | WS_VISIBLE
PRESPARAMS PP_BACKGROUNDCOLORINDEX, CLR_RED
PRESPARAMS PP_FOREGROUNDCOLORINDEX, CLR_YELLOW
PRESPARAMS PP_FONTNAMESIZE, "10.Courier"
CONTROL "Change Font", ID_FONT, 167, 5, 62, 13, WC_BUTTON, BS_PUSHBUTTON |
WS_TABSTOP | WS_VISIBLE
CONTROL "Exit", ID_EXIT, 240, 5, 29, 13, WC_BUTTON, BS_PUSHBUTTON |
WS_TABSTOP | WS_VISIBLE
END
END
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
#define INCL_WIN
#define INCL_GPILCIDS
#define INCL_GPIPRIMITIVES
#define INCL_DOS
#include <os2.h>
#include <string.h>
#include "hints.h"
MRESULT EXPENTRY DlgProc(HWND, USHORT, MPARAM, MPARAM);
/******************************************************************************/
VOID cdecl main()
{
HAB hab;
HMQ hmq;
HWND hDlg;
hab = WinInitialize(NULL);
hmq = WinCreateMsgQueue(hab, 0);
WinDlgBox(HWND_DESKTOP, HWND_DESKTOP, DlgProc, NULL, DLG_HINTS, NULL);
WinDestroyMsgQueue(hmq);
WinTerminate(hab);
}
/******************************************************************************/
MRESULT EXPENTRY DlgProc(HWND hwndDlg, USHORT msg, MPARAM mp1, MPARAM mp2)
{
static HWND hwndEntry;
HWND hwndItem;
SWCNTRL PgmEntry;
RECTL rc;
SHORT X_Left,
Y_Bot,
Midx;
static SHORT Idx,
Oidx;
LONG ScreenHeight,
ScreenWidth;
CHAR font[15];
ULONG Colour;
SEL sel;
typedef struct _DBDATA
{
USHORT Key;
CHAR Capital[20];
} DBDATA, FAR *PDBDATA;
PDBDATA pDB_Data;
static PSZ szCountry[] = {"Austria", "Belgium", "Canada",
"Denmark", "Egypt", "Finland",
"Greece", "Hungary", "India",
"Japan", "Kenya", "Libya",
"Morocco", "Nigeria", "Oman",
"Peru", "Qatar", "Romania",
"Spain", "Turkey", "Uruguay",
"Venezuela", "Wales", "Xanxere",
"Yemen", "Zambia"};
static PSZ szCapital[] = {"Vienna", "Brussels", "Ottawa",
"Copenhagen", "Cairo", "Helsinki",
"Athens", "Budapest", "Delhi",
"Tokyo", "Nairobi", "Tripoli",
"Rabat", "Lagos", "Muscat",
"Lima", "Doha", "Bucharest",
"Madrid", "Ankara", "Montevideo",
"Caracas", "Cardiff", "None",
"Sana", "Lusaka"};
CHAR szCtry[10],
szCap[12],
szListBuff[50];
CHAR *Country,
*Capital;
ULONG KeyValue;
POWNERITEM pOwner;
SHORT cxText,
cyText;
HPS hps;
FONTMETRICS fm;
POINTL points[TXTBOX_COUNT],
pt;
//=============================================================================
switch (msg)
{
case WM_INITDLG:
WinEnableWindow(WinWindowFromID(hwndDlg, ID_PROCMULT), FALSE);
strcpy(font, "18.Helv");
WinSetPresParam(WinWindowFromID(hwndDlg, ID_ENTRY1),
PP_FONTNAMESIZE, (ULONG)sizeof(font), font);
Colour = CLR_RED;
WinSetPresParam(WinWindowFromID(hwndDlg, ID_ENTRY1),
PP_BACKGROUNDCOLORINDEX,
(ULONG)sizeof(Colour), &Colour);
WinSetPresParam(WinWindowFromID(hwndDlg, ID_ENTRY3),
PP_BACKGROUNDCOLORINDEX,
(ULONG)sizeof(Colour), &Colour);
Colour = CLR_YELLOW;
WinSetPresParam(WinWindowFromID(hwndDlg, ID_ENTRY1),
PP_FOREGROUNDCOLORINDEX,
(ULONG)sizeof(Colour), &Colour);
WinSetPresParam(WinWindowFromID(hwndDlg, ID_ENTRY3),
PP_FOREGROUNDCOLORINDEX,
(ULONG)sizeof(Colour), &Colour);
ScreenWidth = WinQuerySysValue(HWND_DESKTOP, SV_CXSCREEN);
ScreenHeight = WinQuerySysValue(HWND_DESKTOP, SV_CYSCREEN);
WinQueryWindowRect(hwndDlg, &rc); /*---------------*/
X_Left = (SHORT)(ScreenWidth - rc.xRight) / 2; /* Centre window */
Y_Bot = (SHORT)(ScreenHeight - rc.yTop) / 2; /*---------------*/
WinSetWindowPos(hwndDlg, HWND_TOP, X_Left, Y_Bot, 0, 0,
SWP_MOVE | SWP_SHOW | SWP_ACTIVATE);
PgmEntry.hwnd = hwndDlg;
PgmEntry.hwndIcon = NULL;
PgmEntry.hprog = NULL;
PgmEntry.idProcess = NULL;
PgmEntry.idSession = NULL;
PgmEntry.uchVisibility = SWL_VISIBLE;
PgmEntry.fbJump = SWL_JUMPABLE;
strcpy(PgmEntry.szSwtitle, "Hints & Tips");
hwndEntry = WinAddSwitchEntry(&PgmEntry);
for (Idx = 0; Idx < 26; Idx++)
{
/*--------------------------------------------------------------*/
/* If all we want to do is store the key value... */
/* */
/* WinSendDlgItemMsg(hwndDlg, ID_SLISTBOX, LM_INSERTITEM, */
/* MPFROMSHORT(LIT_END), */
/* MPFROMP(szCountry[Idx])); */
/* KeyValue = Idx + 1; */
/* WinSendDlgItemMsg(hwndDlg, ID_SLISTBOX, LM_SETITEMHANDLE, */
/* (MPARAM)Idx, (MPARAM)KeyValue); */
/*--------------------------------------------------------------*/
/*--------------------------------------------------------------*/
/* Otherwise we need to save a pointer to our structure... */
/* */
/*--------------------------------------------------------------*/
WinSendDlgItemMsg(hwndDlg, ID_SLISTBOX, LM_INSERTITEM,
MPFROMSHORT(LIT_END),
MPFROMP(szCountry[Idx]));
DosAllocSeg(22, &sel, 0);
pDB_Data = MAKEP(sel, 0);
pDB_Data->Key = Idx + 1;
strcpy(pDB_Data->Capital, szCapital[Idx]);
WinSendDlgItemMsg(hwndDlg, ID_SLISTBOX, LM_SETITEMHANDLE,
(MPARAM)Idx, MPFROMP(pDB_Data));
WinSendDlgItemMsg(hwndDlg, ID_MLISTBOX, LM_INSERTITEM,
MPFROMSHORT(LIT_END),
MPFROMP(szCountry[Idx]));
strcpy(szListBuff, szCountry[Idx]);
strcat(szListBuff, "\t");
strcat(szListBuff, szCapital[Idx]);
WinSendDlgItemMsg(hwndDlg, ID_OLISTBOX, LM_INSERTITEM,
MPFROMSHORT(LIT_END),
MPFROMP(szListBuff));
}
WinSendDlgItemMsg(hwndDlg, ID_SLISTBOX, LM_SELECTITEM,
MPFROMSHORT(0), (MPARAM)TRUE);
break;
case WM_MEASUREITEM:
hps = WinGetPS(WinWindowFromID(hwndDlg, ID_OLISTBOX));
WinSendDlgItemMsg(hwndDlg, ID_OLISTBOX, LM_QUERYITEMTEXT,
MPFROM2SHORT(Idx, sizeof(szListBuff)),
MPFROMP(szListBuff));
GpiQueryFontMetrics(hps, (LONG)sizeof(FONTMETRICS), &fm);
cyText = (SHORT)fm.lMaxBaselineExt;
GpiQueryTextBox(hps, (LONG)strlen(szListBuff), szListBuff,
TXTBOX_COUNT, points);
/*-------------------------------------------------*/
/* May need to add on a bit to cxText to ensure */
/* the entire item can be read when fully scrolled */
/*-------------------------------------------------*/
cxText = (USHORT)points[TXTBOX_TOPRIGHT].x + 20;
WinReleasePS(hps);
return MRFROM2SHORT(cyText, cxText);
case WM_DRAWITEM:
pOwner = (POWNERITEM)mp2;
rc.xRight = pOwner->rclItem.xRight/3*2;
rc.xLeft = pOwner->rclItem.xLeft;
rc.yTop = pOwner->rclItem.yTop;
rc.yBottom = pOwner->rclItem.yBottom;
GpiSetBackMix(pOwner->hps, BM_OVERPAINT);
if ((!pOwner->fsState) || // Unselected
(pOwner->idItem == 5)) // Don't allow Finland
{
GpiSetBackColor(pOwner->hps, CLR_DARKGREEN);
GpiSetColor(pOwner->hps, CLR_YELLOW);
}
else // Selected
{
GpiSetBackColor(pOwner->hps, CLR_YELLOW);
GpiSetColor(pOwner->hps, CLR_DARKGREEN);
}
WinSendDlgItemMsg(hwndDlg, ID_OLISTBOX, LM_QUERYITEMTEXT,
MPFROM2SHORT(pOwner->idItem, sizeof(szListBuff)),
MPFROMP(szListBuff));
Country = strtok(szListBuff, "\t");
Capital = strtok(NULL, "\t");
WinDrawText(pOwner->hps, strlen(Country),
Country, &rc, 0L, 0L,
DT_LEFT | DT_TEXTATTRS | DT_ERASERECT);
/*-----------------------------------*/
/* Draw next item in right rectangle */
/* allowing for horiz scrolling */
/*-----------------------------------*/
if (pOwner->rclItem.xLeft != 1) // i.e. we have been scrolled
rc.xLeft = rc.xRight + pOwner->rclItem.xLeft - 1;
else
rc.xLeft = rc.xRight;
rc.xRight = pOwner->rclItem.xRight;
WinDrawText(pOwner->hps, strlen(Capital),
Capital, &rc, 0L, 0L,
DT_LEFT | DT_TEXTATTRS | DT_ERASERECT);
pOwner->fsStateOld = pOwner->fsState = 0; // Don't let PM hilite
return (MRESULT)TRUE; // Don't let PM draw
case WM_CONTROL:
switch(SHORT1FROMMP(mp1))
{
case ID_SLISTBOX:
switch(SHORT2FROMMP(mp1))
{
case LN_SELECT:
Idx = (SHORT)WinSendDlgItemMsg(hwndDlg, ID_SLISTBOX,
LM_QUERYSELECTION, 0L, 0L);
if (Idx != LIT_NONE)
{
WinEnableWindow(WinWindowFromID(hwndDlg, ID_DELETE), TRUE);
WinSendDlgItemMsg(hwndDlg, ID_SLISTBOX, LM_QUERYITEMTEXT,
MPFROM2SHORT(Idx, sizeof(szCtry)),
MPFROMP(szCtry));
WinSetDlgItemText(hwndDlg, ID_ENTRY3, szCtry);
/*-----------------------------------------------------------------*/
/* Retrieve the key value... */
/* */
/* KeyValue = (ULONG)WinSendDlgItemMsg(hwndDlg, ID_SLISTBOX, */
/* LM_QUERYITEMHANDLE, */
/* MPFROMSHORT(Idx), NULL); */
/* WinSetDlgItemShort(hwndDlg, ID_ENTRY2, (SHORT)KeyValue, FALSE); */
/*-----------------------------------------------------------------*/
/*-------------------------------------------------------------*/
/* Or, retrieve all data associated with the listbox item... */
/* */
/*-------------------------------------------------------------*/
pDB_Data = (PDBDATA)WinSendDlgItemMsg(hwndDlg, ID_SLISTBOX,
LM_QUERYITEMHANDLE,
MPFROMSHORT(Idx), NULL);
WinSetDlgItemText(hwndDlg, ID_ENTRY1, pDB_Data->Capital);
WinSetDlgItemShort(hwndDlg, ID_ENTRY2,
(SHORT)pDB_Data->Key, FALSE);
}
break;
default:
break;
}
break;
case ID_MLISTBOX:
switch(SHORT2FROMMP(mp1))
{
case LN_SELECT:
WinEnableWindow(WinWindowFromID(hwndDlg, ID_PROCMULT), TRUE);
break;
default:
break;
}
break;
case ID_OLISTBOX:
switch(SHORT2FROMMP(mp1))
{
case LN_SELECT:
Oidx = (SHORT)WinSendDlgItemMsg(hwndDlg, ID_OLISTBOX,
LM_QUERYSELECTION, 0L, 0L);
if (Oidx == 5) // Don't allow Finland
{
DosBeep(1000, 100);
break;
}
WinSendDlgItemMsg(hwndDlg, ID_OLISTBOX, LM_QUERYITEMTEXT,
MPFROM2SHORT(Oidx, sizeof(szListBuff)),
MPFROMP(szListBuff));
Country = strtok(szListBuff, "\t");
Capital = strtok(NULL, "\t");
WinSetDlgItemText(hwndDlg, ID_ENTRY1, Capital);
WinSetDlgItemText(hwndDlg, ID_ENTRY2, "");
WinSetDlgItemText(hwndDlg, ID_ENTRY3, Country);
break;
default:
break;
}
break;
}
case WM_COMMAND:
switch(SHORT1FROMMP(mp1))
{
case ID_DESELECT:
WinSendDlgItemMsg(hwndDlg, ID_SLISTBOX, LM_SELECTITEM,
MPFROMSHORT(Idx), (MPARAM)FALSE);
WinSendDlgItemMsg(hwndDlg, ID_OLISTBOX, LM_SELECTITEM,
MPFROMSHORT(Oidx), (MPARAM)FALSE);
WinEnableWindow(WinWindowFromID(hwndDlg, ID_DELETE), FALSE);
WinSetDlgItemText(hwndDlg, ID_ENTRY1, "");
WinSetDlgItemText(hwndDlg, ID_ENTRY2, "");
WinSetDlgItemText(hwndDlg, ID_ENTRY3, "");
return FALSE;
case ID_DELETE:
pDB_Data = (PDBDATA)WinSendDlgItemMsg(hwndDlg, ID_SLISTBOX,
LM_QUERYITEMHANDLE,
MPFROMSHORT(Idx), NULL);
DosFreeSeg(SELECTOROF(pDB_Data));
WinSendDlgItemMsg(hwndDlg, ID_SLISTBOX, LM_DELETEITEM,
MPFROMSHORT(Idx), NULL);
WinSetDlgItemText(hwndDlg, ID_ENTRY1, "");
WinSetDlgItemText(hwndDlg, ID_ENTRY2, "");
WinSetDlgItemText(hwndDlg, ID_ENTRY3, "");
WinSendDlgItemMsg(hwndDlg, ID_SLISTBOX, LM_SELECTITEM,
MPFROMSHORT(0), (MPARAM)TRUE);
return FALSE;
case ID_PROCMULT:
WinSendMsg(hwndDlg, WM_COMMAND, MPFROMSHORT(ID_DESELECT), 0L);
Midx = (SHORT)WinSendDlgItemMsg(hwndDlg, ID_MLISTBOX,
LM_QUERYSELECTION,
(MPARAM)LIT_FIRST, 0L);
while(Midx != LIT_NONE)
{
WinSendDlgItemMsg(hwndDlg, ID_MLISTBOX, LM_QUERYITEMTEXT,
MPFROM2SHORT(Midx, sizeof(szCtry)),
MPFROMP(szCtry));
WinSetDlgItemText(hwndDlg, ID_ENTRY3, szCtry);
WinSendDlgItemMsg(hwndDlg, ID_MLISTBOX, LM_SELECTITEM,
MPFROMSHORT(Midx), (MPARAM)FALSE);
/*------------------------------*/
DosSleep(1000L); /* DON'T DO THIS IN PM PROGRAMS */
/* AFFECTS PERFORMANCE SEVERELY */
/*------------------------------*/
Midx = (SHORT)WinSendDlgItemMsg(hwndDlg, ID_MLISTBOX,
LM_QUERYSELECTION,
(MPARAM)Midx, 0L);
}
WinSetDlgItemText(hwndDlg, ID_ENTRY3, "Done");
DosBeep(500, 200);
WinEnableWindow(WinWindowFromID(hwndDlg, ID_PROCMULT), FALSE);
return FALSE;
case ID_EXIT:
WinRemoveSwitchEntry(hwndEntry);
WinPostMsg(hwndDlg, WM_QUIT, 0L, 0L);
break;
default:
return FALSE;
}
WinDismissDlg(hwndDlg, TRUE); /* Removes the dialog box */
break;
default:
return WinDefDlgProc(hwndDlg, msg, mp1, mp2);
}
return FALSE;
}
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
#define ID_PROCMULT 266
#define ID_ENTRY3 265
#define ID_ENTRY2 264
#define ID_DELETE 263
#define ID_ENTRY1 262
#define ID_OLISTBOX 261
#define ID_MLISTBOX 260
#define ID_SLISTBOX 259
#define ID_EXIT 258
#define ID_DESELECT 257
#define DLG_HINTS 256
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
#include <os2.h>
#include "hints.h"
rcinclude hints.dlg
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
DLGINCLUDE 1 "HINTS.H"
DLGTEMPLATE DLG_HINTS LOADONCALL MOVEABLE DISCARDABLE
BEGIN
DIALOG "Listbox Sample", DLG_HINTS, 30, 24, 317, 172, FS_NOBYTEALIGN |
FS_DLGBORDER | WS_VISIBLE | WS_CLIPSIBLINGS | WS_SAVEBITS,
FCF_SYSMENU | FCF_TITLEBAR
BEGIN
CONTROL "~Single Selection", 101, 8, 155, 80, 8, WC_STATIC, SS_TEXT |
DT_CENTER | DT_TOP | DT_MNEMONIC | WS_GROUP | WS_VISIBLE
CONTROL "", ID_SLISTBOX, 8, 71, 80, 80, WC_LISTBOX, WS_TABSTOP |
WS_VISIBLE
CONTROL "~Multiple Selection", 102, 115, 155, 80, 8, WC_STATIC,
SS_TEXT | DT_CENTER | DT_TOP | DT_MNEMONIC | WS_VISIBLE
CONTROL "", ID_MLISTBOX, 115, 71, 80, 80, WC_LISTBOX, LS_MULTIPLESEL |
WS_TABSTOP | WS_VISIBLE
CONTROL "~Ownerdraw", 103, 216, 155, 91, 8, WC_STATIC, SS_TEXT |
DT_CENTER | DT_TOP | DT_MNEMONIC | WS_VISIBLE
CONTROL "", ID_OLISTBOX, 216, 71, 91, 83, WC_LISTBOX, LS_OWNERDRAW |
LS_HORZSCROLL | WS_TABSTOP | WS_VISIBLE
CONTROL "Deselect", ID_DESELECT, 5, 5, 49, 13, WC_BUTTON, BS_PUSHBUTTON |
WS_TABSTOP | WS_VISIBLE
CONTROL "Delete", ID_DELETE, 65, 5, 40, 13, WC_BUTTON, BS_PUSHBUTTON |
WS_TABSTOP | WS_VISIBLE
CONTROL "Process MultSel", ID_PROCMULT, 115, 5, 79, 13, WC_BUTTON,
BS_PUSHBUTTON | WS_TABSTOP | WS_VISIBLE
CONTROL "Exit", ID_EXIT, 205, 5, 40, 13, WC_BUTTON, BS_PUSHBUTTON |
WS_TABSTOP | WS_VISIBLE
CONTROL "", ID_ENTRY1, 77, 25, 100, 16, WC_ENTRYFIELD, ES_CENTER |
ES_AUTOSCROLL | ES_MARGIN | ES_READONLY | WS_GROUP | WS_VISIBLE
CONTROL "Capital City", 104, 9, 28, 54, 8, WC_STATIC, SS_TEXT |
DT_LEFT | DT_TOP | WS_VISIBLE
CONTROL "Key", 105, 200, 28, 21, 8, WC_STATIC, SS_TEXT | DT_LEFT |
DT_TOP | WS_VISIBLE
CONTROL "", ID_ENTRY2, 232, 30, 39, 8, WC_ENTRYFIELD, ES_CENTER |
ES_MARGIN | ES_READONLY | WS_VISIBLE
CONTROL "Country", 106, 9, 50, 48, 8, WC_STATIC, SS_TEXT | DT_LEFT |
DT_TOP | WS_VISIBLE
CONTROL "", ID_ENTRY3, 77, 51, 100, 8, WC_ENTRYFIELD, ES_CENTER |
ES_MARGIN | ES_READONLY | WS_VISIBLE
END
END
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
VOID AddMenuItem(HWND hwnd)
{
HWND hSysMenu,
hSysSubMenu;
MENUITEM SysMenu;
SHORT I,
idSysMenu;
static MENUITEM Item[2] = {MIT_END, MIS_SEPARATOR, 0, 0, NULL, NULL,
MIT_END, MIS_TEXT, 0, ID_ABOUT, NULL, NULL};
static CHAR *Text[2] = {NULL, "~About..."};
hSysMenu = WinWindowFromID(WinQueryWindow(hwnd, QW_PARENT, FALSE),
FID_SYSMENU);
idSysMenu = SHORT1FROMMR(WinSendMsg(hSysMenu, MM_ITEMIDFROMPOSITION,
NULL, NULL));
WinSendMsg(hSysMenu, MM_QUERYITEM, MPFROM2SHORT(idSysMenu, FALSE),
MPFROMP(&SysMenu));
hSysSubMenu = SysMenu.hwndSubMenu;
for (I = 0; I < 2; I++)
WinSendMsg(hSysSubMenu, MM_INSERTITEM, MPFROMP(Item+I), MPFROMP(Text[I]));
}
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
case WM_INITMENU:
switch (SHORT1FROMMP(mp1))
{
case IDM_TWO:
/*---------------------------*/
/* Toggle menu item 1 on/off */
/*---------------------------*/
hFrame = WinQueryWindow(hwnd, QW_PARENT, FALSE);
hMenu = WinWindowFromID(hFrame, FID_MENU);
WinSendMsg(hMenu, MM_SETITEMATTR,
MPFROM2SHORT(MI_ITEM1, TRUE),
MPFROM2SHORT(MIA_CHECKED,
fbChecked ? MIA_CHECKED : 0));
break;
}
break;
case WM_COMMAND:
switch (SHORT1FROMMP(mp1))
{
case MI_ITEM1:
fbChecked = (fbChecked ? FALSE : TRUE);
break;
;
;
;
}
break;
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
/*-------------------------------------------*/
/* Delete 'Size' and 'Move' from system menu */
/*-------------------------------------------*/
hwndSysMenu = WinWindowFromID(hwndFrame, FID_SYSMENU);
WinSendMsg(hwndSysMenu, MM_DELETEITEM,
MPFROM2SHORT(SC_SIZE, TRUE),
MPFROMSHORT(NULL));
WinSendMsg(hwndSysMenu, MM_DELETEITEM,
MPFROM2SHORT(SC_MOVE, TRUE),
MPFROMSHORT(NULL));
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
/*------------------------*/
/* Disable all menu items */
/*------------------------*/
hFrame = WinQueryWindow(hwnd, QW_PARENT, FALSE);
WinEnableWindow(WinWindowFromID(hFrame, FID_MENU), FALSE);
/*-----------------------*/
/* Enable all menu items */
/*-----------------------*/
hFrame = WinQueryWindow(hwnd, QW_PARENT, FALSE);
WinEnableWindow(WinWindowFromID(hFrame, FID_MENU), TRUE);
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
/*-------------------------------------*/
/* To disable CLOSE in the system menu */
/*-------------------------------------*/
hwndSysMenu = WinWindowFromID(hwndFrame, FID_SYSMENU);
WinSendMsg(hwndSysMenu, MM_SETITEMATTR,
MPFROM2SHORT(SC_CLOSE, TRUE),
MPFROM2SHORT(MIA_DISABLED, MIA_DISABLED));
/*--------------------*/
/* To enable it again */
/*--------------------*/
WinSendMsg(hwndSysMenu, MM_SETITEMATTR,
MPFROM2SHORT(SC_CLOSE, TRUE),
MPFROM2SHORT(MIA_DISABLED, 0));
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
hFrame = WinQueryWindow(hwnd, QW_PARENT, FALSE);
WinDestroyWindow(WinWindowFromID(hFrame, FID_MENU));
WinLoadMenu(hFrame, NULL, ID_MENU2);
WinSendMsg(hFrame, WM_UPDATEFRAME, (MPARAM)FCF_MENU, (MPARAM)NULL);
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
case ID_ABOUT:
WinMessageBox(HWND_DESKTOP, hwnd,
"Version 1\n24 April 1991\nWritten by Bryan Goodyer",
"PM Hints and Tips",
0,
MB_INFORMATION | MB_OK | MB_MOVEABLE );
break;
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
case WM_BUTTON2DOWN:
Pt.x = MOUSEMSG(&msg)->x;
Pt.y = MOUSEMSG(&msg)->y + MenuHt;
WinPostMsg(hMenu, MM_STARTMENUMODE, MPFROM2SHORT(TRUE, TRUE), NULL);
WinSetWindowPos(hMenu, HWND_TOP, (USHORT)Pt.x, (USHORT)Pt.y, 0, 0,
SWP_MOVE | SWP_SHOW);
break;
case WM_NEXTMENU:
return (MRESULT)NULL;
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
BEGIN
MENUITEM "Menu Item ~1", MI_ITEM1, MIS_TEXT
MENUITEM "Menu Item ~2", MI_ITEM2, MIS_TEXT, MIA_NODISMISS
END
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
static HWND hABar;
case WM_INITDLG:
;
;
hABar = WinLoadMenu(hwndDlg, NULL, ID_MENU);
WinSendMsg(hwndDlg, WM_UPDATEFRAME, (MPARAM)FID_MENU, (MPARAM)NULL);
MenuHt = WinQuerySysValue(HWND_DESKTOP, SV_CYMENU);
hMenu = WinLoadMenu(hwndDlg, NULL, ID_MENU2);
;
;
break
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
static HWND hMenu;
static ULONG MenuHt;
POINTL Pt;
case WM_CREATE:
hMenu = WinLoadMenu(hwnd, NULL, ID_MENU2);
MenuHt = WinQuerySysValue(HWND_DESKTOP, SV_CYMENU);
break;
case WM_BUTTON2DOWN:
Pt.x = MOUSEMSG(&msg)->x;
Pt.y = MOUSEMSG(&msg)->y + MenuHt;
WinPostMsg(hMenu, MM_STARTMENUMODE, MPFROM2SHORT(TRUE, TRUE), NULL);
WinSetWindowPos(hMenu, HWND_TOP, (SHORT)Pt.x, (SHORT)Pt.y, 0, 0,
SWP_MOVE | SWP_SHOW);
break;
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
MENU ID_MENU2 PRELOAD
BEGIN
SUBMENU "", ID_OPTIONS2
BEGIN
MENUITEM "Menu Item ~1", ID_ITEM1
MENUITEM "Menu Item ~2", ID_ITEM2
MENUITEM "Menu Item ~3", ID_ITEM3
MENUITEM SEPARATOR
MENUITEM "Menu Item ~4", ID_ITEM4
MENUITEM "Menu Item ~5", ID_ITEM5
END
END
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
VOID DelClose(HWND hwnd)
{
HWND hSysMenu,
hSysSubMenu;
MENUITEM SysMenu;
SHORT idItem,
idSep,
idSysMenu;
hSysMenu = WinWindowFromID(WinQueryWindow(hwnd, QW_PARENT, FALSE),
FID_SYSMENU);
idSysMenu = SHORT1FROMMR(WinSendMsg(hSysMenu, MM_ITEMIDFROMPOSITION,
NULL, NULL));
WinSendMsg(hSysMenu, MM_QUERYITEM, MPFROM2SHORT(idSysMenu, FALSE),
MPFROMP(&SysMenu));
hSysSubMenu = SysMenu.hwndSubMenu;
idItem = SHORT1FROMMR(WinSendMsg(hSysSubMenu, MM_ITEMPOSITIONFROMID,
MPFROM2SHORT(SC_CLOSE, FALSE), NULL));
if (idItem != MIT_ERROR)
{
idSep = idItem + 1; // Get separator ID
idSep = SHORT1FROMMR(WinSendMsg(hSysSubMenu, MM_ITEMIDFROMPOSITION,
MPFROMSHORT(idSep), NULL));
WinSendMsg(hSysMenu, MM_DELETEITEM, MPFROM2SHORT(SC_CLOSE, TRUE),
MPFROMSHORT(NULL));
WinSendMsg(hSysSubMenu, MM_DELETEITEM, MPFROM2SHORT(idSep, FALSE), NULL);
}
}
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
case WM_ADJUSTWINDOWPOS:
if (((PSWP)mp1)->fs & SWP_MINIMIZE)
{
WinDestroyWindow(hABar);
}
else
if (((PSWP)mp1)->fs & SWP_RESTORE)
{
;
;
hABar = WinLoadMenu(hwndDlg, NULL, ID_MENU);
WinSendMsg(hwndDlg, WM_UPDATEFRAME, (MPARAM)FID_MENU, (MPARAM)NULL);
;
;
}
return WinDefDlgProc(hwndDlg, msg, mp1, mp2);
break;
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
case WM_BUTTON1DOWN:
/*-----------------------*/
/* Force menu to dismiss */
/*-----------------------*/
hMenu = WinWindowFromID(hFrame, FID_MENU);
WinPostMsg(hMenu, MM_STARTMENUMODE,
MPFROM2SHORT(FALSE, TRUE), (MPARAM)NULL);
WinPostMsg(hMenu, MM_ENDMENUMODE,
MPFROMSHORT(TRUE), (MPARAM)NULL);
;
;
;
break;
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
MENU ID_MAINWND PRELOAD
BEGIN
SUBMENU "E~xit", IDM_ONE
BEGIN
MENUITEM "~Exit Program\tF3", MI_EXIT, MIS_TEXT
MENUITEM "~Resume Program", MI_RESUME, MIS_TEXT
END
END
MENU ID_MENU2
BEGIN
SUBMENU "~Option 1", IDM_TWO
BEGIN
MENUITEM "Menu Item ~1", MI_ITEM1, MIS_TEXT
MENUITEM "Menu Item ~2", MI_ITEM2, MIS_TEXT
END
SUBMENU "E~xit", IDM_THREE
BEGIN
MENUITEM "~Exit Program\tF3", MI_EXIT, MIS_TEXT
MENUITEM "~Resume Program", MI_RESUME, MIS_TEXT
END
END
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
#define INCL_WIN
#include <os2.h>
#include <string.h>
#include <stdlib.h>
#include "hints.h"
MRESULT EXPENTRY MainWndProc (HWND, USHORT, MPARAM, MPARAM);
VOID APIENTRY WinSetTitle (PSZ);
BOOL APIENTRY WinNoShutdown(USHORT, BOOL);
VOID AddMenuItem (HWND);
VOID DelClose (HWND);
/****************************************************************************/
VOID cdecl main (void)
{
HAB hab;
HMQ hmq;
HWND hwndFrame,
hwndEntry,
hwndClient,
hwndSysMenu;
QMSG qmsg;
ULONG flFrameFlags;
CHAR Title[80];
SWCNTRL PgmEntry;
SHORT X_Left,
Y_Bot,
Height,
Width;
LONG ScrHeight,
ScrWidth;
/****************************************************************************/
hab = WinInitialize(0);
hmq = WinCreateMsgQueue(hab, 0);
WinRegisterClass(hab,
"Hints",
MainWndProc,
CS_SIZEREDRAW,
0);
WinLoadString( hab, NULL, ID_TITLE, sizeof(Title), Title );
flFrameFlags = FCF_TITLEBAR | FCF_SYSMENU | FCF_MENU |
FCF_SIZEBORDER | FCF_MINMAX | FCF_ACCELTABLE |
FCF_ICON | FCF_NOBYTEALIGN;
hwndFrame = WinCreateStdWindow(HWND_DESKTOP,
0L,
&flFrameFlags,
"Hints",
(PSZ)Title,
0L,
NULL,
ID_MAINWND,
&hwndClient);
WinCreateWindow(hwndClient,
WC_BUTTON,
"Switch Menus",
WS_VISIBLE,
10,
10,
120,
30,
hwndClient,
HWND_TOP,
ID_SWITCH,
0,
0);
ScrWidth = WinQuerySysValue(HWND_DESKTOP, SV_CXSCREEN);
ScrHeight = WinQuerySysValue(HWND_DESKTOP, SV_CYSCREEN);
Width = 400;
Height = 300;
X_Left = ((SHORT)ScrWidth - Width) / 2;
Y_Bot = ((SHORT)ScrHeight - Height) / 2;
/*-----------------------------------------------------------------------*/
/* Startup in background */
/* */
/* WinSetWindowPos(hwndFrame, HWND_BOTTOM, X_Left, Y_Bot, Width, Height, */
/* SWP_SIZE | SWP_MOVE | SWP_SHOW | SWP_ZORDER); */
/*-----------------------------------------------------------------------*/
/*-----------------------*/
/* Startup in foreground */
/*-----------------------*/
WinSetWindowPos(hwndFrame, NULL, X_Left, Y_Bot, Width, Height,
SWP_SIZE | SWP_MOVE | SWP_SHOW | SWP_ACTIVATE);
/*------------------*/
/* Add to task list */
/*------------------*/
PgmEntry.hwnd = hwndFrame;
PgmEntry.hwndIcon = NULL;
PgmEntry.hprog = NULL;
PgmEntry.idProcess = NULL;
PgmEntry.idSession = NULL;
PgmEntry.uchVisibility = SWL_VISIBLE;
PgmEntry.fbJump = SWL_JUMPABLE;
strcpy(PgmEntry.szSwtitle, Title);
hwndEntry = WinAddSwitchEntry(&PgmEntry);
/*---------------------------------*/
/* Disable 'End Task' in task list */
/*---------------------------------*/
WinNoShutdown(0, TRUE);
/*--------------------------------*/
/* Disable 'Close' in system menu */
/*--------------------------------*/
hwndSysMenu = WinWindowFromID(hwndFrame, FID_SYSMENU);
WinSendMsg(hwndSysMenu, MM_SETITEMATTR,
MPFROM2SHORT(SC_CLOSE, TRUE),
MPFROM2SHORT(MIA_DISABLED, MIA_DISABLED));
/*---------------------------------------*/
/* Disable 'Switch to...' in system menu */
/*---------------------------------------*/
WinSendMsg(hwndSysMenu, MM_SETITEMATTR,
MPFROM2SHORT(SC_TASKMANAGER, TRUE),
MPFROM2SHORT(MIA_DISABLED, MIA_DISABLED));
/*-------------------------------------------*/
/* Delete 'Size' and 'Move' from system menu */
/*-------------------------------------------*/
WinSendMsg(hwndSysMenu, MM_DELETEITEM,
MPFROM2SHORT(SC_SIZE, TRUE),
MPFROMSHORT(NULL));
WinSendMsg(hwndSysMenu, MM_DELETEITEM,
MPFROM2SHORT(SC_MOVE, TRUE),
MPFROMSHORT(NULL));
while (TRUE)
{
while (WinGetMsg(hab, &qmsg, NULL, 0, 0))
WinDispatchMsg(hab, &qmsg);
/*---------------------------------*/
/* Don't allow exit from task list */
/*---------------------------------*/
if (qmsg.mp1 == NULL)
break;
else
{
DosBeep(100, 200);
WinCancelShutdown(hmq, FALSE);
}
}
/*------------------------------------*/
/* Remove from task list and clean up */
/*------------------------------------*/
WinRemoveSwitchEntry(WinQuerySwitchHandle(hwndFrame, 0));
WinDestroyWindow(hwndFrame);
WinDestroyMsgQueue(hmq);
WinTerminate(hab);
}
/****************************************************************************/
MRESULT EXPENTRY MainWndProc (HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2)
{
SWCNTRL PgmEntry;
HWND hFrame,
hMenu,
hSwL,
hSysMenu;
static BOOL fbSwitched = FALSE,
fbChecked = FALSE;
switch (msg)
{
case WM_CREATE:
/*----------------------------*/
/* Add 'About' to system menu */
/*----------------------------*/
AddMenuItem(hwnd);
/*------------------------*/
/* Disable all menu items */
/*------------------------*/
hFrame = WinQueryWindow(hwnd, QW_PARENT, FALSE);
WinEnableWindow(WinWindowFromID(hFrame, FID_MENU), FALSE);
/*---------------------------------------------*/
/* Make system modal */
/* */
/* WinSetSysModalWindow(HWND_DESKTOP, hFrame); */
/*---------------------------------------------*/
break;
case WM_INITMENU:
switch (SHORT1FROMMP(mp1))
{
case IDM_TWO:
/*---------------------------*/
/* Toggle menu item 1 on/off */
/*---------------------------*/
hFrame = WinQueryWindow(hwnd, QW_PARENT, FALSE);
hMenu = WinWindowFromID(hFrame, FID_MENU);
WinSendMsg(hMenu, MM_SETITEMATTR,
MPFROM2SHORT(MI_ITEM1, TRUE),
MPFROM2SHORT(MIA_CHECKED,
fbChecked ? MIA_CHECKED : 0));
break;
}
break;
case WM_BUTTON1DOWN:
/*--------------------------------*/
/* Enable 'End Task' in task list */
/*--------------------------------*/
WinNoShutdown(0, FALSE);
/*-------------------------------*/
/* Enable 'Close' in system menu */
/*-------------------------------*/
hSysMenu = WinWindowFromID(WinQueryWindow(hwnd, QW_PARENT, FALSE),
FID_SYSMENU);
WinSendMsg(hSysMenu, MM_SETITEMATTR,
MPFROM2SHORT(SC_CLOSE, TRUE),
MPFROM2SHORT(MIA_DISABLED, 0));
/*-----------------------*/
/* Enable all menu items */
/*-----------------------*/
hFrame = WinQueryWindow(hwnd, QW_PARENT, FALSE);
WinEnableWindow(WinWindowFromID(hFrame, FID_MENU), TRUE);
/*-----------------------*/
/* Force menu to dismiss */
/*-----------------------*/
hMenu = WinWindowFromID(hFrame, FID_MENU);
WinPostMsg(hMenu, MM_STARTMENUMODE,
MPFROM2SHORT(FALSE, TRUE), (MPARAM)NULL);
WinPostMsg(hMenu, MM_ENDMENUMODE,
MPFROMSHORT(TRUE), (MPARAM)NULL);
/*------------------------*/
/* Change task list entry */
/*------------------------*/
PgmEntry.hwnd = WinQueryWindow(hwnd, QW_PARENT, FALSE);
PgmEntry.hwndIcon = NULL;
PgmEntry.hprog = NULL;
PgmEntry.idProcess = NULL;
PgmEntry.idSession = NULL;
PgmEntry.uchVisibility = SWL_VISIBLE;
PgmEntry.fbJump = SWL_JUMPABLE;
strcpy(PgmEntry.szSwtitle, "Tips and Hints");
WinChangeSwitchEntry(WinQuerySwitchHandle(PgmEntry.hwnd, 0), &PgmEntry);
/*-----------------------*/
/* Query task list entry */
/*-----------------------*/
hSwL = WinQuerySwitchHandle(WinQueryWindow(hwnd, QW_PARENT, FALSE), 0);
WinQuerySwitchEntry(hSwL, &PgmEntry);
/*-------------------------------------------*/
/* Remove system modality */
/* */
/* WinSetSysModalWindow(HWND_DESKTOP, NULL); */
/*-------------------------------------------*/
break;
case WM_BUTTON2DOWN:
/*----------------------------------*/
/* Delete 'Close' and its Separator */
/*----------------------------------*/
DelClose(hwnd);
break;
case WM_COMMAND:
switch (SHORT1FROMMP(mp1))
{
case ID_SWITCH:
/*--------------*/
/* Switch menus */
/*--------------*/
hFrame = WinQueryWindow(hwnd, QW_PARENT, FALSE);
if (!fbSwitched)
{
WinDestroyWindow(WinWindowFromID(hFrame, FID_MENU));
WinLoadMenu(hFrame, NULL, ID_MENU2);
WinSendMsg(hFrame, WM_UPDATEFRAME,
(MPARAM)FCF_MENU, (MPARAM)NULL);
fbSwitched = TRUE;
}
else
{
WinDestroyWindow(WinWindowFromID(hFrame, FID_MENU));
WinLoadMenu(hFrame, NULL, ID_MAINWND);
WinSendMsg(hFrame, WM_UPDATEFRAME,
(MPARAM)FCF_MENU, (MPARAM)NULL);
fbSwitched = FALSE;
}
break;
case ID_ABOUT:
/*-------------------*/
/* Display About box */
/*-------------------*/
WinMessageBox(HWND_DESKTOP, hwnd,
"Version 1\n24 April 1991\nWritten by Bryan Goodyer",
"PM Hints and Tips",
0,
MB_INFORMATION | MB_OK | MB_MOVEABLE );
break;
case MI_ITEM1:
fbChecked = (fbChecked ? FALSE : TRUE);
break;
case MI_EXIT:
WinPostMsg(hwnd, WM_QUIT, 0L, 0L);
break;
default:
break;
}
break;
case WM_ERASEBACKGROUND:
return (MRESULT)TRUE;
}
return WinDefWindowProc(hwnd, msg, mp1, mp2);
}
VOID AddMenuItem(HWND hwnd)
{
HWND hSysMenu,
hSysSubMenu;
MENUITEM SysMenu;
SHORT I,
idSysMenu;
static MENUITEM Item[2] = {MIT_END, MIS_SEPARATOR, 0, 0, NULL, NULL,
MIT_END, MIS_TEXT, 0, ID_ABOUT, NULL, NULL};
static CHAR *Text[2] = {NULL, "~About..."};
hSysMenu = WinWindowFromID(WinQueryWindow(hwnd, QW_PARENT, FALSE),
FID_SYSMENU);
idSysMenu = SHORT1FROMMR(WinSendMsg(hSysMenu, MM_ITEMIDFROMPOSITION,
NULL, NULL));
WinSendMsg(hSysMenu, MM_QUERYITEM, MPFROM2SHORT(idSysMenu, FALSE),
MPFROMP(&SysMenu));
hSysSubMenu = SysMenu.hwndSubMenu;
for (I = 0; I < 2; I++)
WinSendMsg(hSysSubMenu, MM_INSERTITEM, MPFROMP(Item+I), MPFROMP(Text[I]));
}
VOID DelClose(HWND hwnd)
{
HWND hSysMenu,
hSysSubMenu;
MENUITEM SysMenu;
SHORT idItem,
idSep,
idSysMenu;
hSysMenu = WinWindowFromID(WinQueryWindow(hwnd, QW_PARENT, FALSE),
FID_SYSMENU);
idSysMenu = SHORT1FROMMR(WinSendMsg(hSysMenu, MM_ITEMIDFROMPOSITION,
NULL, NULL));
WinSendMsg(hSysMenu, MM_QUERYITEM, MPFROM2SHORT(idSysMenu, FALSE),
MPFROMP(&SysMenu));
hSysSubMenu = SysMenu.hwndSubMenu;
idItem = SHORT1FROMMR(WinSendMsg(hSysSubMenu, MM_ITEMPOSITIONFROMID,
MPFROM2SHORT(SC_CLOSE, FALSE), NULL));
if (idItem != MIT_ERROR)
{
idSep = idItem + 1; // Get separator ID
idSep = SHORT1FROMMR(WinSendMsg(hSysSubMenu, MM_ITEMIDFROMPOSITION,
MPFROMSHORT(idSep), NULL));
WinSendMsg(hSysMenu, MM_DELETEITEM, MPFROM2SHORT(SC_CLOSE, TRUE),
MPFROMSHORT(NULL));
WinSendMsg(hSysSubMenu, MM_DELETEITEM, MPFROM2SHORT(idSep, FALSE), NULL);
}
}
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
#define ID_MAINWND 200
#define ID_TITLE 201
#define ID_ABOUT 202
#define MI_EXIT 203
#define MI_RESUME 204
#define ID_MENU2 205
#define MI_ITEM1 206
#define MI_ITEM2 207
#define ID_SWITCH 208
#define IDM_ONE 209
#define IDM_TWO 210
#define IDM_THREE 211
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
#include <os2.h>
#include "hints.h"
STRINGTABLE PRELOAD
BEGIN
ID_TITLE, "PM Hints and Tips"
END
ICON ID_MAINWND hints.ico
ACCELTABLE ID_MAINWND
BEGIN
VK_F3, MI_EXIT, VIRTUALKEY
END
MENU ID_MAINWND PRELOAD
BEGIN
SUBMENU "E~xit", IDM_ONE
BEGIN
MENUITEM "~Exit Program\tF3", MI_EXIT, MIS_TEXT
MENUITEM "~Resume Program", MI_RESUME, MIS_TEXT
END
END
MENU ID_MENU2
BEGIN
SUBMENU "~Option 1", IDM_TWO
BEGIN
MENUITEM "Menu Item ~1", MI_ITEM1, MIS_TEXT
MENUITEM "Menu Item ~2", MI_ITEM2, MIS_TEXT, MIA_NODISMISS
END
SUBMENU "E~xit", IDM_THREE
BEGIN
MENUITEM "~Exit Program\tF3", MI_EXIT, MIS_TEXT
MENUITEM "~Resume Program", MI_RESUME, MIS_TEXT
END
END
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
hints.exe: hints.obj \
hints.def hints.res
link @hints.l
rc hints.res
hints.obj: hints.c hints.h
cl /c /Alfu /W2 /Gs /Gc /Zi /Od hints.c
hints.res: hints.h hints.rc hints.ico
rc -r hints.rc
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
HPOINTER hptr;
case WM_CONTROLPOINTER:
hptr = WinQuerySysPointer(HWND_DESKTOP, SPTR_WAIT, FALSE);
WinSetPointer(HWND_DESKTOP, hptr);
return(hptr);
case WM_MOUSEMOVE:
hptr = WinQuerySysPointer(HWND_DESKTOP, SPTR_WAIT, FALSE);
WinSetPointer(HWND_DESKTOP, hptr);
return (MPARAM)TRUE;
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
WinLoadPointer(HWND_DESKTOP, NULL, ID_ICON);
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
POINTL ptl;
WinMapWindowPoints(HWND_DESKTOP, hwnd, &ptl, 1);
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
POINTL ptl;
WinQueryPointerPos(HWND_DESKTOP, &ptl);
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
/*------------------------*/
/* In your main procedure */
/*------------------------*/
MRESULT EXPENTRY EntryProc(HWND, USHORT, MPARAM, MPARAM);
PFNWP EntryFieldProc; // Public Entry Field procedure
/*------------------------------*/
/* In your dialog box procedure */
/*------------------------------*/
case WM_INITDLG:
EntryFieldProc = WinSubclassWindow(WinWindowFromID(hwndDlg, ID_ENTRY),
EntryProc);
;
;
;
break;
/*--------------------*/
/* Subclass procedure */
/*--------------------*/
MRESULT EXPENTRY EntryProc(HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2)
{
HPOINTER hptr;
switch (msg)
{
case WM_MOUSEMOVE:
hptr = WinQuerySysPointer(HWND_DESKTOP, SPTR_WAIT, FALSE);
WinSetPointer(HWND_DESKTOP, hptr);
return (MPARAM)TRUE;
}
// Call public entry field procedure
return ((*EntryFieldProc)(hwnd, msg, mp1, mp2));
}
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
/*------------------------*/
/* In your main procedure */
/*------------------------*/
MRESULT EXPENTRY ListProc(HWND, USHORT, MPARAM, MPARAM);
PFNWP ListboxProc; // Public Listbox procedure
/*------------------------------*/
/* In your dialog box procedure */
/*------------------------------*/
case WM_INITDLG:
ListboxProc = WinSubclassWindow(WinWindowFromID(hwndDlg, ID_LISTBOX),
ListProc);
;
;
;
break;
/*--------------------*/
/* Subclass procedure */
/*--------------------*/
MRESULT EXPENTRY ListProc(HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2)
{
HPOINTER hptr;
switch (msg)
{
case WM_CONTROLPOINTER:
hptr = WinQuerySysPointer(HWND_DESKTOP, SPTR_WAIT, FALSE);
WinSetPointer(HWND_DESKTOP, hptr);
return(hptr);
}
// Call public listbox procedure
return ((*ListboxProc)(hwnd, msg, mp1, mp2));
}
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
#define INCL_WIN
#include <os2.h>
#include <string.h>
#include <stdlib.h>
#include "hints.h"
MRESULT EXPENTRY MainWndProc (HWND, USHORT, MPARAM, MPARAM);
MRESULT EXPENTRY TestDlgProc (HWND, USHORT, MPARAM, MPARAM);
MRESULT EXPENTRY EntryProc (HWND, USHORT, MPARAM, MPARAM);
MRESULT EXPENTRY ListProc (HWND, USHORT, MPARAM, MPARAM);
PFNWP EntryFieldProc; // Public Entry Field procedure
PFNWP ListboxProc; // Public Listbox procedure
BOOL fbBusy = TRUE;
/****************************************************************************/
VOID cdecl main (void)
{
HAB hab;
HMQ hmq;
HWND hwndFrame,
hwndEntry,
hwndClient,
hstatic;
QMSG qmsg;
ULONG flFrameFlags;
CHAR Title[80];
SWCNTRL PgmEntry;
SHORT X_Left,
Y_Bot,
Height,
Width;
LONG ScrHeight,
ScrWidth;
/****************************************************************************/
hab = WinInitialize(0);
hmq = WinCreateMsgQueue(hab, 0);
WinRegisterClass(hab,
"Hints",
MainWndProc,
CS_SIZEREDRAW,
0);
WinLoadString( hab, NULL, ID_TITLE, sizeof(Title), Title );
flFrameFlags = FCF_TITLEBAR | FCF_SYSMENU | FCF_MENU |
FCF_SIZEBORDER | FCF_MINMAX | FCF_ACCELTABLE |
FCF_ICON | FCF_NOBYTEALIGN;
hwndFrame = WinCreateStdWindow(HWND_DESKTOP,
0L,
&flFrameFlags,
"Hints",
(PSZ)Title,
0L,
NULL,
ID_MAINWND,
&hwndClient);
WinCreateWindow(hwndClient, WC_BUTTON, "Test DLG", WS_VISIBLE,
10, 10, 150, 30, hwndClient, HWND_TOP, ID_DLG, 0, 0);
WinCreateWindow(hwndClient, WC_BUTTON, "Remove Hourglass", WS_VISIBLE,
175, 10, 200, 30, hwndClient, HWND_TOP, ID_REMOVE, 0, 0);
WinCreateWindow(hwndClient, WC_STATIC, "", WS_VISIBLE | SS_TEXT,
10, 125, 400, 30, hwndClient, HWND_TOP, ID_PTRTEXT1, 0, 0);
WinCreateWindow(hwndClient, WC_STATIC, "", WS_VISIBLE | SS_TEXT,
10, 75, 400, 30, hwndClient, HWND_TOP, ID_PTRTEXT2, 0, 0);
ScrWidth = WinQuerySysValue(HWND_DESKTOP, SV_CXSCREEN);
ScrHeight = WinQuerySysValue(HWND_DESKTOP, SV_CYSCREEN);
Width = 450;
Height = 300;
X_Left = ((SHORT)ScrWidth - Width) / 2;
Y_Bot = ((SHORT)ScrHeight - Height) / 2;
/*-----------------------*/
/* Startup in foreground */
/*-----------------------*/
WinSetWindowPos(hwndFrame, NULL, X_Left, Y_Bot, Width, Height,
SWP_SIZE | SWP_MOVE | SWP_SHOW | SWP_ACTIVATE);
/*------------------*/
/* Add to task list */
/*------------------*/
PgmEntry.hwnd = hwndFrame;
PgmEntry.hwndIcon = NULL;
PgmEntry.hprog = NULL;
PgmEntry.idProcess = NULL;
PgmEntry.idSession = NULL;
PgmEntry.uchVisibility = SWL_VISIBLE;
PgmEntry.fbJump = SWL_JUMPABLE;
strcpy(PgmEntry.szSwtitle, Title);
hwndEntry = WinAddSwitchEntry(&PgmEntry);
while (WinGetMsg(hab, &qmsg, NULL, 0, 0))
WinDispatchMsg(hab, &qmsg);
/*------------------------------------*/
/* Remove from task list and clean up */
/*------------------------------------*/
WinRemoveSwitchEntry(WinQuerySwitchHandle(hwndFrame, 0));
WinDestroyWindow(hwndFrame);
WinDestroyMsgQueue(hmq);
WinTerminate(hab);
}
/****************************************************************************/
MRESULT EXPENTRY MainWndProc (HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2)
{
HPOINTER hptr;
POINTL ptl;
CHAR szText[100],
szCoord[10];
switch (msg)
{
case WM_PAINT:
WinQueryPointerPos(HWND_DESKTOP, &ptl);
strcpy(szText, "(Screen Coords) Mouse X = ");
ltoa(ptl.x, szCoord, 10);
strcat(szText, szCoord);
strcat(szText, " Mouse Y = ");
ltoa(ptl.y, szCoord, 10);
strcat(szText, szCoord);
WinSetWindowText(WinWindowFromID(hwnd, ID_PTRTEXT1), szText);
WinMapWindowPoints(HWND_DESKTOP, hwnd, &ptl, 1);
strcpy(szText, "(Window Coords) Mouse X = ");
ltoa(ptl.x, szCoord, 10);
strcat(szText, szCoord);
strcat(szText, " Mouse Y = ");
ltoa(ptl.y, szCoord, 10);
strcat(szText, szCoord);
WinSetWindowText(WinWindowFromID(hwnd, ID_PTRTEXT2), szText);
break;
case WM_CONTROLPOINTER:
if (!fbBusy)
break;
/*-----------------------------------------------------*/
/* Load icon */
/* hptr = WinLoadPointer(HWND_DESKTOP, NULL, ID_ICON); */
/*-----------------------------------------------------*/
/*-----------------------------*/
/* Change pointer to hourglass */
/*-----------------------------*/
hptr = WinQuerySysPointer(HWND_DESKTOP, SPTR_WAIT, FALSE);
WinSetPointer(HWND_DESKTOP, hptr);
return(hptr);
case WM_BUTTON2DOWN:
WinSetCapture(HWND_DESKTOP, hwnd);
break;
case WM_BUTTON2UP:
WinSetCapture(HWND_DESKTOP, NULL);
break;
case WM_MOUSEMOVE:
WinInvalidateRect(hwnd, NULL, FALSE);
if (!fbBusy)
break;
/*-----------------------------------------------------*/
/* Load icon */
/* hptr = WinLoadPointer(HWND_DESKTOP, NULL, ID_ICON); */
/*-----------------------------------------------------*/
/*-----------------------------*/
/* Change pointer to hourglass */
/*-----------------------------*/
hptr = WinQuerySysPointer(HWND_DESKTOP, SPTR_WAIT, FALSE);
WinSetPointer(HWND_DESKTOP, hptr);
return (MPARAM)TRUE;
case WM_COMMAND:
switch (SHORT1FROMMP(mp1))
{
case ID_DLG:
WinDlgBox(HWND_DESKTOP, hwnd, TestDlgProc, NULL,
DLG_HINTS, NULL );
break;
case ID_REMOVE:
fbBusy = FALSE;
WinEnableWindow(WinWindowFromID(hwnd, ID_REMOVE), FALSE);
break;
case MI_EXIT:
WinPostMsg(hwnd, WM_QUIT, 0L, 0L);
break;
default:
break;
}
break;
case WM_ERASEBACKGROUND:
return (MRESULT)TRUE;
}
return WinDefWindowProc(hwnd, msg, mp1, mp2);
}
MRESULT EXPENTRY TestDlgProc(HWND hwndDlg, USHORT msg, MPARAM mp1, MPARAM mp2)
{
HPOINTER hptr;
switch (msg)
{
case WM_INITDLG:
if (!fbBusy)
break;
EntryFieldProc = WinSubclassWindow(WinWindowFromID(hwndDlg, ID_ENTRY),
EntryProc);
ListboxProc = WinSubclassWindow(WinWindowFromID(hwndDlg, ID_LISTBOX),
ListProc);
WinEnableWindow(WinWindowFromID(hwndDlg, ID_ENTRY), FALSE);
break;
case WM_CONTROLPOINTER:
if (!fbBusy)
return (WinQuerySysPointer(HWND_DESKTOP, SPTR_ARROW, FALSE));
hptr = WinQuerySysPointer(HWND_DESKTOP, SPTR_WAIT, FALSE);
WinSetPointer(HWND_DESKTOP, hptr);
return(hptr);
case WM_COMMAND:
switch(SHORT1FROMMP(mp1))
{
case ID_OK:
WinDismissDlg(hwndDlg, TRUE);
break;
default:
return WinDefDlgProc(hwndDlg, msg, mp1, mp2);
}
WinDismissDlg(hwndDlg, TRUE);
break;
default:
return WinDefDlgProc(hwndDlg, msg, mp1, mp2);
}
return FALSE;
}
MRESULT EXPENTRY EntryProc(HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2)
{
HPOINTER hptr;
switch (msg)
{
case WM_MOUSEMOVE:
hptr = WinQuerySysPointer(HWND_DESKTOP, SPTR_WAIT, FALSE);
WinSetPointer(HWND_DESKTOP, hptr);
return (MPARAM)TRUE;
}
// Call public entry field procedure
return ((*EntryFieldProc)(hwnd, msg, mp1, mp2));
}
MRESULT EXPENTRY ListProc(HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2)
{
HPOINTER hptr;
switch (msg)
{
case WM_CONTROLPOINTER:
hptr = WinQuerySysPointer(HWND_DESKTOP, SPTR_WAIT, FALSE);
WinSetPointer(HWND_DESKTOP, hptr);
return(hptr);
}
// Call public listbox procedure
return ((*ListboxProc)(hwnd, msg, mp1, mp2));
}
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
#define ID_PTRTEXT2 262
#define ID_PTRTEXT1 261
#define ID_REMOVE 260
#define ID_DLG 259
#define ID_LISTBOX 258
#define ID_OK 257
#define DLG_HINTS 256
#define ID_ICON 206
#define ID_ENTRY 205
#define MI_RESUME 204
#define MI_EXIT 203
#define IDM_ONE 202
#define ID_TITLE 201
#define ID_MAINWND 200
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
#include <os2.h>
#include "hints.h"
STRINGTABLE PRELOAD
BEGIN
ID_TITLE, "PM Hints and Tips"
END
ICON ID_MAINWND hints.ico
ICON ID_ICON wait.ico
ACCELTABLE ID_MAINWND
BEGIN
VK_F3, MI_EXIT, VIRTUALKEY
END
MENU ID_MAINWND PRELOAD
BEGIN
SUBMENU "E~xit", IDM_ONE
BEGIN
MENUITEM "~Exit Program\tF3", MI_EXIT, MIS_TEXT
MENUITEM "~Resume Program", MI_RESUME, MIS_TEXT
END
END
rcinclude hints.dlg
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
DLGINCLUDE 1 "HINTS.H"
DLGTEMPLATE DLG_HINTS LOADONCALL MOVEABLE DISCARDABLE
BEGIN
DIALOG "Test Dialog Box", DLG_HINTS, 22, 20, 114, 101, FS_NOBYTEALIGN |
FS_DLGBORDER | WS_VISIBLE | WS_CLIPSIBLINGS | WS_SAVEBITS,
FCF_TITLEBAR
BEGIN
CONTROL "OK", ID_OK, 5, 5, 29, 13, WC_BUTTON, BS_PUSHBUTTON | BS_DEFAULT |
WS_TABSTOP | WS_VISIBLE
CONTROL "", ID_ENTRY, 7, 84, 100, 8, WC_ENTRYFIELD, ES_LEFT | ES_MARGIN |
WS_TABSTOP | WS_VISIBLE
CONTROL "", ID_LISTBOX, 5, 21, 104, 56, WC_LISTBOX, WS_TABSTOP |
WS_VISIBLE
END
END
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
hints.exe: hints.obj \
hints.def hints.res
link @hints.l
rc hints.res
hints.obj: hints.c hints.h
cl /c /Alfu /W2 /Gs /Gc /Zi /Od hints.c
hints.res: hints.h hints.rc hints.ico hints.dlg wait.ico
rc -r hints.rc
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
ULONG Colour;
Colour = CLR_RED;
WinSetPresParam(WinWindowFromID(hwndDlg, ID_CLEAR),
PP_BACKGROUNDCOLORINDEX,
(ULONG)sizeof(Colour), &Colour);
Colour = CLR_YELLOW;
WinSetPresParam(WinWindowFromID(hwndDlg, ID_CLEAR),
PP_FOREGROUNDCOLORINDEX,
(ULONG)sizeof(Colour), &Colour);
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
CONTROL "Clear MLE", ID_CLEAR, 85, 5, 70, 13, WC_BUTTON, BS_PUSHBUTTON |
WS_TABSTOP | WS_VISIBLE
PRESPARAMS PP_BACKGROUNDCOLORINDEX, CLR_RED
PRESPARAMS PP_FOREGROUNDCOLORINDEX, CLR_YELLOW
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
CHAR font[11];
/*------------------------------------------------*/
/* Length parameter must include NULL terminator, */
/* so use SIZEOF and not STRLEN */
/*------------------------------------------------*/
strcpy(font, "10.Courier");
WinSetPresParam(WinWindowFromID(hwndDlg, ID_CLEAR),
PP_FONTNAMESIZE, (ULONG)sizeof(font), font);
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
CONTROL "Clear MLE", ID_CLEAR, 85, 5, 70, 13, WC_BUTTON, BS_PUSHBUTTON |
WS_TABSTOP | WS_VISIBLE
PRESPARAMS PP_FONTNAMESIZE, "10.Courier"
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
static HWND hwndEntry;
SWCNTRL PgmEntry;
PgmEntry.hwnd = hwndFrame;
PgmEntry.hwndIcon = NULL;
PgmEntry.hprog = NULL;
PgmEntry.idProcess = NULL;
PgmEntry.idSession = NULL;
PgmEntry.uchVisibility = SWL_VISIBLE;
PgmEntry.fbJump = SWL_JUMPABLE;
strcpy(PgmEntry.szSwtitle, Title);
hwndEntry = WinAddSwitchEntry(&PgmEntry);
while(WinGetMsg(hab, &qmsg, NULL, 0, 0))
WinDispatchMsg(hab, &qmsg);
WinRemoveSwitchEntry(hwndEntry);
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
SWCNTRL PgmEntry;
case WM_xxx:
;
;
PgmEntry.hwnd = WinQueryWindow(hwnd, QW_PARENT, FALSE);
PgmEntry.hwndIcon = NULL;
PgmEntry.hprog = NULL;
PgmEntry.idProcess = NULL;
PgmEntry.idSession = NULL;
PgmEntry.uchVisibility = SWL_VISIBLE;
PgmEntry.fbJump = SWL_JUMPABLE;
strcpy(PgmEntry.szSwtitle, "Tips and Hints");
WinChangeSwitchEntry(WinQuerySwitchHandle(PgmEntry.hwnd, 0), &PgmEntry);
break;
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
VOID APIENTRY WinSetTitle(PSZ);
case WM_xxx:
;
;
WinSetTitle("Tips and Hints");
break;
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
while (TRUE)
{
while (WinGetMsg(hab, &qmsg, NULL, 0, 0))
WinDispatchMsg(hab, &qmsg);
if (qmsg.mp1 == NULL)
break;
else
WinCancelShutdown(hmq, FALSE);
}
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
BOOL APIENTRY WinNoShutdown(USHORT sessionid, BOOL fNoShutdown);
WinNoShutdown(0, TRUE); // To disable
WinNoShutdown(0, FALSE); // To enable
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
hSwL = WinQuerySwitchHandle(hwndFrame, 0);
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
hSwL = WinQuerySwitchHandle(WinQueryWindow(hwnd, QW_PARENT, FALSE), 0);
WinQuerySwitchEntry(hSwL, &PgmEntry);
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
#define INCL_WIN
#include <os2.h>
#include <string.h>
#include <stdlib.h>
#include "hints.h"
MRESULT EXPENTRY MainWndProc (HWND, USHORT, MPARAM, MPARAM);
/****************************************************************************/
VOID cdecl main (void)
{
HAB hab;
HMQ hmq;
HWND hwndFrame,
hwndClient;
QMSG qmsg;
ULONG flFrameFlags;
CHAR Title[80];
SWCNTRL PgmEntry;
SHORT X_Left,
Y_Bot,
Height,
Width;
LONG ScrHeight,
ScrWidth;
/****************************************************************************/
hab = WinInitialize(0);
hmq = WinCreateMsgQueue(hab, 0);
WinRegisterClass(hab,
"Hints",
MainWndProc,
CS_SIZEREDRAW,
0);
WinLoadString( hab, NULL, ID_TITLE, sizeof(Title), Title );
flFrameFlags = FCF_TITLEBAR | FCF_SYSMENU | FCF_MENU |
FCF_SIZEBORDER | FCF_MINMAX | FCF_ACCELTABLE |
FCF_ICON;
hwndFrame = WinCreateStdWindow(HWND_DESKTOP,
0L,
&flFrameFlags,
"Hints",
(PSZ)Title,
0L,
NULL,
ID_MAINWND,
&hwndClient);
ScrWidth = WinQuerySysValue(HWND_DESKTOP, SV_CXSCREEN);
ScrHeight = WinQuerySysValue(HWND_DESKTOP, SV_CYSCREEN);
Width = 400;
Height = 300;
X_Left = ((SHORT)ScrWidth - Width) / 2;
Y_Bot = ((SHORT)ScrHeight - Height) / 2;
/*-----------------------*/
/* Startup in foreground */
/*-----------------------*/
WinSetWindowPos(hwndFrame, NULL, X_Left, Y_Bot, Width, Height,
SWP_SIZE | SWP_MOVE | SWP_SHOW | SWP_ACTIVATE);
/*------------------*/
/* Add to task list */
/*------------------*/
PgmEntry.hwnd = hwndFrame;
PgmEntry.hwndIcon = NULL;
PgmEntry.hprog = NULL;
PgmEntry.idProcess = NULL;
PgmEntry.idSession = NULL;
PgmEntry.uchVisibility = SWL_VISIBLE;
PgmEntry.fbJump = SWL_JUMPABLE;
strcpy(PgmEntry.szSwtitle, Title);
WinAddSwitchEntry(&PgmEntry);
while (WinGetMsg(hab, &qmsg, NULL, 0, 0))
WinDispatchMsg(hab, &qmsg);
/*------------------------------------*/
/* Remove from task list and clean up */
/*------------------------------------*/
WinRemoveSwitchEntry(WinQuerySwitchHandle(hwndFrame, 0));
WinDestroyWindow(hwndFrame);
WinDestroyMsgQueue(hmq);
WinTerminate(hab);
}
/****************************************************************************/
MRESULT EXPENTRY MainWndProc (HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2)
{
switch (msg)
{
case WM_COMMAND:
switch (SHORT1FROMMP(mp1))
{
case MI_EXIT:
WinPostMsg(hwnd, WM_QUIT, 0L, 0L);
break;
default:
break;
}
break;
case WM_ERASEBACKGROUND:
return (MRESULT)TRUE;
}
return WinDefWindowProc(hwnd, msg, mp1, mp2);
}
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
#define ID_MAINWND 200
#define ID_TITLE 201
#define IDM_ONE 202
#define MI_EXIT 203
#define MI_RESUME 204
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
#include <os2.h>
#include "hints.h"
STRINGTABLE PRELOAD
BEGIN
ID_TITLE, "PM Hints and Tips"
END
ICON ID_MAINWND hints.ico
ACCELTABLE ID_MAINWND
BEGIN
VK_F3, MI_EXIT, VIRTUALKEY
END
MENU ID_MAINWND PRELOAD
BEGIN
SUBMENU "E~xit", IDM_ONE
BEGIN
MENUITEM "~Exit Program\tF3", MI_EXIT, MIS_TEXT
MENUITEM "~Resume Program", MI_RESUME, MIS_TEXT
END
END
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
hints.exe: hints.obj \
hints.def hints.res
link @hints.l
rc hints.res
hints.obj: hints.c hints.h
cl /c /Alfu /W2 /Gs /Gc /Zi /Od hints.c
hints.res: hints.h hints.rc hints.ico
rc -r hints.rc
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
SHORT X_Left,
Y_Bot,
Height,
Width;
LONG ScrHeight,
ScrWidth;
ScrWidth = WinQuerySysValue(HWND_DESKTOP, SV_CXSCREEN);
ScrHeight = WinQuerySysValue(HWND_DESKTOP, SV_CYSCREEN);
/*-----------------------------------------------*/
Width = 400; /* Or set as a percentage of screen size */
Height = 300; /* eg. Width = ScrWidth/2; Height = ScrHeight/2; */
/*-----------------------------------------------*/
X_Left = ((SHORT)ScrWidth - Width) / 2;
Y_Bot = ((SHORT)ScrHeight - Height) / 2;
WinSetWindowPos(hwndFrame, HWND_TOP, X_Left, Y_Bot, Width, Height,
SWP_SIZE | SWP_MOVE | SWP_SHOW | SWP_ACTIVATE);
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
hwndFrame = WinQueryWindow(hwnd, QW_PARENT, FALSE);
WinSetWindowText(hwndFrame, "Hints - Size and Position Fixed");
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
FCF_STANDARD includes the following flags -
o FCF_TITLEBAR
o FCF_SYSMENU
o FCF_MINMAX
o FCF_SIZEBORDER
o FCF_TASKLIST
o FCF_MENU
o FCF_ACCELTABLE
o FCF_SHELLPOSITION
o FCF_ICON
If you required all these flags except FCF_ACCELTABLE then you could set up
your own identifier as follows -
#define FCF_NOACCEL FCF_STANDARD & ~FCF_ACCELTABLE
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
WinMapWindowPoints(hwnd, WinQueryWindow(hwnd, QW_PARENT, FALSE),
(PPOINTL)&WinRect, 2);
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
hwndFrame = WinQueryWindow(hwnd, QW_PARENT, FALSE);
WinSetWindowPos(hwndFrame, NULL, 0, 0, 0, 0, SWP_MINIMIZE);
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
case WM_MINMAXFRAME:
if (((PSWP)mp1)->fs & SWP_MINIMIZE)
{
/*-----------------------*/
/* About to be minimized */
/*-----------------------*/
}
else
if (((PSWP)mp1)->fs & SWP_MAXIMIZE)
{
/*-----------------------*/
/* About to be maximized */
/*-----------------------*/
}
else
if (((PSWP)mp1)->fs & SWP_RESTORE)
{
/*----------------------*/
/* About to be restored */
/*----------------------*/
}
break;
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
WinEnableWindow (WinWindowFromID (hwndFrame, FID_MINMAX), FALSE);
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
flCFrameFlags = FCF_TITLEBAR | FCF_SYSMENU | FCF_NOBYTEALIGN |
FCF_SIZEBORDER | FCF_MINMAX;
hwndChildFrame = WinCreateStdWindow(HWND_DESKTOP,
0L,
&flCFrameFlags,
"Hints2",
(PSZ)CTitle,
0L,
NULL,
0,
&hwndChild);
WinSetOwner(hwndChildFrame, hwndFrame);
WinSetWindowPos(hwndChildFrame, HWND_TOP, 350, 100, 200, 200,
SWP_SIZE | SWP_MOVE | SWP_SHOW | SWP_ACTIVATE);
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
RECTL rc;
HPS hps;
HWND hwndActiveWin;
PID pid;
TID tid;
CHAR szText[20],
szPid[6];
case WM_PAINT:
hwndActiveWin = WinQueryActiveWindow(HWND_DESKTOP, FALSE);
WinQueryWindowProcess(hwndActiveWin, &pid, &tid);
strcpy(szText, "Process ID = ");
strcat(szText, itoa(pid, szPid, 10));
WinQueryWindowRect(hwnd, &rc);
hps = WinBeginPaint(hwnd, NULL, &rc);
WinDrawText (hps, strlen(szText), szText, &rc, SYSCLR_WINDOWTEXT,
SYSCLR_WINDOW, DT_LEFT | DT_ERASERECT);
WinEndPaint(hps);
break;
case WM_TIMER:
hwndFrame = WinQueryWindow(hwnd, QW_PARENT, FALSE);
WinSetWindowPos(hwndFrame, HWND_TOP, 0, 0, 0, 0, SWP_ZORDER);
WinInvalidateRect(hwnd, NULL, TRUE); /* Cause PID to be displayed */
break;
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
hwndFrame = WinQueryWindow(hwnd, QW_PARENT, FALSE);
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
hwndFrame = WinQueryWindow(hwnd, QW_PARENT, FALSE);
WinEnableWindow(WinWindowFromID(hwndFrame, FID_TITLEBAR), FALSE);
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
hwndFrame = WinQueryWindow(hwnd, QW_PARENT, FALSE);
WinEnableWindow(WinWindowFromID(hwndFrame, FID_TITLEBAR), TRUE);
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
hwndFrame = WinQueryWindow(hwnd, QW_PARENT, FALSE);
WinSetWindowULong(hwndFrame, QWL_STYLE,
(WinQueryWindowULong(hwndFrame, QWL_STYLE) &
~FS_SIZEBORDER | FS_DLGBORDER));
WinInvalidateRect(hwndFrame, NULL, TRUE);
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
hwndFrame = WinQueryWindow(hwnd, QW_PARENT, FALSE);
WinSetWindowULong(hwndFrame, QWL_STYLE,
(WinQueryWindowULong(hwndFrame, QWL_STYLE) &
~FS_DLGBORDER | FS_SIZEBORDER));
WinInvalidateRect(hwndFrame, NULL, TRUE);
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
hwndFrame = WinQueryWindow(hwnd, QW_PARENT, FALSE);
WinSetWindowBits(hwndFrame, QWL_STYLE,
(~FS_SIZEBORDER | FS_DLGBORDER),
( FS_SIZEBORDER | FS_DLGBORDER));
WinInvalidateRect(hwndFrame, NULL, TRUE);
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
hwndFrame = WinQueryWindow(hwnd, QW_PARENT, FALSE);
WinSetWindowBits(hwndFrame, QWL_STYLE,
(FS_SIZEBORDER | ~FS_DLGBORDER),
(FS_SIZEBORDER | FS_DLGBORDER));
WinInvalidateRect(hwndFrame, NULL, TRUE);
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
WinQueryWindowRect(hwnd, (PRECTL)&WinRect);
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
case WM_MINMAXFRAME:
hwndFrame = WinQueryWindow(hwnd, QW_PARENT, FALSE);
WinSetWindowUShort(hwndFrame, QWS_XRESTORE, 100);
WinSetWindowUShort(hwndFrame, QWS_YRESTORE, 100);
WinSetWindowUShort(hwndFrame, QWS_CXRESTORE, 200);
WinSetWindowUShort(hwndFrame, QWS_CYRESTORE, 200);
break;
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
ACCELTABLE ID_MAINWND
BEGIN
VK_F3, MI_EXIT, VIRTUALKEY
END
ICON ID_MAINWND hints.ico
MENU ID_MAINWND PRELOAD
BEGIN
.
.
.
END
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
case WM_SAVEAPPLICATION:
WinQueryWindowPos(WinQueryWindow(hwnd, QW_PARENT, FALSE), &swp);
PrfWriteProfileData(HINI_USERPROFILE, "Hints", "Size",
&swp, (ULONG)sizeof(swp));
return NULL;
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
/*--------------------------------------------------------------*/
/* This should probably go just after your WinCreate... call */
/*--------------------------------------------------------------*/
ULONG DataLength;
DataLength = sizeof(swp);
if (!PrfQueryProfileData(HINI_USERPROFILE, "Hints", "Size",
&swp, &DataLength))
{
swp.x = 100; /*-----------------------------------*/
swp.y = 100; /* Profile not found so use defaults */
swp.cx = 200; /*-----------------------------------*/
swp.cy = 200;
}
WinSetWindowPos(hwndFrame, HWND_TOP, swp.x, swp.y, swp.cx, swp.cy,
SWP_SIZE | SWP_MOVE | SWP_SHOW | SWP_ACTIVATE);
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
SHORT X_Left,
Y_Bot,
Height,
Width;
X_Left = 100;
Y_Bot = 100;
Width = 400;
Height = 300;
WinSetWindowPos(hwndFrame, HWND_TOP, X_Left, Y_Bot, Width, Height,
SWP_SIZE | SWP_MOVE | SWP_SHOW | SWP_ACTIVATE);
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
WinSetWindowPos(hwndFrame, HWND_BOTTOM, X_Left, Y_Bot, Width, Height,
SWP_SIZE | SWP_MOVE | SWP_SHOW | SWP_ZORDER);
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
swp.x = 100; /*----------------------------*/
swp.y = 100; /* Set restored size/position */
swp.cx = 200; /*----------------------------*/
swp.cy = 200;
WinSetWindowPos(hwndFrame, HWND_TOP, swp.x, swp.y, swp.cx, swp.cy,
SWP_SIZE | SWP_MOVE | SWP_SHOW |
SWP_ACTIVATE | SWP_MINIMIZE);
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
swp.x = 100; /*----------------------------*/
swp.y = 100; /* Set restored size/position */
swp.cx = 200; /*----------------------------*/
swp.cy = 200;
WinSetWindowPos(hwndFrame, HWND_TOP, swp.x, swp.y, swp.cx, swp.cy,
SWP_SIZE | SWP_MOVE | SWP_SHOW |
SWP_ACTIVATE | SWP_MAXIMIZE);
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
/*-------------------------------------------------------------*/
/* Declare your subclassed window procedure and pointer to the */
/* default frame window procedure */
/*-------------------------------------------------------------*/
MRESULT EXPENTRY SubFrameProc(HWND, USHORT, MPARAM, MPARAM);
PFNWP OldFrameProc;
/*-------------------------------------------------------------*/
/* Immediately after creating your main window store the */
/* address of the default frame window procedure */
/*-------------------------------------------------------------*/
OldFrameProc = WinSubclassWindow(hwndFrame, (PFNWP)SubFrameProc);
/*-------------------------------------------------------------*/
/* The following example procedure allows your window to be */
/* reduced in size to 25x25 pels. */
/*-------------------------------------------------------------*/
MRESULT EXPENTRY SubFrameProc(HWND hwnd,
USHORT msg,
MPARAM mp1,
MPARAM mp2)
{
PTRACKINFO ptrack;
switch(msg)
{
case WM_QUERYTRACKINFO:
/*----------------------------------------------------------*/
/* Invoke the default frame window procedure first in order */
/* to update the tracking rectangle to the new position. */
/*----------------------------------------------------------*/
OldFrameProc(hwnd, msg, mp1, mp2);
ptrack = (PTRACKINFO)mp2;
ptrack->ptlMinTrackSize.x = 25;
ptrack->ptlMinTrackSize.y = 25;
return((MRESULT)TRUE);
break;
default:
return(OldFrameProc(hwnd, msg, mp1, mp2));
break;
}
return((MRESULT)NULL);
}
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
ScrWidth = WinQuerySysValue(HWND_DESKTOP, SV_CXSCREEN);
ScrHeight = WinQuerySysValue(HWND_DESKTOP, SV_CYSCREEN);
WinSetWindowPos(hwndFrame, HWND_TOP,
0, 0, (SHORT)ScrWidth, (SHORT)ScrHeight,
SWP_SIZE | SWP_MOVE | SWP_SHOW | SWP_ACTIVATE);
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
/*----------------------------------*/
/* To start a 500 millisecond timer */
/*----------------------------------*/
WinStartTimer(hab, hwndClient, TimerID, 500);
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
WinStopTimer(hab, hwndClient, TimerID);
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
case WM_TIMER:
hwndFrame = WinQueryWindow(hwnd, QW_PARENT, FALSE);
WinSetWindowPos(hwndFrame, HWND_TOP, 0, 0, 0, 0, SWP_ZORDER);
break;
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
case WM_CREATE:
;
;
/*-------------------*/
/* Make system modal */
/*-------------------*/
hFrame = WinQueryWindow(hwnd, QW_PARENT, FALSE);
WinSetSysModalWindow(HWND_DESKTOP, hFrame);
break;
case WM_xxx:
/*------------------------*/
/* Remove system modality */
/*------------------------*/
WinSetSysModalWindow(HWND_DESKTOP, NULL);
break;
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
#define INCL_WIN
#include <os2.h>
#include <string.h>
#include <stdlib.h>
#include "hints.h"
PFNWP OldFrameProc;
MRESULT EXPENTRY MainWndProc (HWND, USHORT, MPARAM, MPARAM);
MRESULT EXPENTRY ChildWndProc (HWND, USHORT, MPARAM, MPARAM);
MRESULT EXPENTRY NewFrame (HWND, USHORT, MPARAM, MPARAM);
/****************************************************************************/
VOID cdecl main (void)
{
HAB hab;
HMQ hmq;
static HWND hwndEntry,
hwndClient,
hwndChild,
hwndFrame,
hwndChildFrame;
QMSG qmsg;
ULONG flFrameFlags,
flCFrameFlags,
DataLength;
CHAR Title[80],
CTitle[80];
SWCNTRL PgmEntry;
SWP swp;
/****************************************************************************/
hab = WinInitialize(0);
hmq = WinCreateMsgQueue(hab, 0);
WinRegisterClass(hab,
"Hints",
MainWndProc,
CS_SIZEREDRAW,
0);
WinRegisterClass(hab,
"Hints2",
ChildWndProc,
CS_SIZEREDRAW,
0);
WinLoadString( hab, NULL, ID_TITLE, sizeof(Title), Title );
WinLoadString( hab, NULL, ID_CTITLE, sizeof(CTitle), CTitle );
flCFrameFlags = FCF_TITLEBAR | FCF_SYSMENU | FCF_NOBYTEALIGN |
FCF_SIZEBORDER | FCF_MINMAX;
flFrameFlags = FCF_TITLEBAR | FCF_SYSMENU | FCF_MENU |
FCF_SIZEBORDER | FCF_MINMAX | FCF_ACCELTABLE |
FCF_NOBYTEALIGN;
hwndFrame = WinCreateStdWindow(HWND_DESKTOP,
0L,
&flFrameFlags,
"Hints",
(PSZ)Title,
0L,
NULL,
ID_MAINWND,
&hwndClient);
OldFrameProc = WinSubclassWindow(hwndFrame, (PFNWP)NewFrame);
DataLength = sizeof(swp);
if (!PrfQueryProfileData(HINI_USERPROFILE, "Hints", "Size",
&swp, &DataLength))
{
swp.x = 100;
swp.y = 100;
swp.cx = 200;
swp.cy = 200;
/*-------------------------------------------------------------*/
/* For full screen - */
/* */
/* swp.cx = WinQuerySysValue(HWND_DESKTOP, SV_CXSCREEN); */
/* swp.cy = WinQuerySysValue(HWND_DESKTOP, SV_CYSCREEN); */
/*-------------------------------------------------------------*/
}
WinSetWindowPos(hwndFrame, HWND_TOP, swp.x, swp.y, swp.cx, swp.cy,
SWP_SIZE | SWP_MOVE | SWP_SHOW | SWP_ACTIVATE);
hwndChildFrame = WinCreateStdWindow(HWND_DESKTOP,
0L,
&flCFrameFlags,
"Hints2",
(PSZ)CTitle,
0L,
NULL,
0,
&hwndChild);
WinSetOwner(hwndChildFrame, hwndFrame);
WinSetWindowPos(hwndChildFrame, HWND_TOP, 350, 100, 200, 200,
SWP_SIZE | SWP_MOVE | SWP_SHOW | SWP_ACTIVATE);
PgmEntry.hwnd = hwndFrame;
PgmEntry.hwndIcon = NULL;
PgmEntry.hprog = NULL;
PgmEntry.idProcess = NULL;
PgmEntry.idSession = NULL;
PgmEntry.uchVisibility = SWL_VISIBLE;
PgmEntry.fbJump = SWL_JUMPABLE;
strcpy(PgmEntry.szSwtitle, Title);
hwndEntry = WinAddSwitchEntry(&PgmEntry);
WinStartTimer( hab, hwndClient, 1, 500 );
WinSendMsg(hwndFrame, WM_SETICON,
WinQuerySysPointer(HWND_DESKTOP, SPTR_APPICON, FALSE), NULL);
WinSendMsg(hwndChildFrame, WM_SETICON,
WinQuerySysPointer(HWND_DESKTOP, SPTR_APPICON, FALSE), NULL);
while(WinGetMsg(hab, &qmsg, NULL, 0, 0))
WinDispatchMsg(hab, &qmsg);
WinStopTimer( hab, hwndClient, 1);
WinDestroyWindow(hwndFrame);
WinRemoveSwitchEntry(hwndEntry);
WinDestroyMsgQueue(hmq);
WinTerminate(hab);
}
/****************************************************************************/
MRESULT EXPENTRY MainWndProc (HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2)
{
RECTL rc;
SWP swp;
HPS hps;
HWND hwndActiveWin,
hwndFrame;
PID pid;
TID tid;
CHAR szText[20],
szPid[6];
switch (msg)
{
case WM_PAINT:
hwndActiveWin = WinQueryActiveWindow(HWND_DESKTOP, FALSE);
WinQueryWindowProcess(hwndActiveWin, &pid, &tid);
strcpy(szText, "Process ID = ");
strcat(szText, itoa(pid, szPid, 10));
WinQueryWindowRect(hwnd, &rc);
/*------------------------------------------------------------------*/
/* WinMapWindowPoints(hwnd, WinQueryWindow(hwnd, QW_PARENT, FALSE), */
/* (PPOINTL)&rc, 2); */
/*------------------------------------------------------------------*/
hps = WinBeginPaint(hwnd, NULL, &rc);
WinDrawText (hps, strlen(szText), szText, &rc, SYSCLR_WINDOWTEXT,
SYSCLR_WINDOW, DT_LEFT | DT_ERASERECT);
WinEndPaint(hps);
break;
case WM_TIMER:
hwndFrame = WinQueryWindow(hwnd, QW_PARENT, FALSE);
WinSetWindowPos(hwndFrame, HWND_TOP, 0, 0, 0, 0, SWP_ZORDER);
WinInvalidateRect(hwnd, NULL, TRUE); /* Cause PID to be displayed */
break;
case WM_BUTTON1DOWN:
hwndFrame = WinQueryWindow(hwnd, QW_PARENT, FALSE);
WinSetWindowText(hwndFrame, "Hints - Size and Position Fixed");
WinEnableWindow (WinWindowFromID (hwndFrame, FID_TITLEBAR), FALSE);
WinEnableWindow (WinWindowFromID (hwndFrame, FID_MINMAX), FALSE);
WinSetWindowBits(hwndFrame, QWL_STYLE,
(~FS_SIZEBORDER | FS_DLGBORDER),
( FS_SIZEBORDER | FS_DLGBORDER));
/*-----------------------------------------------------------------*/
/* WinSetWindowULong(hwndFrame, QWL_STYLE, */
/* (WinQueryWindowULong(hwndFrame, QWL_STYLE) & */
/* ~FS_SIZEBORDER | FS_DLGBORDER)); */
/*-----------------------------------------------------------------*/
WinInvalidateRect(hwndFrame, NULL, TRUE);
break;
case WM_BUTTON2DOWN:
hwndFrame = WinQueryWindow(hwnd, QW_PARENT, FALSE);
WinSetWindowText(hwndFrame, "Hints");
WinEnableWindow (WinWindowFromID (hwndFrame, FID_TITLEBAR), TRUE);
WinEnableWindow (WinWindowFromID (hwndFrame, FID_MINMAX), TRUE);
WinSetWindowBits(hwndFrame, QWL_STYLE,
(FS_SIZEBORDER | ~FS_DLGBORDER),
(FS_SIZEBORDER | FS_DLGBORDER));
/*-----------------------------------------------------------------*/
/* WinSetWindowULong(hwndFrame, QWL_STYLE, */
/* (WinQueryWindowULong(hwndFrame, QWL_STYLE) & */
/* ~FS_DLGBORDER | FS_SIZEBORDER)); */
/*-----------------------------------------------------------------*/
WinInvalidateRect(hwndFrame, NULL, TRUE);
break;
case WM_MINMAXFRAME:
hwndFrame = WinQueryWindow(hwnd, QW_PARENT, FALSE);
if (((PSWP)mp1)->fs & SWP_MINIMIZE)
{
DosBeep(100, 100);
}
else
if (((PSWP)mp1)->fs & SWP_MAXIMIZE)
{
DosBeep(1000, 100);
}
else
if (((PSWP)mp1)->fs & SWP_RESTORE)
{
DosBeep(500, 100);
}
WinSetWindowUShort(hwndFrame, QWS_XRESTORE, 100);
WinSetWindowUShort(hwndFrame, QWS_YRESTORE, 100);
WinSetWindowUShort(hwndFrame, QWS_CXRESTORE, 200);
WinSetWindowUShort(hwndFrame, QWS_CYRESTORE, 200);
break;
case WM_SAVEAPPLICATION:
WinQueryWindowPos(WinQueryWindow(hwnd, QW_PARENT, FALSE), &swp);
PrfWriteProfileData(HINI_USERPROFILE, "Hints", "Size",
&swp, (ULONG)sizeof(swp));
return NULL;
case WM_COMMAND:
switch (SHORT1FROMMP(mp1))
{
case MI_MIN:
hwndFrame = WinQueryWindow(hwnd, QW_PARENT, FALSE);
WinSetWindowPos(hwndFrame, NULL, 0, 0, 0, 0, SWP_MINIMIZE);
break;
case MI_EXIT:
WinPostMsg(hwnd, WM_QUIT, 0L, 0L);
break;
}
case WM_ERASEBACKGROUND:
return (MRESULT)TRUE;
}
return WinDefWindowProc(hwnd, msg, mp1, mp2);
}
/****************************************************************************/
MRESULT EXPENTRY NewFrame(HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2)
{
PTRACKINFO ptrack;
switch(msg)
{
case WM_QUERYTRACKINFO:
/*----------------------------------------------------------*/
/* Invoke the default frame window procedure first in order */
/* to update the tracking rectangle to the new position. */
/*----------------------------------------------------------*/
OldFrameProc(hwnd, msg, mp1, mp2);
ptrack = (PTRACKINFO)mp2;
ptrack->ptlMinTrackSize.x = 25;
ptrack->ptlMinTrackSize.y = 25;
return((MRESULT)TRUE);
break;
default:
return(OldFrameProc(hwnd, msg, mp1, mp2));
break;
}
return((MRESULT)NULL);
}
/****************************************************************************/
MRESULT EXPENTRY ChildWndProc (HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2)
{
RECTL rc;
HPS hps;
CHAR szText[22];
HWND hwndChildFrame;
switch(msg)
{
case WM_PAINT:
strcpy(szText, "I am a child of Hints");
WinQueryWindowRect(hwnd, &rc);
hps = WinBeginPaint(hwnd, NULL, &rc);
WinDrawText (hps, strlen(szText), szText, &rc, SYSCLR_WINDOWTEXT,
SYSCLR_WINDOW, DT_LEFT | DT_ERASERECT);
WinEndPaint(hps);
break;
case WM_ERASEBACKGROUND:
return (MRESULT)TRUE;
case WM_CLOSE:
hwndChildFrame = WinQueryWindow(hwnd, QW_PARENT, FALSE);
WinDestroyWindow(hwndChildFrame);
break;
}
return WinDefWindowProc(hwnd, msg, mp1, mp2);
}
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
#define ID_MAINWND 200
#define ID_CHILDWND 201
#define ID_TITLE 202
#define ID_CTITLE 203
#define MI_EXIT 100
#define MI_RESUME 101
#define MI_MIN 102
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
hints +
/A:16 /CO
hints.exe
hints.map /NOD
llibce.lib+
os2.lib
hints.def
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
NAME Hints WINDOWAPI
DESCRIPTION 'Test program for OS/2 Hints and Tips'
STUB 'OS2STUB.EXE'
DATA MULTIPLE
HEAPSIZE 8192
STACKSIZE 8192
PROTMODE
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
#include <os2.h>
#include "hints.h"
STRINGTABLE PRELOAD
BEGIN
ID_TITLE, "Hints"
ID_CTITLE, "Child Window of Hints"
END
ACCELTABLE ID_MAINWND
BEGIN
VK_F3, MI_EXIT, VIRTUALKEY
END
MENU ID_MAINWND PRELOAD
BEGIN
MENUITEM "~Minimize", MI_MIN, MIS_TEXT
SUBMENU "E~xit", 1
BEGIN
MENUITEM "~Exit Program\tF3", MI_EXIT, MIS_TEXT
MENUITEM "~Resume Program", MI_RESUME, MIS_TEXT
END
END
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
hints.exe: hints.obj \
hints.def hints.res
link @hints.l
rc hints.res
hints.obj: hints.c hints.h
cl /c /Alfu /W2 /Gs /Gc /Zi /Od hints.c
hints.res: hints.h hints.rc
rc -r hints.rc