Anda di halaman 1dari 179

Basics of C/C++ & Windows Programming to learn COM

(Note: This document does not cover C/C++ or SDK & VC++ in detail. This is only a document made to give one enough no!ledge to "roceed !ith #indo!s $rogramming !ith C/C++ and then C%&.The contents o' this document are retrived 'rom various (oo s and !e( "ages and modi'ied to suit the re)uirement.*

By Network Solutions Ltd. Koramangala Banglore

Contents
+ntroduction to the $rogramming ,anguage C -istory %' C Nature C as a second generation and third generation ,anguage

.sage ,oo ing at C 'or the /irst Time Com"iling 01uilding and #arning &essages Ste"s to Create a C a""lication Some Theory a(out Com"iling and ,in ing $rinting moe than one line Data declaration Some comments a(out Comments The 2rammer o' C 34ercise 5 'e! de'initions and Terms /unctions %%$S (%(6ect %riented $rograming Systems* $rocedural0 Structured and %(6ect %riented $romming %(6ect Class 3nca"sulation 5(straction #hy C++ 5 com"arison o' C and C++ +ntoduction #hy is C++ (etter than C Streams 3sca"e Se)uences #hat is a $ointer The +ndirection and 5ddress%' %"erators /unctions Structures 3numerations Class 3nca"sulation +nline /unctions $olymor"hism +nheritance Dynamic ,in ing 5$+s and &emory &odels Threading #indo!s $rograming in C (SDK* 5n +ntroducton to .nicode #ide Characters and #indo!s #indo!s and &essages 5 #indo! o' %ne7s %!n The #indo!s $rogramming -urdles 5n 34ercise in Te4t %ut"ut $ainting and 8e"ainting The #&9$5+NT &essage 5n +ntroduction to 2D+ 1asic Dra!ing The Structure o' 2D+ The Device Conte4t

Dra!ing Dots and ,ines Child #indo! Controls ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

+nstructions /or the /aculty


+ntroduction to the $rogramming ,anguage C -istory %' C Nature C as a second generation and third generation ,anguage .sage ,oo ing at C 'or the /irst Time Com"iling 01uilding and #arning &essages For the Rest of the section give a Demo Ste"s to Create a C a""lication Some Theory a(out Com"iling and ,in ing $rinting moe than one line Data declaration Some comments a(out Comments The 2rammer o' C 34ercise 5 'e! de'initions and Terms /unctions %%$S (%(6ect %riented $rograming Systems* (<ust The Theory* $rocedural0 Structured and %(6ect %riented $romming %(6ect Class 3nca"sulation 5(straction #hy C++ 5 com"arison o' C and C++ +ntoduction #hy is C++ (etter than C Streams 3sca"e Se)uences #hat is a $ointer The +ndirection and 5ddress%' %"erators /unctions Structures ;hrs 3numerations Class 3nca"sulation +nline /unctions $olymor"hism +nheritance Dynamic ,in ing 5$+s and &emory &odels =hrs Threading ;hrs

=hrs

=hrs =hrs

>hrs

#indo!s $rograming in C (SDK* 5n +ntroducton to .nicode #ide Characters and #indo!s #indo!s and &essages 5 #indo! o' %ne7s %!n The #indo!s $rogramming -urdles 5n 34ercise in Te4t %ut"ut $ainting and 8e"ainting The #&9$5+NT &essage 5n +ntroduction to 2D+ 1asic Dra!ing The Structure o' 2D+ The Device Conte4t Dra!ing Dots and ,ines Child #indo! Controls

;.? hrs %nly a Demo and @5

MFC COM

------------------------------------------------- hrs -------------------------------------------------!"hrs

#ntrod$ction %o Programming &ang$age C 'istor( of C


The milestones in C7s develo"ment as a language are listed (elo!: .N+A develo"ed c. =BCB :: D3C $D$:D 5ssem(ly ,anguage 1C$, :: a user 'riendly %S "roviding "o!er'ul develo"ment tools develo"ed 'rom 1C$,. 5ssem(ler tedious long and error "rone. 5 ne! language EE177 a second attem"t. c. =BDF. 5 totally ne! language EEC77 a successor to EE177. c. =BD= 1y =BDG .N+A %S almost totally !ritten in EEC77.

)at$re C as a second generation and third generation lang$age


The C language "ossesses the "o!er'ul lo!:level 'eatures o' second generation languages li e "ointers0 memory allocation0 (it mani"ulation etc. +t also su""orts conditional constructs0 loo" constructs0 a rich set o' o"erators and a variety o' data structures as in third generation languages. The com(ined 'eatures o' second and third generation languages ma e C language a very "o!er'ul and a 'le4i(le language. These 'eatures o' C language ma e it "ossi(le to use the language 'or Systems "rogramming0 li e develo"ment o' Com"ilers0 +nter"reters0 %"erating Systems0 2ra"hics and 2eneral .tilities and also the 'or the host o' a""lications in commercial environment.

*sage &oo+ing at C for the First %ime


ThereHs something to (e said 'or starting !ith sim"le e4am"les. 5 la!yer0 e4"laining a conce"t to a "erson !ith no no!ledge o' the la!0 !ould do !ell to (egin !ith an elementary e4am"le rather than hitting the lay"erson !ith years o' legal training at once. The lay"erson doesnHt "ay to (e im"ressed0 (ut to understand his or her "ro(lems (etter. ,earning a(out "rogramming is no di''erent. ThatHs !hy !eHll start !ith the sim"lest e4am"le you can imagine. To ma e it even easier0 letHs loo at the 15S+C version 'irst: $8+NT I-ere + amJI This statement0 in case you havenHt seen it (e'ore0 constitutes a com"lete "rogram in 15S+C. &oreover0 it actually "rints something0 so you can veri'y that it !or ed. -ereHs ho! the same "rogram loo s in C: main (* K "rint'(I-ere + amJI*L M +' youHre relatively ne! to "rogramming (though + assume youHve "ro(a(ly seen 15S+C (e'ore*0 the 'irst thing you need to no! is that these e4am"les suggest a larger "attern o' sim"le

"rograms. #ithin these "atterns are0 (elieve it or not0 vast "ossi(ilities. The "attern 'or the sim"le 15S+C "rogram is: $8+NT Iyour9te4t9hereI -ere +Hm introducing a convention +Hll use throughout the (oo : !ords in italics re"resent something that you "rovide. Nou could ty"e any com(ination o' characters you !anted !here your9te4t9here is indicated. The C version is: main (* K "rint'(Iyour9te4t9hereI*L M So0 'or C0 another e4am"le that 'ollo!s this "attern is: main(* K "rint'(I$rogramming0 it sounds li e 'un.I*L M #hen you ty"e in this short "rogram0 you should (e care'ul a(out the 'ollo!ing matters: O Ca"italiPation counts. %r rather0 in this case0 lac o' ca"italiPation counts. 15S+C "rogrammers0 'or some reason no one understands0 o'ten leave the C5$S ,%CK ey on0 (ut it !ould ma e no di''erence i' they al!ays le't ca"italiPation o''. #ith C0 youHll )uic ly 'ind that ty"ing Q$8+NT/R or Q$rint'R instead o' Q"rint'R results in an un'riendly error message. O $unctuation also counts. The 'irst mista e that a!aits you i' youHre coming 'rom 15S+C or /%8T85N is to 'orget the semicolon (L* at the end o' a statement. 5t least C is sim"ler in this res"ect than $ascal: you al!ays terminate a statement !ith a semicolonL you donHt have to guess !hether or not to use one. -o!ever0 this rule doesnHt mean that you "ut one a'ter the terminating (race (L*. (#eHll s"end more time !ith semicolons and statements later0 in case youHre thirsting 'or more no!ledge on these esoteric su(6ects.* O 8emem(er also that dou(le:)uotation mar s (I*0 not single0 are re)uired. O S"acing does not count. Nou can "ut any num(er o' e4tra s"aces around the "arentheses and (races0 i' you !ant0 or even ty"e everything on the same line. %' course0 you canHt "ut s"aces in the middle o' individual !ords0 turning Q"rint'R into Q"r int '0R 'or e4am"le. 5nd s"acing matters to some e4tent in the te4t inside the )uotation mar s0 (ecause the te4t you enter there !ill (e "rinted as you entered it0 letter 'or letter. -ereHs the "rogram one more time0 !ith slightly di''erent s"acing: main( * K "rint'( I$rogramming0 it sounds li e 'un.I *L M +' all goes !ell !hen you enter and run the "rogram0 it !ill "rint the te4t string sans )uotation mar s: $rogramming0 it sounds li e 'un.

5ssuming that this !or s0 you might try redoing the "rogram !ith di''erent strings. +' you have "ro(lems0 revie! the "receding "aragra"hs 'or "ossi(le mista es in entering the "rogram. Nou also might need to ma e sure that youHre using your com"iler to correctly (uild an a""lication.

5 /e! #ords a(out Com"iling0 1uilding0 and #arning &essages


5lthough it may sound hard:hearted0 in this (oo +Hll o''er only limited hel" in using a C com"ilerSthat is0 the so't!are you (uy to translate and run your "rogram. 3ach C "ac age has its o!n commands and idiosyncrasies0 and each comes !ith its o!n instruction manual that ought to (e the (est guide to use o' commands. /ortunately0 the language itsel' (ho! you actually !rite the "rogram* has a standard that is more or less universally adhered to aside 'rom occasional e4tensions. -o!ever0 there are a 'e! things that can (e said a(out the "rocess o' com"iling. Together with linking, the process of compiling a program and getting it ready to run is called building.
Try out $lease

+' youHre using &icroso't Visual C++0 !hich + re'er to (ecause it is one o' the standard com"ilers in use today0 the ste"s you ta e are sho!n in the list that 'ollo!s. Nou !ould 'ollo! roughly the same ste"s !ith other com"ilers0 although the menus and e4act command names may (e di''erent. Note that although QC++R is in the "roduct name0 the com"iler is "er'ectly ca"a(le o' acting as a straight C com"ilerS6ust ma e sure you give your source 'iles a .C e4tension0 and the com"iler !ill use the rules o' the C language rather than C++. + !ould e4"ect other C/C++ "ac ages to (ehave in a similar !ay. 5nother thing + recommend0 i' you are using Visual C++ in the #indo!s environment0 is to select Console a""lication (i' running #indo!s NT* or @uic #in (i' running in the =C:(it environment* as the "ro6ect ty"e. 1oth o' these ty"es o' a""lications "rint directly to the screen !ithout 'orcing you to !orry a(out all the e4tra details o' managing a #indo!s a""lication. (ThatHs a su(6ect 'or another (oo .* The ste"s 'or com"iling and lin ing are: =. 5'ter entering a "rogram0 save it as a source 'ile !ith a .C e4tension ('or e4am"le0 -+.C*. ;. Create a ne! "ro6ect and select Console or @uic #in as the a""lication ty"e. 5dd the source 'ile (-+.C* to the "ro6ect. G. /rom the $ro6ect menu0 choose 1uild. >. /rom the $ro6ect menu0 choose 8un. +' you got stuc on ste" G0 you encountered either a com"iler error or a lin er error or (oth. 5 com"iler error indicates that something !as !rong in the !ay you ty"ed in the "rogramL "erha"s you 'orgot to ty"e in the semicolon (L* or one o' the )uotation mar s (I*. 5 lin er error0 at this "oint0 "ro(a(ly indicates that something in the develo"ment environment !as not set u" correctly. Chec your manual to ma e sure that you installed the "roduct correctly. +'0 ho!ever0 you ty"ed in the "rogram and 'ollo!ed all the ste"s correctly0 instead o' error messages you "ro(a(ly received a cou"le o' !arning messages. 5t this "oint0 donHt "anic i' you got !arning messagesL thereHs a (ig di''erence (et!een !arnings and errors. #arning messages donHt sto" you. 5s long as you got only !arning messages0 you can run the "rogram.

1ut you may !ant to get rid o' the !arning messages any!ay0 and 'or a good reason: !arning messages are there to alert you that something une4"ected may (e ha""ening. Not much can go !rong !ith this "articular "rogram0 (ut in a larger "rogram0 a !arning can easily catch the source o' a "otential error. Nou may as !ell get in the ha(it o' trying to eliminate causes o' !arnings. +n the !orld o' "ro'essional develo"ment0 testers donHt certi'y that a (uild is correct unless it com"letes !ith Pero !arnings and Pero errors. +' youHre running Visual C++0 version =.F0 !ith the standard environment settings0 you got these !arnings: !arning C>F=G: 7"rint'7 unde'inedL assuming e4tern returning int !arning C>FG?: 7main7 : no return value The 'irst !arning message tells you that the "rint' 'unction has no return value0 so the com"iler assumes an integer (int* return value (y de'ault. T!o things a(out this 'act may (e sur"rising. /irst0 C has no conce"t o' a statement or su(routine the !ay that 15S+C and /%8T85N do. 5ll routines are 'unctions0 and every 'unction returns a value. +n this "rogram0 "rint' is a 'unction !hose return value is ignored. (+n C0 you can al!ays ignore return values i' you choose.* The 'ollo!ing directive0 added to the (eginning o' the "rogram0 clears u" the "ro(lem: Tinclude Ustdio.hV The Tinclude directive causes the com"iler to read in a 'ile that "ro"erly declares "rint'. 5t this "oint0 you may (e "rotesting that it shouldnHt (e necessary to declare such a 'unction (e'ore using it. 5'ter all0 it isnHt necessary !ith the $8+NT statement in 15S+C. 1ut C is di''erent. The num(er o' ey!ords in C is e"t )uite small0 and "rint' is not a ey!ordL itHs 6ust another 'unction !ith no s"ecial status. 5s it ha""ens0 "rint' is e4tremely use'ul and is there'ore "rovided in every standard C li(rary. 1ut you could 'reely re!rite or rede'ine "rint' i' you choose to0 and the com"iler itsel' doesnHt no! anything a(out it. This as"ect o' C may (e a slight inconvenience 'or no!0 (ut it ultimately ma es C much more com"act and 'le4i(le. /or all these reasons0 the com"iler e4"ects you to declare "rint' (e'ore you use it. 5s mentioned0 the stdio.h header 'ile ta es care o' this declaration. N%T3: 5 directive is not )uite the same thing as a statement0 although they may loo similar. %ne critical di''erence is that a directive does not end !ith a semicolon (L*. There is e4actly one 'unction !ith s"ecial status to C itsel': the main 'unction. Nou must have a main 'unction some!here 'or your "rogram to actually do anything0 (ut e4ce"t 'or that0 main o(eys all the (asic C "rinci"les a""lying to 'unctions. So main should return a value too0 shouldnHt itW This is true0 and it e4"lains the second !arning: main has no return value. The !ay to clear u" this "ro(lem is to "recede main !ith the ey!ord void0 !hich tells the com"iler not to e4"ect the 'unction to return a value: void main(* K 3arlier + stated that every 'unction must return a value0 (ut void 'unctions are the e4ce"tion. The com"lete !arning:'ree "rogram is no!: Tinclude Ustdio.hV

void main(*K "rint'(I$rogramming0 it sounds li e 'un.I*L M

,ome %heor( of Com-iling and &in+ing


+t !ould (e nice i' "rograms ran (y magic0 (ut 'irst they have to (e com"iled and lin ed. This is true 'or a num(er o' reasons0 !hich +Hll ta e some time to e4"lore here. If youre already comfortable with the concept of language translators, you can safely skip to the next section. You can also skip this section if you dont like theory. There is no availa(le !ay to !rite "rograms directly 'or most com"uters0 using their native language. $rograms have to 'irst (e translated into (inary code that the com"uter can e4ecute. 3ven assem(ly language0 !hich conce"tually is nearly the same thing as machine language0 has to (e translated. /or e4am"le0 the assem(ly language instruction <&$ ,513,= must (e translated into the (inary code that the "rocessor recogniPes as a 6um" (<&$* instruction. These 'acts seem to create a cou"le o' chic en:and:egg "ro(lems that "uPPled me 'or the 'irst several years + had anything to do !ith com"uters. The 'irst is an immediate "ro(lem. +' the com"uter understands nothing (ut ones and Peros0 !ho or !hat does the translating (et!een C0 15S+C0 and assem(ly language0 on the one hand0 and machine language0 on the other handW #hat 'orms the (ridge (et!een the com"uter and me0 considering that neither s"ea s the otherHs languageW (5s an analogy0 i' you understand only 3nglish and + understand only 2erman0 neither o' us can translate 'or the other.* The ans!er is that a s"ecial "rogram understands (oth languages. This s"ecial "rogram has itsel' already (een com"iled0 so it consists o' instructions in (inary codeSit can there'ore run on the com"uter. 5t the same time0 the logical structure o' the "rogram ena(les it to recogniPe statements in a language such as C0 15S+C0 or assem(ler. The underlying "rinci"le is something li e a Xen oan. DonHt !orry i' you donHt get it right no!0 (ut itHs !orth understanding eventually. The "rocessor is unso"histicated in terms o' its (ehavior. +t can res"ond only to a 'inite set o' instructions. 1ut a !hole series o' instructions0 "ro"erly ordered0 creates rich and com"le4 (ehavior that the chi" designer couldnHt even imagine. Such a series o' instructions is a "rogram. 5s an analogy0 + can translate (et!een any languages i' + have a com"rehensive instruction (oo that tells me ho! to do it. The instruction (oo must (e !ritten in my native language0 (ut + donHt need to no! anything else (assuming + have enough time and "atience to 'ollo! the instructions0 a )uality com"uters have in a(undance*. 5 "rogram "lays the role o' this instruction (oo . The "rocessor carries out the instructions0 one at a time. This s"ecial "rogram is called a lang$age translator0 o' !hich there are three main inds: com-ilers. inter-reters. and assem/lers. +n e''ect0 these are "rograms that hel" you create your o!n "rograms. (Nes0 you can !rite your o!n language translator i' you !ant0 although this re)uires )uite a (it o' s"ecialiPed no!ledge.* #ith C0 the translator is nearly al!ays a com"iler0 meaning that it !aits until you are 'inished !riting a "rogram 'ile and then translates the !hole thing. Visual 1asic0 !hich is a cross (et!een an inter"reter and a com"iler0 translates a little (it o' code every time you enter a statement. The 'ormer a""roach (that o' C* ta es more time to "re"are your "rogram a'ter you 'inish !riting it0 (ut this a""roach is necessary 'or higher:)uality

code. The resulting "rogram runs 'aster and ta es u" less s"ace. NouHll have to !ait !hile the com"iler translates your "rogram0 (ut the !ait is 'or a good reason. The second chic en:and:egg "ro(lem is this: ho! can anyone create a translator in the 'irst "lace0 i' no one ever !rites directly in machine languageW This "ro(lem is similar to the 'ollo!ing "ro(lem in economics: i' nothing can (e (uilt 'rom scratch and i' every tool re)uires the e4istence o' another tool in order to (e (uilt0 then ho! did our industrial society ever come to e4istW This is the 'amiliar 1ootstra" "ro(lem: ho! do you get startedW 1ut the +ndustrial 8evolution did ha""en0 and a similar revolution has (een going on !ith com"uters. 3ssentially0 !henever a ne! chi" is introduced0 the manu'acturer ma es sure that a rudimentary assem(ler and systems so't!are are availa(le. This initial software may be generated on another previously existing computer. (This is called cross platform development.! .ltimately0 you can trace the lineage o' all so't!are (ac to a time !hen "eo"le really did !rite in machine code and 'ed it into a dinosaur in the 'orm o' "unch cards. The 'inal stage in (uilding a "rogram is usually lin ing. ,in ing is the "rocess o' (ringing together your "rogram module !ith code 'rom li(rariesL this is !hat ma es it "ossi(le 'or you to call the "rint' 'unction. +n addition0 i' you (rea your "rogram into multi"le modulesSes"ecially use'ul 'or multi"rogrammer "ro6ectsSthe "rocess o' lin ing connects these modules and com"letes 'unction calls (et!een the modules. ,in er errors tend to occur !hen a 'unction re'erred to in one module is not de'ined any!here else or is de'ined in a !ay that is inconsistent !ith ho! it !as used. %'ten0 you clear u" a lin er error (y ma ing sure that a li(rary is in the right directory or that the environment varia(les are correctly set. The (ottom line is that a'ter you !rite a "rogram0 there is a !ait !hile the com"iler e4amines your "rogram 'or correctness and translates it. 1ut there are good reasons 'or having to !ait. No! itHs time to get (ac to creating "rograms.

Printing More than One &ine


The a(ility to "rint only one line is much too limiting0 so letHs add the a(ility to "rint multi"le lines. /irst0 +Hll introduce you to a 'unny character0 the ne!line. +n C notation0 it loo s li e this: \n )O%01 DonHt 'orget that this se)uence uses a (ac slash (Y*0 not a 'or!ard slash (/*. ThatHs the mista e + made the 'irst =F times + tried !riting a C "rogram. The (ac slash is CHs !ay o' re"resenting a s"ecial character inside a string o' te4t. Some o' the s"ecial characters include the ne!line (Yn*0 the ta( (Yt*0 and em(edded )uotation mar s (YR*. 5 (ac slash indicates that the character to 'ollo! has s"ecial meaning. ,o what do (o$ do if (o$ want to -rint an act$al /ac+slash2 %he answer is1 $se two /ac+slashes 3445 . T!o (ac slashes result in "rinting one (ac slash0 'our (ac slashes result in "rinting t!o0 and so on. 1y "utting Yn inside a string0 you cause the "rint' 'unction to advance to the ne4t line !here indicated. /or e4am"le0 the 'ollo!ing "rogram starts a ne! line a'ter each line o' te4t is "rinted: #include <stdio.h> void main (){ printf("Line 1\n"); printf("Line 2\n");

printf("Last line"); %ne thing that may sur"rise you is that (ecause Yn is a character li e any other0 you can 'reely em(ed it inside a te4t string. The 'ollo!ing "rogram "rints the same results: #include <stdio.h> void main() { printf("Line1\nLine2\nLast line"); Nou can even dou(le:s"ace0 i' you !ant to: #include <stdio.h> void main() { printf("Line1\n\nLine2\n\nLast line"); +t should (e clear !hat is going on at this "oint. 5s the "rint' 'unction reads each character that is not a (ac slash0 it out"uts the character to the terminal as is. +'0 ho!ever0 it reads a (ac slash0 it inter"ets the ne4t character as a s"ecial character. #hen an QnR 'ollo!s the (ac slash0 it causes out"ut to start on a ne! line. (5nother !ay o' saying this is to say that "rint' generates a carriage return.* +' there is te4t remaining in the string0 "rint' continues reading characters normally. 1y the !ay0 itHs common "ractice to terminate every lineSeven the lastS!ith a ne!line (Yn*0 unless you no! that the ne4t in"ut or out"ut is to continue on the same line. #ith this a""roach0 the 'irst e4am"le in this section !ould (e re!ritten as: #include <stdio.h> void main (){ printf("Line 1\n"); printf("Line 2\n"); printf("Last line\n");

Data Declaration and )$m/er Cr$nching


To do anything use'ul in C0 you need to de'ine varia(les. +' you have ever used any other "rogramming language0 you no! that a varia(le is 6ust a "lace in memory that stores a value 'or you. 5ny varia(le you use must 'irst (e declared0 (ecause C needs to no! !hat ind o' data youHre storing and ho! much s"ace to allocate in memory. &ost "rogramming languages re)uire e4"licit declaration0 although a 'e! (such as 15S+C* let you declare varia(les (y de'aultL i' you use a varia(le !ithout declaring it0 15S+C ma es assum"tions a(out the ty"e and attri(utes o' the varia(le. 1ut in com"uter "rogramming0 as in li'e0 relying on assum"tions is dangerous. C has no de'ault declarations0 and C "rogrammers usually donHt mind the small amount o' additional !or that this ma es necessary. The 'ollo!ing three lines o' code gives e4am"les o' C data de'initions ('or no!0 donHt !orry a(out the di''erence (et!een de'inition and declaration*: dou!le "; int count; int i# $# emplo%ee&num;

These statements0 li e any other C statements0 are each terminated (y a semicolon (L*. The ey!ords do$/le and int s"eci'y data ty"esSdou(le:"recision 'loating "oint and integer0 res"ectively. (The di''erence (et!een these ty"es is that the com"uter can mani"ulate integers much more e''iciently0 (ut only 'loating:"oint varia(les can store 'ractional )uantities.* The names 40 count0 i0 60 and em"loyee9num in the "receding e4am"le all (ecome the names o' varia(les created (y the de'inition. 34ce"t 'or 40 all the varia(les are integers. 5n e4am"le "rogram should hel" clari'y this. #include <stdio.h> void main(){ int i# $; i ' 1; $ ' 2; printf("(he sum of i and $ is )d"# i * $); This e4am"le introduces a very use'ul 'eature o' "rint': 'ormatted num(er out"ut. The 'irst argument to "rint' is the 'ormat string: IThe sum o' i and 6 is ZdI This is a )uoted string o' te4t in !hich most characters are "rinted literally (ut some se)uences o' characters have s"ecial meaning. T!o:character se)uences starting !ith a (ac slash (Y* are one ind o' s"ecial se)uence0 as !eHve seen. 5nother ind o' s"ecial se)uence consists o' those starting !ith the "ercent sign (Z*. Such se)uences "rint num(ers. S"eci'ically0 the meaning o' Zd is0 Q$rint the integer value o' the ne4t argument.R +n this case0 that argument is the result calculated (y adding the value o' i to the value o' 6: i+6 The "ractice o' com"uter languages varies 'rom standard 3nglish here. Note the "lacement o' the comma (0* in the com"lete statement: "rint'(IThe sum o' i and 6 is ZdI0 i + 6*L The comma must a""ear a'ter0 not (e'ore0 the second )uotation mar (I*. The role o' the comma is to se"arate the t!o arguments0 and it must a""ear between those arguments. +n this case0 at least0 the rule im"osed (y the "rogramming language is a good deal more logical than 3nglish is. Nou donHt "lace the comma inside the )uotation mar s unless you intend 'or it to (e "rinted. Commas can (e used in (oth !ays0 o' course. Nou could "lace a comma inside the )uotation mar s (ecause you actually did !ant to "rint it. NouHd still need to "lace another comma outside the )uotation mar s so that the arguments !ould (e se"arated. Nou can e4"eriment !ith much more interesting calculations here0 such as the 'ollo!ing 'loating:"oint calculation. Note that almost all 'loating:"oint calculations assume that data ty"es and return values are do$/le (dou(le "recision*0 !hich "rovides greater accuracy than single "recision (float*. 5nother thing to ee" in mind is that to "rint a 'loating:"oint value0 you must use Z'0 not Zd. /or e4am"le: Tinclude Ustdio.hV Tinclude Umath.hV void main(*K dou(le a [ G.FL dou(le ( [ >.FL

dou(le cL c [ s)rt(a \ a + ( \ (*L "rint'(IThe hy"otenuse [ Z'I0 c*L M This e4am"le introduces a cou"le o' ne! 'eatures !orth commenting on. /irst0 the "rogram calls another 'unction0 s)rt. ,i e "rint'0 s)rt is "rovided (y the standard li(rary. The math.h header 'ile "ro"erly declares the s)rt 'unction0 so math.h is included at the (eginning o' the "rogram. +' s)rt is not declared0 C assumes that the 'unction returns an integer value0 !hich in 'act it does not (li e most math 'unctions0 s)rt returns a dou(le:"recision 'loating:"oint result*. This !ould (e a serious "ro(lem (ecause it !ould cause the com"uter to ma e a mista e a(out !hat ind o' data to "ass.
)O%01 The s)rt 'unction ta es the s)uare root o' its argument0 (ut C "rogrammers a''ectionately re'er to this 'unction as the Qs)uirtR 'unction.

+tHs al!ays good to declare all 'unctions (e'ore using them. +' the 'unction is 'rom the standard C li(rary0 thereHs a header 'ile availa(le !ith the a""ro"riate declaration. Documentation on li(rary 'unctions indicates !hich header 'ile to include. 5nother 'eature introduced here is the use o' de'inition and assignment o' values in the same statement. This assignment is actually initialization0 and it has some im"ortant restrictions: dou(le a [ G.FL dou(le ( [ >.FL dou(le cL The varia(les a and ( are "ro"erly intialiPed !ith constant values. #hen you com(ine varia(le de'inition !ith the e)ual sign ([* this !ay0 the value assigned must (e a constantL the com"iler must (e a(le to determine !hat this value is at the time the com"iler reads the "rogram. The ne4t statement0 !hich assigns a value to the varia(le c0 cannot (e com(ined !ith a declaration0 (ecause the value on the right is not a constant: c [ s)rt(a \ a + ( \ (*L This may seem li e a lot o' rules0 (ut it stems 'rom the 'act that the C language reuses o"erators very e''iciently. #hen you de'ine a varia(le (such as a0 (0 or c*0 you can give it an initial value0 (ut ma e sure it is a constant. The use o' the e)ual sign ([* in other inds o' statements is much more 'le4i(le. Nou can "lace any varia(le on the le't side and any valid e4"ression on the right. The "revious line o' code0 !hich calcalates the value o' c0 is an e4am"le.

,ome Comments a/o$t Comments


No "rogramming language !ould (e com"lete !ithout a 'acility 'or "lacing comments in the "rogram. +t (others me !hen "rogramming manuals say things such as QComments e4"lain the "ur"ose o' the code you !rite.R #ell0 thatHs not automatically true. The comment 'acility gives you the ca"a(ility to include such e4"lanations0 (ut you have to !rite them yoursel'. +' you !anted to0 you could go craPy and "lace any !ords in comments0 even the !ords to Q&ary -ad a ,ittle ,am(.RThe com"iler a(solutely does not care. -o!ever0 itHs certainly in your interest to "lace in'ormation in comments that may (e hel"'ul to someone reading the "rogram. Technically s"ea ing0 a comment consists o' te4t that the com"iler ignores. $eriod. The te4t you "ut there !onHt (e evaluated as "art o' the C "rogram itsel'. Net you really ought to use comments (ecause humansSas !ell as com"utersSo'ten have to read "rograms. 5s a "rogram

gro!s in com"le4ity0 you may not understand the "ur"ose o' a declaration or statement !ritten earlier0 even i' you !rote it yoursel'. The solution to this "ro(lem is to use a healthy dose o' comments and to say things that !ill (e hel"'ul 'or someone loo ing at the code. C comments consist o' te4t (et!een the sym(ols /\ and \/. This te4t may occur on a single line or can s"an multi"le lines. /or e4am"le0 the last e4am"le in the "receding section could "ro'ita(ly (e commented as 'ollo!s: Tinclude Ustdio.hV Tinclude Umath.hV void main(*K /\ Declare a0 (0 and c as three sides o' a triangle0 in !hich a and ( are G and > units long. \/ dou(le a [ G.FL dou(le ( [ >.FL dou(le cL /\/ind hy"otenuse and "rint result. \/ c [ s)rt(a \ a + ( \ (*L "rint'(IThe hy"otenuse [ Z'I0 c*L M 5gain0 the com"iler ignores all the te4t (et!een /\ and \/. The e4act !ording and s"elling are there'ore unim"ortant.

%he 6rammar of C
$rogramming0 i' you thin a(out it0 is all a(out "atterns. 5 "rogramming:language grammar is a set o' "atterns 'or "utting !ords and sym(ols together to 'orm meaning'ul actions. #hen you understand the "atterns !ell enough0 you can use them to get the com"uter to do anything you !ant0 !ithin limitations. 1ut !ithout some ind o' easy introduction to C0 loo ing at a "ure0 com"rehensive summary o' CHs grammar !ould (e over!helming. /or this reason0 !eHll start !ith "atterns around !hich you can (uild sim"le "rograms and then gradually add to their com"le4ity. The sim"lest "rograms 'ollo! this "attern: include&directives void main () { data_declaration_statements executable_statements include_directives use the 7incl$de ey!ord to read header 'iles (the effect is the same as if you typed the entire file right into your program code*. 5s mentioned earlier0 such header 'iles are necessary (ecause C doesnHt no! anything a(out li(rary 'unctions. +t doesnHt no!0 'or e4am"le0 !hether the s)uare root 'unction (s)rt* returns an integer or a 'loating:"oint result. Nor does it no! ho! many arguments to e4"ect. The header 'iles0 such as stdio.h and math.h0 "rovide this in'ormation. 34am"les o' 7incl$de directives are: #include <stdio.h> #include <math.h>

#include <strin+.h> #hen you use a li(rary 'unction0 such as "rint'0 consult C standard:li(rary documentation to determine the corres"onding header 'ile to include. 5 header 'ile needs to (e included no more than one time0 regardless o' ho! many di''erent 'unctions re)uire it. 8o$ ma( /e wondering wh( these lines of code are called 9directives: and wh( the( don;t end with a semicolon. This is the ind o' distinction that can drive a novice craPy0 although e4"erienced C "rogrammers gro! used to it. The easiest0 most "ractical rule to remem(er is that any line (eginning !ith a "ound sign (T* is a directive0 and0 unli e statements0 directives are not terminated !ith semicolons. )O%01 +n case youHre curious0 a directive is an instruction to the com"iler that controls a general condition during com"ilation. /or e4am"le0 there are directives that a''ect re"orting o' error and !arning messages. 5 C statement0 in contrast0 either declares data or is translated directly into an action that is "er'ormed !hen the "rogram is actually running. The distinction (et!een statements and directives may seem ar(itrary0 es"ecially (ecause there are some directives that can have im"ortant e''ects on "rogram (ehavior. +t may (e easiest 'or no! 6ust to remem(er that i' something (egins !ith a "ound sign (T*0 itHs a directive. 1y data_definition_statements0 + re'er to varia(le de'initions you "lace in your "rogram. 5lthough technically you donHt have to have varia(les0 virtually any "rogram that does anything use'ul has at least a 'e!. +n C0 varia(le de'initions are statements0 and each must (e terminated (y a semicolon (L*. The sim"lest data de'initions declare one varia(le each. The ty"e nameSint0 long0 or do$/le in the 'ollo!ing e4am"lesS"recedes the varia(le name: dou!le "; dou!le %; dou!le h%potenuse; int total; int c; Varia(le declarations in C ena(le you to de'ine as many varia(les on the same line as you choose Sas long as you se"arate the names (y using commas. /or e4am"le0 the 'ollo!ing e4am"le de'ines the same dou(le:"recision 'loating "oint varia(les and integers that the "receding e4am"le does. +n the 'irst line0 40 y0 and hy"otenuse are all de'ined as having ty"e do$/le0 meaning that each varia(le stores dou(le:"recision 'loating:"oint data. The varia(les total and c are integers. dou!le "# %# h%potenuse; int total# c; Nou can also com(ine muli"le data de'initions !ith initialiPation: dou!le ,ei+ht ' -..# hei+ht ' 1./; int i# $# 0 ' 1; int a ' /# !# c ' 21; /inally0 (y executable_statements + re'er to the rest o' the "rogram. These statements ta e some sort o' action during run time. Data de'initions0 in contrast0 donHt cause any actions !hile the "rogram is actually runningL they 6ust reserve s"ace. The distinction (et!een data de'initions and e4ecuta(le statements is im"ortant0 (ecause you must "lace all data de'initions ahead o' all e4ecuta(le statementsSthe t!o inds cannot (e

intermingled. 34ecuta(le statements can do a lot o' things0 (ut nearly all o' these things 'all into one o' three ma6or categories o' actions: < Call a 'unction. < 5ssign a value to a varia(le (or other memory location*. < Trans'er "rogram control to a ne! location or "er'orm an action conditionally. The last category involves control structures0 !hich !eHll start to e4amine later in the cha"ter. 5side 'rom control structures0 nearly all actions in C (oil do!n to either calling a 'unction or assigning a value. &any statements do (oth0 as in the 'ollo!ing statement0 !hich uses the result o' the s)rt 'unction to hel" calcuate the ne! value o' c: 23 4alculate c as the s5uare root of a s5uared plus ! s5uared. 32 c ' s5rt(a 3 a * ! 3 !); This list o' action categories shouldnHt (e too sur"rising i' youHve loo ed at other "rogramming languages. 5ll the "rocessor can do0 really0 is move data0 "er'orm calculations0 or 6um" to a ne! instruction. 5s !ith all other high:level languages0 C lets you com(ine assignment to a varia(le !ith calculation. C is no di''erent 'rom any other language in this res"ect e4ce"t that it com(ines t!o inds o' routines ('unctions and "rocedures in 15S+C* into one: the C 'unction. 5(out the only innovation here is that C uses 6ust one ty"e o' su(routine: the 'unction. Nou can use a 'unctionHs return value 'or calculation0 as !as done in the "receding e4am"le. 1ut you can also thro! a!ay the return value0 6ust as you !ould !ith a 15S+C "rocedure or a /%8T85N su(routine. /or e4am"le: printf("(he value of c is )f\n"# c);

0=ercise Solve the "ro(lem and get introduced to Data Ty"es0 "rogramming Constructs and &odular "rogramming.
#rite a "rogram to acce"t t!o num(ers and Dis"lay highest o' the t!o. Dis"lay all the odd num(ers (et!een the t!o (inclusive o' (oth*. Dis"lay all the even num(ers (et!een the t!o (inclusive o' (oth*.

%ime O$t for a Few Definitions of %erms


.ntil no!0 +Hve assumed that you no! some o' the standard terms 'rom math and com"uter "rogramming. +n case +Hve assumed too much0 here are de'initions 'or terms that come u" a lot in this cha"ter and in others. >rg$ment This is a term that comes u" a lot in this (oo . &any "eo"le use argument interchangea(ly !ith "arameter. 5lthough there is a di''erence0 + donHt thin itHs !orth !orrying a(out too much here. 5n argument is a value that you "ass to a 'unction. /or e4am"le0 in the 'ollo!ing line o' code0 angle5 and angle1 are arguments to the Calculate95ngle 'unction0 and angleC is a varia(le that stores the result: /\ angle5 and angle1 are arguments \/

angleC [ Calculate95ngle(angle50 angle1* 5s youHll see in Cha"ter G0 you can use the same or di''erent varia(les !ithin the 'unction de'initionSthe code that de'ines !hat Calculate95ngle does. Some "urists insist on calling the values actually "assed arguments and the varia(les used in de'initions "arametersSor alternatively0 actual arguments vs. 'ormal argumentsS(ut !eHll stic !ith using arguments e4ce"t !here the distinction is critical. #nteger Nou may recall 'rom high:school math that an integer is a !hole num(er (no 'ractional "ortion* that can range into negative values as !ell as Pero or "ositive. This corres"onds e4actly !ith the conce"t o' integer (int* in C and other languages. 2enerally s"ea ing0 'loating:"oint varia(les can hold any value that an integer can0 so !hy use integers at allW The reason is that 'loating:"oint math is much more com"le4. 5 C$. can o"erate 'ar more e''iciently on an integer. &oreover0 there are many cases in !hich a varia(le needs to hold a num(er that !ill never (e a 'raction. 3ver. 5n e4am"le is a varia(le used to count tri"s through a loo". +ntegers are a much (etter choice 'or data re"resentation in such cases. Floating-Point ?al$es /loating:"oint values can hold 'ractions. %ther languages o'ten re'er to 'loating:"oint values as reals ('or real num(ers*0 and0 realistically s"ea ing0 the terms can (e used interchangea(ly. To "rovide ma4imum 'le4i(ility0 'loating:"oint values are re"resented !ith a ind o' scienti'ic notation involving sign0 e4"onent0 and mantissa. +' you donHt remem(er these terms 'rom school0 thatHs %K0 (ecause itHs all su""osed to (e hidden 'rom you any!ay. The only thing to remem(er is that it re)uires more com"uting "o!er 'or the "oor little C$. to handle 'loating "oint0 although modern:day math co"rocessors do hel". /or o"timal results0 stic to integers as much as "ossi(le. ,ingle-Precision ?al$es 5 single:"recision value in C is a 'loating:"oint value stored in 'our (ytes. Strangely0 varia(les o' this ty"e are declared !ith the 'loat ey!ord. Do$/le Precision ?al$es 5 dou(le:"recision value (dou(le* in C is a 'loating:"oint value stored in eight (ytes. These values re)uire more s"ace (ut "rovide su(stantially more range and accuracy. 1ecause o' the necessary conversion (et!een decimal ('or dis"lay* and (inary ('or internal storage*0 thereHs usually a loss o' "recision !henever 'ractions are involved. /or this reason0 i' you are going to do 'loating:"oint calculations0 dou(le "recision is much (etter. 0=-ressions 5n e4"ression is a single num(er or varia(le0 or a com(ination o' varia(les0 num(ers0 and o"erators (such as +* that evaluates to a single value. The numeral ? is an e4"ressionL so is 4 + y. +n C0 e4"ressions have an interesting relationshi" to statements (the (asic unit o' e4ecution* as descri(ed in the ne4t section. 0=-ressions and ,tatements %ne o' the areas in !hich C most strongly de"arts 'rom other languages is in its conce"t o' e4"ressions. There are some "oints here that arenHt o(vious0 and you need to understand them to 'ully ta e advantage o' C or to read C code.

+n 15S+C or /%8T85N0 !hich are ty"ical o' most com"uter languages0 you can only assign a value to only one varia(le at a time. /or e4am"le0 the 'ollo!ing is a com"lete statement in either 15S+C or /%8T85N: i[6+= 15S+C and /%8T85N use a single e)ual sign ([* to sho! assignment. C does the same. +n $ascal0 youHd use the :[ sym(ol instead: i :[ 6 + = $ascal also uses semicolons in its o!n "erverse 'ashion0 (ut letHs not get into that. #ith all three languagesS15S+C0 /%8T85N0 and $ascalSyou can loo at this e4"ression and no! that it 'orms a com"lete statement. 1ut !ith C0 the e)ual sign ([* is an o"erator li e any other0 and it returns a value 6ust as o"erators such as +0 ]0 \0 and / do. This means that assignment may (e "er'ormed in the middle o' a larger e4"ression. 5n e4am"le should hel" clari'y. Nou can !rite the same e4"ression in C as you can in 15S+C or /%8T85N0 (ut the C version returns a valueSnamely0 the value that !as assigned: i[6+= /\ Value o' this e4"ression is 6 + = \/ 5nd hereHs !here !e can see the (ig di''erence. 1ecause this assignment returns a value (namely0 6 + =*0 you can "lace the !hole thing inside a more com"le4 e4"ression: [ i [ 6 + =L #hat is this 'unny:loo ing constructW To understand it0 you 'irst have to understand that the associativity o' assignment is right:to:le't0 !hich means that !hen more than one assignment o"erator ([* is involved0 the rightmost assignment is evaluated 'irst. Conse)uently0 the "receding e4am"le is e)uivalent to: [ (i [ 6 + =*L The su(e4"ression i [ 6 + = does t!o things: it assigns the value o' 6 + = to i and then it returns the value that !as assignedSnamely0 6 + =. 8e"lacing the right side !ith 6 + = creates the 'ollo!ing e4"ression: [ 6 + =L +n other !ords0 a'ter i is assigned the value 6 + =0 that value is then assigned to . So (oth and i are assigned the value o' 6 + =. ,etHs loo at another e4am"le0 !hich uses a common coding techni)ue. This e4am"le assigns the value F to all 'our varia(les: a0 (0 c0 and d. a [ ( [ c [ d [ FL 5gain0 associativity is right:to:le't. There'ore0 this e4"ression is e)uivalent to: a [ (( [ (c [ (d [ F***L /\ 5ssign F to d \/ The su(e4"ression d [ F o(viously assigns F to d. The return value o' d [ F is F0 !hich means that the "rogram acts as though d [ F !ere re"laced !ith F. The "rogram then evaluates the statement as i' it !ere: a [ (( [ (c [ F**L /\ 5ssign F to c \/ This causes F to (e assigned to the varia(le c. The "rocess continues0 (y successive ste"s: a [ (( [ F*L /\ 5ssign F to ( \/ a [ FL So a0 (0 c0 and d all get the value F. The statement isnHt really (eing re!ritten. The "rogram statements al!ays remain intact and can (e e4ecuted re"eatedly (!hich can ha""en !hen you !rite a loo"*. #hatHs going on is that the C com"iler inter"rets the statement as though it !ere a series o' smaller statements.

,etHs loo at one more e4am"le. 1ecause the e)ual sign ([* is an o"erator li e any other0 it can (e com(ined !ith other o"erators0 such as addition (+*. /or e4am"le0 assume that a0 (0 and c are all integer varia(les: a [ = + (( [ = + (c [ GF**L /\ 5ssign GF to c \/ The "rogram 'irst evaluates c [ GF0 !hich "laces GF into c and returns the value GF. The "rogram then "roceeds as i' the su(e4"ression c [ GF !ere re"laced (y its return value0 GF: a [ = + (( [ = + GF*L /\ 5ssign G= to ( \/ No! the "rogram evaluates ( [ = + GF0 !hich "laces G= into ( and returns the value G=. The "rogram "roceeds as i' the su(e4"ression ( [ = + GF !ere re"laced (y the value G=: a [ = + G=L /\ 5ssign G; to a \/ /inally0 a is assigned the value G;. N%T3: +n the "receding e4am"le0 "arentheses are necessary. 5lthough you can 'reely mi4 the assignment o"erator ([* !ith other o"erators0 the assignments must ma e sense. C language e4"ressions are governed (y CHs rules o' "recedence0 !hich dictate that addition (+* is evaluated (e'ore assignment ([*. Consider !hat !ould ha""en i' the "receding e4am"le had no "arentheses: a [ = + ( [ = + c [ GFL 1ecause addition (+* has higher "recedence than assignment ([*0 this statement is e)uivalent to: a [ (= + (* [ (= + c* [ GFL This in turn "laces the su(e4"ression (= + c* on the le't side o' an assignment: (= + c* [ GF This last e4"ression clearly ma+es no sense and is e4"licitly disallowed /( r$les of C synta4. There'ore0 !hen you mi4 assignment !ith other o"erations0 (e sure to use "arentheses to clari'y order o' evaluation. This 'le4i(ility in the use o' assignment has im"ortant im"lications 'or C synta4. 5ssignments are 6ust one o' the (uilding (loc s o' e4"ressionsSassignments donHt automatically 'orm com"lete statements as they do in other languages. #hen does an e4"ression (ecome a statementW ThatHs sim"le: !hen itHs terminated (y a semicolon. 5n e4"ression terminated (y a semicolon is the most common ty"e o' statement in C: e4"ressionL This synta4 has some interesting conse)uences. +t im"lies that any e4"ression can (e terminated !ith a semicolon to 'orm a com"lete statement. Such e4"ressions donHt even have to involve assignment. -ereHs an e4am"le: 4L i + 6L total \ sum + ;L ?L ;D.FL Nou !ill li ely never see these statements in a real C "rogram0 'or the good reason that they donHt actually do anything. 1ut they are legal 6ust the same. 5s !ith all e4"ressions0 each o' these returns a value. 1ut !hen a statement is terminated (y a semicolon0 the overall value o' the e4"ression is thro!n a!ay. #hat you !ill see0 and o'ten0 are e4"ressions in !hich a 'unctionHs return value is ignored. /or e4am"le0 (oth o' the 'ollo!ing are legal constructs: result [ Calc(a0 (0 c*L

Calc(a0 (0 c*L Nou could !rite either statement de"ending on !hether you !anted to save the result o' the 'unction. This is a nice convenience0 (ecause some times you may care a(out the result o' the 'unction and other times you may not. N%T3: The 'irst statement in the "receding e4am"le is not legal i' the 'unction is declared void0 although the second statement is al!ays legal. &any 'unctions (o' !hich "rint' is a "rominent e4am"le* have side e''ects: they do more than 6ust return a value. #hen a 'unction has side e''ects o' some ind0 a 'unction call can (e use'ul even though it has no return value or that value is ignored. Ret$rning a ?al$e to the ,(stem The main 'unction can return a value 6ust as other 'unctions can0 de"ending on ho! you declare it. The value returned (y main is "assed (ac to the system or calling "rocess. 5n e4am"le o' !here such a return value might (e used is in an &S:D%S (atch 'ile. The value returned (y the "rogram (its return code* can cause a 6um" to a ne! location !ithin the (atch 'ile0 assuming that the 'ile is !ritten to test the "rogramHs return code. 5s a rule0 a return code o' F indicates that the "rogram detected no "ro(lems. 1y convention0 a nonPero return code indicates an error. The revised synta4 'or a "rogram is: include9directives int main (* K data9declaration9statements e4ecuta(le9statements return e4"ressionL M Strictly s"ea ing0 this synta4 isnHt a(solutely "recise0 (ut it gives you an idea o' !hatHs "ossi(le. 5ctually0 the return statement can occur any num(er o' times !ithin e4ecuta(le9statements0 and it doesnHt necessarily have to occur on the last line. 5s a 'irst e4am"le0 the 'ollo!ing "rogram "rints out a message and returns F unconditionally0 to indicate sucess: Tinclude Ustdio.hV int main(* K "rint'(I-ello0 there.YnI*L return FL M &ore ty"ical is the ne4t e4am"le0 !hich tests 'or an error condition (a Pero divisor* (e'ore deciding !hether to return an error code: Tinclude Ustdio.hV Tinclude Umath.hV int main(* K dou(le divisor0 )uotientL scan'(IZ'I0 divisor*L

i' (divisor [[ F* return :=L )uotient [ =FF.F / divisorL "rint'(IThe )uotient is ZdYnI0 )uotient*L return FL M This e4am"le introduces the use o' the C i' statement0 !hich in this case tests the value o' divisor (e'ore deciding !hether to return an error code. Note care'ully the use o' dou(le e)ual signs ([[* to test 'or e)uality. i' (divisor [[ F* return :=L #eHll see a lot more o' the i' statement in later cha"ters. The sim"lest 'orm o' the i' statement has the 'ollo!ing 'ormat: i' (condition* statement + should clari'y that condition is 6ust an integer e4"ression. 5n e4"ression evaluating to Pero means 'alseSstatement is not e4ecutedS!hereas everything else means true. This im"lies that any integer e4"ression is valid in this conte4t. So you can !rite this: i' (=* return :=L 1ut this code !ould mean return ]= unconditionally0 !hich is silly0 i' you thin a(out it0 (ecause it !ould (e easier 6ust to ty"e: return :=L The i' statement loo s harmless0 (ut it has a 'e! "it'alls that a!ait you. 1y 'ar the !orst is the "ossi(ility o' mista ing the assignment o"erator ([* 'or the test:'or:e)uality o"erator ([[*. 1e care'ulJ These t!o o"erators are very di''erent0 in !ays to (e e4"lained later. /or no!0 6ust ma e sure that you dou(le chec all tests 'or e)uality !ithin an i' condition to ma e sure that dou(le e)ual signs ([[* are in use. There are times !hen you !ill !ant to use the assignment o"erator ([* !ithin a condition0 (ut they are much less common. /or no!0 consider a single e)ual sign ([* !ithin a condition as a sure:'ire indicator o' a (ug. The i' statement is the 'irst e4am"le o' a control structure in this (oo . 5 control structure is a "lace at !hich the "rogram may s i" ahead or (ac instead o' going to the ne4t statement. +n the case o' i'0 a condition that evaluates to 'alse causes the "rogram to s i" over the statement immediately 'ollo!ing the i'. 5 condition evaluating to true lets the "rogram e4ecute that statement. #eHll return to the su(6ect o' control structures in detail0 (ut 'irst letHs move to the all:im"ortant to"ic o' 'unctions in C.

F$nctions
%ne o' the greatest aids in "rogramming is the use o' 'unctions. They can save you 'rom having to ty"e common se)uences o' code over and over. They also let you organiPe your "rogram into logical and coherent units. 5 'unction de'ines ho! to carry out a s"eci'ic tas . %nce the tas is de'ined0 you can have it carried out !herever you !ant0 sim"ly (y calling the 'unction. +' youHve (een 'ollo!ing all thrugh0 youHve seen e4am"les o' 'unction calls:

"rint'(I-i thereJYnI*L scan'(IZdI0 &num(er*L 4 [ s)rt(;.F*L The !ords "rint'0 scan'0 and s)rt re'er to 'unctions0 although only in the last case is the value returned (y the 'unction actually used. +n C0 a 'unction is a 'unction !hether or not it returns a value and !hether or not the value is used. There is no se"arate terminology such as "rocedure0 su(routine0 or su("rogram. %' course0 Qsu("rogramR is a good !ay to suggest !hat 'unctions do. #hen a 'unction is called0 control "asses to the 'unction as i' it !ere a se"arate "rogram. The com"uter then e4ecutes each statement in that 'unction until it either comes to the end o' the 'unction or encounters a return statement. +n either case0 the 'unction is said to return. 5t that "oint0 control returns to the "lace in the "rogram !here the 'unction !as called. 8eturn is an a""ro"riate term. +t means that the "rogram goes (ac to !here it !as (e'ore the 'unction !as called.
Calls to 'unctions such as "rint'0 scan'0 and s)rt !or (ecause these 'unctions are de'ined in the standard li(rary. Nou donHt need to su""ly de'initions 'or the 'unctions.

&ost C "rogrammers usually "lace the main 'unction 'irst0 'ollo!ed (y the 'unctions that main calls directly0 'ollo!ed (y other 'unctions. This style o' "rogram organiPation is the to":do!n a""roach. %he new s(nta= element here is f$nction@-rotot(-esA 5 'unction "rototy"e "rovides ty"e in'ormation to the com"iler. Nou can call a 'unction !ithout 'irst "roviding a "rototy"e0 (ut the com"iler !ould have to assume a de'ault return ty"e (int*0 and it !ould not (e a(le to chec argument ty"es. 5s a rule0 you should al!ays include 'unction "rototy"es 'or each 'unction you call. -ereHs the general 'orm 'or a 'unction "rototy"e: return9ty"e 'unction9name(arguments*L The arguments consist o' a list o' argument declarationsL they are se"arated (y commas i' there are more than one. The declarations0 in turn0 consist o' a data ty"e 'ollo!ed (y an argument name: ty"e name0 ty"e name0 ... -ere are some e4am"les o' "rototy"es: =. Dou(le:"recision result0 integer argument. dou(le /ind8eci"rocal(int n*L ;. Dou(le:"recision result0 three dou(le:"recision arguments. dou(le @uadratic(dou(le a0 dou(le (0 dou(le c*L G. +nteger result0 t!o integer and one dou(le:"recision argument. int 8esetVars(int Ne!Start0 int Delta0 dou(le 8atio*L The argument names have little "ur"ose in a "rototy"e e4ce"t 'or documentation. +' you !ant to0 you can omit argument names 'rom "rototy"es. The 'ollo!ing declarations are e)uivalent to the ones youHve 6ust seen: dou(le /ind8eci"rocal(int*L dou(le @uadratic(dou(le0 dou(le0 dou(le*L int 8esetVars(int0 int0 dou(le*L De'ining the /unction %nce again0 hereHs the 'unction:de'inition "art o' the synta4: return9ty"e 'unction9name ( arguments * K

data9declaration9statements e4ecuta(le9statements M The e4ecuta(le9statements can include one or more return statements (assuming return9ty"e is not void*: return e4"ressionL T!o things may stri e you a(out this synta4. /irst0 it loo s very similar to the synta4 'or the main 'unction. +t should0 (ecause the main 'unction is li e any other 'unction e4ce"t 'or a 'e! ey di''erences (mainly0 that it gets e4ecuted 'irst*. Second0 the 'irst line is almost the same as a 'unction "rototy"e. /or e4am"le0 here is a "ossi(le 'irst line o' a 'unction de'inition: dou(le /ind8eci"rocal(int n* K +n 'act0 the (eginning o' a 'unction de'inition is so close to the synta4 'or a "rototy"e that you can save !or (y co"ying the "rototy"e and "asting it into the de'inition. 1ut there are a cou"le o' im"ortant di''erences (et!een "rototy"es and de'initions: O 5 "rototy"e ends !ith a semicolon (L*0 (ut in a 'unction de'inition0 an o"ening (race (K* 'ollo!s the argument list. /unction de'initions are not terminated (y semicolons at all0 not even a'ter the 'inal (race (M*. +ndividual statements inside the (races !ill have semicolons0 ho!ever. O The argument name is not o"tional in a 'unction de'inition even though it is o"tional in "rototy"es. > Com-lete 0=am-le /unctions donHt do anything until called (y an e4ecuting "rogram. 3ven main has to (e called (e'ore it can e4ecuteSalthough in the case o' main0 the caller is the o"erating system. %nce !ritten0 a 'unction can (e called any num(er o' times. Nou can use this techni)ue to create a more com"act version o' the "rogram:
"ont worry #ead$n to understand the program

Tinclude Ustdio.hV int /actorial(int n*L void main(* K "rint'(IThe 'actorial o' G is ZdYnI0 /actorial(G**L "rint'(IThe 'actorial o' > is ZdYnI0 /actorial(>**L "rint'(IThe 'actorial o' ? is ZdYnI0 /actorial(?**L M int /actorial(int n* K int result [ =L !hile (n V =* result \[ n::L return resultL
M

/\ #hile n V =0 /\ multi"ly (y n decrement n \/

>rg$ments and More >rg$ments (he 6actorial function ta0es a certain amount of li!ert% ,ith its ar+ument# n7 ,hile (n > 1) 23 8hile n > 1# result 3' n99; 23 multipl% !% n decrement n 32 (hese statements cause n to chan+e durin+ e"ecution of the function7 n is continuall% decremented until it is no lon+er +reater than 1. :o n is finall% reduced to 1. ;o,# ,hat do %ou thin0 the follo,in+ statements do< int (emp1# (emp2 ' -; (emp1 ' 6actorial((emp2); printf("(he value of (emp2 is still )d.\n"# (emp2); =f %ou put this code into a pro+ram and run it# %ou>ll find that it produces the follo,in+7 (he value of (emp2 is still -. ?o, can this !e< (he value of (emp2 ,as passed to the ar+ument n# and the function chan+ed the value of n to 1. 8h% didn>t (emp2 chan+e< (he ans,er is that the function +ets a cop% of (emp2>s value !ut not the ri+ht to alter it. (he ar+ument# n# is initiali@ed to the same value as (emp2. (he function then +oes on its merr% ,a% ,ithout havin+ an% further interaction ,ith (emp2. 8hat happens to n later doesn>t matter; the value of n is thro,n a,a% as the function returns. (his is called pass by value. ((he other principal method for passin+ ar+umentsApass by referenceA re5uires pointers in 4 and is the su!$ect of 4hapter 1# BCointers and Dther :harp =nstrumentsE.) Fs a conse5uence# an% valid e"pression can !e passed as an ar+ument as lon+ as it is the ri+ht t%pe. Gou aren>t limited to passin+ varia!les. (he follo,in+ function calls are all le+al7 temp ' 6actorial(1 * 2 * (- 9 1) ); temp ' 6actorial(- * diff); result ' s5rt(1./ * 6actorial(thin+)); 6unctions can have multiple ar+uments. 6or e"ample# here is a protot%pe for the C%tha+oras function7 dou!le C%tha+oras(dou!le a# dou!le !); Fnd here>s the function definition7 dou!le C%tha+oras(dou!le a# dou!le !) { return s5rt(a 3 a * ! 3 !); Dnce C%tha+oras is properl% declared and defined# %ou can pass an% t,o valid ar+uments. (he first ar+ument in the function call is assi+ned to a; the second# to !7 23 Cass -'>a# H'>! 32

h%p1 ' C%tha+oras (-#H); 23 Cass H./'>a# ../'>! 32 h%p2 ' C%tha+oras (H./# ../); 23 Cass temp1'>a# "*-'>!32 h%p- ' C%tha+oras (temp1# "*-); ?ere# of course# the order doesn>t matter. Iut it usuall% does matter ,ith most functions. 6or e"ample# the Juadratic function treats its ar+uments differentl%7 dou!le Juadratic(dou!le a# dou!le !# dou!le c) { dou!le temp; temp ' s5rt(! 3 ! 9 H 3 a 3 c); return ((9! * temp) 2 (2 3 a));

)O%01 &athematically0 this 'unction is incom"lete (ecause it returns only one o' the t!o roots o' a )uadratic e)uation. -o!ever0 the 'unction can return only one value. +n Cha"ter D0 youHll see ho! to return more than one value.

F function can even have no ar+uments. F trivial e"ample is a function that prints a standard messa+e. (he protot%pe uses the void 0e%,ord in the ar+ument list# as does the function definition. =n this conte"t# void simpl% means Bno ar+uments.E int Crint&messa+e(void); ... int Crint&messa+e(void) { printf("6atal error7 stop the pro+ram."); return /; (he function is then called ,ith an empt% ar+ument list# !ut the parentheses must still !e used7 temp ' Crint&messa+e(); +' the 'unction has no need to return a value0 the return value may also (e void. This means that no value is returned at allL in that case0 no ret$rnexpression statement may a""ear !ithin the 'unction de'inition0 and the 'unction0 !hen called0 cannot (e used as "art o' a larger e4"ression. +nstead0 a void 'unction can (e called only directly: Crint&messa+e(); +tHs not very common to see a 'unction !ith (oth a void return ty"e and a void argument list0 (ut such a 'unction !ould (e "er'ectly valid. Note the a(sence o' a ret$rn statement in the 'unction de'inition: void Crint&messa+e(void); 23 function protot%pe 32 ... void Crint&messa+e(void) { printf("6atal error7 stop the pro+ram.");

+' you have a "hiloso"hical turn o' mind0 you might thin o' void as CHs contri(ution to the conce"t o' (eing and nothingness. (To !hat entity does the !ord nothing re'erW* The void ey!ord can mean an em"ty argument list0 orSmore "arado4icallySa return value that is not a return value0 (ut is instead an indicator o' the absence o' return value. %he Bo( of Rec$rsion Sim"ly stated0 recursion occurs !hen a 'unction calls itsel'. This is legal in C0 as it is in many other "rogramming languages. )O%01 8ecursion is an interesting logical and mathematical techni)ue0 (ut itHs not vital to the !riting o' most C "rograms. +' you are eager to understand 6ust the (asics o' C synta40 you can sa'ely s i" this section. Nou might thin that recursion leads automatically to an in'inite regress0 as is the case !hen you "oint a mirror at another mirror. #hen recursion is "ro"erly done0 this doesnHt ha""en at all0 (ecause there is an initial condition. ,etHs return to the 'actorial e4am"le. The 'actorial o' a num(er is the "roduct o' all the integers 'rom = to the num(er. /or any num(er n: factorial of n ' 1 3 2 3 - 3 ... n To go 'rom the 'actorial o' n ] = to n0 multi"ly (y n. /or e4am"le0 here are the 'actorials o' G and >: factorial of - ' 1 3 2 3 factorial of H ' 1 3 2 3 - 3 H &ulti"lying 'actorial o' G (y > "roduces the 'actorial o' >. 2eneraliPing on this0 !e can say: factorial of n ' (factorial of n 9 1) 3 n There is one case in !hich this does not hold: the case o' the num(er =. The 'actorial o' = is sim"ly =. So0 logically0 !e can say: +' n V = then 'actorial o' n [ ('actorial o' n : =* \ n else 'actorial o' n [ = #e can code this logic in a C 'unction very nicely (y !riting a /actorial 'unction that calls itsel': int /actorial(int n* K i' (n V =* return (/actorial(n : =* \ n*L return =L M +' n is greater than =0 the 'irst ret$rn statement causes the 'unction to return immediately a'ter calculating the value. %nly i' n is not greater than = does the second ret$rn get e4ecuted. The statements there'ore create an Qi':then:elseR logic. This a""roach results in a !hole series o' 'unction calls0 (ecause0 in most cases0 (e'ore the 'unction can com"lete e4ecution0 it must call itsel'. 1ut during each call to /actorial0 there is a di''erent value o' n. This is "er'ectly 'ine. C su""orts multi"le instances o' the same 'unction0 each !ith its o!n value o' n. +' the main "rogram e4ecutes /actorial(>*0 'or e4am"le0 the series o' actions is:

!A &ain "rogram calls /actorial(>*. CA /actorial(>* calls /actorial(G*. DA /actorial(G* calls /actorial(;*. EA /actorial(;* calls /actorial(=*. FA /actorial(=* returns the value =. A /actorial(;* multi"lies this result (y ; and returns ;. GA /actorial(G* multi"lies this result (y G and returns C. HA /actorial(>* multi"lies this result (y > and returns ;>.

8ecursion can (e a use'ul techni)ue 'or e4"ressing a calculation succinctly. +tHs most o'ten a""lica(le in "rograms that involve com"le4 math or logical relationshi"s. 'owever. (o$ sho$ld /e aware that rec$rsion is almost never the most efficient wa( to im-lement somethingA 2enerally s"ea ing0 any algorithm that can (e e4"ressed through recursion also has an iterative solutionSthat is0 an a""roach that uses a loo" (such as a while loo"*. The recursive a""roach is almost al!ays less e''icient0 (ecause 'or each 'unction call0 there is a certain amount o' overhead. $art o' the 'unction overhead stores the values o' arguments and local varia(les0 such as n0 'or the "articular instance o' the 'unction call. The 'unction overhead also ee"s trac o' !here the 'unction returns !hen 'inished. #;m not sa(ing that (o$ sho$ld never $se rec$rsionI /$t if there is an o/vio$s alternative that $ses a loo- 3as is the case with factorials5. $se the loo- instead. +n some cases0 though0 the recursive version may (e much easier to !rite and nearly as e''icient.
#hy do + mention recursion0 i' it is rarely the (est a""roachW 8ecursion is use'ul as a !ay o' illustrating a (asic 'act o' most real:!orld C "rograms: at any time0 there may (e many 'unction calls "ending. %nly one 'unction call can (e currently e4ecuting0 (ut there may (e a num(er o' them !aiting 'or another 'unction to return.

None o' that !ould (e the case i' you did a!ay !ith all 'unctions e4ce"t main. +n 'act0 you could do 6ust that0 using com"le4 loo"s and control structures to handle re"eated o"erations. -o!ever0 such code !ould (e e4ce"tionally di''icult to !rite0 understand0 and maintain0 even though in theory it might (e slightly more e''icient. +t !ouldnHt (e reusa(leL only !hen you !rite 'unctions can you create "art o' a "rogram so that it can easily (e reused in another "rogram. /unctions0 a'ter all0 "rovide many (ene'its. 5lthough machine:level e''iciency is an im"ortant goal in C0 the a(ility o' a human (eing to !rite good "rograms is even more im"ortant. /or all these reasons0 'unctions are an invalua(le tool. +' you !ant to avoid having to !rite "rototy"es0 one !ay to do so is to de'ine a 'unction com"letely (e'ore using it. This (ottom:u" a""roach means "utting main last. #ith this a""roach0 the /actorial 'unction !ould (e re!ritten as 'ollo!s: Tinclude Ustdio.hV int /actorial(int n* K int result [ =L !hile (n V =* /\ #hile n is greater than =0 \/ result \[ n::L /\ multi"ly result (y n and decrement n \/ return resultL M void main(* K "rint'(IThe 'actorial o' G is ZdYnI0 /actorial(G**L

"rint'(IThe 'actorial o' > is ZdYnI0 /actorial(>**L "rint'(IThe 'actorial o' ? is ZdYnI0 /actorial(?**L M &ost C "rogrammers donHt use this a""roach0 (ecause they li e to start !ith the (ig "icture (the main "rogram* and !or do!n!ard. &oreover0 i' you s"end enough time "rogramming0 youHll 'ind that ultimately there is no esca"e 'rom !riting "rototy"es. +n a serious "rogram0 the relationshi"s (et!een di''erent 'unctions (ecome very com"le4. +t is not uncommon 'or 'unctions to end u" calling each other (a variation on recursion*0 in !hich case it is im"ossi(le to de'ine every 'unction (e'ore it is called. The (ottom line is that you might as !ell get into the ha(it o' "utting a "rototy"e 'or every 'unction at the (eginning o' your "rogram. > Final Word on Protot(-es +n many serious C "rograms0 you !onHt see "rototy"es at the (eginning o' a source:code 'ile0 and 'or a good reason: all the "rototy"es are "laced in a header 'ile0 !hich is then read in !ith a 7incl$de directive. This is a sensi(le a""roach0 es"ecially !hen you have multi"le source 'iles and !ant all o' them to get the "rototy"es 'or all the 'unctions in the "rogram. /or e4am"le0 you might "lace "rototy"es 'or all your 'unctions in a 'ile called my9"rog.h. Then include my9"rog.h along !ith the other header 'iles: #include <stdio.h> #include <math.h> #include "m%&pro+.h" The synta4 'or the last 7incl$de is a little di''erent 'rom that o' the 'irst t!oL the )uotation mar s cause the current directory to (e searched 'or the header 'ile. +n the 'inal analysis0 entering "rototy"es may seem li e unnecessary !or at 'irst0 (ut they are 6ust too use'ul to ignoreSas are 'unctions in general.

OOP,
O/Ject Oriented Programming
Proced$ral. ,tr$ct$red. and O/Ject-Oriented Programming
.ntil recently0 "rograms !ere thought o' as a series o' "rocedures that acted u"on data. 5 "rocedure0 or 'unction0 is a set o' s"eci'ic instructions e4ecuted one a'ter the other. The data !as )uite se"arate 'rom the "rocedures0 and the tric in "rogramming !as to ee" trac o' !hich 'unctions called !hich other 'unctions0 and !hat data !as changed. To ma e sense o' this "otentially con'using situation0 structured "rogramming !as created The "rinci"le idea (ehind structured "rogramming is as sim"le as the idea o' divide and con)uer. 5 com"uter "rogram can (e thought o' as consisting o' a set o' tas s. 5ny tas that is too com"le4 to (e descri(ed sim"ly !ould (e (ro en do!n into a set o' smaller com"onent tas s0 until the tas s !ere su''iciently small and sel':contained enough that they !ere easily understood. 5s an e4am"le0 com"uting the average salary o' every em"loyee o' a com"any is a rather com"le4 tas . Nou can0 ho!ever0 (rea it do!n into the 'ollo!ing su(tas s:

!A /ind out !hat each "erson earns. CA Count ho! many "eo"le you have.

DA Total all the salaries. EA Divide the total (y the num(er o' "eo"le you have.
Totaling the salaries can (e (ro en do!n into the 'ollo!ing ste"s:

!A 2et each em"loyeeHs record. CA 5ccess the salary. DA 5dd the salary to the running total. EA 2et the ne4t em"loyeeHs record.
+n turn0 o(taining each em"loyeeHs record can (e (ro en do!n into the 'ollo!ing:

!A %"en the 'ile o' em"loyees. CA 2o to the correct record. DA 8ead the data 'rom dis .
Structured "rogramming remains an enormously success'ul a""roach 'or dealing !ith com"le4 "ro(lems. 1y the late =B^Fs0 ho!ever0 some o' the de'iciencies o' structured "rogramming had (ecome all too clear. 5s "rograms gro! ever larger and more com"le40 even the structured "rogramming a""roach (egins to sho! signs o' strain. Nou may have heard a(out0 or (een involved in0 horror stories o' "rogram develo"ment. The "ro6ect is too com"le40 the schedule sli"s0 more "rogrammers are added0 com"le4ity increases0 costs s yroc et0 the schedule sli"s 'urther0 and disaster ensues. 5nalyPing the reasons 'or these 'ailures reveals that there are !ea nesses in the "rocedural "aradigm itsel'. No matter ho! !ell the structured "rogramming a""roach is im"lemented0 large "rograms (ecome e4cessively com"le4. #hat are the reasons 'or these "ro(lems !ith "rocedural languagesW There are t!o related "ro(lems. /irst0 f$nctions have $nrestricted access to glo/al dataA Second0 $nrelated f$nctions and data. the /asis of the -roced$ral -aradigm. -rovide a -oor model of the real worldA #hen data items are modi'ied in a large "rogram it may not (e easy to tell !hich 'unctions access the data0 and even !hen you 'igure this out0 modi'ications to the 'unctions may cause them to !or incorrectly !ith other glo(al data items. 3verything is related to everything else0 so a modi'ication any!here has 'ar: reaching0 and o'ten unintended0 conse)uences. The !ay !e are no! using com"utersS!ith menus and (uttons and !indo!sS'osters a more interactive0 event:driven a""roach to com"uter "rogramming. 3vent:driven means that an event ha""ensSthe user "resses a (utton or chooses 'rom a menuSand the "rogram must res"ond. $rograms are (ecoming increasingly interactive0 and it has (ecame im"ortant to design 'or that ind o' 'unctionality. %ld:'ashioned "rograms 'orced the user to "roceed ste":(y:ste" through a series o' screens. &odern event: driven "rograms "resent all the choices at once and res"ond to the userHs actions. %(6ect:oriented "rogramming attem"ts to res"ond to these needs0 "roviding techni)ues 'or managing enormous com"le4ity0 achieving reuse o' so't!are com"onents0 and cou"ling data !ith the tas s that mani"ulate that data. The essence o' o(6ect:oriented "rogramming is to treat data and the "rocedures that act u"on the data as a single Qo(6ectSRa sel':contained entity !ith an identity and certain characteristics o' its o!n. /irst0 a natural desire is to thin o' data (em"loyee records0 'or e4am"le* and !hat you can do !ith data (sort0 edit0 and so on* as a single idea. $rocedural "rogramming !or ed against this0 se"arating data structures 'rom 'unctions that mani"ulated that data.

Second0 programmers found themselves constantly reinventing new solutions to old problems. This is o'ten called Qreinventing the !heel0R !hich is the o""osite o' reusa(ility. The idea (ehind reusa(ility is to (uild com"onents that have no!n "ro"erties0 and then to (e a(le to "lug them into your "rogram as you need them. This is modeled a'ter the hard!are !orldS!hen an engineer needs a ne! transistor0 she doesnHt usually invent one0 she goes to the (ig (in o' transistors and 'inds one that !or s the !ay she needs it to0 or "erha"s modi'ies it. No similar o"tion e4isted 'or a so't!are engineer. O/Ject The 'undamental idea (ehind o(6ect:oriented languages is to com(ine into a single unit (oth data and the 'unctions that o"erate on that data. Such a unit is called an o(6ect. 5n o(6ectHs 'unctions0 called mem(er 'unctions in C++0 ty"ically "rovide the only !ay to access its data. +' you !ant to read a data item in an o(6ect0 you call a mem(er 'unction in the o(6ect. +t !ill access the data and return the value to you. Nou canHt access the data directly. The data is hidden0 so it is sa'e 'rom accidental alteration. Class
Class is the logical category /ty"e o' the %(6ects. 5 class serves as a "lan0 or tem"late. +t s"eci'ies !hat data and !hat 'unctions !ill (e included in o(6ects o' that class. De'ining the class doesnHt create any o(6ects0 6ust as the mere e4istence o' data ty"e int doesnHt create any varia(les.

0nca-s$lation The "ro"erty o' (eing a sel':contained unit is called enca"sulation. #ith enca"sulation0 !e can accom"lish data hiding. Data hiding is the highly valued characteristic that an o(6ect can (e used !ithout the user no!ing or caring ho! it !or s internally. <ust as you can use a re'rigerator !ithout no!ing ho! the com"ressor !or s0 you can use a !ell:designed o(6ect !ithout no!ing a(out its internal data mem(ers. 0nca-s$lation is the a/straction of information and is also called data hiding . +t "revents users 'rom seeing the internal !or ings o' an o(6ect so as to "rotect data that should not (e mani"ulated (y the user. 3nca"sulation im"roves the modularity o' the code and leads to more easy maintenance o' "rograms (y hiding the actual im"lementation details !ithin an o(6ect and sim"ly allo!ing access to an o(6ect7s inter'ace. Pol(mor-hism $olymor"hism allo!s di''erent o(6ects to res"ond di''erently to the same message. There are t!o ty"es o' "olymor"hism (a* %arly &inding !hich allo!s overloading o' 'unctions. %verloading means that di''erent 'unctions can have the same name (ut can (e distinguished (ased on their signature (num(er0 ty"e and order o' "arameters*. ((* 'ate &inding !hich allo!s derived classes to to override the (ase class 'unctionality. #hich 'unction is invo ed de"ends on the conte4t in !hich the 'unction is invo ed. $olymor"hism im"roves the 'le4i(ility o' "rogramming (y allo!ing develo"ers (etter design o"tions #nheritance #hen the engineers at 5cme &otors !ant to (uild a ne! car0 they have t!o choices: They can start 'rom scratch0 or they can modi'y an e4isting model. $erha"s their Star model is nearly "er'ect0 (ut theyHd li e to add a tur(ocharger and a si4:s"eed transmission. The chie' engineer !ould "re'er not to start 'rom the ground u"0 (ut rather

to say0 Q,etHs (uild another Star0 (ut letHs add these additional ca"a(ilities. #eHll call the ne! model a @uasar.R 5 @uasar is a ind o' Star0 (ut a s"ecialiPed one !ith ne! 'eatures. C++ su""orts inheritance. 5 ne! ty"e0 !hich is an e4tension o' an e4isting ty"e0 can (e declared. This ne! su(class is said to derive 'rom the e4isting ty"e and is sometimes called a derived ty"e. The @uasar is derived 'rom the Star and thus inherits all its )ualities0 (ut can add to them as needed. +nheritance allo!s you to create ne! o(6ects o' a derived class 'rom "reviously de'ined o(6ects o' a (ase class. The derived class contains all the attri(utes and methods o' the (ase class "lus any additional s"eci'ications o' the derived class. 5ny changes made to (ase classes are "ro"agated to all derived classes unless e4"licitly overridden. #nheritance
facilitates code re$se there/( c$tting develo-ment costs

>/straction
#hen the engineers at 5cme &otors !ant to (uild a ne! car0 they have t!o choices: They can start 'rom scratch0 or they can modi'y an e4isting model/a set of modals. $erha"s a com(ination o' their Star model and the Su"er Star model loo s li e a great idea0 (ut theyHd li e to add a tur(ocharger and a si4:s"eed transmission. The chie' engineer !ould "re'er not to start 'rom the ground u"0 (ut rather to say0 Q,etHs (uild another model0 (ut letHs add these additional ca"a(ilities. #eHll call the ne! model a Su"er@uasar.R 5 Su"er@uasar is a ind o' Star com Su"er Star0 (ut a s"ecialiPed one !ith ne! 'eatures. +n the a(ove case the user/customer o' the ne! car Su"er@uassar never (others to no! the technology (ie. The "arent technology 'rom !hich it is inherited in this case itHs a com(ination o' the star and su"er star model. *(ehind it.This "rocess o' hiding the technology is called a(straction.

Wh( C++
C++ 'ully su""orts o(6ect:oriented "rogramming0 including the three "illars o' o(6ect:oriented develo"ment: enca"sulation0 inheritance0 5(straction and "olymor"hism

> Com-arison of C and C++


#ntrod$ction
The C "rogramming language !as develo"ed at 5T&T 'or the the "ur"ose o' !riting the o"erating system 'or $D$:== com"uters. This o"erating system evolved into .ni4. 5s you can imagine C is a very e''icient language since it !as designed to develo" an o"erating system. C++ is an e4tension o' C develo"ed (y 16arne Stroustro" (also o' 5T&T* !ith the "ur"ose o' adding o(6ect:oriented 'eatures to C !hile "reserving the e''iciencies o' C.

,imilarities
The C language is a su(set o' C++ 'or all "ractical "ur"oses even though it is "ossi(le to !rite C "rograms that are not valid in C++. The main similarity in C and C++ lies in the synta4 o' the t!o languages. C and C++ (oth share many o' the same 'undamental "rogramming constructs. This is the reason !hy it is easy 'or a "ro'icient C "rogrammer to learn C++ "rovided he/she understands the o(6ect:oriented "aradigm. C++ maintains it7s C roots at various levels: a* Source code level: most 5NS+ C "rograms are valid C++ "rogramsL (* %(6ect code level: C++ structures are I(inary:com"ati(leI !ith e)uivalent C structuresL c* 3nvironment/Tool level: C++ !or s !ith standard tools li e ma eL C++ can (e descri(ed as a "rogramming language derived 'rom C !ith im"roved "rocedural synta4 as com"ared to C and o(6ect:oriented 'eatures not "resent in C. Note that though C++ su""orts o(6ect:oriented "rogramming0 it does not en'orce it. C++ is there'ore a multi:"aradigm language.

Wh( is C++ /etter than C 2

C is a "rocedural language. +t is not designed to su""ort o(6ect:oriented "rogramming. +n a "rocedural "rogram0 the "ro(lem is (ro en do!n into modules and su(:modules !hich im"lement the solution. C++ on the other hand can "rovide all the advantages inherent in the %% "aradigm. +n an %% "rogram the "ro(lem s"ace is re"resented (y o(6ects that interact !ith each other and these o(6ects are im"lemented along !ith messaging mechanisms to "rovide a solution. %% "rogramming languages have a num(er o' inherent advantages. They lend themselves to (etter design (ecause they allo! "ro(lem s"aces to (e modelled li e real !orld o(6ects. +n an o(6ect oriented language0 an o(6ect is called a class !hich is the so't!are re"resentation o' an o(6ect. 5 class "ac ages all the attri(utes and methods o' an o(6ect. 5ttri(utes are the data associated !ith the o(6ect and methods are the 'unctions that o"erate on the data and e4"ress the (ehavior o' the o(6ect. 5s an o(6ect:oriented language C+ + su""orts inheritance0 enca"sulation and "olymor"hism !hich i' "ro"erly used lead to (etter "rograms. -ere is a lin to the a (rie' tutorial e4"laining the (asics o' +nheritance. +nheritance in C++ The 'ollo!ing is a lin to a tutorial on 3nca"sulation. Data -iding and 3nca"sulation in C++ Chec out the 'ollo!ing lin 'or an introduction to "olymor"hism0 illustrated (y e4am"le. 5n +ntroduction to $olymor"hism >n 0=am-le Chec out this lin 'or a tutorial that e4"lores through e4am"les the di''erences (et!een C and C++. Di''erences (et!een C and C++ >ftertho$ght I+ncreasingly0 "eo"le seem to misinter"ret com"le4ity as so"histication0 !hich is (a''ling : the incom"rehensi(le should cause sus"icion0 rather than admirationI0 Ni laus #irth.

Tryout (lease ) *imple problem to *olve in +,,


5cce"t t!o num(ers and dis"lay 5ll the even Num(ers (et!een the t!o. 5ll the odd Num(ers (et!een the t!o. // the 'ile Nums.c"" T includeUiostream.hV void main(* K int inum=0inum;L coutUUR3nter the /irst Num(er : QL//dis"lays the te4t in dou(le )uotes cinVVinum=L//5cce"ts a ey(oard in"ut 'rom the user to the varia(le coutUUR 3nter the ;ndt Num(er : QL//dis"lays the te4t in dou(le )uotes cinVVinum;L//5cce"ts a ey(oard in"ut 'rom the user to the varia(le coutUUR3ven Num(ers are : YnR 'or(int +[inum=L+U[inum;L+++* //+n C++ vari(les can (e declared as and !hen re)uired K i' ((+Z;* [[ F* K coutUU+L M M coutUUR%dd Num(ers are : YnR 'or(int +[inum=L+U[inum;L+++* K

i' ((+Z;* J[ F*//The &odulo 'unction returns a remainder K coutUU+L M M M

,treams (+/%*
5s you have seen0 the statement cout UU Q3very age has a language o' its o!nYnRL causes the "hrase in )uotation mar s to (e dis"layed on the screen. -o! does this !or W 5 com"lete descri"tion o' this statement re)uires an understanding o' o(6ects0 o"erator overloading0 and other to"ics !e !onHt discuss until later in the (oo 0 (ut hereHs a (rie' "revie!. The identi'ier cout ("ronounced QC outR* is actually an object. +t is "rede'ined in C++ to corres"ond to the standard output stream. 5 stream is an a(straction that re'ers to a 'lo! o' data. The standard out"ut stream normally 'lo!s to the screen dis"laySalthough it can (e redirected to other out"ut devices. The o"erator UU is called the insertion or put to o"erator. +t directs the contents o' the varia(le on its right to the o(6ect on its le't(ie the co$t !hich is nothing (ut the Standard %ut"ut Device*. +n /+8ST it directs the string constant Q3very age has a language o' its o!n YnR to cout0 !hich sends it to the dis"lay.

Similarly the o"erator used !ith cin VV is a extraction or get opeator.+t !aits 'or the in"ut o' the user 'rom the Standard +n"ut Device (ie cin* and "uts it to the right hand side varia(le.

(+' you no! C0 youHll recogniPe UU as the left-shift (it:!ise o"erator and !onder ho! it can also (e used to direct out"ut. +n C++0 o"erators can (e overloaded (> wa( to im-lement -ol(mor-hism*. That is0 they can "er'orm di''erent activities0 de"ending on the conte4t. +n the /+8ST e4am"le0 the "re"rocessor directive Tinclude tells the com"iler to add the source 'ile +%ST835& to the /+8ST.C$$ source 'ile (e'ore com"iling. #hy do thisW +%ST835& is an e4am"le o' a header file (sometimes called an include file). +tHs concerned !ith (asic in"ut/out"ut o"erations0 and contains declarations that are needed (y the cout identi'ier and the UU o"erator. #ithout these declarations0 the com"iler !onHt recogniPe cout and !ill thin UU is (eing used incorrectly. There are many such include 'iles. The ne!er Standard C++ header 'iles donHt have a 'ile e4tension0 (ut some older header 'iles0 le't over 'rom the days o' the C language0 have the e4tension .-. +' you !ant to see !hatHs in +%ST835&0 you can use your com"iler to 'ind the include directory 'or your com"iler and dis"lay it as a source 'ile in the edit !indo!. %r you can loo at it !ith the #ord"ad or Note"ad utilities. The contents !onHt ma e much sense at this "oint0 (ut you !ill at least "rove to yoursel' that +%ST835& is a source 'ile0 !ritten in normal 5SC++ characters.

0sca-e ,eK$ences
This second character constant0 _YtH0 is an odd one. ,i e _YnH !hich !e encountered earlier0 itHs an e4am"le o' an escape sequence. The name re'lects the 'act that the (ac slash causes an Qesca"eR 'rom the normal !ay characters are inter"reted. +n this case the t is inter"reted not as the character _tH (ut as the ta( character. 5 ta( causes "rinting to continue at the ne4t ta( sto". +n console:mode "rograms0 ta( sto"s are "ositioned every eight s"aces. 5nother character constant0 _YnH0 is sent directly to cout in the last line o' the "rogram. 3sca"e se)uences can (e used (oth as se"arate characters and also em(edded in string constants. Ta(le (elo! sho!s a list o' common esca"e se)uences. %a/le Common 3sca"e Se)uences 0sca-e ,eK$ence Character Ya 1ell ((ee"* Y( 1ac s"ace Y' /orm'eed Yn Ne!line Yr 8eturn Yt Ta( YY 1ac slash Y_ Single )uotation mar YQ Dou(le )uotation mar s Y4dd -e4adecimal notation

Since the (ac slash0 the single )uotation mar s0 and the dou(le )uotation mar s all have s"ecialiPed meanings !hen used in constants0 they must (e re"resented (y esca"e se)uences !hen !e !ant to dis"lay them as characters. -ereHs an e4am"le o' a )uoted "hrase in a string constant: cout UU QYR8un0 S"ot0 run0YR she said.RL This translates to Q8un0 S"ot0 run0R she said. Sometimes you need to re"resent a character constant that doesnHt a""ear on the ey(oard0 such as the gra"hics characters a(ove 5SC++ code =;D. To do this0 you can use the _Y4ddH re"resentation0 !here each d stands 'or a he4adecimal digit. +' you !ant to "rint a solid rectangle0 'or e4am"le0 youHll 'ind such a character listed as decimal num(er =D^0 !hich is he4adecimal num(er 1; in the 5SC++ ta(le. This character !ould (e re"resented (y the character constant _Y41;H. #eHll see some e4am"les o' this later.

Defining #nteger ?aria/les


+nteger varia(les e4ist in several siPes0 (ut the most commonly used is ty"e int. The amount o' memory occu"ied (y the integer ty"es is system de"endent. %n a G;:(it system li e #indo!s B^0 an int occu"ies > (ytes (!hich is G; (its* o' memory. This allo!s an int to hold num(ers in the range 'rom ];0=>D0>^G0C>^ to ;0=>D0>^G0C>D. /igure ;.G sho!s an integer varia(le in memory. #hile ty"e int occu"ies > (ytes on current #indo!s com"uters0 it occu"ied only ; (ytes in &S:D%S and earlier versions o' #indo!s. The ranges occu"ied (y the various ty"es are listed in the header 'ile ,+&+TSL you can also loo them u" using your com"ilerHs hel" system. &any com"ilers o''er integer ty"es that e4"licitly s"eci'y the num(er o' (its used. (8emem(er there are ^ (its to a

(yte.* These ty"e names are "receded (y t!o underscores. They are 99int^0 99int=C0 99intG;0 and 99intC>. The 99int^ ty"e corres"onds to char0 and (at least in G;:(it systems li e the current version o' #indo!s* The ty"e name 99int=C corres"onds to short and 99intG; corres"onds to (oth int and long. The 99intC> ty"e holds huge integers !ith u" to =B decimal digits. .sing these ty"e names has the advantage that the num(er o' (ytes used 'or a varia(le is not im"lementation de"endent. -o!ever0 this is not usually an issue0 and these ty"es are seldom used.

What is a -ointer W
#hat is a "ointer W 5 "ointer is a varia(le that contains the memory address o' another varia(le (!hich may(e o' any ty"e including an o(6ect*. $ointers are central to C/C++ "rogramming as they allo! the "rogrammer to access and mani"ulate o(6ects in memory.

%(-es of -ointers
5 "ointer varia(le 6ust li e any other varia(le in C and C++ must have a data ty"e. The data ty"e o' a "ointer is the same as that o' the varia(le !hose address is contained in the "ointer. /or e4am"le0 the 'ollo!ing are all valid declarations o' "ointers:

int \"tr&y+ntL //"tr&y+nt is a "ointer to an integer varia(le char \"tr&yCharL //"tr&yChar is a "ointer to a char varia(le 'loat \"tr&y/loatL //"tr&y/loat is a "ointer to a 'loat varia(le The \ in the varia(le name indicates that these varia(les are "ointers.

#nitialiLing Pointers
5 "ointer varia(le can (e initialiPed in a num(er o' di''erent !ays. 5 "ointer can (e assigned the address o' a varia(le or it can (e assigned another "ointer as illustrated in the e4am"les (elo!: //declare varia(les int iL int \"tr&y+ntL //assign values to varia(les i [ =FL//"tr&y+nt contains the address o' i "tr&y+nt [ &iL //declare and assign value to a second "ointer int \"tr&y+nt;L "tr&y+nt; [ "tr&y+ntL //"tr&y+nt; "oints to the address o' integer i

%he #ndirection and the >ddress-of O-erators #e have 6ust seen the address:o' o"erator. This o"erator is used to access the memory address at !hich a varia(le is stored. /or e4am"le i' !e have an integer i0 then &i contains the memory location at !hich the integer i is stored. +ndirection re'ers to the accessing o' the value stored in the memory address contained in the "ointer. /or e4am"le0 i' !e de'ine a second integer 6 and !e !ant to assign to 60 the value contained in the varia(le iL there are t!o !ays to do this: one !ithout "ointers and the second !ith "ointers. 1oth yield the same result. int iL i [ =FL int \"tr+L "tr+ [ &=FL int 6L 6 [ iL //'irst !ay to assign a value to 6 6 [ \"tr+L //second !ay to assign a value to 6 -ere7s another e4am"le continued 'rom the one !e 6ust loo ed at. Say !e de'ine a varia(le that uses the address:o' o"erator to "oint to the address o' i. int \ L [ &iL Then i' !e assign a value to 0 !hat do you thin ha""ens to the value o' i W \ [ GL Nou are right i' you guessed that the value o' i is no! e)ual to G. Since "oints to

the address0 assigning a value to \ actually changes the value stored in the address re'erenced (y . What )e=t 2 Chec out the 'ollo!ing lin s 'or more on "ointers Notes on $ointers ,ecture Notes on $ointers 5 +ntroduction to $ointers in C++ $ointers and 8e'erences

F$nctions
5ny se)uence o' instructions that a""ears in a "rogram more than once is a candidate 'or (eing made into a 'unction. The 'unctionHs code is stored in only one "lace in memory0 even though the 'unction is e4ecuted many times in the course o' the "rogram. /igure (elo! sho!s ho! a 'unction is invo ed 'rom di''erent sections o' a "rogram. ,im-le F$nctions O$r first e=am-le demonstrates a sim-le f$nction whose -$r-ose is to -rint a line of EF asteris+sA %he e=am-le -rogram generates a ta/le. and lines of asteris+s are $sed to ma+e the ta/le more reada/leA 'ere;s the listing for %>B&01 // table.cpp // demonstrates simple function

#include <iostream> using namespace std; void starline(); declaration //function // (prototype)

int main() { starline(); //call to function cout << Data type ange! << endl; starline(); //call to function cout << c"ar #$%& to $%'! << endl << s"ort #(%)'*& to (%)'*'! << endl << int +ystem dependent! << endl << long #%)$,'),&()*,& to %)$,'),&()*,'! << endl; starline(); //call to function return -; . //######################################################### ##### // starline() // function definition void starline() //function declarator { for(int /0-; /<,1; /22) //function body cout << 345; cout << endl; . %he o$t-$t from the -rogram loo+s li+e this1 444444444444444444444444444444444444444444444 Data type ange 444444444444444444444444444444444444444444444 c"ar #$%& to $%' s"ort #(%)'*& to (%)'*' int +ystem dependent double #%)$,'),&()*,& to %)$,'),&()*,' %he -rogram consists of two f$nctions1 main35 and starline35A 8o$;ve alread( seen man( -rograms that $se main35 aloneA What other com-onents are necessar( to add a f$nction to the -rogram2 %here are three1 the f$nction declaration, the calls to the f$nction. and the f$nction definition. %he F$nction Declaration B$st as (o$ can;t $se a varia/le witho$t first telling the com-iler what it is. (o$ also can;t $se a f$nction witho$t telling the com-iler a/o$t itA %here are two wa(s to do thisA %he a--roach we show here is to declare the f$nction /efore it is calledA 3%he

other a--roach is to define it /efore it;s calledI we;ll e=amine that ne=tA5A #n the %>B&0 -rogram. the f$nction starline35 is declared in the line void starline(); %he declaration tells the com-iler that at some later -oint we -lan to -resent a f$nction called starline. %he +e(word void s-ecifies that the f$nction has no ret$rn val$e. and the em-t( -arentheses indicate that it ta+es no arg$mentsA 38o$ can also $se the +e(word void in -arentheses to indicate that the f$nction ta+es no arg$ments. as is often done in C. /$t leaving them em-t( is the more common -ractice in C++A5 We;ll have more to sa( a/o$t arg$ments and ret$rn val$es soonA )otice that the f$nction declaration is terminated with a semicolonA #t is a com-lete statement in itselfA F$nction declarations are also called prototypes, since the( -rovide a model or /l$e-rint for the f$nctionA %he( tell the com-iler. 9a f$nction that loo+s li+e this is coming $- later in the -rogram. so it;s all right if (o$ see references to it /efore (o$ see the f$nction itselfA: Calling the F$nction %he f$nction is called 3or invoked, or executed5 three times from main35A 0ach of the three calls loo+s li+e this1 starline(); %his is all we need to call the f$nction1 the f$nction name. followed /( -arentheses %he call is terminated /( a semicolonA 0=ec$ting the call statement ca$ses the f$nction to e=ec$teI that is. control is transferred to the f$nction. the statements in the f$nction definition 3which we;ll e=amine in a moment5 are e=ec$ted. and then control ret$rns to the statement following the f$nction callA %he F$nction Definition Finall(. we come to the f$nction itself. which is referred to as the f$nction definition. %he definition contains the act$al code for the f$nctionA 'ere;s the definition for starline351 void starline() //declarator { for(int /0-; /<,1; /22) //function body cout << 345; cout << endl; . %he definition consists of a line called the declarator, followed /( the f$nction body. %he f$nction /od( is com-osed of the statements that ma+e $- the f$nction. delimited /( /racesA %he declarator m$st agree with the declaration1 #t m$st $se the same f$nction name. have the same arg$ment t(-es in the same order 3if there are arg$ments5. and have the same ret$rn t(-eA )otice that the declarator is not terminated /( a semicolonA

When the f$nction is called. control is transferred to the first statement in the f$nction /od(A %he other statements in the f$nction /od( are then e=ec$ted. and when the closing /race is enco$ntered. control ret$rns to the calling -rogramA Com-arison with &i/rar( F$nctions We;ve alread( seen some li/rar( f$nctions in $seA We have em/edded calls to li/rar( f$nctions. s$ch as c" 0 getc"e(); in o$r -rogram codeA Where are the declaration and definition for this li/rar( f$nction2 %he declaration is in the header file s-ecified at the /eginning of the -rogram 3CO)#OA'. for getche355A %he definition 3com-iled into e=ec$ta/le code5 is in a li/rar( file that;s lin+ed a$tomaticall( to (o$r -rogram when (o$ /$ild itA When we $se a li/rar( f$nction we don;t need to write the declaration or definitionA B$t when we write o$r own f$nctions. the declaration and definition are -art of o$r so$rce file. 0liminating the Declaration %he second a--roach to inserting a f$nction into a -rogram is to eliminate the f$nction declaration and -lace the f$nction definition 3the f$nction itself5 in the listing /efore the first call to the f$nctionA For e=am-le. we co$ld rewrite %>B&0 to -rod$ce %>B&0C. in which the definition for starline35 a--ears firstA // ta/leCAc-// demonstrates f$nction definition -receding f$nction calls 7incl$de MiostreamN $sing names-ace stdI //no f$nction declaration //-------------------------------------------------------------// starline35 //f$nction definition void starline35 O for3int JP"I JMEFI J++5 co$t MM QR;I co$t MM endlI S //-------------------------------------------------------------int main35 //main35 follows f$nction O starline35I //call to f$nction co$t MM 9Data t(-e Range: MM endlI starline35I //call to f$nction co$t MM 9char -!CH to !CG: MM endl MM 9short -DC.G H to DC.G G: MM endl MM 9int ,(stem de-endent: MM endl MM 9long -C.!EG.EHD. EH to C.!EG.EHD. EG: MM endlI starline35I //call to f$nction ret$rn "I

S %his a--roach is sim-ler for short -rograms. in that it removes the declaration. /$t it is less fle=i/leA %o $se this techniK$e when there are more than a few f$nctions. the -rogrammer m$st give considera/le tho$ght to arranging the f$nctions so that each one a--ears /efore it is called /( an( otherA ,ometimes this is im-ossi/leA >lso. man( -rogrammers -refer to -lace main35 first in the listing. since it is where e=ec$tion /eginsA Passing >rg$ments to F$nctions >n argument is a -iece of data 3an int val$e. for e=am-le5 -assed from a -rogram to the f$nctionA >rg$ments allow a f$nction to o-erate with different val$es. or even to do different things. de-ending on the reK$irements of the -rogram calling itA >s an e=am-le. let;s s$--ose we decide that the starline35 f$nction in the last e=am-le is too rigidA #nstead of a f$nction that alwa(s -rints EF asteris+s. we want a f$nction that will -rint an( character an( n$m/er of timesA 'ere;s a -rogram. %>B&0>R6. that incor-orates J$st s$ch a f$nctionA We $se arg$ments to -ass the character to /e -rinted and the n$m/er of times to -rint itA // tablearg.cpp // demonstrates function arguments #include <iostream> using namespace std; void repc"ar(c"ar) int); declaration

//function

int main() { repc"ar(3#5) ,(); //call to function cout << Data type ange! << endl; repc"ar(305) %(); //call to function cout << c"ar #$%& to $%'! << endl << s"ort #(%)'*& to (%)'*'! << endl << int +ystem dependent! << endl << double #%)$,'),&()*,& to %)$,'),&()*,'! << endl; repc"ar(3#5) ,(); //call to function return -; . //######################################################### ##### // repc"ar() // function definition void repc"ar(c"ar c") int n) //function declarator { for(int /0-; /<n; /22) //function body cout << c"; cout << endl; .

%he new f$nction is called re-char35A #ts declaration loo+s li+e this1 void repc"ar(c"ar) int); // declaration specifies data types %he items in the -arentheses are the data t(-es of the arg$ments that will /e sent to re-char351 char and intA #n a f$nction call. s-ecific val$esTconstants in this caseTare inserted in the a--ro-riate -lace in the -arentheses1 repc"ar(3#5) ,(); // function call specifies actual values %his statement instr$cts re-char35 to -rint a line of ED dashesA %he val$es s$--lied in the call m$st /e of the t(-es s-ecified in the declaration1 the first arg$ment. the Q-; character. m$st /e of t(-e charI and the second arg$ment. the n$m/er ED. m$st /e of t(-e intA %he t(-es in the declaration and the definition m$st also agreeA %he ne=t call to re-char35. repc"ar(305) %(); tells it to -rint a line of CD eK$al signsA %he third call again -rints ED dashesA 'ere;s the o$t-$t from %>B&0>R61 ########################################### Data type ange 00000000000000000000000 c"ar #$%& to $%' s"ort #(%)'*& to (%)'*' int +ystem dependent long #%)$,'),&()*,& to %)$,'),&()*,' Passing ?aria/les #n the %>B&0>R6 e=am-le the arg$ments were constants1 Q-;. ED. and so onA &et;s loo+ at an e=am-le where varia/les. instead of constants. are -assed as arg$mentsA %his -rogram. ?>R>R6. incor-orates the same re-char35 f$nction as did %>B&0>R6. /$t lets the $ser s-ecif( the character and the n$m/er of times it sho$ld /e re-eatedA // vararg.cpp // demonstrates variable arguments #include <iostream> using namespace std; void repc"ar(c"ar) int); //function declaration int main() { c"ar c"in; int nin; cout << 6nter a c"aracter7 !; cin >> c"in; cout << 6nter number of times to repeat it7 !; cin >> nin; repc"ar(c"in) nin); return -;

. //######################################################### ##### // repc"ar() // function definition void repc"ar(c"ar c") int n) //function declarator { for(int /0-; /<n; /22) //function body cout << c"; cout << endl; . 'ere;s some sam-le interaction with ?>R>R61 6nter a c"aracter7 2 6nter number of times to repeat it7 %22222222222222222222 'ere chin and nin in main35 are $sed as arg$ments to re-char351 repc"ar(c"in) nin); // function call %he data t(-es of varia/les $sed as arg$ments m$st match those s-ecified in the f$nction declaration and definition. J$st as the( m$st for constantsA %hat is. chin m$st /e a char. and nin m$st /e an intA Passing /( ?al$e #n ?>R>R6 the -artic$lar val$es -ossessed /( chin and nin when the f$nction call is e=ec$ted will /e -assed to the f$nctionA >s it did when constants were -assed to it. the f$nction creates new varia/les to hold the val$es of these varia/le arg$mentsA %he f$nction gives these new varia/les the names and data t(-es of the -arameters s-ecified in the declarator1 ch of t(-e char and n of t(-e intA #t initialiLes these -arameters to the val$es -assedA %he( are then accessed li+e other varia/les /( statements in the f$nction /od(A Passing arg$ments in this wa(. where the f$nction creates co-ies of the arg$ments -assed to it. is called passing by value. We;ll e=-lore another a--roach. passing by reference, later in this cha-terA Fig$re /elow shows how new varia/les are created in the f$nction when arg$ments are -assed /( val$eA

Ret$rning ?al$es from F$nctions When a f$nction com-letes its e=ec$tion. it can ret$rn a single val$e to the calling -rogramA *s$all( this ret$rn val$e consists of an answer to the -ro/lem the f$nction has solvedA %he ne=t e=am-le demonstrates a f$nction that ret$rns a weight in +ilograms after /eing given a weight in -o$ndsA 'ere;s the listing for CO)?0R%1 // convertAc-// demonstrates ret$rn val$es. converts -o$nds to +g 7incl$de MiostreamN $sing names-ace stdI float l/sto+g3float5I //declaration

int main35 O float l/s. +gsI co$t MM 94n0nter (o$r weight in -o$nds1 :I cin NN l/sI +gs P l/sto+g3l/s5I co$t MM 98o$r weight in +ilograms is : MM +gs MM endlI ret$rn "I S //-------------------------------------------------------------// l/sto+g35 // converts -o$nds to +ilograms float l/sto+g3float -o$nds5 O float +ilograms P "AEFDFUC R -o$ndsI ret$rn +ilogramsI S 'ere;s some sam-le interaction with this -rogram1 0nter (o$r weight in -o$nds1 !HC 8o$r weight in +ilograms is HCAFFDGE! When a f$nction ret$rns a val$e. the data t(-e of this val$e m$st /e s-ecifiedA %he f$nction declaration does this /( -lacing the data t(-e. float in this case. /efore the f$nction name in the declaration and the definitionA F$nctions in earlier -rogram e=am-les ret$rned no val$e. so the ret$rn t(-e was voidA #n the CO)?0R% -rogram. the f$nction l/sto+g35 3pounds to kilograms, where l/s means -o$nds5 ret$rns t(-e float. so the declaration is float l/sto+g3float5I %he first float s-ecifies the ret$rn t(-eA %he float in -arentheses s-ecifies that an arg$ment to /e -assed to l/sto+g35 is also of t(-e floatA When a f$nction ret$rns a val$e. the call to the f$nction l/sto+g3l/s5 is considered to /e an e=-ression that ta+es on the val$e ret$rned /( the f$nctionA We can treat this e=-ression li+e an( other varia/leI in this case we $se it in an assignment statement1 +gs P l/sto+g3l/s5I %his ca$ses the varia/le +gs to /e assigned the val$e ret$rned /( l/sto+g35A %he ret$rn ,tatement %he f$nction l/sto+g35 is -assed an arg$ment re-resenting a weight in -o$nds. which it stores in the -arameter -o$ndsA #t calc$lates the corres-onding weight in +ilograms /( m$lti-l(ing this -o$nds val$e /( a constantI the res$lt is stored in the varia/le +ilogramsA %he val$e of this varia/le is then ret$rned to the calling -rogram $sing a ret$rn statement1 return 8ilograms; )otice that /oth main35 and l/sto+g35 have a -lace to store the +ilogram varia/le1 +gs in main35. and +ilograms in l/sto+g35A When the f$nction ret$rns. the val$e in +ilograms is copied into +gsA %he calling -rogram does not access the +ilograms

varia/le in the f$nctionI onl( the val$e is ret$rnedA %his -rocess is shown in Fig$re /elowA While man( arg$ments ma( /e sent to a f$nction. onl( one arg$ment ma( /e ret$rned from itA %his is a limitation when (o$ need to ret$rn more informationA 'owever. there are other a--roaches to ret$rning m$lti-le varia/les from f$nctionsA One is to -ass arg$ments /( reference. which we;ll loo+ at later in this cha-terA 8o$ sho$ld alwa(s incl$de a f$nction;s ret$rn t(-e in the f$nction declarationA #f the f$nction doesn;t ret$rn an(thing. $se the +e(word void to indicate this factA #f (o$ don;t $se a ret$rn t(-e in the declaration. the com-iler will ass$me that the f$nction ret$rns an int val$eA For e=am-le. the declaration somefunc(); // declaration ## assumes return type is int tells the com-iler that somef$nc35 has a ret$rn t(-e of intA %he reason for this is historical. /ased on $sage in earl( versions of CA #n -ractice (o$ sho$ldn;t ta+e advantage of this defa$lt t(-eA >lwa(s s-ecif( the ret$rn t(-e e=-licitl(. even if it act$all( is intA %his +ee-s the listing consistent and reada/leA Defa$lt >rg$ments ,$r-risingl(. a f$nction can /e called witho$t s-ecif(ing all its arg$mentsA %his won;t wor+ on J$st an( f$nction1 %he f$nction declaration m$st -rovide defa$lt val$es for those arg$ments that are not s-ecifiedA 'ere;s an e=am-le. a variation on the O?0R&O>D -rogram that demonstrates this effectA #n O?0R&O>D we $sed three different f$nctions with the same name to handle different n$m/ers of arg$mentsA %he -resent e=am-le. M#,,>R6. achieves the same effect in a different wa(A

// missargAc-// demonstrates missing and defa$lt arg$ments 7incl$de MiostreamN $sing names-ace stdI void re-char3charP;R;. intPEF5I //declaration with //defa$lt arg$ments int main35 O re-char35I //-rints EF asteris+s re-char3QP;5I //-rints EF eK$al signs re-char3Q+;. D"5I //-rints D" -l$s signs ret$rn "I S //-------------------------------------------------------------// re-char35 // dis-la(s line of characters void re-char3char ch. int n5 //defa$lts s$--lied O // if necessar( for3int JP"I JMnI J++5 //loo-s n times co$t MM chI //-rints ch co$t MM endlI S #n this -rogram the f$nction re-char35 ta+es two arg$mentsA #t;s called three times from main35A %he first time it;s called with no arg$ments. the second time with one. and the third time with twoA Wh( do the first two calls wor+2 Beca$se the called f$nction -rovides defa$lt arg$ments. which will /e $sed if the calling -rogram doesn;t s$--l( themA %he defa$lt arg$ments are s-ecified in the declaration for re-char351 void re-char3charP;R;. intPEF5I //declaration %he defa$lt arg$ment follows an eK$al sign. which is -laced directl( after the t(-e nameA 8o$ can also $se varia/le names. as in void re-char3char re-tCharP;R;. int n$m/erRe-sPEF5I #f one arg$ment is missing when the f$nction is called. it is ass$med to /e the last arg$mentA %he re-char35 f$nction assigns the val$e of the single arg$ment to the ch -arameter and $ses the defa$lt val$e EF for the n -arameterA #f /oth arg$ments are missing. the f$nction assigns the defa$lt val$e QR; to ch and the defa$lt val$e EF to nA %h$s the three calls to the f$nction all wor+. even tho$gh each has a different n$m/er of arg$mentsA Remem/er that missing arg$ments m$st /e the trailing arg$mentsTthose at the end of the arg$ment listA 8o$ can leave o$t the last three arg$ments. /$t (o$ can;t leave o$t the ne=tto-last and then -$t in the lastA %his is reasona/leI how wo$ld the com-iler +now which arg$me nts (o$ meant. if (o$ left o$t some in the middle2 3Missing arg$ments co$ld have /een indicated with commas. /$t commas are notorio$sl( s$/Ject to mis-rints. so the designers of C++ ignored this -ossi/ilit(A5 )ot s$r-risingl(. the com-iler will flag an error if (o$ leave o$t arg$ments for which the f$nction does not -rovide defa$lt val$esA

Defa$lt arg$ments are $sef$l if (o$ don;t want to go to the tro$/le of writing arg$ments that. for e=am-le. almost alwa(s have the same val$eA %he( are also $sef$l in cases where. after a -rogram is written. the -rogrammer decides to increase the ca-a/ilit( of a f$nction /( adding another arg$mentA *sing defa$lt arg$ments means that the e=isting f$nction calls can contin$e to $se the old n$m/er of arg$ments. while new f$nction calls can $se moreA Reference >rg$ments > reference -rovides an aliasTa different nameTfor a varia/leA One of the most im-ortant $ses for references is in -assing arg$ments to f$nctionsA We;ve seen e=am-les of f$nction arg$ments -assed /( val$eA When arg$ments are -assed /( val$e. the called f$nction creates a new varia/le of the same t(-e as the arg$ment and co-ies the arg$ment;s val$e into itA >s we noted. the f$nction cannot access the original varia/le in the calling -rogram. onl( the co-( it createdA Passing arg$ments /( val$e is $sef$l when the f$nction does not need to modif( the original varia/le in the calling -rogramA #n fact. it offers ins$rance that the f$nction cannot harm the original varia/leA Passing arg$ments /( reference $ses a different mechanismA #nstead of a val$e /eing -assed to the f$nction. a reference to the original varia/le. in the calling -rogram. is -assedA 3#t;s act$all( the memory address of the varia/le that is -assed. altho$gh (o$ don;t need to +now thisA5 >n im-ortant advantage of -assing /( reference is that the f$nction can access the act$al varia/les in the calling -rogramA >mong other /enefits. this -rovides a mechanism for -assing more than one val$e from the f$nction /ac+ to the calling -rogramA Passing ,im-le Data %(-es /( Reference ,$--ose (o$ have -airs of n$m/ers in (o$r -rogram and (o$ want to /e s$re that the smaller one alwa(s -recedes the larger oneA %o do this (o$ call a f$nction. order35. which chec+s two n$m/ers -assed to it /( reference and swa-s the originals if the first is larger than the secondA 'ere;s the listing for R0FORD0R1 // reforderAc-// orders two arg$ments -assed /( reference 7incl$de MiostreamN $sing names-ace stdI int main35 O void order3int&. int&5I int n!PUU. nCP!!I int nDPCC. nEPHHI order3n!. nC5I order3nD. nE5I

//-rotot(-e //this -air not ordered //this -air ordered //order each -air of n$m/ers //-rint o$t all n$m/ers

co$t MM 9n!P: MM n! MM endlI co$t MM 9nCP: MM nC MM endlI

co$t MM 9nDP: MM nD MM endlI co$t MM 9nEP: MM nE MM endlI ret$rn "I S //-------------------------------------------------------------void order3int& n$m/!. int& n$m/C5 //orders two n$m/ers O if3n$m/! N n$m/C5 //if !st larger than Cnd. O int tem- P n$m/!I //swa- them n$m/! P n$m/CI n$m/C P tem-I S #n main35 there are two -airs of n$m/ersTthe first -air is not ordered and the second -air is orderedA %he order35 f$nction is called once for each -air. and then all the n$m/ers are -rinted o$tA %he o$t-$t reveals that the first -air has /een swa--ed while the second -air hasn;tA 'ere it is1 n!P!! nCPUU nDPCC nEPHH #n the order35 f$nction. the first varia/le is called n$m/! and the second is n$m/CA #f n$m/! is greater than n$m/C the f$nction stores n$m/! in tem-. -$ts n$m/C in n$m/!. and finall( -$ts tem- /ac+ in n$m/CA Remem/er that n$m/! and n$m/C are sim-l( different names for whatever arg$ments were -assedI in this case. n! and nC on the first call to the f$nction. and nC and nD on the second callA %he effect is to chec+ the ordering of the original arg$ments in the calling -rogram and swa- them if necessar(A *sing reference arg$ments in this wa( is a sort of remote-control o-erationA %he calling -rogram tells the f$nction what varia/les in the calling -rogram to o-erate on. and the f$nction modifies these varia/les witho$t ever +nowing their real namesA #t;s as if (o$ called the ho$se -ainters and. altho$gh the( never left their office. (o$ sat /ac+ and watched as (o$r dining room walls m(sterio$sl( changed colorA

*D% 3*ser Defined Data %(-es5 ,tr$ct$res


%ne o' the (ene'its o' o(6ects is that they give the "rogrammer a convenient !ay to construct ne! data ty"es. Su""ose you !or !ith t!o:dimensional "ositions (such as 4 and y coordinates0 or latitude and longitude* in your "rogram. Nou !ould li e to e4"ress o"erations on these "ositional values !ith normal arithmetic o"erations0 such as "osition= [ "osition; + origin !here the varia(les "osition=0 "osition;0 and origin each re"resent a "air o' inde"endent numerical )uantities. 1y creating a class that incor"orates these t!o values0 and declaring "osition=0 "osition;0 and origin to (e o(6ects o' this class0 !e can0 in e''ect0 create a ne! data ty"e. &any 'eatures o' C++ are intended to 'acilitate the creation o' ne! data ty"es in this manner. These are the t!o things generally used to create ne! data ty"es.

5 structure is a collection o' sim"le varia(les. The varia(les in a structure can (e o' di''erent ty"es: Some can (e int0 some can (e 'loat0 and so on. (This is unli e the array0 !hich !eHll meet later0 in !hich all the varia(les must (e the same ty"e.* The data items in a structure are called the members o' the structure. +n (oo s on C "rogramming0 structures are o'ten considered an advanced 'eature and are introduced to!ard the end o' the (oo . -o!ever0 'or C++ "rogrammers0 structures are one o' the t!o im"ortant (uilding (loc s in the understanding o' o(6ects and classesA #n fact. the s(nta= of a str$ct$re is almost identical to that of a class. 5 structure (as ty"ically used* is a collection o' data0 !hile a class is a collection o' (oth data and 'unctions. So (y learning a(out structures !eHll (e "aving the !ay 'or an understanding o' classes and o(6ects.

> ,im-le ,tr$ct$re


,etHs start o'' !ith a structure that contains three varia(les: t!o integers and a 'loating:"oint num(er. This structure re"resents an item in a !idget com"anyHs "arts inventory. (#e assume that a !idget is com"osed o' several "arts.* The structure is a ind o' (lue"rint s"eci'ying !hat in'ormation is necessary 'or a single "art. The com"any ma es several inds o' !idgets0 so the !idget model num(er is the 'irst mem(er o' the structure. The num(er o' the "art itsel' is the ne4t mem(er0 and the 'inal mem(er is the "artHs cost. (Those o' you !ho consider "art num(ers une4citing need to o"en your eyes to the romance o' commerce.* The "rogram $58TS declares the structure "art0 de'ines a structure varia(le o' that ty"e called "art=0 assigns values to its mem(ers0 and then dis"lays these values. // "arts.c"" // uses "arts inventory to demonstrate structures Tinclude UiostreamV using names"ace stdL //////////////////////////////////////////////////////////////// struct "art //declare a structure K int modelnum(erL //+D num(er o' !idget int "artnum(erL //+D num(er o' !idget "art 'loat costL //cost o' "art ML //////////////////////////////////////////////////////////////// int main(* K "art "art=L //de'ine a structure varia(le "art=.modelnum(er [ C;>>L //give values to //structure mem(ers "art=."artnum(er [ GDGL "art=.cost [ ;=D.??/L //dis"lay structure mem(ers cout UU Q&odel R UU "art=.modelnum(erL cout UU Q0 "art R UU "art=."artnum(erL cout UU Q0 costs `R UU "art=.cost UU endlL return FL M The "rogramHs out"ut loo s li e this: &odel C;>>0 "art GDG0 costs `;=D.?? The $58TS "rogram has three main as"ects: declaring the structure0 de'ining a structure varia(le0 and accessing the mem(ers o' the structure. ,etHs loo at each o' these.

Declaring the ,tr$ct$re


The structure declaration tells ho! the structure is organiPed: +t s"eci'ies !hat mem(ers the structure !ill have. -ere it is: struct part { int modelnum!er; int partnum!er;

float cost; ;

,(nta= of the ,tr$ct$re Declaration


The ey!ord struct introduces the structure declaration. Ne4t comes the structure name or tag0 !hich is "art. The declarations o' the structure mem(ersSmodelnum(er0 "artnum(er0 and costSare enclosed in (races. 5 semicolon 'ollo!s the closing (race0 terminating the entire structure. Note that this use o' the semicolon 'or structures is unli e the usage 'or a (loc o' code. 5s !eHve seen0 (loc s o' code0 !hich are used in loo"s0 decisions0 and 'unctions0 are also delimited (y (races. -o!ever0 they donHt use a semicolon 'ollo!ing the 'inal (race. /igure >.= sho!s the synta4 o' the structure declaration.

0n$merations
5s !eHve seen0 structures can (e loo ed at as a !ay to "rovide user:de'ined data ty"es. 5 di''erent a""roach to de'ining your o!n data ty"e is the enumeration. This 'eature o' C++ is less crucial than structures. Nou can !rite "er'ectly good o(6ect:oriented "rograms in C++ !ithout no!ing anything a(out enumerations. -o!ever0 they are very much in the s"irit o' C++0 in that0 (y allo!ing you to de'ine your o!n data ty"es0 they can sim"li'y and clari'y your "rogramming.

Da(s of the Wee+


3numerated ty"es !or !hen you no! in advance a 'inite (usually short* list o' values that a data ty"e can ta e on. -ereHs an e4am"le "rogram0 D5N3N.&0 that uses an enumeration 'or the days o' the !ee : 22 da%enum.cpp 22 demonstrates enum t%pes #include <iostream> usin+ namespace std; 22specif% enum t%pe enum da%s&of&,ee0 { :un# Kon# (ue# 8ed# (hu# 6ri# :at ; int main() { da%s&of&,ee0 da%1# da%2; da%1 ' Kon; da%2 ' (hu;

22define varia!les 22of t%pe da%s&of&,ee0 22+ive values to 22varia!les

int diff ' da%2 9 da%1; 22can do inte+er arithmetic cout << BLa%s !et,een ' B << diff << endl; if(da%1 < da%2) 22can do comparisons cout << Bda%1 comes !efore da%2\nE; return /; 5n enum declaration de'ines the set o' all names that !ill (e "ermissi(le values o' the ty"e. These "ermissi(le values are called enumerators. The enum ty"e days9o'9!ee has seven enumerators: Sun0 &on0 Tue0 and so on0 u" to Sat.

5n enumeration is a list o' all "ossi(le values. This is unli e the s"eci'ication o' an int0 'or e4am"le0 !hich is given in terms o' a range o' values. +n an enum you must give a s"eci'ic name to every "ossi(le value. /igure (elo! sho!s the di''erence (et!een an int and an enum. %nce youHve declared the enum ty"e days9o'9!ee as sho!n0 you can de'ine varia(les o' this ty"e. D5N3N.& has t!o such varia(les0 day= and day;0 de'ined in the statement da%s&of&,ee0 da%1# da%2; (+n C you must use the ey!ord enum (e'ore the ty"e name. enum da%s&of&,ee0 da%1# da%2; +n C++ this isnHt necessary.* Varia(les o' an enumerated ty"e0 li e day= and day;0 can (e given any o' the values listed in the enum declaration. +n the e4am"le !e give them the values &on and Thu. Nou canHt use values that !erenHt listed in the declaration. Such statements as da%1 ' hallo,een; are illegal. Nou can use the standard arithmetic o"erators on enum ty"es. +n the "rogram !e su(tract t!o values. Nou can also use the com"arison o"erators0 as !e sho!. -ereHs the "rogramHs out"ut: La%s !et,een ' da%1 comes !efore da%2 3numerations are treated internally as integers. This e4"lains !hy you can "er'orm arithmetic and relational o"erations on them. %rdinarily the 'irst name in the list is given the value F0 the ne4t name is given the value =0 and so on. +n the D5N3N.& e4am"le0 the values Sun through Sat are stored as the integer values F through C. 5rithmetic o"erations on enum ty"es ta e "lace on the integer values. -o!ever0 although the com"iler no!s that your enum varia(les are really integers0 you must (e care'ul o' trying to ta e advantage o' this 'act. +' you say da%1 ' .; the com-iler will iss$e a warning 3altho$gh it will com-ile5. +tHs (etter to 'orgetS!henever "ossi(leSthat enums are really integers.

> ,im-le Class


O$r first -rogram contains a class and two o/Jects of that classA >ltho$gh it;s sim-le. the -rogram demonstrates the s(nta= and general feat$res of classes in C++A 'ere;s the listing for the ,M>&&OBB -rogram1 // smallob/.cpp // demonstrates a small) simple ob/ect #include <iostream> using namespace std; //////////////////////////////////////////////////////////////// class smallob/ //declare a class { private7 int somedata; //class data public7 void setdata(int d) //member function to set data O somedata P dI S void showdata35 //mem/er f$nction to dis-la( data O co$t MM 9Data is : MM somedata MM endlI S SI //////////////////////////////////////////////////////////////// int main35 O smallo/J s!. sCI //define two o/Jects of class smallo/J s!Asetdata3!" 5I //call mem/er f$nction to set data sCAsetdata3!GG 5I s!Ashowdata35I //call mem/er f$nction to dis-la( data sCAshowdata35I ret$rn "I S %he class smallo/J declared in this -rogram contains one data item and two mem/er f$nctionsA %he two mem/er f$nctions -rovide the onl( access to the data item from o$tside the classA %he first mem/er f$nction sets the data item to a val$e. and the second dis-la(s the val$eA 3%his ma( so$nd li+e 6ree+. /$t we;ll see what these terms mean as we go alongA5

Placing data and f$nctions together into a single entit( is the central idea of o/JectV oriented -rogramming

Declaring the Class


-ereHs the declaration (sometimes called a specifier* 'or the class smallo(60 co"ied 'rom the S&5,,%1< listing: class smallo!$ 22declare a class { private7 int somedata; 22class data pu!lic7 void setdata(int d) 22mem!er function to set data K somedata [ dL M void sho!data(* //mem(er 'unction to dis"lay data K cout UU QYnData is R UU somedataL M ML The declaration starts !ith the ey!ord class0 'ollo!ed (y the class nameSsmallo(6 in this e4am"le. ,i e a structure0 the (ody o' the class is delimited (y (races and terminated (y a semicolon. (DonHt 'orget the semicolon.

8emem(er0 data constructs li e structures and classes end !ith a semicolon0 !hile control constructs li e 'unctions and loo"s do not.*

0nca-s$lation
The (ody o' the class contains t!o un'amiliar ey!ords: "rivate and "u(lic. #hat is their "ur"oseW 5 ey 'eature o' o(6ect]oriented "rogramming is data hiding. This term does not re'er to the activities o' "articularly "aranoid "rogrammersL rather it means that data is concealed !ithin a class0 so that it cannot (e accessed mista enly (y 'unctions outside the class. The "rimary mechanism 'or hiding data is to "ut it in a class and ma e it "rivate. $rivate data or 'unctions can only (e accessed 'rom !ithin the class. $u(lic data or 'unctions0 on the other hand0 are accessi(le 'rom outside the class. This is sho!n in /igure (elo!:

-idden 'rom #homW

DonHt con'use data hiding !ith the security techni)ues used to "rotect com"uter data(ases. To "rovide a security measure you might0 'or e4am"le0 re)uire a user to su""ly a "ass!ord (e'ore granting access to a data(ase. The "ass!ord is meant to ee" unauthoriPed or malevolent users 'rom altering (or o'ten even reading* the data. Data hiding0 on the other hand0 means hiding data 'rom "arts o' the "rogram that donHt need to access it. &ore s"eci'ically0 one classHs data is hidden 'rom other classes. Data hiding is designed to "rotect !ell] intentioned "rogrammers 'rom honest mista es. $rogrammers !ho really !ant to can 'igure out a !ay to access "rivate data0 (ut they !ill 'ind it hard to do so (y accident.

Class Data
The smallo(6 class contains one data item: somedata0 !hich is o' ty"e int. The data items !ithin a class are called data members (or sometimes member data*. There can (e any num(er o' data mem(ers in a class0 6ust as there can (e any num(er o' data items in a structure. The data mem(er somedata 'ollo!s the ey!ord "rivate0 so it can (e accessed 'rom !ithin the class0 (ut not 'rom outside.

&em(er /unctions
Member functions are 'unctions that are included !ithin a class. (+n some o(6ect]oriented languages0 such as Smalltal 0 mem(er 'unctions are called methodsL some !riters use this term in C++ as !ell.* There are t!o mem(er 'unctions in smallo(6: setdata(* and sho!data(*. The 'unction (odies o' these 'unctions have (een !ritten on the same line as the (races that delimit them. Nou could also use the more traditional 'ormat 'or these 'unction de'initions: void setdata(int d) { somedata ' d; and void sho,data() { cout << B\nLata is E << somedata; -o!ever0 !hen mem(er 'unctions are small0 it is common to com"ress their de'initions this !ay to save s"ace. 1ecause setdata(* and sho!data(* 'ollo! the ey!ord "u(lic0 they can (e accessed 'rom outside the class. #eHll see ho! this is done in a moment. .

/unctions are $u(lic0 Data is $rivate


.sually the data !ithin a class is "rivate and the 'unctions are "u(lic. This is a result o' ho! classes are used. The data is hidden so it !ill (e sa'e 'rom accidental mani"ulation0 !hile the 'unctions that o"erate on the data are "u(lic so they can (e accessed 'rom outside the class. -o!ever0 there is no rule that data must (e "rivate and 'unctions "u(licL in some circumstances you may 'ind youHll need to use "rivate 'unctions and "u(lic data.

&em(er /unctions #ithin Class Declaration


The mem(er 'unctions in the smallo(6 class "er'orm o"erations that are )uite common in classes: setting and retrieving the data stored in the class. The setdata(* 'unction acce"ts a value as a "arameter and sets the somedata varia(le to this value. The sho!data(* 'unction dis"lays the value stored in somedata. Note that the mem(er 'unctions setdata(* and sho!data(* are definitions in that the actual code 'or the 'unction is contained !ithin the class declaration. (The 'unctions are not de'initions in the sense that memory is set aside 'or the 'unction codeL this doesnHt ha""en until an o(6ect o' the class is created.* &em(er 'unctions de'ined inside a class this !ay are created as inline 'unctions (y de'ault.

#nline F$nctions
#e mentioned that 'unctions save memory s"ace (ecause all the calls to the 'unction cause the same code to (e e4ecutedL the 'unction (ody need not (e du"licated in memory. #hen the com"iler sees a 'unction call0 it normally generates a 6um" to the 'unction. 5t the end o' the 'unction it 6um"s (ac to the instruction 'ollo!ing the call. #hile this se)uence o' events may save memory s"ace0 it ta es some e4tra time. There must (e an instruction 'or the 6um" to the 'unction (actually the assem(ly:language instruction C5,, or something similar*0 instructions 'or saving registers0 instructions 'or "ushing arguments onto the stac in the calling "rogram and removing them 'rom the stac in the 'unction (i' there are arguments*0 instructions

'or restoring registers0 and an instruction to return to the calling "rogram. The return value (i' any* must also (e dealt !ith. 5ll these instructions slo! do!n the "rogram. To save e4ecution time in short 'unctions0 you may elect to "ut the code in the 'unction (ody directly in line !ith the code in the calling "rogram. That is0 each time thereHs a 'unction call in the source 'ile0 the actual code 'rom the 'unction is inserted0 instead o' a 6um" to the 'unction. The di''erence (et!een a 'unction and inline code is sho!n in /igure (elo!.

,ong sections o' re"eated code are generally (etter o'' as normal 'unctions: The savings in memory s"ace is !orth the com"aratively small sacri'ice in e4ecution s"eed. 1ut ma ing a short section o' code into an ordinary 'unction may result in little savings in memory s"ace0 !hile im"osing 6ust as much time "enalty as a larger 'unction. +n 'act0 i' a 'unction is very short0 the instructions necessary to call it may ta e u" as much s"ace as the instructions !ithin the 'unction (ody0 so that there is not only a time "enalty (ut a s"ace "enalty as !ell.

.sing the Class


No! that the class is declared0 letHs see ho! main(* ma es use o' it. #eHll see ho! o(6ects are de'ined0 and0 once de'ined0 ho! their mem(er 'unctions are accessed.

De'ining %(6ects
The 'irst statement in main(*0 smallo!$ s1# s2; de'ines t!o o(6ects0 s= and s;0 o' class smallo(6. 8emem(er that the declaration 'or the class smallo(6 does not create any o(6ects. +t only descri(es ho! they !ill loo !hen they are created0 6ust as a structure declaration descri(es ho! a structure !ill loo (ut doesnHt create any structure varia(les. +t is the definition that actually creates o(6ects that can (e used (y the "rogram. De'ining an o(6ect is similar to de'ining a varia(le o' any data ty"e: S"ace is set aside 'or it in memory. De'ining o(6ects in this !ay means creating them. This is also called instantiating them. The term instantiating arises (ecause an instance o' the class is created. 5n o(6ect is an instance (that is0 a s"eci'ic e4am"le* o' a class. %(6ects are sometimes called instance variables.

Calling &em(er /unctions


The ne4t t!o statements in main(* call the mem(er 'unction setdata(*: s1.setdata(1/MM); s2.setdata(111M); These statements donHt loo li e normal 'unction calls. #hy are the o(6ect names s= and s; connected to the 'unction names !ith a "eriodW This strange synta4 is used to call a mem(er 'unction that is associated with a specific object. 1ecause setdata(* is a mem(er 'unction o' the smallo(6 class0 it must al!ays (e called in connection !ith an o(6ect o' this class. +t doesnHt ma e sense to say setdata(1/MM); (y itsel'0 (ecause a mem(er 'unction is al!ays called to act on a s"eci'ic o(6ect0 not on the class in general. 5ttem"ting to access the class this !ay !ould (e li e trying to drive the (lue"rint o' a car. Not only does this statement not ma e sense0 (ut the com"iler !ill issue an error message i' you attem"t it. &em(er 'unctions o' a class can (e accessed only (y an o(6ect o' that class. To use a mem(er 'unction0 the dot o"erator (the "eriod* connects the o(6ect name and the mem(er 'unction. The synta4 is similar to the !ay !e re'er to structure mem(ers0 (ut the "arentheses signal that !eHre e4ecuting a mem(er 'unction rather than re'erring to a data item. (The dot o"erator is also called the class member access o"erator.* The 'irst call to setdata(*0 s1.setdata(1/MM); e4ecutes the setdata(* mem(er 'unction o' the s= o(6ect. This 'unction sets the varia(le somedata in o(6ect s= to the value =FCC. The second call0 s2.setdata(111M); causes the varia(le somedata in s; to (e set to =DDC. No! !e have t!o o(6ects !hose somedata varia(les have di''erent values0 as sho!n in /igure (elo!.

Similarly0 the 'ollo!ing t!o calls to the sho!data(* 'unction !ill cause the t!o o(6ects to dis"lay their values: s1.sho,data();

s2.sho,data();

&essages
Some o(6ect]oriented languages re'er to calls to mem(er 'unctions as messages. Thus the call s1.sho,data(); can (e thought o' as sending a message to s= telling it to sho! its data. The term message is not a 'ormal term in C++0 (ut it is a use'ul idea to ee" in mind as !e discuss mem(er 'unctions. Tal ing a(out messages em"hasiPes that o(6ects are discrete entities and that !e communicate !ith them (y calling their mem(er 'unctions.

Constructor
5 constructor is a mem(er 'unction that is e4ecuted automatically !henever an o(6ect is created. (The term constructor is sometimes a((reviated ctor0 es"ecially in "rogram listings.*

5 Counter 34am"le
5s an e4am"le0 !eHll create a class o' o(6ects that might (e use'ul as a general]"ur"ose "rogramming element. 5 counter is a varia(le that counts things. &ay(e it counts 'ile accesses0 or the num(er o' times the user "resses the a3nterb ey0 or the num(er o' customers entering a (an . 3ach time such an event ta es "lace0 the counter is incremented (= is added to it*. The counter can also (e accessed to 'ind the current count. ,etHs assume that this counter is im"ortant in the "rogram and must (e accessed (y many di''erent 'unctions. +n "rocedural languages such as C0 a counter !ould "ro(a(ly (e im"lemented as an e4ternal

varia(le. This e4am"le0 C%.NT380 "rovides a counter varia(le that can (e modi'ied only through its mem(er 'unctions. 22 counter.cpp 22 o!$ect represents a counter varia!le #include <iostream> usin+ namespace std; 2222222222222222222222222222222222222222222222222222222222222222 class 4ounter { private7 unsi+ned int count; 22count pu!lic7 4ounter() 7 count(/) 22constructor K /\em"ty (ody\/ M void inc9count(* //increment count K count++L M int get9count(* //return count K return countL M ML //////////////////////////////////////////////////////////////// int main(* K Counter c=0 c;L //de'ine and initialiPe cout UU QYnc=[R UU c=.get9count(*L //dis"lay cout UU QYnc;[R UU c;.get9count(*L c=.inc9count(*L c;.inc9count(*L c;.inc9count(*L //increment c= //increment c; //increment c;

cout UU QYnc=[R UU c=.get9count(*L //dis"lay again cout UU QYnc;[R UU c;.get9count(*L cout UU endlL return FL M The Counter class has one data mem(er: count0 o' ty"e unsigned int (since the count is al!ays "ositive*. +t has three mem(er 'unctions: the constructor Counter(*0 !hich !eHll loo at in a momentL inc9count(*0 !hich adds = to countL and get9count(*0 !hich returns the current value o' count.

5utomatic +nitialiPation
#hen an o(6ect o' ty"e Counter is 'irst created0 !e !ant its count to (e initialiPed to F. 5'ter all0 most counts start at F. #e could "rovide a set9count(* 'unction to do this and call it !ith an argument o' F0 or !e could "rovide a Pero9count(* 'unction0 !hich !ould al!ays set count to F. -o!ever0 such 'unctions !ould need to (e e4ecuted every time !e created a Counter o(6ect. 4ounter c1; 22ever% time ,e do this# c1.@ero&count(); 22,e must do this too This is mista e "rone0 (ecause the "rogrammer may 'orget to initialiPe the o(6ect a'ter creating it. +tHs more relia(le and convenient0 es"ecially !hen there are a great many o(6ects o' a given class0 to cause each o(6ect to initialiPe itsel' !hen itHs created. +n the Counter class0 the constructor Counter(* does this. This 'unction is called automatically !henever a ne! o(6ect o' ty"e Counter is created. Thus in main(*0 the statement 4ounter c1# c2;

creates t!o o(6ects o' ty"e Counter. 5s each is created0 its constructor0 Counter(*0 is e4ecuted. This 'unction sets the count varia(le to F. So the e''ect o' this single statement is to not only create t!o o(6ects0 (ut also to initialiPe their count varia(les to F.

Same Name 5s the Class


There are some unusual as"ects o' constructor 'unctions. /irst0 it is no accident that they have e4actly the same name (Counter in this e4am"le* as the class o' !hich they are mem(ers. This is one !ay the com"iler no!s they are constructors. Second0 no return ty"e is used 'or constructors. #hy notW Since the constructor is called automatically (y the system0 thereHs no "rogram 'or it to return anything toL a return value !ouldnHt ma e sense. This is the second !ay the com"iler no!s they are constructors.

+nitialiPer ,ist
%ne o' the most common tas s a constructor carries out is initialiPing data mem(ers. +n the Counter class the constructor must initialiPe the count mem(er to F. Nou might thin that this !ould (e done in the constructorHs 'unction (ody0 li e this: count() K count [ FL M -o!ever0 this is not the "re'erred a""roach (although it does !or *. -ereHs ho! you should initialiPe a data mem(er: count(* : count(F* K M The initialiPation ta es "lace 'ollo!ing the mem(er 'unction declarator (ut (e'ore the 'unction (ody. +tHs "receded (y a colon. The value is "laced in "arentheses 'ollo!ing the mem(er data. +' multi"le mem(ers must (e initialiPed0 theyHre se"arated (y commas. The result is the initializer list (sometimes called (y other names0 such as the memberinitialization list*. someClass(* : m=(D*0 m;(GG*0 m;(>* c initialiPer list K M #hy not initialiPe mem(ers in the (ody o' the constructorW The reasons are com"le40 (ut have to do !ith the 'act that mem(ers initialiPed in the initialiPer list are given a value (e'ore the constructor even starts to e4ecute. This is im"ortant in some situations. /or e4am"le0 the initialiPer list is the only !ay to initialiPe const mem(er data and re'erences. 5ctions more com"licated than sim"le initialiPation must (e carried out in the constructor (ody0 as !ith ordinary 'unctions.

&essing !ith the /ormat


Note that0 in !riting the 'unctions in this e4am"le0 !eHve com"ressed them so they occu"y only t!o lines each: 4ounter() { count ' /; This is 6ust the same (as 'ar as the com"iler is concerned* as the normal 'unction synta4 4ounter() { count ' /; The main(* "art o' this "rogram e4ercises the Counter class (y creating t!o counters0 c= and c;. +t causes the counters to dis"lay their initial values0 !hichSas arranged (y the constructorSare F. +t then increments c= once and c; t!ice0 and again causes the counters to dis"lay themselves (non]criminal (ehavior in this conte4t*. -ereHs the out"ut: c1'/ c2'/ c1'1 c1'2

+' this isnHt enough "roo' that the constructor is o"erating as advertised0 !e can re!rite the constructor to "rint a message !hen it e4ecutes. 4ounter() 7 count(/) { cout << B=>m the constructor\nE; No! the "rogramHs out"ut loo s li e this: =>m the constructor =>m the constructor c1'/ c2'/ c1'1 c2'2 5s you can see0 the constructor is e4ecuted t!iceSonce 'or c= and once 'or c;S!hen the statement 4ounter c1# c2; is e4ecuted in main(*.

Varia(les and Storage Classes


No! that !e no! a(out 'unctions0 !e can e4"lore a 'eature o' C++ thatHs related to the interaction o' varia(les and 'unctions: the storage class. The storage class o' a varia(le determines !hich "arts o' the "rogram can access it and ho! long it stays in e4istence. #eHll loo at varia(les !ith three storage classes Sautomatic0 e4ternal0 and static.

5utomatic Varia(les
So 'ar almost all the varia(les !eHve used in e4am"le "rograms have (een de'ined inside the 'unction in !hich they are used. That is0 the de'inition occurs inside the (races that delimit the 'unction (ody: void somefunc() { int somevar; 22varia!les defined ,ithin float othervar; 22the function !od% 22 other statements Varia(les may (e de'ined inside main(* or inside other 'unctionsL the e''ect is similar0 since main(* is a 'unction. Varia(les de'ined !ithin a 'unction (ody are called automatic variables. 5ctually0 a ey!ord0 auto0 can (e used to s"eci'y an automatic varia(le. Nou !ould say void somefunc() { auto int somevar; 22same as int somevar auto float othervar; 22same as float othervar 22 other statements -o!ever0 since this is the de'ault0 there is seldom any need to use the auto ey!ord. Varia(les de'ined !ithin a 'unction are automatic any!ay. ,etHs loo at the t!o im"ortant characteristics o' automatic varia(lesSli'etime and visi(ility.

&ifetime
5n automatic varia(le is not created until the 'unction in !hich it is de'ined is called. (&ore accurately0 !e can say that varia(les de'ined !ithin any (loc o' code are not created until the (loc is e4ecuted.* +n the "rogram 'ragment 6ust given0 the varia(les somevar and othervar donHt e4ist until the some'unc(* 'unction is called. That is0 there is no "lace in memory !here their values are storedL they are unde'ined. #hen control is trans'erred to some'unc(*0 the varia(les are created and memory s"ace is set aside 'or them. ,ater0 !hen some'unc(* returns and control is "assed (ac to the calling "rogram0 the varia(les are destroyed and their values are lost. The name automatic is used (ecause the varia(les are automatically created !hen a 'unction is called and automatically destroyed !hen it returns.

The time "eriod (et!een the creation and destruction o' a varia(le is called its li'etime (or sometimes its duration*. The li'etime o' an automatic varia(le coincides !ith the time !hen the 'unction in !hich it is de'ined is e4ecuting. The idea (ehind limiting the li'etime o' varia(les is to save memory s"ace. +' a 'unction is not e4ecuting0 the varia(les it uses during e4ecution are "resuma(ly not needed. 8emoving them 'rees u" memory that can then (e used (y other 'unctionsA

?isi/ilit(
5 varia(leHs visi(ility descri(es the locations !ithin a "rogram 'rom !hich it can (e accessed. +t can (e re'erred to in statements in some "arts o' the "rogramL (ut in others0 attem"ts to access it lead to an un no!n varia(le error message. The !ord sco"e is also used to descri(e visi(ility. The sco"e o' a varia(le is that "art o' the "rogram !here the varia(le is visi(le. 5utomatic varia(les are only visi(le0 meaning they can only (e accessed0 !ithin the 'unction in !hich they are de'ined. Su""ose you have t!o 'unctions in a "rogram: void some'unc(* K int somevarL //automatic varia(les 'loat othervarL somevar [ =FL //%K othervar [ ==L //%K ne4tvar [ =;L //illegal: not visi(le in some'unc(* M void other'unc(* K int ne4tvarL //automatic varia(le somevar [ ;FL //illegal: not visi(le in other'unc(* othervar [ ;=L //illegal: not visi(le in other'unc(* ne4tvar [ ;;L //%K M The varia(le ne4tvar is invisi(le in 'unction some'unc(*0 and the varia(les somevar and othervar are invisi(le in other'unc(*. ,imiting the visi(ility o' varia(les hel"s organiPe and modulariPe the "rogram. Nou can (e con'ident that the varia(les in one 'unction are sa'e 'rom accidental alteration (y other 'unctions (ecause the other 'unctions canHt see them. This is an im"ortant "art o' structured "rogramming0 the methodology 'or organiPing old:'ashioned "rocedural "rograms. ,imiting visi(ility is also an im"ortant "art o' %(6ect: %riented $rogramming. +n the case o' automatic varia(les0 li'etime and visi(ility coincide: These varia(les e4ist only !hile the 'unction in !hich they are de'ined is e4ecuting0 and are only visi(le !ithin that 'unction. /or some storage classes0 ho!ever0 li'etime and visi(ility are not the same. +nitialiPation #hen an automatic varia(le is created0 the com"iler does not try to initialiPe it. Thus it !ill start o'' !ith an ar(itrary value0 !hich may (e F (ut "ro(a(ly !ill (e something else. +' you !ant it initialiPed0 you must do it e4"licitly0 as in int n [ GGL then it !ill start o'' !ith this value. 5utomatic varia(les are sometimes called local varia(les0 since they are visi(le only locally0 in the 'unction !here they are de'ined.

0=ternal ?aria/les
The ne4t ma6or storage class is external. #hile automatic varia(les are de'ined !ithin 'unctions0 e4ternal varia(les are de'ined outside o' (e4ternal to* any 'unction. 5n e4ternal varia(le is visi(le to all the

'unctions in a "rogram. &ore "recisely0 it is visi(le to all those 'unctions that 'ollo! the varia(leHs de'inition in the listing. .sually you !ant e4ternal varia(les to (e visi(le to all 'unctions0 so you "ut their declarations at the (eginning o' the listing. 34ternal varia(les are also called global variables since they are no!n (y all the 'unctions in a "rogram. -ereHs a "rogram0 3AT38N0 in !hich three 'unctions all access an e4ternal varia(le. 22 e"tern.cpp 22 demonstrates e"ternal varia!les #include <iostream> usin+ namespace std; #include <conio.h> 22for +etch() char ch ' Na>; void +etachar(); void putachar(); int main() { ,hile( ch O' N\r> ) { +etachar(); putachar(); cout << endl; return /; 2299999999999999999999999999999999999999999999999999999999999999 void +etachar() 22+etachar() accesses ch { ch ' +etch(); 2299999999999999999999999999999999999999999999999999999999999999 void putachar() 22putachar() accesses ch { cout << ch; 22e"teral varia!le ch 22function declarations

22main() accesses ch

%ne 'unction in 3AT38N0 getachar(*0 reads characters 'rom the ey(oard. +t uses the li(rary 'unction getch(*0 !hich is li e getche(* e4ce"t that it doesnHt echo the character ty"ed to the screen (hence the a(sence o' the 'inal e in the name*. 5 second 3AT38N 'unction0 "utachar(*0 dis"lays each character on the screen. The e''ect is that !hat you ty"e is dis"layed in the normal !ay: +Hm ty"ing in this line o' te4t The signi'icant thing a(out this "rogram is that the varia(le ch is not de'ined in any o' the 'unctions. +nstead it is de'ined at the (eginning o' the 'ile0 (e'ore the 'irst 'unction. +t is an e4ternal varia(le. 5ny 'unction that 'ollo!s the de'inition o' ch in the listing can access itSin this case all the 'unctions in 3AT38N: main(*0 getachar(*0 and "utachar(*. Thus the visi(ility o' ch is the entire source 'ile.

Role of 0=ternal ?aria/les


The e4ternal storage class is used !hen a varia(le must (e accessi(le to more than one 'unction in a "rogram. +n "rocedural "rograms0 e4ternal varia(les are o'ten the most im"ortant varia(les in the "rogram. -o!ever0 as !e noted earlier 0 e4ternal varia(les create organiPational "ro(lems 'or the very reason that they can (e accessed (y any 'unction. The !rong 'unctions may access them0 or 'unctions may access them incorrectly. +n an o(6ect:oriented "rogram0 there is less necessity 'or e4ternal varia(les.

#nitialiLation

+' an e4ternal varia(le is initialiPed0 as in int e4var [ =BBL this initialiPation ta es "lace !hen the 'ile is 'irst loaded. +' an e4ternal varia(le is not initialiPed e4"licitly (y the "rogramL 'or e4am"le0 i' it is de'ined as int e4varL then it is initialiPed automatically to F !hen it is created. (This is unli e automatic varia(les0 !hich are not initialiPed and "ro(a(ly contain random or gar(age values !hen they are created.*

&ifetime and ?isi/ilit(


34ternal varia(les e4ist 'or the li'e o' the "rogram. That is0 memory s"ace is set aside 'or them !hen the "rogram (egins0 and continues in e4istence until the "rogram ends. 5s !e noted0 e4ternal varia(les are visi(le in the 'ile in !hich they are de'ined0 starting at the "oint !here they are de'ined. +' ch !ere de'ined 'ollo!ing main(* (ut (e'ore getachar(*0 it !ould (e visi(le in getachar(* and "utachar(*0 (ut not in main(*.

Static Varia(les
#eHll touch on another storage class: static. -ere !e are concerned !ith static automatic varia(les. There are static e4ternal varia(les0 (ut their meaning !ill (e discussed !hen need arises. 5 static automatic varia(le has the visi(ility o' a local varia(le (that is0 inside the 'unction containing it*. +ts li'etime is similar to that o' an e4ternal varia(le0 e4ce"t that it doesnHt come into e4istence until the 'irst call to the 'unction containing it. Therea'ter it remains in e4istence 'or the li'e o' the "rogram. Static automatic varia(les are used !hen itHs necessary 'or a 'unction to remem(er a value !hen it is not (eing e4ecutedL that is0 (et!een calls to the 'unction. +n the ne4t e4am"le0 a 'unction0 getavg(*0 calculates a running average. +t remem(ers the total o' the num(ers it has averaged (e'ore0 and ho! many there !ere. 3ach time it receives a ne! num(er0 sent as an argument 'rom the calling "rogram0 it adds this num(er to the total0 adds = to a count0 and returns the ne! average (y dividing the total (y the count. -ereHs the listing 'or ST5T+C: // static.c"" // demonstrates static varia(les Tinclude UiostreamV using names"ace stdL 'loat getavg('loat*L //declaration int main(* K 'loat data[=0 avgL !hile( data J[ F * K cout UU Q3nter a num(er: RL cin VV dataL avg [ getavg(data*L cout UU QNe! average is R UU avg UU endlL M return FL M //:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: // getavg(* // 'inds average o' old "lus ne! data 'loat getavg('loat ne!data* K static 'loat total [ FL //static varia(les are initialiPed static int count [ FL // only once "er "rogram count++L //increment count

total +[ ne!dataL //add ne! data to total return total / countL //return the ne! average M -ereHs some sam"le interaction: 3nter a num(er: =F Ne! average is =F ctotal is =F0 count is = 3nter a num(er: ;F Ne! average is =? ctotal is GF0 count is ; 3nter a num(er: GF Ne! average is ;F ctotal is CF0 count is G The static varia(les total and count in getavg(* retain their values a'ter getavg(* returns0 so theyHre availa(le the ne4t time itHs called.

+nitialiPation
#hen static varia(les are initialiPed0 as total and count are in getavg(*0 the initialiPation ta es "lace only onceSthe 'irst time their 'unction is called. They are not reinitialiPed on su(se)uent calls to the 'unction0 as ordinary automatic varia(les are.

,torage
+' youHre 'amiliar !ith o"erating system architecture0 you might (e interested to no! that automatic varia(les are stored on the stac 0 !hile e4ternal and static varia(les are stored on the hea" %a/le Storage Ty"es >$tomatic Visi(ility 'unction ,i'etime 'unction +nitialiPed value not initialiPed Storage stac $ur"ose Varia(les used (y a single 'unction. ,tatic >$to 'unction "rogram F hea" Same as auto0 (ut must retain value !hen 'unction terminates. 0=ternal 'ile "rogram F hea" Varia(les used (y several 'unctions

DoV#tV8o$rself Data
Constructors are "retty amaPing !hen you thin a(out it. #hoever !rites language com"ilers ('or C or 15S+C or even 'or C++* must e4ecute the e)uivalent o' a constructor !hen the user de'ines a varia(le. +' you de'ine an int0 'or e4am"le0 some!here thereHs a constructor allocating 'our (ytes o' memory 'or it. +' !e can !rite our o!n constructors !e can start to ta e over some o' the tas s o' a com"iler !riter. This is one ste" on the "ath to creating our o!n data ty"es0 as !eHll see later.

> 6ra-hics 0=am-le


,etHs re!rite our earlier C+8C,3S e4am"le to use a constructor instead o' a set(* 'unction. To handle the initialiPation o' the 'ive attri(utes o' circles0 this constructor !ill have 'ive arguments and 'ive items in its initialiPation list. -ereHs the listing 'or C+8CT%8: // circtor.c"" // circles use constructor 'or initialiPation Tinclude Qmso'tcon.hR // 'or gra"hics 'unctions //////////////////////////////////////////////////////////////// class circle //gra"hics circle K

"rotected: int 4Co0 yCoL int radiusL color 'illcolorL 'style 'illstyleL "u(lic:

//coordinates o' center //color //'ill "attern

//constructor circle(int 40 int y0 int r0 color 'c0 'style 's* : 4Co(4*0 yCo(y*0 radius(r*0 'illcolor('c*0 'illstyle('s* K M void dra!(* //dra!s the circle K set9color('illcolor*L //set color set9'ill9style('illstyle*L //set 'ill dra!9circle(4Co0 yCo0 radius*L //dra! solid circle M ML //////////////////////////////////////////////////////////////// int main(* K init9gra"hics(*L //initialiPe gra"hics system //create circles circle c=(=?0 D0 ?0 c1,.30 A9/+,,*L circle c;(>=0 =;0 D0 c83D0 %9/+,,*L circle cG(C?0 =^0 >0 c2833N0 &3D+.&9/+,,*L c=.dra!(*L //dra! circles c;.dra!(*L cG.dra!(*L set9cursor9"os(=0 ;?*L //lo!er le't corner return FL M This "rogram is similar to C+8C,3S0 e4ce"t that set(* has (een re"laced (y the constructor. Note ho! this sim"li'ies main(*. +nstead o' t!o se"arate statements 'or each o(6ect0 one to create it and one to set its attri(utes0 no! one statement (oth creates the o(6ect and sets its attri(utes at the same time.

Destructors
We;ve seen that a s-ecial mem/er f$nctionTthe constr$ctorTis called automatically !hen an
o(6ect is 'irst created. Nou might guess that another 'unction is called automatically !hen an o(6ect is destroyed. This is indeed the case. Such a 'unction is called a destructor. 5 destructor has the same name as the constructor (!hich is the same as the class name* (ut is "receded (y a tilde: class /oo K "rivate: int dataL "u(lic: /oo(* : data(F* //constructor (same name as class* K M d/oo(* //destructor (same name !ith tilde* K M ML ,i e constructors0 destructors do not have a return value. They also ta e no arguments (the assum"tion (eing that thereHs only one !ay to destroy an o(6ect*. The most common use o' destructors is to deallocate memory that !as allocated 'or the o(6ect (y the constructor.

Pol(mor-hism
The static "olymor"hism is im"lemented (y %verloading and dynamic "olymor"hism is done (y a conce"t ,ate 1inding

%verloaded /unctions
5n overloaded 'unction a""ears to "er'orm di''erent activities de"ending on the ind o' data sent to it. %verloading is li e the 6o e a(out the 'amous scientist !ho insisted that the thermos (ottle !as the greatest invention o' all time. #hyW Q+tHs a miracle device0R he said. Q+t ee"s hot things hot0 (ut cold things it ee"s cold. -o! does it no!WR +t may seem e)ually mysterious ho! an overloaded 'unction no!s !hat to do. +t "er'orms one o"eration on one ind o' data (ut another o"eration on a di''erent ind. ,etHs clari'y matters !ith some e4am"les.

Di''erent Num(ers o' 5rguments


8ecall the starline(* 'unction in the T51,3 e4am"le and the re"char(* 'unction 'rom the T51,3582 e4am"le0 (oth sho!n earlier in this cha"ter. The starline(* 'unction "rinted a line using >? asteris s0 !hile re"char(* used a character and a line length that !ere (oth s"eci'ied !hen the 'unction !as called. #e might imagine a third 'unction0 charline(*0 that al!ays "rints >? characters (ut that allo!s the calling "rogram to s"eci'y the character to (e "rinted. These three 'unctionsSstarline(*0 re"char(*0 and charline(* S"er'orm similar activities (ut have di''erent names. /or "rogrammers using these 'unctions0 that means three names to remem(er and three "laces to loo them u" i' they are listed al"ha(etically in an a""licationHs !unction "eference documentation. +t !ould (e 'ar more convenient to use the same name 'or all three 'unctions0 even though they each have di''erent arguments. -ereHs a "rogram0 %V38,%5D0 that ma es this "ossi(le: 22 overload.cpp 22 demonstrates function overloadin+ #include <iostream> usin+ namespace std; void repchar(); void repchar(char); void repchar(char# int); int main() { repchar(); repchar(N'>); repchar(N*># -/); return /; 2299999999999999999999999999999999999999999999999999999999999999 22 repchar() 22 displa%s H. asteris0s void repchar() { for(int $'/; $<H.; $**) 22 al,a%s loops H. times cout << N3>; 22 al,a%s prints asteris0 cout << endl; 2299999999999999999999999999999999999999999999999999999999999999 22 repchar() // dis"lays >? co"ies o' s"eci'ied character void re"char(char ch* K 22declarations

'or(int 6[FL 6U>?L 6++* // al!ays loo"s >? times cout UU chL // "rints s"eci'ied character cout UU endlL M //:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: // re"char(* // dis"lays s"eci'ied num(er o' co"ies o' s"eci'ied character void re"char(char ch0 int n* K 'or(int 6[FL 6UnL 6++* // loo"s n times cout UU chL // "rints s"eci'ied character cout UU endlL M This "rogram "rints out three lines o' characters. -ereHs the out"ut: \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ ++++++++++++++++++++++++++++++ The 'irst t!o lines are >? characters long0 and the third is GF. The "rogram contains three 'unctions !ith the same name. There are three declarations0 three 'unction calls0 and three 'unction de'initions. #hat ee"s the com"iler 'rom (ecoming ho"elessly con'usedW +t uses the num(er o' arguments0 and their data ty"es0 to distinguish one 'unction 'rom another. +n other !ords0 the declaration void re"char(*L !hich ta es no arguments0 descri(es an entirely di''erent 'unction than the declaration void re"char(char*L !hich ta es one argument o' ty"e char0 or the declaration void re"char(char0 int*L !hich ta es one argument o' ty"e char and another o' ty"e int. The com"iler0 seeing several 'unctions !ith the same name (ut di''erent num(ers o' arguments0 could decide the "rogrammer had made a mista e (!hich is !hat it !ould do in C*. +nstead0 it very tolerantly sets u" a se"arate 'unction 'or every such de'inition. #hich one o' these 'unctions !ill (e called de"ends on the num(er o' arguments su""lied in the call. /igure (elo! sho!s this "rocess.

#nheritance
Inheritance is "ro(a(ly the most "o!er'ul 'eature o' %(6ect:%riented $rogramming0 a'ter classes

themselves. +nheritance is the "rocess o' creating ne! classes0 called derived classes0 'rom e4isting or base classes. The derived class inherits all the ca"a(ilities o' the (ase class (ut can add em(ellishments and re'inements o' its o!n. The (ase class is unchanged (y this "rocess. The inheritance relationshi" is sho!n in /igure (elo!. The arro! goes in the o""osite direction o' !hat you might e4"ect. +' it "ointed do!n !e !ould la(el it inheritance. -o!ever0 the more common a""roach is to "oint the arro! u"0 'rom the derived class to the (ase class0 and to thin o' it as a Qderived 'romR arro!. +nheritance is an essential "art o' %%$. +ts (ig "ayo'' is that it "ermits code reusabilit#. %nce a (ase class is !ritten and de(ugged0 it need not (e touched again0 (ut0 using inheritance0 can nevertheless (e ada"ted to !or in di''erent situations. 8eusing e4isting code saves time and money and increases a "rogramHs relia(ility. +nheritance can also hel" in the original conce"tualiPation o' a "rogramming "ro(lem0 and in the overall design o' the "rogram. 5n im"ortant result o' reusa(ility is the ease o' distri(uting class li(raries. 5 "rogrammer can use a class created (y another "erson or com"any0 and0 !ithout modi'ying it0 derive other classes 'rom it that are suited to "articular situations.

,etHs su""ose that !e have !or ed long and hard to ma e the Counter class o"erate 6ust the !ay !e !ant0 and !eHre "leased !ith the results0 e4ce"t 'or one thing. #e really need a !ay to decrement the count. $erha"s !eHre counting "eo"le entering a (an 0 and !e !ant to increment the count !hen they come in and decrement it !hen they go out0 so that the count re"resents the num(er o' "eo"le in the (an at any moment. #e could insert a decrement routine directly into the source code o' the Counter class. -o!ever0 there are several reasons !hy !e might not !ant to do this. /irst0 the Counter class !or s very !ell and has undergone many hours o' testing and de(ugging. (%' course thatHs an e4aggeration in this case0 (ut it !ould (e true in a larger and more com"le4 class.* +' !e start 'ooling around !ith the source code 'or Counter0 the testing "rocess !ill need to (e carried out again0 and o' course !e may 'oul something u" and s"end hours de(ugging code that !or ed 'ine (e'ore !e modi'ied it. +n some situations there might (e another reason 'or not modi'ying the Counter class: #e might not have access to its source code0 es"ecially i' it had (een distri(uted as "art o' a class li(rary. To avoid these "ro(lems !e can use inheritance to create a ne! class (ased on Counter0 !ithout modi'ying Counter itsel'. -ereHs the listing 'or C%.NT3N0 !hich includes a ne! class0 CountDn0 that adds a decrement o"erator to the Counter class: 22 counten.cpp 22 inheritance ,ith 4ounter class #include <iostream> usin+ namespace std; 2222222222222222222222222222222222222222222222222222222222222222 class 4ounter 22!ase class { protected7 22;D(P7 not private unsi+ned int count; 22count pu!lic7

4ounter() 7 count(/) { 4ounter(int c) 7 count(c) { unsi+ned int +et&count() const K return countL M Counter increment(* //incr count ("re'i4* K return Counter(++count*L M ML //////////////////////////////////////////////////////////////// class CountDn : "u(lic Counter //derived class K "u(lic: Counter decrement(*//decr count ("re'i4* K return Counter(::count*L M ML //////////////////////////////////////////////////////////////// int main(* K CountDn c=L //c= o' class CountDn cout UU QYnc=[R UU c=.get9count(*L //dis"lay c=

22no9ar+ constructor 2219ar+ constructor 22return count

c=.increment(*L c=. increment(*L c=. increment(*L //increment c=0 G times cout UU QYnc=[R UU c=.get9count(*L //dis"lay it c=.decrement(*L c=.decrement(*L cout UU QYnc=[R UU c=.get9count(*L cout UU endlL return FL M //decrement c=0 t!ice //dis"lay it

The listing starts o'' !ith the Counter class0 !hich (!ith one small e4ce"tion0 !hich !eHll loo at later* has not changed since its a""earance in C%.NT$$G.

,-ecif(ing the Derived Class


/ollo!ing the Counter class in the listing is the s"eci'ication 'or a ne! class0 CountDn. This class incor"orates a ne! 'unction0 decrement(*0 !hich decrements the count. -o!everSand hereHs the ey "oint Sthe ne! CountDn class inherits all the 'eatures o' the Counter class. CountDn doesnHt need a constructor or the get9count(* or increment(* 'unctions0 (ecause these already e4ist in Counter. The 'irst line o' CountDn s"eci'ies that it is derived 'rom Counter: class 4ountLn 7 pu!lic 4ounter -ere !e use a single colon (not the dou(le colon used 'or the sco"e resolution o"erator*0 'ollo!ed (y the ey!ord "u(lic and the name o' the (ase class Counter. This sets u" the relationshi" (et!een the classes. %his line sa(s Co$ntDn is derived from the base class Co$nterA 8emem(er that the arro! in diagrams li e this means derived from. The arro!s "oint this !ay to em"hasiPe that the derived class refers to 'unctions and data in the (ase class0 !hile the (ase class has no access to the derived class. &athematicians call this ind o' diagram a directed ac#clic graph.

>ccessing Base Class Mem/ers


5n im"ortant to"ic in inheritance is no!ing !hen a mem(er 'unction in the (ase class can (e used (y o(6ects o' the derived class. This is called accessibilit#. ,etHs see ho! the com"iler handles the accessi(ility issue in the C%.NT3N e4am"le.

,$/stit$ting Base Class Constr$ctors


+n the main(* "art o' C%.NT3N !e create an o(6ect o' class CountDn: 4ountLn c1; This causes c= to (e created as an o(6ect o' class CountDn and initialiPed to F. 1ut !aitSho! is this "ossi(leW There is no constructor in the CountDn class s"eci'ier0 so !hat entity carries out the initialiPationW +t turns out thatSat least under certain circumstancesSi' you donHt s"eci'y a constructor0 the derived class !ill use an a""ro"riate constructor 'rom the (ase class. +n C%.NT3N thereHs no constructor in CountDn0 so the com"iler uses the no:argument constructor 'rom Count. This 'le4i(ility on the "art o' the com"ilerSusing one 'unction (ecause another isnHt availa(leSa""ears regularly in inheritance situations. 2enerally0 the su(stitution is !hat you !ant0 (ut sometimes it can (e unnerving.

,$/stit$ting Base Class Mem/er F$nctions


The o(6ect c= o' the CountDn class also uses the increment(* and get9count(* 'unctions 'rom the Counter class. The 'irst is used to increment c=: **c1; and the second is used to dis"lay the count in c=: cout << B\nc1'E << c1.+et&count(); 5gain the com"iler0 not 'inding these 'unctions in the class o' !hich c= is a mem(er0 uses mem(er 'unctions 'rom the (ase class.

O$t-$t of CO*)%0)
+n main(* !e increment c= three times0 "rint out the resulting value0 decrement c= t!ice0 and 'inally "rint out its value again. -ereHs the out"ut: c1'/ <<<< after initiali@ation c1'<<<< after **c1# **c1# **c1 c1'1 <<<< after 99c1# 99c1 The increment o"erator0 the constructors0 the get9count(* 'unction in the Counter class0 and the decrement in the CountDn class all !or !ith o(6ects o' ty"e CountDn.

%he -rotected >ccess ,-ecifier


#e have increased the 'unctionality o' a class !ithout modi'ying it. #ell0 almost !ithout modi'ying it. ,etHs loo at the single change !e made to the Counter class. The data in the classes !eHve loo ed at so 'ar0 including count in the Counter class in the earlier C%.NT$$G "rogram0 have used the "rivate access s"eci'ier. +n the Counter class in C%.NT3N0 count is given a ne! s"eci'ier: "rotected. #hat does this doW ,etHs 'irst revie! !hat !e no! a(out the access s"eci'iers "rivate and "u(lic. Class mem(ers (!hich can (e data or 'unctions* can al!ays (e accessed (y 'unctions within their own class !hether the mem(ers are "rivate or "u(lic. 1ut o(6ects o' a class de'ined outside the class can access class mem(ers only i' the mem(ers are "u(lic. /or instance0 su""ose an o(6ect o(65 is an instance o' class 50 and 'unction 'unc5(* is a mem(er 'unction o' 5. Then in main(* (or any other 'unction that is not a mem(er o' 5* the statement o!$F.funcF(); !ill not (e legal unless 'unc(* is "u(lic. The o(6ect o(65 cannot access "rivate mem(ers o' class 5. $rivate mem(ers are0 !ell0 private. This is sho!n in /igure (elo!.

This is all !e need to no! i' !e donHt use inheritance. #ith inheritance0 ho!ever0 there is a !hole ra't o' additional "ossi(ilities. The )uestion that concerns us at the moment is0 can mem(er 'unctions o' the derived class access mem(ers o' the (ase classW +n other !ords0 can o"erator::(* in CountDn access count in CounterW The ans!er is that mem(er 'unctions can access mem(ers o' the (ase class i' the mem(ers are "u(lic0 or i' they are "rotected. They canHt access "rivate mem(ers. #e donHt !ant to ma e count "u(lic0 since that !ould allo! it to (e accessed (y any 'unction any!here in the "rogram and eliminate the advantages o' data hiding. 5 "rotected mem(er0 on the other hand0 can (e accessed (y mem(er 'unctions in its o!n class orSand hereHs the eySin any class derived 'rom its o!n class. +t canHt (e accessed 'rom 'unctions outside these classes0 such as main(*. This is 6ust !hat !e !ant. The situation is sho!n (elo! : +nheritance and 5ccessi(ility >ccess >ccessi/le from >ccessi/le from >ccessi/le from ,-ecifier Own Class Derived Class O/Jects O$tside Class $u(lic yes yes yes $rotected yes yes no $rivate yes no no 5ccess s"eci'iers !ith inheritance.

The moral is that i' you are !riting a class that you sus"ect might (e used0 at any "oint in the 'uture0 as a (ase class 'or other classes0 then any mem(er data that the derived classes might need to access should (e made "rotected rather than "rivate. This ensures that the class is Qinheritance ready.R

Dangers of -rotected
Nou should no! that thereHs a disadvantage to ma ing class mem(ers "rotected. Say youHve !ritten a class li(rary0 !hich youHre distri(uting to the "u(lic. 5ny "rogrammer !ho (uys this li(rary can access "rotected mem(ers o' your classes sim"ly (y deriving other classes 'rom them. This ma es "rotected mem(ers considera(ly less secure than "rivate mem(ers. To avoid corru"ted data0 itHs o'ten sa'er to 'orce derived classes to access data in the (ase class using only "u(lic 'unctions in the (ase class0 6ust as ordinary main(* "rograms must do. .sing the "rotected s"eci'ier leads to sim"ler "rogramming0 so !e rely on itS "erha"s a (it too muchSin the e4am"les in this (oo . NouHll need to !eigh the advantages o' "rotected against its disadvantages in your o!n "rograms.

Base Class *nchanged


8emem(er that0 even i' other classes have (een derived 'rom it0 the (ase class remains unchanged. +n the main(* "art o' C%.NT3N0 !e could de'ine o(6ects o' ty"e Counter: 4ounter c2; <<<< o!$ect of !ase class Such o(6ects !ould (ehave 6ust as they !ould i' CountDn didnHt e4ist. Note also that inheritance doesnHt !or in reverse. The (ase class and its o(6ects donHt no! anything a(out any classes derived 'rom the (ase class. +n this e4am"le that means that o(6ects o' class Counter0 such as c; de'ined here0 canHt use the o"erator::(* 'unction in CountDn. +' you !ant a counter that you can decrement0 it must (e o' class CountDn0 not Counter.

Other %erms
+n some languages the (ase class is called the superclass and the derived class is called the subclass. Some !riters also re'er to the (ase class as the parent and the derived class as the child.

Derived Class Constr$ctors


ThereHs a "otential glitch in the C%.NT3N "rogram. #hat ha""ens i' !e !ant to initialiPe a CountDn o(6ect to a valueW Can the one:argument constructor in Counter (e usedW The ans!er is no. 5s !e sa! in C%.NT3N0 the com"iler !ill su(stitute a no:argument constructor 'rom the (ase class0 (ut it dra!s the line at more com"le4 constructors. To ma e such a de'inition !or !e must !rite a ne! set o' constructors 'or the derived class. This is sho!n in the C%.NT3N; "rogram. 22 counten2.cpp

22 constructors in derived class #include <iostream> usin+ namespace std; 2222222222222222222222222222222222222222222222222222222222222222 class 4ounter { protected7 22;D(P7 not private unsi+ned int count; 22count pu!lic7 4ounter() 7 count() 22constructor# no ar+s { 4ounter(int c) 7 count(c) 22constructor# one ar+ { unsi+ned int +et&count() const 22return count { return count; 4ounter increment() 22incr count { return 4ounter(**count); ; 2222222222222222222222222222222222222222222222222222222222222222 class 4ountLn 7 pu!lic 4ounter { pu!lic7 4ountLn() 7 4ounter() 22constructor# no ar+s { 4ountLn(int c) 7 4ounter(c) 22constructor# 1 ar+ { 4ountLn decrement() 22decr count (prefi") K return CountDn(::count*L M ML //////////////////////////////////////////////////////////////// int main(* K CountDn c=L //class CountDn CountDn c;(=FF*L cout UU QYnc=[R UU c=.get9count(*L cout UU QYnc;[R UU c;.get9count(*L //dis"lay //dis"lay //increment c=

c=.increment(*L c=.increment(*L c=.increment(*L cout UU QYnc=[R UU c=.get9count(*L //dis"lay it c;.decrement(*Lc;.decrement(*L cout UU QYnc;[R UU c;.get9count(*L

//decrement c; //dis"lay it

CountDn cG [ c;.decrement(*L //create cG 'rom c; cout UU QYncG[R UU cG.get9count(*L //dis"lay cG cout UU endlL return FL M This "rogram uses t!o ne! constructors in the CountDn class. -ere is the one:argument constructor: CountDn(* : Counter(* KM This constructor has an un'amiliar 'eature: the 'unction name 'ollo!ing the colon. This construction causes the CountDn(* constructor to call the Counter(* constructor in the (ase class. +n main(*0 !hen !e say CountDn c=L the com"iler !ill create an o(6ect o' ty"e CountDn and then call the CountDn constructor to initialiPe it. This constructor !ill in turn call the Counter constructor0 !hich carries out the !or . The CountDn(* constructor could

add additional statements o' its o!n0 (ut in this case it doesnHt need to0 so the 'unction (ody (et!een the (races is em"ty. Calling a constructor 'rom the initialiPation list may seem odd0 (ut it ma es sense. Nou !ant to initialiPe any varia(les0 !hether theyHre in the derived class or the (ase class0 (e'ore any statements in either the derived or (ase: class constructors are e4ecuted. 1y calling the (ase:class constructor (e'ore the derived:class constructor starts to e4ecute0 !e accom"lish this. The statement CountDn c;(=FF*L in main(* uses the one:argument constructor in CountDn. This constructor also calls the corres"onding one: argument constructor in the (ase class: CountDn(int c* : Counter(c* WWWW argument c is "assed to Counter KM This construction causes the argument c to (e "assed 'rom CountDn(* to Counter(*0 !here it is used to initialiPe the o(6ect. +n main(*0 a'ter initialiPing the c= and c; o(6ects0 !e increment one and decrement the other and then "rint the results. The one:argument constructor is also used in an assignment statement. CountDn cG [ c;.decrement(*L

Overriding Mem/er F$nctions


Nou can use mem(er 'unctions in a derived class that overrideSthat is0 have the same name asSthose in the (ase class. Nou might !ant to do this so that calls in your "rogram !or the same !ay 'or o(6ects o' (oth (ase and derived classes. -ereHs an e4am"le (ased on the ST5K585N "rogram 'rom Cha"ter D0 Q5rrays and Strings.R That "rogram modeled a stac 0 a sim"le data storage device. +t allo!ed you to "ush integers onto the stac and "o" them o''. -o!ever0 ST5K585N had a "otential 'la!. +' you tried to "ush too many items onto the stac 0 the "rogram might (om(0 since data !ould (e "laced in memory (eyond the end o' the stab array. %r i' you tried to "o" too many items0 the results !ould (e meaningless0 since you !ould (e reading data 'rom memory locations outside the array. To cure these de'ects !eHve created a ne! class0 Stac ;0 derived 'rom Stac . %(6ects o' Stac ; (ehave in e4actly the same !ay as those o' Stac 0 e4ce"t that you !ill (e !arned i' you attem"t to "ush too many items on the stac 0 or i' you try to "o" an item 'rom an em"ty stac . -ereHs the listing 'or ST5K3N: // sta en.c"" // overloading 'unctions in (ase and derived classes Tinclude UiostreamV using names"ace stdL Tinclude U"rocess.hV //'or e4it(* //////////////////////////////////////////////////////////////// class Stac K "rotected: //N%T3: canHt (e "rivate enum K &5A [ G ML //siPe o' stac array int sta&5AbL //stac : array o' integers int to"L //inde4 to to" o' stac "u(lic: Stac (* //constructor K to" [ :=L M void "ush(int var* //"ut num(er on stac K sta++to"b [ varL M int "o"(* //ta e num(er o'' stac K return stato"::bL M ML //////////////////////////////////////////////////////////////// class Stac ; : "u(lic Stac K "u(lic:

void "ush(int var* //"ut num(er on stac K i'(to" V[ &5A:=* //error i' stac 'ull K cout UU QYn3rror: stac is 'ullRL e4it(=*L M Stac ::"ush(var*L //call "ush(* in Stac class M int "o"(* //ta e num(er o'' stac K i'(to" U F* //error i' stac em"ty K cout UU QYn3rror: stac is em"tyYnRL e4it(=*L M return Stac ::"o"(*L //call "o"(* in Stac class M ML //////////////////////////////////////////////////////////////// int main(* K Stac ; s=L s=."ush(==*L s=."ush(;;*L s=."ush(GG*L //"ush some values onto stac

cout UU endl UU s=."o"(*L cout UU endl UU s=."o"(*L cout UU endl UU s=."o"(*L cout UU endl UU s=."o"(*L cout UU endlL return FL M

//"o" some values 'rom stac //oo"s0 "o""ed one too many...

+ntroduction to #indo!s $rogramming (5s"ects o' #indo!s* 1oth #indo!s B^ and #indo!s NT are G;:(it "reem"tive multitas ing and multithreading gra"hical o"erating systems. #indo!s "ossesses a gra"hical user inter'ace (2.+*0 sometimes also called a Ivisual inter'aceI or Igra"hical !indo!ing environment.I The conce"ts (ehind the 2.+ date 'rom the mid:=BDFs !ith the !or done at the Aero4 $58C 'or machines such as the 5lto and the Star and 'or environments such as SmallTal . This !or !as later (rought into the mainstream and "o"ulariPed (y 5""le Com"uter and &icroso't. 5lthough some!hat controversial 'or a !hile0 it is no! )uite o(vious that the 2.+ is (in the !ords o' &icroso't7s Charles Simonyi* the single most im"ortant Igrand consensusI o' the "ersonal:com"uter industry. 3vent Driven $rogramming Vs Traditional $rogramming 5ll 2.+s ma e use o' gra"hics on a (itma""ed video dis"lay. 2ra"hics "rovides (etter utiliPation o' screen real estate0 a visually rich environment 'or conveying in'ormation0 and the "ossi(ility o' a #NS+#N2 (!hat you see is !hat you get* video dis"lay o' gra"hics and 'ormatted te4t "re"ared 'or a "rinted document. +n earlier days0 the video dis"lay !as used solely to echo te4t that the user ty"ed using the ey(oard. +n a gra"hical user inter'ace0 the video dis"lay itsel' (ecomes a source o' user in"ut. The video dis"lay sho!s various gra"hical o(6ects in the 'orm o' icons and in"ut devices such as (uttons and scroll (ars. .sing the ey(oard (or0 more directly0 a "ointing device such as a mouse*0 the user can directly mani"ulate these o(6ects on the screen. 2ra"hics o(6ects can (e dragged0 (uttons can (e "ushed0 and scroll (ars can (e scrolled. The interaction (et!een the user and a "rogram thus (ecomes more intimate. 8ather than the one:!ay cycle o' in'ormation 'rom the ey(oard to the "rogram to the video dis"lay0 the user directly interacts !ith the o(6ects on the dis"lay. %very user interaction (#e-uest! with the )pplication triggers an %vent and the )pplication handles it.

5n o"erating system cannot im"lement multitas ing !ithout doing something a(out memory management. 5s ne! "rograms are started u" and old ones terminate0 memory can (ecome 'ragmented. The system must (e a(le to consolidate 'ree memory s"ace. This re)uires the system to move (loc s o' code and data in memory. 3ven #indo!s =.F0 running on an ^F^^ micro"rocessor0 !as a(le to "er'orm this ty"e o' memory management. .nder real:mode restrictions0 this a(ility can only (e regarded as an astonishing 'eat o' so't!are engineering. +n #indo!s =.F0 the C>F: ilo(yte (K1* memory limit o' the $C7s architecture !as e''ectively stretched !ithout re)uiring any additional memory. 1ut &icroso't didn7t sto" there: #indo!s ;.F gave the #indo!s a""lications access to e4"anded memory (3&S*0 and #indo!s G.F ran in "rotected mode to give #indo!s a""lications access to u" to =C &1 o' e4tended memory. #indo!s NT and #indo!s B^ (lo! a!ay these old limits (y (eing 'ull:'ledged G;:(it o"erating systems !ith 'lat memory s"ace. $rograms running in #indo!s can share routines that are located in other 'iles called Idynamic:lin li(raries.I #indo!s includes a mechanism to lin the "rogram !ith the routines in the dynamic:lin li(raries at run time. #indo!s itsel' is (asically a set o' dynamic:lin li(raries. (rograms written for .indows do not directly access the hardware of graphics display devices such as the screen and printer. +nstead0 #indo!s includes a gra"hics "rogramming language (called the 2ra"hics Device +nter'ace0 or 2D+* that allo!s the easy dis"lay o' gra"hics and 'ormatted te4t. #indo!s virtualiPes dis"lay hard!are. > -rogram written for Windows will r$n with an( video /oard or an( -rinter for which a Windows device driver is availa/le. The "rogram does not need to determine !hat ty"e o' device is attached to the system.

D(namic &in+ing
Central to the !or ings o' #indo!s is a conce"t no!n as Idynamic lin ing.I #indo!s "rovides a !ealth o' 'unction calls that an a""lication can ta e advantage o'0 mostly to im"lement its user inter'ace and dis"lay te4t and gra"hics on the video dis"lay. These 'unctions are im"lemented in dynamic:lin li(raries0 or D,,s. These are 'iles !ith the e4tension .D,, or sometimes .3A30 and they are mostly located in the Y#+ND%#SYSNST3& su(directory under #indo!s B^ and the Y#+NNTYSNST3& and Y#+NNTYSNST3&G; su(directories under #indo!s NT. +n the early days0 the great (ul o' #indo!s !as im"lemented in 6ust three dynamic:lin li(raries. These re"resented the three main su(systems o' #indo!s0 !hich !ere re'erred to as /ernel, 0ser, and 1"I. #hile the num(er o' su(systems has "roli'erated in recent versions o' #indo!s0 most 'unction calls that a ty"ical #indo!s "rogram ma es !ill still 'all in one o' these three modules. Kernel (!hich is currently im"lemented (y the =C:(it K8N,G^C.3A3 and the G;:(it K38N3,G;.D,,* handles all the stu'' that an o"erating system ernel traditionally handlesSmemory management0 'ile +/%0 and tas ing. .ser (im"lemented in the =C:(it .S38.3A3 and the G;:(it .S38G;.D,,* re'ers to the user inter'ace0 and im"lements all the !indo!ing logic. 2D+ (im"lemented in the =C:(it 2D+.3A3 and the G;:(it 2D+G;.D,,* is the 2ra"hics Device +nter'ace0 !hich allo!s a "rogram to dis"lay te4t and gra"hics on the screen and "rinter. +n your #indo!s "rogram0 you use the #indo!s 'unction calls in generally the same !ay you use C li(rary 'unctions such as strlen. The "rimary di''erence is that the machine code for $ librar# functions is lin%ed into #our program code whereas the code for &indows functions is located outside of #our program in the '((s . #hen you run a #indo!s "rogram0 it inter'aces to #indo!s through a "rocess called Idynamic lin ing.I 5 #indo!s .3A3 'ile contains re'erences to the various dynamic:lin li(raries it uses and the 'unctions therein. #hen a #indo!s "rogram is loaded into memory0 the calls in the "rogram are resolved to "oint to the entries o' the D,, 'unctions0 !hich are also loaded into memory i' not already there. #hen you lin a #indo!s "rogram to "roduce an e4ecuta(le 'ile0 you must lin !ith s"ecial Iim"ort li(rariesI "rovided !ith your "rogramming environment. These im"ort li(raries contain the dynamic:lin li(rary names and re'erence in'ormation 'or all the #indo!s 'unction calls. The lin er uses this in'ormation to construct the ta(le in the .3A3 'ile that #indo!s uses to resolve calls to #indo!s 'unctions !hen loading the "rogram

>P#s and Memor( Models

To a "rogrammer0 an o"erating system is de'ined (y its 5$+. )n )(I encompasses all the function calls that an application program can make of an operating system, as well as definitions of associated data types and structures. The (iggest change in the #indo!s 5$+ and its synta4 came a(out during the s!itch 'rom a =C:(it architecture to a G;:(it architecture. Versions =.F through G.= o' #indo!s used the so:called segmented memory mode o' the =C:(it +ntel ^F^C0 ^F^^0 and ;^C micro"rocessors0 a mode that !as also su""orted 'or com"ati(ility "ur"oses in the G;:(it +ntel micro"rocessors (eginning !ith the G^C. The micro"rocessor register siPe in this mode !as =C (its0 and hence the C int data ty"e !as also =C (its !ide. +n the segmented memory model0 memory addresses !ere 'ormed 'rom t!o com"onentsSa =C:(it segment "ointer and a =C:(it offset "ointer. /rom the "rogrammer7s "ers"ective0 this !as )uite messy and involved di''erentiating (et!een long or far "ointers (!hich involved (oth a segment address and an o''set address* and short or near "ointers (!hich involved an o''set address !ith an assumed segment address*. 1eginning in #indo!s NT and #indo!s B?0 #indo!s su""orted a G;:(it 'lat memory model using the G;:(it modes o' the +ntel G^C0 >^C0 and $entium "rocessors. The C int data ty"e !as "romoted to a G;:(it value. $rograms !ritten 'or G;:(it versions o' #indo!s use sim"le G;:(it "ointer values that address a 'lat linear address s"ace. The 5$+ 'or the =C:(it versions o' #indo!s (#indo!s =.F through #indo!s G.=* is no! no!n as #in=C. The 5$+ 'or the G;:(it versions o' #indo!s (#indo!s B?0 #indo!s B^0 and all versions o' #indo!s NT* is no! no!n as #inG;. &any 'unction calls remained the same in the transition 'rom #in=C to #inG;0 (ut some needed to (e enhanced. /or e4am"le0 gra"hics coordinate "oints changed 'rom =C:(it values in #in=C to G;:(it values in #inG;. 5lso0 some #in=C 'unction calls returned a t!o:dimensional coordinate "oint "ac ed in a G;:(it integer. This !as not "ossi(le in #inG;0 so ne! 'unction calls !ere added that !or ed in a di''erent !ay. 5ll G;:(it versions o' #indo!s su""ort (oth the #in=C 5$+ to ensure com"ati(ility !ith old a""lications and the #inG; 5$+ to run ne! a""lications.

%hreading ,ingle %hreading


+' a 5""lication is ,ingle %hreaded0 then all methods o' that 5""lcation !ill e4ecute on the main thread. There is one main thread 'or each a""lication. #hich is the de'ault (ehavior.

M$lti %hreading
+' the 5""lication is &ulti Threaded 0 then there could me &ulti"le %"erations ha""ening at the same "oint o' time.5n a""lication gets a minimum o' one thread i.e. Thread &5+N. %ther threads are started 'rom the &ain .

,(nchroniLation
5s soon as there is more than one thread running in the system0 a !hole ne! category o' "ro(lems may "o" u" that !ere not "resent in a single:threaded environment. The )uestion that it all comes do!n to is0 I+s there data that is visi(le to more than one threadWI +' the ans!er to this )uestion is INo0I things do not (ecome too much more com"licated than in the single:threaded version. 5ll one needs to do in this case is to dis"atch the threads0 !ait until they return0 and (i' a""lica(le* gather the results. +' the ans!er to the a(ove )uestion is INes0I ho!ever0 more !or needs to (e done. #e 'irst need to determine !hat the critical data is and ho! to "ut the access to it into an order that does not a''ect the correct e4ecution o' the "rogram. 5'ter that0 !e need to ensure that the "rotection mechanisms do not a''ect the liveness o' the a""lication. ,et us (e a little more clear a(out !hat Icon'use one threadI means. 5 ty"ical e4am"le 'or this scenario is the 'ollo!ing: T!o threads have access to the same varia(le 4 and (oth e4ecute this code se)uence at some "oint: " ' "*1/ %n most "rocessors0 this addition is not an atomic instruction0 that is0 the com"iler !ould generate more than one instruction o' machine code 'or that source statement. /or e4am"le0 it might do something li e this:

mov a"#Q"R add a"#1/ mov Q"R#a" #e !ould e4"ect that !hen (oth threads e4ecute this se)uence0 the value o' 4 a'ter (oth threads are done is ;F higher than it !as (e'ore the 'irst thread e4ecuted it. -o!ever0 i' one thread gets "reem"ted (y the o"erating system a'ter having e4ecuted the 'irst mov instruction0 the other thread !ill "ic u" the same value o' 4 as the 'irst thread0 (oth !ill add =F onto that value0 and !hen the threads store the result o' the addition (ac into 40 one !ill over!rite the u"dated 4 varia(le !ith the same value. Thus0 a'ter (oth threads have e4ecuted the se)uence0 4 !ill (e only =F higher than it !as (e'oreJ #e need to esta(lish some mechanism to shield 4 'rom (eing accessed concurrently 'rom the t!o threads. Shared data con'licts may mani'est themselves in a lot o' !ays0 not only the one mentioned in the "revious "aragra"h. /or e4am"le0 one thread might "ic u" the value o' a shared varia(le and !or on it0 assuming that it does not change0 (ut another thread might change the varia(le !hile the 'irst thread !or s on it.

Windows Programming with C 3,DW5


There are three "rere)uisites . /irst0 you should (e familiar with Windows UH 'rom a user7s "ers"ective. Nou cannot ho"e to !rite a""lications 'or #indo!s !ithout understanding its user inter'ace. /or this reason0 + suggest that you do your "rogram develo"ment (as !ell as other !or * on a #indo!s:(ased machine using #indo!s a""lications. Second. (o$ sho$ld +now C 3iAe one should have gone through the (asics o' C given earlier to you* A +' you don7t no! C0 #indo!s "rogramming is "ro(a(ly not a good "lace to start. Nou should have a good !or ing 'amiliarity !ith the language0 "articularly !ith C structures and "ointers. Some no!ledge o' the standard C run:time li(rary is hel"'ul (ut not re)uired. Third0 you should have installed on your machine a G;:(it C com"iler and develo"ment environment suita(le 'or doing #indo!s "rogramming. +n this (oo 0 +7ll (e assuming that you7re using &icroso't Visual C++ C.F. That7s itA #Xm not going to ass$me that (o$ have an( e=-erience at all -rogramming for a gra-hical $ser interface s$ch as WindowsA

> ,im-le window 3,DW5


-ere7s the "rogram: 2399999999999999999999999999999999999999999999999999999999999999 ?elloKs+.c 99 Lispla%s "?ello# 8indo,s STO" in a messa+e !o" (c) 4harles Cet@old# 1SST 9999999999999999999999999999999999999999999999999999999999999932 #include <,indo,s.h> int 8=;FC= 8inKain (?=;:(F;4P h=nstance# ?=;:(F;4P hCrev=nstance# C:(U s@4mdLine# int i4md:ho,) { Kessa+eIo" (;VLL# (PW( ("?ello# 8indo,s STO")# (PW( ("?elloKs+")# /) ; return / ; 1e'ore + (egin dissecting this "rogram0 let7s go through the mechanics o' creating a "rogram in the Visual C++ Develo"er Studio. To (egin0 select Ne! 'rom the /ile menu. +n the Ne! dialog (o40 "ic the $ro6ects ta(. Select #inG; 5""lication. +n the ,ocation 'ield0 select a su(directory. +n the $ro6ect Name 'ield0 ty"e the name o' the "ro6ect0 !hich in this case is -ello&sg. This !ill (e a su(directory o' the directory indicated in the ,ocation 'ield. The Create Ne! #or s"ace (utton should (e chec ed. The $lat'orms section should indicate #inG;. Choose %K.

5 dialog (o4 la(eled #inG; 5""lication : Ste" = %' = !ill a""ear. +ndicate that you !ant to create an 3m"ty $ro6ect0 and "ress the /inish (utton. Select Ne! 'rom the /ile menu again. +n the Ne! dialog (o40 "ic the /iles ta(. Select C++ Source /ile. The 5dd To $ro6ect (o4 should (e chec ed0 and -ello&sg should (e indicated. Ty"e -ello&sg.c in the /ile Name 'ield. Choose %K. No! you can ty"e in the -3,,%&S2.C 'ile sho!n a(ove. %r you can select the +nsert menu and the /ile 5s Te4t o"tion to co"y the contents o' -3,,%&S2.C 'rom the 'ile on this (oo 7s com"anion CD:8%&. Structurally0 -3,,%&S2.C is identical to the K&8 Ihello0 !orldI "rogram. The header 'ile STD+%.- has (een re"laced !ith #+ND%#S.-0 the entry "oint main has (een re"laced !ith &inMain0 and the C run:time li(rary 'unction printf has (een re"laced !ith the #indo!s 5$+ 'unction Message)ox. -o!ever0 there is much in the "rogram that is ne!0 including several strange:loo ing u""ercase identi'iers. ,et7s start at the to".

%he 'eader Files


-3,,%&S2.C (egins !ith a "re"rocessor directive that you7ll 'ind at the to" o' virtually every #indo!s "rogram !ritten in C: #include <,indo,s.h> #+ND%#S.- is a master include 'ile that includes other #indo!s header 'iles0 some o' !hich also include other header 'iles. The most im"ortant and most (asic o' these header 'iles are: &*+',!.- 1asic ty"e de'initions. &*++..- Ty"e de'initions 'or .nicode su""ort. &*+)/0,.- Kernel 'unctions. &*+10,".- .ser inter'ace 'unctions. &*+2'*.- 2ra"hics device inter'ace 'unctions. These header 'iles de'ine all the #indo!s data ty"es0 'unction calls0 data structures0 and constant identi'iers. They are an im"ortant "art o' #indo!s documentation. Nou might 'ind it convenient to use the /ind +n /iles o"tion 'rom the 3dit menu in the Visual C++ Develo"er Studio to search through these header 'iles. Nou can also o"en the header 'iles in the Develo"er Studio and e4amine them directly.

Program 0ntr( Point


<ust as the entry "oint to a C "rogram is the 'unction main0 the entry "oint to a #indo!s "rogram is &inMain0 !hich al!ays a""ears li e this: int 8=;FC= 8inKain (?=;:(F;4P h=nstance# ?=;:(F;4P hCrev=nstance# C:(U s@4mdLine# int i4md:ho,) This entry "oint is documented in 34latform 0'531ser *nterface 0ervices3&indowing3&indows3&indow "eference3&indow !unctions. +t is declared in #+N15S3.- li e so (line (rea s and all*: int 8=;FC= 8inKain( ?=;:(F;4P h=nstance# ?=;:(F;4P hCrev=nstance# LC:(U lp4mdLine# int n:ho,4md ); Nou7ll notice +7ve made a cou"le o' minor changes in -3,,%&S2.C. The third "arameter is de'ined as an ,$ST8 in #+N15S3.-0 and +7ve made it a $ST8. These t!o data ty"es are (oth de'ined in #+NNT.- as "ointers to character strings. The ,$ "re'i4 stands 'or Ilong "ointerI and is an arti'act o' =C:(it #indo!s. +7ve also changed t!o o' the "arameter names 'rom the &inMain declarationL many #indo!s "rograms use a system called I'$ngarian notationI 'or naming varia(les. %his s(stem involves -refacing the varia/le name with a short -refi= that indicates the varia/leXs data t(-e. +7ll discuss this conce"t later. /or no!0 6ust ee" in mind that the "re'i4 i stands 'or int and sz stands 'or Istring terminated !ith a Pero.I

The &inMain 'unction is declared as returning an int. The #+N5$+ identi'ier is de'ined in #+ND3/.- !ith the statement: #define 8=;FC= &&stdcall This statement s"eci'ies a calling convention that involves ho! machine code is generated to "lace 'unction call arguments on the stac . &ost #indo!s 'unction calls are declared as #+N5$+. The 'irst "arameter to &inMain is something called an Iinstance handle.I +n #indo!s "rogramming0 a handle is sim"ly a num(er that an a""lication uses to identi'y something. +n this case0 the handle uni)uely identi'ies the "rogram. +t is re)uired as an argument to some other #indo!s 'unction calls. +n early versions o' #indo!s0 !hen you ran the same "rogram concurrently more than once0 you created multiple instances o' that "rogram. 5ll instances o' the same a""lication shared code and read:only memory (usually resources such as menu and dialog (o4 tem"lates*. 5 "rogram could determine i' other instances o' itsel' !ere running (y chec ing the h4rev*nstance "arameter. +t could then s i" certain chores and move some data 'rom the "revious instance into its o!n data area. +n the G;:(it versions o' #indo!s0 this conce"t has (een a(andoned. The second "arameter to &inMain is al!ays N.,, (de'ined as F*. The third "arameter to &inMain is the command line used to run the "rogram. Some #indo!s a""lications use this to load a 'ile into memory !hen the "rogram is started. The 'ourth "arameter to &inMain indicates ho! the "rogram should (e initially dis"layedSeither normally or ma4imiPed to 'ill the !indo!0 or minimiPed to (e dis"layed in the tas list (ar. #e7ll see ho! this "arameter used some other time.

%he 2essage&ox F$nction


The Message)ox 'unction is designed to dis"lay short messages. The little !indo! that Message)ox dis"lays is actually considered to (e a dialog (o40 although not one !ith a lot o' versatility. The 'irst argument to Message)ox is normally a !indo! handle. The second argument is the te4t string that a""ears in the (ody o' the message (o40 and the third argument is the te4t string that a""ears in the ca"tion (ar o' the message (o4. +n -3,,&S2.C0 each o' these te4t strings is enclosed in a T3AT macro. Nou don7t normally have to enclose all character strings in the T3AT macro0 (ut it7s a good idea i' you !ant to (e ready to convert your "rograms to the .nicode (This !ill (e discussed later*character set. The 'ourth argument to Message)ox can (e a com(ination o' constants (eginning !ith the "re'i4 &19 that are de'ined in #+N.S38.-. Nou can "ic one constant 'rom the 'irst set to indicate !hat (uttons you !ish to a""ear in the dialog (o4: #define KI&DX /"////////L #define KI&DX4F;4PL /"///////1L #define KI&FIDU(UP(UG=Y;DUP /"///////2L #define KI&GP:;D4F;4PL /"///////-L #define KI&GP:;D /"///////HL #define KI&UP(UG4F;4PL /"///////.L #hen you set the 'ourth argument to F in -3,,%&S20 only the %K (utton a""ears. Nou can use the C %8 (e* o"erator to com(ine one o' the constants sho!n a(ove !ith a constant that indicates !hich o' the (uttons is the de'ault: #define KI&LP6IV((D;1 /"////////L #define KI&LP6IV((D;2 /"/////1//L #define KI&LP6IV((D;/"/////2//L #define KI&LP6IV((D;H /"/////-//L Nou can also use a constant that indicates the a""earance o' an icon in the message (o4: #define KI&=4D;?F;L /"//////1/L #define KI&=4D;JVP:(=D; /"//////2/L #define KI&=4D;PW4LFKF(=D; /"//////-/L #define KI&=4D;F:(PU=:X /"//////H/L Some o' these icons have alternate names: #define KI&=4D;8FU;=;Y KI&=4D;PW4LFKF(=D;

#define KI&=4D;PUUDU KI&=4D;?F;L #define KI&=4D;=;6DUKF(=D; KI&=4D;F:(PU=:X #define KI&=4D;:(DC KI&=4D;?F;L There are a 'e! other &19 constants0 (ut you can consult the header 'ile yoursel' or the documentation in 34latform 0'531ser *nterface 0ervices3&indowing3'ialog )oxes3'ialog )ox "eference3'ialog )ox !unctions . +n this "rogram0 the Message)ox 'unction returns the value =0 (ut it7s more "ro"er to say that it returns +D%K0 !hich is de'ined in #+N.S38.- as e)ualing =. De"ending on the other (uttons "resent in the message (o40 the Message)ox 'unction can also return +DN3S0 +DN%0 +DC5NC3,0 +D51%8T0 +D83T8N0 or +D+2N%83. +s this little #indo!s "rogram really the e)uivalent o' the K&8 Ihello0 !orldI "rogramW #ell0 you might thin not (ecause the Message)ox 'unction doesn7t really have all the "otential 'ormatting "o!er o' the printf 'unction in Ihello0 !orld.I 1ut !e7ll see in the ne4t cha"ter ho! to !rite a version o' Message)ox that does printf:li e 'ormatting.

Com-ile. &in+. and R$n


#hen you7re ready to com"ile -3,,%&S20 you can select 1uild -ellomsg.e4e 'rom the 1uild menu0 or "ress /D0 or select the 1uild icon 'rom the 1uild tool(ar. (The a""earance o' this icon is sho!n in the 1uild menu. +' the 1uild tool(ar is not currently dis"layed0 you can choose CustomiPe 'rom the Tools menu and select the Tool(ars ta(. $ic 1uild or 1uild &ini1ar.* 5lternatively0 you can select 34ecute -ellomsg.e4e 'rom the 1uild menu0 or "ress Ctrl+/?0 or clic the 34ecute $rogram icon (!hich loo s li e a red e4clamation "oint* 'rom the 1uild tool(ar. Nou7ll get a message (o4 as ing you i' you !ant to (uild the "rogram. 5s normal0 during the com"ile stage0 the com"iler generates an .%1< (o(6ect* 'ile 'rom the C source code 'ile. During the lin stage0 the lin er com(ines the .%1< 'ile !ith .,+1 (li(rary* 'iles to create the .3A3 (e4ecuta(le* 'ile. Nou can see a list o' these li(rary 'iles (y selecting Settings 'rom the $ro6ect ta( and clic ing the ,in ta(. +n "articular0 you7ll notice K38N3,G;.,+10 .S38G;.,+10 and 2D+G;.,+1. These are Iim"ort li(rariesI 'or the three ma6or #indo!s su(systems. They contain the dynamic:lin li(rary names and re'erence in'ormation that is (ound into the .3A3 'ile. #indo!s uses this in'ormation to resolve calls 'rom the "rogram to 'unctions in the K38N3,G;.D,,0 .S38G;.D,,0 and 2D+G;.D,, dynamic:lin li(raries. +n the Visual C++ Develo"er Studio0 you can com"ile and lin the "rogram in di''erent con'igurations. 1y de'ault0 these are called De(ug and 8elease. The e4ecuta(le 'iles are stored in su(directories o' these names. +n the De(ug con'iguration0 in'ormation is added to the .3A3 'ile that assists in de(ugging the "rogram and in tracing through the "rogram source code. (Nou can tell the Develo"er Studio to generate ma e 'iles (y choosing %"tions 'rom the Tools menu and selecting the 1uild ta(. There7s a chec (o4 to chec .* Nou7ll need to run VCV58SG;.15T located in the 1+N su(directory o' the Develo"er Studio to set environment varia(les. To e4ecute the ma e 'ile 'rom the command line0 change to the -3,,%&S2 directory and e4ecute: ;KFXP 2f ?elloKs+.ma0 46Y'"?elloKs+ & 8in-2 Le!u+" or ;KFXP 2f ?elloKs+.ma0 46Y'"?elloKs+ & 8in-2 Uelease" Nou can then run the .3A3 'ile 'rom the command line (y ty"ing: LPIVY\?PLLDK:Y or UPLPF:P\?PLLDK:Y +n the $ro6ect Settings dialog (o40 a'ter selecting the C/C++ ta(0 in the $re"rocessor De'initions 'ield + have de'ined the identi'ier .N+C%D3. +7ll have much more to say a(out this ne4t

>n #ntrod$ction to *nicode


Very sim"ly0 .nicode is an e4tension o' 5SC++ character encoding. 8ather than the D (its used to re"resent each character in strict 5SC++0 or the ^ (its "er character that have (ecome common on com"uters0 *nicode $ses a f$ll ! /its for character encoding. This allo!s .nicode to re"resent all the letters0 ideogra"hs0 and other sym(ols used in all the !ritten languages o' the !orld that are li ely to (e used in com"uter communication. .nicode is intended

initially to su""lement 5SC++ and0 !ith any luc 0 eventually re"lace it. Considering that 5SC++ is one o' the most dominant standards in com"uting0 this is certainly a tall order. .nicode im"acts every "art o' the com"uter industry0 (ut "erha"s most "ro'oundly o"erating systems and "rogramming languages. +n this res"ect0 !e are almost hal'!ay there. #indo!s NT su""orts .nicode 'rom the ground u". (.n'ortunately0 #indo!s B^ includes only a small amount o' .nicode su""ort.* %he C -rogramming lang$age as formaliLed /( >),# inherentl( s$--orts *nicode thro$gh its s$--ort of wide characters. which #Xll disc$ss in detail /elowA

Wider Characters
)othing a/o$t *nicode or wide characters alters the meaning of the char data t(-e in C. The char continues to indicate = (yte o' storage0 and sizeof 6char) continues to return =. +n theory0 a (yte in C can (e greater than ^ (its0 (ut 'or most o' us0 a (yte (and hence a char* is ^ (its !ide. #ide characters in C are (ased on the wchar_t data ty"e0 !hich is de'ined in several header 'iles0 including #C-58.-0 li e so: t%pedef unsi+ned short ,char&t ; Thus0 the wchar_t data ty"e is the same as an unsigned short integer: =C (its !ide. To de'ine a varia(le containing a single !ide character0 use the 'ollo!ing statement: ,char&t c ' ZF[ ; The varia(le c is the t!o:(yte value F4FF>=0 !hich is the .nicode re"resentation o' the letter 5. (-o!ever0 /eca$se #ntel micro-rocessors store m$lti/(te val$es with the least-significant /(tes first 0 the (ytes are actually stored in memory in the se)uence F4>=0 F4FF. Kee" this in mind i' you e4amine memory storage o' .nicode te4t.* Nou can also de'ine an initialiPed "ointer to a !ide:character string: ,char&t 3 p ' L"?elloO" ; )otice the ca-ital & 3for long5 immediatel( -receding the first K$otation mar+A %his indicates to the com-iler that the string is to /e stored with wide charactersTthat is. with ever( character occ$-(ing C /(tesA The "ointer varia(le p re)uires > (ytes o' storage0 as usual0 (ut the character string re)uires => (ytesS; (ytes 'or each character !ith ; (ytes o' Peros at the end. Similarly0 you can de'ine an array o' !ide characters this !ay: static ,char&t aQR ' L"?elloO" ; The string again re)uires => (ytes o' storage0 and sizeof 6a) !ill return =>. Nou can inde4 the a array to get at the individual characters. The value a789 is the !ide character Ee70 or F4FFC?. 5lthough it loo s more li e a ty"o than anything else0 that , "receding the 'irst )uotation mar is very im"ortant0 and there must not (e s"ace (et!een the t!o sym(ols. %nly !ith that , !ill the com"iler no! you !ant the string to (e stored !ith ; (ytes "er character. ,ater on0 !hen !e loo at !ide:character strings in "laces other than varia(le de'initions0 you7ll encounter the , "receding the 'irst )uotation mar again. /ortunately0 the C com"iler !ill o'ten give you a !arning or error message i' you 'orget to include the ,. Nou can also use the , "re'i4 in 'ront o' single character literals0 as sho!n here0 to indicate that they should (e inter"reted as !ide characters. ,char&t c ' L[F[ ; 1ut it7s usually not necessary. The C com"iler !ill Pero:e4tend the character any!ay.

Wide-Character &i/rar( F$nctions


#e all no! ho! to 'ind the length o' a string. /or e4am"le0 i' !e have de'ined a "ointer to a character string li e so:

char 3 pc ' "?elloO"; !e can call iLen+th ' strlen (pc); The varia(le i(ength !ill (e set e)ual to C0 the num(er o' characters in the string. 34cellentJ No! let7s try de'ining a "ointer to a string o' !ide characters: ,char&t 3 p, ' L"?elloO"; 5nd no! !e call strlen again: iLen+th ' strlen (p,); No! the trou(les (egin. /irst0 the C com"iler gives you a !arning message0 "ro(a(ly something along the lines o' Zfunction[ 7 incompati!le t%pes 9 from Zunsi+ned short 3[ to Zconst char 3[ +t7s telling you that the strlen 'unction is declared as acce"ting a "ointer to a char0 and it7s getting a "ointer to an unsigned short. Nou can still com"ile and run the "rogram0 (ut you7ll 'ind that i(ength is set to =. #hat ha""enedW The C characters o' the character string I-elloJI have the =C:(it values: /"//HT /"//M. /"//M4 /"//M4 /"//M6 /"//21 !hich are stored in memory (y +ntel "rocessors li e so: HT // M. // M4 // M4 // M6 // 21 // The strlen 'unction0 assuming that it7s attem"ting to 'ind the length o' a string o' characters0 counts the 'irst (yte as a character (ut then assumes that the second (yte is a Pero (yte denoting the end o' the string. This little e4ercise clearly illustrates the di''erences (et!een the C language itsel' and the run:time li(rary 'unctions. The com"iler inter"rets the string ,I-elloJI as a collection o' =C:(it short integers and stores them in the wchar_t array. The com"iler also handles any array inde4ing and the sizeof o"erator0 so these !or "ro"erly. 1ut run:time li(rary 'unctions such as strlen are added during lin time. These 'unctions e4"ect strings that com"rise single:(yte characters. #hen they are con'ronted !ith !ide:character strings0 they don7t "er'orm as !e7d li e. %h0 great0 you say. No! every C li(rary 'unction has to (e re!ritten to acce"t !ide characters. #ell0 not ever# C li(rary 'unction. %nly the ones that have string arguments. 5nd #ou don7t have to re!rite them. +t7s already (een done. The !ide:character version o' the strlen 'unction is called wcslen (I!ide:character string lengthI*0 and it7s declared (oth in ST8+N2.- (!here the declaration 'or strlen resides* and #C-58.-. The strlen 'unction is declared li e this: si@e&t &&cdecl strlen (const char 3) ; and the wcslen 'unction loo s li e this: si@e&t &&cdecl ,cslen (const ,char&t 3) ; So no! !e no! that !hen !e need to 'ind out the length o' a !ide:character string !e can call iLen+th ' ,cslen (p,) ; The 'unction returns C0 the num(er o' characters in the string. Kee" in mind that the character length o' a string does not change !hen you move to !ide charactersSonly the (yte length changes. 5ll your 'avorite C run:time li(rary 'unctions that ta e string arguments have !ide:character versions. /or e4am"le0 wprintf is the !ide:character version o' printf. These 'unctions are declared (oth in #C-58.- and in the header 'ile !here the normal 'unction is declared.

Maintaining a ,ingle ,o$rce


There are0 o' course0 certain disadvantages to using .nicode. /irst and 'oremost is that every string in your "rogram !ill occu"y t!ice as much s"ace. +n addition0 you7ll o(serve that the 'unctions in the !ide:character run:time li(rary are larger than the usual 'unctions. /or this reason0 you might !ant to create t!o versions o' your "rogramSone !ith 5SC++ strings and the other !ith .nicode strings. The (est solution !ould (e to maintain a single source code 'ile that you could com"ile 'or either 5SC++ or .nicode. That7s a (it o' a "ro(lem0 though0 (ecause the run:time li(rary 'unctions have di''erent names0 you7re de'ining characters di''erently0 and then there7s that nuisance o' "receding the string literals !ith an ,. %ne ans!er is to use the TC-58.- header 'ile included !ith &icroso't Visual C++. This header 'ile is not "art o' the 5NS+ C standard0 so every 'unction and macro de'inition de'ined therein is "receded (y an underscore. TC-58.- "rovides a set o' alternative names 'or the normal run:time li(rary 'unctions re)uiring string "arameters ('or e4am"le0 _tprintf and _tcslen*. These are sometimes re'erred to as IgenericI 'unction names (ecause they can re'er to either the .nicode or non:.nicode versions o' the 'unctions. +' an identi'ier named 9.N+C%D3 is de'ined and the TC-58.- header 'ile is included in your "rogram0 _tcslen is de'ined to (e wcslen:

#define &tcslen ,cslen +' .N+C%D3 isn7t de'ined0 _tcslen is de'ined to (e strlen: #define &tcslen strlen 5nd so on. TC-58.- also solves the "ro(lem o' the t!o character data ty"es !ith a ne! data ty"e named TC-58. +' the 9.N+C%D3 identi'ier is de'ined0 TC-58 is wchar_t: t%pedef ,char&t (4?FU ; %ther!ise0 TC-58 is sim"ly a char: t%pedef char (4?FU ; No! it7s time to address that stic y , "ro(lem !ith the string literals. +' the 9.N+C%D3 identi'ier is de'ined0 a macro called 99T is de'ined li e this: #define &&((") L##" This is 'airly o(scure synta40 (ut it7s in the 5NS+ C standard 'or the C "re"rocessor. That "air o' num(er signs is called a Ito en "aste0I and it causes the letter , to (e a""ended to the macro "arameter. Thus0 i' the macro "arameter is I-elloJI0 then (::x is ,I-elloJI. +' the 9.N+C%D3 identi'ier is not de'ined0 the 99T macro is sim"ly de'ined in the 'ollo!ing !ay: #define &&((") " 8egardless0 t!o other macros are de'ined to (e the same as 99T: #define &((") &&((") #define &(PW((") &&((") #hich one you use 'or your #inG; console "rograms de"ends on ho! concise or ver(ose you7d li e to (e. 1asically0 you must de'ine your string literals inside the 9T or 9T3AT macro in the 'ollo!ing !ay: &(PW( ("?elloO") Doing so causes the string to (e inter"reted as com"osed o' !ide characters i' the 9.N+C%D3 identi'ier is de'ined and as ^:(it characters i' not.

Wide Characters and Windows


#indo!s NT su""orts .nicode 'rom the ground u". #hat this means is that #indo!s NT internally uses character strings com"osed o' =C:(it characters. Since much o' the rest o' the !orld doesn7t use =C:(it character strings yet0 #indo!s NT must o'ten convert character strings on the !ay into the o"erating system or on the !ay out. #indo!s NT can run "rograms !ritten 'or 5SC++0 'or .nicode0 or 'or a mi4 o' 5SC++ and .nicode. That is0 #indo!s NT su""orts di''erent 5$+ 'unction calls that acce"t ^:(it or =C:(it character strings. (#e7ll see ho! this !or s shortly.* #indo!s B^ has much less su""ort o' .nicode than #indo!s NT does. %nly a 'e! #indo!s B^ 'unction calls su""ort !ide:character strings. (These 'unctions are listed in &icroso't Kno!ledge 1ase article @=;?CD=L they include Message)ox.* +' you7re going to distri(ute only one .3A3 'ile that must run under (oth #indo!s NT and #indo!s B^0 it shouldn7t use .nicode or else it !on7t run under #indo!s B^L in "articular0 the "rogram shouldn7t call the .nicode versions o' the #indo!s 'unction calls. -o!ever0 so that you can (e in a (etter "osition to distri(ute a .nicode version o' your "rogram sometime in the 'uture0 you should "ro(a(ly attem"t to have a single source that can (e com"iled 'or either 5SC++ or .nicode. That7s ho! all the "rograms in the (oo are !ritten.

Windows 'eader File %(-es


5s you sa! earlier0 a #indo!s "rogram includes the header 'ile #+ND%#S.-. This 'ile includes a num(er o' other header 'iles0 including #+ND3/.-0 !hich has many o' the (asic ty"e de'initions used in #indo!s and !hich itsel' includes #+NNT.-. #+NNT.- handles the (asic .nicode su""ort. #+NNT.- (egins (y including the C header 'ile CTN$3.-0 !hich is one o' many C header 'iles that have a de'inition o' wchar_t. #+NNT.- de'ines ne! data ty"es named C-58 and #C-58: t%pedef char 4?FU ; t%pedef ,char&t 84?FU ; 22 ,c C-58 and #C-58 are the data ty"es recommended 'or your use in a #indo!s "rogram !hen you need to de'ine an ^:(it character or a =C:(it character. That comment 'ollo!ing the #C-58 de'inition is a suggestion 'or -ungarian notation: a varia(le (ased on the #C-58 data ty"e can (e "receded !ith the letters wc to indicate a !ide character.

The #+NNT.- header 'ile goes on to de'ine si4 data ty"es you can use as "ointers to ^:(it character strings and 'our data ty"es you can use as "ointers to const ^:(it character strings. +7ve condensed the actual header 'ile statements a (it to sho! the data ty"es here: t%pedef 4?FU 3 C4?FU# 3 LC4?# 3 C4?# 3 ;C:(U# 3 LC:(U# 3 C:(U ; t%pedef 4D;:( 4?FU 3 LC44?# 3 C44?# 3 LC4:(U# 3 C4:(U ; The N and , "re'i4es stand 'or InearI and IlongI and re'er to the t!o di''erent siPes o' "ointers in =C:(it #indo!s. There is no di''erentiation (et!een near and long "ointers in #inG;. Similarly0 #+NNT.- de'ines si4 data ty"es you can use as "ointers to =C:(it character strings and 'our data ty"es you can use as "ointers to const =C:(it character strings: t%pedef 84?FU 3 C84?FU# 3 LC84?# 3 C84?# 3 ;8C:(U# 3 LC8:(U# 3 C8:(U ; t%pedef 4D;:( 84?FU 3 LC484?# 3 C484?# 3 LC48:(U# 3 C48:(U ; So 'ar0 !e have the data ty"es C-58 (!hich is an ^:(it char* and #C-58 (!hich is a =C:(it wchar_t* and "ointers to C-58 and #C-58. 5s in TC-58.-0 #+NNT.- de'ines TC-58 to (e the generic character ty"e. +' the identi'ier .N+C%D3 (without the underscore* is de'ined0 TC-58 and "ointers to TC-58 are de'ined (ased on #C-58 and "ointers to #C-58L i' the identi'ier .N+C%D3 is not de'ined0 TC-58 and "ointers to TC-58 are de'ined (ased on char and "ointers to char: #ifdef V;=4DLP t%pedef 84?FU (4?FU# 3 C(4?FU ; t%pedef LC8:(U LC(4?# C(4?# C(:(U# LC(:(U ; t%pedef LC48:(U LC4(:(U ; #else t%pedef char (4?FU# 3 C(4?FU ; t%pedef LC:(U LC(4?# C(4?# C(:(U# LC(:(U ; t%pedef LC4:(U LC4(:(U ; #endif 1oth the #+NNT.- and #C-58.- header 'iles are "rotected against rede'inition o' the TC-58 data ty"e i' it7s already (een de'ined (y one or the other o' these header 'iles. -o!ever0 !henever you7re using other header 'iles in your "rogram0 you should include #+ND%#S.- (e'ore all others. The #+NNT.- header 'ile also de'ines a macro that a""ends the , to the 'irst )uotation mar o' a character string. +' the .N+C%D3 identi'ier is de'ined0 a macro called 99T3AT is de'ined as 'ollo!s: #define &&(PW((5uote) L##5uote +' the identi'ier .N+C%D3 is not de'ined0 the 99T3AT macro is de'ined li e so: #define &&(PW((5uote) 5uote 8egardless0 the T3AT macro is de'ined li e this: #define (PW((5uote) &&(PW((5uote) This is very similar to the !ay the 9T3AT macro is de'ined in TC-58.-0 e4ce"t that you need not (other !ith the underscore. +7ll (e using the T3AT version o' this macro throughout this (oo . These de'initions let you mi4 5SC++ and .nicode characters strings in the same "rogram or !rite a single "rogram that can (e com"iled 'or either 5SC++ or .nicode. +' you !ant to e4"licitly de'ine ^:(it character varia(les and strings0 use C-580 $C-58 (or one o' the others*0 and strings !ith )uotation mar s. /or e4"licit =C:(it character varia(les and strings0 use #C-580 $#C-580 and a""end an , (e'ore )uotation mar s. /or varia(les and characters strings that !ill (e ^ (it or =C (it de"ending on the de'inition o' the .N+C%D3 identi'ier0 use TC-580 $TC-580 and the T3AT macro.

%he Windows F$nction Calls


+n the =C:(it versions o' #indo!s (eginning !ith #indo!s =.F and ending !ith #indo!s G.=0 the Message)ox 'unction !as located in the dynamic:lin li(rary .S38.3A3. +n the #+ND%#S.- header 'iles included in the #indo!s G.= So't!are Develo"ment Kit0 the Message)ox 'unction !as de'ined li e so: int 8=;FC= Kessa+eIo" (?8;L# LC4:(U# LC4:(U# V=;() ; Notice that the second and third arguments to the 'unction are "ointers to constant character strings. #hen a #in=C "rogram !as com"iled and lin ed0 #indo!s le't the call to Message)ox unresolved. 5 ta(le in the "rogram7s .3A3 'ile allo!ed #indo!s to dynamically lin the call 'rom the "rogram to the Message)ox 'unction located in the .S38 li(rary.

The G;:(it versions o' #indo!s (that is0 all versions o' #indo!s NT0 as !ell as #indo!s B? and #indo!s B^* include .S38.3A3 'or =C:(it com"ati(ility (ut also have a dynamic:lin li(rary named .S38G;.D,, that contains entry "oints 'or the G;:(it versions o' the user inter'ace 'unctions0 including the G;:(it version o' Message)ox. 1ut here7s the ey to #indo!s su""ort o' .nicode: +n .S38G;.D,,0 there is no entry "oint 'or a G;:(it 'unction named Message)ox. +nstead0 there are t!o entry "oints0 one named Message)ox/ (the 5SC++ version* and the other named Message)ox& (the !ide:character version*. 3very #inG; 'unction that re)uires a character string argument has t!o entry "oints in the o"erating systemJ /ortunately0 you usually don7t have to !orry a(out this. Nou can sim"ly use Message)ox in your "rograms. 5s in the TC-58 header 'ile0 the various #indo!s header 'iles "er'orm the necessary tric s. -ere7s ho! Message)ox/ is de'ined in #+N.S38.-. This is )uite similar to the earlier de'inition o' Message)ox: 8=;V:PUFC= int 8=;FC= Kessa+eIo"F (?8;L h8nd# LC4:(U lp(e"t# LC4:(U lp4aption# V=;( u(%pe) ; 5nd here7s Message)ox&: 8=;V:PUFC= int 8=;FC= Kessa+eIo"8 (?8;L h8nd# LC48:(U lp(e"t# LC48:(U lp4aption# V=;( u(%pe) ; Notice that the second and third "arameters to the Message)ox& 'unction are "ointers to !ide:character strings. Nou can use the Message)ox/ and Message)ox& 'unctions e4"licitly in your #indo!s "rograms i' you need to mi4 and match 5SC++ and !ide:character 'unction calls. 1ut most "rogrammers !ill continue to use Message)ox0 !hich !ill (e the same as Message)ox/ or Message)ox& de"ending on !hether .N+C%D3 is de'ined. -ere7s the rather trivial code in #+N.S38.- that does the tric : #ifdef V;=4DLP #define Kessa+eIo" Kessa+eIo"8 #else #define Kessa+eIo" Kessa+eIo"F #endif Thus0 all the Message)ox 'unction calls that a""ear in your "rogram !ill actually (e Message)ox& 'unctions i' the .N+C%D3 identi'ier is de'ined and Message)ox/ 'unctions i' it7s not de'ined. #hen you run the "rogram0 #indo!s lin s the various 'unction calls in your "rogram to the entry "oints in the various #indo!s dynamic:lin li(raries. #ith 6ust a 'e! e4ce"tions0 ho!ever0 the .nicode versions o' the #indo!s 'unctions are not im"lemented in #indo!s B^. The 'unctions have entry "oints0 (ut they usually return an error code. +t is u" to an a""lication to ta e note o' this error return and do something reasona(le.

WindowsX ,tring F$nctions


5s + noted earlier0 &icroso't C includes !ide:character and generic versions o' all C run:time li(rary 'unctions that re)uire character string arguments. -o!ever0 #indo!s du"licates some o' these. /or e4am"le0 here is a collection o' string 'unctions de'ined in #indo!s that calculate string lengths0 co"y strings0 concatenate strings0 and com"are strings: =Len+th ' lstrlen (p:trin+) ; p:trin+ ' lstrcp% (p:trin+1# p:trin+2) ; p:trin+ ' lstrcp%n (p:trin+1# p:trin+2# i4ount) ; p:trin+ ' lstrcat (p:trin+1# p:trin+2) ; i4omp ' lstrcmp (p:trin+1# p:trin+2) ; i4omp ' lstrcmpi (p:trin+1# p:trin+2) ; These !or much the same as their C li(rary e)uivalents. They acce"t !ide:character strings i' the .N+C%D3 identi'ier is de'ined and regular strings i' not. The !ide:character version o' the lstrlen& 'unction is im"lemented in #indo!s B^.

*sing printf in Windows


$rogrammers !ho have a (ac ground in character:mode0 command:line C "rogramming are o'ten e4cessively 'ond o' the printf 'unction. +t7s no sur"rise that printf sho!s u" in the Kernighan and 8itchie Ihello0 !orldI "rogram even though a sim"ler alternative (such as puts* could have (een used. 3veryone no!s that enhancements to Ihello0 !orldI !ill need the 'ormatted te4t out"ut o' printf eventually0 so !e might as !ell start using it at the outset.

The (ad ne!s is that you can7t use printf in a #indo!s "rogram. 5lthough you can use most o' the C run:time li(rary in #indo!s "rogramsSindeed0 many "rogrammers "re'er to use the C memory management and 'ile +/% 'unctions over the #indo!s e)uivalentsS#indo!s has no conce"t o' standard in"ut and standard out"ut. Nou can use fprintf in a #indo!s "rogram0 (ut not printf. The good ne!s is that you can still dis"lay te4t (y using sprintf and other 'unctions in the sprintf 'amily. These 'unctions !or 6ust li e printf0 e4ce"t that they !rite the 'ormatted out"ut to a character string (u''er that you "rovide as the 'unction7s 'irst argument. Nou can then do !hat you !ant !ith this character string (such as "ass it to Message)ox*. +' you7ve never had occasion to use sprintf (as + didn7t !hen + 'irst (egan "rogramming 'or #indo!s*0 here7s a (rie' rundo!n. 8ecall that the printf 'unction is declared li e so: int printf (const char 3 s@6ormat# ...) ; The 'irst argument is a 'ormatting string that is 'ollo!ed (y a varia(le num(er o' arguments o' various ty"es corres"onding to the codes in the 'ormatting string. The sprintf 'unction is de'ined li e this: int sprintf (char 3 s@Iuffer# const char 3 s@6ormat# ...) ; The 'irst argument is a character (u''erL this is 'ollo!ed (y the 'ormatting string. 8ather than !riting the 'ormatted result in standard out"ut0 sprintf stores it in sz)uffer. The 'unction returns the length o' the string. +n character:mode "rogramming0 printf ("(he sum of )i and )i is )i"# .# -# .*-) ; is 'unctionally e)uivalent to char s@Iuffer Q1//R ; sprintf (s@Iuffer# "(he sum of )i and )i is )i"# .# -# .*-) ; puts (s@Iuffer) ; +n #indo!s0 you can use Message)ox rather than puts to dis"lay the results. 5lmost everyone has e4"erience !ith printf going a!ry and "ossi(ly crashing a "rogram !hen the 'ormatting string is not "ro"erly in sync !ith the varia(les to (e 'ormatted. #ith sprintf0 you still have to !orry a(out that and you also have a ne! !orry: the character (u''er you de'ine must (e large enough 'or the result. 5 &icroso't:s"eci'ic 'unction named _snprintf solves this "ro(lem (y introducing another argument that indicates the siPe o' the (u''er in characters. 5 variation o' sprintf is vsprintf0 !hich has only three arguments. The vsprintf 'unction is used to im"lement a 'unction o' your o!n that must "er'orm printf:li e 'ormatting o' a varia(le num(er o' arguments. The 'irst t!o arguments to vsprintf are the same as sprintf: the character (u''er 'or storing the result and the 'ormatting string. The third argument is a "ointer to an array o' arguments to (e 'ormatted. +n "ractice0 this "ointer actually re'erences varia(les that have (een stored on the stac in "re"aration 'or a 'unction call. The va_list0 va_start0 and va_end macros (de'ined in STD582.-* hel" in !or ing !ith this stac "ointer. The SC8NS+X3 "rogram at the end o' this cha"ter demonstrates ho! to use these macros. The sprintf 'unction can (e !ritten in terms o' vsprintf li e so: int sprintf (char 3 s@Iuffer# const char 3 s@6ormat# ...) { int iUeturn ; va&list pFr+s ; va&start (pFr+s# s@6ormat) ; iUeturn ' vsprintf (s@Iuffer# s@6ormat# pFr+s) ; va&end (pFr+s) ; return iUeturn ; The va_start macro sets p/rg to "oint to the varia(le on the stac right a(ove the sz!ormat argument on the stac . So many early #indo!s "rograms used sprintf and vsprintf that &icroso't eventually added t!o similar 'unctions to the #indo!s 5$+. The #indo!s wsprintf and wvsprintf 'unctions are 'unctionally e)uivalent to sprintf and vsprintf0 e4ce"t that they don7t handle 'loating:"oint 'ormatting. %' course0 !ith the introduction o' !ide characters0 the sprintf 'unctions (lossomed in num(er0 creating a thoroughly con'using 6um(le o' 'unction names. -ere7s a chart that sho!s all the sprintf 'unctions su""orted (y &icroso't7s C run:time li(rary and (y #indo!s. )*+II .ide +haracter 1eneric Standard Version sprintf swprintf _stprintf &a4:,ength Version _snprintf _snwprintf _sntprintf

#indo!s Version wsprintf/ wsprintf& wsprintf Standard Version vsprintf vswprintf _vstprintf &a4:,ength Version _vsnprintf _vsnwprintf _vsntprintf #indo!s Version wvsprintf/ wvsprintf& wvsprintf +n the !ide:character versions o' the sprintf 'unctions0 the string (u''er is de'ined as a !ide:character string. +n the !ide:character versions o' all these 'unctions0 the 'ormatting string must (e a !ide:character string. -o!ever0 it7s u" to you to ma e sure that any other strings you "ass to these 'unctions are also com"osed o' !ide characters.

> Formatting Message Bo=


The SC8NS+X3 "rogram sho!n in /igure ;:G sho!s ho! to im"lement a Message)ox4rintf 'unction that ta es a varia(le num(er o' arguments and 'ormats them li e printf. Fig$re C-DA .he 0$"+0*;, program.

,CR),#Y0AC
2399999999999999999999999999999999999999999999999999999 :4U;:=\P.4 99 Lispla%s screen si@e in a messa+e !o" (c) 4harles Cet@old# 1SST 9999999999999999999999999999999999999999999999999999932 #include <,indo,s.h> #include <tchar.h> #include <stdio.h> int 4LP4L Kessa+eIo"Crintf ((4?FU 3 s@4aption# (4?FU 3 s@6ormat# ...) { (4?FU s@Iuffer Q1/2HR ; va&list pFr+List ; 22 (he va&start macro (defined in :(LFUY.?) is usuall% e5uivalent to7 22 pFr+List ' (char 3) ]s@6ormat * si@eof (s@6ormat) ; va&start (pFr+List# s@6ormat) ; 22 (he last ar+ument to ,vsprintf points to the ar+uments &vsntprintf (s@Iuffer# si@eof (s@Iuffer) 2 si@eof ((4?FU)# s@6ormat# pFr+List) ; reason 22 (he va&end macro $ust @eroes out pFr+List for no +ood

va&end (pFr+List) ; return Kessa+eIo" (;VLL# s@Iuffer# s@4aption# /) ; int 8=;FC= 8inKain (?=;:(F;4P h=nstance# ?=;:(F;4P hCrev=nstance# C:(U s@4mdLine# int i4md:ho,) { int c":creen# c%:creen ; c":creen ' Yet:%stemKetrics (:K&4W:4UPP;) ;

c%:creen ' Yet:%stemKetrics (:K&4G:4UPP;) ; Kessa+eIo"Crintf ((PW( (":crn:i@e")# (PW( ("(he screen is )i pi"els ,ide !% )i pi"els hi+h.")# c":creen# c%:creen) ; return / ; The "rogram dis"lays the !idth and height o' the video dis"lay in "i4els (y using in'ormation o(tained 'rom the 2et0#stemMetrics 'unction. 2et0#stemMetrics is a use'ul 'unction 'or o(taining in'ormation a(out the siPes o' various o(6ects in #indo!s.

#nternationaliLation
$re"aring your #indo!s "rograms 'or an international mar et involves more than using .nicode. +nternationaliPation is (eyond our sco"e o' discussion (ut is covered e4tensively in 'eveloping *nternational 0oftware for &indows <= and &indows +. (y Nadine Kano (&icroso't $ress0 =BB?*. #e !ill restrict ourselves to sho!ing "rograms that can (e com"iled either !ith or !ithout he .N+C%D3 identi'ier de'ined. This involves using TC-58 'or all character and string de'initions0 using the T3AT macro 'or string literals0 and ta ing care not to con'use (ytes and characters. /or e4am"le0 notice the _vsntprintf call in SC8NS+X3. The second argument is the siPe o' the (u''er in characters. Ty"ically0 you7d use sizeof 6sz)uffer). 1ut i' the (u''er has !ide characters0 that7s not the siPe o' the (u''er in characters (ut the siPe o' the (u''er in (ytes. Nou must divide it (y sizeof 6.$-/").

Windows and Messages


The sam"le "rograms0earlier0 used the Message)ox 'unction to deliver te4t out"ut to the user. The Message)ox 'unction creates a I!indo!.I +n #indo!s0 the !ord I!indo!I has a "recise meaning. 5 !indo! is a rectangular area on the screen that receives user in"ut and dis"lays out"ut in the 'orm o' te4t and gra"hics. The Message)ox 'unction creates a !indo!0 (ut it is a s"ecial:"ur"ose !indo! o' limited 'le4i(ility. The message (o4 !indo! has a title (ar !ith a close (utton0 an o"tional icon0 one or more lines o' te4t0 and u" to 'our (uttons. -o!ever0 the icons and (uttons must (e chosen 'rom a small collection that #indo!s "rovides 'or you. The Message)ox 'unction is certainly use'ul0 (ut !e7re not going to get very 'ar !ith it. #e can7t dis"lay gra"hics in a message (o40 and !e can7t add a menu to a message (o4. /or that !e need to create our o!n !indo!s0 and no! is the time.

> Window of OneXs Own


Creating a !indo! is as easy as calling the $reate&indow 'unction. #ell0 not really. 5lthough 0 the 'unction to create a !indo! is indeed named $reate&indow and you can 'ind documentation 'or this 'unction at 34latform 0'531ser *nterface 0ervices3&indowing3&indows3&indow "eference3&indow !unctions0 you7ll discover that the 'irst argument to $reate&indow is something called a I!indo! class nameI and that a !indo! class is connected to something called a I!indo! "rocedure.I $erha"s (e'ore !e try calling $reate&indow0 a little (ac ground in'ormation might "rove hel"'ul.

>n >rchitect$ral Overview


#hen "rogramming 'or #indo!s0 you7re really engaged in a ty"e o' o(6ect:oriented "rogramming. This is most evident in the o(6ect you7ll (e !or ing !ith most in #indo!s0 the o(6ect that gives #indo!s its name0 the o(6ect that !ill soon seem to ta e on anthro"omor"hic characteristics0 the o(6ect that might even sho! u" in your dreams: the o(6ect no!n as the I!indo!.I The most o(vious !indo!s adorning your des to" are a""lication !indo!s. These !indo!s contain a title (ar that sho!s the "rogram7s name0 a menu0 and "erha"s a tool(ar and a scroll (ar. 5nother ty"e o' !indo! is the dialog (o40 !hich may or may not have a title (ar.

,ess o(vious are the various "ush (uttons0 radio (uttons0 chec (o4es0 list (o4es0 scroll (ars0 and te4t:entry 'ields that adorn the sur'aces o' dialog (o4es. 3ach o' these little visual o(6ects is a !indo!. More s-ecificall(. these are called Zchild windowsZ or Zcontrol windowsZ or Zchild window controlsAZ %he $ser sees these windows as o/Jects on the screen and interacts directl( with them $sing the +e(/oard or the mo$se. +nterestingly enough0 the "rogrammer7s "ers"ective is analogous to the user7s "ers"ective. The !indo! receives the user in"ut in the 'orm o' ImessagesI to the !indo!. 5 !indo! also uses messages to communicate !ith other !indo!s. 2etting a good 'eel 'or messages is an im"ortant "art o' learning ho! to !rite "rograms 'or #indo!s. -ere7s an e4am"le o' #indo!s messages: 5s you no!0 most #indo!s "rograms have siPea(le a""lication !indo!s. That is0 you can gra( the !indo!7s (order !ith the mouse and change the !indo!7s siPe. %'ten the "rogram !ill res"ond to this change in siPe (y altering the contents o' its !indo!. Nou might guess (and you !ould (e correct* that #indo!s itsel' rather than the a""lication is handling all the messy code involved !ith letting the user resiPe the !indo!. Net the a""lication I no!sI that the !indo! has (een resiPed (ecause it can change the 'ormat o' !hat it dis"lays. -o! does the a""lication no! that the user has changed the !indo!7s siPeW /or "rogrammers accustomed to only conventional character:mode "rogramming0 there is no mechanism 'or the o"erating system to convey in'ormation o' this sort to the user. +t turns out that the ans!er to this )uestion is central to understanding the architecture o' #indo!s. #hen a user resiPes a !indo!0 #indo!s sends a message to the "rogram indicating the ne! !indo! siPe. The "rogram can then ad6ust the contents o' its !indo! to re'lect the ne! siPe. I#indo!s sends a message to the "rogram.I + ho"e you didn7t read that statement !ithout (lin ing. #hat on earth could it meanW #e7re tal ing a(out "rogram code here0 not a telegra"h system. -o! can an o"erating system send a message to a "rogramW #hen + say that I#indo!s sends a message to the "rogramI + mean that #indo!s calls a 'unction !ithin the "rogramSa 'unction that you !rite and !hich is an essential "art o' your "rogram7s code. The "arameters to this 'unction descri(e the "articular message that is (eing sent (y #indo!s and received (y your "rogram. This 'unction in your "rogram is no!n as the I!indo! "rocedure.I Nou are undou(tedly accustomed to the idea o' a "rogram ma ing calls to the o"erating system. This is ho! a "rogram o"ens a dis 'ile0 'or e4am"le. #hat you may not (e accustomed to is the idea o' an o"erating system ma ing calls to a "rogram. Net this is 'undamental to #indo!s7 architecture. 3very !indo! that a "rogram creates has an associated !indo! "rocedure. This !indo! "rocedure is a 'unction that could (e either in the "rogram itsel' or in a dynamic:lin li(rary. #indo!s sends a message to a !indo! (y calling the !indo! "rocedure. The !indo! "rocedure does some "rocessing (ased on the message and then returns control to #indo!s. &ore "recisely0 a !indo! is al!ays created (ased on a I!indo! class.I The !indo! class identi'ies the !indo! "rocedure that "rocesses messages to the !indo!. The use o' a !indo! class allo!s multi"le !indo!s to (e (ased on the same !indo! class and hence use the same !indo! "rocedure. /or e4am"le0 all (uttons in all #indo!s "rograms are (ased on the same !indo! class. This !indo! class is associated !ith a !indo! "rocedure located in a #indo!s dynamic:lin li(rary that "rocesses messages to all the (utton !indo!s. +n o(6ect:oriented "rogramming0 an o(6ect is a com(ination o' code and data. 5 !indo! is an o(6ect. The code is the !indo! "rocedure. The data is in'ormation retained (y the !indo! "rocedure and in'ormation retained (y #indo!s 'or each !indo! and !indo! class that e4ists in the system. 5 !indo! "rocedure "rocesses messages to the !indo!. Very o'ten these messages in'orm a !indo! o' user in"ut 'rom the ey(oard or the mouse. /or e4am"le0 this is ho! a "ush:(utton !indo! no!s that it7s (eing Iclic ed.I %ther messages tell a !indo! !hen it is (eing resiPed or !hen the sur'ace o' the !indo! needs to (e redra!n. #hen a #indo!s "rogram (egins e4ecution0 #indo!s creates a Imessage )ueueI 'or the "rogram. This message )ueue stores messages to all the !indo!s a "rogram might create. 5 #indo!s a""lication includes a short chun o' code called the Imessage loo"I to retrieve these messages 'rom the )ueue and dis"atch them to the a""ro"riate !indo! "rocedure. %ther messages are sent directly to the !indo! "rocedure !ithout (eing "laced in the message )ueue. +' your eyes are (eginning to glaPe over !ith this e4cessively a(stract descri"tion o' the #indo!s architecture0 may(e it !ill hel" to see ho! the !indo!0 the !indo! class0 the !indo! "rocedure0 the message )ueue0 the message loo"0 and the !indo! messages all 'it together in the conte4t o' a real "rogram.

%he '0&&OW#) Program

Creating a !indo! 'irst re)uires registering a !indo! class0 and that re)uires a !indo! "rocedure to "rocess messages to the !indo!. This involves a (it o' overhead that a""ears in almost every #indo!s "rogram. The -3,,%#+N "rogram0 sho!n in /igure G:=0 is a sim"le "rogram sho!ing mostly that overhead. Fig$re D-!A .he -,((>&*+ program.

'0&&OW#)AC
23999999999999999999999999999999999999999999999999999999999999 ?PLLD8=;.4 99 Lispla%s "?ello# 8indo,s STO" in client area (c) 4harles Cet@old# 1SST 99999999999999999999999999999999999999999999999999999999999932 #include <,indo,s.h> LUP:VL( 4FLLIF4X 8ndCroc (?8;L# V=;(# 8CFUFK# LCFUFK) ; int 8=;FC= 8inKain (?=;:(F;4P h=nstance# ?=;:(F;4P hCrev=nstance# C:(U s@4mdLine# int i4md:ho,) { static (4?FU s@Fpp;ameQR ' (PW( ("?ello8in") ; ?8;L h,nd ; K:Y ms+ ; 8;L4LF:: ,ndclass ; ,ndclass.st%le ,ndclass.lpfn8ndCroc ,ndclass.c!4lsP"tra ,ndclass.c!8ndP"tra ,ndclass.h=nstance ,ndclass.h=con ,ndclass.h4ursor ,ndclass.h!rIac0+round ,ndclass.lps@Kenu;ame ,ndclass.lps@4lass;ame ' ' ' ' ' ' ' ' ' ' 4:&?UPLUF8 ^ 4:&_UPLUF8 ; 8ndCroc ; / ; / ; h=nstance ; Load=con (;VLL# =L=&FCCL=4F(=D;) ; Load4ursor (;VLL# =L4&FUUD8) ; (?IUV:?) Yet:toc0D!$ect (8?=(P&IUV:?) ; ;VLL ; s@Fpp;ame ;

if (OUe+ister4lass (],ndclass)) { Kessa+eIo" (;VLL# (PW( ("(his pro+ram re5uires 8indo,s ;(O")# s@Fpp;ame# KI&=4D;PUUDU) ; return / ; name h,nd ' 4reate8indo, (s@Fpp;ame# 22 ,indo, class

position position

(PW( ("(he ?ello Cro+ram")# 22 ,indo, caption 8:&D_PULFCCPL8=;LD8# 22 ,indo, st%le 48&V:PLP6FVL(# 22 initial " 48&V:PLP6FVL(# 48&V:PLP6FVL(# 48&V:PLP6FVL(# ;VLL# ;VLL# h=nstance# 22 initial % 22 initial " si@e 22 initial % si@e 22 parent ,indo, 22 ,indo, menu 22 pro+ram

handle handle

instance handle parameters

;VLL) ;

22 creation

:ho,8indo, (h,nd# i4md:ho,) ; Vpdate8indo, (h,nd) ; ,hile (YetKessa+e (]ms+# ;VLL# /# /)) { (ranslateKessa+e (]ms+) ; LispatchKessa+e (]ms+) ; return ms+.,Caram ; LUP:VL( 4FLLIF4X lCaram) { ?L4 CF=;(:(UV4( UP4( 8ndCroc (?8;L h,nd# V=;( messa+e# 8CFUFK ,Caram# LCFUFK hdc ; ps ; rect ;

s,itch (messa+e) { case 8K&4UPF(P7 Cla%:ound ((PW( ("hello,in.,av")# ;VLL# :;L&6=LP;FKP ^ :;L&F:G;4) ; return / ; case 8K&CF=;(7 hdc ' Ie+inCaint (h,nd# ]ps) ; Yet4lientUect (h,nd# ]rect) ; Lra,(e"t (hdc# (PW( ("?ello# 8indo,s STO")# 91# ]rect# L(&:=;YLPL=;P ^ L(&4P;(PU ^ L(&_4P;(PU) ; PndCaint (h,nd# ]ps) ; return / ; case 8K&LP:(UDG7 CostJuitKessa+e (/) ; return / ; return Lef8indo,Croc (h,nd# messa+e# ,Caram# lCaram) ; This "rogram creates a normal a""lication !indo!0 as sho!n in /igure G:;0 and dis"lays0 I-ello0 #indo!s B^JI in the center o' that !indo!. +' you have a sound (oard installed0 you !ill also hear me saying the same thing.

6avascri"t:'ullSiPe(7/FGPgF;4.htm7*6avascri"t:'ullSiPe(7/FGPgF;4.htm7* Fig$re D-CA .he -,((>&*+ window. 5 cou"le o' !arnings: +' you use &icroso't Visual C++ to create a ne! "ro6ect 'or this "rogram0 you need to ma e an addition to the o(6ect li(raries the lin er uses. Select the Settings o"tion 'rom the $ro6ect menu0 and "ic the ,in ta(. Select 2eneral 'rom the Category list (o40 and add #+N&&.,+1 (I#indo!s multimediaI* to the %(6ect/,i(rary &odules te4t (o4. Nou need to do this (ecause -3,,%#+N ma es use o' a multimedia 'unction call0 and the multimedia o(6ect li(rary isn7t included in a de'ault "ro6ect. %ther!ise you7ll get an error message 'rom the lin er indicating that the 4la#0ound 'unction is unresolved. -3,,%#+N accesses a 'ile named -3,,%#+N.#5V0 !hich is on the com"anion CD:8%& in the -3,,%#+N directory. #hen you e4ecute -3,,%#+N.3A30 the de'ault directory must (e -3,,%#+N. This is the case !hen you e4ecute the "rogram !ithin Visual C++0 even though the e4ecuta(le !ill (e in the 83,35S3 or D31.2 su(directory o' -3,,%#+N.

%hin+ing 6lo/all(
&ost o' -3,,%#+N.C is overhead 'ound in virtually every #indo!s "rogram. + mentioned a(ove that -3,,%#+N dis"lays the te4t string in the center o' its !indo!. That7s not "recisely true. The te4t is actually dis"layed in the center o' the "rogram7s Iclient area0I !hich in /igure G:; is the large !hite area !ithin the title (ar and the siPing (order. This distinction !ill (e im"ortant to usL the client area is that area of the window in which a -rogram is free to draw and deliver vis$al o$t-$t to the $ser . #hen you thin a(out it0 this "rogram has an amaPing amount o' 'unctionality in its ^F:odd lines o' code. Nou can gra( the title (ar !ith the mouse and move the !indo! around the screen. Nou can gra( the siPing (orders and resiPe the !indo!. #hen the !indo! changes siPe0 the "rogram automatically re"ositions the te4t string in the center o' its client area. Nou can clic the &a4imiPe (utton and Poom -3,,%#+N to 'ill the screen. Nou can clic the minimiPe (utton and clear it 'rom the screen. Nou can invo e all these o"tions 'rom the system menu (the small icon at the 'ar le't o' the title (ar*. Nou can also close the !indo! to terminate the "rogram (y selecting the Close o"tion 'rom the system menu0 (y clic ing the close (utton at the 'ar right o' the title (ar0 or (y dou(le:clic ing the system menu icon. #e7ll (e e4amining this "rogram in detail 'or much o' the remainder o' the cha"ter. /irst0 ho!ever0 let7s ta e a more glo(al loo . -3,,%#+N.C has a &inMain 'unction li e the sam"le "rograms !e sa! earlier0 (ut it also has a second 'unction named .nd(rocA This is the !indo! "rocedure. (+n conversation among #indo!s "rogrammers0 it7s called the I!in "roc .I* Notice that there7s no code in -3,,%#+N.C that calls &nd4roc. -o!ever0 there is a re'erence to &nd4roc in &inMain0 !hich is !hy the 'unction is declared near the to" o' the "rogram.

%he Windows F$nction Calls


-3,,%#+N ma es calls to no 'e!er than =^ #indo!s 'unctions. +n the order they occur0 these 'unctions (!ith a (rie' descri"tion* are: (oad*con ,oads an icon 'or use (y a "rogram. (oad$ursor ,oads a mouse cursor 'or use (y a "rogram. 2et0toc%>bject %(tains a gra"hic o(6ect0 in this case a (rush used 'or "ainting the !indo!7s (ac ground. "egister$lass 8egisters a !indo! class 'or the "rogram7s !indo!. Message)ox Dis"lays a message (o4. $reate&indow Creates a !indo! (ased on a !indo! class. 0how&indow Sho!s the !indo! on the screen. 1pdate&indow Directs the !indo! to "aint itsel'. 2etMessage %(tains a message 'rom the message )ueue. .ranslateMessage Translates some ey(oard messages. 'ispatchMessage Sends a message to a !indo! "rocedure. 4la#0ound $lays a sound 'ile. )egin4aint +nitiates the (eginning o' !indo! "ainting. 2et$lient"ect %(tains the dimensions o' the !indo!7s client area. 'raw.ext Dis"lays a te4t string. ,nd4aint 3nds !indo! "ainting. 4ost?uitMessage +nserts a I)uitI message into the message )ueue. 'ef&indow4roc $er'orms de'ault "rocessing o' messages. These 'unctions are descri(ed in the $lat'orm SDK documentation0 and they are declared in various header 'iles0 mostly in #+N.S38.-.

*--ercase #dentifiers
Nou7ll notice the use o' )uite a 'e! u""ercase identi'iers in -3,,%#+N.C. These identi'iers are de'ined in the #indo!s header 'iles. Several o' these identi'iers contain a t!o:letter or three:letter "re'i4 'ollo!ed (y an underscore: $0_-",'"/& '._@$,+.," 0+'_!*(,+/M, $0_@",'"/& *'$_/"">& &M_$",/., $&_10,',!/1(. *'*_/44(*$/.*>+ &M_',0.">A '._$,+.," M)_*$>+,"">" &M_4/*+. '._0*+2(,(*+, 0+'_/0A+$ &0_>@,"(/44,'&*+'>& %hese are sim-l( n$meric constants. The "re'i4 indicates a general category to !hich the constant (elongs0 as indicated in this ta(le: (refix +onstant CS Class style o"tion C# Create !indo! o"tion DT Dra! te4t o"tion +D+ +D num(er 'or an icon +DC +D num(er 'or a cursor &1 &essage (o4 o"tions SND Sound o"tion #& #indo! message #S #indo! style Nou almost never need to remem(er numeric constants !hen "rogramming 'or #indo!s. Virtually every numeric constant has an identi'ier de'ined in the header 'iles.

)ew Data %(-es

Some other identi'iers used in -3,,%#+N.C are ne! data ty"es0 also de'ined in the #indo!s header 'iles using either t#pedef or :define statements. This !as originally done to ease the transition o' #indo!s "rograms 'rom the original =C:(it system to 'uture o"erating systems that !ould (e (ased on G;:(it technology. This didn7t )uite !or as smoothly and trans"arently as everyone thought at the time0 (ut the conce"t !as 'undamentally sound. Sometimes these ne! data ty"es are 6ust convenient a((reviations. /or e4am"le0 the .+NT data ty"e used 'or the second "arameter to &nd4roc is sim"ly an unsigned int0 !hich in #indo!s B^ is a G;:(it value. The $ST8 data ty"e used 'or the third "arameter to &inMain is a "ointer to a non!ide character string0 that is0 a char B. %thers are less o(vious. /or e4am"le0 the third and 'ourth "arameters to &nd4roc are de'ined as #$585& and ,$585&0 res"ectively. The origin o' these names re)uires a (it o' history. #hen #indo!s !as a =C:(it system0 the third "arameter to &nd4roc !as de'ined as a #%8D0 !hich !as a =C:(it unsigned short integer0 and the 'ourth "arameter !as de'ined as a ,%N20 !hich !as a G;:(it signed long integer. That7s the reason 'or the I#I and I,I "re'i4es on the !ord I$585&.I +n the G;:(it versions o' #indo!s0 ho!ever0 #$585& is de'ined as a .+NT and ,$585& is de'ined as a ,%N2 (!hich is still the C long data ty"e*0 so (oth "arameters to the !indo! "rocedure are G;:(it values. This may (e a little con'using (ecause the #%8D data ty"e is still de'ined as a =C:(it unsigned short integer in #indo!s B^0 so the I#I "re'i4 to I$585&I creates some!hat o' a misnomer. The &nd4roc 'unction returns a value o' ty"e ,83S.,T. That7s sim"ly de'ined as a ,%N2. The &inMain 'unction is given a ty"e o' #+N5$+ (as is every #indo!s 'unction call de'ined in the header 'iles*0 and the &nd4roc 'unction is given a ty"e o' C5,,15CK. 1oth these identi'iers are de'ined as __stdcall0 !hich re'ers to a s"ecial calling se)uence 'or 'unction calls that occur (et!een #indo!s itsel' and your a""lication. -3,,%#+N also uses 'our data structures (!hich +7ll discuss later in this cha"ter* de'ined in the #indo!s header 'iles. These data structures are sho!n in the ta(le (elo!. *tructure 2eaning &S2 &essage structure #NDC,5SS #indo! class structure $5+NTST8.CT $aint structure 83CT 8ectangle structure The 'irst t!o data structures are used in &inMain to de'ine t!o structures named msg and wndclass. The second t!o are used in &nd4roc to de'ine t!o structures named ps and rect.

6etting a 'andle on 'andles


/inally0 there are three u""ercase identi'iers 'or various ty"es o' IhandlesI: Identifier 2eaning -+NST5NC3 -andle to an IinstanceISthe "rogram itsel' -#ND -andle to a !indo! -DC -andle to a device conte4t -andles are used )uite 're)uently in #indo!s. Nou !ill also encounter -+C%N (a handle to an icon*0 -C.8S%8 (a handle to a mouse cursor*0 and -18.S- (a handle to a gra"hics (rush*. 5 handle is sim"ly a num(er (usually G; (its in siPe* that re'ers to an o(6ect. The handles in #indo!s are similar to 'ile handles used in conventional C or &S:D%S "rogramming. 5 "rogram almost al!ays o(tains a handle (y calling a #indo!s 'unction. The "rogram uses the handle in other #indo!s 'unctions to re'er to the o(6ect. The actual value o' the handle is unim"ortant to your "rogram0 (ut the #indo!s module that gives your "rogram the handle no!s ho! to use it to re'erence the o(6ect.

'$ngarian )otation
Nou might also notice that some o' the varia(les in -3,,%#+N.C have "eculiar:loo ing names. %ne e4am"le is sz$md(ine0 "assed as a "arameter to &inMain. &any #indo!s "rogrammers use a varia(le:naming convention no!n as I-ungarian Notation0I in honor o' the legendary &icroso't "rogrammer Charles Simonyi. Very sim"ly0 the varia(le name (egins !ith a lo!ercase letter or letters that denote the data ty"e o' the varia(le. /or e4am"le0 the sz "re'i4 in sz$md(ine stands 'or Istring terminated (y Pero.I The h "re'i4 in h*nstance and h4rev*nstance stands 'or IhandleLI the i "re'i4 in i$md0how stands 'or

Iinteger.I The last t!o "arameters to &nd4roc also use -ungarian notation0 although0 as + e4"lained (e'ore0 w4aram should more "ro"erly (e named ui4aram (ui 'or Iunsigned integerI*. 1ut (ecause these t!o "arameters are de'ined using the data ty"es #$585& and ,$585&0 +7ve chosen to retain their traditional names. #hen naming structure varia(les0 you can use the structure name (or an a((reviation o' the structure name* in lo!ercase either as a "re'i4 to the varia(le name or as the entire varia(le name. /or e4am"le0 in the &inMain 'unction in -3,,%#+N.C0 the msg varia(le is a structure o' the &S2 ty"eL wndclass is a structure o' the #NDC,5SS ty"e. +n the &nd4roc 'unction0 ps is a $5+NTST8.CT structure and rect is a 83CT structure. -ungarian notation hel"s you avoid errors in your code (e'ore they turn into (ugs. 1ecause the name o' a varia(le descri(es (oth the use o' a varia(le and its data ty"e0 you are much less li ely to ma e coding errors involving mismatched data ty"es. The varia(le name "re'i4es +7ll generally (e using in this (oo are sho!n in the 'ollo!ing ta(le. (refix "ata Type c Char or #C-58 or TC-58 b# 1NT3 (unsigned char* n Short i int x0 # int used as 4:coordinate or y:coordinate cx0 c# int used as 4 or y lengthL c stands 'or IcountI b or f 1%%, (int*L ' stands 'or I'lagI w #%8D (unsigned short* l ,%N2 (long* dw D#%8D (unsigned long* fn 'unction s string sz string terminated (y F character h handle p "ointer

Registering the Window Class


5 !indo! is al!ays created (ased on a !indo! class. The !indo! class identi'ies the !indo! "rocedure that "rocesses messages to the !indo!. &ore than one !indo! can (e created (ased on a single !indo! class. /or e4am"le0 all (utton !indo!sSincluding "ush (uttons0 chec (o4es0 and radio (uttonsSare created (ased on the same !indo! class. The !indo! class de'ines the !indo! "rocedure and some other characteristics o' the !indo!s that are created (ased on that class. #hen you create a !indo!0 you de'ine additional characteristics o' the !indo! that are uni)ue to that !indo!. 1e'ore you create an a""lication !indo!0 you must register a !indo! class (y calling "egister$lass. This 'unction re)uires a single "arameter0 !hich is a "ointer to a structure o' ty"e #NDC,5SS. This structure includes t!o 'ields that are "ointers to character strings0 so the structure is de'ined t!o di''erent !ays in the #+N.S38.- header 'ile. /irst0 there7s the 5SC++ version0 #NDC,5SS5: t%pedef struct ta+8;L4LF::F { V=;( st%le ; 8;LCUD4 lpfn8ndCroc ; int c!4lsP"tra ; int c!8ndP"tra ; ?=;:(F;4P h=nstance ; ?=4D; h=con ; ?4VU:DU h4ursor ; ?IUV:? h!rIac0+round ; LC4:(U lps@Kenu;ame ; LC4:(U lps@4lass;ame ; 8;L4LF::F# 3 C8;L4LF::F# ;PFU 3 ;C8;L4LF::F# 6FU 3 LC8;L4LF::F ;

Notice some uses o' -ungarian notation here: The lpfn "re'i4 means Ilong "ointer to a 'unction.I (8ecall that in the #inG; 5$+ there is no distinction (et!een long "ointers and near "ointers. This is a remnant o' =C:(it #indo!s.* The cb "re'i4 stands 'or Icount o' (ytesI and is o'ten used 'or a varia(le that denotes a (yte siPe. The h "re'i4 is a handle0 and the hbr "re'i4 means Ihandle to a (rush.I The lpsz "re'i4 is a Ilong "ointer to a string terminated !ith a Pero.I The .nicode version o' the structure is de'ined li e so: t%pedef struct ta+8;L4LF::8 { V=;( st%le ; 8;LCUD4 lpfn8ndCroc ; int c!4lsP"tra ; int c!8ndP"tra ; ?=;:(F;4P h=nstance ; ?=4D; h=con ; ?4VU:DU h4ursor ; ?IUV:? h!rIac0+round ; LC48:(U lps@Kenu;ame ; LC48:(U lps@4lass;ame ; 8;L4LF::8# 3 C8;L4LF::8# ;PFU 3 ;C8;L4LF::8# 6FU 3 LC8;L4LF::8 ; The only di''erence is that the last t!o 'ields are de'ined as "ointers to constant !ide:character strings rather than "ointers to constant 5SC++ character strings. 5'ter #+N.S38.- de'ines the #NDC,5SS5 and #NDC,5SS# structures (and "ointers to the structures*0 the header 'ile de'ines #NDC,5SS and "ointers to #NDC,5SS (some included 'or (ac !ard com"ati(ility* (ased on the de'inition o' the .N+C%D3 identi'ier: #ifdef V;=4DLP t%pedef 8;L4LF::8 8;L4LF:: ; t%pedef C8;L4LF::8 C8;L4LF:: ; t%pedef ;C8;L4LF::8 ;C8;L4LF:: ; t%pedef LC8;L4LF::8 LC8;L4LF:: ; #else t%pedef 8;L4LF::F 8;L4LF:: ; t%pedef C8;L4LF::F C8;L4LF:: ; t%pedef ;C8;L4LF::F ;C8;L4LF:: ; t%pedef LC8;L4LF::F LC8;L4LF:: ; #endif #hen + sho! su(se)uent structures in this (oo 0 +7ll 6ust sho! the 'unctionally e)uivalent de'inition o' the structure0 !hich 'or #NDC,5SS is this: t%pedef struct { V=;( st%le ; 8;LCUD4 lpfn8ndCroc ; int c!4lsP"tra ; int c!8ndP"tra ; ?=;:(F;4P h=nstance ; ?=4D; h=con ; ?4VU:DU h4ursor ; ?IUV:? h!rIac0+round ; LC4(:(U lps@Kenu;ame ; LC4(:(U lps@4lass;ame ; 8;L4LF::# 3 C8;L4LF:: ; +7ll also go easy on the various "ointer de'initions. There7s no reason 'or you to clutter u" your code !ith varia(le ty"es (eginning !ith ,$ and N$. +n &inMain0 you de'ine a structure o' ty"e #NDC,5SS0 generally li e this: 8;L4LF:: ,ndclass ; Nou then initialiPe the =F 'ields o' the structure and call "egister$lass.

The t!o most im"ortant 'ields in the #NDC,5SS structure are the second and the last. The second 'ield (lpfn&nd4roc* is the address o' a !indo! "rocedure used 'or all !indo!s (ased on this class. +n -3,,%#+N.C0 this !indo! "rocedure is &nd4roc. The last 'ield is the te4t name o' the !indo! class. This can (e !hatever you !ant. +n "rograms that create only one !indo!0 the !indo! class name is commonly set to the name o' the "rogram. The other 'ields descri(e some characteristics o' the !indo! class0 as descri(ed (elo!. ,et7s ta e a loo at each 'ield o' the #NDC,5SS structure in order. The statement ,ndclass.st%le ' 4:&?UPLUF8 ^ 4:&_UPLUF8 ; com(ines t!o G;:(it Iclass styleI identi'iers !ith a C (it!ise %8 o"erator. The #+N.S38.- header 'iles de'ines a !hole collection o' identi'iers !ith the CS "re'i4: #define 4:&_UPLUF8 /"///1 #define 4:&?UPLUF8 /"///2 #define 4:&XPG4_(8=;LD8 /"///H #define 4:&LIL4LX: /"///T #define 4:&D8;L4 /"//2/ #define 4:&4LF::L4 /"//H/ #define 4:&CFUP;(L4 /"//T/ #define 4:&;DXPG4_( /"/1// #define 4:&;D4LD:P /"/2// #define 4:&:F_PI=(: /"/T// #define 4:&IG(PFL=Y;4L=P;( /"1/// #define 4:&IG(PFL=Y;8=;LD8 /"2/// #define 4:&YLDIFL4LF:: /"H/// #define 4:&=KP /"///1//// +denti'iers de'ined in this !ay are o'ten called I(it 'lagsI (ecause each identi'ier sets a single (it in a com"osite value. %nly a 'e! o' these class styles are commonly used. The t!o identi'iers used in -3,,%#+N indicate that all !indo!s created (ased on this class are to (e com"letely re"ainted !henever the horiPontal !indo! siPe (CS9-83D85#* or the vertical !indo! siPe (CS9V83D85#* changes. +' you resiPe -3,,%#+N7s !indo!0 you7ll see that the te4t string is redra!n to (e in the ne! center o' the !indo!. These t!o identi'iers ensure that this ha""ens. #e7ll see shortly ho! the !indo! "rocedure is noti'ied o' this change in !indo! siPe. The second 'ield o' the #NDC,5SS structure is initialiPed (y the statement: ,ndclass.lpfn8ndCroc ' 8ndCroc ; This sets the !indo! "rocedure 'or this !indo! class to &nd4roc0 !hich is the second 'unction in -3,,%#+N.C. This !indo! "rocedure !ill "rocess all messages to all !indo!s created (ased on this !indo! class. +n C0 !hen you use a 'unction name in a statement li e this0 you7re really re'erring to a "ointer to a 'unction. The ne4t t!o 'ields are used to reserve some e4tra s"ace in the class structure and the !indo! structure that #indo!s maintains internally: ,ndclass.c!4lsP"tra ' / ; ,ndclass.c!8ndP"tra ' / ; 5 "rogram can use this e4tra s"ace 'or its o!n "ur"oses. -3,,%#+N does not use this 'eature0 so F is s"eci'ied. %ther!ise0 as the -ungarian notation indicates0 the 'ield !ould (e set to a Icount o' (ytes.I (+7ll use the cb&nd,xtra 'ield in the C-3CK38G "rogram sho!n in Cha"ter D.* The ne4t 'ield is sim"ly the instance handle o' the "rogram (!hich is one o' the "arameters to &inMain*: ,ndclass.h=nstance ' h=nstance ; The statement ,ndclass.h=con ' Load=con (;VLL# =L=&FCCL=4F(=D;) ; sets an icon 'or all !indo!s created (ased on this !indo! class. The icon is a small (itma" "icture that re"resents the "rogram to the user. #hen the "rogram is running0 the icon a""ears in the #indo!s tas (ar and at the le't side o' the "rogram !indo!7s title (ar. ,ater in this (oo 0 you7ll learn ho! to create customiPed icons 'or your #indo!s "rograms. 8ight no!0 !e7ll ta e an easy a""roach and use a "rede'ined icon. To o(tain a handle to a "rede'ined icon0 you call (oad*con !ith the 'irst argument set to N.,,. #hen you7re loading your o!n customiPed icons that are stored in your "rogram7s .3A3 'ile on dis 0 this argument !ould (e set to h*nstance0 the instance handle o' the "rogram. The second argument identi'ies the icon. /or the "rede'ined icons0 this argument is an identi'ier (eginning !ith the "re'i4 +D+ (I+D 'or an iconI* de'ined in #+N.S38.-. The +D+95$$,+C5T+%N icon is sim"ly a little "icture o' a !indo!. The (oad*con 'unction returns a handle to this icon.

#e don7t really care a(out the actual value o' the handle. +t7s sim"ly used to set the value o' the h*con 'ield. This 'ield is de'ined in the #NDC,5SS structure to (e o' ty"e -+C%N0 !hich stands 'or Ihandle to an icon.I The statement ,ndclass.h4ursor ' Load4ursor (;VLL# =L4&FUUD8) ; is similar to the "revious statement. The (oad$ursor 'unction loads a "rede'ined mouse cursor no!n as +DC9588%# and returns a handle to the cursor. This handle is assigned to the b$ursor 'ield o' the #NDC,5SS structure. #hen the mouse cursor a""ears over the client area o' a !indo! that is created (ased on this class0 the cursor (ecomes a small arro!. The ne4t 'ield s"eci'ies the (ac ground color o' the client area o' !indo!s created (ased on this class. The hbr "re'i4 o' the hbr)ac%ground 'ield name stands 'or Ihandle to a (rush.I 5 (rush is a gra"hics term that re'ers to a colored "attern o' "i4els used to 'ill an area. #indo!s has several standard0 or Istoc 0I (rushes. The 2et0toc%>bject call sho!n here returns a handle to a !hite (rush: ,ndclass.h!rIac0+round ' Yet:toc0D!$ect (8?=(P&IUV:?) ; This means that the (ac ground o' the client area o' the !indo! !ill (e solid !hite0 !hich is a common choice. The ne4t 'ield s"eci'ies the !indo! class menu. -3,,%#+N has no a""lication menu0 so the 'ield is set to N.,,: ,ndclass.lps@Kenu;ame ' ;VLL ; /inally the class must (e given a name. /or a small "rogram0 this can (e sim"ly the name o' the "rogram0 !hich is the I-ello#inI string stored in the sz/pp+ame varia(le. ,ndclass.lps@4lass;ame ' s@Fpp;ame ; This string is com"osed o' either 5SC++ characters or .nicode characters de"ending on !hether the .N+C%D3 identi'ier has (een de'ined. #hen all =F 'ields o' the structure have (een initialiPed0 -3,,%#+N registers the !indo! class (y calling "egister$lass. The only argument to the 'unction is a "ointer to the #NDC,5SS structure. 5ctually0 there7s a "egister$lass/ 'unction that ta es a "ointer to the #NDC,5SS5 structure0 and a "egister$lass& 'unction that ta es a "ointer to the #NDC,5SS# structure. #hich 'unction the "rogram uses to register the !indo! class determines !hether messages sent to the !indo! !ill contain 5SC++ te4t or .nicode te4t. No! here7s a "ro(lem: +' you have com"iled the "rogram !ith the .N+C%D3 identi'ier de'ined0 your "rogram !ill call "egister$lass&. That7s 'ine i' you7re running the "rogram on &icroso't #indo!s NT. 1ut i' you7re running the "rogram on #indo!s B^0 the "egister$lass& 'unction is not really im"lemented. There7s an entry "oint 'or the 'unction0 (ut it 6ust returns a Pero 'rom the 'unction call0 indicating an error. This is a good o""ortunity 'or a .nicode "rogram running under #indo!s B^ to in'orm the user o' the "ro(lem and terminate. -ere7s the !ay most o' the "rograms in this (oo !ill handle the "egister$lass 'unction call: if (OUe+ister4lass (],ndclass)) { Kessa+eIo" (;VLL# (PW( ("(his pro+ram re5uires 8indo,s ;(O")# s@Fpp;ame# KI&=4D;PUUDU) ; return / ; The Message)ox& 'unction !or s "ro"erly (ecause it is one o' the 'e! .nicode 'unctions im"lemented in #indo!s B^. This code 'ragment assumes0 o' course0 that "egister$lass is not 'ailing 'or some other reason0 such as a N.,, lpfn&nd4roc 'ield o' the #NDC,5SS structure. The 2et(ast,rror 'unction hel"s you determine the cause o' the error in cases li e this. 2et(ast,rror is a general:"ur"ose 'unction in #indo!s to get e4tended error in'ormation !hen a 'unction call 'ails. The documentation o' the various 'unctions !ill indicate !hether you can use 2et(ast,rror to o(tain this in'ormation. +n the case o' calling "egister$lass& in #indo!s B^0 2et(ast,rror returns =;F. Nou can loo in #+N388%8.- to see that the value =;F corres"onds to the identi'ier 388%89C5,,9N%T9+&$,3&3NT3D. Nou can also loo u" the error in 34latform 0'53&indows )ase 0ervices3'ebugging and ,rror -andling3,rror $odes30#stem ,rrors - +umerical >rder. Some #indo!s "rogrammers li e to chec the return value o' every 'unction call 'or errors. This certainly ma es some sense0 and here7s !hy: +7m sure you7re 'amiliar !ith the rule that you al!ays0 al!ays chec 'or an error !hen you7re allocating memory. #ell0 many #indo!s 'unctions need to allocate some memory. /or e4am"le0 "egister$lass needs to allocate memory to store in'ormation a(out the !indo! class. So you should (e chec ing the 'unction regardless. %n the other hand0 i' "egister$lass 'ails (ecause it can7t allocate the memory it needs0 #indo!s has "ro(a(ly already ground to a halt. + do a minimum o' error chec ing in the sam"le "rograms in this (oo . This is not (ecause + don7t thin error chec ing is a good idea0 (ut (ecause it !ould distract 'rom !hat the "rograms are su""osed to illustrate. /inally0 a historical note: +n some sam"le #indo!s "rograms0 you might see the 'ollo!ing code in &inMain:

if (OhCrev=nstance) { ,ndclass.c!:t%le ' 4:&?UPLUF8 ^ 4:&_UPLUF8 ; [other wndclass initialization] Ue+ister4lass (],ndclass) ; This comes under the category o' Iold ha(its die hard.I +n =C:(it versions o' #indo!s0 i' you started u" a ne! instance o' a "rogram that !as already running0 the h4rev*nstance "arameter to &inMain !ould (e the instance handle o' the "revious instance. To save memory0 t!o or more instances !ere allo!ed to share the same !indo! class. Thus0 the !indo! class !as registered only i' h4rev*nstance !as N.,,0 indicating that no other instances o' the "rogram !ere running. +n G;:(it versions o' #indo!s0 h4rev*nstance is al!ays N.,,. This code !ill still !or "ro"erly0 (ut it7s not necessary to chec h4rev*nstance.

Creating the Window


The !indo! class de'ines general characteristics o' a !indo!0 thus allo!ing the same !indo! class to (e used 'or creating many di''erent !indo!s. #hen you go ahead and create a !indo! (y calling $reate&indow0 you s"eci'y more detailed in'ormation a(out the !indo!. $rogrammers ne! to #indo!s are sometimes con'used a(out the distinction (et!een the !indo! class and the !indo! and !hy all the characteristics o' a !indo! can7t (e s"eci'ied in one shot. 5ctually0 dividing the in'ormation in this !ay is )uite convenient. /or e4am"le0 all "ush:(utton !indo!s are created (ased on the same !indo! class. The !indo! "rocedure associated !ith this !indo! class is located inside #indo!s itsel'0 and it is res"onsi(le 'or "rocessing ey(oard and mouse in"ut to the "ush (utton and de'ining the (utton7s visual a""earance on the screen. 5ll "ush (uttons !or the same !ay in this res"ect. 1ut not all "ush (uttons are the same. They almost certainly have di''erent siPes0 di''erent locations on the screen0 and di''erent te4t strings. These latter characteristics are "art o' the !indo! de'inition rather than the !indo! class de'inition. #hile the in'ormation "assed to the "egister$lass 'unction is s"eci'ied in a data structure0 the in'ormation "assed to the $reate&indow 'unction is s"eci'ied as se"arate arguments to the 'unction. -ere7s the $reate&indow call in -3,,%#+N.C0 com"lete !ith comments identi'ying the 'ields: h,nd ' 4reate8indo, (s@Fpp;ame# 22 ,indo, class name (PW( ("(he ?ello Cro+ram")# 22 ,indo, caption 8:&D_PULFCCPL8=;LD8# 22 ,indo, st%le 48&V:PLP6FVL(# 22 initial " position 48&V:PLP6FVL(# 22 initial % position 48&V:PLP6FVL(# 22 initial " si@e 48&V:PLP6FVL(# 22 initial % si@e ;VLL# 22 parent ,indo, handle ;VLL# 22 ,indo, menu handle h=nstance# 22 pro+ram instance handle ;VLL) ; 22 creation parameters 5t this "oint + !on7t (other to mention that there are actually a $reate&indow/ 'unction and a $reate&indow& 'unction0 !hich treat the 'irst t!o "arameters to the 'unction as 5SC++ or .nicode0 res"ectively. The argument mar ed I!indo! class nameI is sz/pp+ame0 !hich contains the string I-ello#inISthe name o' the !indo! class the "rogram 6ust registered. This is ho! the !indo! !e7re creating is associated !ith a !indo! class. The !indo! created (y this "rogram is a normal overla""ed !indo!. +t !ill have a title (arL a system menu (utton to the le't o' the title (arL a thic !indo!:siPing (orderL and minimiPe0 ma4imiPe0 and close (uttons to the right o' the title (ar. That7s a standard style 'or !indo!s0 and it has the name #S9%V38,5$$3D#+ND%#0 !hich a""ears as the I!indo! styleI "arameter in $reate&indow. +' you loo in #+N.S38.-0 you7ll 'ind that this style is a com(ination o' several (it 'lags: #define 8:&D_PULFCCPL8=;LD8 (8:&D_PULFCCPL ^ \ 8:&4FC(=D; ^ \ 8:&:G:KP;V ^ \ 8:&(?=4X6UFKP ^ \

8:&K=;=K=\PIDW ^ \ 8:&KFW=K=\PIDW) The I!indo! ca"tionI is the te4t that !ill a""ear in the title (ar o' the !indo!. The arguments mar ed Iinitial 4 "ositionI and Iinitial y "ositionI s"eci'y the initial "osition o' the u""er le't corner o' the !indo! relative to the u""er le't corner o' the screen. 1y using the identi'ier C#9.S3D3/5.,T 'or these "arameters0 !e are indicating that !e !ant #indo!s to use the de'ault "osition 'or an overla""ed !indo!. (C#9.S3D3/5.,T is de'ined as F4^FFFFFFF.* 1y de'ault0 #indo!s "ositions successive ne!ly created !indo!s at ste""ed horiPontal and vertical o''sets 'rom the u""er le't corner o' the dis"lay. Similarly0 the Iinitial 4 siPeI and Iinitial y siPeI arguments s"eci'y the initial !idth and height o' the !indo!. The C#9.S3D3/5.,T identi'ier again indicates that !e !ant #indo!s to use a de'ault siPe 'or the !indo!. The argument mar ed I"arent !indo! handleI is set to N.,, !hen creating a Ito":levelI !indo!0 such as an a""lication !indo!. Normally0 !hen a "arent:child relationshi" e4ists (et!een t!o !indo!s0 the child !indo! al!ays a""ears on the sur'ace o' its "arent. 5n a""lication !indo! a""ears on the sur'ace o' the des to" !indo!0 (ut you don7t need to 'ind out the des to" !indo!7s handle to call $reate&indow. The I!indo! menu handleI is also set to N.,, (ecause the !indo! has no menu. The I"rogram instance handleI is set to the instance handle "assed to the "rogram as a "arameter o' &inMain. /inally0 a Icreation "arametersI "ointer is set to N.,,. Nou could use this "arameter to "oint to some data that you might later !ant to re'erence in your "rogram. The $reate&indow call returns a handle to the created !indo!. This handle is saved in the varia(le hwnd0 !hich is de'ined to (e o' ty"e -#ND (Ihandle to a !indo!I*. 3very !indo! in #indo!s has a handle. Nour "rogram uses the handle to re'er to the !indo!. &any #indo!s 'unctions re)uire hwnd as an argument so that #indo!s no!s !hich !indo! the 'unction a""lies to. +' a "rogram creates many !indo!s0 each has a di''erent handle. The handle to a !indo! is one o' the most im"ortant handles that a #indo!s "rogram ("ardon the e4"ression* handles.

Dis-la(ing the Window


5'ter the $reate&indow call returns0 the !indo! has (een created internally in #indo!s. #hat this means (asically is that #indo!s has allocated a (loc o' memory to hold all the in'ormation a(out the !indo! that you s"eci'ied in the $reate&indow call0 "lus some other in'ormation0 all o' !hich #indo!s can 'ind later (ased on the !indo! handle. -o!ever0 the !indo! does not yet a""ear on the video dis"lay. T!o more calls are needed. The 'irst is :ho,8indo, (h,nd# i4md:ho,) ; The 'irst argument is the handle to the !indo! 6ust created (y $reate&indow. The second argument is the i$md0how value "assed as a "arameter to &inMain. This determines ho! the !indo! is to (e initially dis"layed on the screen0 !hether it7s normal0 minimiPed0 or ma4imiPed. The user "ro(a(ly selected a "re'erence !hen adding the "rogram to the Start menu. The value you receive 'rom &inMain and "ass to 0how&indow is S#9S-%#N%8&5, i' the !indo! is dis"layed normally0 S#9S-%#&5A+&+X3D i' the !indo! is to (e ma4imiPed0 and S#9S-%#&+NN%5CT+V3 i' the !indo! is 6ust to (e dis"layed in the tas (ar. The 0how&indow 'unction "uts the !indo! on the dis"lay. +' the second argument to 0how&indow is S#9S-%#N%8&5,0 the client area o' the !indo! is erased !ith the (ac ground (rush s"eci'ied in the !indo! class. The 'unction call Vpdate8indo, (h,nd) ; then causes the client area to (e "ainted. +t accom"lishes this (y sending the !indo! "rocedure (that is0 the &nd4roc 'unction in -3,,%#+N.C* a #&9$5+NT message. #e7ll soon e4amine ho! &nd4roc deals !ith this message.

%he Message &oo5'ter the 1pdate&indow call0 the !indo! is 'ully visi(le on the video dis"lay. The "rogram must no! ma e itsel' ready to read ey(oard and mouse in"ut 'rom the user. #indo!s maintains a Imessage )ueueI 'or each #indo!s "rogram currently running under #indo!s. #hen an in"ut event occurs0 #indo!s translates the event into a ImessageI that it "laces in the "rogram7s message )ueue. 5 "rogram retrieves these messages 'rom the message )ueue (y e4ecuting a (loc o' code no!n as the Imessage loo"I: ,hile (YetKessa+e (]ms+# ;VLL# /# /))

(ranslateKessa+e (]ms+) ; LispatchKessa+e (]ms+) ;

The msg varia(le is a structure o' ty"e &S20 !hich is de'ined in the #+N.S38.- header 'ile li e this: t%pedef struct ta+K:Y { ?8;L h,nd ; V=;( messa+e ; 8CFUFK ,Caram ; LCFUFK lCaram ; L8DUL time ; CD=;( pt ; K:Y# 3 CK:Y ; The $%+NT data ty"e is yet another structure0 de'ined in the #+ND3/.- header 'ile li e this: t%pedef struct ta+CD=;( { LD;Y " ; LD;Y % ; CD=;(# 3 CCD=;(; The 2etMessage call that (egins the message loo" retrieves a message 'rom the message )ueue: YetKessa+e (]ms+# ;VLL# /# /) This call "asses to #indo!s a "ointer to a &S2 structure named msg. The second0 third0 and 'ourth arguments are set to N.,, or F to indicate that the "rogram !ants all messages 'or all !indo!s created (y the "rogram. #indo!s 'ills in the 'ields o' the message structure !ith the ne4t message 'rom the message )ueue. The 'ields o' this structure are: hwnd The handle to the !indo! !hich the message is directed to. +n the -3,,%#+N "rogram0 this is the same as the hwnd value returned 'rom $reate&indow0 (ecause that7s the only !indo! the "rogram has. message The message identi'ier. This is a num(er that identi'ies the message. /or each message0 there is a corres"onding identi'ier de'ined in the #indo!s header 'iles (most o' them in #+N.S38.-* that (egins !ith the identi'ier #& (I!indo! messageI*. /or e4am"le0 i' you "osition the mouse "ointer over -3,,%#+N7s client area and "ress the le't mouse (utton0 #indo!s !ill "ut a message in the message )ueue !ith a message 'ield e)ual to #&9,1.TT%ND%#N0 !hich is the value F4F;F=. w4aram 5 G;:(it Imessage "arameter0I the meaning and value o' !hich de"end on the "articular message. l4aram 5nother G;:(it message "arameter de"endent on the message. time The time the message !as "laced in the message )ueue. pt The mouse coordinates at the time the message !as "laced in the message )ueue. +' the message 'ield o' the message retrieved 'rom the message )ueue is anything e4ce"t #&9@.+T (!hich e)uals F4FF=;*0 2etMessage returns a nonPero value. 5 #&9@.+T message causes 2etMessage to return F. The statement: (ranslateKessa+e (]ms+) ; "asses the msg structure (ac to #indo!s 'or some ey(oard translation. (+7ll discuss this more in Cha"ter C.* The statement LispatchKessa+e (]ms+) ; again "asses the msg structure (ac to #indo!s. #indo!s then sends the message to the a""ro"riate !indo! "rocedure 'or "rocessing. #hat this means is that #indo!s calls the !indo! "rocedure. +n -3,,%#+N0 the !indo! "rocedure is &nd4roc. 5'ter &nd4roc "rocesses the message0 it returns control to #indo!s0 !hich is still servicing the 'ispatchMessage call. #hen #indo!s returns to -3,,%#+N 'ollo!ing the 'ispatchMessage call0 the message loo" continues !ith the ne4t 2etMessage call.

%he Window Proced$re

5ll that +7ve descri(ed so 'ar is really 6ust overhead. The !indo! class has (een registered0 the !indo! has (een created0 the !indo! has (een dis"layed on the screen0 and the "rogram has entered a message loo" to retrieve messages 'rom the message )ueue. The real action occurs in the !indo! "rocedure. The !indo! "rocedure determines !hat the !indo! dis"lays in its client area and ho! the !indo! res"onds to user in"ut. +n -3,,%#+N0 the !indo! "rocedure is the 'unction named &nd4roc. 5 !indo! "rocedure can have any name (as long as it doesn7t con'lict !ith some other name0 o' course*. 5 #indo!s "rogram can contain more than one !indo! "rocedure. 5 !indo! "rocedure is al!ays associated !ith a "articular !indo! class that you register (y calling "egister$lass. The $reate&indow 'unction creates a !indo! (ased on a "articular !indo! class. &ore than one !indo! can (e created (ased on the same !indo! class. 5 !indo! "rocedure is al!ays de'ined li e this: LUP:VL( 4FLLIF4X 8ndCroc (?8;L h,nd# V=;( messa+e# 8CFUFK ,Caram# LCFUFK lCaram) The 'our "arameters to the !indo! "rocedure are identical to the 'irst 'our 'ields o' the &S2 structure. The 'irst "arameter is hwnd0 the handle to the !indo! receiving the message. This is the same handle returned 'rom the $reate&indow 'unction. /or a "rogram li e -3,,%#+N0 !hich creates only one !indo!0 this is the only !indo! handle the "rogram no!s a(out. +' a "rogram creates multi"le !indo!s (ased on the same !indo! class (and hence the same !indo! "rocedure*0 hwnd identi'ies the "articular !indo! receiving the message. The second "arameter is the same as the message 'ield in the &S2 structure. +t7s a num(er that identi'ies the message. The last t!o "arameters are G;:(it message "arameters that "rovide more in'ormation a(out the message. #hat these "arameters contain is s"eci'ic to each ty"e o' message. Sometimes a message "arameter is t!o =C:(it values stuc together0 and sometimes a message "arameter is a "ointer to a te4t string or to a data structure. $rograms generally don7t call !indo! "rocedures directly. The !indo! "rocedure is almost al!ays called 'rom #indo!s itsel'. 5 "rogram can indirectly call its o!n !indo! "rocedure (y calling a 'unction named 0endMessage0 !hich !e7ll e4amine in later cha"ters.

Processing the Messages


3very message that a !indo! "rocedure receives is identi'ied (y a num(er0 !hich is the message "arameter to the !indo! "rocedure. The #indo!s header 'ile #+N.S38.- de'ines identi'iers (eginning !ith the "re'i4 #& (I!indo! messageI* 'or each ty"e o' message. 2enerally0 #indo!s "rogrammers use a switch and case construction to determine !hat message the !indo! "rocedure is receiving and ho! to "rocess it accordingly. #hen a !indo! "rocedure "rocesses a message0 it should return F 'rom the !indo! "rocedure. 5ll messages that a !indo! "rocedure chooses not to "rocess must (e "assed to a #indo!s 'unction named 'ef&indow4roc. The value returned 'rom 'ef&indow4roc must (e returned 'rom the !indo! "rocedure. +n -3,,%#+N0 &nd4roc chooses to "rocess only three messages: #&9C835T30 #&9$5+NT0 and #&9D3ST8%N. The !indo! "rocedure is structured li e this: s,itch (iKs+) { case 8K&4UPF(P 7 [process WM_CRE !E messa"e] return / ; case 8K&CF=;( 7 [process WM_# $%! messa"e] return / ; case 8K&LP:(UDG 7 [process WM_&E'!R() messa"e] return / ; return Lef8indo,Croc (h,nd# iKs+# ,Caram# lCaram) ; +t is im"ortant to call 'ef&indow4roc 'or de'ault "rocessing o' all messages that your !indo! "rocedure does not "rocess. %ther!ise (ehavior regarded as normal0 such as (eing a(le to terminate the "rogram0 !ill not !or .

Pla(ing a ,o$nd File


The very 'irst message that a !indo! "rocedure receivesSand the 'irst that -3,,%#+N7s &nd4roc chooses to "rocessSis #&9C835T3. &nd4roc receives this message !hile #indo!s is "rocessing the $reate&indow 'unction in &inMain. That is0 !hen -3,,%#+N calls $reate&indow0 #indo!s does !hat it has to do and0 in the "rocess0 #indo!s calls &nd4roc !ith the 'irst argument set to the !indo! handle and the second argument set to #&9C835T3 (the value =*. &nd4roc "rocesses the #&9C835T3 message and returns controls (ac to #indo!s. #indo!s can then return to -3,,%#+N 'rom the $reate&indow call to continue 'urther "rogress in &inMain. %'ten a !indo! "rocedure "er'orms one:time !indo! initialiPation during #&9C835T3 "rocessing. -3,,%#+N chooses to "rocess this message (y "laying a !ave'orm sound 'ile named -3,,%#+N.#5V. +t does this using the sim"le 4la#0ound 'unction0 !hich is descri(ed in 34latform 0'532raphics and Multimedia 0ervices3Multimedia /udio3&aveform /udio and documented in 34latform 0'532raphics and Multimedia 0ervices3Multimedia "eference3Multimedia !unctions. The 'irst argument to 4la#0ound is the name o' a !ave'orm 'ile. (+t could also (e a sound alias name de'ined in the Sounds section o' the Control $anel or a "rogram resource.* The second argument is used only i' the sound 'ile is a resource. The third argument s"eci'ies a cou"le o' o"tions. +n this case0 +7ve indicated that the 'irst argument is a 'ilename and that the sound is to (e "layed asynchronouslySthat is0 the 4la#0ound 'unction call is to return as soon as the sound 'ile starts "laying !ithout !aiting 'or it to com"lete. That !ay the "rogram can continue !ith its initialiPation. &nd4roc concludes #&9C835T3 "rocessing (y returning F 'rom the !indo! "rocedure.

%he WM@P>#)% Message


The second message that &nd4roc "rocesses is #&9$5+NT. This message is e4tremely im"ortant in #indo!s "rogramming. +t in'orms a "rogram !hen "art or all o' the !indo!7s client area is IinvalidI and must (e Iu"dated0I !hich means that it must (e redra!n or I"ainted.I -o! does a client area (ecome invalidW #hen the !indo! is 'irst created0 the entire client area is invalid (ecause the "rogram has not yet dra!n anything on the !indo!. The 'irst #&9$5+NT message (!hich normally occurs !hen the "rogram calls 1pdate&indow in &inMain* directs the !indo! "rocedure to dra! something on the client area. #hen you resiPe -3,,%#+N7s !indo!0 the client area (ecomes invalid. Nou7ll recall that the st#le 'ield o' -3,,%#+N7s wndclass structure !as set to the 'lags CS9-83D85# and CS9V83D85#. This directs #indo!s to invalidate the !hole !indo! !hen the siPe changes. The !indo! "rocedure then receives a #&9$5+NT message. #hen you minimiPe -3,,%#+N and then restore the !indo! again to its "revious siPe0 #indo!s does not save the contents o' the client area. .nder a gra"hical environment0 this !ould (e too much data to retain. +nstead0 #indo!s invalidates the !indo!. The !indo! "rocedure receives a #&9$5+NT message and itsel' restores the contents o' its !indo!. #hen you move !indo!s around the screen so that they overla"0 #indo!s does not save the area o' a !indo! covered (y another !indo!. #hen that area o' the !indo! is later uncovered0 it is 'lagged as invalid. The !indo! "rocedure receives a #&9$5+NT message to re"aint the contents o' the !indo!. #&9$5+NT "rocessing almost al!ays (egins !ith a call to )egin4aint: hdc ' Ie+inCaint (h,nd# ]ps) ; and ends !ith a call to ,nd4aint: PndCaint (h,nd# ]ps) ; +n (oth cases0 the 'irst argument is a handle to the "rogram7s !indo!0 and the second argument is a "ointer to a structure o' ty"e $5+NTST8.CT. The $5+NTST8.CT structure contains some in'ormation that a !indo! "rocedure can use 'or "ainting the client area. +7ll discuss the 'ields o' this structure in the ne4t cha"terL 'or no!0 !e7ll 6ust use it in the )egin4aint and ,nd4aint 'unctions. During the )egin4aint call0 #indo!s erases the (ac ground o' the client area i' it hasn7t (een erased already. +t erases the (ac ground using the (rush s"eci'ied in the hbr)ac%ground 'ield o' the #NDC,5SS structure used to register the !indo! class. +n the case o' -3,,%#+N0 this is a stoc !hite (rush0 !hich means that #indo!s erases the (ac ground o' the !indo! (y coloring it !hite. The )egin4aint call validates the entire client area and returns a Ihandle to a device conte4t.I 5 device conte4t re'ers to a "hysical out"ut device (such as a video dis"lay* and its

device driver. Nou need the device conte4t handle to dis"lay te4t and gra"hics in the client area o' a !indo!. .sing the device conte4t handle returned 'rom )egin4aint0 you cannot dra! outside the client area0 even i' you try. ,nd4aint releases the device conte4t handle so that it is no longer valid. +' a !indo! "rocedure does not "rocess #&9$5+NT messages (!hich is very rare*0 they must (e "assed on to 'ef&indow4roc. 'ef&indow4roc sim"ly calls )egin4aint and ,nd4aint in succession so that the client area is validated. 5'ter &nd4roc calls )egin4aint0 it calls 2et$lient"ect: Yet4lientUect (h,nd# ]rect) ; The 'irst argument is the handle to the "rogram7s !indo!. The second argument is a "ointer to a rectangle structure o' ty"e 83CT. This structure has 'our ,%N2 'ields named left0 top0 right0 and bottom. The 2et$lient"ect 'unction sets these 'our 'ields to the dimensions o' the client area o' the !indo!. The left and top 'ields are al!ays set to F. Thus0 the right and bottom 'ields re"resent the !idth and height o' the client area in "i4els. &nd4roc doesn7t do anything !ith this 83CT structure e4ce"t "ass a "ointer to it as the 'ourth argument to 'raw.ext: Lra,(e"t (hdc# (PW( ("?ello# 8indo,s STO")# 91# ]rect# L(&:=;YLPL=;P ^ L(&4P;(PU ^ L(&_4P;(PU) ; 'raw.ext0 as the name im"lies0 dra!s te4t. 1ecause this 'unction dra!s something0 the 'irst argument is a handle to the device conte4t returned 'rom )egin4aint. The second argument is the te4t to dra!0 and the third argument is set to := to indicate that the te4t string is terminated !ith a Pero character. The last argument to 'raw.ext is a series o' (it 'lags de'ined in #+N.S38.-. (5lthough 'raw.ext seems to (e a 2D+ 'unction call (ecause it dis"lays out"ut0 it7s actually considered "art o' the .ser module (ecause it7s a 'airly high:level dra!ing 'unction. The 'unction is documented in 34latform 0'532raphics and Multimedia 0ervices32'*3!onts and .ext.* The 'lags indicate that the te4t should (e dis"layed as a single line centered horiPontally and vertically !ithin the rectangle s"eci'ied (y the 'ourth argument. This 'unction call thus causes the string I-ello0 #indo!s B^JI to (e dis"layed centered in the client area. #henever the client area (ecomes invalid (as it does !hen you change the siPe o' the !indo!*0 &nd4roc receives a ne! #&9$5+NT message. &nd4roc o(tains the u"dated !indo! siPe (y calling 2et$lient"ect and again dis"lays the te4t in the ne4t center o' the !indo!.

%he WM@D0,%RO8 Message


The #&9D3ST8%N message is another im"ortant message. This message indicates that #indo!s is in the "rocess o' destroying a !indo! (ased on a command 'rom the user. The message is a result o' the user clic ing on the Close (utton or selecting Close 'rom the "rogram7s system menu. (,ater in this cha"ter0 +7ll discuss in more detail ho! the #&9D3ST8%N message gets generated.* -3,,%#+N res"onds to the #&9D3ST8%N message in a standard !ay (y calling CostJuitKessa+e (/) ; This 'unction inserts a #&9@.+T message in the "rogram7s message )ueue. + mentioned earlier that 2etMessage returns nonPero 'or any message other than #&9@.+T that it retrieves 'rom the message )ueue. #hen 2etMessage retrieves a #&9@.+T message0 2etMessage returns F. This causes &inMain to dro" out o' the message loo". The "rogram then e4ecutes the 'ollo!ing statement: return ms+.,Caram ; The w4aram 'ield o' the structure is the value "assed to the 4ost?uitMessage 'unction (generally F*. The return statement e4its 'rom &inMain and terminates the "rogram.

%he Windows Programming '$rdles 3ven !ith my e4"lanation o' -3,,%#+N0 the structure and !or ings o' the "rogram are "ro(a(ly still )uite mysterious. +n a short C "rogram !ritten 'or a character:mode environment0 the entire "rogram might (e contained in the main 'unction. +n -3,,%#+N0 &inMain contains only "rogram overhead necessary to

register the !indo! class0 create the !indo!0 and retrieve and dis"atch messages 'rom the message )ueue. 5ll the real action o' the "rogram occurs in the !indo! "rocedure. +n -3,,%#+N0 this action is not muchS&nd4roc sim"ly "lays a sound 'ile and dis"lays a te4t string in its !indo!. 1ut in later cha"ters0 you7ll 'ind that almost everything a #indo!s "rogram does is in res"onse to a message to a !indo! "rocedure. This is one o' the ma6or conce"tual hurdles you must lea" to (egin !riting #indo!s "rograms. DonXt Call Me. #Xll Call 8o$ Programmers are well acK$ainted with the idea of calling on the o-erating s(stem to do something. /or e4am"le0 C "rogrammers use the "rint' 'unction to dis"lay on the console. The "rint' 'unction is im"lemented !ith a call to the o"erating system to dis"lay out"ut on de'ault out"ut device. No "ro(lem. 1ut #indo!s is di''erent. 5lthough #indo!s has a cou"le thousand 'unction calls0 #indo!s also ma es calls to #our "rogram0 s"eci'ically to the !indo! "rocedure !e have called &nd4roc. The !indo! "rocedure is associated !ith a !indo! class that the "rogram registers (y calling "egister$lass. 5 !indo! that is created (ased on this !indo! class uses this !indo! "rocedure 'or "rocessing all messages to the !indo!. #indo!s sends a message to the !indo! (y calling the !indo! "rocedure. #indo!s calls &nd4roc !hen a !indo! is 'irst created. #indo!s calls &nd4roc !hen the !indo! is eventually destroyed. #indo!s calls &nd4roc !hen the !indo! has (een resiPed or moved or minimiPed. #indo!s calls &nd4roc !hen a user clic s on the !indo! !ith the mouse. #indo!s calls &nd4roc !hen characters are ty"ed 'rom the ey(oard. #indo!s calls &nd4roc !hen an item has (een selected 'rom a menu. #indo!s calls &nd4roc !hen a scroll (ar is mani"ulated or clic ed !ith the mouse. #indo!s calls &nd4roc to tell it !hen it must re"aint its client area. 5ll these calls to &nd4roc are in the 'orm o' messages. +n most #indo!s "rograms0 the (ul o' the "rogram is dedicated to handling these messages. The messages that #indo!s can send to a "rogram are generally identi'ied !ith names that (egin !ith the letters #& and are de'ined in the #+N.S38.- header 'ile. 5ctually0 the idea o' a routine !ithin a "rogram that is called 'rom outside the "rogram is not unheard o' in character:mode "rogramming. The signal 'unction in

C can tra" a Ctrl:C (rea or other interru"ts 'rom the o"erating system. %ld "rograms !ritten 'or &S:D%S o'ten tra""ed hard!are interru"ts. 1ut in #indo!s this conce"t is e4tended to cover everything. 3verything that ha""ens to a !indo! is relayed to the !indo! "rocedure in the 'orm o' a message. The !indo! "rocedure then res"onds to this message in some !ay or "asses the message to 'ef&indow4roc 'or de'ault "rocessing. The w4aram and l4aram "arameters to the !indo! "rocedure are not used in -3,,%#+N e4ce"t as "arameters to 'ef&indow4roc. These "arameters give the !indo! "rocedure additional in'ormation a(out the message. The meaning o' the "arameters is message:de"endent. ,et7s loo at an e4am"le. #henever the client area o' a !indo! changes in siPe0 #indo!s calls that !indo!7s !indo! "rocedure. The hwnd "arameter to the !indo! "rocedure is the handle o' the !indo! changing in siPe. (Remem/er that one window -roced$re co$ld /e handling messages for m$lti-le windows that were created /ased on the same window classA %he hwnd -arameter lets the window -roced$re +now which window is receiving the message .* The message "arameter is #&9S+X3. The w4aram "arameter 'or a #&9S+X3 message is the value S+X3983ST%83D0 S+X39&+N+&+X3D0 S+X39&5A+&+X3D0 S+X39&5AS-%#0 or S+X39&5A-+D3 (de'ined in the #+N.S38.- header 'ile as the num(ers F through >*. That is0 the w4aram "arameter indicates !hether the !indo! is (eing changed to a nonminimiPed or nonma4imiPed siPe0 (eing minimiPed0 (eing ma4imiPed0 or (eing hidden. The l4aram "arameter contains the ne! siPe o' the !indo!. The ne! !idth (a =C: (it value* and the ne! height (a =C:(it value* are stuc together in the G;:(it l4aram. The #+ND3/.- header 'ile de'ines some handy macros that hel" you e4tract these t!o values 'rom l4aram. #e !ill see that later. Sometimes messages generate other messages as a result o' 'ef&indow4roc "rocessing. /or e4am"le0 su""ose you run -3,,%#+N and you eventually clic the Close (utton0 or su""ose you select Close 'rom the system menu using either the ey(oard or the mouse. 'ef&indow4roc "rocesses this ey(oard or mouse in"ut. #hen it detects that you have selected the Close o"tion0 it sends a #&9SNSC%&&5ND message to the !indo! "rocedure. &nd4roc "asses this message to 'ef&indow4roc. 'ef&indow4roc res"onds (y sending a #&9C,%S3 message to the !indo! "rocedure. &nd4roc again "asses this message to 'ef&indow4roc. 'ef&indow4roc res"onds to the #&9C,%S3 message (y

calling 'estro#&indow. 'estro#&indow causes #indo!s to send a #&9D3ST8%N message to the !indo! "rocedure. &nd4roc 'inally res"onds to this message (y calling 4ost?uitMessage to "ut a #&9@.+T message in the message )ueue. This message causes the message loo" in &inMain to terminate and the "rogram to end. [$e$ed and )onK$e$ed Messages +7ve tal ed a(out #indo!s sending messages to a !indo!0 !hich means that #indo!s calls the !indo! "rocedure. 1ut a #indo!s "rogram also has a message loo" that retrieves messages 'rom a message )ueue (y calling 2etMessage and dis"atches these messages to the !indo! "rocedure (y calling 'ispatchMessage. So0 does a #indo!s "rogram "oll 'or messages (much li e a character:mode "rogram "olling 'or ey(oard in"ut* and then route these messages to some locationW %r does it receive messages directly 'rom outside the "rogramW #ell0 (oth. &essages can (e either I)ueuedI or Inon)ueued.I The )ueued messages are those that are "laced in a "rogram7s message )ueue (y #indo!s. +n the "rogram7s message loo"0 the messages are retrieved and dis"atched to the !indo! "rocedure. The non:)ueued messages are the results o' calls (y #indo!s (%S* directly to the !indo! "rocedure. +t is said that )ueued messages are I"ostedI to a message )ueue and that non:)ueued messages are IsentI to the !indo! "rocedure. +n any case0 the !indo! "rocedure gets all the messagesS(oth )ueued and non:)ueuedS'or the !indo!. The !indo! "rocedure is Imessage centralI 'or the !indo!. The )ueued messages are "rimarily those that result 'rom user in"ut in the 'orm o' eystro es (such as the #&9K3ND%#N and #&9K3N.$ messages*0 characters that result 'rom eystro es (#&9C-58*0 mouse movement (#&9&%.S3&%V3*0 and mouse:(utton clic s (#&9,1.TT%ND%#N*. @ueued messages also include the timer message (#&9T+&38*0 the re"aint message (#&9$5+NT*0 and the )uit message (#&9@.+T*. The non)ueued messages are everything else. Non)ueued messages o'ten result 'rom calling certain #indo!s 'unctions. /or e4am"le0 !hen &inMain calls $reate&indow0 #indo!s creates the !indo! and in the "rocess sends the !indo! "rocedure a #&9C835T3 message. #hen &inMain calls 0how&indow0 #indo!s sends the !indo! "rocedure #&9S+X3 and #&9S-%##+ND%# messages. #hen &inMain calls 1pdate&indow0 #indo!s sends the !indo!

"rocedure a #&9$5+NT message. @ueued messages signaling ey(oard or mouse in"ut can also result in non:)ueued messages. /or e4am"le0 !hen you select a menu item !ith the ey(oard or mouse0 the ey(oard or mouse message is )ueued (ut the eventual #&9C%&&5ND message indicating that a menu item has (een selected is non:)ueued. This "rocess is o(viously com"le40 (ut 'ortunately most o' the com"le4ity is #indo!s7 "ro(lem rather than our "rogram7s. /rom the "ers"ective o' the !indo! "rocedure0 these messages come through in an orderly and synchroniPed manner. The !indo! "rocedure can do something !ith these messages or ignore them. #hen + say that messages come through in an orderly and synchroniPed manner0 + mean 'irst that messages are not li+e hardware interr$-ts. #hile "rocessing one message in a !indo! "rocedure0 the "rogram !ill not (e suddenly interru"ted (y another message. 5lthough #indo!s "rograms can have multi"le threads o' e4ecution0 each thread7s message )ueue handles messages 'or only the !indo!s !hose !indo! "rocedures are e4ecuted in that thread. +n other !ords0 the message loo" and the !indo! "rocedure do not run concurrently. #hen a message loo" retrieves a message 'rom its message )ueue and calls 'ispatchMessage to send the message o'' to the !indo! "rocedure0 'ispatchMessage does not return until the !indo! "rocedure has returned control (ac to #indo!s. -o!ever0 the !indo! "rocedure could call a 'unction that sends the !indo! "rocedure another message0 in !hich case the !indo! "rocedure must 'inish "rocessing the second message (e'ore the 'unction call returns0 at !hich time the !indo! "rocedure "roceeds !ith the original message. /or e4am"le0 !hen a !indo! "rocedure calls 1pdate&indow0 #indo!s calls the !indo! "rocedure !ith a #&9$5+NT message. #hen the !indo! "rocedure 'inishes "rocessing the #&9$5+NT message0 the 1pdate&indow call !ill return controls (ac to the !indo! "rocedure. This means that !indo! "rocedures must (e reentrant. +n most cases0 this doesn7t cause "ro(lems0 (ut you should (e a!are o' it. /or e4am"le0 su""ose you set a static varia(le in the !indo! "rocedure !hile "rocessing a message and then you call a #indo!s 'unction. ."on return 'rom that 'unction0 can you (e assured that the varia(le is still the sameW Not necessarilySnot i' the "articular #indo!s 'unction you call generated another message and the !indo! "rocedure changes the varia(le !hile "rocessing that second message. This is one o' the reasons !hy

certain 'orms o' com"iler o"timiPation must (e turned o'' !hen com"iling #indo!s "rograms. +n many cases0 the !indo! "rocedure must retain in'ormation it o(tains in one message and use it !hile "rocessing another message. This in'ormation must (e saved in varia(les de'ined as static in the !indo! "rocedure0 or saved in glo(al varia(les. %' course0 you7ll get a much (etter 'eel 'or all o' this in later cha"ters as the !indo! "rocedures are e4"anded to "rocess more messages. 6et #n and O$t Fast #indo!s B^ and #indo!s NT are "reem"tive multitas ing environments. This means that as one "rogram is doing a lengthy 6o(0 #indo!s can allo! the user to s!itch control to another "rogram. This is a good thing0 and it is one advantage o' the current versions o' #indo!s over the older =C:(it versions. -o!ever0 (ecause o' the !ay that #indo!s is structured0 this "reem"tive multitas ing does not al!ays !or the !ay you might li e. /or e4am"le0 su""ose your "rogram s"ends a minute or t!o "rocessing a "articular message. Nes0 the user can s!itch to another "rogram. 1ut the user cannot do anything !ith #our "rogram. The user cannot move your "rogram7s !indo!0 resiPe/ minimiPe/close it. That7s (ecause your !indo! "rocedure is (usy doing a lengthy 6o(. %h0 it may not seem li e the !indo! "rocedure "er'orms its o!n moving and siPing o"erations0 (ut it does. That7s "art o' the 6o( o' 'ef&indow4roc0 !hich must (e considered as "art o' your !indo! "rocedure.

>n 0=ercise in %e=t O$t-$t


+n the "revious cha"ter0 !e e4"lored the !or ings o' a sim"le #indo!s B^ "rogram that dis"layed a single line o' te4t in the center o' its !indo! or0 more "recisely0 the center o' its client area. 5s !e learned0 the client area is that "art o' the total a""lication !indo! that is not ta en u" (y the title (ar0 the !indo!:siPing (order0 and0 o"tionally0 the menu (ar0 tool (ars0 status (ar0 and scroll (ars. +n short0 the client area is the "art o' the !indo! on !hich a "rogram is 'ree to dra! and deliver visual in'ormation to the user. Nou can do almost anything you !ant !ith your "rogram7s client areaSanything0 that is0 e4ce"t assume that it !ill (e a "articular siPe or that the siPe !ill remain constant !hile your "rogram is running. #f (o$ are not acc$stomed to writing -rograms for a gra-hical windowing environment. these sti-$lations ma( come as a /it of a shoc+ . Nou can7t thin in terms o' a 'i4ed num(er o' ^F:character lines. Nour "rogram must share the video dis"lay !ith other #indo!s "rograms. The #indo!s user controls ho! the "rograms7 !indo!s are arranged on the screen. 5lthough it is "ossi(le 'or a "rogrammer to create a !indo! o' a 'i4ed siPe (!hich might (e a""ro"riate 'or calculators or similar utilities*0 users are usually a(le to siPe a""lication !indo!s. Nour "rogram must acce"t the siPe it7s given and do something reasona(le !ith it.

This !or s (oth !ays. <ust as your "rogram may 'ind itsel' !ith a client area (arely large enough in !hich to say I-ello0I it may also someday (e run on a (ig:screen0 high:resolution video system and discover a client area large enough 'or t!o entire "ages o' te4t and "lenty o' closet s"ace (esides. Dealing intelligently !ith (oth eventualities is an im"ortant "art o' #indo!s "rogramming. #e !ill learn ho! a "rogram dis"lays something on the sur'ace o' its client area !ith more so"histication than that illustrated in the last cha"ter. #hen a "rogram dis"lays te4t or gra"hics in its client area0 it is o'ten said to (e I"aintingI its client area. 5lthough #indo!s has e4tensive 2ra"hics Device +nter'ace (2D+* 'unctions 'or dis"laying gra"hics0 here0 +7ll stic to dis"laying sim"le lines o' te4t. +7ll also ignore the various 'ont 'aces and 'ont siPes that #indo!s ma es availa(le and use only #indo!s7 de'ault Isystem 'ont.I

Painting and Re-ainting


+n character:mode environments0 "rograms can generally !rite to any "art o' the video dis"lay. #hat the "rogram "uts on the dis"lay !ill stay there and not mysteriously disa""ear. The "rogram can then discard the in'ormation needed to re:create the screen dis"lay. +n #indo!s0 you can dra! te4t and gra"hics only in the client area o' your !indo!0 and you cannot (e assured that !hat you "ut !ill remain there until your "rogram s"eci'ically !rites over it. /or instance0 the user may move another "rogram7s !indo! on the screen so that it "artially covers your a""lication7s !indo!. #indo!s !ill not attem"t to save the area o' your !indo! that the other "rogram covers. #hen the "rogram is moved a!ay0 #indo!s !ill re)uest that your "rogram re"aint this "ortion o' your client area. #indo!s is a message:driven system. #indo!s in'orms a""lications o' various events (y "osting messages in the a""lication7s message )ueue or sending messages to the a""ro"riate !indo! "rocedure. #indo!s in'orms a !indo! "rocedure that "art o' the !indo!7s client area needs "ainting (y "osting a #&9$5+NT message.

%he WM@P>#)% Message


&ost #indo!s "rograms call the 'unction 1pdate&indow during initialiPation in &inMain shortly (e'ore entering the message loo". #indo!s ta es this o""ortunity to send the !indo! "rocedure its 'irst #&9$5+NT message. This message in'orms the !indo! "rocedure that the client area must (e "ainted. Therea'ter0 that !indo! "rocedure should (e ready at almost any time to "rocess additional #&9$5+NT messages and even to re"aint the entire client area o' the !indo! i' necessary. 5 !indo! "rocedure receives a #&9$5+NT message !henever one o' the 'ollo!ing events occurs: 5 "reviously hidden area o' the !indo! is (rought into vie! !hen a user moves a !indo! or uncovers a !indo!. The user resiPes the !indo! (i' the !indo! class style has the CS9-83D85# and C#9V83D85# (its set*. The "rogram uses the 0croll&indow or 0croll'$ 'unction to scroll "art o' its client area. The "rogram uses the *nvalidate"ect or *nvalidate"gn 'unction to e4"licitly generate a #&9$5+NT message. +n some cases !hen "art o' the client area is tem"orarily !ritten over0 #indo!s attem"ts to save an area o' the dis"lay and restore it later. This is not al!ays success'ul. #indo!s may sometimes "ost a #&9$5+NT message !hen: #indo!s removes a dialog (o4 or message (o4 that !as overlaying "art o' the !indo!. 5 menu is "ulled do!n and then released. 5 tool ti" is dis"layed. +n a 'e! cases0 #indo!s al!ays saves the area o' the dis"lay it over!rites and then restores it. This is the case !henever: The mouse cursor is moved across the client area. 5n icon is dragged across the client area.

Dealing !ith #&9$5+NT message re)uires that you alter the !ay you thin a(out ho! you !rite to the video dis"lay. Nour "rogram should (e structured so that it accumulates all the in'ormation necessary to "aint the client area (ut "aints only Ion demandIS!hen #indo!s sends the !indo! "rocedure a #&9$5+NT message. +' your "rogram needs to u"date its client area at some other time0 it can 'orce #indo!s to generate this #&9$5+NT message. This may seem a rounda(out method o' dis"laying something on the screen0 (ut the structure o' your "rogram !ill (ene'it 'rom it.

?alid and #nvalid Rectangles


5lthough a !indo! "rocedure should (e "re"ared to u"date the entire client area !henever it receives a #&9$5+NT message0 it o'ten needs to u"date only a smaller area0 most o'ten a rectangular area !ithin the client area. This is most o(vious !hen a dialog (o4 overlies "art o' the client area. 8e"ainting is re)uired only 'or the rectangular area uncovered !hen the dialog (o4 is removed. That area is no!n as an Iinvalid regionI or Iu"date region.I The "resence o' an invalid region in a client area is !hat "rom"ts #indo!s to "lace a #&9$5+NT message in the a""lication7s message )ueue. Nour !indo! "rocedure receives a #&9$5+NT message only i' "art o' your client area is invalid. #indo!s internally maintains a I"aint in'ormation structureI 'or each !indo!. This structure contains0 among other in'ormation0 the coordinates o' the smallest rectangle that encom"asses the invalid region. This is no!n as the Iinvalid rectangle.I +' another region o' the client area (ecomes invalid (e'ore the !indo! "rocedure "rocesses a "ending #&9$5+NT message0 #indo!s calculates a ne! invalid region (and a ne! invalid rectangle* that encom"asses (oth areas and stores this u"dated in'ormation in the "aint in'ormation structure. #indo!s does not "lace multi"le #&9$5+NT messages in the message )ueue. 5 !indo! "rocedure can invalidate a rectangle in its o!n client area (y calling *nvalidate"ect. +' the message )ueue already contains a #&9$5+NT message0 #indo!s calculates a ne! invalid rectangle. %ther!ise0 it "laces a #&9$5+NT message in the message )ueue. 5 !indo! "rocedure can o(tain the coordinates o' the invalid rectangle !hen it receives a #&9$5+NT message (as !e7ll see later in this cha"ter*. +t can also o(tain these coordinates at any other time (y calling 2et1pdate"ect. 5'ter the !indo! "rocedure calls )egin4aint during the #&9$5+NT message0 the entire client area is validated. 5 "rogram can also validate any rectangular area !ithin the client area (y calling the @alidate"ect 'unction. +' this call has the e''ect o' validating the entire invalid area0 then any #&9$5+NT message currently in the )ueue is removed.

>n #ntrod$ction to 6D#


To "aint the client area o' your !indo!0 you use #indo!s7 2ra"hics Device +nter'ace (2D+* 'unctions. #indo!s "rovides several 2D+ 'unctions 'or !riting te4t strings to the client area o' the !indo!. #e7ve already encountered the 'raw.ext 'unction in the last cha"ter0 (ut the most commonly used te4t out"ut 'unction is undou(tedly .ext>ut. This 'unction has the 'ollo!ing 'ormat: (e"tDut (hdc# "# %# ps(e"t# iLen+th) ; .ext>ut !rites a character string to the client area o' the !indo!. The ps.ext argument is a "ointer to the character string0 and i(ength is the length o' the string in characters. The x and # arguments de'ine the starting "osition o' the character string in the client area. (&ore details soon on ho! these !or .* The hdc argument is a Ihandle to a device conte4t0I and it is an im"ortant "art o' 2D+. Virtually every 2D+ 'unction re)uires this handle as the 'irst argument to the 'unction.

%he Device Conte=t


5 handle0 you7ll recall0 is sim"ly a num(er that #indo!s uses 'or internal re'erence to an o(6ect. Nou o(tain the handle 'rom #indo!s and then use the handle in other 'unctions. The device conte4t handle is your !indo!7s "ass"ort to the 2D+ 'unctions. #ith that device conte4t handle you are 'ree to "aint your client area and ma e it as (eauti'ul or as ugly as you li e.

The device conte4t (also called sim"ly the IDCI* is really 6ust a data structure maintained internally (y 2D+. 5 device conte4t is associated !ith a "articular dis"lay device0 such as a video dis"lay or a "rinter. /or a video dis"lay0 a device conte4t is usually associated !ith a "articular !indo! on the dis"lay. Some o' the values in the device conte4t are gra"hics Iattri(utes.I These attri(utes de'ine some "articulars o' ho! 2D+ dra!ing 'unctions !or . #ith .ext>ut0 'or instance0 the attri(utes o' the device conte4t determine the color o' the te4t0 the color o' the te4t (ac ground0 ho! the 4:coordinate and y:coordinate in the .ext>ut 'unction are ma""ed to the client area o' the !indo!0 and !hat 'ont #indo!s uses !hen dis"laying the te4t. #hen a "rogram needs to "aint0 it must 'irst o(tain a handle to a device conte4t. #hen you o(tain this handle0 #indo!s 'ills the internal device conte4t structure !ith de'ault attri(ute values. 5s you7ll see in later cha"ters0 you can change these de'aults (y calling various 2D+ 'unctions. %ther 2D+ 'unctions let you o(tain the current values o' these attri(utes. Then0 o' course0 there are still other 2D+ 'unctions that let you actually "aint the client area o' the !indo!. 5'ter a "rogram has 'inished "ainting its client area0 it should release the device conte4t handle. #hen a "rogram releases the handle0 the handle is no longer valid and must not (e used. The "rogram should o(tain the handle and release the handle during the "rocessing o' a single message. 34ce"t 'or a device conte4t created !ith a call to $reate'$ (a 'unction + !on7t discuss in this cha"ter*0 you should not ee" a device conte4t handle around 'rom one message to another. #indo!s a""lications generally use t!o methods 'or getting a device conte4t handle in "re"aration 'or "ainting the screen.

6etting a Device Conte=t 'andle1 Method One


Nou use this method !hen you "rocess #&9$5+NT messages. T!o 'unctions are involved: )egin4aint and ,nd4aint. These t!o 'unctions re)uire the handle to the !indo!0 !hich is "assed to the !indo! "rocedure as an argument0 and the address o' a structure varia(le o' ty"e $5+NTST8.CT0 !hich is de'ined in the #+N.S38.header 'ile. #indo!s "rogrammers usually name this structure varia(le ps and de'ine it !ithin the !indo! "rocedure li e so: CF=;(:(UV4( ps ; #hile "rocessing a #&9$5+NT message0 the !indo! "rocedure 'irst calls )egin4aint. The )egin4aint 'unction generally causes the (ac ground o' the invalid region to (e erased in "re"aration 'or "ainting. The 'unction also 'ills in the 'ields o' the ps structure. The value returned 'rom )egin4aint is the device conte4t handle. This is commonly saved in a varia(le named hdc. Nou de'ine this varia(le in your !indo! "rocedure li e so: ?L4 hdc ; The -DC data ty"e is de'ined as a G;:(it unsigned integer. The "rogram may then use 2D+ 'unctions0 such as .ext>ut0 that re)uire the handle to the device conte4t. 5 call to ,nd4aint releases the device conte4t handle. Ty"ically0 "rocessing o' the #&9$5+NT message loo s li e this: case 8K&CF=;(7 hdc ' Ie+inCaint (h,nd# ]ps) ; [use *&$ functions] PndCaint (h,nd# ]ps) ; return / ; The !indo! "rocedure must call )egin4aint and ,nd4aint as a "air !hile "rocessing the #&9$5+NT message. +' a !indo! "rocedure does not "rocess #&9$5+NT messages0 it must "ass the #&9$5+NT message to 'ef&indow4roc0 !hich is the de'ault !indo! "rocedure located in #indo!s. 'ef&indow4roc "rocesses #&9$5+NT messages !ith the 'ollo!ing code: case 8K&CF=;(7 Ie+inCaint (h,nd# ]ps) ; PndCaint (h,nd# ]ps) ; return / ; The se)uence o' )egin4aint and ,nd4aint calls !ith nothing in (et!een validates the "reviously invalid region. 1ut don7t do this: case 8K&CF=;(7 return / ; 22 8UD;Y OOO #indo!s "laces a #&9$5+NT message in the message )ueue (ecause "art o' the client area is invalid. .nless you call )egin4aint and ,nd4aint (or @alidate"ect*0 #indo!s !ill not validate that area. +nstead0 #indo!s !ill send you another #&9$5+NT message0 and another0 and another0 and anotherf.

%he Paint #nformation ,tr$ct$re


3arlier + mentioned a I"aint in'ormation structureI that #indo!s maintains 'or each !indo!. That7s !hat $5+NTST8.CT is. The structure is de'ined as 'ollo!s: t%pedef struct ta+CF=;(:(UV4( { ?L4 hdc ; IDDL fPrase ; UP4( rcCaint ; IDDL fUestore ; IDDL f=ncVpdate ; IG(P r+!UeservedQ-2R ; CF=;(:(UV4( ; #indo!s 'ills in the 'ields o' this structure !hen your "rogram calls )egin4aint. Nour "rogram can use only the 'irst three 'ields. The others are used internally (y #indo!s. The hdc 'ield is the handle to the device conte4t. +n a redundancy ty"ical o' #indo!s0 the value returned 'rom )egin4aint is also this device conte4t handle. +n most cases0 f,rase !ill (e 'lagged /5,S3 (F*0 meaning that #indo!s has already erased the (ac ground o' the invalid rectangle. This ha""ens earlier in the )egin4aint 'unction. (+' you !ant to do some customiPed (ac ground erasing in your !indo! "rocedure0 you can "rocess the #&9385S31K2ND message.* #indo!s erases the (ac ground using the (rush s"eci'ied in the hbr)ac%ground 'ield o' the #NDC,5SS structure that you use !hen registering the !indo! class during &inMain initialiPation. &any #indo!s "rograms s"eci'y a !hite (rush 'or the !indo! (ac ground. This is indicated !hen the "rogram sets u" the 'ields o' the !indo! class structure !ith a statement li e this: ,ndclass.h!rIac0+round ' (?IUV:?) Yet:toc0D!$ect (8?=(P&IUV:?) ; -o!ever0 i' your "rogram invalidates a rectangle o' the client area (y calling *nvalidate"ect0 the last argument o' the 'unction s"eci'ies !hether you !ant the (ac ground erased. +' this argument is /5,S3 (that is0 F*0 #indo!s !ill not erase the (ac ground and the f,rase 'ield o' the $5+NTST8.CT structure !ill (e T8.3 (nonPero* a'ter you call )egin4aint. The rc4aint 'ield o' the $5+NTST8.CT structure is a structure o' ty"e 83CT. 5s you learned earlier0 the 83CT structure de'ines a rectangle !ith 'our 'ields named left0 top0 right0 and bottom. The rc4aint 'ield in the $5+NTST8.CT structure de'ines the (oundaries o' the invalid rectangle. The values are in units o' "i4els relative to the u""er le't corner o' the client area. The invalid rectangle is the area that you should re"aint.

.he boundaries of the invalid rectangle.

The rc4aint rectangle in $5+NTST8.CT is not only the invalid rectangleL it is also a Icli""ingI rectangle. This means that #indo!s restricts "ainting to !ithin the cli""ing rectangle. &ore "recisely0 i' the invalid region is not rectangular0 #indo!s restricts "ainting to !ithin that region. To "aint outside the u"date rectangle !hile "rocessing #&9$5+NT messages0 you can ma e this call: =nvalidateUect (h,nd# ;VLL# (UVP) ; (e'ore calling )egin4aint. This invalidates the entire client area and causes )egin4aint to erase the (ac ground. 5 /5,S3 value in the last argument !ill not erase the (ac ground. #hatever !as there !ill stay. +t is usually most convenient 'or a #indo!s "rogram to sim"ly re"aint the entire client area !henever it receives a #&9$5+NT message0 regardless o' the rc4aint structure. /or e4am"le0 i' "art o' the dis"lay out"ut in the client area includes a circle (ut only "art o' the circle 'alls !ithin the invalid rectangle0 it ma es little sense to dra! only the invalid "art o' the circle. Dra! the !hole circle. #hen you use the device conte4t handle returned 'rom )egin4aint0 #indo!s !ill not "aint outside the rc4aint rectangle any!ay. +n the -3,,%#+N "rogram in Cha"ter ;0 !e didn7t care a(out invalid rectangles !hen "rocessing the #&9$5+NT message. +' the area !here the te4t !as dis"layed ha""ened to (e !ithin the invalid rectangle0 'raw.ext restored it. +' not0 then at some "oint during "rocessing o' the 'raw.ext call #indo!s determined it didn7t need to !rite anything on the dis"lay. 1ut this determination ta es time. 5 "rogrammer concerned a(out "er'ormance and s"eed (and that includes all o' us0 + ho"e* !ill !ant to use the invalid rectangle during "rocessing o' the #&9$5+NT message to avoid unnecessary 2D+ calls. This is "articularly im"ortant i' "ainting re)uires accessing dis 'iles such as (itma"s.

6etting a Device Conte=t 'andle1 Method %wo


5lthough it is (est to structure your "rogram so that you can u"date the entire client area during the #&9$5+NT message0 you may also 'ind it use'ul to "aint "art o' the client area !hile "rocessing messages other than #&9$5+NT. %r you may need a device conte4t handle 'or other "ur"oses0 such as o(taining in'ormation a(out the device conte4t. To get a handle to the device conte4t o' the client area o' the !indo!0 you call 2et'$ to o(tain the handle and "elease'$ a'ter you7re done !ith it: hdc ' YetL4 (h,nd) ; [use *&$ functions] UeleaseL4 (h,nd# hdc) ; ,i e )egin4aint and ,nd4aint0 the 2et'$ and "elease'$ 'unctions should (e called in "airs. #hen you call 2et'$ !hile "rocessing a message0 you should call "elease'$ (e'ore you e4it the !indo! "rocedure. Do not call 2et'$ in one message and "elease'$ in another. .nli e the device conte4t handle returned 'rom )egin4aint0 the device conte4t handle returned 'rom 2et'$ has a cli""ing rectangle e)ual to the entire client area. Nou can "aint on any "art o' the client area0 not merely on the invalid rectangle (i' indeed there is an invalid rectangle*. .nli e )egin4aint0 2et'$ does not validate any invalid regions. +' you need to validate the entire client area0 you can call _alidateUect (h,nd# ;VLL) ; 2enerally0 you7ll use the 2et'$ and "elease'$ calls in res"onse to ey(oard messages (such as in a !ord "rocessing "rogram* or mouse messages (such as in a dra!ing "rogram*. This allo!s the "rogram to dra! on the client area in "rom"t reaction to the user7s ey(oard or mouse in"ut !ithout deli(erately invalidating "art o' the client area to generate #&9$5+NT messages. -o!ever0 even i' you "aint during messages other than #&9$5+NT0 your "rogram must still accumulate enough in'ormation to (e a(le to u"date the dis"lay !henever you do receive a #&9$5+NT message. 5 'unction similar to 2et'$ is 2et&indow'$. #hile 2et'$ returns a device conte4t handle 'or !riting on the client area o' the !indo!0 2et&indow'$ returns a device conte4t handle that lets you !rite on the entire !indo!. /or e4am"le0 your "rogram can use the device conte4t handle returned 'rom 2et&indow'$ to !rite on the !indo!7s title (ar. -o!ever0 your "rogram !ould also have to "rocess #&9NC$5+NT (Inonclient "aintI* messages as !ell.

Text$ut1 %he Details


.ext>ut is the most common 2D+ 'unction 'or dis"laying te4t. +ts synta4 is (e"tDut (hdc# "# %# ps(e"t# iLen+th) ;

,et7s e4amine this 'unction in more detail. The 'irst argument is the handle to the device conte4tSeither the hdc value returned 'rom 2et'$ or the hdc value returned 'rom )egin4aint during "rocessing o' a #&9$5+NT message. The attri(utes o' the device conte4t control the characteristics o' this dis"layed te4t. /or instance0 one attri(ute o' the device conte4t s"eci'ies the te4t color. The de'ault color (!e discover !ith some degree o' com'ort* is (lac . The de'ault device conte4t also de'ines a te4t (ac ground color0 and this is !hite. #hen a "rogram !rites te4t to the dis"lay0 #indo!s uses this (ac ground color to 'ill in the rectangular s"ace surrounding each character0 called the Icharacter (o4.I The te4t (ac ground color is not the same (ac ground you set !hen de'ining the !indo! class. The (ac ground in the !indo! class is a (rushS!hich is a "attern that may or may not (e a "ure colorSthat #indo!s uses to erase the client area. +t is not "art o' the device conte4t structure. #hen de'ining the !indo! class structure0 most #indo!s a""lications use #-+T3918.S- so that the de'ault te4t (ac ground color in the de'ault device conte4t is the same color as the (rush #indo!s uses to erase the (ac ground o' the client area. The ps.ext argument is a "ointer to a character string0 and i(ength is the num(er o' characters in the string. +' ps.ext "oints to a .nicode character string0 then the num(er o' (ytes in the string is dou(le the i(ength value. The string should not contain any 5SC++ control characters such as carriage returns0 line'eeds0 ta(s0 or (ac s"aces. #indo!s dis"lays these control characters as (o4es or solid (loc s. .ext>ut does not recogniPe a Pero (yte (or 'or .nicode0 a Pero short integer* as denoting the end o' a string. The 'unction uses the i(ength argument to determine the string7s length. The x and # arguments to .ext>ut de'ine the starting "oint o' the character string !ithin the client area. The x value is the horiPontal "ositionL the # value is the vertical "osition. The u""er le't corner o' the 'irst character is "ositioned at the coordinate "oint (x0 #*. +n the de'ault device conte4t0 the origin (that is0 the "oint !here x and # (oth e)ual F* is the u""er le't corner o' the client area. +' you use Pero values 'or x and # in .ext>ut0 the character string starts 'lush against the u""er le't corner o' the client area. #hen you read the documentation o' a 2D+ dra!ing 'unction such as .ext>ut0 you7ll 'ind that the coordinates "assed to the 'unction are usually documented as Ilogical coordinates.I /or no!0 (e a!are that #indo!s has a variety o' Ima""ing modesI that govern ho! the logical coordinates s"eci'ied in 2D+ dra!ing 'unctions are translated to the "hysical "i4el coordinates o' the dis"lay. The ma""ing mode is de'ined in the device conte4t. The de'ault ma""ing mode is called &&9T3AT (using the identi'ier de'ined in the #+N2D+.- header 'ile*. .nder the &&9T3AT ma""ing mode0 logical units are the same as "hysical units0 !hich are "i4els0 relative to the u""er le't corner o' the client area. Values o' x increase as you move to the right in the client area0 and values o' # increase as you move do!n in the client area. (See /igure (elo!.* The &&9T3AT coordinate system is identical to the coordinate system that #indo!s uses to de'ine the invalid rectangle in the $5+NTST8.CT structure. (Things are not )uite as convenient !ith the other ma""ing modes0 ho!ever.*

.he x-coordinate and #-coordinate in the MM_.,C. mapping mode.

The device conte4t also de'ines a cli""ing region. 5s you7ve seen0 the de'ault cli""ing region is the entire client area 'or a device conte4t handle o(tained 'rom 2et'$ and the invalid region 'or the device conte4t handle o(tained 'rom )egin4aint. #hen you call .ext>ut0 #indo!s !ill not dis"lay any "art o' the character string that lies outside the cli""ing region. +' a character is "artly !ithin the cli""ing region0 #indo!s dis"lays only the "ortion o' the character inside the region. #riting outside the client area o' your !indo! isn7t easy to do0 so don7t !orry a(out doing it inadvertently.

%he ,(stem Font


The device conte4t also de'ines the 'ont that #indo!s uses !hen you call .ext>ut to dis"lay te4t. The de'ault is a 'ont called the Isystem 'ontI or (using the identi'ier in the #+N2D+.- header 'ile* SNST3&9/%NT. The system 'ont is the 'ont that #indo!s uses (y de'ault 'or te4t strings in title (ars0 menus0 and dialog (o4es. +n the early days o' #indo!s0 the system 'ont !as a 'i4ed:"itch 'ont0 !hich means that all the characters had the same !idth0 much li e a ty"e!riter. -o!ever0 (eginning !ith #indo!s G.F0 the system 'ont (ecame a varia(le:"itch 'ont0 !hich means that di''erent characters have di''erent !idths. 5 I#I is !ider than an IiI0 'or e4am"le. +t has (een !ell esta(lished (y studies in reading that te4t "rinted !ith varia(le:"itch 'onts is more reada(le than 'i4ed: "itch 'ont te4ts. +t seems to have something to do !ith the letters (eing closer together0 allo!ing the eyes and mind to more clearly see entire !ords rather than individual letters. 5s you might imagine0 the change 'rom 'i4ed:"itch 'onts to varia(le:"itch 'onts (ro e a lot o' early #indo!s code and re)uired that "rogrammers learn some ne! techni)ues 'or !or ing !ith te4t. The system 'ont is a Iraster 'ont0I !hich means that the characters are de'ined as (loc s o' "i4els. To a certain e4tent0 the siPe o' the characters in the system 'ont is (ased on the siPe o' the video dis"lay. The system 'ont is designed to allo! at least ;? lines o' ^F:character te4t to 'it on the screen.

%he ,iLe of a Character


To dis"lay multi"le lines o' te4t (y using the .ext>ut 'unction0 you need to no! the dimensions o' characters in the 'ont. Nou can s"ace successive lines o' te4t (ased on the height o' the characters0 and you can s"ace columns o' te4t across the client area (ased on the average !idth o' the characters. #hat is the height and average !idth o' characters in the system 'ontW #ell0 +7m not going to tell you. %r rather0 + canDt tell you. %r rather0 + could tell you0 (ut + might (e !rong. The "ro(lem is that it all de"ends on the "i4el siPe o' the video dis"lay. #indo!s re)uires a minimum dis"lay siPe o' C>F (y >^F0 (ut many users "re'er ^FF (y CFF or =F;> (y DC^. +n addition0 'or these larger dis"lay siPes0 #indo!s allo!s the user to select di''erent siPed system 'onts. <ust as a "rogram can determine in'ormation a(out the siPes (or ImetricsI* o' user inter'ace items (y calling the 2et0#stemMetrics 'unction0 a "rogram can determine 'ont siPes (y calling 2et.extMetrics. 2et.extMetrics re)uires a handle to a device conte4t (ecause it returns in'ormation a(out the 'ont currently selected in the device conte4t. #indo!s co"ies the various values o' te4t metrics into a structure o' ty"e T3AT&3T8+C de'ined in #+N2D+.-. The T3AT&3T8+C structure has ;F 'ields0 (ut !e7re interested in only the 'irst seven: t%pedef struct ta+(PW(KP(U=4 { LD;Y tm?ei+ht ; LD;Y tmFscent ; LD;Y tmLescent ; LD;Y tm=nternalLeadin+ ; LD;Y tmP"ternalLeadin+ ; LD;Y tmFve4har8idth ; LD;Y tmKa"4har8idth ; [other structure fields] (PW(KP(U=4# 3 C(PW(KP(U=4 ; The values o' these 'ields are in units that de"end on the ma""ing mode currently selected 'or the device conte4t. +n the de'ault device conte4t0 this ma""ing mode is &&9T3AT0 so the dimensions are in units o' "i4els. To use the 2et.extMetrics 'unction0 you 'irst need to de'ine a structure varia(le0 commonly called tm: (PW(KP(U=4 tm ;

#hen you need to determine the te4t metrics0 you get a handle to a device conte4t and call 2et.extMetrics: hdc ' YetL4 (h,nd) ; Yet(e"tKetrics (hdc# ]tm) ; UeleaseL4 (h,nd# hdc) ; Nou can then e4amine the values in the te4t metric structure and "ro(a(ly save a 'e! o' them 'or 'uture use.

%e=t Metrics1 %he Details


The T3AT&3T8+C structure "rovides various ty"es o' in'ormation a(out the 'ont currently selected in the device conte4t. -o!ever0 the vertical siPe o' a 'ont is de'ined (y only 'ive 'ields o' the structure0 'our o' !hich are sho!n in here.

!our values defining vertical character sizes in a font. The most im"ortant value is tm-eight0 !hich is the sum o' tm/scent and tm'escent. These t!o values re"resent the ma4imum vertical e4tents o' characters in the 'ont a(ove and (elo! the (aseline. The term IleadingI re'ers to s"ace that a "rinter inserts (et!een lines o' te4t. +n the T3AT&3T8+C structure0 internal leading is included in tm/scent (and thus in tm-eight* and is o'ten the s"ace in !hich accent mar s a""ear. The tm*nternal(eading 'ield could (e set to F0 in !hich case accented letters are made a little shorter so that the accent mar s 'it !ithin the ascent o' the character. The T3AT&3T8+C structure also includes a 'ield named tm,xternal(eading0 !hich is not included in the tm-eight value. This is an amount o' s"ace that the designer o' the 'ont suggests (e added (et!een successive ro!s o' dis"layed te4t. Nou can acce"t or re6ect the 'ont designer7s suggestion 'or including e4ternal leading !hen s"acing lines o' te4t. +n the system 'onts that +7ve encountered recently0 tm,xternal(eading has (een Pero0 !hich is !hy + didn7t include it in /igure >:G. (Des"ite my vo! not to tell you the dimensions o' a system 'ont0 /igure >:G is accurate 'or the system 'ont that #indo!s uses (y de'ault 'or a C>F (y >^F dis"lay.* The T3AT&3T8+C structure contains t!o 'ields that descri(e character !idths: the tm/ve$har&idth 'ield is a !eighted average o' lo!ercase characters0 and tmMax$har&idth is the !idth o' the !idest character in the 'ont. /or a 'i4ed:"itch 'ont0 these values are the same. The sam"le "rograms in this cha"ter !ill re)uire another character !idthSthe average !idth o' u""ercase letters. Nou can calculate this 'airly accurately as =?FZ o' tm/ve$har&idth. +t7s im"ortant to realiPe that the dimensions o' a system 'ont are de"endent on the "i4el siPe o' the video dis"lay on !hich #indo!s runs and0 in some cases0 on the system 'ont siPe the user has selected. #indo!s "rovides a device: inde"endent gra"hics inter'ace0 (ut you have to hel". Don7t !rite your #indo!s "rograms so that they guess at character dimensions. Don7t hard:code any values. .se the 2et.extMetrics 'unction to o(tain this in'ormation.

Formatting %e=t

1ecause the dimensions o' the system 'ont do not change during a #indo!s session0 you need to call 2et.extMetrics only once !hen your "rogram e4ecutes. 5 good "lace to ma e this call is !hile "rocessing the #&9C835T3 message in the !indo! "rocedure. The #&9C835T3 message is the 'irst message the !indo! "rocedure receives. #indo!s calls your !indo! "rocedure !ith a #&9C835T3 message !hen you call $reate&indow in &inMain. Su""ose you7re !riting a #indo!s "rogram that dis"lays several lines o' te4t running do!n the client area. Nou7ll !ant to o(tain values 'or the character !idth and height. #ithin the !indo! "rocedure you can de'ine t!o varia(les to save the average character !idth (cx$har* and the total character height (c#$har*: static int c"4har# c%4har ; The "re'i4 c added to the varia(les names stands 'or Icount0I and in this case means a count o' (or num(er o'* "i4els. +n com(ination !ith x or #0 the "re'i4 re'ers to a !idth or height. These varia(les are de'ined as static (ecause they must (e valid !hen the !indo! "rocedure "rocesses other messages0 such as #&9$5+NT. %r you can de'ine the varia(les glo(ally outside o' any 'unction. -ere7s the #&9C835T3 code to o(tain the !idth and height o' characters in the system 'ont: case 8K&4UPF(P7 hdc ' YetL4 (h,nd) ; Yet(e"tKetrics (hdc# ]tm) ; c"4har ' tm.tmFve4har8idth ; c%4har ' tm.tm?ei+ht * tm.tmP"ternalLeadin+ ; UeleaseL4 (h,nd# hdc) ; return / ; Notice that +7ve included the tm,xternal(eading 'ield in the calculation o' c#$har. 3ven though this 'ield is F in the system 'onts +7ve seen lately0 it should (e included i' it7s ever nonPero (ecause it ma es 'or more reada(le line s"acing. 3ach successive line o' te4t is dis"layed c#$har "i4els 'urther do!n the !indo!. Nou7ll o'ten 'ind it necessary to dis"lay 'ormatted num(ers as !ell as sim"le character strings. 5s + discussed earlier you can7t use the traditional tool 'or this 6o( (the (eloved printf 'unction*0 (ut you can use sprintf and the #indo!s version o' sprintf0 wsprintf. These 'unctions !or 6ust li e printf e4ce"t that they "ut the 'ormatted string into a character string. Nou can then use .ext>ut to !rite the string to the dis"lay. Very conveniently0 the value returned 'rom sprintf and wsprintf is the length o' the string. Nou can "ass that value to .ext>ut as the i(ength argument. This code sho!s a ty"ical wsprintf and .ext>ut com(ination: int iLen+th ; (4?FU s@Iuffer QH/R ; [ other pro"ram lines ] iLen+th ' ,sprintf (s@Iuffer# (PW( ("(he sum of )i and )i is )i")# iF# iI# iF * iI) ; (e"tDut (hdc# "# %# s@Iuffer# iLen+th) ; /or something as sim"le as this0 you could dis"ense !ith the i(ength de'inition and com(ine the t!o statements into one: (e"tDut (hdc# "# %# s@Iuffer# ,sprintf (s@Iuffer# (PW( ("(he sum of )i and )i is )i")# iF# iI# iF * iI)) ; +t ain7t "retty0 (ut it !or s.

P$tting #t >ll %ogether


No! !e seem to have everything !e need to !rite a sim"le "rogram that dis"lays multi"le lines o' te4t on the screen. #e no! ho! to get a handle to a device conte4t during the #&9$5+NT message0 ho! to use the .ext>ut 'unction0 and ho! to s"ace te4t (ased on the siPe o' a single character. The only thing le't 'or us to do is to dis"lay something interesting. +n the "revious cha"ter0 !e too a little "ee at the interesting in'ormation availa(le 'rom the #indo!s 2et0#stemMetrics 'unction. The 'unction returns in'ormation a(out the siPe o' various gra"hical items in #indo!s0 such as icons0 cursors0 title (ars0 and scroll (ars. These siPes vary !ith the dis"lay ada"ter and driver. 2et0#stemMetrics is an im"ortant 'unction 'or achieving device:inde"endent gra"hical out"ut in your "rogram.

The 'unction re)uires a single argument called an Iinde4.I The inde4 is one o' D? integer identi'iers de'ined in the #indo!s header 'iles. (The num(er o' identi'iers has increased !ith each release o' #indo!sL the "rogrammer7s documentation in #indo!s =.F listed only ;C o' them.* 2et0#stemMetrics returns an integer0 usually the siPe o' the item s"eci'ied in the argument. ,et7s !rite a "rogram that dis"lays some o' the in'ormation availa(le 'rom the 2et0#stemMetrics calls in a sim"le one:line:"er:item 'ormat. #or ing !ith this in'ormation is easier i' !e create a header 'ile that de'ines an array o' structures containing (oth the #indo!s header:'ile identi'iers 'or the 2et0#stemMetrics inde4 and the te4t !e !ant to dis"lay 'or each value returned 'rom the call. This header 'ile is called SNS&3TS.- and is sho!n here.. .he 0A0M,.0.- file.

,8,M0%,A'
2399999999999999999999999999999999999999999999999 :G:KP(:.? 99 :%stem metrics displa% structure 9999999999999999999999999999999999999999999999932 #define ;VKL=;P: ((int) (si@eof s%smetrics 2 si@eof s%smetrics Q/R)) struct { int i=nde" ; (4?FU 3 s@La!el ; (4?FU 3 s@Lesc ; s%smetrics QR ' { :K&4W:4UPP;# :K&4G:4UPP;# :K&4W_:4UDLL# :K&4G?:4UDLL# :K&4G4FC(=D;# :K&4WIDULPU# :K&4GIDULPU# :K&4W6=WPL6UFKP# :K&4G6=WPL6UFKP# :K&4G_(?VKI# :K&4W?(?VKI# :K&4W=4D;# :K&4G=4D;# :K&4W4VU:DU# :K&4G4VU:DU#

(PW( (PW( (PW( (PW( (PW( (PW( (PW( (PW( (PW( (PW( (PW( (PW( (PW( (PW( (PW( (PW( (PW( (PW( (PW( (PW( (PW( (PW( (PW( (PW( (PW( (PW( (PW( (PW( (PW( (PW(

(":K&4W:4UPP;")# (":creen ,idth in pi"els")# (":K&4G:4UPP;")# (":creen hei+ht in pi"els")# (":K&4W_:4UDLL")# ("_ertical scroll ,idth")# (":K&4G?:4UDLL")# ("?ori@ontal scroll hei+ht")# (":K&4G4FC(=D;")# ("4aption !ar hei+ht")# (":K&4WIDULPU")# ("8indo, !order ,idth")# (":K&4GIDULPU")# ("8indo, !order hei+ht")# (":K&4W6=WPL6UFKP")# ("Lialo+ ,indo, frame ,idth")# (":K&4G6=WPL6UFKP")# ("Lialo+ ,indo, frame hei+ht")# (":K&4G_(?VKI")# ("_ertical scroll thum! hei+ht")# (":K&4W?(?VKI")# ("?ori@ontal scroll thum! ,idth")# (":K&4W=4D;")# ("=con ,idth")# (":K&4G=4D;")# ("=con hei+ht")# (":K&4W4VU:DU")# ("4ursor ,idth")# (":K&4G4VU:DU")# ("4ursor hei+ht")#

:K&4GKP;V# :K&4W6VLL:4UPP;# :K&4G6VLL:4UPP;# :K&4GXF;`=8=;LD8# :K&KDV:PCUP:P;(# :K&4G_:4UDLL# :K&4W?:4UDLL# :K&LPIVY# :K&:8FCIV((D;# :K&4WK=;# :K&4GK=;# :K&4W:=\P# :K&4G:=\P# :K&4W:=\P6UFKP# :K&4G:=\P6UFKP# :K&4WK=;(UF4X# :K&4GK=;(UF4X# :K&4WLDVILP4LX# :K&4GLDVILP4LX# :K&4W=4D;:CF4=;Y# :K&4G=4D;:CF4=;Y# :K&KP;VLUDCFL=Y;KP;(# :K&CP;8=;LD8:# :K&LI4:P;FILPL# :K&4KDV:PIV((D;:# :K&:P4VUP# :K&4WPLYP# :K&4GPLYP# :K&4WK=;:CF4=;Y#

(PW( (PW( (PW( (PW( (PW( (PW( (PW( (PW( (PW( (PW( (PW( (PW( (PW( (PW( (PW( (PW( (PW( (PW( (PW( (PW( (PW( (PW( (PW( (PW( (PW( (PW( (PW( (PW( (PW( (PW( (PW( (PW( (PW( (PW( (PW( (PW( (PW( (PW( (PW( (PW( (PW( (PW( (PW( (PW( (PW( (PW( (PW( (PW( (PW( (PW( (PW( (PW( (PW( (PW( (PW( (PW( (PW(

(":K&4GKP;V")# ("Kenu !ar hei+ht")# (":K&4W6VLL:4UPP;")# ("6ull screen client area ,idth")# (":K&4G6VLL:4UPP;")# ("6ull screen client area hei+ht")# (":K&4GXF;`=8=;LD8")# ("Xan$i ,indo, hei+ht")# (":K&KDV:PCUP:P;(")# ("Kouse present fla+")# (":K&4G_:4UDLL")# ("_ertical scroll arro, hei+ht")# (":K&4W?:4UDLL")# ("?ori@ontal scroll arro, ,idth")# (":K&LPIVY")# ("Le!u+ version fla+")# (":K&:8FCIV((D;")# ("Kouse !uttons s,apped fla+")# (":K&4WK=;")# ("Kinimum ,indo, ,idth")# (":K&4GK=;")# ("Kinimum ,indo, hei+ht")# (":K&4W:=\P")# ("Kin2Ka"24lose !utton ,idth")# (":K&4G:=\P")# ("Kin2Ka"24lose !utton hei+ht")# (":K&4W:=\P6UFKP")# ("8indo, si@in+ frame ,idth")# (":K&4G:=\P6UFKP")# ("8indo, si@in+ frame hei+ht")# (":K&4WK=;(UF4X")# ("Kinimum ,indo, trac0in+ ,idth")# (":K&4GK=;(UF4X")# ("Kinimum ,indo, trac0in+ hei+ht")# (":K&4WLDVILP4LX")# ("Lou!le clic0 " tolerance")# (":K&4GLDVILP4LX")# ("Lou!le clic0 % tolerance")# (":K&4W=4D;:CF4=;Y")# ("?ori@ontal icon spacin+")# (":K&4G=4D;:CF4=;Y")# ("_ertical icon spacin+")# (":K&KP;VLUDCFL=Y;KP;(")# ("Left or ri+ht menu drop")# (":K&CP;8=;LD8:")# ("Cen e"tensions installed")# (":K&LI4:P;FILPL")# ("Lou!le9I%te 4har :et ena!led")# (":K&4KDV:PIV((D;:")# (";um!er of mouse !uttons")# (":K&:P4VUP")# (":ecurit% present fla+")# (":K&4WPLYP")# ("-9L !order ,idth")# (":K&4GPLYP")# ("-9L !order hei+ht")# (":K&4WK=;:CF4=;Y")#

:K&4GK=;:CF4=;Y# :K&4W:K=4D;# :K&4G:K=4D;# :K&4G:K4FC(=D;# :K&4W:K:=\P# :K&4G:K:=\P# :K&4WKP;V:=\P# :K&4GKP;V:=\P# :K&FUUF;YP# :K&4WK=;=K=\PL# :K&4GK=;=K=\PL# :K&4WKFW(UF4X# :K&4GKFW(UF4X# :K&4WKFW=K=\PL# :K&4GKFW=K=\PL# :K&;P(8DUX# :K&4LPF;IDD(# :K&4WLUFY# :K&4GLUFY# :K&:?D8:DV;L:# :K&4WKP;V4?P4X# :K&4GKP;V4?P4X# :K&:LD8KF4?=;P# :K&K=LPF:(P;FILPL# :K&KDV:P8?PPLCUP:P;(# :K&W_=U(VFL:4UPP;# :K&G_=U(VFL:4UPP;# :K&4W_=U(VFL:4UPP;#

(PW( (PW( (PW( (PW( (PW( (PW( (PW( (PW( (PW( (PW( (PW( (PW( (PW( (PW( (PW( (PW( (PW( (PW( (PW( (PW( (PW( (PW( (PW( (PW( (PW( (PW( (PW( (PW( (PW( (PW( (PW( (PW( (PW( (PW( (PW( (PW( (PW( (PW( (PW( (PW( (PW( (PW( (PW( (PW( (PW( (PW( (PW( (PW( (PW( (PW( (PW( (PW( (PW( (PW( (PW( (PW( (PW(

("Kinimi@ed ,indo, spacin+ ,idth")# (":K&4GK=;:CF4=;Y")# ("Kinimi@ed ,indo, spacin+ hei+ht")# (":K&4W:K=4D;")# (":mall icon ,idth")# (":K&4G:K=4D;")# (":mall icon hei+ht")# (":K&4G:K4FC(=D;")# (":mall caption hei+ht")# (":K&4W:K:=\P")# (":mall caption !utton ,idth")# (":K&4G:K:=\P")# (":mall caption !utton hei+ht")# (":K&4WKP;V:=\P")# ("Kenu !ar !utton ,idth")# (":K&4GKP;V:=\P")# ("Kenu !ar !utton hei+ht")# (":K&FUUF;YP")# ("?o, minimi@ed ,indo,s arran+ed")# (":K&4WK=;=K=\PL")# ("Kinimi@ed ,indo, ,idth")# (":K&4GK=;=K=\PL")# ("Kinimi@ed ,indo, hei+ht")# (":K&4WKFW(UF4X")# ("Ka"imum dra++a!le ,idth")# (":K&4GKFW(UF4X")# ("Ka"imum dra++a!le hei+ht")# (":K&4WKFW=K=\PL")# ("8idth of ma"imi@ed ,indo,")# (":K&4GKFW=K=\PL")# ("?ei+ht of ma"imi@ed ,indo,")# (":K&;P(8DUX")# (";et,or0 present fla+")# (":K&4LPF;IDD(")# ("?o, s%stem ,as !ooted")# (":K&4WLUFY")# ("Fvoid dra+ " tolerance")# (":K&4GLUFY")# ("Fvoid dra+ % tolerance")# (":K&:?D8:DV;L:")# ("Cresent sounds visuall%")# (":K&4WKP;V4?P4X")# ("Kenu chec09mar0 ,idth")# (":K&4GKP;V4?P4X")# ("Kenu chec09mar0 hei+ht")# (":K&:LD8KF4?=;P")# (":lo, processor fla+")# (":K&K=LPF:(P;FILPL")# ("?e!re, and Fra!ic ena!led fla+")# (":K&KDV:P8?PPLCUP:P;(")# ("Kouse ,heel present fla+")# (":K&W_=U(VFL:4UPP;")# ("_irtual screen " ori+in")# (":K&G_=U(VFL:4UPP;")# ("_irtual screen % ori+in")# (":K&4W_=U(VFL:4UPP;")# ("_irtual screen ,idth")#

:K&4G_=U(VFL:4UPP;# :K&4KD;=(DU:# :K&:FKPL=:CLFG6DUKF(#

(PW( (PW( (PW( (PW( (PW( (PW(

(":K&4G_=U(VFL:4UPP;")# ("_irtual screen hei+ht")# (":K&4KD;=(DU:")# (";um!er of monitors")# (":K&:FKPL=:CLFG6DUKF(")# (":ame color format fla+")

; The "rogram that dis"lays this in'ormation is called SNS&3TS=. The SNS&3TS=.C source code 'ile is sho!n . &ost o' the code should loo 'amiliar (y no!. The code in &inMain is virtually identical to that in -3,,%#+N0 and much o' the code in &nd4roc has already (een discussed. 0A0M,.08.$.

,8,M0%,!AC
239999999999999999999999999999999999999999999999999999 :G:KP(:1.4 99 :%stem Ketrics Lispla% Cro+ram ;o. 1 (c) 4harles Cet@old# 1SST 999999999999999999999999999999999999999999999999999932 #include <,indo,s.h> #include "s%smets.h" LUP:VL( 4FLLIF4X 8ndCroc (?8;L# V=;(# 8CFUFK# LCFUFK) ; int 8=;FC= 8inKain (?=;:(F;4P h=nstance# ?=;:(F;4P hCrev=nstance# C:(U s@4mdLine# int i4md:ho,) { static (4?FU s@Fpp;ameQR ' (PW( (":%sKets1") ; ?8;L h,nd ; K:Y ms+ ; 8;L4LF:: ,ndclass ; 8ndclass.st%le 8ndclass.lpfn8ndCroc 8ndclass.c!4lsP"tra 8ndclass.c!8ndP"tra 8ndclass.h=nstance 8ndclass.h=con 8ndclass.h4ursor 8ndclass.h!rIac0+round 8ndclass.lps@Kenu;ame 8ndclass.lps@4lass;ame ' ' ' ' ' ' ' ' ' ' 4:&?UPLUF8 ^ 4:&_UPLUF8 ; 8ndCroc ; / ; / ; h=nstance ; Load=con (;VLL# =L=&FCCL=4F(=D;) ; Load4ursor (;VLL# =L4&FUUD8) ; (?IUV:?) Yet:toc0D!$ect (8?=(P&IUV:?) ; ;VLL ; s@Fpp;ame ;

if (OUe+ister4lass (],ndclass)) { Kessa+eIo" (;VLL# (PW( ("(his pro+ram re5uires 8indo,s ;(O")# s@Fpp;ame# KI&=4D;PUUDU) ; return / ; h,nd ' 4reate8indo, (s@Fpp;ame# (PW( ("Yet :%stem Ketrics ;o. 1")# 8:&D_PULFCCPL8=;LD8# 48&V:PLP6FVL(# 48&V:PLP6FVL(# 48&V:PLP6FVL(# 48&V:PLP6FVL(# ;VLL# ;VLL# h=nstance# ;VLL) ;

:ho,8indo, (h,nd# i4md:ho,) ; Vpdate8indo, (h,nd) ; ,hile (YetKessa+e (]ms+# ;VLL# /# /)) { (ranslateKessa+e (]ms+) ; LispatchKessa+e (]ms+) ; return ms+.,Caram ; LUP:VL( 4FLLIF4X lCaram) { static int ?L4 int CF=;(:(UV4( (4?FU (PW(KP(U=4 8ndCroc (?8;L h,nd# V=;( messa+e# 8CFUFK ,Caram# LCFUFK c"4har# c"4aps# c%4har ; hdc ; i ; ps ; s@Iuffer Q1/R ; tm ;

s,itch (messa+e) { case 8K&4UPF(P7 hdc ' YetL4 (h,nd) ; Yet(e"tKetrics (hdc# ]tm) ; 4"4har ' tm.tmFve4har8idth ; 4"4aps ' (tm.tmCitchFnd6amil% ] 1 < - 7 2) 3 c"4har 2 2 ; 4%4har ' tm.tm?ei+ht * tm.tmP"ternalLeadin+ ; UeleaseL4 (h,nd# hdc) ; Ueturn / ; case 8K&CF=;( 7 hdc ' Ie+inCaint (h,nd# ]ps) ; for (i ' / ; i < ;VKL=;P: ; i**) { (e"tDut (hdc# /# c%4har 3 i# s%smetricsQiR.s@La!el# lstrlen (s%smetricsQiR.s@La!el)) ; (e"tDut (hdc# 22 3 c"4aps# c%4har 3 i# s%smetricsQiR.s@Lesc# lstrlen (s%smetricsQiR.s@Lesc)) ; :et(e"tFli+n (hdc# (F&U=Y?( ^ (F&(DC) ; s@Iuffer# (e"tDut (hdc# 22 3 c"4aps * H/ 3 c"4har# c%4har 3 i#

,sprintf (s@Iuffer# (PW( (").d")# Yet:%stemKetrics (s%smetricsQiR.i=nde"))) ; :et(e"tFli+n (hdc# (F&LP6( ^ (F&(DC) ; PndCaint (h,nd# ]ps) ;

Ueturn / ; case 8K&LP:(UDG 7 CostJuitKessa+e (/) ; Ueturn / ; return Lef8indo,Croc (h,nd# messa+e# ,Caram# lCaram) ; /igure >:C sho!s SNS&3TS= running on a standard V25. 5s you can see 'rom the 'irst t!o lines in the "rogram7s client area0 the screen !idth is C>F "i4els and the screen height is >^F "i4els. These t!o values0 as !ell as many o' the other values sho!n (y the "rogram0 may (e di''erent 'or di''erent ty"es o' video dis"lays.

Fig$re E- A .he 0A0M,.08 displa#.

%he ,8,M0%,!AC Window Proced$re


The &nd4roc !indo! "rocedure in the SNS&3TS=.C "rogram "rocesses three messages: #&9C835T30 #&9$5+NT0 and #&9D3ST8%N. The #&9D3ST8%N message is "rocessed in the same !ay as the -3,,%#+N "rogram. The #&9C835T3 message is the 'irst message the !indo! "rocedure receives. #indo!s generates the message !hen the $reate&indow 'unction creates the !indo!. During the #&9C835T3 message0 SNS&3TS= o(tains a device conte4t 'or the !indo! (y calling 2et'$ and gets the te4t metrics 'or the de'ault system 'ont (y calling 2et.extMetrics. SNS&3TS= saves the average character !idth in cx$har and the total height o' the characters (including e4ternal leading* in c#$har. SNS&3TS= also saves an average !idth o' u""ercase letters in the static varia(le cx$aps. /or a 'i4ed:"itch 'ont0 cx$aps !ould e)ual cx$har. /or a varia(le:!idth 'ont0 cx$aps is set to =?F "ercent o' cx$har. The lo! (it o' the tm4itch/nd!amil# 'ield in the T3AT&3T8+C structure is = 'or a varia(le:!idth 'ont and F 'or a 'i4ed:"itch 'ont. SNS&3TS= uses this (it to calculate cx$aps 'rom cx$har: c"4aps ' (tm.tmCitchFnd6amil% ] 1 < - 7 2) 3 c"4har 2 2 ; SNS&3TS= does all !indo! "ainting during the #&9$5+NT message. 5s normal0 the !indo! "rocedure 'irst o(tains a handle to the device conte4t (y calling )egin4aint. 5 for statement loo"s through all the lines o' the s#smetrics structure de'ined in SNS&3TS.-. The three columns o' te4t are dis"layed !ith three .ext>ut 'unction calls. +n each case0 the third argument to .ext>ut (that is0 the # starting "osition* is set to c%4har 3 i This argument indicates the "i4el "osition o' the to" o' the character string relative to the to" o' the client area.

The 'irst .ext>ut statement dis"lays the u""ercase identi'iers in the 'irst o' the three columns. The second argument to .ext>ut is F to (egin the te4t at the le't edge o' the client area. The te4t is o(tained 'rom the sz(abel 'ield o' the s#smetrics structure. + use the #indo!s 'unction lstrlen to calculate the length o' the string0 !hich is re)uired as the last argument to .ext>ut. The second .ext>ut statement dis"lays the descri"tion o' the system metrics value. These descri"tions are stored in the sz'esc 'ield o' the s#smetrics structure. +n this case0 the second argument to .ext>ut is set to 22 3 c"4aps The longest u""ercase identi'ier dis"layed in the 'irst column is ;F characters0 so the second column must (egin at least ;F g cx$aps to the right o' the (eginning o' the 'irst column o' te4t. + use ;; to add a little e4tra s"ace (et!een the columns. The third .ext>ut statement dis"lays the numeric values o(tained 'rom the 2et0#stemMetrics 'unction. The varia(le:!idth 'ont ma es 'ormatting a column o' right:6usti'ied num(ers a little tric y. /ortunately0 in all varia(le: !idth 'onts used today0 the digits 'rom F through B all have the same !idth. %ther!ise0 dis"laying columns o' num(ers !ould (e monstrous. -o!ever0 the !idth o' the digits is greater than the !idth o' a s"ace. Num(ers can (e one or more digits !ide0 so di''erent num(ers can (egin at di''erent horiPontal "ositions. #ouldn7t it (e easier i' !e could dis"lay a column o' right:6usti'ied num(ers (y s"eci'ying the horiPontal "i4el "osition !here the num(er ends rather than (eginsW This is !hat the 0et.ext/lign 'unction lets us do (among other things*. 5'ter SNS&3TS= calls :et(e"tFli+n (hdc# (F&U=Y?( ^ (F&(DC) ; #indo!s !ill inter"ret the coordinates "assed to su(se)uent .ext>ut 'unctions as s"eci'ying the to":right corner o' the te4t string rather than the to":le't corner. The .ext>ut 'unction to dis"lay the column o' num(ers has its second argument set to 22 3 c"4aps * H/ 3 c"4har The >F g cx$har value accommodates the !idth o' the second column and the !idth o' the third column. /ollo!ing the .ext>ut 'unction0 another call to 0et.ext/lign sets things (ac to normal 'or the ne4t time through the loo".

)ot 0no$gh Room


%ne nasty little "ro(lem e4ists !ith the SNS&3TS= "rogram: .nless you have a gigantic0 (ig:screen0 high: resolution video ada"ter0 you can7t see many o' the lines in the system metrics lists. +' you ma e the !indo! narro!er0 you can7t even see the values. SNS&3TS= is not a!are o' this "ro(lem. %ther!ise !e might have included a message (o4 that said0 ISorryJI +t7s not a!are o' the "ro(lem (ecause the "rogram doesn7t even no! ho! large its client area is. +t (egins dis"laying the te4t at the to" o' the !indo! and relies on #indo!s to cli" everything that dri'ts (eyond the (ottom o' the client area. Clearly0 this is not desira(le. %ur 'irst 6o( in solving this "ro(lem is to determine ho! much o' the "rogram7s out"ut can actually 'it !ithin the client area.

%he ,iLe of the Client >rea


+' you e4"eriment !ith e4isting #indo!s a""lications0 you7ll 'ind that !indo! siPes can vary !idely. +' a !indo! is ma4imiPed0 the client area occu"ies nearly the entire video dis"lay. The dimensions o' a ma4imiPed client area are0 in 'act0 availa(le 'rom the 2et0#stemMetrics call (y using arguments o' S&9CA/.,,SC833N and S&9CN/.,,SC833N (assuming that the !indo! has only a title (ar and no menu*. The minimum siPe o' a !indo! can (e )uite smallSsometimes almost none4istentSvirtually eliminating the client area. +n the last cha"ter0 !e used the 2et$lient"ect 'unction 'or determining the dimensions o' the client area. There7s nothing really !rong !ith this 'unction0 (ut it7s a (it ine''icient to call it every time you need to use this in'ormation. 5 much (etter method 'or determining the siPe o' a !indo!7s client is to "rocess the #&9S+X3 message !ithin your !indo! "rocedure. #indo!s sends a #&9S+X3 message to a !indo! "rocedure !henever the siPe o' the !indo! changes. The l4aram varia(le "assed to the !indo! "rocedure contains the !idth o' the client area in the lo! !ord and the height in the high !ord. To save these dimensions0 you7ll !ant to de'ine t!o static varia(les in your !indo! "rocedure: static int c"4lient# c%4lient ; ,i e cx$har and c#$har0 these varia(les are de'ined as static (ecause they are set !hile "rocessing one message and used !hile "rocessing another message. Nou handle the #&9S+X3 method li e so:

case 8K&:=\P7 c"4lient ' LD8DUL (lCaram) ; c%4lient ' ?=8DUL (lCaram) ; return / ; Nou7ll see code li e this in virtually every #indo!s "rogram. ,%#%8D and -+#%8D are macros that are de'ined in the #indo!s header 'ile #+ND3/.-. +' you7re curious0 the de'initions o' these macros loo li e this: #define LD8DUL(l) ((8DUL)(l)) #define ?=8DUL(l) ((8DUL)(((L8DUL)(l) >> 1M) ] /"6666)) The t!o macros return #%8D valuesSthat is0 =C:(it unsigned short integers that range 'rom F through F4////. Ty"ically you7ll store these values in G;:(it signed integers. That doesn7t involve any conversion "ro(lems and ma es the values easier to use in any calculations you may later need. +n many #indo!s "rograms0 a #&9S+X3 message !ill eventually (e 'ollo!ed (y a #&9$5+NT message. -o! do !e no! thisW 1ecause !hen !e de'ine the !indo! class !e s"eci'y the class style as 4:&?UPLUF8 ^ 4:&_UPLUF8 This class style tells #indo!s to 'orce a re"aint i' either the horiPontal or vertical siPe changes. Nou can calculate the num(er o' 'ull lines o' te4t dis"laya(le !ithin the client area !ith the 'ormula: c%4lient 2 c%4har This can (e F i' the height o' the client area is too small to dis"lay a 'ull character. Similarly0 the a""ro4imate num(er o' lo!ercase characters you can dis"lay horiPontally !ithin the client area is e)ual to c"4lient 2 c"4har +' you determine cx$har and c#$har during the #&9C835T3 message0 don7t !orry a(out dividing (y F in these calculations. Nour !indo! "rocedure receives a #&9C835T3 message !hen &inMain calls $reate&indow. The 'irst #&9S+X3 message comes a little later0 !hen &inMain calls 0how&indow0 at !hich "oint cx$har and c#$har have already (een assigned "ositive nonPero values. Kno!ing the siPe o' the !indo!7s client area is the 'irst ste" in "roviding a !ay 'or the user to move the te4t !ithin the client area i' the client area is not large enough to hold everything. +' you7re 'amiliar !ith other #indo!s:(ased a""lications that have similar re)uirements0 you "ro(a(ly no! !hat !e need: this is a 6o( 'or those !onder'ul inventions no!n as scroll (ars.

Basic Drawing
The su(system o' &icroso't #indo!s res"onsi(le 'or dis"laying gra"hics on video dis"lays and "rinters is no!n as the 2ra"hics Device +nter'ace (2D+*. 5s you might imagine0 2D+ is an e4tremely im"ortant "art o' #indo!s. Not only do the a""lications you !rite 'or #indo!s use 2D+ 'or the dis"lay o' visual in'ormation0 (ut #indo!s itsel' uses 2D+ 'or the visual dis"lay o' user inter'ace items such as menus0 scroll (ars0 icons0 and mouse cursors. .n'ortunately0 a com"rehensive discussion o' 2D+ !ould re)uire an entire (oo 0 and this is not that (oo . +nstead0 in this cha"ter + !ant to "rovide you !ith the (asics o' dra!ing lines and 'illed areas. This is enough 2D+ to get you through the ne4t 'e! cha"ters. +n later cha"ters0 !e7ll loo at 2D+ su""ort o' (itma"s0 meta'iles0 and 'ormatted te4t.

%he ,tr$ct$re of 6D#


/rom the "rogrammer7s "ers"ective0 2D+ consists o' several hundred 'unction calls and some associated data ty"es0 macros0 and structures. 1ut (e'ore !e (egin loo ing at some o' these 'unctions in detail0 let7s ste" (ac and get a 'eel 'or the overall structure o' 2D+.

%he 6D# Philoso-h(


2ra"hics in #indo!s B^ and &icroso't #indo!s NT is handled "rimarily (y 'unctions e4"orted 'rom the dynamic: lin li(rary 2D+G;.D,,. +n #indo!s B^0 this 2D+G;.D,, ma es use o' the =C:(it 2D+.3A3 dynamic:lin li(rary 'or the actual im"lementation o' many o' the 'unctions. +n #indo!s NT0 2D+.3A3 is used only 'or =C:(it "rograms.

These dynamic:lin li(raries call routines in device drivers 'or the video dis"lay and any "rinters you may have set u". The video driver accesses the hard!are o' the video dis"lay0 and the "rinter driver converts 2D+ commands into codes or commands that the various "rinters understand. %(viously0 di''erent video dis"lay ada"ters and "rinters re)uire di''erent device drivers. 5 !ide variety o' dis"lay devices can (e attached to $C com"ati(les. %ne o' the "rimary goals o' 2D+ is to su""ort device:inde"endent gra"hics. #indo!s "rograms should (e a(le to run !ithout "ro(lems on any gra"hics out"ut device that #indo!s su""orts. 2D+ accom"lishes this goal (y "roviding 'acilities to insulate your "rograms 'rom the "articular characteristics o' di''erent out"ut devices. The !orld o' gra"hics out"ut devices is divided into t!o (road grou"s: raster devices and vector devices. &ost $C out"ut devices are raster devices0 !hich means that they re"resent images as a rectangular "attern o' dots. This category includes video dis"lay ada"ters0 dot:matri4 "rinters0 and laser "rinters. Vector devices0 !hich dra! images using lines0 are generally limited these days to "lotters. &uch o' traditional com"uter gra"hics "rogramming (the ty"e you7ll 'ind in older (oo s* is (ased solely on vectors. This means that a "rogram using a vector gra"hics system is a level o' a(straction a!ay 'rom the hard!are. The out"ut device uses "i4els 'or a gra"hics re"resentation0 (ut the "rogram doesn7t tal to the inter'ace in terms o' "i4els. #hile you can certainly use the #indo!s 2D+ as a high:level vector dra!ing system0 you can also use it 'or relatively lo!:level "i4el mani"ulation. +n this res"ect0 #indo!s 2D+ is to traditional gra"hics inter'ace languages !hat C is to other "rogramming languages. C is !ell no!n 'or its high degree o' "orta(ility among di''erent o"erating systems and environments. Net C is also !ell no!n 'or allo!ing a "rogrammer to "er'orm lo!:level system 'unctions that are o'ten im"ossi(le in other high:level languages. <ust as C is sometimes thought o' as a Ihigh:level assem(ly language0I you can thin o' 2D+ as a high:level inter'ace to the hard!are o' the gra"hics device. 5s you7ve seen0 (y de'ault #indo!s uses a coordinate system (ased on "i4els. &ost traditional gra"hics languages use a IvirtualI coordinate system !ith horiPontal and vertical a4es that range ('or instance* 'rom F to G;0DCD. 5lthough some gra"hics languages don7t let you use "i4el coordinates0 #indo!s 2D+ lets you use either system (as !ell as additional coordinate systems (ased on "hysical measurements*. Nou can use a virtual coordinate system and ee" your "rogram distanced 'rom the hard!are0 or you can use the device coordinate system and snuggle right u" to the hard!are. Some "rogrammers thin that !hen you7re !or ing in terms o' "i4els0 you7ve a(andoned device inde"endence. #e7ve already seen in the last cha"ter that this is not necessarily the case. The tric is to use the "i4els in a device: inde"endent manner. This re)uires that the gra"hics inter'ace language "rovide 'acilities 'or a "rogram to determine the hard!are characteristics o' the device and ma e a""ro"riate ad6ustments. /or e4am"le0 in the SNS&3TS "rograms !e used the "i4el siPe o' a standard system 'ont character to s"ace te4t on the screen. This a""roach allo!ed the "rograms to ad6ust to di''erent dis"lay ada"ters !ith di''erent resolutions0 te4t siPes0 and as"ect ratios. Nou7ll see other methods in this cha"ter 'or determining dis"lay siPes. +n the early days0 many users ran #indo!s !ith a monochrome dis"lay. 3ven in more recent years0 la"to" users !ere restricted to gray shades. /or this reason0 2D+ !as constructed so that you can !rite a "rogram !ithout !orrying much a(out colorSthat is0 #indo!s can convert colors to gray shades. 3ven today0 video dis"lays used !ith #indo!s B^ have di''erent color ca"a(ilities (=C color0 ;?C color0 Ihigh color0I and Itrue colorI*. 5lthough in :6et "rinters have (rought lo!:cost hard:co"y color to the masses0 many users still "re'er their (lac :only laser "rinters 'or high:)uality out"ut. +t is "ossi(le to use these devices (lindly0 (ut your "rogram can also determine ho! many colors are availa(le on the "articular dis"lay device and ta e (est advantage o' the hard!are. %' course0 6ust as you can !rite C "rograms that have su(tle "orta(ility "ro(lems !hen they run on other com"uters0 you can also inadvertently let device de"endencies cree" into your #indo!s "rograms. That7s "art o' the "rice o' not (eing 'ully insulated 'rom the hard!are. Nou should also (e a!are o' the limitations o' #indo!s 2D+. 5lthough you can certainly move gra"hics o(6ects around the dis"lay0 2D+ is generally a static dis"lay system !ith only limited animation su""ort. +' you need to !rite so"histicated animations 'or games0 you should e4"lore &icroso't DirectA0 !hich "rovides the su""ort you7ll need.

%he 6D# F$nction Calls


The several hundred 'unction calls that com"rise 2D+ can (e classi'ied in several (road grou"s: !unctions that get 6or create) and release 6or destro#) a device context 5s !e sa! in earlier "ages0 you need a handle to a device conte4t in order to dra!. The )egin4aint and ,nd4aint 'unctions (although technically a "art o' the .S38 module rather than the 2D+ module* let you do this during the #&9$5+NT

message0 and 2et'$ and "elease'$ 'unctions let you do this during other messages. #e7ll e4amine some other 'unctions regarding device conte4ts shortly. !unctions that obtain information about the device context +n the SNS&3TS "rograms earlier0 !e used the 2et.extMetrics 'unction to o(tain in'ormation a(out the dimensions o' the 'ont currently selected in the device conte4t. ,ater in this document0 !e7ll loo at the D3VC5$S= "rogram0 !hich o(tains other0 more general0 device conte4t in'ormation. !unctions that draw something %(viously0 once all the "reliminaries are out o' the !ay0 this is the really im"ortant stu''. +n the last cha"ter0 !e used the .ext>ut 'unction to dis"lay some te4t in the client area o' the !indo!. 5s !e7ll see0 other 2D+ 'unctions let us dra! lines and 'illed areas. !unctions that set and get attributes of the device context 5n Iattri(uteI o' the device conte4t determines various details regarding ho! the dra!ing 'unctions !or . /or e4am"le0 you can use 0et.ext$olor to s"eci'y the color o' any te4t you dra! using .ext>ut or other te4t out"ut 'unctions. +n the SNS&3TS "rograms in earlier0 !e used 0et.ext/lign to tell 2D+ that the starting "osition o' the te4t string in the .ext>ut 'unction should (e the right side o' the string rather than the le't0 !hich is the de'ault. 5ll attri(utes o' the device conte4t have de'ault values that are set !hen the device conte4t is o(tained. /or all 0et 'unctions0 there are 2et 'unctions that let you o(tain the current device conte4t attri(utes. !unctions that wor% with 2'* EobjectsE -ere7s !here 2D+ gets a (it messy. /irst an e4am"le: 1y de'ault0 any lines you dra! using 2D+ are solid and o' a standard !idth. Nou may !ish to dra! thic er lines or use lines com"osed o' a series o' dots or dashes. The line !idth and this line style are not attri(utes o' the device conte4t. +nstead0 they are characteristics o' a Ilogical "en.I Nou can thin o' a "en as a collection o' (undled attri(utes. Nou create a logical "en (y s"eci'ying these characteristics in the $reate4en0 $reate4en*ndirect0 or ,xt$reate4en 'unction. 5lthough these 'unctions are considered to (e "art o' 2D+0 unli e most 2D+ 'unctions they do not re)uire a handle to a device conte4t. The 'unctions return a handle to a logical "en. To use this "en0 you IselectI the "en handle into the device conte4t. The current "en selected in the device conte4t is considered an attri(ute o' the device conte4t. /rom then on0 !hatever lines you dra! use this "en. ,ater on0 you deselect the "en o(6ect 'rom the device conte4t and destroy the o(6ect. Destroying the "en is necessary (ecause the "en de'inition occu"ies allocated memory s"ace. 1esides "ens0 you also use 2D+ o(6ects 'or creating (rushes that 'ill enclosed areas0 'or 'onts0 'or (itma"s0 and 'or other as"ects o' 2D+.

%he 6D# Primitives


The ty"es o' gra"hics you dis"lay on the screen or the "rinter can themselves (e divided into several categories0 !hich are called I"rimitives.I These are: (ines and curves ,ines are the 'oundation o' any vector gra"hics dra!ing system. 2D+ su""orts straight lines0 rectangles0 elli"ses (including that su(set o' elli"ses no!n as circles*0 IarcsI that are "artial curves on the circum'erence o' an elli"se0 and 1ePier s"lines0 all o' !hich +7ll discuss in this cha"ter. +' you need to dra! a di''erent ty"e o' curve0 you can dra! it as a "olyline0 !hich is a series o' very short lines that de'ine a curve. 2D+ dra!s lines using the current "en selected in the device conte4t. !illed areas #henever a series o' lines or curves encloses an area0 you can cause that area to (e 'illed !ith the current 2D+ (rush o(6ect. This (rush can (e a solid color0 a "attern (!hich can (e a series o' horiPontal0 vertical0 or diagonal hatch mar s*0 or a (itma""ed image that is re"eated vertically or horiPontally !ithin the area. )itmaps 5 (itma" is a rectangular array o' (its that corres"ond to the "i4els o' a dis"lay device. The (itma" is the 'undamental tool o' raster gra"hics. 1itma"s are generally used 'or dis"laying com"le4 (o'ten real: !orld* images on the video dis"lay or "rinter. 1itma"s are also used 'or dis"laying small images that must (e dra!n very )uic ly0 such as icons0 mouse cursors0 and (uttons that a""ear in a""lication tool(ars. 2D+ su""orts t!o ty"es o' (itma"sSthe old (although still )uite use'ul* Idevice:de"endentI (itma"0 !hich is a 2D+ o(6ect0 and the ne!er (as o' #indo!s G.F* Idevice:inde"endentI (itma" (or D+1*0 !hich can (e stored in dis 'iles. .ext Te4t is not )uite as mathematical as other as"ects o' com"uter gra"hicsL instead it is (ound to hundreds o' years o' traditional ty"ogra"hy0 !hich many ty"ogra"hers and other o(servers a""reciate as an art. /or this reason0 te4t is o'ten the most com"le4 "art o' any com"uter gra"hics system0 (ut it is also (assuming literacy remains the norm* the most im"ortant. Data structures used 'or de'ining 2D+ 'ont

o(6ects and 'or o(taining 'ont in'ormation are among the largest in #indo!s. 1eginning !ith #indo!s G.=0 2D+ (egan su""orting TrueTy"e 'onts0 !hich are (ased on 'illed outlines that can (e mani"ulated !ith other 2D+ 'unctions. #indo!s B^ continues to su""ort the older (itma":(ased 'onts 'or com"ati(ility and small memory re)uirements.

Other ,t$ff
%ther as"ects o' 2D+ are not so easily classi'ia(le. These are: Mapping modes and transforms 5lthough (y de'ault you dra! in units o' "i4els0 you are not limited to doing that. The 2D+ ma""ing modes allo! you to dra! in units o' inches (or rather0 'ractions o' inches*0 millimeters0 or anything you !ant. +n addition0 #indo!s NT su""orts a traditional I!orld trans'ormI e4"ressed as a G:(y:G matri4. This allo!s 'or s e!ing and rotation o' gra"hics o(6ects. The !orld trans'orm is not su""orted under #indo!s B^. Metafiles 5 meta'ile is a collection o' 2D+ commands stored in a (inary 'orm. &eta'iles are used "rimarily to trans'er re"resentations o' vector gra"hic dra!ings through the cli"(oard. "egions 5 region is a com"le4 area o' any sha"e and is generally de'ined as a 1oolean com(ination o' sim"ler regions. &ore com"le4 regions can (e stored internally in 2D+ as a series o' scan lines derived 'rom the original de'inition o' the region. Nou can use regions 'or outlining0 'illing0 and cli""ing. 4aths 5 "ath is a collection o' straight lines and curves stored internally in 2D+. $aths can (e used 'or dra!ing0 'illing0 and cli""ing. $aths can also (e converted to regions. $lipping Dra!ing can (e restricted to a "articular section o' the client area. This is no!n as cli""ing. The cli""ing area can (e rectangular or nonrectangular0 generally s"eci'ied as a region or a "ath. 4alettes The use o' a customiPed "alette is generally restricted to dis"lays that sho! ;?C colors. #indo!s reserves only ;F o' these colors 'or use (y the system. Nou can alter the other ;GC colors to accurately dis"lay the colors o' real:!orld images stored in (itma"s. 4rinting 5lthough this cha"ter is restricted to the video dis"lay0 almost everything you learn here can (e a""lied to "rinting.

chF?(chF?d .htmc.htmc hF?(.hF?d. htmhtm

%he Device Conte=t


#hen you !ant to dra! on a gra"hics out"ut device such as the screen or "rinter0 you must 'irst o(tain a handle to a device conte4t (or DC*. +n giving your "rogram this handle0 #indo!s is giving you "ermission to use the device. Nou then include the handle as an argument to the 2D+ 'unctions to identi'y to #indo!s the device on !hich you !ish to dra!. The device conte4t contains many Iattri(utesI that determine ho! the 2D+ 'unctions !or on the device. These attri(utes allo! 2D+ 'unctions to have 6ust a 'e! arguments0 such as starting coordinates. The 2D+ 'unctions do not need arguments 'or everything else that #indo!s needs to dis"lay the o(6ect on the device. /or e4am"le0 !hen you call .ext>ut0 you need s"eci'y in the 'unction only the device conte4t handle0 the starting coordinates0 the te4t0 and the length o' the te4t. Nou don7t need to s"eci'y the 'ont0 the color o' the te4t0 the color o' the (ac ground (ehind the te4t0 or the intercharacter s"acing. These are all attri(utes that are "art o' the device conte4t. #hen you !ant to change one o' these attri(utes0 you call a 'unction that does so. Su(se)uent .ext>ut calls to that device conte4t use the ne! attri(ute.

6etting a Device Conte=t 'andle

#indo!s "rovides several methods 'or o(taining a device conte4t handle. +' you o(tain a video dis"lay device conte4t handle !hile "rocessing a message0 you should release it (e'ore e4iting the !indo! "rocedure. 5'ter you release the handle0 it is no longer valid. /or a "rinter device conte4t handle0 the rules are not as strict. The most common method 'or o(taining a device conte4t handle and then releasing it involves using the )egin4aint and ,nd4aint calls !hen "rocessing the #&9$5+NT message: hdc ' Ie+inCaint (h,nd# ]ps) ; [other pro"ram lines] PndCaint (h,nd# ]ps) ; The varia(le ps is a structure o' ty"e $5+NTST8.CT. The hdc 'ield o' this structure is the same handle to the device conte4t that )egin4aint returns. The $5+NST8.CT structure also contains a 83CT (rectangle* structure named rc4aint that de'ines a rectangle encom"assing the invalid region o' the !indo!7s client area. #ith the device conte4t handle o(tained 'rom )egin4aint you can dra! only !ithin this region. The )egin4aint call also validates this region. #indo!s "rograms can also o(tain a handle to a device conte4t !hile "rocessing messages other than #&9$5+NT: hdc ' YetL4 (h,nd) ; [other pro"ram lines] UeleaseL4 (h,nd# hdc) ; This device conte4t a""lies to the client area o' the !indo! !hose handle is hwnd. The "rimary di''erence (et!een the use o' these calls and the use o' the )egin4aint and ,nd4aint com(ination is that you can dra! on your entire client area !ith the handle returned 'rom 2et'$. -o!ever0 2et'$ and "elease'$ don7t validate any "ossi(ly invalid regions o' the client area. 5 #indo!s "rogram can also o(tain a handle to a device conte4t that a""lies to the entire !indo! and not only to the !indo!7s client area: hdc ' Yet8indo,L4 (h,nd) ; [other pro"ram lines] UeleaseL4 (h,nd# hdc) ; This device conte4t includes the !indo! title (ar0 menu0 scroll (ars0 and 'rame in addition to the client area. 5""lications "rograms rarely use the 2et&indow'$ 'unction. +' you !ant to e4"eriment !ith it0 you should also tra" the #&9NC$5+NT (Inonclient "aintI* message0 !hich is the message #indo!s uses to dra! on the nonclient areas o' the !indo!. The )egin4aint0 2et'$0 and 2et&indow'$ calls o(tain a device conte4t associated !ith a "articular !indo! on the video dis"lay. 5 much more general 'unction 'or o(taining a handle to a device conte4t is $reate'$: hdc ' 4reateL4 (ps@Lriver# ps@Levice# ps@Dutput# pLata) ; [other pro"ram lines] LeleteL4 (hdc) ; /or e4am"le0 you can o(tain a device conte4t handle 'or the entire dis"lay (y calling hdc ' 4reateL4 ((PW( ("L=:CLFG")# ;VLL# ;VLL# ;VLL) ; #riting outside your !indo! is generally im"olite0 (ut it7s convenient 'or some unusual a""lications. (5lthough this 'act is not documented0 you can also retrieve a device conte4t 'or the entire screen (y calling 2et'$ !ith a N.,, argument.* Sometimes you need only to o(tain some in'ormation a(out a device conte4t and not do any dra!ing. +n these cases0 you can o(tain a handle to an Iin'ormation conte4tI (y using $reate*$. The arguments are the same as 'or the $reate'$ 'unction. /or e4am"le0 hdc ' 4reate=4 ((PW( ("L=:CLFG")# ;VLL# ;VLL# ;VLL); Nou can7t !rite to the device (y using this in'ormation conte4t handle.

6etting Device Conte=t #nformation


5 device conte4t usually re'ers to a "hysical dis"lay device such as a video dis"lay or a "rinter. %'ten0 you need to o(tain in'ormation a(out this device0 including the siPe o' the dis"lay0 in terms o' (oth "i4els and "hysical dimensions0 and its color ca"a(ilities. Nou can get this in'ormation (y calling the 2et'evice$ap (Iget device ca"a(ilitiesI* 'unction: i_alue ' YetLevice4aps (hdc# i=nde") ;

The i*ndex argument is one o' ;B identi'iers de'ined in the #+N2D+.- header 'ile. /or e4am"le0 the i*ndex value o' -%8X83S causes 2et'evice$aps to return the !idth o' the device in "i4elsL a V38T83S argument returns the height o' the device in "i4els. +' hdc is a handle to a screen device conte4t0 that7s the same in'ormation you can get 'rom 2et0#stemMetrics. +' hdc is a handle to a "rinter device conte4t0 2et'evice$aps returns the height and !idth o' the "rinter dis"lay area in "i4els. Nou can also use 2et'evice$aps to determine the device7s ca"a(ilities o' "rocessing various ty"es o' gra"hics. This is usually not im"ortant 'or dealing !ith the video dis"lay0 (ut it (ecomes more im"ortant !ith !or ing !ith "rinters. /or e4am"le0 most "en "lotters can7t dra! (itma""ed images and 2et'evice$aps can tell you that.

%he D0?C>P,! Program


The D3VC5$S= "rogram0 sho!n in /igure (elo!0dis"lays some ((ut not all* o' the in'ormation availa(le 'rom the 2et'evice$aps 'unction using a device conte4t 'or the video dis"lay. Fig$re F-!A .he ',@$/408 program.

D0?C>P,!AC
23999999999999999999999999999999999999999999999999999999999 LP_4FC:1.4 99 Levice 4apa!ilities Lispla% Cro+ram ;o. 1 (c) 4harles Cet@old# 1SST 99999999999999999999999999999999999999999999999999999999932 #include <,indo,s.h> #define ;VKL=;P: ((int) (si@eof devcaps 2 si@eof devcaps Q/R)) struct { int i=nde" ; (4?FU 3 s@La!el ; (4?FU 3 s@Lesc ; devcaps QR ' { ?DU\:=\P# millimeters7")# _PU(:=\P# millimeters7")# ?DU\UP:# _PU(UP:# lines7")# I=(:C=WPL# pi"el7")# CLF;P:# planes7")# ;VKIUV:?P:# !rushes7")# ;VKCP;:# pens7")# ;VKKFUXPU:# mar0ers7")# ;VK6D;(:# fonts7")#

(PW( ("?DU\:=\P")# (PW( ("_PU(:=\P")# (PW( ("?DU\UP:")# (PW( ("_PU(UP:")# (PW( ("I=(:C=WPL")# (PW( ("CLF;P:")# (PW( (";VKIUV:?P:")# (PW( (";VKCP;:")# (PW( (";VKKFUXPU:")# (PW( (";VK6D;(:")#

(PW( ("8idth in (PW( ("?ei+ht in (PW( ("8idth in pi"els7")# (PW( ("?ei+ht in raster (PW( ("4olor !its per (PW( (";um!er of color (PW( (";um!er of device (PW( (";um!er of device (PW( (";um!er of device (PW( (";um!er of device

;VK4DLDU:# colors7")# CLP_=4P:=\P# structure7")# F:CP4(W# pi"el7")# F:CP4(G# pi"el7")# F:CP4(WG# pi"el7")# LDYC=WPL:W# inch7")# LDYC=WPL:G# inch7")# :=\PCFLP((P# entries7")# ;VKUP:PU_PL# entries7")# 4DLDUUP:# resolution7") ;

(PW( (";VK4DLDU:")# (PW( ("CLP_=4P:=\P")# (PW( ("F:CP4(W")# (PW( ("F:CP4(G")# (PW( ("F:CP4(WG")# (PW( ("LDYC=WPL:W")# (PW( ("LDYC=WPL:G")# (PW( (":=\PCFLP((P")# (PW( (";VKUP:PU_PL")# (PW( ("4DLDUUP:")#

(PW( (";um!er of device (PW( (":i@e of device (PW( ("Uelative ,idth of (PW( ("Uelative hei+ht of (PW( ("Uelative dia+onal of (PW( ("?ori@ontal dots per (PW( ("_ertical dots per (PW( (";um!er of palette (PW( ("Ueserved palette (PW( ("Fctual color

LUP:VL( 4FLLIF4X 8ndCroc (?8;L# V=;(# 8CFUFK# LCFUFK) ; int 8=;FC= 8inKain (?=;:(F;4P h=nstance# ?=;:(F;4P hCrev=nstance# C:(U s@4mdLine# int i4md:ho,) { static (4?FU s@Fpp;ameQR ' (PW( ("Lev4aps1") ; ?8;L h,nd ; K:Y ms+ ; 8;L4LF:: ,ndclass ; ,ndclass.st%le ,ndclass.lpfn8ndCroc ,ndclass.c!4lsP"tra ,ndclass.c!8ndP"tra ,ndclass.h=nstance ,ndclass.h=con ,ndclass.h4ursor ,ndclass.h!rIac0+round ,ndclass.lps@Kenu;ame ,ndclass.lps@4lass;ame ' ' ' ' ' ' ' ' ' ' 4:&?UPLUF8 ^ 4:&_UPLUF8 ; 8ndCroc ; / ; / ; h=nstance ; Load=con (;VLL# =L=&FCCL=4F(=D;) ; Load4ursor (;VLL# =L4&FUUD8) ; (?IUV:?) Yet:toc0D!$ect (8?=(P&IUV:?) ; ;VLL ; s@Fpp;ame ;

if (OUe+ister4lass (],ndclass)) { Kessa+eIo" (;VLL# (PW( ("(his pro+ram re5uires 8indo,s ;(O")# s@Fpp;ame# KI&=4D;PUUDU) ; return / ; h,nd ' 4reate8indo, (s@Fpp;ame# (PW( ("Levice 4apa!ilities")# 8:&D_PULFCCPL8=;LD8# 48&V:PLP6FVL(# 48&V:PLP6FVL(# 48&V:PLP6FVL(# 48&V:PLP6FVL(# ;VLL# ;VLL# h=nstance# ;VLL) ; :ho,8indo, (h,nd# i4md:ho,) ;

Vpdate8indo, (h,nd) ; ,hile (YetKessa+e (]ms+# ;VLL# /# /)) { (ranslateKessa+e (]ms+) ; LispatchKessa+e (]ms+) ; return ms+.,Caram ; LUP:VL( 4FLLIF4X lCaram) { static int (4?FU ?L4 int CF=;(:(UV4( (PW(KP(U=4 8ndCroc (?8;L h,nd# V=;( messa+e# 8CFUFK ,Caram# LCFUFK c"4har# c"4aps# c%4har ; s@IufferQ1/R ; hdc ; i ; ps ; tm ;

s,itch (messa+e) { case 8K&4UPF(P7 hdc ' YetL4 (h,nd) ; Yet(e"tKetrics (hdc# ]tm) ; c"4har ' tm.tmFve4har8idth ; c"4aps ' (tm.tmCitchFnd6amil% ] 1 < - 7 2) 3 c"4har 2 2 ; c%4har ' tm.tm?ei+ht * tm.tmP"ternalLeadin+ ; UeleaseL4 (h,nd# hdc) ; return / ; case 8K&CF=;(7 hdc ' Ie+inCaint (h,nd# ]ps) ; for (i ' / ; i < ;VKL=;P: ; i**) { (e"tDut (hdc# /# c%4har 3 i# devcapsQiR.s@La!el# lstrlen (devcapsQiR.s@La!el)) ; (e"tDut (hdc# 1H 3 c"4aps# c%4har 3 i# devcapsQiR.s@Lesc# lstrlen (devcapsQiR.s@Lesc)) ; :et(e"tFli+n (hdc# (F&U=Y?( ^ (F&(DC) ; (e"tDut (hdc# 1H 3 c"4aps * -. 3 c"4har# c%4har 3 i# s@Iuffer# ,sprintf (s@Iuffer# (PW( (").d")# YetLevice4aps (hdc# devcapsQiR.i=nde"))) ; :et(e"tFli+n (hdc# (F&LP6( ^ (F&(DC) ; PndCaint (h,nd# ]ps) ; return / ;

case 8K&LP:(UDG7 CostJuitKessa+e (/) ; return / ; return Lef8indo,Croc (h,nd# messa+e# ,Caram# lCaram) ; 5s you can see0 this "rogram is )uite similar to the SNS&3TS= "rogram sho!n earlier. To ee" the code short0 + didn7t include scroll (ars (ecause + ne! the in'ormation !ould 'it on one screen. The results 'or a ;?C:color0 C>F: (y:>^F V25 are sho!n here.

.he ',@$/408 displa# for a F=G-color GHI-b#-HJI @2/.

%he ,iLe of the Device


Su""ose you !ant to dra! a s)uare !ith sides that are = inch in length. To do this0 either you (the "rogrammer* or #indo!s (the o"erating system* !ould need to no! ho! many "i4els corres"onded to = inch on the video dis"lay. The 2et'evice$aps 'unction hel"s you o(tain in'ormation regarding the "hysical siPe o' the out"ut device0 (e it the video dis"lay or "rinter. Video dis"lays and "rinters are t!o very di''erent devices. 1ut "erha"s the least o(vious di''erence is ho! the !ord IresolutionI is used in connection !ith the device. #ith "rinters0 !e o'ten indicate a resolution in dots "er inch. /or e4am"le0 most laser "rinters have a resolution o' GFF or CFF dots "er inch. -o!ever0 the resolution o' a video dis"lay is given as the total num(er o' "i4els horiPontally and vertically0 'or e4am"le0 =F;> (y DC^. &ost "eo"le couldn7t tell you the total num(er o' "i4els their "rinters dis"lay horiPontally and vertically on a sheet o' "a"er or the num(er o' "i4els "er inch on their video dis"lays. +n this (oo +7m going to use the !ord IresolutionI in the strict sense o' a num(er o' "i4els "er metrical unit0 generally an inch. +7ll use the "hrase I"i4el siPeI or I"i4el dimensionI to indicate the total num(er o' "i4els that the device dis"lays horiPontally or vertically. The Imetrical siPeI or Imetrical dimensionI is the siPe o' the dis"lay area o' the device in inches or millimeters. (/or a "rinter "age0 this is not the !hole siPe o' the "a"er (ut only the "rinta(le area.* Dividing the "i4el siPe (y the metrical siPe gives you a resolution. &ost video dis"lays used !ith #indo!s these days have screens that are GG "ercent !ider than they are high. This re"resents an as"ect ratio o' =.GG:= or (as it7s more commonly !ritten* >:G. -istorically0 this as"ect ratio goes !ay (ac to !hen Thomas 3dison !as ma ing movies. +t remained the standard as"ect ratio 'or motion "ictures until various ty"es o' !idescreen "ro6ection started to (e used (eginning in =B?G. Television sets also have an as"ect ratio o' >:G.

-o!ever0 your #indo!s a""lications should not assume that the video dis"lay has a >:G as"ect ratio. $eo"le !ho do mostly !ord "rocessing sometimes "re'er a video dis"lay that resem(les the height and !idth o' a sheet o' "a"er. The most common alternative to a >:G dis"lay is a G:> dis"laySessentially a standard dis"lay turned on its side. +' the horiPontal resolution o' a device e)uals the vertical resolution0 the device is said to have Is)uare "i4els.I No!adays all video dis"lays in common use !ith #indo!s have s)uare "i4els0 (ut this !as not al!ays the case. (Nor should your a""lications assume that the video dis"lay al!ays has s)uare "i4els.* #hen #indo!s !as 'irst introduced0 the standard video ada"ter (oards !ere the +1& Color 2ra"hics 5da"ter (C25*0 !hich had a "i4el dimension area o' C>F (y ;FF "i4elsL the 3nhanced 2ra"hics 5da"ter (325*0 !hich had a "i4el dimension o' C>F (y G?F "i4elsL and the -ercules 2ra"hics Card0 !hich had a "i4el dimension o' D;F (y G>^ "i4els. 5ll these video (oards used a dis"lay that had a >:G as"ect ratio0 (ut the num(er o' "i4els horiPontally and vertically !as not in the ratio >:G. +t7s )uite easy 'or a user running #indo!s to determine the "i4el dimensions o' a video dis"lay. 8un the Dis"lay a""let in Control $anel0 and select the Settings ta(. +n the area la(eled Screen 5rea0 you7ll "ro(a(ly see one o' these "i4el dimensions: C>F (y >^F "i4els ^FF (y CFF "i4els =F;> (y DC^ "i4els =;^F (y =F;> "i4els =CFF (y =;FF "i4els 5ll o' these are in the ratio >:G. (#ell0 all e4ce"t the =;^F (y =F;> "i4el siPe. This should "ro(a(ly (e considered an annoying anomaly rather than anything more signi'icant. 5s !e7ll see0 all these "i4el dimensions !hen com(ined !ith a >:G monitor are considered to yield s)uare "i4els.* 5 #indo!s a""lication can o(tain the "i4el dimensions o' the dis"lay 'rom 2et0#stemMetrics !ith the S&9CASC833N and S&9CNSC833N arguments. 5s you7ll note 'rom the D3VC5$S= "rogram0 a "rogram can o(tain the same values 'rom 2et'evice$aps !ith the -%8X83S (IhoriPontal resolutionI* and V38T83S arguments. This is a use o' the !ord IresolutionI that means the "i4el siPe rather than the "i4els "er metrical unit. That7s the sim"le "art o' the device siPe. No! the con'usion (egins. The 'irst t!o device ca"a(ilities0 -%8XS+X3 and V38TS+X30 are documented as I#idth0 in millimeters0 o' the "hysical screenI and I-eight0 in millimeters0 o' the "hysical screenI (in 34latform 0'532raphics and Multimedia 0ervices32'*3'evice $ontexts3'evice $ontext "eference3'evice $ontext !unctions32et'evice$aps *. These seem li e straight'or!ard de'initions until one (egins to thin through their im"lications. /or e4am"le0 given the nature o' the inter'ace (et!een video dis"lay ada"ters and monitors0 ho! can #indo!s really no! the monitor siPeW 5nd !hat i' you have a la"to" (in !hich the video driver conceiva(ly could no! the e4act "hysical dimensions o' the screen* and you attach an e4ternal monitor to itW 5nd !hat i' you attach a video "ro6ector to your $CW +n the =C:(it versions o' #indo!s (and in #indo!s NT*0 #indo!s uses a IstandardI dis"lay siPe 'or the -%8XS+X3 and V38TS+X3 values. 1eginning !ith #indo!s B?0 ho!ever0 the -%8XS+X3 and V38TS+X3 values are derived 'rom the -%8X83S0 V38T83S0 ,%2$+A3,SA0 and ,%2$+A3,SN values. -ere7s ho! it !or s. #hen you use the Dis"lay a""let o' the Control $anel to select a "i4el siPe o' the dis"lay0 you can also select a siPe o' your system 'ont. The reason 'or this o"tion is that the 'ont used 'or the C>F (y >^F dis"lay may (e too small to read !hen you go u" to =F;> (y DC^ or (eyond. +nstead0 you7ll !ant a larger system 'ont. These system 'ont siPes are re'erred to on the Settings ta( o' the Dis"lay a""let as Small /onts and ,arge /onts. +n traditional ty"ogra"hy0 the siPe o' the characters in a 'ont is indicated (y a I"oint siPe.I 5 "oint is a""ro4imately =/D; inch and in com"uter ty"ogra"hy is o'ten assumed to (e e4actly =/D; inch. +n theory0 the "oint siPe o' a 'ont is the distance 'rom the to" o' the tallest character in the 'ont to the (ottom o' descenders in characters such as 60 "0 )0 and y0 e4cluding accent mar s. /or e4am"le0 in a =F:"oint 'ont this distance !ould (e =F/D; inch. +n terms o' the T3AT&3T8+C structure0 the "oint siPe o' the 'ont is e)uivalent to the tm-eight 'ield minus the tm*nternal(eading 'ield0 as sho!n in /igure (elo!.

.he small font and the .,C.M,."*$ fields. +n real:li'e ty"ogra"hy0 the "oint siPe o' a 'ont is not so "recisely related to the actual siPe o' the 'ont characters. The designer o' the 'ont might ma e the actual characters a (it larger or smaller than the "oint siPe !ould indicate. 5'ter all0 'ont design is an art rather than a science. The tm-eight 'ield o' the T3AT&3T8+C structure indicates ho! successive lines o' te4t should (e s"aced on the screen or "rinter. This can also (e measured in "oints. /or e4am"le0 a =;:"oint line s"acing indicates the (aselines o' successive lines o' te4t should (e =;/D; (or =/C* inch a"art. Nou don7t !ant to use =F:"oint line s"acing 'or a =F: "oint 'ont (ecause the successive lines o' te4t could actually touch each other. This (oo is "rinted !ith a =F:"oint 'ont and =G:"oint line s"acing. 5 =F:"oint 'ont is considered com'orta(le 'or reading. 5nything much smaller than =F "oints !ould (e di''icult to read 'or long "eriods o' time. The #indo!s system 'ontSregardless o' !hether it is the Ismall 'ontI or the Ilarge 'ontI and regardless o' !hat video "i4el dimension you7ve selectedSis assumed to (e a =F:"oint 'ont !ith a =;:"oint line s"acing. + no! this sounds odd. #hy call the system 'onts Ismall 'ontI and Ilarge 'ontI i' they7re (oth =F:"oint 'ontsW -ere7s the ey: &hen #ou select the small font or the large font in the 'ispla# applet of the $ontrol 4anel #ou are actuall# selecting an assumed video displa# resolution in dots per inch. #hen you select the small 'ont0 you are saying that you !ant #indo!s to assume that the video dis"lay resolution is BC dots "er inch. #hen you select the large 'ont0 you !ant #indo!s to assume that the video dis"lay resolution is =;F dots "er inch. ,oo at /igure ?:G again. That7s the small 'ont0 !hich is (ased on a dis"lay resolution o' BC dots "er inch. + said it7s a =F:"oint 'ont. Ten "oints is =F/D; inch0 !hich i' you multi"ly (y BC dots "er inch yields a result o' (a""ro4imately* =G "i4els. That7s tm-eight minus tm*nternal(eading. The line s"acing is =; "oints0 or =;/D; inch0 !hich multi"lied (y BC dots "er inch yields =C "i4els. That7s tm-eight. /igure sho!s the large 'ont. This is (ased on a resolution o' =;F dots "er inch. 5gain0 it7s a =F:"oint 'ont0 and =F/D; times =;F dots "er inch e)uals =C "i4els (i' you round do!n*0 !hich is tm-eight minus tm*nternal(eading. The =;: "oint line s"acing is e)uivalent to ;F "i4els0 !hich is tm-eight.

.he large font and the !>+.M,."*$ fields. #ithin a #indo!s "rogram you can use the 2et'evice$aps 'unction to o(tain the assumed resolution in dots "er inch that the user selected in the Dis"lay a""let o' the Control $anel. To get these valuesS!hich in theory could (e di''erent i' the video dis"lay doesn7t have s)uare "i4elsSyou use the indices ,%2$+A3,SA and ,%2$+A3,SN. The name ,%2$+A3,S stands 'or Ilogical "i4els0I !hich (asically means Inot the actual resolution in "i4els "er inch.I The device ca"a(ilities that you o(tain 'rom 2et'evice$aps !ith the -%8XS+X3 and V38TS+X3 indices are documented (as + indicated earlier* as I#idth0 in millimeters0 o' the "hysical screenI and I-eight0 in millimeters0 o' the "hysical screen.I These should (e documented as a Ilogical !idthI and a Ilogical height0I (ecause the values are derived 'rom the -%8X83S0 V38T83S0 ,%2$+A3,SA0 and ,%2$+A3,SN values. The 'ormulas are -orizontal 0ize 6mm) K F=.H L -orizontal "esolution 6pixels)3 (ogical 4ixels C 6dots per inch) @ertical 0ize 6mm) K F=.H L @ertical "esolution 6pixels)3 (ogical 4ixels A 6dots per inch) The ;?.> constant is necessary to convert 'rom inches to millimeters. This may seem (ac !ard and illogical. 5'ter all0 your video dis"lay has a siPe in millimeters that you can actually measure !ith a ruler (at least a""ro4imately*. 1ut #indo!s B^ doesn7t care a(out that siPe. +nstead it calculates a dis"lay siPe in millimeters (ased on the "i4el siPe o' the dis"lay the user selects and also the resolution the user selects 'or siPing the system 'ont. Change the "i4el siPe o' your dis"lay and according to 2et'evice$aps the metrical siPe changes. -o! much sense does that ma eW +t ma es more sense than you might sus"ect. ,et7s su""ose you have a =D:inch monitor. The actual dis"lay siPe !ill "ro(a(ly (e a(out =; inches (y B inches. Su""ose you !ere running #indo!s !ith the minimum re)uired "i4el dimensions o' C>F (y >^F. This means that the actual resolution is ?G dots "er inch. 5 =F:"oint 'ontS"er'ectly reada(le on "a"erSon the screen !ould (e only D "i4els in height 'rom the to" o' the 5 to the (ottom o' the ). Such a 'ont !ould (e ugly and 6ust a(out unreada(le. (5s "eo"le !ho ran #indo!s on the old Color 2ra"hics 5da"ter.* No! hoo u" a video "ro6ector to your $C. ,et7s say the "ro6ected video dis"lay is a > 'eet !ide and G 'eet high. That same C>F (y >^F "i4el dimension no! im"lies a resolution o' a(out =G dots "er inch. +t !ould (e ridiculous to try dis"laying a =F:"oint 'ont under such conditions. 5 =F:"oint 'ont should (e reada(le on the video dis"lay (ecause it is surely reada(le !hen "rinted. The =F:"oint 'ont thus (ecomes an im"ortant 'rame o' re'erence. #hen a #indo!s a""lication is guaranteed that a =F:"oint screen 'ont is o' average siPe0 it can then dis"lay smaller ((ut still reada(le* te4t using an ^:"oint 'ont and larger te4t using 'onts o' "oint siPes greater than =F. Thus0 it ma es sense that the video resolution (in dots "er inch* (e im"lied (y the "i4el siPe o' that =F:"oint 'ont. +n #indo!s NT0 ho!ever0 an older a""roach is used in de'ining the -%8XS+X3 and V38TS+X3 values. This a""roach is consistent !ith =C:(it versions o' #indo!s. The -%8X83S and V38T83S values still indicate the num(er o' "i4els horiPontally and vertically (o' course*0 and ,%2$+A3,SA and ,%2$+A3,SN are still related to the 'ont that you choose !hen setting the video resolution in the Dis"lay a""let o' the Control $anel. 5s !ith #indo!s B^0 ty"ical values o' ,%2$+A3,SA and ,%2$+A3,SN are BC and =;F dots "er inch0 de"ending on !hether you select a small 'ont or large 'ont.

The di''erence in #indo!s NT is that the -%8XS+X3 and V38TS+X3 values are 'i4ed to indicate a standard monitor siPe. /or common ada"ters0 the values o' -%8XS+X3 and V38TS+X3 you7ll o(tain are G;F and ;>F millimeters0 res"ectively. These values are the same regardless o' !hat "i4el dimension you choose. There'ore0 these values are inconsistent !ith the values you o(tain 'rom 2et'evice$aps !ith the -%8X83S0 V38T83S0 ,%2$+A3,SA0 and ,%2$+A3,SN indices. -o!ever0 you can al!ays calculate -%8XS+X3 and V38TS+X3 values li e those you7d o(tain under #indo!s B^ (y using the 'ormulas sho!n earlier. #hat i' your "rogram needs the actual "hysical dimensions o' the video dis"layW $ro(a(ly the (est solution is to actually re)uest them o' the user !ith a dialog (o4. /inally0 three other values 'rom 2et'evice$aps are related to the video dimensions. The 5S$3CTA0 5S$3CTN0 and 5S$3CTAN values are the relative !idth0 height0 and diagonal siPe o' each "i4el0 rounded to the nearest integer. /or s)uare "i4els0 the 5S$3CTA and 5S$3CTN values !ill (e the same. 8egardless0 the 5S$3CTAN value e)uals the s)uare root o' the sum o' the s)uares o' the 5S$3CTA and 5S$3CTN values0 as you7ll recall 'rom $ythagoras.

Finding O$t >/o$t Color


5 video dis"lay ca"a(le o' dis"laying only (lac "i4els and !hite "i4els re)uires only one (it o' memory "er "i4el. Color dis"lays re)uire multi"le (its "er "i4els. The more (its0 the more colorsL or more s"eci'ically0 the num(er o' uni)ue simultaneous colors is e)ual to ; to the num(er o' (its "er "i4el. 5 I'ull colorI video dis"lay resolution has ;> (its "er "i4elS^ (its 'or red0 ^ (its 'or green0 and ^ (its 'or (lue. 8ed0 green0 and (lue are no!n as the Iadditive "rimaries.I &i4es o' these three "rimary colors can create many other colors0 as you can veri'y (y "eering at your color video dis"lay through a magni'ying glass. 5 Ihigh colorI dis"lay resolution has =C (its "er "i4el0 generally ? (its 'or red0 C (its 'or green0 and ? (its 'or (lue. &ore (its are used 'or the green "rimary (ecause the human eye is more sensitive to variations in green than to the other t!o "rimaries. 5 video ada"ter that dis"lays ;?C colors re)uires ^ (its "er "i4el. -o!ever0 these ^:(it values are generally indices into a "alette ta(le that de'ines the actual colors. /inally0 a video (oard that dis"lays =C colors re)uires > (its "er "i4el. These =C colors are generally 'i4ed as dar and light versions o' red0 green0 (lue0 cyan0 magenta0 yello!0 t!o shades o' gray0 (lac 0 and !hite. These =C colors date (ac to the old +1& C25. %nly in some odd "rogramming 6o(s is it necessary to no! ho! memory is organiPed on the video ada"ter (oard0 (ut 2et'evice$aps !ill hel" you determine that. Video memory can (e organiPed either !ith consecutive color (its 'or each "i4el or !ith each color (it in a se"arate "lane o' memory. This call returns the num(er o' color "lanes: iClanes ' YetLevice4aps (hdc# CLF;P:) ; and this call returns the num(er o' color (its "er "i4el: iIitsCi"el ' YetLevice4aps (hdc# I=(:C=WPL) ; %ne o' these calls !ill return a value o' =. The num(er o' colors that can (e simultaneously rendered on the video ada"ter can (e calculated (y the 'ormula i4olors ' 1 << (iClanes 3 iIitsCi"el) ; This value may or may not (e the same as the num(er o' colors o(taina(le !ith the N.&C%,%8S argument: i4olors ' YetLevice4aps (hdc# ;VK4DLDU:) ; + mentioned that ;?C:color video ada"ters use color "alettes. +n that case0 2et'evice$aps !ith the N.&C%,%8S inde4 returns the num(er o' colors reserved (y #indo!s0 !hich !ill (e ;F. The remaining ;GC colors can (e set (y a #indo!s "rogram using the "alette manager. /or high:color and 'ull:color dis"lay resolutions0 2et'evice$aps !ith the N.&C%,%8S inde4 o'ten returns :=0 ma ing it a generally unrelia(le 'unction 'or determining this in'ormation. +nstead0 use the i$olors 'ormula sho!n earlier that uses the $,5N3S and 1+TS$+A3, values. +n most 2D+ 'unction calls0 you use a C%,%883/ value (!hich is sim"ly a G;:(it unsigned long integer* to re'er to a "articular color. The C%,%883/ value s"eci'ies a color in terms o' red0 green0 and (lue intensities and is o'ten called an I821 color.I The G; (its o' the C%,%883/ value are set as sho!n in /igure (elo!.

.he MF-bit $>(>"",! value.

Notice that the most:signi'icant ^ (its are Pero0 and that each "rimary is s"eci'ied as an ^:(it value. +n theory0 a C%,%883/ value can re'er to ;;> or a(out =C million colors. The #indo!s header 'ile #+N2D+.- "rovides several macros 'or !or ing !ith 821 color values. The "2) macro ta es three arguments re"resenting red0 green0 and (lue values and com(ines them into an unsigned long: #define UYI(r#+#!) ((4DLDUUP6)(((IG(P)(r) ^ \ ((8DUL)((IG(P)(+)) << T)) ^ \ (((L8DUL)(IG(P)(!)) << 1M))) Notice that the order o' the three arguments is red0 green0 and (lue. Thus0 the value 821 (;??0 ;??0 F* is F4FFFF//// or yello!Sthe com(ination o' red and green. #hen all three arguments are set to F0 the color is (lac L !hen all the arguments are set to ;??0 the color is !hite. The 2et"@alue0 2et2@alue0 and 2et)@alue macros e4tract the "rimary color values 'rom a C%,%883/ value. These macros are sometimes handy !hen you7re using a #indo!s 'unction that returns 821 color values to your "rogram. %n =C:color or ;?C:color video ada"ters0 #indo!s can use IditheringI to simulate more colors than the device can dis"lay. Dithering involves a small "attern that com(ines "i4els o' di''erent colors. Nou can determine the closest "ure nondithered color o' a "articular color value (y calling 2et+earest$olor: crCure4olor ' Yet;earest4olor (hdc# cr4olor) ;

%he Device Conte=t >ttri/$tes


5s + noted a(ove0 #indo!s uses the device conte4t to store Iattri(utesI that govern ho! the 2D+ 'unctions o"erate on the dis"lay. /or instance0 !hen you dis"lay some te4t using the .ext>ut 'unction0 you don7t have to s"eci'y the color o' the te4t or the 'ont. #indo!s uses the device conte4t to o(tain this in'ormation. #hen a "rogram o(tains a handle to a device conte4t0 #indo!s sets all the attri(utes to de'ault values. (-o!ever0 see the ne4t section 'or ho! to override this (ehavior.* The 'ollo!ing ta(le sho!s many o' the device conte4t attri(utes su""orted under #indo!s B^0 along !ith the de'ault values and the 'unctions to change or o(tain their values. Device Conte=t Defa$lt F$nction3s5 to Change F$nction to O/tain >ttri/$te &a""ing &ode &&9T3A 0etMapMode 2etMapMode T #indo! %rigin (F0 F* 0et&indow>rg,x 2et&indow>rg,x >ffset&indow>rg,x Vie!"ort %rigin (F0 F* 0et@iewport>rg,x 2et@iewport>rg,x >ffset@iewport>rg,x #indo! 34tents (=0 =* 0et&indow,xt,x 2et&indow,xt,x 0etMapMode 0cale&indow,xt,x Vie!"ort 34tents (=0 =* 0et@iewport,xt,x 0etMapMode 2et@iewport,xt,x 0cale@iewport,xt,x $en 1,5CK9$ 0elect>bject 0elect>bject 3N 1rush #-+T391 0elect>bject 0elect>bject 8.S/ont SNST3&9 0elect>bject 0elect>bject /%NT 1itma" None 0elect>bject 0elect>bject Current $osition (F0 F* Move.o,x 2et$urrent4osition (ine.o ,x 4ol#line.o 4ol#)ezier.o 1ac ground &ode %$5@.3 0et)%Mode 2et)%Mode 1ac ground Color #hite 0et)%$olor 2et)%$olor Te4t Color 1lac 0et.ext$olor 2et.ext$olor Dra!ing &ode 8;9C%$N 0et">4F 2et">4F

Stretching &ode $olygon /ill &ode +ntercharacter S"acing 1rush %rigin Cli""ing 8egion

$3N 1,5CK% N#-+T3 5,T38N 5T3 F (F0 F* None

0et0tretch)ltMode 0et4ol#!illMode 0et.ext$haracter,xtra 0et)rush>rg,x 0elect>bject 0elect$lip"gn *ntersect$lip"gn >ffset$lip"gn ,xclude$lip"ect 0elect$lip4ath

2et0tretch)ltMode 2et4ol#!illMode 2et.ext$haracter, xtra 2et)rush>rg,x 2et$lip)ox

,aving Device Conte=ts


Normally !hen you call 2et'$ or )egin4aint0 #indo!s gives you a device conte4t !ith de'ault values 'or all the attri(utes. 5ny changes you ma e to the attri(utes are lost !hen the device conte4t is released !ith the "elease'$ or ,nd4aint call. +' your "rogram needs to use nonde'ault device conte4t attri(utes0 you7ll have to initialiPe the device conte4t every time you o(tain a ne! device conte4t handle: case 8K&CF=;(7 hdc ' Ie+inCaint (h,nd# ]ps) ; [initialize device context attributes] [paint client area of window] PndCaint (h,nd# ]ps) ; return / ; 5lthough this a""roach is generally satis'actory0 you might "re'er that changes you ma e to the attri(utes (e saved !hen you release the device conte4t so that they !ill (e in e''ect the ne4t time you call 2et'$ or )egin4aint. Nou can accom"lish this (y including the CS9%#NDC 'lag as "art o' the !indo! class style !hen you register the !indo! class: ,ndclass.st%le ' 4:&?UPLUF8 ^ 4:&_UPLUF8 ^ 4:&D8;L4 ; No! each !indo! that you create (ased on this !indo! class !ill have its o!n "rivate device conte4t that continues to e4ist !hen the !indo! is destroyed. #hen you use the CS9%#NDC style0 you need to initialiPe the device conte4t attri(utes only once0 "erha"s !hile "rocessing the #&9C835T3 message: case 8K&4UPF(P7 hdc ' YetL4 (h,nd) ; [initialize device context attributes] UeleaseL4 (h,nd# hdc) ; The attri(utes continue to (e valid until you change them. The CS9%#NDC style a''ects only the device conte4ts retrieved 'rom 2et'$ and )egin4aint and not device conte4ts o(tained 'rom the other 'unctions (such as 2et&indow'$*. 3m"loying CS9%#NDC !as once discouraged (ecause it re)uired some memory overheadL no!adays it can im"rove "er'ormance in some gra"hics: intensive #indo!s NT a""lications. 3ven i' you use CS9%#NDC0 you should still release the device conte4t handle (e'ore e4iting the !indo! "rocedure. +n some cases you might !ant to change certain device conte4t attri(utes0 do some "ainting using the changed attri(utes0 and then revert to the original device conte4t. To sim"li'y this "rocess0 you save the state o' a device conte4t (y calling id:aved ' :aveL4 (hdc) ; No! you can change some attri(utes. #hen you !ant to return to the device conte4t as it e4isted (e'ore the 0ave'$ call0 you use UestoreL4 (hdc# id:aved) ; Nou can call 0ave'$ any num(er o' times (e'ore you call "estore'$. &ost "rogrammers use 0ave'$ and "estore'$ in a di''erent manner0 ho!ever0 much li e $.S- and $%$ instructions in assem(ly language. #hen you call 0ave'$0 you don7t need to save the return value:

:aveL4 (hdc) ; Nou can then change some attri(utes and call 0ave'$ again. To restore the device conte4t to a saved state0 call UestoreL4 (hdc# 91) ; This restores the device conte4t to the state saved (y the most recent 0ave'$ 'unction.

Drawing Dots and &ines


+n the (egnng 0 + discussed ho! the #indo!s 2ra"hics Device +nter'ace ma es use o' device drivers 'or the gra"hics out"ut devices attached to your com"uter. +n theory0 all that a gra"hics device driver needs 'or dra!ing is a 0et4ixel 'unction and a 2et4ixel 'unction. 3verything else could (e handled !ith higher:level routines im"lemented in the 2D+ module. Dra!ing a line0 'or instance0 sim"ly re)uires that 2D+ call the 0et4ixel routine numerous times0 ad6usting the 4: and y:coordinates a""ro"riately. +n reality0 you can indeed do almost any dra!ing you need !ith only 0et4ixel and 2et4ixel 'unctions. Nou can also design a neat and !ell:structured gra"hics "rogramming system on to" o' these 'unctions. The only "ro(lem is "er'ormance. 5 'unction that is several calls a!ay 'rom each 0et4ixel 'unction !ill (e "ain'ully slo!. +t is much more e''icient 'or a gra"hics system to do line dra!ing and other com"le4 gra"hics o"erations at the level o' the device driver0 !hich can have its o!n o"timiPed code to "er'orm the o"erations. &oreover0 some video ada"ter (oards contain gra"hics co"rocessors that allo! the video hard!are itsel' to dra! the 'igures.

,etting Pi=els
3ven though the #indo!s 2$+ includes 0et4ixel and 2et4ixel 'unctions0 they are not commonly used. The 0et4ixel 'unction sets the "i4el at a s"eci'ied 4: and y:coordinate to a "articular color: :etCi"el (hdc# "# %# cr4olor) ; 5s in any dra!ing 'unction0 the 'irst argument is a handle to a device conte4t. The second and third arguments indicate the coordinate "osition. &ostly you7ll o(tain a device conte4t 'or the client area o' your !indo!0 and x and # !ill (e relative to the u""er le't corner o' that client area. The 'inal argument is o' ty"e C%,%883/ to s"eci'y the color. +' the color you s"eci'y in the 'unction cannot (e realiPed on the video dis"lay0 the 'unction sets the "i4el to the nearest "ure nondithered color and returns that value 'rom the 'unction. The 2et4ixel 'unction returns the color o' the "i4el at the s"eci'ied coordinate "osition: cr4olor ' YetCi"el (hdc# "# %) ;

,traight &ines
#indo!s can dra! straight lines0 elli"tical lines (curved lines on the circum'erence o' an elli"se*0 and 1ePier s"lines. #indo!s B^ su""orts seven 'unctions that dra! lines: (ine.o Dra!s a straight line. 4ol#line and 4ol#line.o Dra! a series o' connected straight lines. 4ol#4ol#line Dra!s multi"le "olylines. /rc Dra!s elli"tical lines. 4ol#)ezier and 4ol#)ezier.o Dra! 1ePier s"lines. +n addition0 #indo!s NT su""orts three more line:dra!ing 'unctions: /rc.o and /ngle/rc Dra! elli"tical lines. 4ol#'raw Dra!s a series o' connected straight lines and 1ePier s"lines. These three 'unctions are not su""orted under #indo!s B^. ,ater in this cha"ter +7ll also (e discussing some 'unctions that dra! lines (ut that also 'ill the enclosed area !ithin the 'igure they dra!. These 'unctions are "ectangle Dra!s a rectangle. ,llipse Dra!s an elli"se. "ound"ect Dra!s a rectangle !ith rounded corners. 4ie Dra!s a "art o' an elli"se that loo s li e a "ie slice.

$hord Dra!s "art o' an elli"se 'ormed (y a chord. /ive attri(utes o' the device conte4t a''ect the a""earance o' lines that you dra! using these 'unctions: current "en "osition ('or (ine.o0 4ol#line.o0 4ol#)ezier.o0 and /rc.o only*0 "en0 (ac ground mode0 (ac ground color0 and dra!ing mode. To dra! a straight line0 you must call t!o 'unctions. The 'irst 'unction s"eci'ies the "oint at !hich the line (egins0 and the second 'unction s"eci'ies the end "oint o' the line: Kove(oP" (hdc# "Ie+# %Ie+# ;VLL) ; Line(o (hdc# "Pnd# %Pnd) ; Move.o,x doesn7t actually dra! anythingL instead0 it sets the attri(ute o' the device conte4t no!n as the Icurrent "osition.I The (ine.o 'unction then dra!s a straight line 'rom the current "osition to the "oint s"eci'ied in the (ine.o 'unction. The current "osition is sim"ly a starting "oint 'or several other 2D+ 'unctions. +n the de'ault device conte4t0 the current "osition is initially set to the "oint (F0 F*. +' you call (ine.o !ithout 'irst setting the current "osition0 it dra!s a line starting at the u""er le't corner o' the client area. 5 (rie' historical note: +n the =C:(it versions o' #indo!s0 the 'unction to set the current "osition !as Move.o. This 'unction had 6ust three argumentsSthe device conte4t handle and 4: and y:coordinates. The 'unction returned the "revious current "osition "ac ed as t!o =C:(it values in a G;:(it unsigned long. -o!ever0 in the G;:(it versions o' #indo!s0 coordinates are G;:(it values. 1ecause the G;:(it versions o' C do not de'ine a C>:(it integral data ty"e0 this change meant that Move.o could no longer indicate the "revious current "osition in its return value. 5lthough the return value 'rom Move.o !as almost never used in real:li'e "rogramming0 a ne! 'unction !as re)uired0 and this !as Move.o,x. The last argument to Move.o,x is a "ointer to a $%+NT structure. %n return 'rom the 'unction0 the x and # 'ields o' the $%+NT structure !ill indicate the "revious current "osition. +' you don7t need this in'ormation (!hich is almost al!ays the case*0 you can sim"ly set the last argument to N.,, as in the e4am"le sho!n a(ove. 5nd no! the caveat: 5lthough coordinate values in #indo!s B^ a""ear to (e G;:(it values0 only the lo!er =C (its are used. Coordinate values are e''ectively restricted to :G;0DC^ to G;0DCD. +n #indo!s NT0 the 'ull G;:(it values are used. +' you ever need the current "osition0 you can o(tain it (y calling Yet4urrentCositionP" (hdc# ]pt) ; !here pt is a $%+NT structure. The 'ollo!ing code dra!s a grid in the client area o' a !indo!0 s"acing the lines =FF "i4els a"art starting 'rom the u""er le't corner. The varia(le hwnd is assumed to (e a handle to the !indo!0 hdc is a handle to the device conte4t0 and x and # are integers: Yet4lientUect (h,nd# ]rect) ; for (" ' / ; " < rect.ri+ht ; "*' 1//) { Kove(oP" (hdc# "# /# ;VLL) ; Line(o (hdc# "# rect.!ottom) ; for (% ' / ; % < rect.!ottom ; % *' 1//) { Kove(oP" (hdc# /# %# ;VLL) ; Line(o (hdc# rect.ri+ht# %) ; 5lthough it seems li e a nuisance to (e 'orced to use t!o 'unctions to dra! a single line0 the current "osition comes in handy !hen you !ant to dra! a series o' connected lines. /or instance0 you might !ant to de'ine an array o' ? "oints (=F values* that de'ine the outline o' a rectangle: CD=;( aptQ.R ' { 1//# 1//# 2//# 1//# 2//# 2//# 1//# 2//# 1//# 1// ; Notice that the last "oint is the same as the 'irst. No! you need only use Move.o,x 'or the 'irst "oint and (ine.o 'or the successive "oints: Kove(oP" (hdc# aptQ/R."# aptQ/R.%# ;VLL) ; for (i ' 1 ; i < . ; i**) Line(o (hdc# aptQiR."# aptQiR.%) ; 1ecause (ine.o dra!s 'rom the current "osition u" to ((ut not including* the "oint in the (ine.o 'unction0 no coordinate gets !ritten t!ice (y this code. #hile over!riting "oints is not a "ro(lem !ith a video dis"lay0 it might not loo good on a "lotter or !ith some dra!ing modes that +7ll discuss later in this cha"ter.

#hen you have an array o' "oints that you !ant connected !ith lines0 you can dra! the lines more easily using the 4ol#line 'unction. This statement dra!s the same rectangle as in the code sho!n a(ove: Col%line (hdc# apt# .) ; The last argument is the num(er o' "oints. #e could also have re"resented this value (y sizeof 6apt) 3 sizeof 64>*+.). 4ol#line has the same e''ect on dra!ing as an initial Move.o,x 'ollo!ed (y multi"le (ine.o 'unctions. -o!ever0 4ol#line doesn7t use or change the current "osition. 4ol#line.o is a little di''erent. This 'unction uses the current "osition 'or the starting "oint and sets the current "osition to the end o' the last line dra!n. The code (elo! dra!s the same rectangle as that last sho!n a(ove: Kove(oP" (hdc# aptQ/R."# aptQ/R.%# ;VLL) ; Col%line(o (hdc# apt * 1# H) ; 5lthough you can use 4ol#line and 4ol#line.o to dra! 6ust a 'e! lines0 the 'unctions are most use'ul !hen you need to dra! a com"le4 curve. Nou do this (y using hundreds or even thousands o' very short lines. +' they7re short enough and there are enough o' them0 together they7ll loo li e a curve. /or e4am"le0 su""ose you need to dra! a sine !ave. The S+N3#5V3 "rogram sho!s ho! to do it. .he 0*+,&/@, program.

,#)0W>?0AC
2399999999999999999999999999999999999999999 :=;P8F_P.4 99 :ine 8ave Vsin+ Col%line (c) 4harles Cet@old# 1SST 9999999999999999999999999999999999999999932 #include <,indo,s.h> #include <math.h> #define ;VK #define (8DC= 1/// (2 3 -.1H1.S)

LUP:VL( 4FLLIF4X 8ndCroc (?8;L# V=;(# 8CFUFK# LCFUFK) ; int 8=;FC= 8inKain (?=;:(F;4P h=nstance# ?=;:(F;4P hCrev=nstance# C:(U s@4mdLine# int i4md:ho,) { static (4?FU s@Fpp;ameQR ' (PW( (":ine8ave") ; ?8;L h,nd ; K:Y ms+ ; 8;L4LF:: ,ndclass ; ,ndclass.st%le ,ndclass.lpfn8ndCroc ,ndclass.c!4lsP"tra ,ndclass.c!8ndP"tra ,ndclass.h=nstance ,ndclass.h=con ,ndclass.h4ursor ,ndclass.h!rIac0+round ,ndclass.lps@Kenu;ame ,ndclass.lps@4lass;ame ' ' ' ' ' ' ' ' ' ' 4:&?UPLUF8 ^ 4:&_UPLUF8 ; 8ndCroc ; / ; / ; h=nstance ; Load=con (;VLL# =L=&FCCL=4F(=D;) ; Load4ursor (;VLL# =L4&FUUD8) ; (?IUV:?) Yet:toc0D!$ect (8?=(P&IUV:?) ; ;VLL ; s@Fpp;ame ;

if (OUe+ister4lass (],ndclass)) { Kessa+eIo" (;VLL# (PW( ("Cro+ram re5uires 8indo,s ;(O")# s@Fpp;ame# KI&=4D;PUUDU) ; return / ;

h,nd ' 4reate8indo, (s@Fpp;ame# (PW( (":ine 8ave Vsin+ Col%line")# 8:&D_PULFCCPL8=;LD8# 48&V:PLP6FVL(# 48&V:PLP6FVL(# 48&V:PLP6FVL(# 48&V:PLP6FVL(# ;VLL# ;VLL# h=nstance# ;VLL) ; :ho,8indo, (h,nd# i4md:ho,) ; Vpdate8indo, (h,nd) ; ,hile (YetKessa+e (]ms+# ;VLL# /# /)) { (ranslateKessa+e (]ms+) ; LispatchKessa+e (]ms+) ; return ms+.,Caram ; LUP:VL( 4FLLIF4X lCaram) { static int ?L4 int CF=;(:(UV4( CD=;( 8ndCroc (?8;L h,nd# V=;( messa+e# 8CFUFK ,Caram# LCFUFK c"4lient# c%4lient ; hdc ; i ; ps ; apt Q;VKR ;

s,itch (messa+e) { case 8K&:=\P7 c"4lient ' LD8DUL (lCaram) ; c%4lient ' ?=8DUL (lCaram) ; return / ; case 8K&CF=;(7 hdc ' Ie+inCaint (h,nd# ]ps) ; Kove(oP" (hdc# /# c%4lient 2 2# ;VLL) ; Line(o (hdc# c"4lient# c%4lient 2 2) ; for (i ' / ; i < ;VK ; i**) { aptQiR." ' i 3 c"4lient 2 ;VK ; aptQiR.% ' (int) (c%4lient 2 2 3 (1 9 sin ((8DC= 3 i 2 ;VK))) ; Col%line (hdc# apt# ;VK) ; return / ; case 8K&LP:(UDG7 CostJuitKessa+e (/) ; return / ; return Lef8indo,Croc (h,nd# messa+e# ,Caram# lCaram) ;

The "rogram has an array o' =FFF $%+NT structures. 5s the for loo" is incremented 'rom F through BBB0 the x 'ields o' the $%+NT structure are set to incrementally increasing values 'rom F to cx$lient. The "rogram sets the # 'ields o' the $%+NT structure to sine curve values 'or one cycle and enlarged to 'ill the client area. The !hole curve is dra!n using a single 4ol#line call. 1ecause the 4ol#line 'unction is im"lemented at the device driver level0 it is 'aster than calling (ine.o =FFF times. The results are sho!n here

.he 0*+,&/@, displa#.

Child Window Controls


5s !e7ve (een doing 0 to create your normal a""lication !indo! you 'irst de'ine a !indo! class and register it !ith #indo!s using "egister$lass. Nou then create the !indo! (ased on that class using $reate&indow. #hen you use one o' the "rede'ined controls0 ho!ever0 you do not register a !indo! class 'or the child !indo!. The class already e4ists !ithin #indo!s and has a "rede'ined name. Nou sim"ly use the name as the !indo! class "arameter in $reate&indow. The !indo! style "arameter to $reate&indow de'ines more "recisely the a""earance and 'unctionality o' the child !indo! control. #indo!s contains the !indo! "rocedures that "rocess messages to the child !indo!s (ased on these classes. .sing child !indo! controls directly on the sur'ace o' your !indo! involves tas s o' a lo!er level than are re)uired 'or using child !indo! controls in dialog (o4es0 !here the dialog (o4 manager adds a layer o' insulation (et!een your "rogram and the controls themselves. +n "articular0 you7ll discover that the child !indo! controls you create on the sur'ace o' your !indo! have no (uilt:in 'acility to move the in"ut 'ocus 'rom one control to another using the Ta( or cursor movement eys. 5 child !indo! control can o(tain the in"ut 'ocus0 (ut once it does it !on7t 'reely relin)uish the in"ut 'ocus (ac to the "arent !indo!. This is a "ro(lem !e7ll struggle !ith throughout this cha"ter. The #indo!s "rogramming documentation discusses child !indo! controls in t!o "laces: /irst0 the sim"le standard controls that you7ve seen in countless dialog (o4es are descri(ed in 34latform 0'531ser *nterface 0ervices3$ontrols. These are (uttons (including chec (o4es and radio (uttons*0 static controls (such as te4t la(els*0 edit (o4es (!hich let you enter and edit lines or multi"le lines o' te4t*0 scroll (ars0 list (o4es0 and com(o (o4es. #ith the e4ce"tion o' the com(o (o40 these controls have (een around since #indo!s =.F. This section o' the #indo!s documentation also includes the rich edit control0 !hich is similar to the edit (o4 (ut allo!s editing 'ormatted te4t !ith di''erent 'onts and such0 and a""lication des to" tool(ars. There is also a collection o' more esoteric and s"ecialiPed controls that are "erversely re'erred to as Icommon controls.I These are descri(ed in 34latform 0'531ser *nterface 0ervices30hell and $ommon $ontrols3$ommon $ontrols. + !on7t (e discussing the common controls in this cha"ter0 (ut they7ll a""ear in various "rograms throughout the rest o' the (oo . This section o' the #indo!s documentation is a good "lace to loo i' you see something in a #indo!s a""lication that could (e use'ul to your o!n a""lication.

The 1utton Class


#e7ll (egin our e4"loration o' the (utton !indo! class !ith a "rogram named 1TN,%%K (I(utton loo I*0 !hich is sho!n here. 1TN,%%K creates =F child !indo! (utton controls0 one 'or each o' the =F standard styles o' (uttons. .he ).+(>>5 program. 1TN,%%K.C /\:::::::::::::::::::::::::::::::::::::::: 1TN,%%K.C :: 1utton ,oo $rogram (c* Charles $etPold0 =BB^ ::::::::::::::::::::::::::::::::::::::::\/ Tinclude U!indo!s.hV struct K int iStyle L TC-58 \ sPTe4t L M (uttonab [ K 1S9$.S-1.TT%N0 T3AT (I$.S-1.TT%NI*0 1S9D3/$.S-1.TT%N0 T3AT (ID3/$.S-1.TT%NI*0 1S9C-3CK1%A0 T3AT (IC-3CK1%AI*0 1S95.T%C-3CK1%A0 T3AT (I5.T%C-3CK1%AI*0 1S985D+%1.TT%N0 T3AT (I85D+%1.TT%NI*0 1S9GST5T30 T3AT (IGST5T3I*0 1S95.T%GST5T30 T3AT (I5.T%GST5T3I*0 1S928%.$1%A0 T3AT (I28%.$1%AI*0 1S95.T%85D+%1.TT%N0 T3AT (I5.T%85D+%I*0 1S9%#N38D85#0 T3AT (I%#N38D85#I* ML Tde'ine N.& (siPeo' (utton / siPeo' (uttonaFb* ,83S.,T C5,,15CK #nd$roc (-#ND0 .+NT0 #$585&0 ,$585&* L int #+N5$+ #in&ain (-+NST5NC3 h+nstance0 -+NST5NC3 h$rev+nstance0 $ST8 sPCmd,ine0 int iCmdSho!* K static TC-58 sP5""Nameab [ T3AT (I1tn,oo I* L -#ND h!nd L &S2 msg L #NDC,5SS !ndclass L !ndclass.style [ CS9-83D85# e CS9V83D85# L !ndclass.l"'n#nd$roc [ #nd$roc L !ndclass.c(Cls34tra [ F L !ndclass.c(#nd34tra [ F L !ndclass.h+nstance [ h+nstance L !ndclass.h+con [ ,oad+con (N.,,0 +D+95$$,+C5T+%N* L !ndclass.hCursor [ ,oadCursor (N.,,0 +DC9588%#* L !ndclass.h(r1ac ground [ (-18.S-* 2etStoc %(6ect (#-+T3918.S-* L !ndclass.l"sP&enuName [ N.,, L !ndclass.l"sPClassName [ sP5""Name L

i' (J8egisterClass (&!ndclass** K &essage1o4 (N.,,0 T3AT (IThis "rogram re)uires #indo!s NTJI*0 sP5""Name0 &19+C%N388%8* L return F L M h!nd [ Create#indo! (sP5""Name0 T3AT (I1utton ,oo I*0 #S9%V38,5$$3D#+ND%#0 C#9.S3D3/5.,T0 C#9.S3D3/5.,T0 C#9.S3D3/5.,T0 C#9.S3D3/5.,T0 N.,,0 N.,,0 h+nstance0 N.,,* L Sho!#indo! (h!nd0 iCmdSho!* L ."date#indo! (h!nd* L !hile (2et&essage (&msg0 N.,,0 F0 F** K Translate&essage (&msg* L Dis"atch&essage (&msg* L M return msg.!$aram L M ,83S.,T C5,,15CK #nd$roc (-#ND h!nd0 .+NT message0 #$585& !$aram0 ,$585& l$aram* K static -#ND h!nd1uttonaN.&b L static 83CT rect L static TC-58 sPTo"ab [ T3AT (Imessage !$aram l$aramI*0 sP.ndab [ T3AT (I9999999 999999 999999I*0 sP/ormatab [ T3AT (IZ:=CsZF>A:ZF>A ZF>A:ZF>AI*0 sP1u''era?Fb L static int c4Char0 cyChar L -DC hdc L $5+NTST8.CT "s L int iL s!itch (message* K case #&9C835T3 : c4Char [ ,%#%8D (2etDialog1ase.nits (** L cyChar [ -+#%8D (2etDialog1ase.nits (** L 'or (i [ F L i U N.& L i++* h!nd1uttonaib [ Create#indo! ( T3AT(I(uttonI*0 (uttonaib.sPTe4t0 #S9C-+,D e #S9V+S+1,3 e (uttonaib.iStyle0 c4Char0 cyChar \ (= + ; \ i*0 ;F \ c4Char0 D \ cyChar / >0 h!nd0 (-&3N.* i0 ((,$C835T3ST8.CT* l$aram*:Vh+nstance0 N.,,* L return F L case #&9S+X3 : rect.le't [ ;> \ c4Char L rect.to" [ ; \ cyChar L

rect.right [ ,%#%8D (l$aram* L rect.(ottom [ -+#%8D (l$aram* L return F L case #&9$5+NT : +nvalidate8ect (h!nd0 &rect0 T8.3* L hdc [ 1egin$aint (h!nd0 &"s* L Select%(6ect (hdc0 2etStoc %(6ect (SNST3&9/+A3D9/%NT** L Set1 &ode (hdc0 T85NS$583NT* L Te4t%ut (hdc0 ;> \ c4Char0 cyChar0 sPTo"0 lstrlen (sPTo"** L Te4t%ut (hdc0 ;> \ c4Char0 cyChar0 sP.nd0 lstrlen (sP.nd** L 3nd$aint (h!nd0 &"s* L return F L case #&9D85#+T3& : case #&9C%&&5ND : Scroll#indo! (h!nd0 F0 :cyChar0 &rect0 &rect* L hdc [ 2etDC (h!nd* L Select%(6ect (hdc0 2etStoc %(6ect (SNST3&9/+A3D9/%NT** L Te4t%ut (hdc0 ;> \ c4Char0 cyChar \ (rect.(ottom / cyChar : =*0 sP1u''er0 !s"rint' (sP1u''er0 sP/ormat0 message [[ #&9D85#+T3& W T3AT (I#&9D85#+T3&I* : T3AT (I#&9C%&&5NDI*0 -+#%8D (!$aram*0 ,%#%8D (!$aram*0 -+#%8D (l$aram*0 ,%#%8D (l$aram*** L 8eleaseDC (h!nd0 hdc* L Validate8ect (h!nd0 &rect* L (rea L case #&9D3ST8%N : $ost@uit&essage (F* L return F L M return De'#indo!$roc (h!nd0 message0 !$aram0 l$aram* L M

5s you clic on each (utton0 the (utton sends a #&9C%&&5ND message to the "arent !indo! "rocedure0 !hich is the 'amiliar &nd4roc. 1TN,%%K7s &nd4roc dis"lays the w4aram and l4aram "arameters o' this message in the right hal' o' the client area0 as sho!n. The (utton !ith the style 1S9%#N38D85# is dis"layed on this !indo! only !ith a (ac ground shading (ecause this is a style o' (utton that the "rogram is res"onsi(le 'or dra!ing. The (utton indicates it needs dra!ing (y #&9D85#+T3& messages containing an l4aram message "arameter that is a "ointer to a structure o' ty"e D85#+T3&ST8.CT. These messages are also dis"layed in 1TN,%%K. +7ll discuss o!ner:dra! (uttons in more detail later in this cha"ter.

.he ).+(>>5 displa#.

Creating the Child Windows


1TN,%%K de'ines a structure called button that contains (utton !indo! styles and descri"tive te4t strings 'or each o' the =F ty"es o' (uttons. The (utton !indo! styles all (egin !ith the letters 1S0 !hich stand 'or I(utton style.I The =F (utton child !indo!s are created in a for loo" during #&9C835T3 message "rocessing in &nd4roc. The $reate&indow call uses the 'ollo!ing "arameters: (PW( ("!utton") Class name !uttonQiR.s@(e"t #indo! te4t 8:&4?=LL a 8:&_=:=ILP a !uttonQiR.i:t%le #indo! style 4"4har 4 "osition c%4har 3 (1 * 2 3 i) y "osition 2/ 3 "4har #idth 1 3 %4har 2 H -eight ?,nd $arent !indo! (?KP;V) = Child !indo! +D ((LC4UPF(P:(UV4() lCaram) 9> h=nstance +nstance handle ;VLL 34tra "arameters The class name "arameter is the "rede'ined name. The !indo! style uses #S9C-+,D0 #S9V+S+1,30 and one o' the =F (utton styles (1S9$.S-1.TT%N0 1S9D3/$.S-1.TT%N0 and so 'orth* that are de'ined in the (utton structure. The !indo! te4t "arameter (!hich 'or a normal !indo! is the te4t that a""ears in the ca"tion (ar* is te4t that !ill (e dis"layed !ith each (utton. +7ve sim"ly used te4t that identi'ies the (utton style. The x "osition and # "osition "arameters indicate the "lacement o' the u""er le't corner o' the child !indo! relative to the u""er le't corner o' the "arent !indo!7s client area. The !idth and height "arameters s"eci'y the !idth and height o' each child !indo!. Notice that +7m using a 'unction named 2et'ialog)ase1nits to o(tain the !idth and height o' the characters in the de'ault 'ont. This is the 'unction that dialog (o4es use to o(tain te4t dimensions. The

'unction returns a G;:(it value com"rising a !idth in the lo! !ord and a height in the high !ord. #hile 2et'ialog)ase1nits returns roughly the same values as can (e o(tained 'rom the 2et.extMetrics 'unction0 it7s some!hat easier to use and !ill ensure more consistency !ith controls in dialog (o4es. The child !indo! +D "arameter should (e uni)ue 'or each child !indo!. This +D hel"s your !indo! "rocedure identi'y the child !indo! !hen "rocessing #&9C%&&5ND messages 'rom it. Notice that the child !indo! +D is "assed in the $reate&indow "arameter normally used to s"eci'y the "rogram7s menu0 so it must (e cast to an -&3N.. The instance handle "arameter o' the $reate&indow call loo s a little strange0 (ut !e7re ta ing advantage o' the 'act that during a #&9C835T3 message l4aram is actually a "ointer to a structure o' ty"e C835T3ST8.CT (Icreation structureI* that has a mem(er h*nstance. So !e cast l4aram into a "ointer to a C835T3ST8.CT structure and get h*nstance out. (Some #indo!s "rograms use a glo(al varia(le named h*nst to give !indo! "rocedures access to the instance handle availa(le in &inMain. +n &inMain0 you need to sim"ly set h=nst ' h=nstance ; 2et&indow(ong to o(tain this instance handle: Yet8indo,Lon+ (h,nd# Y8L&?=;:(F;4P) 5ny o' these methods is 'ine.* 5'ter the $reate&indow call0 !e needn7t do anything more !ith these child !indo!s. The (utton !indo! "rocedure !ithin #indo!s maintains the (uttons 'or us and handles all re"ainting 6o(s. (The e4ce"tion is the (utton !ith the 1S9%#N38D85# styleL as +7ll discuss later0 this (utton style re)uires the "rogram to dra! the (utton.* 5t the "rogram7s termination0 #indo!s destroys these child !indo!s !hen the "arent !indo! is destroyed.

%he Child %al+s to #ts Parent


#hen you run 1TN,%%K0 you see the di''erent (utton ty"es dis"layed on the le't side o' the client area. 5s + mentioned earlier0 !hen you clic a (utton !ith the mouse0 the child !indo! control sends a #&9C%&&5ND message to its "arent !indo!. 1TN,%%K tra"s the #&9C%&&5ND message and dis"lays the values o' w4aram and l4aram. -ere7s !hat they mean: ,%#%8D (!$aram* Child !indo! +D -+#%8D (!$aram* Noti'ication code (param Child !indo! handle +' you7re converting "rograms !ritten 'or the =C:(it versions o' #indo!s0 (e a!are that these message "arameters have (een altered to accommodate G;:(it handles. The child !indo! +D is the value "assed to $reate&indow !hen the child !indo! is created. +n 1TN,%%K0 these +Ds are F through B 'or the =F (uttons dis"layed in the client area. The child !indo! handle is the value that #indo!s returns 'rom the $reate&indow call. The noti'ication code indicates in more detail !hat the message means. The "ossi(le values o' (utton noti'ication codes are de'ined in the #indo!s header 'iles: &utton 3otification +ode Identifier 4alue 1N9C,+CK3D F 1N9$5+NT = 1N9-+,+T3 or 1N9$.S-3D ; 1N9.N-+,+T3 or 1N9.N$.S-3D G 1N9D+S51,3 > 1N9D%.1,3C,+CK3D or 1N9D1,C,K ? 1N9S3T/%C.S C 1N9K+,,/%C.S D +n reality0 you7ll never see most o' these (utton values. The noti'ication codes = through > are 'or an o(solete (utton style called 1S9.S381.TT%N. (+t7s (een re"laced !ith 1S9%#N38D85# and a di''erent noti'ication mechanism.* The noti'ication codes C and D are sent only i' the (utton style includes the 'lag 1S9N%T+/N. The noti'ication code ? is sent only 'or 1S985D+%1.TT%N0 1S95.T%85D+%1.TT%N0 and 1S9%#N38D85# (uttons0 or 'or other (uttons i' the (utton style includes 1S9N%T+/N. Nou7ll notice that !hen you clic a (utton !ith the mouse0 a dashed line surrounds the te4t o' the (utton. This indicates that the (utton has the in"ut 'ocus. 5ll ey(oard in"ut no! goes to the child !indo! (utton control rather

than to the main !indo!. -o!ever0 !hen the (utton control has the in"ut 'ocus0 it ignores all eystro es e4ce"t the S"ace(ar0 !hich no! has the same e''ect as a mouse clic .

%he Parent %al+s to #ts Child


5lthough 1TN,%%K does not demonstrate this 'act0 a !indo! "rocedure can also send messages to the child !indo! control. These messages include many o' the !indo! messages (eginning !ith the "re'i4 #&. +n addition0 eight (utton:s"eci'ic messages are de'ined in #+N.S38.-L each (egins !ith the letters 1&0 !hich stand 'or I(utton message.I These (utton messages are sho!n in the 'ollo!ing ta(le: &utton 2essage 4alue 1&923TC-3CK F4FF/F 1&9S3TC-3CK F4FF/= 1&923TST5T3 F4FF/; 1&9S3TST5T3 F4FF/G 1&9S3TSTN,3 F4FF/> 1&9C,+CK F4FF/? 1&923T+&523 F4FF/C 1&9S3T+&523 F4FF/D The 1&923TC-3CK and 1&9S3TC-3CK messages are sent (y a "arent !indo! to a child !indo! control to get and set the chec mar o' chec (o4es and radio (uttons. The 1&923TST5T3 and 1&9S3TST5T3 messages re'er to the normal0 or "ushed0 state o' a !indo! !hen you clic it !ith the mouse or "ress it !ith the S"ace(ar. #e7ll see ho! these messages !or !hen !e loo at each ty"e o' (utton. The 1&9S3TSTN,3 message lets you change the (utton style a'ter the (utton is created. 3ach child !indo! has a !indo! handle and an +D that is uni)ue among its si(lings. Kno!ing one o' these items allo!s you to get the other. +' you no! the !indo! handle o' the child0 you can o(tain the +D using id ' Yet8indo,Lon+ (h,nd4hild# Y8L&=L) ; The area accessed !ith the 2#,9+D identi'ier is reserved (y #indo!s !hen the child !indo! is created. Nou can also use id ' YetLl+4trl=L (h,nd4hild) ; 3ven though the IDlgI "art o' the 'unction name re'ers to a dialog (o40 this is really a general:"ur"ose 'unction. Kno!ing the +D and the "arent !indo! handle0 you can get the child !indo! handle: h,nd4hild ' YetLl+=tem (h,ndCarent# id) ;

P$sh B$ttons The 'irst t!o (uttons sho!n in 1TN,%%K are I"ushI (uttons. 5 "ush (utton is a rectangle enclosing te4t s"eci'ied in the !indo! te4t "arameter o' the $reate&indow call. The rectangle ta es u" the 'ull height and !idth o' the dimensions given in the $reate&indow or Move&indow call. The te4t is centered !ithin the rectangle. $ush:(utton controls are used mostly to trigger an immediate action !ithout retaining any ty"e o' on/o'' indication. The t!o ty"es o' "ush:(utton controls have !indo! styles called 1S9$.S-1.TT%N and 1S9D3/$.S-1.TT%N. The ID3/I in 1S9D3/$.S-1.TT%N stands 'or Ide'ault.I #hen used to design dialog (o4es0 1S9$.S-1.TT%N controls and 1S9D3/$.S-1.TT%N controls 'unction di''erently 'rom one another. #hen used as child !indo! controls0 ho!ever0 the t!o ty"es o' "ush (uttons 'unction the same !ay0 although 1S9D3/$.S-1.TT%N has a heavier outline.

5 "ush (utton loo s (est !hen its height is D/> times the height o' a te4t character0 !hich is !hat 1TN,%%K uses. The "ush (utton7s !idth must accommodate at least the !idth o' the te4t0 "lus t!o additional characters. #hen the mouse cursor is inside the "ush (utton0 "ressing the mouse (utton causes the (utton to re"aint itsel' using GD:style shading to a""ear as i' it7s (een de"ressed. 8eleasing the mouse (utton restores the original a""earance and sends a #&9C%&&5ND message to the "arent !indo! !ith the noti'ication code 1N9C,+CK3D. 5s !ith the other (utton ty"es0 !hen a "ush (utton has the in"ut 'ocus0 a dashed line surrounds the te4t and "ressing and releasing the S"ace(ar has the same e''ect as "ressing and releasing the mouse (utton. Nou can simulate a "ush:(utton 'lash (y sending the !indo! a 1&9S3TST5T3 message. This causes the (utton to (e de"ressed: :endKessa+e (h,ndIutton# IK&:P(:(F(P# 1# /) ; This call causes the (utton to return to normal: :endKessa+e (h,ndIutton# IK&:P(:(F(P# /# /) ; The hwnd)utton !indo! handle is the value returned 'rom the $reate&indow call. Nou can also send a 1&923TST5T3 message to a "ush (utton. The child !indo! control returns the current state o' the (utton: T8.3 i' the (utton is de"ressed and /5,S3 i' it isn7t de"ressed. &ost a""lications do not re)uire this in'ormation0 ho!ever. 5nd (ecause "ush (uttons do not retain any on/o'' in'ormation0 the 1&9S3TC-3CK and 1&923TC-3CK messages are not used. Chec+ Bo=es 5 chec (o4 is a s)uare (o4 !ith te4tL the te4t usually a""ears to the right o' the chec (o4. (+' you include the 1S9,3/TT3AT style !hen creating the (utton0 the te4t a""ears to the le'tL you7ll "ro(a(ly !ant to com(ine this style !ith 1S98+2-T to right:6usti'y the te4t.* Chec (o4es are usually incor"orated in an a""lication to allo! a user to select o"tions. The chec (o4 commonly 'unctions as a toggle s!itch: clic ing the (o4 once causes a chec mar to a""earL clic ing again toggles the chec mar o''. The t!o most common styles 'or a chec (o4 are 1S9C-3CK1%A and 1S95.T%C-3CK1%A. #hen you use the 1S9C-3CK1%A style0 you must set the chec mar yoursel' (y sending the control a 1&9S3TC-3CK message. The w4aram "arameter is set to = to create a chec mar and to F to remove it. Nou can o(tain the current chec state o' the (o4 (y sending the control a 1&923TC-3CK message. Nou might use code li e this to toggle the A mar !hen "rocessing a #&9C%&&5ND message 'rom the control: :endKessa+e ((?8;L) lCaram# IK&:P(4?P4X# (8CFUFK) O:endKessa+e ((?8;L) lCaram# IK&YP(4?P4X# /# /)# /) ;

Notice the J o"erator in 'ront o' the second 0endMessage call. The l4aram value is the child !indo! handle that is "assed to your !indo! "rocedure in the #&9C%&&5ND message. #hen you later need to no! the state o' the (utton0 send it another 1&923TC-3CK message. %r you can retain the current chec state in a static varia(le in your !indo! "rocedure. Nou can also initialiPe a 1S9C-3CK1%A chec (o4 !ith a chec mar (y sending it a 1&9S3TC-3CK message: :endKessa+e (h,ndIutton# IK&:P(4?P4X# 1# /) ; /or the 1S95.T%C-3CK1%A style0 the (utton control itsel' toggles the chec mar on and o''. Nour !indo! "rocedure can ignore #&9C%&&5ND messages. #hen you need the current state o' the (utton0 send the control a 1&923TC-3CK message: i4hec0 ' (int) :endKessa+e (h,ndIutton# IK&YP(4?P4X# /# /) ; The value o' iChec is T8.3 or nonPero i' the (utton is chec ed and /5,S3 or F i' not. The other t!o chec (o4 styles are 1S9GST5T3 and 1S95.T%GST5T3. 5s their names indicate0 these styles can dis"lay a third state as !ellSa gray color !ithin the chec (o4S!hich occurs !hen you send the control a #&9S3TC-3CK message !ith w4aram e)ual to ;. The gray color indicates to the user that the selection is indeterminate or irrelevant. The chec (o4 is aligned !ith the rectangle7s le't edge and is centered !ithin the to" and (ottom dimensions o' the rectangle that !ere s"eci'ied during the $reate&indow call. Clic ing any!here !ithin the rectangle causes a #&9C%&&5ND message to (e sent to the "arent. The minimum height 'or a chec (o4 is one character height. The minimum !idth is the num(er o' characters in the te4t0 "lus t!o. Radio B$ttons
5 radio (utton is named a'ter the ro! o' (uttons that !ere once )uite common on car radios. 3ach (utton on a car radio is set 'or a di''erent radio station0 and only one (utton can (e "ressed at a time. +n dialog (o4es0 grou"s o' radio (uttons are conventionally used to indicate mutually e4clusive o"tions. .nli e chec (o4es0 radio (uttons do not !or as togglesSthat is0 !hen you clic a radio (utton a second time0 its state remains unchanged. The radio (utton loo s very much li e a chec (o4 e4ce"t that it contains a little circle rather than a (o4. 5 heavy dot !ithin the circle indicates that the radio (utton has (een chec ed. The radio (utton has the !indo! style 1S985D+%1.TT%N or 1S95.T%85D+%1.TT%N0 (ut the latter is used only in dialog (o4es. #hen you receive a #&9C%&&5ND message 'rom a radio (utton0 you should dis"lay its chec (y sending it a 1&9S3TC-3CK message !ith w4aram e)ual to =: :endKessa+e (h,ndIutton# IK&:P(4?P4X# 1# /) ; /or all other radio (uttons in the same grou"0 you can turn o'' the chec s (y sending them 1&9S3TC-3CK messages !ith w4aram e)ual to F: :endKessa+e (h,ndIutton# IK&:P(4?P4X# /# /) ;

6ro$- Bo=es The grou" (o40 !hich has the 1S928%.$1%A style0 is an oddity in the (utton class. +t neither "rocesses mouse or ey(oard in"ut nor sends #&9C%&&5ND messages to its "arent. The grou" (o4 is a rectangular outline !ith its !indo! te4t at the to". 2rou" (o4es are o'ten used to enclose other (utton controls. Changing the B$tton %e=t
Nou can change the te4t in a (utton (or in any other !indo!* (y calling 0et&indow.ext: :et8indo,(e"t (h,nd# ps@:trin+) ; !here hwnd is a handle to the !indo! !hose te4t is (eing changed and psz0tring is a "ointer to a null:terminated string. /or a normal !indo!0 this te4t is the te4t o' the ca"tion (ar. /or a (utton control0 it7s the te4t dis"layed !ith the (utton. Nou can also o(tain the current te4t o' a !indo!: iLen+th ' Yet8indo,(e"t (h,nd# ps@Iuffer# iKa"Len+th) ; The iMax(ength "arameter s"eci'ies the ma4imum num(er o' characters to co"y into the (u''er "ointed to (y psz)uffer. The 'unction returns the string length co"ied. Nou can "re"are your "rogram 'or a "articular te4t length (y 'irst calling iLen+th ' Yet8indo,(e"tLen+th (h,nd) ;

?isi/le and 0na/led B$ttons


To receive mouse and ey(oard in"ut0 a child !indo! must (e (oth visi(le (dis"layed* and ena(led. #hen a child !indo! is visi(le (ut not ena(led0 #indo!s dis"lays the te4t in gray rather than (lac . +' you don7t include #S9V+S+1,3 in the !indo! class !hen creating the child !indo!0 the child !indo! !ill not (e dis"layed until you ma e a call to 0how&indow: :ho,8indo, (h,nd4hild# :8&:?D8;DUKFL) ; 1ut i' you include #S9V+S+1,3 in the !indo! class0 you don7t need to call 0how&indow. -o!ever0 you can hide the child !indo! (y this call to 0how&indow: :ho,8indo, (h,nd4hild# :8&?=LP) ; Nou can determine i' a child !indo! is visi(le (y a call to =s8indo,_isi!le (h,nd4hild) ; Nou can also ena(le and disa(le a child !indo!. 1y de'ault0 a !indo! is ena(led. Nou can disa(le it (y calling Pna!le8indo, (h,nd4hild# 6FL:P) ; /or (utton controls0 this call has the e''ect o' graying the (utton te4t string. The (utton no longer res"onds to mouse or ey(oard in"ut. This is the (est method 'or indicating that a (utton o"tion is currently unavaila(le. Nou can reena(le a child !indo! (y calling Pna!le8indo, (h,nd4hild# (UVP) ; Nou can determine !hether a child !indo! is ena(led (y calling =s8indo,Pna!led (h,nd4hild) ;

B$ttons and #n-$t Foc$s


5s + noted earlier in this cha"ter0 "ush (uttons0 chec (o4es0 radio (uttons0 and o!ner:dra! (uttons receive the in"ut 'ocus !hen they are clic ed !ith the mouse. The control indicates it has the in"ut 'ocus !ith a dashed line that surrounds the te4t. #hen the child !indo! control gets the in"ut 'ocus0 the "arent !indo! loses itL all ey(oard in"ut then goes to the control rather than to the "arent !indo!. -o!ever0 the child !indo! control res"onds only to the S"ace(ar0 !hich no! 'unctions li e the mouse. This situation "resents an o(vious "ro(lem: your "rogram has lost control o' ey(oard "rocessing. ,et7s see !hat !e can do a(out it.

5s + discussed0 !hen #indo!s s!itches the in"ut 'ocus 'rom one !indo! (such as a "arent* to another (such as a child !indo! control*0 it 'irst sends a #&9K+,,/%C.S message to the !indo! losing the in"ut 'ocus. The w4aram "arameter is the handle o' the !indo! that is to receive the in"ut 'ocus. #indo!s then sends a #&9S3T/%C.S message to the !indo! receiving the in"ut 'ocus0 !ith w4aram s"eci'ying the handle o' the !indo! losing the in"ut 'ocus. (+n (oth cases0 w4aram might (e N.,,0 !hich indicates that no !indo! has or is receiving the in"ut 'ocus.* 5 "arent !indo! can "revent a child !indo! control 'rom getting the in"ut 'ocus (y "rocessing #&9K+,,/%C.S messages. 5ssume that the array hwnd$hild contains the !indo! handles o' all child !indo!s. (These !ere saved in the array during the $reate&indow calls that created the !indo!s.* N.& is the num(er o' child !indo!s. case 8K&X=LL6D4V: 7 for (i ' / ; i < ;VK ; i**) if (h,nd4hild QiR '' (?8;L) ,Caram) { :et6ocus (h,nd) ; !rea0 ; return / ; +n this code0 !hen the "arent !indo! detects that it7s losing the in"ut 'ocus to one o' its child !indo! controls0 it calls 0et!ocus to restore the in"ut 'ocus to itsel'. -ere7s a sim"ler ((ut less o(vious* !ay o' doing it: case 8K&X=LL6D4V: 7 if (h,nd '' YetCarent ((?8;L) ,Caram)) :et6ocus (h,nd) ; return / ; 1oth these methods have a shortcoming0 ho!ever: they "revent the (utton 'rom res"onding to the S"ace(ar0 (ecause the (utton never gets the in"ut 'ocus. 5 (etter a""roach !ould (e to let the (utton get the in"ut 'ocus (ut also to include the 'acility 'or the user to move 'rom (utton to (utton using the Ta( ey. 5t 'irst this sounds im"ossi(le0 (ut +7ll sho! you ho! to accom"lish it !ith a techni)ue called I!indo! su(classingI in the C%,%8S= "rogram sho!n later in this cha"ter. 5 menu is "ro(a(ly the most im"ortant "art o' the consistent user inter'ace that #indo!s "rograms o''er0 and adding a menu to your "rogram is a relatively easy "art o' #indo!s "rogramming. Nou de'ine the menu in Develo"er Studio. 3ach selecta(le menu item is given a uni)ue +D num(er. Nou s"eci'y the name o' the menu in the !indo! class structure. #hen the user chooses a menu item0 #indo!s sends your "rogram a #&9C%&&5ND message containing that +D. 5'ter discussing menus0 +7ll conclude this cha"ter !ith a section on ey(oard accelerators0 !hich are ey com(inations that are used "rimarily to du"licate menu 'unctions.

Men$ Conce-ts
5 !indo!7s menu (ar is dis"layed immediately (elo! the ca"tion (ar. This menu (ar is sometimes called a "rogram7s Imain menuI or the Ito":level menu.I +tems listed in the to":level menu usually invo e dro":do!n menus0 !hich are also called I"o"u" menusI or Isu(menus.I Nou can also de'ine multi"le nestings o' "o"u"s: that is0 an item on a "o"u" menu can invo e another "o"u" menu. Sometimes items in "o"u" menus invo e a dialog (o4 'or more in'ormation. (Dialog (o4es are covered in the ne4t cha"ter.* &ost "arent !indo!s have0 to the 'ar le't o' the ca"tion (ar0 a dis"lay o' the "rogram7s small icon. This icon invo es the system menu0 !hich is really another "o"u" menu. &enu items in "o"u"s can (e Ichec ed0I !hich means that #indo!s dra!s a small chec mar to the le't o' the menu te4t. The use o' chec mar s lets the user choose di''erent "rogram o"tions 'rom the menu. These o"tions can (e mutually e4clusive0 (ut they don7t have to (e. To":level menu items cannot (e chec ed. &enu items in the to":level menu or in "o"u" menus can (e Iena(led0I Idisa(led0I or Igrayed.I The !ords IactiveI and IinactiveI are sometimes used synonymously !ith Iena(ledI and Idisa(led.I &enu items 'lagged as ena(led or disa(led loo the same to the user0 (ut a grayed menu item is dis"layed in gray te4t. /rom the "ers"ective o' the user0 ena(led0 disa(led0 and grayed menu items can all (e IselectedI (highlighted*. That is0 the user can clic the mouse on a disa(led menu item0 or move the reverse:video cursor (ar to a disa(led menu

item0 or trigger the menu item (y using the item7s ey letter. -o!ever0 'rom the "ers"ective o' your "rogram0 ena(led0 disa(led0 and grayed menu items 'unction di''erently. #indo!s sends your "rogram a #&9C%&&5ND message only 'or ena(led menu items. Nou use disa(led and grayed menu items 'or o"tions that are not currently valid. +' you !ant to let the user no! the o"tion is not valid0 ma e it grayed.

Men$ ,tr$ct$re
#hen you create or change menus in a "rogram0 it7s use'ul to thin o' the to":level menu and each "o"u" menu as (eing se"arate menus. The to":level menu has a menu handle0 each "o"u" menu !ithin a to":level menu has its o!n menu handle0 and the system menu (!hich is also a "o"u"* has a menu handle. 3ach item in a menu is de'ined (y three characteristics. The 'irst characteristic is !hat a""ears in the menu. This is either a te4t string or a (itma". The second characteristic is either an +D num(er that #indo!s sends to your "rogram in a #&9C%&&5ND message or the handle to a "o"u" menu that #indo!s dis"lays !hen the user chooses that menu item. The third characteristic descri(es the attri(ute o' the menu item0 including !hether the item is disa(led0 grayed0 or chec ed.

Defining the Men$


To use Develo"er Studio to add a menu to your "rogram7s resource scri"t0 select 8esource 'rom the +nsert menu and "ic &enu. (1ut you "ro(a(ly 'igured that out already.* Nou can then interactively de'ine your menu. 3ach item in the menu has an associated &enu +tem $ro"erties dialog (o4 that indicates the item7s te4t string. +' the $o":u" (o4 is chec ed0 the item invo es a "o"u" menu and no +D is associated !ith the item. +' the $o":u" (o4 is not chec ed0 the item generates a #&9C%&&5ND message !ith a s"eci'ied +D. These t!o ty"es o' menu items !ill a""ear in the resource scri"t as $%$.$ and &3N.+T3& statements0 res"ectively. #hen you ty"e the te4t 'or an item in a menu0 you can ty"e an am"ersand (&* to indicate that the 'ollo!ing character is to (e underlined !hen #indo!s dis"lays the menu. Such an underlined character is the character #indo!s searches 'or !hen you select a menu item using the 5lt ey. +' you don7t include an am"ersand in the te4t0 no underline !ill a""ear0 and #indo!s !ill instead use the 'irst letter o' the menu item7s te4t 'or 5lt: ey searches. +' you select the 2rayed o"tion in the &enu +tems $ro"erties dialog (o40 the menu item is inactive0 its te4t is grayed0 and the item does not generate a #&9C%&&5ND message. +' you select the +nactive o"tion0 the menu item is inactive and does not generate a #&9C%&&5ND message (ut its te4t is dis"layed normally. The Chec ed o"tion "laces a chec mar ne4t to a menu item. The Se"arator o"tion causes a horiPontal se"arator (ar to (e dra!n on "o"u" menus. /or items in "o"u" menus0 you can use the columnar ta( character Yt in the character string. Te4t 'ollo!ing the Yt is "laced in a ne! column s"aced 'ar enough to the right to accommodate the longest te4t string in the 'irst column o' the "o"u". #e7ll see ho! this !or s !hen !e loo at ey(oard accelerators to!ard the end o' this cha"ter. 5 Ya in the character string right:6usti'ies the te4t that 'ollo!s it. The +D values you s"eci'y are the num(ers that #indo!s sends to the !indo! "rocedure in menu messages. The +D values should (e uni)ue !ithin a menu. 1y convention0 + use identi'iers (eginning !ith the letters +D& (I+D 'or a &enuI*.

Referencing the Men$ in 8o$r Program


&ost #indo!s a""lications have only one menu in the resource scri"t. Nou can give the menu a te4t name that is the same as the name o' the "rogram. $rogrammers o'ten use the name o' the "rogram as the name o' the menu so that the same character string can (e used 'or the !indo! class0 the name o' the "rogram7s icon0 and the name o' the menu. The "rogram then ma es re'erence to this menu in the de'inition o' the !indo! class: ,ndclass.lps@Kenu;ame ' s@Fpp;ame ; 5lthough s"eci'ying the menu in the !indo! class is the most common !ay to re'erence a menu resource0 that7s not the only !ay to do it. 5 #indo!s a""lication can load a menu resource into memory !ith the (oadMenu 'unction0 !hich is similar to the (oad*con and (oad$ursor 'unctions descri(ed earlier. (oadMenu returns a handle to the menu. +' you use a name 'or the menu in the resource scri"t0 the statement loo s li e this: hKenu ' LoadKenu (h=nstance# (PW( ("K%Kenu")) ; +' you use a num(er0 the (oadMenu call ta es this 'orm:

hKenu ' LoadKenu (h=nstance# KFXP=;(UP:DVU4P (=L&KP;V)) ; Nou can then s"eci'y this menu handle as the ninth "arameter to $reate&indow: h,nd ' 4reate8indo, ((PW( ("K%4lass")# (PW( ("8indo, 4aption")# 8:&D_PULFCCPL8=;LD8# 48&V:PLP6FVL(# 48&V:PLP6FVL(# 48&V:PLP6FVL(# 48&V:PLP6FVL(# ;VLL# hKenu# h=nstance# ;VLL) ; +n this case0 the menu s"eci'ied in the $reate&indow call overrides any menu s"eci'ied in the !indo! class. Nou can thin o' the menu in the !indo! class as (eing a de'ault menu 'or the !indo!s (ased on the !indo! class i' the ninth "arameter to $reate&indow is N.,,. There'ore0 you can use di''erent menus 'or several !indo!s (ased on the same !indo! class. Nou can also have a N.,, menu name in the !indo! class and a N.,, menu handle in the $reate&indow call and assign a menu to a !indo! a'ter the !indo! has (een created: :etKenu (h,nd# hKenu) ; This 'orm lets you dynamically change a !indo!7s menu. #e7ll see an e4am"le o' this in the N%$%$.$S "rogram0 sho!n later in this cha"ter. 5ny menu that is attached to a !indo! is destroyed !hen the !indo! is destroyed. 5ny menus not attached to a !indo! should (e e4"licitly destroyed (y calls to 'estro#Menu (e'ore the "rogram terminates.

Men$s and Messages


#indo!s usually sends a !indo! "rocedure several di''erent messages !hen the user selects a menu item. +n most cases0 your "rogram can ignore many o' these messages and sim"ly "ass them to 'ef&indow4roc. %ne such message is #&9+N+T&3N. !ith the 'ollo!ing "arameters: w4aram: -andle to main menu l4aram: F The value o' w4aram is the handle to your main menu even i' the user is selecting an item 'rom the system menu. #indo!s "rograms generally ignore the #&9+N+T&3N. message. 5lthough the message e4ists to give you the o""ortunity to change the menu (e'ore an item is chosen0 + sus"ect any changes to the to":level menu at this time !ould (e disconcerting to the user. Nour "rogram also receives #&9&3N.S3,3CT messages. 5 "rogram can receive many #&9&3N.S3,3CT messages as the user moves the cursor or mouse among the menu items. This is hel"'ul 'or im"lementing a status (ar that contains a 'ull te4t descri"tion o' the menu o"tion. The "arameters that accom"any #&9&3N.S3,3CT are as 'ollo!s: ,%#%8D (w4aram*: Selected item: &enu +D or "o"u" menu inde4 -+#%8D (w4aram*: Selection 'lags l4aram: -andle to menu containing selected item #&9&3N.S3,3CT is a menu:trac ing message. The value o' w4aram tells you !hat item o' the menu is currently selected (highlighted*. The Iselection 'lagsI in the high !ord o' w4aram can (e a com(ination o' the 'ollo!ing: &/9285N3D0 &/9D+S51,3D0 &/9 C-3CK3D0 &/91+T&5$0 &/9$%$.$0 &/9-3,$0 &/9SNS&3N.0 and &/9&%.S3S3,3CT. Nou may !ant to use #&9&3N.S3,3CT i' you need to change something in the client area o' your !indo! (ased on the movement o' the highlight among the menu items. &ost "rograms "ass this message to 'ef&indow4roc. #hen #indo!s is ready to dis"lay a "o"u" menu0 it sends the !indo! "rocedure a #&9+N+T&3N.$%$.$ message !ith the 'ollo!ing "arameters: w4aram: $o"u" menu handle ,%#%8D (l4aram*: $o"u" inde4 -+#%8D (l4aram*: = 'or system menu0 F other!ise This message is im"ortant i' you need to ena(le or disa(le items in a "o"u" menu (e'ore it is dis"layed. /or instance0 su""ose your "rogram can co"y te4t 'rom the cli"(oard using the $aste command on a "o"u" menu. #hen you receive a #&9+N+T&3N.$%$.$ message 'or that "o"u"0 you should determine !hether the cli"(oard has te4t in it. +' it doesn7t0 you should gray the $aste menu item. #e7ll see an e4am"le o' this in the revised $%$$5D "rogram sho!n to!ard the end o' this cha"ter. The most im"ortant menu message is #&9C%&&5ND. This message indicates that the user has chosen an ena(led menu item 'rom your !indo!7s menu.

#f (o$ ha--en to $se the same #D codes for men$s and child window controls. (o$ can differentiate /etween them /( e=amining the val$e of l(aram0 !hich !ill (e F 'or a menu item. 2enus +ontrols ,%#%8D (w4aram*: &enu +D Control +D -+#%8D (w4aram*: F Noti'ication code l4aram: F Child !indo! handle The #&9SNSC%&&5ND message is similar to the #&9C%&&5ND message e4ce"t that #&9SNSC%&&5ND signals that the user has chosen an ena(led menu item 'rom the system menu: w4aram: &enu +D l4aram: F -o!ever0 i' the #&9SNSC%&&5ND message is the result o' a mouse clic 0 ,%#%8D ( l4aram* and -+#%8D (l4aram* !ill contain the x and # screen coordinates o' the mouse cursor7s location. /or #&9SNSC%&&5ND0 the menu +D indicates !hich item on the system menu has (een chosen. /or the "rede'ined system menu items0 the (ottom 'our (its should (e mas ed out (y 5NDing !ith F4///F. The resultant value !ill (e one o' the 'ollo!ing: SC9S+X30 SC9&%V30 SC9&+N+&+X30 SC9&5A+&+X30 SC9N3AT#+ND%#0 SC9$83V#+ND%#0 SC9C,%S30 SC9VSC8%,,0 SC9-SC8%,,0 SC95885N230 SC983ST%830 and SC9T5SK,+ST. +n addition0 w4aram can (e SC9&%.S3&3N. or SC9K3N&3N.. +' you add menu items to the system menu0 the lo! !ord o' w4aram !ill (e the menu +D that you de'ine. To avoid con'licts !ith the "rede'ined menu +Ds0 use values (elo! F4/FFF. +t is im"ortant that you "ass normal #&9SNSC%&&5ND messages to 'ef&indow4roc. +' you do not0 you7ll e''ectively disa(le the normal system menu commands. The 'inal message !e7ll loo at is #&9&3N.C-580 !hich isn7t really a menu message at all. #indo!s sends this message to your !indo! "rocedure in one o' t!o circumstances: i' the user "resses 5lt and a character ey that does not corres"ond to a menu item0 or0 !hen a "o"u" is dis"layed0 i' the user "resses a character ey that does not corres"ond to an item in the "o"u". The "arameters that accom"any the #&9&3N.C-58 message are as 'ollo!s: ,%#%8D (w4aram*: Character code (5SC++ or .nicode* -+#%8D (w4aram*: Selection code l4aram: -andle to menu The selection code is: I No "o"u" is dis"layed. M!_4>414 $o"u" is dis"layed. M!_0A0M,+1 System menu "o"u" is dis"layed. #indo!s "rograms usually "ass this message to 'ef&indow4roc0 !hich normally returns a F to #indo!s0 !hich causes #indo!s to (ee".

> ,am-le Program


,et7s loo at a sim"le e4am"le. The &3N.D3&% "rogram0 sho!n in the /igure has 'ive items in the main menuS /ile0 3dit0 1ac ground0 Timer0 and -el". 3ach o' these items has a "o"u". &3N.D3&% does the sim"lest and most common ty"e o' menu "rocessing0 !hich involves tra""ing #&9C%&&5ND messages and chec ing the lo! !ord o' w4aram. .he M,+1',M> program.

M0)*D0MOAC
2399999999999999999999999999999999999999999 KP;VLPKD.4 99 Kenu Lemonstration (c) 4harles Cet@old# 1SST 9999999999999999999999999999999999999999932 #include <,indo,s.h> #include "resource.h" #define =L&(=KPU 1

LUP:VL( 4FLLIF4X 8ndCroc (?8;L# V=;(# 8CFUFK# LCFUFK) ; (4?FU s@Fpp;ameQR ' (PW( ("KenuLemo") ; int 8=;FC= 8inKain (?=;:(F;4P h=nstance# ?=;:(F;4P hCrev=nstance# C:(U s@4mdLine# int i4md:ho,) { ?8;L h,nd ; K:Y ms+ ; 8;L4LF:: ,ndclass ; ,ndclass.st%le ,ndclass.lpfn8ndCroc ,ndclass.c!4lsP"tra ,ndclass.c!8ndP"tra ,ndclass.h=nstance ,ndclass.h=con ,ndclass.h4ursor ,ndclass.h!rIac0+round ,ndclass.lps@Kenu;ame ,ndclass.lps@4lass;ame ' ' ' ' ' ' ' ' ' ' 4:&?UPLUF8 ^ 4:&_UPLUF8 ; 8ndCroc ; / ; / ; h=nstance ; Load=con (;VLL# =L=&FCCL=4F(=D;) ; Load4ursor (;VLL# =L4&FUUD8) ; (?IUV:?) Yet:toc0D!$ect (8?=(P&IUV:?) ; s@Fpp;ame ; s@Fpp;ame ;

if (OUe+ister4lass (],ndclass)) { Kessa+eIo" (;VLL# (PW( ("(his pro+ram re5uires 8indo,s ;(O")# s@Fpp;ame# KI&=4D;PUUDU) ; return / ; h,nd ' 4reate8indo, (s@Fpp;ame# (PW( ("Kenu Lemonstration")# 8:&D_PULFCCPL8=;LD8# 48&V:PLP6FVL(# 48&V:PLP6FVL(# 48&V:PLP6FVL(# 48&V:PLP6FVL(# ;VLL# ;VLL# h=nstance# ;VLL) ; :ho,8indo, (h,nd# i4md:ho,) ; Vpdate8indo, (h,nd) ; ,hile (YetKessa+e (]ms+# ;VLL# /# /)) { (ranslateKessa+e (]ms+) ; LispatchKessa+e (]ms+) ; return ms+.,Caram ; LUP:VL( 4FLLIF4X 8ndCroc (?8;L h,nd# V=;( messa+e# 8CFUFK ,Caram# LCFUFK lCaram) { static int id4olor Q.R ' { 8?=(P&IUV:?# L(YUFG&IUV:?# YUFG&IUV:?# LXYUFG&IUV:?# ILF4X&IUV:? ; static int i:election ' =LK&IXY;L&8?=(P ; ?KP;V hKenu ; s,itch (messa+e) { case 8K&4DKKF;L7

hKenu ' YetKenu (h,nd) ; s,itch (LD8DUL (,Caram)) { case =LK&6=LP&;P87 case =LK&6=LP&DCP;7 case =LK&6=LP&:F_P7 case =LK&6=LP&:F_P&F:7 Kessa+eIeep (/) ; return / ; case =LK&FCC&PW=(7 :endKessa+e (h,nd# 8K&4LD:P# /# /) ; return / ; case case case case case =LK&PL=(&V;LD7 =LK&PL=(&4V(7 =LK&PL=(&4DCG7 =LK&PL=(&CF:(P7 =LK&PL=(&4LPFU7 Kessa+eIeep (/) ; return / ; =LK&IXY;L&8?=(P7 =LK&IXY;L&L(YUFG7 =LK&IXY;L&YUFG7 =LK&IXY;L&LXYUFG7 =LK&IXY;L&ILF4X7 22 ;ote7 Lo+ic !elo, 22 assumes that =LK&8?=(P 22 throu+h =LK&ILF4X are 22 consecutive num!ers in 22 the order sho,n here.

case case case case case

4hec0Kenu=tem (hKenu# i:election# K6&V;4?P4XPL) ; i:election ' LD8DUL (,Caram) ; 4hec0Kenu=tem (hKenu# i:election# K6&4?P4XPL) ; :et4lassLon+ (h,nd# Y4L&?IUIF4XYUDV;L# (LD;Y) Yet:toc0D!$ect (id4olor QLD8DUL (,Caram) 9 =LK&IXY;L&8?=(PR)) ; =nvalidateUect (h,nd# ;VLL# (UVP) ; return / ; case =LK&(=KPU&:(FU(7 if (:et(imer (h,nd# =L&(=KPU# 1///# ;VLL)) { Pna!leKenu=tem (hKenu# =LK&(=KPU&:(FU(# K6&YUFGPL) ; Pna!leKenu=tem (hKenu# =LK&(=KPU&:(DC# K6&P;FILPL) ; return / ; case =LK&(=KPU&:(DC7 Xill(imer (h,nd# =L&(=KPU) ; Pna!leKenu=tem (hKenu# =LK&(=KPU&:(FU(# K6&P;FILPL) ; Pna!leKenu=tem (hKenu# =LK&(=KPU&:(DC# K6&YUFGPL) ; return / ; case =LK&FCC&?PLC7

Kessa+eIo" (h,nd# (PW( ("?elp not %et implementedO")# s@Fpp;ame# KI&=4D;PW4LFKF(=D; ^ KI&DX) ; return / ; case =LK&FCC&FIDV(7 Kessa+eIo" (h,nd# (PW( ("Kenu Lemonstration Cro+ram\n") (PW( ("(c) 4harles Cet@old# 1SST")# s@Fpp;ame# KI&=4D;=;6DUKF(=D; ^ KI&DX) ; return / ; !rea0 ; case 8K&(=KPU7 Kessa+eIeep (/) ; return / ; case 8K&LP:(UDG7 CostJuitKessa+e (/) ; return / ; return Lef8indo,Croc (h,nd# messa+e# ,Caram# lCaram) ;

M0)*D0MOARC 3e=cer-ts5
22Kicrosoft Leveloper :tudio +enerated resource script. #include "resource.h" #include "af"res.h" 222222222222222222222222222222222222222222222222222222222222222222222222 22222 22 Kenu KP;VLPKD KP;V L=:4FULFILP IPY=; CDCVC "]6ile" IPY=; KP;V=(PK "];e,"# KP;V=(PK "]Dpen"# KP;V=(PK "]:ave"# KP;V=(PK ":ave ]Fs..."# KP;V=(PK :PCFUF(DU KP;V=(PK "P]"it"# P;L CDCVC "]Pdit" IPY=; KP;V=(PK "]Vndo"# KP;V=(PK :PCFUF(DU KP;V=(PK "4]ut"# KP;V=(PK "]4op%"# KP;V=(PK "]Caste"# KP;V=(PK "Le]lete"# P;L CDCVC "]Iac0+round"

=LK&6=LP&;P8 =LK&6=LP&DCP; =LK&6=LP&:F_P =LK&6=LP&:F_P&F: =LK&FCC&PW=(

=LK&PL=(&V;LD =LK&PL=(&4V( =LK&PL=(&4DCG =LK&PL=(&CF:(P =LK&PL=(&4LPFU

P;L

IPY=; KP;V=(PK "]8hite"# KP;V=(PK "]Li+ht Yra%"# KP;V=(PK "]Yra%"# KP;V=(PK "]Lar0 Yra%"# KP;V=(PK "]Ilac0"# P;L CDCVC "](imer" IPY=; KP;V=(PK "]:tart"# KP;V=(PK ":]top"# P;L CDCVC "]?elp" IPY=; KP;V=(PK "]?elp..."# KP;V=(PK "]F!out KenuLemo..."# P;L

=LK&IXY;L&8?=(P# 4?P4XPL =LK&IXY;L&L(YUFG =LK&IXY;L&YUFG =LK&IXY;L&LXYUFG =LK&IXY;L&ILF4X

=LK&(=KPU&:(FU( =LK&(=KPU&:(DC# YUFGPL

=LK&FCC&?PLC =LK&FCC&FIDV(

R0,O*RC0A' 3e=cer-ts5
22 Kicrosoft Leveloper :tudio +enerated include file. 22 Vsed !% KenuLemo.rc #define =LK&6=LP&;P8 H///1 #define =LK&6=LP&DCP; H///2 #define =LK&6=LP&:F_P H///#define =LK&6=LP&:F_P&F: H///H #define =LK&FCC&PW=( H///. #define =LK&PL=(&V;LD H///M #define =LK&PL=(&4V( H///1 #define =LK&PL=(&4DCG H///T #define =LK&PL=(&CF:(P H///S #define =LK&PL=(&4LPFU H//1/ #define =LK&IXY;L&8?=(P H//11 #define =LK&IXY;L&L(YUFG H//12 #define =LK&IXY;L&YUFG H//1#define =LK&IXY;L&LXYUFG H//1H #define =LK&IXY;L&ILF4X H//1. #define =LK&(=KPU&:(FU( H//1M #define =LK&(=KPU&:(DC H//11 #define =LK&FCC&?PLC H//1T #define =LK&FCC&FIDV( H//1S The &3N.D3&%.8C resource scri"t should give you hints on de'ining the menu. The menu has a te4t name o' I&enuDemo.I &ost items have underlined letters0 !hich means you must ty"e an am"ersand (&* (e'ore the letter. The &3N.+T3& S3$585T%8 statement results 'rom chec ing the Se"arator (o4 in the &enu +tem $ro"erties dialog (o4. Notice that one item in the menu has the Chec ed o"tion and another has the 2rayed o"tion. 5lso0 the 'ive items in the 1ac ground "o"u" menu should (e entered in the order sho!n to ensure that the identi'iers are in numeric orderL the "rogram relies on this. 5ll the menu item identi'iers are de'ined in 83S%.8C3.-. The &3N.D3&% "rogram sim"ly (ee"s !hen it receives a #&9C%&&5ND message 'or most items in the /ile and 3dit "o"u"s. The 1ac ground "o"u" lists 'ive stoc (rushes that &3N.D3&% can use to color the (ac ground. +n the &3N.D3&%.8C resource scri"t0 the #hite menu item (!ith a menu +D o' +D&91K2ND9#-+T3* is 'lagged as C-3CK3D0 !hich "laces a chec mar ne4t to the item. +n &3N.D3&%.C0 the value o' i0election is initially set to +D&91K2ND9#-+T3.

The 'ive (rushes on the 1ac ground "o"u" menu are mutually e4clusive. #hen &3N.D3&%.C receives a #&9C%&&5ND message !here w4aram is one o' these 'ive items on the 1ac ground "o"u"0 it must remove the chec mar 'rom the "reviously chosen (ac ground color and add a chec mar to the ne! (ac ground color. To do this0 it 'irst gets a handle to its menu: hKenu ' YetKenu (h,nd) ; The $hec%Menu*tem 'unction is used to unchec the currently chec ed item: 4hec0Kenu=tem (hKenu# i:election# K6&V;4?P4XPL) ; The i0election value is set to the value o' w4aram0 and the ne! (ac ground color is chec ed: i:election ' ,Caram ; 4hec0Kenu=tem (hKenu# i:election# K6&4?P4XPL) ; The (ac ground color in the !indo! class is then re"laced !ith the ne! (ac ground color0 and the !indo! client area is invalidated. #indo!s erases the !indo!0 using the ne! (ac ground color. The Timer "o"u" lists t!o o"tionsSStart and Sto". +nitially0 the Sto" o"tion is grayed (as indicated in the menu de'inition 'or the resource scri"t*. #hen you choose the Start o"tion0 &3N.D3&% tries to start a timer and0 i' success'ul0 grays the Start o"tion and ma es the Sto" o"tion active: Pna!leKenu=tem (hKenu# =LK&(=KPU&:(FU(# K6&YUFGPL) ; Pna!leKenu=tem (hKenu# =LK&(=KPU&:(DC# K6&P;FILPL) ; %n recei"t o' a #&9C%&&5ND message !ith w4aram e)ual to +D&9T+&389ST%$0 &3N.D3&% ills the timer0 activates the Start o"tion0 and grays the Sto" o"tion: Pna!leKenu=tem (hKenu# =LK&(=KPU&:(FU(# K6&P;FILPL) ; Pna!leKenu=tem (hKenu# =LK&(=KPU&:(DC# K6&YUFGPL) ; Notice that it7s im"ossi(le 'or &3N.D3&% to receive a #&9C%&&5ND message !ith w4aram e)ual to +D&9T+&389ST58T !hile the timer is going. Similarly0 it7s im"ossi(le to receive a #&9C%&&5ND !ith w4aram e)ual to +D&9T+&389ST%$ !hile the timer is not going. #hen &3N.D3&% receives a #&9C%&&5ND message !ith the w4aram "arameter e)ual to +D&95$$951%.T or +D&95$$9-3,$0 it dis"lays a message (o4. (+n the ne4t cha"ter0 !e7ll change this to a dialog (o4.* #hen &3N.D3&% receives a #&9C%&&5ND message !ith w4aram e)ual to +D&95$$93A+T0 it sends itsel' a #&9C,%S3 message. This is the same message that 'ef&indow4roc sends the !indo! "rocedure !hen it receives a #&9SNSC%&&5ND message !ith w4aram e)ual to SC9C,%S3. #e7ll e4amine this more in the $%$$5D; "rogram sho!n near the end o' this cha"ter.

Men$ 0tiK$ette
The 'ormat o' the /ile and 3dit "o"u"s in &3N.D3&% is )uite similar to those in other #indo!s "rograms. %ne o' the o(6ectives o' #indo!s is to "rovide a user !ith a recogniPa(le inter'ace that does not re)uire relearning (asic conce"ts 'or each "rogram. +t certainly hel"s i' the /ile and 3dit menus loo the same in every #indo!s "rogram and use the same letters 'or selection in com(ination !ith the 5lt ey. 1eyond the /ile and 3dit "o"u"s0 the menus o' most #indo!s "rograms !ill "ro(a(ly (e di''erent. #hen designing a menu0 you should loo at e4isting #indo!s "rograms and aim 'or some consistency. %' course0 i' you thin these other "rograms are !rong and you no! the right !ay to do it0 no(ody7s going to sto" you. 5lso ee" in mind that revising a menu usually re)uires revising only the resource scri"t and not your "rogram code. Nou can move menu items around at a later time !ithout many "ro(lems. 5lthough your "rogram menu can have &3N.+T3& statements on the to" level0 these are not ty"ical (ecause they can (e too easily chosen (y mista e. +' you do this0 use an e4clamation "oint a'ter the te4t string to indicate that the menu item does not invo e a "o"u".

Defining a Men$ the 'ard Wa(


De'ining a menu in a "rogram7s resource scri"t is usually the easiest !ay to add a menu in your !indo!0 (ut it7s not the only !ay. Nou can dis"ense !ith the resource scri"t and create a menu entirely !ithin your "rogram (y using t!o 'unctions called $reateMenu and /ppendMenu. 5'ter you 'inish de'ining the menu0 you can "ass the menu handle to $reate&indow or use 0etMenu to set the !indo!7s menu. -ere7s ho! it7s done. $reateMenu sim"ly returns a handle to a ne! menu: hKenu ' 4reateKenu () ;

The menu is initially em"ty. /ppendMenu inserts items into the menu. Nou must o(tain a di''erent menu handle 'or the to":level menu item and 'or each "o"u". The "o"u"s are constructed se"aratelyL the "o"u" menu handles are then inserted into the to":level menu. The code sho!n creates a menu in this 'ashionL in 'act0 it is the same menu that + used in the &3N.D3&% "rogram. /or illustrative sim"licity0 the code uses 5SC++ character strings. $ code that creates the same menu as used in the M,+1',M> program but without requiring a resource script file. hKenu ' 4reateKenu () ; hKenuCopup ' 4reateKenu () ; FppendKenu FppendKenu FppendKenu FppendKenu FppendKenu FppendKenu (hKenuCopup# (hKenuCopup# (hKenuCopup# (hKenuCopup# (hKenuCopup# (hKenuCopup# K6&:(U=;Y# K6&:(U=;Y# K6&:(U=;Y# K6&:(U=;Y# K6&:PCFUF(DU# K6&:(U=;Y# =LK&6=LP&;P8# =LK&6=LP&DCP;# =LK&6=LP&:F_P# =LK&6=LP&:F_P&F:# /# =LK&FCC&PW=(# "];e,") ; "]Dpen...") ; "]:ave") ; ":ave ]Fs...") ; ;VLL) ; "P]"it") ;

FppendKenu (hKenu# K6&CDCVC# hKenuCopup# "]6ile") ; hKenuCopup ' 4reateKenu () ; FppendKenu FppendKenu FppendKenu FppendKenu FppendKenu FppendKenu FppendKenu (hKenuCopup# K6&:(U=;Y# =LK&PL=(&V;LD# (hKenuCopup# K6&:PCFUF(DU# /# (hKenuCopup# K6&:(U=;Y# =LK&PL=(&4V(# (hKenuCopup# K6&:(U=;Y# =LK&PL=(&4DCG# (hKenuCopup# K6&:(U=;Y# =LK&PL=(&CF:(P# (hKenuCopup# K6&:(U=;Y# =LK&PL=(&4LPFU# (hKenu# K6&CDCVC# hKenuCopup# "]Pdit") ; "]Vndo") ; ;VLL) ; "4u]t") ; "]4op%") ; "]Caste") ; "Le]lete") ;

hKenuCopup ' 4reateKenu () ; FppendKenu (hKenuCopup# "]8hite") ; FppendKenu (hKenuCopup# Yra%"); FppendKenu (hKenuCopup# "]Yra%") ; FppendKenu (hKenuCopup# Yra%"); FppendKenu (hKenuCopup# "]Ilac0") ; K6&:(U=;Ya K6&4?P4XPL# =LK&IXY;L&8?=(P# K6&:(U=;Y# K6&:(U=;Y# K6&:(U=;Y# K6&:(U=;Y# =LK&IXY;L&L(YUFG# "]Li+ht =LK&IXY;L&YUFG# =LK&IXY;L&LXYUFG# "]Lar0 =LK&IXY;L&ILF4X#

FppendKenu (hKenu# K6&CDCVC# hKenuCopup# "]Iac0+round") ; hKenuCopup ' 4reateKenu () ; FppendKenu (hKenuCopup# K6&:(U=;Y# =LK&(=KPU&:(FU(# "]:tart") ; FppendKenu (hKenuCopup# K6&:(U=;Y a K6&YUFGPL# =LK&(=KPU&:(DC# ":]top") ; FppendKenu (hKenu# K6&CDCVC# hKenuCopup# "](imer") ; hKenuCopup ' 4reateKenu () ; FppendKenu (hKenuCopup# K6&:(U=;Y# =LK&?PLC&?PLC# FppendKenu (hKenuCopup# K6&:(U=;Y# =LK&FCC&FIDV(# "]?elp") ; "]F!out KenuLemo...")

; FppendKenu (hKenu# K6&CDCVC# hKenuCopup# "]?elp") ; + thin you7ll agree that the resource scri"t menu tem"late is easier and clearer. +7m not recommending that you de'ine a menu in this !ay0 only sho!ing that it can (e done. Certainly you could cut do!n on the code siPe su(stantially (y using some arrays o' structures containing all the menu item character strings0 +Ds0 and 'lags. 1ut i' you do that0 you might as !ell ta e advantage o' the third method #indo!s "rovides 'or de'ining a menu. The (oadMenu*ndirect 'unction acce"ts a "ointer to a structure o' ty"e &3N.+T3&T3&$,5T3 and returns a handle to a menu. This 'unction is used !ithin #indo!s to construct a menu a'ter loading the normal menu tem"late 'rom a resource scri"t. +' you7re (rave0 you can try using it yoursel'.

Floating Po-$- Men$s


Nou can also ma e use o' menus !ithout having a to":level menu (ar. Nou can instead cause a "o"u" menu to a""ear on to" o' any "art o' the screen. %ne a""roach is to invo e this "o"u" menu in res"onse to a clic o' the right mouse (utton. The $%$&3N. "rogram sho!s ho! this is done. .he 4>4M,+1 program.

POPM0)*AC
239999999999999999999999999999999999999999 CDCKP;V.4 99 Copup Kenu Lemonstration (c) 4harles Cet@old# 1SST 999999999999999999999999999999999999999932 #include <,indo,s.h> #include "resource.h" LUP:VL( 4FLLIF4X 8ndCroc (?8;L# V=;(# 8CFUFK# LCFUFK) ; ?=;:(F;4P h=nst ; (4?FU s@Fpp;ameQR ' (PW( ("CopKenu") ; int 8=;FC= 8inKain (?=;:(F;4P h=nstance# ?=;:(F;4P hCrev=nstance# C:(U s@4mdLine# int i4md:ho,) { ?8;L h,nd ; K:Y ms+ ; 8;L4LF:: ,ndclass ; ,ndclass.st%le ,ndclass.lpfn8ndCroc ,ndclass.c!4lsP"tra ,ndclass.c!8ndP"tra ,ndclass.h=nstance ,ndclass.h=con ,ndclass.h4ursor ,ndclass.h!rIac0+round ,ndclass.lps@Kenu;ame ,ndclass.lps@4lass;ame ' ' ' ' ' ' ' ' ' ' 4:&?UPLUF8 ^ 4:&_UPLUF8 ; 8ndCroc ; / ; / ; h=nstance ; Load=con (;VLL# s@Fpp;ame) ; Load4ursor (;VLL# =L4&FUUD8) ; (?IUV:?) Yet:toc0D!$ect (8?=(P&IUV:?) ; ;VLL ; s@Fpp;ame ;

if (OUe+ister4lass (],ndclass)) { Kessa+eIo" (;VLL# (PW( ("(his pro+ram re5uires 8indo,s ;(O")# s@Fpp;ame# KI&=4D;PUUDU) ;

return / ; h=nst ' h=nstance ; h,nd ' 4reate8indo, (s@Fpp;ame# (PW( ("Copup Kenu Lemonstration")# 8:&D_PULFCCPL8=;LD8# 48&V:PLP6FVL(# 48&V:PLP6FVL(# 48&V:PLP6FVL(# 48&V:PLP6FVL(# ;VLL# ;VLL# h=nstance# ;VLL) ; :ho,8indo, (h,nd# i4md:ho,) ; Vpdate8indo, (h,nd) ; ,hile (YetKessa+e (]ms+# ;VLL# /# /)) { (ranslateKessa+e (]ms+) ; LispatchKessa+e (]ms+) ; return ms+.,Caram ; LUP:VL( 4FLLIF4X 8ndCroc (?8;L h,nd# V=;( messa+e# 8CFUFK ,Caram# LCFUFK lCaram) { static ?KP;V hKenu ; static int id4olor Q.R ' { 8?=(P&IUV:?# L(YUFG&IUV:?# YUFG&IUV:?# LXYUFG&IUV:?# ILF4X&IUV:? ; static int i:election ' =LK&IXY;L&8?=(P ; CD=;( point ; s,itch (messa+e) { case 8K&4UPF(P7 hKenu ' LoadKenu (h=nst# s@Fpp;ame) ; hKenu ' Yet:u!Kenu (hKenu# /) ; return / ; case 8K&UIV((D;VC7 point." ' LD8DUL (lCaram) ; point.% ' ?=8DUL (lCaram) ; 4lient(o:creen (h,nd# ]point) ; (rac0CopupKenu (hKenu# (CK&U=Y?(IV((D;# point."# point.%# /# h,nd# ;VLL) ; return / ; case 8K&4DKKF;L7 s,itch (LD8DUL (,Caram)) { case =LK&6=LP&;P87 case =LK&6=LP&DCP;7 case =LK&6=LP&:F_P7 case =LK&6=LP&:F_P&F:7 case =LK&PL=(&V;LD7 case =LK&PL=(&4V(7

case =LK&PL=(&4DCG7 case =LK&PL=(&CF:(P7 case =LK&PL=(&4LPFU7 Kessa+eIeep (/) ; return / ; case case case case case =LK&IXY;L&8?=(P7 =LK&IXY;L&L(YUFG7 =LK&IXY;L&YUFG7 =LK&IXY;L&LXYUFG7 =LK&IXY;L&ILF4X7 22 ;ote7 Lo+ic !elo, 22 assumes that =LK&8?=(P 22 throu+h =LK&ILF4X are 22 consecutive num!ers in 22 the order sho,n here.

4hec0Kenu=tem (hKenu# i:election# K6&V;4?P4XPL) ; i:election ' LD8DUL (,Caram) ; 4hec0Kenu=tem (hKenu# i:election# K6&4?P4XPL) ; :et4lassLon+ (h,nd# Y4L&?IUIF4XYUDV;L# (LD;Y) Yet:toc0D!$ect (id4olor QLD8DUL (,Caram) 9 =LK&IXY;L&8?=(PR)) ; =nvalidateUect (h,nd# ;VLL# (UVP) ; return / ; case =LK&FCC&FIDV(7 Kessa+eIo" (h,nd# (PW( ("Copup Kenu Lemonstration Cro+ram\n") (PW( ("(c) 4harles Cet@old# 1SST")# s@Fpp;ame# KI&=4D;=;6DUKF(=D; ^ KI&DX) ; return / ; case =LK&FCC&PW=(7 :endKessa+e (h,nd# 8K&4LD:P# /# /) ; return / ; case =LK&FCC&?PLC7 Kessa+eIo" (h,nd# (PW( ("?elp not %et implementedO")# s@Fpp;ame# KI&=4D;PW4LFKF(=D; ^ KI&DX) ; return / ; !rea0 ; case 8K&LP:(UDG7 CostJuitKessa+e (/) ; return / ; return Lef8indo,Croc (h,nd# messa+e# ,Caram# lCaram) ;

POPM0)*ARC 3e=cer-ts5
22Kicrosoft Leveloper :tudio +enerated resource script. #include "resource.h" #include "af"res.h"

222222222222222222222222222222222222222222222222222222222222222222222222 22222 22 Kenu CDCKP;V KP;V L=:4FULFILP IPY=; CDCVC "K%Kenu" IPY=; CDCVC "]6ile" IPY=; KP;V=(PK "];e,"# KP;V=(PK "]Dpen"# KP;V=(PK "]:ave"# KP;V=(PK ":ave ]Fs"# KP;V=(PK :PCFUF(DU KP;V=(PK "P]"it"# P;L CDCVC "]Pdit" IPY=; KP;V=(PK "]Vndo"# KP;V=(PK :PCFUF(DU KP;V=(PK "4u]t"# KP;V=(PK "]4op%"# KP;V=(PK "]Caste"# KP;V=(PK "Le]lete"# P;L CDCVC "]Iac0+round" IPY=; KP;V=(PK "]8hite"# 4?P4XPL KP;V=(PK "]Li+ht Yra%"# KP;V=(PK "]Yra%"# KP;V=(PK "]Lar0 Yra%"# KP;V=(PK "]Ilac0"# P;L CDCVC "]?elp" IPY=; KP;V=(PK "]?elp..."# KP;V=(PK "]F!out CopKenu..."# P;L P;L P;L

=LK&6=LP&;P8 =LK&6=LP&DCP; =LK&6=LP&:F_P =LK&6=LP&:F_P&F: =LK&FCC&PW=(

=LK&PL=(&V;LD =LK&PL=(&4V( =LK&PL=(&4DCG =LK&PL=(&CF:(P =LK&PL=(&4LPFU

=LK&IXY;L&8?=(P# =LK&IXY;L&L(YUFG =LK&IXY;L&YUFG =LK&IXY;L&LXYUFG =LK&IXY;L&ILF4X

=LK&FCC&?PLC =LK&FCC&FIDV(

R0,O*RC0A' 3e=cer-ts5
22 Kicrosoft Leveloper :tudio +enerated include file. 22 Vsed !% CopKenu.rc #define #define #define #define #define #define =LK&6=LP&;P8 =LK&6=LP&DCP; =LK&6=LP&:F_P =LK&6=LP&:F_P&F: =LK&FCC&PW=( =LK&PL=(&V;LD H///1 H///2 H///H///H H///. H///M

#define =LK&PL=(&4V( H///1 #define =LK&PL=(&4DCG H///T #define =LK&PL=(&CF:(P H///S #define =LK&PL=(&4LPFU H//1/ #define =LK&IXY;L&8?=(P H//11 #define =LK&IXY;L&L(YUFG H//12 #define =LK&IXY;L&YUFG H//1#define =LK&IXY;L&LXYUFG H//1H #define =LK&IXY;L&ILF4X H//1. #define =LK&FCC&?PLC H//1M #define =LK&FCC&FIDV( H//11 The $%$&3N..8C resource scri"t de'ines a menu similar to the one in &3N.D3&%.8C. The di''erence is that the to":level menu contains only one itemSa "o"u" named I&y&enuI that invo es the /ile0 3dit0 1ac ground0 and -el" o"tions. These 'our o"tions !ill (e arranged on the "o"u" menu in a vertical list rather than on the main menu in a horiPontal list. During the #&9C835T3 message in &nd4roc0 $%$&3N. o(tains a handle to the 'irst "o"u" menuSthat is0 the "o"u" !ith the te4t I&y&enuI: hKenu ' LoadKenu (h=nst# s@Fpp;ame) ; hKenu ' Yet:u!Kenu (hKenu# /) ; During the #&981.TT%N.$ message0 $%$&3N. o(tains the "osition o' the mouse "ointer0 converts the "osition to screen coordinates0 and "asses the coordinates to .rac%4opupMenu: point." ' LD8DUL (lCaram) ; point.% ' ?=8DUL (lCaram) ; 4lient(o:creen (h,nd# ]point) ; (rac0CopupKenu (hKenu# (CK&U=Y?(IV((D;# point."# point.%# /# h,nd# ;VLL) ; #indo!s then dis"lays the "o"u" menu !ith the items /ile0 3dit0 1ac ground0 and -el". Selecting any o' these o"tions causes the nested "o"u" menus to a""ear to the right. The menu 'unctions the same as a normal menu. +' you !ant to use the same menu 'or the "rogram7s main menu and !ith the .rac%4opupMenu0 you7ll have a (it o' a "ro(lem (ecause the 'unction re)uires a "o"u" menu handle. 5 !or around is "rovided in the &icroso't Kno!ledge 1ase article +D @BB^FC.

*sing the ,(stem Men$


$arent !indo!s created !ith a style that includes #S9SNS&3N. have a system menu (o4 at the le't o' the ca"tion (ar. +' you li e0 you can modi'y this menu (y adding your o!n menu commands. +n the early days o' #indo!s0 "rograms commonly "ut the I5(outI menu item on the system menu. #hile modi'ying the system menu is not nearly as common these days0 it remains a )uic :and:dirty !ay to add a menu to a short "rogram !ithout de'ining it in the resource scri"t. The only restriction is this: the +D num(ers you use to add commands to the system menu must (e lo!er than F4/FFF. %ther!ise0 they !ill con'lict !ith the +Ds that #indo!s uses 'or the normal system menu commands. 5nd ee" in mind that !hen you "rocess #&9SNSC%&&5ND messages in your !indo! "rocedure 'or these ne! menu items0 you must "ass the other #&9SNSC%&&5ND messages to 'ef&indow4roc. +' you don7t0 you7ll e''ectively disa(le all normal o"tions on the system menu. The "rogram $%%8&3N. (I$oor $erson7s &enuI*0 sho!n in the /igure 0 adds a se"arator (ar and three commands to the system menu. The last o' these commands removes the additions. .he 4>>"M,+1 program.

POORM0)*AC
2399999999999999999999999999999999999999999 CDDUKP;V.4 99 (he Coor Cerson[s Kenu (c) 4harles Cet@old# 1SST 9999999999999999999999999999999999999999932

#include <,indo,s.h> #define =LK&:G:&FIDV( #define =LK&:G:&?PLC #define =LK&:G:&UPKD_P 1 2 -

LUP:VL( 4FLLIF4X 8ndCroc (?8;L# V=;(# 8CFUFK# LCFUFK) ; static (4?FU s@Fpp;ameQR ' (PW( ("CoorKenu") ; int 8=;FC= 8inKain (?=;:(F;4P h=nstance# ?=;:(F;4P hCrev=nstance# C:(U s@4mdLine# int i4md:ho,) { ?KP;V hKenu ; ?8;L h,nd ; K:Y ms+ ; 8;L4LF:: ,ndclass ; 8ndclass.st%le ,ndclass.lpfn8ndCroc ,ndclass.c!4lsP"tra ,ndclass.c!8ndP"tra ,ndclass.h=nstance ,ndclass.h=con ,ndclass.h4ursor ,ndclass.h!rIac0+round ,ndclass.lps@Kenu;ame ,ndclass.lps@4lass;ame ' ' ' ' ' ' ' ' ' ' 4:&?UPLUF8 ^ 4:&_UPLUF8 ; 8ndCroc ; / ; / ; h=nstance ; Load=con (;VLL# =L=&FCCL=4F(=D;) ; Load4ursor (;VLL# =L4&FUUD8) ; (?IUV:?) Yet:toc0D!$ect (8?=(P&IUV:?) ; ;VLL ; s@Fpp;ame ;

if (OUe+ister4lass (],ndclass)) { Kessa+eIo" (;VLL# (PW( ("(his pro+ram re5uires 8indo,s ;(O")# s@Fpp;ame# KI&=4D;PUUDU) ; return / ; h,nd ' 4reate8indo, (s@Fpp;ame# (PW( ("(he Coor9Cerson[s Kenu")# 8:&D_PULFCCPL8=;LD8# 48&V:PLP6FVL(# 48&V:PLP6FVL(# 48&V:PLP6FVL(# 48&V:PLP6FVL(# ;VLL# ;VLL# h=nstance# ;VLL) ; ?Kenu ' Yet:%stemKenu (h,nd# 6FL:P) ; FppendKenu FppendKenu FppendKenu FppendKenu Fdditions")) ; (hKenu# (hKenu# (hKenu# (hKenu# K6&:PCFUF(DU# /# K6&:(U=;Y# =LK&:G:&FIDV(# K6&:(U=;Y# =LK&:G:&?PLC# K6&:(U=;Y# =LK&:G:&UPKD_P# ;VLL) ; (PW( ("F!out...")) ; (PW( ("?elp...")) ; (PW( ("Uemove

:ho,8indo, (h,nd# i4md:ho,) ; Vpdate8indo, (h,nd) ; 8hile (YetKessa+e (]ms+# ;VLL# /# /)) { (ranslateKessa+e (]ms+) ; LispatchKessa+e (]ms+) ;

return ms+.,Caram ; LUP:VL( 4FLLIF4X 8ndCroc (?8;L h,nd# V=;( messa+e# 8CFUFK ,Caram# LCFUFK lCaram) { s,itch (messa+e) { case 8K&:G:4DKKF;L7 s,itch (LD8DUL (,Caram)) { case =LK&:G:&FIDV(7 Kessa+eIo" (h,nd# (PW( ("F Coor9Cerson[s Kenu Cro+ram\n") (PW( ("(c) 4harles Cet@old# 1SST")# s@Fpp;ame# KI&DX ^ KI&=4D;=;6DUKF(=D;) ; return / ; case =LK&:G:&?PLC7 Kessa+eIo" (h,nd# (PW( ("?elp not %et implementedO")# s@Fpp;ame# KI&DX ^ KI&=4D;PW4LFKF(=D;) ; return / ; case =LK&:G:&UPKD_P7 Yet:%stemKenu (h,nd# (UVP) ; return / ; !rea0 ; case 8K&LP:(UDG7 CostJuitKessa+e (/) ; return / ; return Lef8indo,Croc (h,nd# messa+e# ,Caram# lCaram) ; The three menu +Ds are de'ined near the to" o' $%%8&3N..C: #define =LK&FIDV( 1 #define =LK&?PLC 2 #define =LK&UPKD_P 5'ter the "rogram7s !indo! has (een created0 $%%8&3N. o(tains a handle to the system menu: hKenu ' Yet:%stemKenu (h,nd# 6FL:P) ; #hen you 'irst call 2et0#stemMenu0 you should set the second "arameter to /5,S3 in "re"aration 'or modi'ying the menu. The menu is altered !ith 'our /ppendMenu calls: FppendKenu (hKenu# K6&:PCFUF(DU# /# ;VLL) ; FppendKenu (hKenu# K6&:(U=;Y# =LK&:G:&FIDV(# (PW( ("F!out...")) ; FppendKenu (hKenu# K6&:(U=;Y# =LK&:G:&?PLC# (PW( ("?elp...")) ; FppendKenu (hKenu# K6&:(U=;Y# =LK&:G:&UPKD_P# (PW( ("Uemove Fdditions")); The 'irst /ppendMenu call adds the se"arator (ar. Choosing the 8emove 5dditions menu item causes $%%8&3N. to remove these additions0 !hich it accom"lishes sim"ly (y calling 2et0#stemMenu again !ith the second "arameter set to T8.3: Yet:%stemKenu (h,nd# (UVP) ; The standard system menu has the o"tions 8estore0 &ove0 SiPe0 &inimiPe0 &a4imiPe0 and Close. These generate #&9SNSC%&&5ND messages !ith w4aram e)ual to SC983ST%830 SC9&%V30 SC9S+X30 SC9&+N+&.&0 SC9&5A+&.&0 and SC9C,%S3. 5lthough #indo!s "rograms do not normally do so0 you can "rocess these messages yoursel' rather than "ass them on to 'ef&indow4roc. Nou can also disa(le or remove some o' these standard o"tions 'rom the system menu using methods descri(ed (elo!. The #indo!s documentation also includes

some standard additions to the system menu. These use the identi'iers SC9N3AT#+ND%#0 SC9$83V#+ND%#0 SC9VSC8%,,0 SC9-SC8%,,0 and SC95885N23. Nou might 'ind it a""ro"riate to add these commands to the system menu in some a""lications.

Changing the Men$


#e7ve already seen ho! the /ppendMenu 'unction can (e used to de'ine a menu entirely !ithin a "rogram and to add menu items to the system menu. $rior to #indo!s G.F0 you !ould have (een 'orced to use the $hangeMenu 'unction 'or this 6o(. $hangeMenu !as so versatile that it !as one o' the most com"le4 'unctions in all o' #indo!s (at least at that time*. Times have changed. &any other current 'unctions are no! more com"le4 than $hangeMenu ever !as0 and $hangeMenu has (een re"laced !ith 'ive ne!er 'unctions: /ppendMenu 5dds a ne! item to the end o' a menu. 'eleteMenu Deletes an e4isting item 'rom a menu and destroys the item. *nsertMenu +nserts a ne! item into a menu. Modif#Menu Changes an e4isting menu item. "emoveMenu 8emoves an e4isting item 'rom a menu. The di''erence (et!een 'eleteMenu and "emoveMenu is im"ortant i' the item is a "o"u" menu. 'eleteMenu destroys the "o"u" menuS(ut "emoveMenu does not.

Other Men$ Commands


+n this section0 you7ll 'ind some more 'unctions use'ul 'or !or ing !ith menus. #hen you change a to":level menu item0 the change is not sho!n until #indo!s redra!s the menu (ar. Nou can 'orce this redra!ing (y calling Lra,KenuIar (h,nd) ; Notice that the argument to 'rawMenu)ar is a handle to the !indo! rather than a handle to the menu. Nou can o(tain the handle to a "o"u" menu using hKenuCopup ' Yet:u!Kenu (hKenu# iCosition) ; !here i4osition is the inde4 (starting at F* o' the "o"u" !ithin the to":level menu indicated (y hMenu. Nou can then use the "o"u" menu handle !ith other 'unctions (such as /ppendMenu*. Nou can o(tain the current num(er o' items in a to":level or "o"u" menu (y using i4ount ' YetKenu=tem4ount (hKenu) ; Nou can o(tain the menu +D 'or an item in a "o"u" menu 'rom id ' YetKenu=tem=L (hKenuCopup# iCosition) ; !here i4osition is the "osition (starting at F* o' the item !ithin the "o"u". +n &3N.D3&%0 you sa! ho! to chec or unchec an item in a "o"u" menu using 4hec0Kenu=tem (hKenu# id# i4hec0) ; +n &3N.D3&%0 hMenu !as the handle to the to":level menu0 id !as the menu +D0 and the value o' i$hec% !as either &/9C-3CK3D or &/9.NC-3CK3D. +' hMenu is a handle to a "o"u" menu0 the id "arameter can (e a "ositional inde4 rather than a menu +D. +' an inde4 is more convenient0 you include &/91N$%S+T+%N in the third argument: 4hec0Kenu=tem (hKenu# iCosition# K6&4?P4XPL a K6&IGCD:=(=D;) ; The ,nableMenu*tem 'unction !or s similarly to $hec%Menu*tem0 e4ce"t that the third argument is &/93N51,3D0 &/9D+S51,3D0 or &/9285N3D. +' you use ,nableMenu*tem on a to":level menu item that has a "o"u"0 you must also use the &/91N$%S+T+%N identi'ier in the third "arameter (ecause the menu item has no menu +D. #e7ll see an e4am"le o' ,nableMenu*tem in the $%$$5D; "rogram sho!n later in this cha"ter. -iliteMenu*tem is similar to $hec%Menu*tem and ,nableMenu*tem (ut uses &/9-+,+T3 and &/9.N-+,+T3. This highlighting is the reverse video that #indo!s uses !hen you move among menu items. Nou do not normally need to use -iliteMenu*tem. #hat else do you need to do !ith your menuW -ave you 'orgotten !hat character string you used in a menuW Nou can re'resh your memory (y calling i4har4ount ' YetKenu:trin+ (hKenu# id# p:trin+# iKa"4ount# i6la+) ; The i!lag is either &/91NC%&&5ND (!here id is a menu +D* or &/91N$%S+T+%N (!here id is a "ositional inde4*. The 'unction co"ies u" to iMax$ount characters into p0tring and returns the num(er o' characters co"ied. %r "erha"s you7d li e to no! !hat the current 'lags o' a menu item are:

i6la+s ' YetKenu:tate (hKenu# id# i6la+) ; 5gain0 i!lag is either &/91NC%&&5ND or &/91N$%S+T+%N. The i!lags "arameter is a com(ination o' all the current 'lags. Nou can determine the current 'lags (y testing against the &/9D+S51,3D0 &/9285N3D0 &/9C-3CK3D0 &/9&3N.1835K0 &/9&3N.1581835K0 and &/9S3$585T%8 identi'iers. %r may(e (y this time you7re a little 'ed u" !ith menus. +n that case0 you7ll (e "leased to no! that i' you no longer need a menu in your "rogram0 you can destroy it: Lestro%Kenu (hKenu) ; This 'unction invalidates the menu handle.

>n *northodo= >--roach to Men$s


No! let7s ste" a little o'' the (eaten "ath. +nstead o' having dro":do!n menus in your "rogram0 ho! a(out creating multi"le to":level menus !ithout any "o"u"s and s!itching (et!een the to":level menus using the 0etMenu callW Such a menu might remind old:timers o' that character:mode classic0 ,otus =:;:G. The N%$%$.$S "rogram0 sho!n in the /igure0 demonstrates ho! to do it. This "rogram includes /ile and 3dit items similar to those that &3N.D3&% uses (ut dis"lays them as alternate to":level menus. .he +>4>4140 program.

)OPOP*P,AC
239999999999999999999999999999999999999999999999999 ;DCDCVC:.4 99 Lemonstrates ;o9Copup ;ested Kenu (c) 4harles Cet@old# 1SST 999999999999999999999999999999999999999999999999932 #include <,indo,s.h> #include "resource.h" LUP:VL( 4FLLIF4X 8ndCroc (?8;L# V=;(# 8CFUFK# LCFUFK) ; int 8=;FC= 8inKain (?=;:(F;4P h=nstance# ?=;:(F;4P hCrev=nstance# C:(U s@4mdLine# int i4md:ho,) { static (4?FU ?8;L K:Y 8;L4LF:: s@Fpp;ameQR ' (PW( (";oCopVps") ; h,nd ; ms+ ; ,ndclass ; ' ' ' ' ' ' ' ' ' ' 4:&?UPLUF8 ^ 4:&_UPLUF8 ; 8ndCroc ; / ; / ; h=nstance ; Load=con (;VLL# =L=&FCCL=4F(=D;) ; Load4ursor (;VLL# =L4&FUUD8) ; (?IUV:?) Yet:toc0D!$ect (8?=(P&IUV:?) ; ;VLL ; s@Fpp;ame ;

,ndclass.st%le ,ndclass.lpfn8ndCroc ,ndclass.c!4lsP"tra ,ndclass.c!8ndP"tra ,ndclass.h=nstance ,ndclass.h=con ,ndclass.h4ursor ,ndclass.h!rIac0+round ,ndclass.lps@Kenu;ame ,ndclass.lps@4lass;ame

if (OUe+ister4lass (],ndclass)) { Kessa+eIo" (;VLL# (PW( ("(his pro+ram re5uires 8indo,s ;(O")# s@Fpp;ame# KI&=4D;PUUDU) ; return / ;

h,nd ' 4reate8indo, (s@Fpp;ame# (PW( (";o9Copup ;ested Kenu Lemonstration")# 8:&D_PULFCCPL8=;LD8# 48&V:PLP6FVL(# 48&V:PLP6FVL(# 48&V:PLP6FVL(# 48&V:PLP6FVL(# ;VLL# ;VLL# h=nstance# ;VLL) ; :ho,8indo, (h,nd# i4md:ho,) ; Vpdate8indo, (h,nd) ; ,hile (YetKessa+e (]ms+# ;VLL# /# /)) { (ranslateKessa+e (]ms+) ; LispatchKessa+e (]ms+) ; return ms+.,Caram ; LUP:VL( 4FLLIF4X 8ndCroc (?8;L h,nd# V=;( messa+e# 8CFUFK ,Caram# LCFUFK lCaram) { static ?KP;V hKenuKain# hKenuPdit# hKenu6ile ; ?=;:(F;4P h=nstance ; s,itch (messa+e) { case 8K&4UPF(P7 h=nstance ' (?=;:(F;4P) Yet8indo,Lon+ (h,nd# Y8L&?=;:(F;4P) ; hKenuKain ' LoadKenu (h=nstance# (PW( ("KenuKain")) ; hKenu6ile ' LoadKenu (h=nstance# (PW( ("Kenu6ile")) ; hKenuPdit ' LoadKenu (h=nstance# (PW( ("KenuPdit")) ; :etKenu (h,nd# hKenuKain) ; return / ; case 8K&4DKKF;L7 s,itch (LD8DUL (,Caram)) { case =LK&KF=;7 :etKenu (h,nd# hKenuKain) ; return / ; case =LK&6=LP7 :etKenu (h,nd# hKenu6ile) ; return / ; case =LK&PL=(7 :etKenu (h,nd# hKenuPdit) ; return / ; case case case case =LK&6=LP&;P87 =LK&6=LP&DCP;7 =LK&6=LP&:F_P7 =LK&6=LP&:F_P&F:7

case case case case case

=LK&PL=(&V;LD7 =LK&PL=(&4V(7 =LK&PL=(&4DCG7 =LK&PL=(&CF:(P7 =LK&PL=(&4LPFU7 Kessa+eIeep (/) ; return / ;

!rea0 ; case 8K&LP:(UDG7 :etKenu (h,nd# hKenuKain) ; Lestro%Kenu (hKenu6ile) ; Lestro%Kenu (hKenuPdit) ; CostJuitKessa+e (/) ; return / ; return Lef8indo,Croc (h,nd# messa+e# ,Caram# lCaram) ;

)OPOP*P,ARC 3e=cer-ts5
22Kicrosoft Leveloper :tudio +enerated resource script. #include "resource.h" #include "af"res.h" 222222222222222222222222222222222222222222222222222222222222222222222222 22222 22 Kenu KP;VKF=; KP;V L=:4FULFILP IPY=; KP;V=(PK "KF=;7"# KP;V=(PK "]6ile..."# KP;V=(PK "]Pdit..."# P;L KP;V6=LP KP;V L=:4FULFILP IPY=; KP;V=(PK "6=LP7"# KP;V=(PK "];e,"# KP;V=(PK "]Dpen..."# KP;V=(PK "]:ave"# KP;V=(PK ":ave ]Fs"# KP;V=(PK "(]Kain)"# P;L KP;VPL=( KP;V L=:4FULFILP IPY=; KP;V=(PK "PL=(7"# KP;V=(PK "]Vndo"# KP;V=(PK "4u]t"# KP;V=(PK "]4op%"# KP;V=(PK "]Caste"# KP;V=(PK "Le]lete"#

/# =;F4(=_P =LK&6=LP =LK&PL=(

/# =;F4(=_P =LK&6=LP&;P8 =LK&6=LP&DCP; =LK&6=LP&:F_P =LK&6=LP&:F_P&F: =LK&KF=;

/# =;F4(=_P =LK&PL=(&V;LD =LK&PL=(&4V( =LK&PL=(&4DCG =LK&PL=(&CF:(P =LK&PL=(&4LPFU

P;L

KP;V=(PK "(]Kain)"#

=LK&KF=;

R0,O*RC0A' 3e=cer-ts5
22 Kicrosoft Leveloper :tudio +enerated include file. 22 Vsed !% ;oCopups.rc #define =LK&6=LP H///1 #define =LK&PL=( H///2 #define =LK&6=LP&;P8 H///#define =LK&6=LP&DCP; H///H #define =LK&6=LP&:F_P H///. #define =LK&6=LP&:F_P&F: H///M #define =LK&KF=; H///1 #define =LK&PL=(&V;LD H///T #define =LK&PL=(&4V( H///S #define =LK&PL=(&4DCG H//1/ #define =LK&PL=(&CF:(P H//11 #define =LK&PL=(&4LPFU H//12 +n &icroso't Develo"er Studio0 you create three menus rather than one. Nou7ll (e selecting 8esource 'rom the +nsert menu three times. 3ach menu has a di''erent te4t name. #hen the !indo! "rocedure "rocesses the #&9C835T3 message0 #indo!s loads each menu resource into memory: hKenuKain ' LoadKenu (h=nstance# (PW( ("KenuKain")) ; hKenu6ile ' LoadKenu (h=nstance# (PW( ("Kenu6ile")) ; hKenuPdit ' LoadKenu (h=nstance# (PW( ("KenuPdit")) ; +nitially0 the "rogram dis"lays the main menu: :etKenu (h,nd# hKenuKain) ; The main menu lists the three o"tions using the character strings I&5+N:I0 I/ile...I0 and I3dit...I -o!ever0 I&5+N:I is disa(led0 so it doesn7t cause #&9C%&&5ND messages to (e sent to the !indo! "rocedure. The /ile and 3dit menus (egin I/+,3:I and I3D+T:I to identi'y these as su(menus. The last item in each menu is the character string I(&ain*IL this o"tion indicates a return to the main menu. S!itching among these three menus is sim"le: case 8K&4DKKF;L 7 s,itch (,Caram) { case =LK&KF=; 7 :etKenu (h,nd# hKenuKain) ; return / ; case =LK&6=LP 7 :etKenu (h,nd# hKenu6ile) ; return / ; case =LK&PL=( 7 :etKenu (h,nd# hKenuPdit) ; return / ; [other pro"ram lines] !rea0 ; During the #&9D3ST8%N message0 N%$%$.$S sets the "rogram7s menu to the &ain menu and destroys the /ile and 3dit menus !ith calls to 'estro#Menu. The &ain menu is destroyed automatically !hen the !indo! is destroyed.

FOR MFC
8e'er to IYYSo'9serverYD9DriveY3:1oo sY$rogramming:,anguagesY$rogramming #indo!s !ith &/C ;nd 3ditionY$rogm'c;.chmI

FOR COM
$l 8e'er: +nside %le 1oo availa(le in the ,i(rary %8 'rom &SDN 5nd IYYSo'9serverYD9DriveY3:1oo sY$rogramming:,anguagesYDesigning Com"onent:1ased 5""licationsY.ndercom.chmI

Anda mungkin juga menyukai