`
`1
`
`SAMSUNG 1020
`
`
`
`PROGRAMillER'5 WORKBENCH
`
`A Multimedia Class
`
`Library for Windows
`
`Encapsulating the
`.- Media Control Interface
`
`John Musser
`
`
`
`DLLS that come with the Video for Win-
`
`dows package and its SDK. They’re
`available Free of charge from the Win-
`dows Extensions forum on CompuServe
`(G0 WINEXD, Vi‘wrun.zip contains the
`runtime DLLS and vfwdltzip is the Video
`for Windows Development Kit.
`
`added in 1992. Another example is
`Medirtvision, which supplies an MCI
`driver that provides audio-mixing ca-
`pabilities using extended commands
`specific to this device type. The speci-
`fication as documented in the Windows
`SDK identifies 1] device types. Some
`drivers are supplied with either Win-
`MCI Overview
`dows or the SDK. while others are pro-
`vided by the device supplier. Table 1
`The MCI specification, released in 1991
`describes most of the currently available
`by Microsoft and IBM. defines a set of
`MCI drivers. As of this writing, howev-
`base commands that can be applied to
`er. not all the device types listed actu-
`any general device, and extended com-
`ally had MCI drivers available.
`mands for specific device types. The
`into
`MCI
`all multimedia
`specification is designed to be extensi-
`one of two device types: simple or com-
`ble so that other devices may be added.
`For example, the AVI specification was
`pound. The basic difference is that sim-
`_
`_
`_
`.
`.
`--_-
`r.
`= 5..--atom --
`_
`'
`—: .1
`
`MCIAAPDFW
`Ptays Autodeslr Animator
`
`(.llct.tIi) files
`MCIMMP. DFW
`MDK, Visual Basic
`Plays MacroMind Director
`lmrnrn) files
`Controls ootnpact disc audio MC!CDA.DHV
`Controls Digital Audio Tape
`deck
`
`odaudio
`
`dat
`
`Windows 3.1 SDK, MDK
`
`digitalvideo
`other
`
`Plays AVI video files
`An undefined MCI davioe
`
`overlay
`
`Controls a video overlay
`ctevioe—analog video in a
`window
`
`MC|AVl.DRV
`
`Video for Windows
`
`MCJVBLSTDFIV Creative Labs
`
`
`
`scanner
`
`sequencer
`vor
`
`MCJSEQDRV
`
`Retail Windows
`
`
`Controls an image scanner
`Plays MIDI audio files
`Controls a video cassette
`
`
`raoorder
`
`
`Controls the Pioneer
`LD-V4200 videodisc player
`
`
`wavoaudio
`Retail Windows
`Plays and records waveiorm MCIWAVEDFIV
`
`audio files
`
`Table 1: Several Windows MCI devices.
`
`videodisc
`
`MClPlONH.DR\i‘ Windows 3.1 SDK, MDK
`
`Dr. Dobbitjoumal. July .1993"
`
`icrosoft Windows’ Media
`Control Interface (MCI) is a
`standard command language
`for communicating with mul-
`timedia devices—CD, Wave-
`form and MIDI audio. AVI, videodiscs.
`video overlay devices, audio mixers, and
`the like. However, even though both
`Microsoft and Borland provide with their
`compilers large, comprehensive class li-
`braries—Ihe Microsoft Foundation Class
`
`library and ObjectW'indows Library, re-
`spect:ively—-—neither provide object sup-
`port for multimedia or Windows API
`multimedia extensions.
`This article addresses this gap by
`showing how to design and implement
`a comprehensive C++ class library that
`enhances the MCI interface to multi-
`media devices. This hierarchy employs
`encapsulation, inheritance, and poly-
`morphism to create a flexible and ex-
`tensible framework for controlling mul-
`timedia devices under Windows. The
`result is a set of objects that make
`programming multimedia easier, more
`robust, concise, and maintainable. A
`simple client program, MciMan, demon-
`strates the use of the Wavefonn audio
`and AVI video classes. The class library
`and client program are compiler inde-
`pendent and can be used with any Win-
`dows 5.1 compatible C++ compiler, in-
`cluding Borland’s C/C++ and Microsol't’s
`Visual C++. The AV] portions of this
`code require the digitalvh ithtclude file.
`Video for Windows drivers, and ntntime
`
`John is a senior ckwtoper or Personal
`Media Intemationat, at startup special-
`izing in multimedia entertairzmenr soft-
`-ware. He can be reached via Compu-
`Serve at 70621, I460.
`
`84
`
`2
`
`
`
`We slash interface
`development time across
`DOS, UNIX, POSIX, VMS...
`(and we can prove it!)
`
`The Designer: Easy
`to use lonn builder.
`creates all objects
`interactively without
`coding.
`
`om fields:
`Serottable regions. memo
`fields, ticker-tape fields.
`
`Graphic-style fields:
`Che-ck boxes. push
`buttons. radio buttons.
`
`Shadow borders,
`exploding windows.
`
`I
`
`. m-
`
`.
`
`l
`
`|
`
`|
`
`:i:rt:::Ji1:I:n:m:u
`ununrnrtdml
`iIrtttrIiI:r-Hint urraatlltllllltl-nil
`flrlnrltltl--tltt
`llll-‘lfllllllllilillllll
`ll=lll=l!l=!llll|ll4II||
`:nI|wIiII
`
`‘lllilllllfll-'lHIl|l
`
`Hl.
`
`|'li
`
`F
`
`Code Generator:
`Creates data strucauzes
`and source (node in C for
`a complete and working
`prototype.
`
`Scroll Bets:
`Horizontally. vertically.
`lull mouse support.
`
`Status Line; Optional
`lines for helpful Information
`when using the Designer-
`may be disabled for
`advanced users.
`
`C-Programmers:
`See for yourself how
`Vermont Views® can help
`you create powerful user
`interfaces——whatever your
`environment!
`If you want to create sophisticated
`user interfaces—and save tremendous
`
`time and effort doing it—Vermont
`Views is exactly what you need.
`
`Vermont Views isn’t just a
`common interface package.
`It's a deep, flexible, menu-
`driven screen designer supported
`by a C library of over 580 functions.
`It lets you create tl1e ultimate user
`interfaces for complex database
`applications - in a fraction of the time
`it would take to code it yourself!
`With Vermont Views, you create
`screens interactively. Designing is fast
`and creative. And changes—both tiny
`adjustments and huge reworks—are
`incredibly easy.
`Pull down menus. window~basecl
`data entry forms with tickertape or
`memo fields, scrollable regions,
`choice lists. context sensitive help
`All these interface objects (and more)
`are immediately accessible. Your
`
`I
`
`DOS applications can have full mouse
`control, and work in graphics as well
`as text modes! And with Vermont
`
`Views. even terminal-based applica-
`tions can have the elegant features
`usually found only on micros.
`Create prototypes fast,
`applications even faster.
`With most systems, you have to
`throw away your prototypes when
`coding begins. But with Vermont
`Views, prototypes become the actual
`application.
`Menus, data—entry forms, and all
`screen features are usable in the final
`
`applications without change.
`NEW! Vermont Views PLUS
`An enhanced version of Vermont
`Views for DOS. Vermont Views
`
`PLUS provides the interface power
`needed for developing multi-mega-
`byte, graphic—enhanced C applica-
`tions. Best of all it supports all
`popular DOS extenders and graphics
`libraries. VVPLUS also includes full
`source code for all libraries.
`
`It's the universal solution.
`Vermont Views operates com-
`pletely independent of hardware.
`operating system, and database.
`
`Any interface you create can be
`ported easily among DOS, UNIX,
`XENIX, POSIX. QNX. OS/2. and
`VMS.
`You can use Vertnont Views with
`
`any database that has a C-language
`interface (including Oracle, lnformix,
`db_Vista, and C-Tree). You can nan
`on PCs, DEC, NCR. HP, AT&T, and
`other systems.
`No runtime fees or royalties.
`Don’t take our word for it—put
`Vermont Views to the test. Call or
`
`fax now for your personal, free
`demonstration kit. Or order Vermont
`
`Views with our 60-day, money back
`guarantee.
`Either way, you’ll immediately see
`how Vermont Views can slash your
`interface development time.
`For MS:‘PCDOS.VeI1nont Views In 5495. Vermont View
`PLUS wllh MemF.x.Gnp|:EI and full source end: is $795.
`For UNIX. POSIX. and VHS. prices sum It $1.795.
`dcprndingun multinc class.
`
`
`
`I Pinnacle Meadows. Richford. VT 05476
`Phone (302)-843-773i FAX (302)-348-3502
`Piease Mention "Offer 396"
`
`Call 1-800-848-1248 for a free demo of the ultimate application interface!
`CIRCLE NO. 529 ON READER SERVICE CARD
`
`i L
`
`3
`
`
`
`- A far pointer to a data structure con-
`taining values to be sent or returned.
`(The structure is often specific to each
`message type.)
`
`Nearly all the member functions in
`this library make at least one call to
`mciSendCommand(). But don't be
`fooled by its simplicity: It has many op-
`tions, constants, flags, messages, struc-
`tures, and return values (and our goal
`is to hide these).
`
`MCI Clnss library
`The MCI class hierarchy is designed to
`encapsulate and enhance the MCI in-
`terface and to get the most benefit from
`the least code. It is part of a C++ Iibrary
`that will be used as part of the basis for
`the commercial multimedia products we
`are currently developing. As such, it was
`designed for a specific immediate pur-
`pose, but also had to be capable of han-
`dling unknown future requirements.
`This influenced both the design and the
`implementation. The design had to be
`flexible, extensible, and (most of all)
`practical. Because our needs are for spe-
`cific devices only, not all MCI devices
`are directly implemented although
`adding support for additional devices is
`a short process. Figure 1 diagrams the
`MCI class hierarchy, giving an overview
`of this single-inheritance tree.
`All MCI commands are classified into
`one of four categories: system, required,
`basic, and extended. Commands spec-
`ified for the first two types (such as
`open, close, and status) require support
`by all device types and are good can-
`didates for member-function definitions
`in the base class(es) of the MCI class hi-
`erarchy. The basic commands, includ-
`ing play, stop, and seek, are supported
`by most device types and can also be
`placed at or near the top of the tree.
`Extended commands that support spe-
`cific devices can be implemented farther
`down the hierarchy.
`The root node for the MCI class hi-
`erarchy, MC‘IDev£ce, serves as the base
`class for both the Compoumfl)evr'ceclass
`
`Figure 1: MCI class hierarchy.
`
`Dr. Dobbisjounral, juiy 1993-
`
`“
`"
`'".-;I.'.
`FR-'ll“fi’ltA‘M Mi R ' 5' “we at rut-it
`
`(continuedfiom page 84)
`ple devices do not use data files, where-
`as compound devices usually do. CD au-
`dio and videodisc players are simple de-
`vices; waveform audio, MIDI sequencers,
`and AVI are all compound devices.
`MCI provides two basic programming
`interfaces: 2 command-string interface
`that allows the use of ordinary text
`strings such as play cdaudio to control
`multimedia devices (this very open ap-
`proach is well suited to scripting and
`authoring applications); and a command-
`message interface that uses C-language
`structures and a Windows-style message-
`passing model for device control. The
`MC] (213536 I describe here use the com-
`
`mand-message interface because it’s
`more efficient and better suited to gen-
`eral programming.
`A single function, mct'SendC'om-
`mrmdf), is used along with a set of
`“polymorphic” arguments to access the
`command-message interface. The ma’-
`SendCommcmd() function takes:
`
`- A WORD device identifier (analogous
`to a handle).
`- A message-type constant prefixed with
`MCI, (such as MCIHPLAY).
`I A DWORD value set to one or more
`flags usually specifying which ele-
`ments of a given structure contain
`valid Values.
`
`-lint
`
`5.0 presents
`
`C Bug # 502
`
`l
`
`(3112;
`
`int mnint)
`
`I c
`
`'\x0P',-
`har chi in
`char ch: = '\xFF':
`unsigned U. I (chi << 8)
`3'‘ some computation *1’
`I1 = 11 5:
`"E2112;
`printft "9sx\n", u ).-
`return 0;
`I
`
`It was the programmer's intent toform a byte pair, do some computation,
`and then remove the second byte .' but it’s not working. Why does this
`program not print "F00"? Cat! tfyou need a hint. Refer to B143 #502.
`
`Attn: Power users with huge programs.
`PC-lint 386 uses DOS Extender
`Technology to access the full storage
`and Hal model speed of your 386.
`
`PC-lint 386 — $23 9
`PC-lim‘ DOS - OSI2 — $139
`
`PC-lint will catch this and many other
`C bugs. Unlike your compiler, PC-lint
`looks across all modules of your
`application for bugs and inconsistencies.
`More than 330 messages. Includes
`optional Strong Type Checking and
`flow of control analysis. More than 105
`options for complete customization.
`Suppress error messages, locally or
`globally. by symbol name. by message
`number, by filename. etc. Check for
`portability problems. Alter size of
`scalars. Adjust format of error
`messages. Automatically generate ANSI
`prototypes for your K&R functions.
`
`Gimpel Software
`
`3207 Hogarth Lane. Collegeville. PA W426
`CALL TODAY (215) ss4~42s1 Or FAX (215) 584-4266
`30 Day Money-back Guarantee.
`PAatH6‘K:sal.!5IaJ|.
`Plllint and F|exeLirIl me tradcrnarlrs ol'CIirtIpe| Scitwaa:
`
`4
`
`
`
`5
`
`
`
` Pliiifi-RAM'ME-R'.S work-atrial
`
`(continued_/i-om page 86)
`and all simple device classes. It provides
`the basic open/close/play type corn-
`mands, status commands for querying
`2 device's state, set commands to con-
`figure devices, and a number of other
`miscellaneous functions. The data items
`needed (all private) are:
`
`I An integer device id.
`0 An error-status value.
`I A string pointer to the device name.
`0 Anoptionalhandletoa parent window.
`
`The constructor (see Listing One,
`page 102) does not automatically open
`the device—doing so would mean that
`the device would be opened and po-
`tentially unavailable to other applica-
`tions from the time this object is con-
`structed until it’s destroyed. This is also
`true for all the derived classes: A de-
`vice is not opened until explicitly told
`todosowith an Optmflcall. It is closed
`either through a call to the C'lose()
`member function or when the object is
`destroyed and the destructor is invoked.
`(Constructing a C‘ompoundDem'ce with
`a filename is treated as if it were an
`Open() call and that file is immediate-
`ly opened.) Keeping devices open only
`as long as necessary is generally polite
`behavior in a multitasking environment
`such as Windows.
`The constructor for MCIDevice and
`any derived simple device (such as
`CD/ludfo) takes a single argument, a
`string value specifying the appropriate
`MCI device name. A default value is pro-
`vided for each of the simple device
`types so that an application will rarely
`have to explicitly provide this value. The
`only exception might be on a system
`using nonstandard or additional device
`names that do not match the usual MCI
`device-name strings defined in the [mail
`section of the SYSTEMINI file. MCI-
`Device is not an abstract class and can
`therefore be constructed and used di-
`rectly. It is designed, however, to serve
`as the basis for derived classes sup-
`porting unique device types.
`Most of the member functions have
`a direct mapping to a corresponding
`MCI command. These functions almost
`always require fewer arguments than
`either the command-message or the
`command-string interfaces because
`some of the necessary information has
`been encapsulated in the object. Each
`member function first
`any nec-
`essary data structures, sets the apprcr
`priate flags and arguments, and calls
`mcz'S'ena'C‘ommand(), occasionally more
`than once.
`The function’s return code is passed
`back to the object’s client and is also
`saved in order to maintain an error state
`
`88
`
`for later reference. The En-orMessage()
`member function calls mciGetError-
`
`.Sltn’ng() to get the error description, and
`displays a standard Windows error-
`message dialog box to the user. This
`class and all derived classes highlight
`one of the benefits of using C++: the
`ability to use destructors to perform
`automatic cleanup. It is important that
`applications properly close all MCI de-
`vices and files they have opened. By
`utilizing the C++ destructor mechanism
`we can autornatically trigger the closing
`of any open devices before an applica-
`tion exits and thereby improve reliabil-
`ity and robustness (not to mention
`avoiding any extra general-protectiorr
`fault-type messages).
`A sampling of functions built upon
`the MCI set, status, and capability com-
`mands are implemented to show how
`these access operations can be imple-
`mented. MC1Dew'ce provides the virtu-
`al functions SetO, Sraiusf), and GetDev-
`Capsf) for this purpose, but makes
`these protected because they are not
`intended to be directly called. Making
`these public forces the user to be fa-
`rniliar with the numerous MCI_SET and
`MCLSTATUS constant values needed
`for each specific option. Instead, these
`are used as the mechanism within pub-
`licly defined inline functions defined
`for each of the set and status options.
`For example, the Lengtbf) function,
`which returns the length of the current
`device, uses the Stnmsf) function with
`the MCI_STATUS_LENGTH option to
`get its value. (It should be pointed out
`that a type of simple runtirne type iden-
`tification can be achieved by using in-
`formation functions such as Device-
`Type() and C‘ompoundDew'ce(). The
`Device
`J function returns a unique
`constant identifier for each device type,
`and therefore each class. Compound-
`Devicef) returns a Boolean value of
`True if the given object is a compound
`device.)
`One other notable method, SetPar-
`em(), is used to assign the handle of a
`window designated as the parent of this
`MCI object. PiayO checks to see if a
`parent ‘window has been assigned to it
`and if so, stores this handle in the pa-
`rameter block given to mcz'SendCom-
`mana'() and sets the MCI_NOTiFY bit
`of the corresponding flags value. This
`causes MCI to post the MM_MCINOTI FY
`message to the specified window when
`the operation is completed. When this
`occurs, the window procedures IPamm
`is set to the device id that initiated the
`Callback, and the wPar-am gives the sta-
`tus of the operation, which can be suc-
`cess, failure, superseded, or aborted.
`MCI allows the Notify option to be used
`with all cornrnands, and this library uses
`
`it specifically as an option to the Play()
`function. if needed, this option can be
`added to any or all of the other func-
`tions for these classes.
`
`A Simple MCiDevice
`CDAudio is a simple class for this “sim-
`ple” device. In fact, all the basic func-
`tionality for simple devices is provid-
`ed in the MCIDem‘ce base class.
`Therefore, C'DAud:'o doesn't need to
`provide additional functions of its own.
`It can instead rely on the operations
`inherited from its parent. The MC] com-
`mand set for CDAud:'o defines a few
`additional options for some of the base
`commands, three of which are imple-
`mented here. These are Eject() to eject
`the disc, and 5erT:'meFormatMSFi’) and
`SerTimeFormat7MSF() for setting the
`time format (T-tracks, M-minutes,
`S=seconds, F=frames). Each is imple-
`mented as an inline function that pass-
`es the appropriate flags to the S930
`function. By allowing just the time for-
`mat to be set through these functions.
`we can avoid inadvertently trying to
`set a device to 9. time format that it will
`not accept. This lets the programmer
`know which formats are acceptable for
`each device by looking at its class def-
`inition, which cannot be determined
`without the documentation using the
`C interface.
`This CDAudfo device an be opened,
`closed, played, stopped, queried for its
`status, and so on. All common opera-
`tions are inherited from the MCIDew'ce
`base class. Other simple devices such as
`Vdeodisc and VCR can be implement-
`ed similarly by deriving from Mciflavice,
`specifying the appropriate device-type
`string for the constructor and adding any
`device-specific operations.
`
`CompotmdDevr'ce
`A compound device is an MCI device
`that uses files. Therefore, the Com-
`potmdflevice class and its descendants
`must be able to handle a filenarrre on
`open. Keep in mind that the device id
`is more like an element id, one of
`which is allocated for each open corn-
`pound-device file. (A filename for a
`compound device is known as the “de-
`vice element.”) The constructor for
`C'ompomzdDew'ce takes two optional
`arguments: the name of the file to open,
`and the name of the device type to be
`opened. The second argument is im-
`mediately passed to the base-class con-
`structor. The first argument, if given, is
`stored internally and then used to open
`the file. This approach follows the
`iostream model, in which a filename
`passed to the constructor automatical-
`ly opens the file. The implementation
`could easily be changed to not open
`
`Dr. Dobbsjournal, July 1993
`
`
`
`6
`
`
`
`7
`
`
`
`8
`
`
`
`msanmmt-R"-‘s w'o'amn'cH
`
`if Iivnevicellfl
`return HCl.£i.R_!0U'r_UFEIl:
`if (d\-‘Flags & |0GI-SET.T'Il'lE-1’ORHAT)
`H dvkltre in forum
`mciSetParu.d\f1'i.IIeFurIat I rlullltra:
`|'1'u'F].egl.
`dufirrfitete I nc1Ser|d{:onIIrId(\IDeuiceID. 311221-831‘.
`{WORD} *'.I.PH(2I_S1!'l‘,1'»‘AR.l‘lS) &Ic.‘.SerPanu):
`
`IWORD
`1
`return dufirrsnte:
`NCIBevice:13I'.ntu:{D‘HGR|} duP‘Laga. DHORD dulten. WORD dwfixtn)
`I
`HGI_S'l'.\'1‘EFS_PARHS IciS1:aI:ueParIIs:
`if Ilullevicelb)
`return MC3_EElR_NOT_OPBN:
`mci.StatunPar:I.I.dHItel I dwltel:
`H Determine which extra strut: Heir}: to set based on flags.
`if (duF.'P.a§a a mrrmcx)
`nc1StIr.uIFerua.dvT:eck = dufixtra:
`dufirrfitete I Icisendconend (uDev1ceID. N'CI.S'L'A'.l‘lJS. duPl,e3I.
`{WORD} [LPl'|CI_S‘EA!'lIS_PARH3] &n::l51.ltuaE’.uru):
`return IuiStatusParII.dHReturI1:
`WORD
`I£(:II)e\rjr:e1 zsatnmzapaimmnn du-Item}
`I
`KCI_GE’l'DE\I‘CA.PS_PABJ!.S ncifietbevflepnflrns:
`if tluhevicelm
`return HCIJ-RR_NOT-DPE'N:
`|ciGetl}evGapaPar|a.duI1:eI I duIteI;
`d\IE1'rSt|ta I lnifiendcnmand-livfleuicelfl. HCI_I'.{KfDE'u'I1.LP3, HCI_GKfl)l'."|ICAP5_I'l'D(.
`(numu:-) (LP!lCl_G‘£‘l'DEVcAPS_PAH4SJ hcscennevcnpaenml -.
`return lc:iGetDeu'CapaParlu.d.II'Return:
`}
`void
`
`JI
`
`Iiecillevice: :Set1JeviceI1vpc[LPS‘1'R lDszDevi.ce}
`if (lpu.Device'l‘y'peJ
`delete I}
`lpasfievicehvpe:
`1puDeviceT)'pe I new “far ch.ar[lstr.lenllpsz.I!evice)+11:
`Irlzrcpyi
`I'pszDev:‘.ca'l‘ypn.
`lpnzneuicel:
`void
`HC'|.'Deu'1ce: :ErrcrNeaeageBoxU
`I
`that eflrrcrMf[ ] ;
`if {Ic‘.'|Gel;Iz|'arSt:.ixI|§{dIIErIState. {L.PS'IRhiz.ErrIJz'3nf. ))
`e re
`‘N61 Error‘. K!_IUDHElCLM|.|\TIUNJ:
`1 Hesugelox(h|PndPara1t. uflrrozluf.
`HeanageBux[hHnd1?arer|t. "'IInknauII IICI Error‘. “HCI Error".
`
`)
`DUOE
`
`lI3_ICDNKXC1.flI!.i\'l'IUN) I
`
`ilfllibevica: :DpelI(LPSTI1 ipszfievice II *1 NIILL ‘N
`HCI_UPKN_P.1\8.lIS
`nc1DpenPnm.I:
`if [UDev:iI:nIIl}
`H Already open darn’: du it again
`return l{CI.,h'ARN..Al.F.EADLOPEN:
`if (lp8:De1Ii.ceI
`H Type given.
`luv: it in private data
`SetDeviceType{1p:sDevice]:
`else
`H Hake sure we have a type to open.
`if tllpazbevieehrpel
`U had to given here at in ctnr.
`return }IXIIjK|LNO_DEV'IC'ENa\H3:
`nc:i0penPIru . ].pItrDev1ce'I'ype I 1puI:Ievi.ce'l‘ypE:
`dsfflrrstate I ncisendcomnndfiflull, HCI_GP8ll, }9Gl_0PBJI_'l'YP3,
`KDWRD) {LPHCI..0PEN_]ARH5} hIci0?2lI¥ll'l8):
`if (1dvErI:$tIt¢}
`Weviceln I lc‘iDpenFnrn:.uDevice1'B:
`return du-Brrstate:
`ORD
`
`JW
`
`1lCI_G'.ENERIC_l'AR!|S a¢iGenezicPeru:
`Ilfclbevice: :GlonU
`if (lube-riceID}
`return M(iI_1!RR_ND'E'_0P!N:
`if {1(£‘<H'BI::State I misendceaundtuuevicelfl. HCLCLDSE. J|I.'I_|lAl?.
`(moan) (LPnc1_::xnxaIc.mm-Is} aaeisamricvarum
`wDIviI:aID I NIJLL:
`
`return dulzrstete:
`)
`[WORD
`Mclfleuicez :5tapU
`I
`HCI_G3NERIC_P.LRHS :v:.iGeneri.cPnI:ms:
`if U\9‘DeviceID)
`return KCI_E|lR_H0'1‘_0PEN:
`return dullrrstare I |r_iSemlCauend[\fl)ev:lceID. HCI_S1'9F. HGI_H'AI'!'.
`(DilD‘Rn](LPHC1'_K:BllEn1C_PARHS] an-.ia.ngr1mns1:
`
`JW
`
`ORD
`MCI Device: :Pause 0
`I
`KCI-ElNZRIC-FAM!S w:iGenericFnrIs:
`1r (Iunuvi-urn)
`return HCI_BP.'R_N01‘._DPIN':
`IiGI_PA|£S2. racnum.
`re1‘.u.rn dulnstate = ucisendcauandiufieviceln.
`[NERD] {LPHCI_GBNE|lIC_?Alfl£E} &nciGmer‘1cPanu):
`
`JI
`
`WORD
`
`|{(CIDavi.ce::Rea1mn{}
`HGI_6lN3RIC_l'ARHS IwlGenericPams:
`if (|vDe\riceID)
`return HCI_ERR_NflT_DPBH:
`IICI.RESU'Hl. HCIJIAIT.
`return dulin-State I ucisendconandh-Deviceln.
`(WORD) (LPI{CI_l‘£ENB£IC_PMH.S} &IciGenerir;Parna):
`
`'.|
`D'ri0‘RD
`
`l(iCIDev1ce::P]aJr[Ia0NG 11’:aI. DONG 110}
`|lGI_l'I-\Y_FARKS Il:1PllyParl3:
`
`Dr. Dobbisjoumal. Jmfy 19935
`
`lisling One (Text begins cmpage 84.)
`,I'o--- ----- --- ------ -----we -«--- ----------- --- ------ --~~---------- ----~------I\
`I }tci.cpp:
`94- class hierarchy for lvlinrhwr llI1].1'.i.lE|‘H.B object: using HCI.
`I $Author:
`John Huuer
`S
`‘ Shate:
`234 Fe]: 1993 19:a:==e2
`5
`' $Gupyri§ht:
`Personal Media Inteznltinnal Inc., 1993 5
`I Delcriptiun:
`A set of classes to encapsulate the connmd-neruge interface
`I
`to M1. mrrentlr ilplenented: Cbfiufilo. lhveforn Audie. MP1.
`I
`‘hm hue classes HCIDev-ice anti Conpnundflevice provide max: of
`0
`the basic functionality needed for derived IICI typn.
`
`linclude "H£I.h"
`limlude <II.e|ary.h>
`Iinclude <rtring.h>
`N used for char array sizing
`128
`fldefine
`14'CI_B’UESIZB
`I ---- --if
`N---- -- * |!CIDevice functium:
`l!CIDe\r1:e: :I9CIDavicaELPS‘I?. lpszlievicel
`{
`Imevicelh
`INl.|'LL:
`hindhrent
`I Hl|'J'..L:
`dwBrrStete
`I NULL:
`lplnbevicefype I NIFLL:
`if tlpaxnevicej
`
`3etDev:‘.ce'!‘ype(1pezDeviceJ :
`}
`ltlcinawiee: :"1{Gl'De\ri:eU
`I
`if WDevi.ceID}
`clout):
`if (lpnznevicenrpel
`delete I] lpswevicefive:
`
`IL
`
`ESTR
`
`!(|CJBe\-‘ice: :I1Ifu(D'H01lD dvflusal
`I{C'LIHl’O_PAlll!5 nci1r|foFarn.I:
`Int:-e char aEuf{llCI_B1I'ESI1l!]:
`it (h-fleviceln)
`return (LFS'l'R)NlJ'LL:
`nci.InfoPerIn.1patrRerurn I eauft
`:u:i.InfoPeru.duRet9i:e
`I llCJ_BT.|l’SIZE:
`du-Errstare I nci.3endCuInnIId(U'Device1'D. HCLIN?0, dufiilagi.
`{WORD} U-PHCI_INYO_1’.lJ?.K5J 5!w:iIr1‘fn?|rIU):
`return leiIn'EoParnr . lpstrlleturn:
`3DUORD
`
`lgcllleviea: :Sat{D|i0RI3 dwflagl. WORD dufixtra}
`ll.'C[_SET_PARMS n:iSet¥arIl:
`
`Real- Time Multitasking
`
`for Microsoft C, Borland C, Turbo Pascal
`
`Develop Real-'|’Ime Murtllasldng Applicationswith RTKemefl
`n1'Kornelisapmfeea'onaJ.h'
`rlomaancereal-1irnemu' ~
`a
`ycueen n no
`r
`non.
`=
`HTKemaiaI2d library in
`In'mmma$é:m°n
`prooad.Ira3aspeIal|a|1ash3.R'Tl<
`oflalsrhese :
`I pte-ernmive. warn-I ‘mllmqn-driwn
`scheduling
`Inurrharn1 laslesunly ifrfiedbyfififl
`-teal:-awltl1flrI\eaf§5ne<:s{33~MHz-I86]
`-sooodhdnperldentoflhunmnberoflasks
`-I.pb€4prlorI§aa(d'|angsabbn:ru
`IflIna~fldng<:anbeam¢ated
`viilrnarmalfl-l31fi1eo'l0.11n55 Q
`-N91-reeolulionhtamal
`-auIhra1eorwspordI:sl\s
`
`-. Indahls-DOSaDb6.D.DR-D05.
`4 s.orvri§l'IuLuopam1i1gs)¢sharn
`- raat$aa11nuI1n-taaI:rI¢}appfI:ahoI‘:s('fSRs)
`- runswrndom orDOSE:dendersasa1aek
`- u.IcporlsOode\fiewundTu'bo Debugger
`- HUI-lame
`-fulsvnumacodeavallahle
`- nonm-flrnernyllliu
`-fieehchnlcelluppoflbyphmnarnx
`
`mtornol-C mscaoa7.uva.u, ao+c-1.ne.cv.u}
`fi1'Kume|-Pascal [|'P!EP5x!6fl"?D.SBPEx} .
`Foti'Imn'aioI1zioII1ers.add$Mkxzfi:pirga-Idrnrni-lg.
`I-laaeorc-aId.VIn.mocIs.baI1kn'ar§ar.C0DaooepIod
`
`...s495{5'ourneCade:add$445)
`..$u5[Sou1'caCodo:aadS:IT5|
`
`MARKETING
`
`OnTime.—
`
`Professional Programmhg Tools
` ”' a:|G67Hm'buu- Gcnuw
`llhono 049-AD-43‘.|'aI?2-Fen: 449-an-435196-Darnaflolw l|:l:IlJ0.633
`CIRCLE ND. I22 ON READER SERVICE CARD
`
`9
`
`
`
`
`
`)i
`
`}i
`
`}d
`
` wmtn iuFl:g.I - $1.:
`if (|IDuVicalD}
`return l!.Gl.£R3..N0‘l‘_0PEN:
`if (hii'rIdParentl
`I
`|ci.F1nyl'n.rIa.duCa11b|ck I [UHDRDHL.P'\rCIIDJ hfindhrant:
`
`dwE1ay .'- l{GI_NG'l"IF‘{;
`
`f (1FroI !- current! {
`-:i.PlayPnrnIu.d.I'?ml I llrnm:
`
`dvrlangu I‘ IUCIJROH:
`f [1'l'u In and J
`[
`Ici.Fl.nyFarns.d.Vli'o I ].‘].‘a:
`
`d\rPln5a it $161.10:
`
`ulrrfiuto I n:iSendConunrIdlu'DaviceID. HCI_PI.AY. dulflaga.
`{DHORIU [LPHCI,PI.I\Y-PAI'IHS} hci?l:yPn1-nil:
`
`tetu.m{dv!rrStat:):
`
`WORD
`
`
`
`
`
`.
`
`|{ICIDcvi:e::Seek{LDlIG ITO)
`HC1_S3EK_|’A?JlS uc.iSEekPBrIa:
`WORD dufllgs - EL:
`if Uwbevicelfl)
`return KCI_ER.l._N0'I'_0?Bl:
`§H'.itCh[lTD:|
`[
`BIKE Ktlftl
`flirting: I HCI_SEElL1‘U_S‘l'AR'.|‘:
`break:
`case end:
`duI'lngs - I{CI_SEEl(_'l'0_END:
`break:
`defnult:
`1u:iSc?.'kFnrua.dwTn '* {!}|I‘DRD]lTo:
`
`
`
`
`
`
`
`
`
`
`
`
`
`
`
`
`
`
`
`
`
`
`
`
`
`viIFl:gI I IEIQN:
`}
`dusrrscat-e = ncisendcoanman-i(uDeviceID. MCI_SEBK. «Flags.
`(LONG) (LPNCI_SE!ILP.R£)lS) Elciseeithmsll
`l.'€T.I.I.|.'1'I
`(SHE! P5281! I
`MDRD
`l§C[Dev1ce::Su:pAll(?
`C
`return |ciSe11dComand(1!CI.aI.L_DEVICE_ID. IlCI_S'mP. 0. NULL);
`f‘ ---- --
`1 Gonpmmdnzvice functions * -------U‘
`
`Conpaunduavicu::CoIpwndDevice(1.P5TR lpaznle. LFSTR ipulievicel
`
`
`
`llaquiresunlyfilllnflnasemennnv
`Inqnlemented m 1III% Windows III.L (not a TSII)
`I All applications are both client and server
`I Works concurrently with Netware, LAN Manager, Vines etc.
`I Up to 64 concurrent sessions
`I Extensible SNMP Agent
`wmdggggggglim
`Berkeley 4.3 Socket API
`ONC RPCLXDR
`WinsNMP AP]
`mwow
`TELNET (VT100, VT220),
`§§‘«3$§&a*§1TPéoT§‘2T§map
`PING,BINf>,sran%tics,
`and CLISIJOM
`
`NFS Ch'8m' :9 Server
`
`For overnight deliver)! ran;
`@NErM4M4G "
`(408) 973'7171
`%’§§§§a‘§§,”E1‘3?’o°1§%'§3L
`Fax (103) 257-5405
`
`’
`
`CIRCLE NO. B05 ON HEADER SERVICE CARD
`
`(
`
`: llclbavicaflpazbaviccl
`1pe:?11e1L-me - NULL:
`if flpaflilei
`0‘pen(lps:Filcl:
`Gulrpaundnzvica: :“CoIrp-oundllevicef}
`(
`if (unavxcam
`close (1 :
`if flpazliiell-Hie}
`
`
`
`
`
`
`
`
`
`
`
`
`
`
`
`
`
`
`
`
`
`
`
`
`
`
`
`
`
`
`
`,
`
`
`
`
`
`
`‘.
`
`
`
`
`IN}-RD
`lpszfilellnne:
`delete [I
`I
`Guipaundlievice: :Upcn [LFSTR lpsflilel
`K
`PEI .0PEN_PAP3|S Iniopenhma:
`WORD duflnga I EL:
`11 (uDeviceIDJ
`1'! If ue‘re already apem don't 3:: it 53.011:
`return I!CI_|u'.t\NLI'\LRIADY_DFI3H:
`lpszfxialhln I net "in ch.nr[1atr1en(1pnr.E:11a]1'1]1
`lnrcpfl lpszfiilafluu. 1pa:Pila}:
`|c:'|OpenP|mI.1pItrE1eu:nT.Na|t= I‘ lpszfileilaue:
`lc:l0penParla.IpItrDevice'I'ype - lguflevicefirpe:
`d'I|’1a3I I HCI_O|’BN_EJ'..l1‘.'EN'l‘
`I HCI_0PEN_1'Y'PE:
`dukrrsnta I IciSundCamnnndUllJLL. 14.01.0193“. duflngs.
`(SWORD) (LPHC1_0PZH_PARl1S} énciopenfnrmoli
` '
`it ildufin-State}
`
`1
`
`
`|
`
`
`1
`
`
`
`
`
`ul>e\ri.cu‘.ED - m1opanrams.w1:eu1cetD:
`teturn duE1‘I:5I:.n\:e:
`}
`NEED
`{Enpuund.Dav1r:e::CluIe(}
`!|C‘.lDeu-ice: :C1oI:U:
`if Klplflilaflale) I
`delete [I
`.1ps:Fi1e1lne:
`
`Ipaflileflam - HULL:
`J
`I
`return dullrrstatai
`J'V------ I All’! flmctinna ‘ *-----If
`DWRD
`.WI::iJ'pr1nl:e(|iJ:-C lads?
`I
`|$I_DGV_TJl’DA'.l'.B_|'ARHS nclLlpda:eParIs:
`mom duilqs:
`if (|wDeviv:eID}
`return flCI_ER.R_IiO'1‘_0PEH:
`IcilIpdnr1PuIl.hDC I hdc:
`dvilags * |ICI..DGV_UP'DA'1'3_HDC F HCI_DG'i'_U'PDATE_PAIHT:
`fivlrrfitata - Icisendcolneradh-IDeviceID. HCLUPDATE. Ilfllegl.
`(I.UHG](LFl'iCI_DGV_U'PDATE_1?.I.itH5J aneiupaatennsl :
`
`RUDD
`I
`return dultrrstne:
`
`_.:‘|l'I::1’utDutinntion (REC? amt)
`W2'I_DG\L1’U'I'_F.hPJlS w:iPIatParua:
`numm dvFhga:
`
`(continued on page 105)
`
`.
`
`
`
`
`
`
`
`
`
`
`
`
`
`
`
`
`.. Ha1jf._th_.e_.
`'
`'
`
`d
`
` ':theSpeed&
`iz_eQf‘»E1LE.iL _
`ic,{’1sua.l
`ic
`(1:e1§L)sup
`rt
`
`‘»?*°*“ W‘:
`
`=
`'aailgb|5.
`'
`S cngivrogrm
`_
`1
`__
`-r1i1r=:r1=:;~_ae1J!!:rv-r _”- 8.8
`.23
`; Cc?)
`‘
`In emqtiohol
`td.
`winat;:.:|in:ss$1e7;
`7op:sa2— 698
`I
`I
`1
`
`l
`
`10
`
`103
`
`10
`
`
`
`11