home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Professional
/
OS2PRO194.ISO
/
os2
/
prgramer
/
slider
/
slider.txt
< prev
Wrap
Text File
|
1992-09-08
|
36KB
|
905 lines
Column Name: Advanced PM Programming
Column Title: Using Sliders
by: Guy Scharf
(c) Copyright 1992 Software Architects, Inc.
Introducing Sliders
OS/2 2.0 introduces four new controls-slider, value set,
notebook, and container. We'll look this month at the
slider.
The slider is best used for setting values that are more
analog than digital in nature. Visually, the slider is
represented as a bar with a handle that can be moved to any
location along the bar. The user can grab the handle and
move it to the desired location. The slider can have detents
that allow the user to set the slider to preselected values
with a single click of the mouse. Optional buttons can be
used to move the slider bar one increment at a time.
Used for output, the slider control also makes an excellent
progress or percentage complete bar. Our example
program shows sliders used for input and as a progress bar.
CUA Controls Library/2
IBM has not forgotten OS/2 1.3 developers. IBM's CUA
Controls Library/2 product makes all of the OS/2 2.0
controls as well as the standard font selection and file open
dialogs available to both OS/2 1.3 and Windows
developers.
This product provides OS/2 1.3 with the same API as with
OS/2 2.0. Converting a program using CUA Library/2
controls to OS/2 2.0 requires making only minor changes:
1) a DosLoadModule call required to register the CUA
Library/2 control is deleted, 2) if the control is defined in
a resource script, the window class name is changed from
CCL_SLIDER to WC_SLIDER and 3) a #include statement
required for CUA Library/2 is deleted. These are all the
changes that are required, and selective use of #ifdef and
#define can take care of most of these changes. Messages
sent to or received from the control remain unchanged.
The sample code in this article has been compiled using
both OS/2 1.3 and OS/2 2.0 with just these changes.
Converting from OS/2 1.3 to 2.0
Before examining the slider, let's look at some issues
involved in developing applications for both OS/2 1.3 and
OS/2 2.0. A reader asks why the subclassing example of
the column in the first issue does not work under OS/2 2.0.
Two minor changes are required to make that example
work. These are typical of the changes required when
converting to OS/2 2.0.
First, the length of the message-number parameter in
messages sent to windows must be changed from a
USHORT to a ULONG. In many OS/2 2.0 functions,
parameters that were USHORTs in OS/2 1.3 have been
changed to ULONGs. If you use the header files supplied
with the toolkit, most of these changes should be nearly
transparent. If you have typed your own prototypes of
OS/2 functions, you will probably need to update them.
I now define a MSGID type in my programs, and
conditionally compile MSGID as a USHORT or a ULONG
as appropriate for the target operating system.
The second change is caused by a change in the
WinRegisterClass API. In OS/2 1.3, this API was
documented as requiring the existence of a message queue,
but it does not. In OS/2 2.0, this API is not documented
as requiring existence of a message queue, but it does! To
fix SUBCLASS.C for OS/2 2.0, move the call to the class
registering function to follow the creation of the message
queue.
Slider Basics
A slider can be used as an input control device or as a
read-only display device. While the latter is simply a
variation on the input device, it is visually distinctive.
Figures 1 and 2 demonstrate these two appearances.
The most visible component of a slider is the slider shaft.
The width of the shaft can be varied, which is especially
useful in displaying progress bars. The shaft can be
arranged horizontally or vertically. The slider arm defines
the position of the control along a scale of increments. In
an input control, this arm is represented by a handle that
the user can grab and drag. On an output control, the arm
is a vertical line, usually with a different color, called a
ribbon strip, on each side.
The bottom of the slider can be at either the left or right
(top or bottom) of the control. Labels, tick marks of
various sizes, and detents can be placed above or below the
shaft.
If the user clicks on the slider to either side of the slider
arm, the arm is moved one increment in that direction.
Holding the mouse button down does not cause further
movement. Optional slider buttons at either end of the
slider cause a single movement if clicked once, and
continuing movement if the mouse button is held down.
A detent allows a user to move the slider arm to a
prespecified value by clicking on the detent with the mouse
button.
Creating a Slider
As with most controls, you can create a control window
using WinCreateWindow or you can define the control in a
resource script. However, unlike older controls, slider
control windows require that some control data be supplied
at the time the control is created. The SLDCDATA
structure defines the required data:
typedef struct _SLDCDATA {
ULONG cbSize; // Size of control data
USHORT usScale1Increments; // # of divisions
USHORT usScale1Spacing; // Space in pels
USHORT usScale2Increments; // # of divisions
USHORT usScale2Spacing; // Space in pels
} SLDCDATA;
The control data specifies the length of the slider, in
arbitrary units called increments, and the distance between
each increment, in pixels for two scales. Scale 1, if used,
appears above or to the left of the slider; scale 2, below or
to the right. Since calculating distances in pixels is a
nuisance, the control will calculate it for you if the distance
value is given as 0. If the SLDCDATA structure is not
provided, the slider is not created. When defining a slider
in a resource script, the CTLDATA statement can be used
to create the required data structure.
After creating the basic slider control, the developer sends
messages to the control to establish the size and placement
of tick marks, text above one or more tick marks, detents,
and the slider arm position. You can also change the
dimensions of the slider and modify other appearances of
the control. An owner-draw style is available, so that you
can draw the control yourself.
You retrieve information from the slider by sending
messages to it. Some messages return values in
increments; others, in pixels. Some messages offer you a
choice.
Sliders in Dialog Resource Scripts
In our example, we have two sliders. The first allows the
user to choose a value of 0 to 90 seconds. Having chosen
that value using the slider, the user presses the OK button
and a progress bar is displayed for that number of seconds.
The progress bar advances evenly over the number of
seconds requested.
Let's look first at the resource script, SLIDER.RC in our
example. Both sliders are horizontally arranged with
SLS_HORIZONTAL. On the time-setting slider,
SLS_PRIMARYSCALE1 says that we are going to write our
tick marks and text above the slider shaft. To make more
room for this text in the control area, we move the slider
shaft to the bottom of the control window with
SLS_BOTTOM. We define 0 as being at the left end of the
slider with SLS_HOMELEFT. We then request buttons at
the right end of the control with SLS_BUTTONSRIGHT.
The CTLDATA statement defines the SLDCDATA structure.
The CTLDATA statement is followed by a series of numeric
parameters. These parameters are each converted by the
resource compiler into a USHORT. The complete string of
USHORTs constitutes the data structure used by the dialog
when creating the slider control window. Since the first
element of the SLDCDATA structure is a ULONG giving
the total size of the structure, we must compose that
ULONG with two USHORTs. The total length of the data
structure is 12 bytes. Since Intel architecture places the
least significant digits in the high-order bytes, we define a
ULONG with a value of 12 as two USHORTs with values
of 12 and 0. We define this slider as having 91
increments, allowing us to represent values from 0 through
90. We set the pixel spacing of the increments to 0, to
allow the dialog to compute the largest spacing that will fit
within the bounds of the control. We need to define only
the scale that we are going to use; any definition we
provide for the other scale is ignored.
Our definition for the progress bar is similar. We put the
slider in the center of the control window with
SLS_CENTER. We make it a read-only control, and thus
having a vertical line instead of a handle as the slider arm,
with SLS_READONLY. We put the text below the slider by
specifying SLS_PRIMARYSCALE2. Finally, we ask that the
slider have a different color on each side of the slider arm,
making the appearance that of a horizontal bar. This is
called a ribbon strip and we request it with the
SLS_RIBBONSTRIP style.
We define CTLDATA for this slider similarly. The 101
increments allow values of 0 through 100.
Initializing the Slider
Sliders require more setup than older controls. In the
example, the setup code is isolated in the InitSlider()
function. We call this function during WM_INITDLG
processing to initialize each slider.
As the first step, we obtain the increments and spacing
values from the original CTLDATA structure (or as
calculated by the control). Most of the messages we will
be sending the slider control will use increments. Detents,
however, are set in terms of pixels, as they are not required
to be aligned with an increment. Since our initialization
function is a general utility, we obtain this information
from the control rather than hard coding it or having it
passed in by the caller. We use
WM_QUERYWINDOWPARAMS to obtain this control data.
Alternatively, we could have used the
SLM_QUERYSLIDERINFO message to obtain most of the
information we need. This message returns four types of
dimension information, either as increments or as pixel
dimensions. This message is used frequently when
programming sliders.
If the caller wants the slider shaft to be larger, we change
its dimensions using SLM_SETSLIDERINFO. Again, this
is a message that can set many values. In our example, we
increase the width when using the slider as a progress bar.
Ticks are set at specific increments. (An increment is an
arbitrary unit between 0 and the maximum specified in the
CTLDATA statement.) The programmer controls tick sizes.
In this example, we use two tick sizes, which we refer to
as major and minor tick marks. Detents are set similarly.
Our utility can set tick marks only on a linear scale. You
can set tick marks at any increment values, or at none. We
set no tick marks for the progress bar, as the absolute value
is of little interest.
Text can also be set at increments. While any text string
can be set, we use numbers corresponding to the increment
value.
Looking at the Sample Program
The sample program is relatively simple-the slider control
is easy to program and to use. The main program simply
starts a dialog to obtain a time interval between 0 and 90
seconds. When the user presses OK, that dialog starts a
second dialog to count down that number of seconds the
user specified. The dialogs then return to the main
program, which then terminates. This demo program does
not have a standard window.
The GetAmountDlgProc() dialog procedure is the dialog
procedure for the IDLG_SETTIME dialog. It initializes the
slider during WM_INITDLG processing and waits for the
user to press the OK or Cancel button. When the user
presses OK, the dialog reads the number of seconds set on
the slider control and starts the progress display dialog,
passing the number of seconds requested.
The ProgressDlgProc() dialog procedure is the dialog
procedure for the IDLG_PROGRESS dialog. It initializes
its slider, using different parameters more appropriate to a
progress bar. It then sets up a repetitive timer using
WinStartTimer(). Each time the timer sends a WM_TIMER
message, the dialog computes the percentage complete and
updates the slider if the percentage has changed.
The frequency of the timer is controlled by the
TIMERINTERVAL #define statement. We have defined the
slider as having 100 increments, so the movement of the
slider will never be finer than 1/100 of the total distance.
If the duration is large, then very frequent timer messages
are wasteful, as the percentage complete will not change
with each message. However, if the timer intervals are
large, then the progress bar does not move smoothly when
the number of seconds is small. Picking a good frequency
for the timer depends on the use planned for the slider.
We used a rate of four per second in this example.
In a real application, you could use a progress bar like this
to report the status of some time-consuming task. That task
could send periodic updates to the dialog, which would then
update the progress bar to reflect the progress of the task.
Or, you could use a WM_TIMER message to poll the state
of a task and update the progress bar appropriate. We have
used both approaches, depending on whether the task knew
how to send messages or whether it could only update a
counter.
Summary
Sliders are very useful for obtaining or displaying analog
values. They excel when a bar representation fits the
experience of the user. Sliders also make great progress
bars or percentage complete displays.
The programs in this article are available on the OS2DEV
forum on CompuServe. GO OS2DEV and download file
SLIDER.ZIP from library 4, Ver 2.0.
------------------------
Guy Scharf is president of Software Architects, Inc., 2163
Jardin Drive, Mountain View, CA 94040. Software
Architects, Inc. specializes in OS/2 Presentation Manager
software development and consulting. Guy can be reached
on the CompuServe OS2DEV forum or on CompuServe
Mail at 76702,557 or through Internet at
76702.557@compuserve.com.
LISTING 1. SLIDER.C
====================
// slider.c -- Sample program to demonstrate slider
//--------------------------------------------------------------
// slider.c
//
// Sample program to demonstrate sliders.
//
// By: Guy Scharf (415) 948-9186
// Software Architects, Inc. FAX: (415) 948-1620
// 2163 Jardin Drive
// Mountain View, CA 94040
// CompuServe: 76702,557
// Internet: 76702.557@compuserve.com
// (c) Copyright 1992 Software Architects, Inc.
//
// All Rights Reserved.
//
// Software Architects, Inc. develops software products for
// independent software vendors using OS/2 and Presentation
// Manager.
//--------------------------------------------------------------
#define INCL_PM // Basic OS/2 PM
#define INCL_BASE // components
#include <OS2.H>
#include <stdlib.h> // C runtime library
#include <string.h>
#include "slider.h" // Slider demo defs
// Prototypes of dialog procedures
static MRESULT EXPENTRY GetAmountDlgProc (HWND, MSGID, MPARAM,
MPARAM);
static MRESULT EXPENTRY ProgressDlgProc (HWND, MSGID, MPARAM,
MPARAM);
//--------------------------------------------------------------
//
// Main program to drive slider example
//
//--------------------------------------------------------------
int main (void)
{
HAB hab; // Handle to anchor block
HMQ hmqMsgQueue; // Handle to msg queue
#ifndef OS220
HMODULE hmodSlider; // Handle to slider mod
#endif
hab = WinInitialize (0); // Initialize PM
hmqMsgQueue = WinCreateMsgQueue (hab, 0); // Create msg queue
#ifndef OS220
if (DosLoadModule (NULL, 0, CCL_SLIDER_DLL, &hmodSlider))
return FALSE;
#endif
WinDlgBox (HWND_DESKTOP, HWND_DESKTOP, GetAmountDlgProc, 0,
IDLG_SETTIME, NULL);
#ifndef OS220
DosFreeModule (hmodSlider);
#endif
WinDestroyMsgQueue (hmqMsgQueue); // Shutdown
WinTerminate (hab);
return 0;
}
//--------------------------------------------------------------
//
// GetAmountDlgProc() -- Determine time delay desired
//
//--------------------------------------------------------------
static MRESULT EXPENTRY GetAmountDlgProc (
HWND hwndDlg,
MSGID msg,
MPARAM mp1,
MPARAM mp2)
{
USHORT usTime; // Time for progress
switch(msg)
{
//------------------------------------------------------
// Initialize dialog by setting labels, ticks, detents,
// etc. This must all be done programmatically.
//------------------------------------------------------
case WM_INITDLG:
//--------------------------------------------------
// Set the marks, detents, and labels
// Set small tick marks every 1 second
// Set large tick marks every 10 seconds
// Set detent every 15 seconds
//--------------------------------------------------
InitSlider (hwndDlg, IDSL_SETTIME_TIME, 0,
1, 4,
10, 8,
30, 30,
"8.Courier");
return 0;
//------------------------------------------------------
// Process pushbuttons. Enter starts a progress bar.
// Cancel (ESC) just quits quietly.
//------------------------------------------------------
case WM_COMMAND:
switch (SHORT1FROMMP(mp1))
{
// Cancel pressed
// Dismiss dialog
case DID_CANCEL:
WinDismissDlg (hwndDlg, FALSE);
return 0;
// OK button pressed
case DID_OK: // Read slider position
// from slider
usTime = SHORT1FROMMR(WinSendDlgItemMsg(
hwndDlg,
IDSL_SETTIME_TIME,
SLM_QUERYSLIDERINFO,
MPFROM2SHORT(SMA_SLIDERARMPOSITION,
SMA_INCREMENTVALUE),
0));
// Start progress bar
// dialog
if (usTime > 0)
WinDlgBox (HWND_DESKTOP, HWND_DESKTOP,
ProgressDlgProc, 0,
IDLG_PROGRESS, &usTime);
return 0;
}
return 0;
//------------------------------------------------------
// All other messages go to default window procedure
//------------------------------------------------------
default:
return (WinDefDlgProc (hwndDlg, msg, mp1, mp2));
}
return FALSE;
}
//--------------------------------------------------------------
//
// ProgressDlgProc() -- Show progress bar. This is a minimal
// function dialog. It just moves the progress bar along
// without reflecting any particular activity.
//
//--------------------------------------------------------------
typedef struct
{
USHORT usTotalUnits; // # units to count
USHORT usUnitsSoFar; // count so far
USHORT usPctDone; // Last reported % done
} PROG, *PPROG;
#define TIMERINTERVAL 4 // Timer checks per sec
static MRESULT EXPENTRY ProgressDlgProc (
HWND hwndDlg,
MSGID msg,
MPARAM mp1,
MPARAM mp2)
{
PPROG pprog; // Progress data
switch(msg)
{
//------------------------------------------------------
// Initialize dialog by constructing a work area and
// establishing a pointer to it in the dialog window
// word. Set initial values to 0 and compute the
// number of ticks desired from the passed value
// (which is in seconds)
//------------------------------------------------------
case WM_INITDLG: // Initialize data
pprog = malloc (sizeof (PROG));
WinSetWindowPtr (hwndDlg, QWL_USER, pprog);
pprog->usUnitsSoFar = 0; // Ticks so far
pprog->usPctDone = 0; // Start at 0
pprog->usTotalUnits = (USHORT)(*(PUSHORT)mp2
* TIMERINTERVAL);
//--------------------------------------------------
// Set 2x wide slider,
// No small tick
// No large ticks
// No detents
// 0, 50, 100% complete
//--------------------------------------------------
InitSlider (hwndDlg, IDSL_PROGRESS_BAR, 2,
0, 4,
0, 8,
0, 50,
NULL);
//--------------------------------------------------
// Start the timer for periodic display
//--------------------------------------------------
WinStartTimer (WinQueryAnchorBlock (hwndDlg),
hwndDlg, ID_TIMER,
1000/TIMERINTERVAL);
return 0;
//------------------------------------------------------
// When dialog is destroyed, we release any data
// we have allocated. This prevents memory leakage.
//------------------------------------------------------
case WM_DESTROY:
pprog = WinQueryWindowPtr (hwndDlg, QWL_USER);
// Stop the timer
WinStopTimer (WinQueryAnchorBlock (hwndDlg),
hwndDlg, ID_TIMER);
if (pprog != NULL) // If data exists,
free (pprog); // free it
WinSetWindowPtr (hwndDlg, QWL_USER, NULL);
return 0;
//------------------------------------------------------
// We support only a Cancel pushbutton
//------------------------------------------------------
case WM_COMMAND:
switch (SHORT1FROMMP(mp1))
{ // Cancel key pressed
case DID_CANCEL: // Just quit quietly
WinDismissDlg (hwndDlg, FALSE);
return 0;
}
return 0;
//------------------------------------------------------
// On every timer tick, we computer the percent
// complete. If different than on the last timer
// click, we update the progress bar.
//------------------------------------------------------
case WM_TIMER:
{
USHORT usNewPctDone = 0; // Percent complete
// Get ptr to dialog data
pprog = WinQueryWindowPtr (hwndDlg, QWL_USER);
// Compute % complete
// and update the slider
pprog->usUnitsSoFar++;
// Don't allow over 100
usNewPctDone = (USHORT)min((100*pprog->usUnitsSoFar)
/ pprog->usTotalUnits, 100);
// If % done is changed,
// update slider
if (usNewPctDone != pprog->usPctDone)
{
pprog->usPctDone = usNewPctDone;
WinSendDlgItemMsg (hwndDlg, IDSL_PROGRESS_BAR,
SLM_SETSLIDERINFO,
MPFROM2SHORT (SMA_SLIDERARMPOSITION,
SMA_INCREMENTVALUE),
MPFROMSHORT (usNewPctDone));
}
// If all done, quit
if (pprog->usUnitsSoFar > pprog->usTotalUnits)
WinSendMsg (hwndDlg, WM_CLOSE, 0, 0);
return 0;
}
//------------------------------------------------------
// All other messages go to default window procedure
//------------------------------------------------------
default:
return (WinDefDlgProc (hwndDlg, msg, mp1, mp2));
}
return FALSE;
}
//--------------------------------------------------------------
// Function: InitSlider
// Outputs: none
//
// This function receives all parameters for configuring a
// slider. It sets tick marks, tick text, and detents
// according to the input parameters. The scale text font is
// changed if requested. This function works only on scale 1.
//--------------------------------------------------------------
VOID InitSlider ( // Initialize slider
HWND hwndDlg, // Handle of dialog
ULONG idSlider, // ID of slider control
USHORT usSizeMultiplier, // Size multiplier
USHORT usMinorTickSpacing, // Minor tick spacing
USHORT usMinorTickSize, // Size of minor ticks
USHORT usMajorTickSpacing, // Major tick spacing
USHORT usMajorTickSize, // Size of major ticks
USHORT usDetentSpacing, // Detent spacing
USHORT usTextSpacing, // Text label spacing
PSZ pszFont) // Font for text or NULL
{
USHORT i; // Loop index
CHAR buffer[20]; // String buffer
USHORT usIncrements = 0; // Number of increments
USHORT usSpacing = 0; // Spacing
WNDPARAMS wprm; // Window parameters ct;
SLDCDATA sldcd; // Slider control data
HWND hwndSlider = WinWindowFromID (hwndDlg, idSlider);
//----------------------------------------------------------
// Get original slider dimensions in increments for future
// calls. (My thanks to Wayne Kovsky for this example of
// using WM_QUERYWINDOWPARAMS.)
//----------------------------------------------------------
wprm.fsStatus = WPM_CTLDATA; // Request control data
wprm.cbCtlData = sizeof (SLDCDATA);
wprm.pCtlData = &sldcd;
if (WinSendMsg (hwndSlider, WM_QUERYWINDOWPARAMS,
MPFROMP(&wprm), 0))
{ // Copy fields we need
usIncrements = sldcd.usScale1Increments;
usSpacing = sldcd.usScale1Spacing;
}
//----------------------------------------------------------
// If requested, change dimensions of the slider
//----------------------------------------------------------
if (usSizeMultiplier > 1)
{
MRESULT mr;
mr = WinSendMsg (hwndSlider,
SLM_QUERYSLIDERINFO,
MPFROMSHORT(SMA_SHAFTDIMENSIONS), 0);
WinSendMsg (hwndSlider,
SLM_SETSLIDERINFO,
MPFROMSHORT(SMA_SHAFTDIMENSIONS),
MPFROMSHORT (SHORT2FROMMR(mr) *
usSizeMultiplier));
}
//----------------------------------------------------------
// If requested, set minor ticks along axis
//----------------------------------------------------------
if (usMinorTickSpacing != 0)
for (i = 0; i <= usIncrements; i += usMinorTickSpacing)
{
WinSendMsg (hwndSlider, // Set minor tick
SLM_SETTICKSIZE,
MPFROM2SHORT(i, usMinorTickSize),
NULL);
}
//----------------------------------------------------------
// If requested, set major ticks along axis
//----------------------------------------------------------
if (usMajorTickSpacing != 0)
for (i = 0; i <= usIncrements; i += usMajorTickSpacing)
{
WinSendMsg (hwndSlider, // Set major tick
SLM_SETTICKSIZE,
MPFROM2SHORT(i, usMajorTickSize),
NULL);
}
//----------------------------------------------------------
// If requested, set detents
//----------------------------------------------------------
if (usDetentSpacing != 0)
for (i = 0; i <= usIncrements; i += usDetentSpacing)
{
WinSendMsg (hwndSlider, // Set the detent
SLM_ADDDETENT,
MPFROM2SHORT((i*usSpacing), usDetentSpacing),
NULL);
}
//----------------------------------------------------------
// If requested, set text labels. Also change font if
// requested
//----------------------------------------------------------
if (usTextSpacing != 0)
{
if (pszFont != NULL)
WinSetPresParam (hwndSlider,
PP_FONTNAMESIZE,
(strlen(pszFont)+1),
pszFont);
for (i = 0; i <= usIncrements; i += usTextSpacing)
{
itoa (i, buffer, 10); // Convert to string
WinSendMsg (hwndSlider, // Place in slider scale
SLM_SETSCALETEXT,
MPFROMSHORT(i),
MPFROMP(buffer));
}
}
return;
}
LISTING 2. SLIDER.H
====================
// slider.h -- Definitions for slider demo
//--------------------------------------------------------------
// Change the following as required for target system
//--------------------------------------------------------------
#define OS220 // Define target system
#ifdef OS220
#define MSGID ULONG // OS/2 2.0
#else
#define MSGID USHORT // OS/2 1.3
#include <fclsldp.h> // CUA Library/2
#define WC_SLIDER CCL_SLIDER // Window class
#endif
// Defines for dialogs, controls
#define IDLG_SETTIME 100 // Set time dialog
#define IDSL_SETTIME_TIME 101
#define IDLG_PROGRESS 200 // Progress bar dialog
#define IDSL_PROGRESS_BAR 201
#define ID_TIMER 1 // For WinStartTimer
// Prototypes for useful functions
VOID InitSlider ( // Initialize slider
HWND hwndDlg, // Handle of dialog
ULONG idSlider, // ID of slider control
USHORT usSizeMultiplier, // Size multiplier
USHORT usMinorTickSpacing, // Minor tick spacing
USHORT usMinorTickSize, // Size of minor ticks
USHORT usMajorTickSpacing, // Major tick spacing
USHORT usMajorTickSize, // Size of major ticks
USHORT usDetentSpacing, // Detent spacing
USHORT usTextSpacing, // Text label spacing
PSZ pszFont); // Font for text or NULL
LISTING 3. SLIDER.RC
=====================
#include <os2.h> // OS/2 definitions
#include "slider.h" // Application defs
DLGTEMPLATE IDLG_SETTIME LOADONCALL MOVEABLE DISCARDABLE
BEGIN
DIALOG "Set Time to Wait", IDLG_SETTIME, 66, 27, 203, 64,
WS_VISIBLE, FCF_SYSMENU | FCF_TITLEBAR
BEGIN
CONTROL "", IDSL_SETTIME_TIME, 15, 33, 173, 25,
WC_SLIDER,
SLS_HORIZONTAL | SLS_BOTTOM |
SLS_SNAPTOINCREMENT | SLS_BUTTONSRIGHT |
SLS_HOMELEFT | SLS_PRIMARYSCALE1 |
WS_GROUP | WS_TABSTOP | WS_VISIBLE
CTLDATA 12, 0, 91, 0, 0, 0
DEFPUSHBUTTON "OK", DID_OK, 33, 10, 48, 14, WS_GROUP
PUSHBUTTON "Cancel", DID_CANCEL, 113, 11, 48, 14,
NOT WS_TABSTOP
END
END
DLGTEMPLATE IDLG_PROGRESS LOADONCALL MOVEABLE DISCARDABLE
BEGIN
DIALOG "Percent Complete", IDLG_PROGRESS, 38, 57, 224, 73,
WS_VISIBLE, FCF_SYSMENU | FCF_TITLEBAR
BEGIN
CONTROL "", IDSL_PROGRESS_BAR, 18, 23, 189, 40,
WC_SLIDER,
SLS_HORIZONTAL | SLS_CENTER | SLS_READONLY
SLS_RIBBONSTRIP | SLS_HOMELEFT |
SLS_PRIMARYSCALE2 |
WS_GROUP | WS_TABSTOP | WS_VISIBLE
CTLDATA 12, 0, 101, 0, 101, 0
PUSHBUTTON "Cancel", DID_CANCEL, 93, 4, 40, 14
END
END
LISTING 4. SLIDER.MAK
======================
# IBM Developer's Workframe/2 Make File Creation run at 14:39:08 on 06/30/92
# Make File Creation run in directory:
# D:\P\MAGAZINE\SLIDER;
.SUFFIXES:
.SUFFIXES: .c .rc
ALL: SLIDER.EXE \
SLIDER.RES
slider.exe: \
SLIDER.OBJ \
SLIDER.RES \
SLIDER.MAK
@REM @<<SLIDER.@0
/A:16 /CO /F /M /ST:16384 /NOL /PM:PM +
SLIDER.OBJ
slider.exe
;
<<
LINK386.EXE @SLIDER.@0
RC SLIDER.RES slider.exe
{.}.rc.res:
RC -r .\$*.RC
{.}.c.obj:
ICC.EXE /Sm /Ss /Kbocgapexr /Ti /W2 /C .\$*.c
!include SLIDER.DEP
LISTING 5. SLIDER.DEP
======================
# IBM Developer's Workframe/2 Make File Creation run at 14:39:08 on 06/30/92
# Make File Creation run in directory:
# D:\P\MAGAZINE\SLIDER;
# Assumed INCLUDE environment variable path:
# C:\TOOLKT20\C\OS2H;
# C:\TOOLKT20\ASM\OS2INC;
# C:\IBMC\INCLUDE;
SLIDER.RES: SLIDER.RC \
# {.;$(INCLUDE)}OS2.H \
{.;$(INCLUDE)}SLIDER.H \
SLIDER.MAK
SLIDER.OBJ: SLIDER.C \
# {$(INCLUDE);}OS2.H \
# {$(INCLUDE);}stdlib.h \
# {$(INCLUDE);}string.h \
# {$(INCLUDE);}fclsldp.h \
{.;$(INCLUDE);}slider.h \
SLIDER.MAK