Gary Entsminger
TURBO PASCAL B
FOR WINDOWS
I B L E
The Most Comprehensive Tutorial and Reference for Experienced Pro...
224 downloads
2417 Views
16MB Size
Report
This content was uploaded by our users and we assume good faith they have the permission to share this book. If you own the copyright to this book and it is wrongfully on our website, we offer a simple DMCA procedure to remove your content from our site. Start by pressing the button below!
Report copyright / DMCA form
Gary Entsminger
TURBO PASCAL B
FOR WINDOWS
I B L E
The Most Comprehensive Tutorial and Reference for Experienced Programmers
E x a m p l e s , screen illustrations, and practical application samples Essential command reference section describes all features Exclusive coverage of ObjectWindows functions and the Windows A P I
The TPW Command-line Compiler T u r b o Pascal for W i n d o w s c o m m a n d - l i n e o p t i o n s u s e this syntax:
TPCW
[options]
w h e r e [options]
[options]
can b e o n e or m o r e options, separated by spaces. Y o u designate the
s t a t u s o f t h e c o m p i l e r o p t i o n b y s p e c i f y i n g a p l u s ( + ) o r a m i n u s (-) after t h e o p t i o n . •
P l a c e a + ( o r a s p a c e ) after a n o p t i o n t o t u r n it O n .
•
P l a c e a - after t h e o p t i o n t o t u r n it O f f . Compiler Options Directive
Option /$A /IB /$D /IF /|G /II /|L
options Option
Meaning Align data Boolean evaluation Debug information Force FAR calls Generate 286 instructions Input/output checking Local symbol information
Meaning
/IN /|R /IS /IV /|W
80x87 code (numeric coprocessor) Range checking Stack-overflow checking String var checking Windows stack frame
/IX
Extended syntax
Mode options Option
Option
Meaning
/B /F /L
Build all Find error Link buffer Conditional
Option /D
/M
Make
/Q
Quiet (no IDE equivalent)
defines
Meaning
Meaning
option
Option
Meaning
Conditional defines Debug options
Option
Meaning
/G
MAP file Directory
Option
Meaning
/E /I /O
E X E and TPU directory Include directories Object Files directories
Option
Meaning
/V
Debug info in EXE option
options Option
Meaning
/R /T /U
Resource directories Turbo directory Unit directories
C o m m a n d - l i n e Options a n d Their IDE Equivalents. Option
IDE
/|A /IB /ID /IF /|G /II /|L /|M /IN /|R /IS /IV
Options/Compiler/Align data Options/Compiler/Boolean evaluation Options/Compiler/Debug information Options/Compiler/Force far calls Options/Compiler/286 code Options/Compiler/I/O checking Options/Compiler/Local symbols Options/Compiler/Memory sizes Options/Compiler/80x87 code Options/Compiler/Range checking Options/Compiler/Stack checking Options/Compiler/String var checking options Optioni/Compiler/Windows stack frames Options/Compiler/Extended syntax
/|W /IX
Equivalent
Option
IDE
/B /D /E /F /G /I /L /M /O /Q /R /T /U /V
Compile/Build Options/Compiler/Conditional defines Options/Directories/EXE and TPU directory Search/Find error Options/Linker/MAP file Options/Compiler/Include directories Options/Linker/Link buffer Compile/Make Options/Directories/Object directories (none) • Options/Directories/Resource directories (none) Options/Directories/Unit directories Options/Linker/Debug info in EXE
Equivalent
Turbo Pascal® for Windows™ Bible
Turbo Pascal® for Windows Bible Gary Entsminger
SAMS A Division of Macmillan Computer Publishing 11711 North College, Carmel, Indiana 46032 USA
For Alison
© 1992 by SAMS FIRST EDITION FIRST PRINTING—1991 All rights reserved. No part of this book shall be reproduced, stored in a retrieval system, or transmitted by any means, electronic, mechanical, photocopying, recording, or otherwise, without written permission from the publisher. N o patent liability is assumed with respect to the use of the information contained herein. Although every precaution has been taken in the preparation of this book, the publisher and author assume no responsibility for errors or omission. Neither is any liability assumed for damages resulting from the use of the information contained herein. For information, address SAMS, 11711 N. College Ave., Carmel, IN 46032. International Standard Book Number: 0-672-30212-8 Library of Congress Catalog No.: 91-66924
Publisher Richard K. Swadley Publishing Manager Joseph Wikert Managing Editor Neweleen A. Trebnik Acquisitions Editor Gregory S. Croy Development Editor Paula Northam Grady Editors Kezia Endsley Becky Freeman Jodi Jensen Rebecca Whitney Technical
Production Claudia Bell Sandy Grieshop Denny Hager Audra Hershman Bob LaRoche Laurie Lee Juli Pavey Howard Peirce Tad Ringo Bruce Steed Mary Beth Wakefield Lisa Wilson Phil Worthington Christine Young Book
Design Scott Cook Michele Laseau
Cover Design Tim Amrhein
Editor
Jeffrey Hsu
Indexer Johnna VanHoose
Composed in Garamond
and MCP Digital by Macmillan
Computer
Printed in the United States of America
Publishing.
Overview Parti
Working with TPW
1
G e t t i n g Started, 3
2 3 4
E l e m e n t s o f A p p l i c a t i o n D e v e l o p m e n t , 43 Objects for W i n d o w s , 77 Inheriting a n Interface, 111
5 6
Putting Pictures in W i n d o w s , 149 Painting, C o l l e c t i n g , a n d S t r e a m i n g , 185
Part II Advanced Topics 7 8 9 10 11 12 13
Part III A B C
M a n y W i n d o w s : A M u l t i - D o c u m e n t Interface, 2 1 3 R e s o u r c e s a n d C o n t r o l O b j e c t s , 241 M e m o r y Matters, 2 7 9 D i s p l a y C o n t e x t s a n d D r a w i n g T o o l s , 301 F r o m Program to Program Using D D E (Dynamic Data Exchange), 343 S h a r i n g Libraries U s i n g D L L ( D y n a m i c L i n k Libraries), 3 6 9 D e s i g n i n g W i n d o w s A p p l i c a t i o n s , 383
References O b j e c t W i n d o w s O b j e c t s , 405 ObjectWindows Constants, 499 O b j e c t W i n d o w s P r o c e d u r e s a n d F u n c t i o n s , 505
D
O b j e c t W i n d o w s R e c o r d s , 509
E F G H I J K L M N O P Q R S
T h e W i n C r t Unit, 515 A W i n C r t E x a m p l e , 525 T h e Strings Unit, 539 T h e T u r b o Pascal for W i n d o w s S y s t e m Unit, 553 T h e T u r b o Pascal for W i n d o w s W i n D o s Unit, 561 D e b u g g i n g T u r b o Pascal for W i n d o w s A p p l i c a t i o n s , 587 T u r b o Pascal for W i n d o w s Error M e s s a g e s , 591 W i n d o w M a n a g e r Interface P r o c e d u r e s a n d F u n c t i o n s , 635 S y s t e m Services Interface P r o c e d u r e s a n d F u n c t i o n s , 723 G D I ( G r a p h i c s D e v i c e Interface) P r o c e d u r e s a n d F u n c t i o n s , 793 O b j e c t G r a p h i c s (A W h i t e w a t e r G r o u p G r a p h i c s T o o l k i t ) , 861 N o t e s for M a n a g i n g a Project, 8 6 7 Glossary, 8 6 9 R e f e r e n c e s , R e s o u r c e s , a n d N o t e s , 881 A S C I I C o d e C h a r a c t e r Set, 8 8 7 I n d e x , 891
Contents I
WORKING WITH TPW
1
Getting Started, 3 C r e a t i n g Windows A p p l i c a t i o n s , 3 S y s t e m R e q u i r e m e n t s a n d Installation, 4 T h e T u r b o Pascal for Windows I D E , 4 T u r b o Pascal for Windows I D E M e n u C o m m a n d s , 7 T h e T u r b o Pascal for Windows D e s k t o p C o n t r o l M e n u , 7 Restore, 8 Move, 8 Size, 8 Minimize, 8 Maximize, 8 Close, 8 Switch T o , 9 T h e Edit Window
Control Menu, 9
Restore, 9 Move, 9 Size, 10 M i n i m i z e , 10 M a x i m i z e , 10 C l o s e , 10 N e x t , 10 T h e File M e n u , 10 N e w , 11 O p e n , 11 Save, 12 Save A s , 12 Save All, 12 Print, 12 Printer S e t u p , 13 Exit, 14 List o f C l o s e d Files, 14
vii
T u r b o Pascal for W i n d o w s B i b l e
T h e Edit M e n u , 14 U n d o , 14 R e d o , 15 C u t , 15 C o p y , 15 Paste, 15 C l e a r , 16 T h e S e a r c h M e n u , 16 F i n d , 16 R e p l a c e , 16 S e a r c h A g a i n , 16 G o t o L i n e N u m b e r , 17 S e a r c h / S h o w Last C o m p i l e Error, 18 Search/Find Error, 18 T h e R u n M e n u , 18 R u n / R u n , 18 R u n / D e b u g g e r , 18 Run/Parameters, 19 T h e C o m p i l e M e n u , 19 Compile/Compile, 20 C o m p i l e / M a k e , 20 C o m p i l e / B u i l d , 21 C o m p d e / P r i m a r y File, 21 C o m p i l e / C l e a r Primary File, 21 C o m p i l e / I n f o r m a t i o n , 21 C o m p i l e I n f o r m a t i o n B o x , 21 T h e O p t i o n s M e n u , 22 C o m p i l e r , 22 Linker, 23 Directories, 23 G u i d e l i n e s for E n t e r i n g Directory N a m e s , 24 Preferences, 25 E d i t o r O p t i o n s , 25 O p e n , 26 Save, 26 Save A s , 2 7 Directories List B o x , 28 T h e W i n d o w M e n u , 28 T i l e , 28 C a s c a d e , 28 A r r a n g e I c o n s , 28 C l o s e All, 29
viii
Contents
T h e H e l p M e n u (Alt-H), 29 I n d e x ( S h i f t - F l ) , 29 T o p i c S e a r c h ( C t r l - F l ) , 29 Help/Using H e l p , 30 C o m p i l e r Directives, 30 O b j e c t W i n d o w s , 30 P r o c e d u r e s a n d F u n c t i o n s , 30 Reserved W o r d s , 30 S t a n d a r d U n i t s , 31 T u r b o Pascal for W i n d o w s L a n g u a g e , 31 W i n d o w s A P I , 31 A b o u t T u r b o Pascal for W i n d o w s , 31 Editor, 31 T h e E d i t o r C o m m a n d s , 31 T h e B l o c k C o m m a n d s , 32 C o p y B l o c k , 32 C o p y Text, 32 C u t Text, 32 D e l e t e B l o c k , 32 M o v e B l o c k , 32 Paste f r o m C l i p b o a r d , 33 R e a d B l o c k from D i s k , 33 Write B l o c k t o D i s k , 33 E d i t o r - C o m m a n d T a b l e s , 33 A u t o I n d e n t , 36 C u r r e n t C o m p i l e r O p t i o n s , 36 C u r s o r t h r o u g h T a b s , 36 F i n d Place M a r k e r , 3 7 O p e n File, 3 7 O p t i m a l Fill, 3 7 Save File, 3 7 Set Place, 3 7 S h o w Last C o m p i l e Error, 3 7 T a b M o d e , 37 Unindent, 37 T h e T P W C o m m a n d - l i n e Compiler, 38 O n w a r d , F o r w a r d , a n d U p w a r d , 41
2
Elements of Application Development, 43 Units, 44 D a t a T y p e s a n d Identifiers, 50 O r d i n a l T y p e s , 52 B o o l e a n T y p e s , 52
ix
T u r b o Pascal for W i n d o w s B i b l e
C h a r T y p e , 53 E n u m e r a t e d T y p e s , 54 S u b r a n g e T y p e s , 54 Reals, 55 Strings, 55 S t r u c t u r e d T y p e s , 56 Arrays, 57 R e c o r d s , 57 O b j e c t T y p e s , 58 Sets, 59 Files, 59 Pointer T y p e s , 6 0 P C h a r , 61 P r o c e d u r a l T y p e s , 62 T u r b o Pascal for W i n d o w s Reserved W o r d s , 62 S t a t e m e n t s , 63 a s s i g n m e n t ( : = ) , 64 begin..end, 64 c a s e . . o f . . e l s e . . e n d , 65 for..to/downto..do, 66 g o t o , 66 if..then..else, 67 inline(...), 68 p r o c e d u r e call, 69 r e p e a t . . u n t i l , 70 w h i l e . . d o , 70 w i t h . . d o , 71 D e b u g g i n g T u r b o Pascal for W i n d o w s A p p l i c a t i o n s , 72 B e g i n . . , 75
3
Objects for Windows, 77 Overture, 77 A b o u t T u r b o Pascal W i n d o w s , 7 8 W h y D o e s t h e W o r l d M a k e S o M u c h Sense?, 81 T h e T a o o f O b j e c t s , 81 Inheritance, 84 P o l y m o r p h i s m , 86 Messages, 88 Static a n d D y n a m i c B i n d i n g , 9 0 D y n a m i c Style, 91 E x t e n d e d V i e w s , 92
X
Contents
A b o u t Microsoft W i n d o w s , 9 3 W i n d o w s Structure, 95 W h y O O P a n d W i n d o w s , 101 A b o u t O b j e c t W i n d o w s , 102 Events, M e s s a g e s , a n d O b j e c t s , 106 W i n d o w s M e s s a g e s , 107 A b o u t W i n C r t , 107 M o v i n ' O n , 109
4
Inheriting an Interface, 111 T h e Basiclnterface, 113 A p p l i c a t i o n a n d W i n d o w O b j e c t s , 114 T h e M a i n W i n d o w , 116 Details, 119 W i n d o w M e s s a g e s , 122 D i s p l a y C o n t e x t s , 126 U s i n g R e s o u r c e s , 127 Pascal a n d C Strings, 129 A F e w R u l e s , 130 A d d i n g D i a l o g s , 130 A d d i n g a File D i a l o g , 134 T w o K i n d s o f File D i a l o g s , 135 C o n s t a n t s , 136 C o n t r o l s , 136 A d d i n g List B o x e s , 138 M e s s a g e B o x e s , 141 C l o s i n g a n A p p l i c a t i o n , 142 W r a p p i n g U p t h e Basiclnterface, 143
5
Putting Pictures in Windows, 149 M e n u s , I D s , a n d M e s s a g e s , 150 Tasks, 156 O t h e r W i n d o w s , O t h e r T a s k s , 162 M o d e l Tasks, 162 M o d e l i n g , 163 C h a o s a n d S t r a n g e Attractors, 166 M a t h e m a t i c Attraction, 170 O r d e r i n C h a o s , 171 G r a n d F i n a l e , 175
xi
T u r b o Pascal for W i n d o w s B i b l e
6
Painting, Collecting, and Streaming, 185 P o l y m o r p h i c C o l l e c t i o n s , 187 C o l l e c t i n g Points, 189 Streams, 194 Putting Points in a Stream, 199 H o w Put Works, 2 0 0 G e t t i n g Points, 201 T h e S u m o f Streams, 203
II
ADVANCED TOPICS
7
Many Windows: A Multi-Document Interface, 213 A Basic M D I Interface, 214 Setting U p a Basic M D I Interface, 2 1 7 A M o d e l M D I , 219 M D I M e s s a g e Processing, 221 Editors, 222 A n M D I Editor, 226 M D I Wrap-up,
8
233
Resources and Control Objects, 241 R e s o u r c e s , 242 R e s o u r c e Editors, 255 D i a l o g Windows, 256 Details, 2 6 0 C o n t r o l O b j e c t s , 267 G r o u p Boxes, 270 C o n t r o l s in C o m b i n a t i o n , 274 Bit M a p s , 2 7 6 Wrap-up, 278
9
Memory Matters, 279 M e m o r y M a n a g e m e n t , Windows Style, 2 8 0 G l o b a l a n d L o c a l M e m o r y , 283 Allocating L o c a l M e m o r y B l o c k s , 284 G l o b a l Memory Blocks, 290 A F e w A d v a n c e d M e m o r y Matters, 2 9 7 Direct M e m o r y A c c e s s , 2 9 7
xii
Contents
Data Segments, 297 H e a p Errors, 298 C o d e Segments, 299 w m C o m p a c t i n g , 299 Wrap-up, 300
10 Display Contexts and Drawing Tools, 301 H a n d l i n g a D i s p l a y C o n t e x t , 302 M a p p i n g M o d e s , 315 D r a w i n g F i g u r e s , 322 A Stranger G r a p h i c s F u n c t i o n D e m o , 3 2 7 Wrap-up, 340
11 From Program to Program Using D D E (Dynamic Data Exchange), 343 T h e C l i p b o a r d , 344 Pasting from t h e C l i p b o a r d , 348 S h a r i n g D a t a B e t w e e n A p p l i c a t i o n s , 353 A t o m s , a n d S o O n , 354 W r a p - u p , 368
12 Sharing libraries: Using DLL (Dynamic Link Libraries), 369 D L L Details, 3 7 0 U s i n g D L L s , 371
13 Designing Windows Applications, 383 C o m m o n U s e r A c c e s s , 384 O b j e c t s a n d W i n d o w s , 386 D e s i g n i n g for C h a n g e , 3 8 9 O b j e c t - O r i e n t e d A p p l i c a t i o n D e s i g n , 392 A T a o o f W i n d o w s , 393 O b j e c t Discovery, 394 Star W a r s a n d D a n c e s : T h e S e q u e l , 395 Begin Discovering Objects, 400 W r a p - u p , 401
xiii
T u r b o Pascal for W i n d o w s B i b l e
III REFERENCES A
ObjectWindows Objects, 405 TApplication, 406 TBufStream, 411 T B u t t o n , 414 T C h e c k B o x , 416 TCollection, 419 T C o m b o B o x , 427 TControl, 430 T D i a l o g , 432 TDlgWindow, 436 TDosStream, 437 TEdit, 4 4 0 TEmsStream, 447 T G r o u p B o x , 450 TListBox, 452 TMDIClient, 457 TMDIWindow, 459 T O b j e c t , 464 T R a d i o B u t t o n , 465 TScrollBar, 4 6 6 TScroller, 471 TSortedCollection, 479 TStatic, 4 8 2 T S t r C o l l e c t i o n , 484 TStream, 486 T W i n d o w , 491
B
ObjectWindows Constants, 499 b f _ X X X X Constants, 499 c m X X X X Constants, 499 c o X X X X C o n s t a n t s , 501 e m X X X X C o n s t a n t s , 501 id_XXXX C o n s t a n t s , 502 n f X X X X C o n s t a n t s , 502 s t X X X X C o n s t a n t s , 502 t f _ X X X X C o n s t a n t s , 503 w b _ X X X X C o n s t a n t s , 503 w m _ X X X X C o n s t a n t s , 504
xiv
Contents
C
ObjectWindows Procedures and Functions, 505 Abstract, 506 A l l o c M u l t i S e l , 506 D i s p o s e S t r , 506 F r e e M u l t i S e l , 506 G e t O b j e c t P t r , 506 L o n g D i v , 507 L o n g M u l , 507 L o w M e m o r y , 507 M e m A l l o c , 507 N e w S t r , 508 RegisterType, 508 R e g i s t e r W O b j e c t s , 508 R e s t o r e M e m o r y , 508
D
ObjectWindows Records, 509 L o n g R e c , 509 PtrRec, 510 T D i a l o g A t t r , 510 T M e s s a g e , 510 T M u l t i S e l R e c , 511 T S c r o l l B a r T r a n s f e r R e c , 511 T S t r e a m R e c , 511 T W i n d o w A t t r , 512 W o r d R e c , 513
E
The WinCrt Unit, 515 A s s i g n C r t , 516 ClrEol, 517 C l r S c r , 517 C u r s o r T o , 518 D o n e W i n C r t , 518 G o t o X Y , 519 I n i t W i n C r t , 519 KeyPressed, 520 R e a d B u f , 520 R e a d K e y , 521 S c r o l l T o , 521 T r a c k C u r s o r , 522 W h e r e X , ^22
XV
T u r b o Pascal for W i n d o w s B i b l e
W h e r e Y , 523 WriteBuf, 523 W r i t e C h a r , 524
F
A WinCrt Example, 525
G
The Strings Unit, 539 StrCat, 540 S t r C o m p , 541 S t r C o p y , 542 S t r D i s p o s e , 542 S t r E C o p y , 543 S t r E n d , 543 S t r l C o m p , 544 StrLCat, 544 S t r L C o m p , 545 S t r L C o p y , 546 StrLen, 546 S t r L I C o m p , 547 StrLower, 547 S t r M o v e , 548 S t r N e w , 548 StrPas, 549 S t r P C o p y , 550 StrPos, 550 S t r R S c a n , 551 S t r S c a n , 551 S t r U p p e r , 552
H
The Turbo Pascal for Windows System Unit, 553
I
The Turbo Pascal for Windows WinDos Unit, 561 C o n s t a n t s , 561 T y p e s , 563 A n Index of W i n D o s Procedures and Functions b y F u n c t i o n (or C a t e g o r y ) , 566
J
xvi
Debugging Turbo Pascal for Windows Applications, 587
Contents
K
Turbo Pascal for Windows Error Messages, 591 C o m p i l e r Error M e s s a g e s , 592 R u n - t i m e Error M e s s a g e s , 6 2 6
L
Window Manager Interface Procedures and Functions, 635 C a r e t P r o c e d u r e s a n d F u n c t i o n s , 635 Clipboard Procedures and Functions, 638 C u r s o r P r o c e d u r e s a n d F u n c t i o n s , 642 D i a l o g - B o x P r o c e d u r e s a n d F u n c t i o n s , 645 Display and M o v e m e n t Procedures and Functions, 658 Error P r o c e d u r e s a n d F u n c t i o n s , 6 6 4 H a r d w a r e P r o c e d u r e s a n d F u n c t i o n s , 665 H o o k Procedures and Functions, 669 I n f o r m a t i o n P r o c e d u r e s a n d F u n c t i o n s , 671 Input Procedures and Functions, 676 M e n u P r o c e d u r e s a n d F u n c t i o n s , 681 M e s s a g e P r o c e d u r e s a n d F u n c t i o n s , 691 Painting P r o c e d u r e s a n d F u n c t i o n s , 6 9 8 Property P r o c e d u r e s a n d F u n c t i o n s , 705 Scrolling P r o c e d u r e s a n d F u n c t i o n s , 7 0 6 System Procedures a n d Functions, 710 W i n d o w - C r e a t i o n P r o c e d u r e s a n d F u n c t i o n s , 711
M
System Services Interface Procedures and Functions, 723 Application-Execution Functions, 723 A t o m - M a n a g e m e n t P r o c e d u r e s a n d F u n c t i o n s , 725 C o m m u n i c a t i o n Procedures and Functions, 729 File I/O P r o c e d u r e s a n d F u n c t i o n s , 735 Initialization-File P r o c e d u r e s a n d F u n c t i o n s , 7 4 0 M e m o r y - M a n a g e m e n t P r o c e d u r e s a n d F u n c t i o n s , 743 Module-Management Procedures and Functions, 757 O p e r a t i n g - S y s t e m Interrupt P r o c e d u r e s a n d F u n c t i o n s , 761 R e s o u r c e - M a n a g e m e n t P r o c e d u r e s a n d F u n c t i o n s , 762 Segment Procedures and Functions, 768 S o u n d Procedures and Functions, 773 S t r i n g - M a n i p u l a t i o n P r o c e d u r e s a n d F u n c t i o n s , 778 Task Procedures and Functions, 786 Utility M a c r o s a n d F u n c t i o n s , 788
xvii
T u r b o Pascal for W i n d o w s B i b l e
N
G D I (Graphics Device Interface) Procedures and Functions, 793 B i t m a p P r o c e d u r e s a n d F u n c t i o n s , 794 Clipping Procedures a n d Functions, 800 C o l o r Palette P r o c e d u r e s a n d F u n c t i o n s , 8 0 3 C o o r d i n a t e - T r a n s l a t i o n Procedures a n d F u n c t i o n s , 8 0 7 D e v i c e - C o n t e x t Procedures a n d F u n c t i o n s , 8 0 9 Device-Independent Bitmap Procedures a n d Functions, 812 Drawing-Attribute Procedures a n d F u n c t i o n s , 815 Drawing-Tool Procedures a n d Functions, 819 Environment Procedures and Functions, 826 F o n t Procedures a n d F u n c t i o n s , 8 2 7 Line-Drawing Procedures a n d F u n c t i o n s , 8 3 0 M a p p i n g Procedures and Functions, 832 Metafile P r o c e d u r e s a n d F u n c t i o n s , 8 3 7 Printer-Control P r o c e d u r e s a n d F u n c t i o n s , 8 4 1 R e c t a n g l e Procedures a n d F u n c t i o n s , 8 4 2 Region Procedures a n d Functions, 844 S h a p e - D r a w i n g P r o c e d u r e s a n d F u n c t i o n s , 851 T e x t - D r a w i n g P r o c e d u r e s a n d F u n c t i o n s , 855
O
ObjectGraphics (A Whitewater Group Graphics Toolkit), 861
P
Notes for Managing a Project, 867
Q
Glossary, 869
R
References, Resources, and Notes, 881 Quotation Acknowledgments, 884
S
ASCII Code Character Set, 887 Index, 891
xviii
Introduction
Look out of any window,
any morning,
any evening, any day. Robert H u n t e r
How This Book Is Organized W e l c o m e t o Turbo Pascal for Windows Bible, a b o o k that will clear m a n y o f t h e mysteries o f W i n d o w s p r o g r a m m i n g i n T u r b o Pascal for W i n d o w s style. W i n d o w s p r o g r a m m i n g is difficult, b u t T u r b o Pascal for W i n d o w s m a k e s t h e difficulty m a n a g e a b l e . I n fact, d e v e l o p i n g W i n d o w s applications w i t h T u r b o Pascal for W i n d o w s is m u c h m o r e f u n o n c e y o u get t h e h a n g o f it. T h i s bible s h o w s y o u h o w t o get t h e h a n g o f it. Turbo 1.
Pascal
for
Windows
Bible
consists of three sections:
Working With TPW A n introduction to object-oriented p r o g r a m m i n g and the T u r b o Pascal for W i n d o w s o b j e c t library, O b j e c t W i n d o w s , p l u s t h e l a n g u a g e s y n t a x a n d o t h e r d e t a i l s . T h i s s e c t i o n is l o a d e d w i t h p r a c t i c a l e x a m p l e s a n d is i n t e n d e d t o b r i n g y o u u p t o W i n d o w s application d e v e l o p m e n t s p e e d in a hurry.
2.
Advanced topics This section discusses s o m e of the m o r e c o m p l e x aspects of W i n d o w s a p p l i c a t i o n d e v e l o p m e n t , s u c h as m e m o r y m a n a g e m e n t ,
T u r b o Pascal for W i n d o w s B i b l e
d y n a m i c d a t a e x c h a n g e ( D D E ) , d y n a m i c l i n k libraries ( D L L ) , d e s i g n c o n s i d e r a t i o n s , a n d s o o n . T h i s s e c t i o n is t h e o n e t o r e a d a n d s t u d y after y o u k n o w t h e basics o f o b j e c t - o r i e n t e d p r o g r a m m i n g , TPW-style. 3.
Reference A d e t a i l e d a c c o u n t o f t h e O b j e c t W i n d o w o b j e c t - o r i e n t e d library, i n c l u d i n g o b j e c t s , p r o c e d u r e s , r e c o r d s , a n d c o n s t a n t s . T h e refere n c e a l s o is a c o m p l e t e d e s c r i p t i o n o f t h e W i n d o w s A P I f u n c t i o n s , a g l o s s a r y , a r e a d i n g list, a n d a n y t h i n g e l s e that is i m p o r t a n t b u t d o e s n o t fit i n t h e first t w o s e c t i o n s .
Reader, Who Are You? A l t h o u g h I c a n n o t b e sure, I a s s u m e that y o u already k n o w h o w t o p r o g r a m u s i n g T u r b o P a s c a l (for D O S ) . T u r b o P a s c a l f o r W i n d o w s u s e s s i m i l a r s y n t a x a n d m a n y o f t h e s a m e f u n c t i o n s a n d p r o c e d u r e s as T u r b o Pascal (for D O S ) . A n y t h i n g specific t o T u r b o Pascal for W i n d o w s is e x p l a i n e d , a n d a n y differences b e t w e e n T u r b o Pascal for W i n d o w s a n d T u r b o Pascal (for D O S ) are d i s c u s s e d . If y o u h a v e n e v e r p r o g r a m m e d i n T u r b o Pascal for W i n d o w s , b u t h a v e p r o g r a m m e d i n a p r o c e d u r a l l a n g u a g e s u c h as C , C + + , o r M o d u l a 2 , y o u p r o b a b l y will m a n a g e t o learn T u r b o Pascal for W i n d o w s p r o g r a m m i n g . T h i s b o o k m a k e s it easier for y o u w i t h a g e n e r a l i n t r o d u c t i o n t o T u r b o Pascal syntax a n d p r o g r a m m i n g . If y o u n e e d m o r e details a b o u t T u r b o Pascal i n g e n e r a l (not W i n d o w s - s p e c i f i c i n f o r m a t i o n ) , p i c k u p a g o o d T u r b o Pascal (for D O S ) b o o k , s u c h as T o m S w a n ' s Mastering Turbo Pascal 6 ( H a y d e n B o o k s ) t o u s e as a g e n e r a l T u r b o Pascal r e f e r e n c e . If y o u are already familiar w i t h t h e T u r b o Pascal for W i n d o w s integrated d e v e l o p m e n t e n v i r o n m e n t ( I D E ) a n d editor, y o u c a n either g l a n c e o v e r o r skip t h e first c h a p t e r . C h a p t e r 1 is primarily i n t e n d e d to familiarize y o u w i t h t h e preliminaries: h o w t o install T u r b o Pascal for W i n d o w s , system r e q u i r e m e n t s , h o w t h e I D E , c o m p i l e r , a n d e d i t o r w o r k , a n d s o o n . T h e "real" p r o g r a m m i n g a n d objecto r i e n t e d discussions start in C h a p t e r 2.
Conventions in This Book T h e s e c o n v e n t i o n s h a v e b e e n u s e d t h r o u g h o u t t h e b o o k t o increase its readability: • All p r o g r a m listings; " s n i p p e t s " o f p r o g r a m c o d e ; k e y w o r d s ; p r o c e d u r e , f u n c t i o n , a n d m e t h o d n a m e s ; types (such as b a s e a n d d e r i v e d ) ; a n d objects ( s u c h a s B a s i c I n t e r f a c e , MainWindow, TWindow, T A p p l i c a t i o n , B a s i c A p p l i c a t i o n ) are in m o n o s p a c e t y p e .
XX
Introduction
• B o o k titles, a l o n g with terms i n c l u d e d i n t h e G l o s s a r y ( o n first o c c u r r e n c e i n the text), a p p e a r i n italics. • U n i t s , p r o g r a m n a m e s , a n d library n a m e s ( O b j e c t W i n d o w s ) a p p e a r i n regular type.
Acknowledgments I'd like t o t h a n k a f e w folks w h o h a v e s u p p o r t e d , advised, offered s u g g e s t i o n s , r e a d t h e m a n u s c r i p t , p r o v i d e d software, o r just p l a i n b e e n h e l p f u l t o m e d u r i n g t h e writing o f Turbo Pascal for Windows Bible: G r e g C r o y a n d Paula N o r t h a m G r a d y at M a c m i l l a n C o m p u t e r P u b l i s h i n g ; N a n B o r e n s o n at B o r l a n d International; Phil Davis at the W h i t e w a t e r G r o u p ; A l i s o n B r o d y ; S u s a n A l l e n ; a n d Billy Ban* at t h e R o c k y M o u n t a i n B i o l o g i c a l Laboratory.
Trademarks S A M S h a s m a d e every attempt t o s u p p l y t r a d e m a r k i n f o r m a t i o n a b o u t c o m p a n y n a m e s , p r o d u c t s , a n d services m e n t i o n e d i n this b o o k . T r a d e m a r k s i n d i c a t e d b e l o w w e r e d e r i v e d from various s o u r c e s . S A M S c a n n o t attest t o t h e accuracy o f this i n f o r m a t i o n . A p p l e a n d M a c i n t o s h are registered trademarks o f A p p l e C o m p u t e r , I n c . B o r l a n d , B o r l a n d C + + , T u r b o D e b u g g e r , a n d T u r b o Pascal are registered trademarks o f B o r l a n d International, I n c . Intel is a registered t r a d e m a r k o f Intel C o r p o r a t i o n . Microsoft C , Microsoft E x c e l , a n d Microsoft W o r d are registered trademarks o f Microsoft C o r p o r a t i o n . W i n d o w s is a t r a d e m a r k o f Microsoft C o r p o r a t i o n . Smalltalk is a t r a d e m a r k o f ParcPlace systems. W h i t e w a t e r R e s o u r c e T o o l k i t is a t r a d e m a r k o f T h e W h i t e w a t e r G r o u p . Z o r t e c h is a t r a d e m a r k o f Z o r t e c h , I n c .
XXI
T u r b o Pascal for W i n d o w s B i b l e
About the Author G a r y E n t s m i n g e r is a writer, p r o g r a m m e r , a n d c o n s u l t a n t . H e w a s a n associate e d i t o r for Micro Cornucopia, (the technical journal) for five years, a n d a c o l u m n i s t for B o r l a n d ' s Turbo Technix m a g a z i n e . H e is t h e a u t h o r o f The Tao of Objects, a b e g i n n e r ' s g u i d e t o o b j e c t - o r i e n t e d p r o g r a m m i n g , a n d his articles h a v e a p p e a r e d in Dr. Dobb's Journal, Computer Language, AI Expert, Midnight Engineering, AI Week, a n d Neural Network News. G a r y lives i n t h e E l k M o u n t a i n s o f C o l o r a d o . Gary Entsminger c/o: R o c k y M o u n t a i n B i o l o g i c a l Laboratory B o x 519 Crested Butte, C O 81224
xxii
PART ONE
WORKING WITH TPW
1 CHAPTER
GETTING STARTED In earlier days, the video display was used solely to echo text that the user typed using the keyboard. In a graphical user interface, the video display itself becomes a source of user input. Charles Petzold
Creating Windows Applications Y o u c a n c r e a t e W i n d o w s a p p l i c a t i o n s u s i n g T u r b o Pascal f o r W i n d o w s i n t h r e e different ways: 1. T h e easiest w a y is t o u s e t h e WinCrt u n i t . T h i s u n i t e n a b l e s y o u t o w r i t e " s t a n d a r d " T u r b o Pascal f o r W i n d o w s a p p l i c a t i o n s that u s e T u r b o Pascal (for D O S ) f u n c t i o n s a n d p r o c e d u r e s , s u c h as Readln a n d Writeln i n a s c r o l l a b l e w i n d o w . T h e WinCrt u n i t a l s o lets y o u transfer y o u r e x i s t i n g T u r b o P a s c a l c o d e t o W i n d o w s w i t h t h e least a m o u n t o f effort. I d e s c r i b e t h e WinCrt u n i t i n m o r e d e t a i l i n C h a p t e r 2 , " E l e ments of Application Development," a n d in the reference section. 2. Y o u a l s o c a n w r i t e W i n d o w s a p p l i c a t i o n s i n t h e m o r e o r less "traditional" way, b y creating y o u r o w n w i n d o w s a n d w i n d o w s classes, a n d s e t t i n g u p y o u r o w n m e s s a g e l o o p . T h i s is t h e w a y " C ' e r s " u s u a l l y d o it, a n d I briefly d e s c r i b e this m e t h o d i n a n e x a m p l e i n C h a p t e r 2 . 3. T h e b e s t w a y t o w r i t e f u l l - f e a t u r e d , e x t e n d a b l e W i n d o w s a p p l i c a t i o n s is to u s e the O b j e c t W i n d o w s application framework (or object library).
4
P a r t i — W o r k i n g with T P W
ObjectWindows uses object-oriented techniques to encapsulate complex Windows behavior a n d make connections between Windows a n d y o u r a p p l i c a t i o n . If y o u u s e O b j e c t W i n d o w s , W i n d o w s a p p l i c a t i o n s a r e b o t h e a s i e r t o w r i t e a n d m o r e efficient. T h r o u g h o u t this b o o k , I u s e a n d describe in detail h o w t o u s e O b j e c t W i n d o w s .
System Requirements and Installation T o r u n T u r b o P a s c a l f o r W i n d o w s , y o u n e e d M i c r o s o f t W i n d o w s , a P C w i t h at least 2 M ( m e g a b y t e s ) o f R A M , a n d a n E G A , V G A , o r H e r c u l e s v i d e o a d a p t e r . Y o u also have t o r u n W i n d o w s in Standard or 386 E n h a n c e d m o d e because T u r b o Pascal f o r W i n d o w s d o e s n o t r u n i n R e a l m o d e . I n a d d i t i o n , if y o u p l a n t o d e b u g in S V G A (Super V i d e o Graphics Adapter) m o d e , y o u must u s e dual monitors. T o install T u r b o Pascal f o r W i n d o w s , u s e t h e Install p r o g r a m o n t h e T u r b o P a s c a l f o r W i n d o w s d i s t r i b u t i o n d i s k s . T h e T u r b o Pascal f o r W i n d o w s s y s t e m a n d e x a m p l e files o n t h e d i s t r i b u t i o n d i s k s a r e a r c h i v e d , s o Install d e - a r c h i v e s t h e m for y o u , puts t h e m in convenient subdirectories, a n d automatically c r e a t e s c o n f i g u r a t i o n files f o r b o t h t h e c o m m a n d - l i n e c o m p i l e r a n d t h e i n t e grated development environment (IDE). T o r u n t h e i n s t a l l a t i o n p r o g r a m f r o m drive A , e n t e r :
C:\ Win A:Install o r , if W i n d o w s is active, select t h e P r o g r a m M a n a g e r ' s
File/Run c o m m a n d
and enter:
A: Install Note: I f y o u a r e a h a n d s - o n k i n d o f p e r s o n , o r h a v e a n o t h e r m o t i v e , y o u c a n u s e U n p a k . e x e t o u n p a c k t h e a r c h i v e d files m a n u a l l y . After y o u h a v e c o m p l e t e d t h e i n s t a l l a t i o n , a d d t h e T u r b o Pascal f o r W i n d o w s d i r e c t o r i e s (for e x a m p l e , C: \TPW; C: \TPW\UTILS) i n t h e D O S p a t h y o u specify in A U T O E X E C . B A T . If y o u d o n o t k n o w h o w t o edit y o u r A U T O E X E C . B A T file, refer t o y o u r D O S m a n u a l s .
The Turbo Pascal for Windows IDE T u r b o Pascal f o r W i n d o w s is a c o m p l e t e d e v e l o p m e n t e n v i r o n m e n t f o r M i c r o soft W i n d o w s . It c o n s i s t s o f a n e d i t o r , c o m p i l e r , l i n k e r , a n d d e b u g g e r i n o n e p a c k a g e . Y o u c a n edit m a n y s o u r c e - c o d e files (as a p r o j e c t ) , c o m p i l e t h e m , a n d l i n k t h e m i n t o a n e x e c u t a b l e a p p l i c a t i o n w i t h o u t l e a v i n g t h e T u r b o Pascal for W i n d o w s e n v i r o n m e n t . F i g u r e 1.1 s h o w s t h e T u r b o Pascal for W i n d o w s startu p screen.
1 — G e t t i n g Started
M o s t o f y o u r v i s u a l activity (what y o u see) o c c u r s i n a T u r b o P a s c a l f o r W i n d o w s E d i t w i n d o w . T u r b o Pascal f o r W i n d o w s lets y o u h a v e as m a n y as 32 w i n d o w s o p e n at a t i m e , p r o v i d e d t h e r e is e n o u g h m e m o r y . O n l y o n e w i n d o w c a n b e active at a t i m e . T h e active w i n d o w is t h e o n e i n w h i c h y o u are w o r k i n g (editing, c o m p i l i n g , a n d so o n ) .
Figure
1.1. The Turbo Pascal for Windows start-up screen.
A n Edit w i n d o w consists o f • A title b a r • The Window Control menu box • Scroll bars • Minimize and Maximize buttons R e f e r t o f i g u r e 1.2 f o r a s a m p l e E d i t w i n d o w . I n a d d i t i o n t o E d i t w i n d o w s , T u r b o Pascal f o r W i n d o w s d i s p l a y s v a r i o u s dialog w i n d o w s in response to user m e n u selections, errors, a n d so o n . A R e p l a c e T e x t d i a l o g b o x , f o r e x a m p l e , a p p e a r s w h e n y o u select S e a r c h / R e p l a c e T e x t f r o m t h e M a i n m e n u , as s h o w n i n f i g u r e 1.3. D i a l o g s ( w h i c h y o u w i l l l e a r n m u c h m o r e a b o u t i n this b o o k ) c a n c o n s i s t o f input b o x e s , c o m m a n d b u t t o n s , a n d so o n . Typically, y o u c h e c k b o x e s , inp u t text, a n d specify o p t i o n s ; t h e n y o u c l i c k a c o m m a n d b u t t o n t o c l o s e t h e dialog box.
5
6
Part I — W o r k i n g w i t h T P W
Figure 1.2. An Edit
window.
Figure 1.3- A Replace Text dialog box.
1 — G e t t i n g Started
Turbo Pascal for Windows IDE Menu Commands T h e T u r b o Pascal f o r W i n d o w s I D E M e n u o p t i o n s are c o m p l e x a n d p o w e r f u l . F o r y o u r c o n v e n i e n c e , t h e m e n u s are s e p a r a t e d i n t o • Desktop control • Edit w i n d o w control •
File
•
Edit
•
Search
•
Run
•
Compile
•
Options
•
Window
• Help menus
The Turbo Pascal for Windows Desktop Control Menu T h e T u r b o Pascal f o r W i n d o w s C o n t r o l M e n u b o x is o n t h e far left s i d e o f t h e title b a r . C l i c k t h e c o n t r o l m e n u b o x o n c e o r p r e s s A l t - S p a c e b a r t o d i s p l a y t h e m e n u . T h e c o m m a n d s g r o u p e d i n this m e n u m a n a g e t h e T u r b o P a s c a l f o r Windows desktop. E a c h E d i t w i n d o w a n d d i a l o g b o x a l s o h a s a (similar) C o n t r o l m e n u . T h e D e s k t o p C o n t r o l m e n u c o m m a n d s are •
Restore
•
Move
•
Size
•
Minimize
•
Maximize
•
Close
• Switch
To
7
8
P a r t i — W o r k i n g with TPW
Restore W h e n y o u select t h e R e s t o r e c o m m a n d f r o m t h e D e s k t o p C o n t r o l m e n u , t h e T u r b o Pascal f o r W i n d o w s d e s k t o p w i n d o w r e t u r n s t o its p r e v i o u s s i z e . Note: Y o u c a n u s e this c o m m a n d o n l y if t h e T u r b o Pascal f o r W i n d o w s d e s k t o p w i n d o w is m a x i m i z e d o r m i n i m i z e d .
Move T h e M o v e c o m m a n d moves the desktop w i n d o w . Use t h e w i n d o w w h e r e y o u w a n t it a n d t h e n p r e s s E n t e r . w i n d o w b y d r a g g i n g its title b a r . T h e title b a r is t h e w i n d o w ; it c o n t a i n s t h e n a m e o f t h e file that is i n t h e Note:
the arrow keys to m o v e Y o u also can m o v e the top horizontal bar of a window.
Y o u c a n n o t u s e this c o m m a n d w h e n t h e d e s k t o p is m a x i m i z e d .
Size Y o u c a n alter t h e size o f t h e d e s k t o p w i n d o w w i t h t h e S i z e c o m m a n d . U s e t h e c u r s o r a r r o w k e y s t o m o v e t h e w i n d o w b o r d e r s . T h e n p r e s s E n t e r w h e n y o u are satisfied w i t h t h e w i n d o w ' s s i z e . Note: S i z e is a n available o p t i o n o n l y w h e n t h e T u r b o Pascal f o r W i n d o w s d e s k t o p is n o t m a x i m i z e d .
Minimize B y s e l e c t i n g t h e M i n i m i z e c o m m a n d , y o u c a n t u r n t h e T u r b o Pascal f o r W i n d o w s d e s k t o p i n t o t h e T P W i c o n . (An i c o n r e p r e s e n t s a w i n d o w i n its m i n i m i z e d state. A p p l i c a t i o n s , s u c h as T P W , c a n h a v e t h e i r o w n u n i q u e i c o n s . ) Note: Y o u c a n select this c o m m a n d o n l y if t h e d e s k t o p w i n d o w h a s n ' t b e e n m i n i m i z e d already.
Maximize If y o u select t h e M a x i m i z e c o m m a n d , t h e d e s k t o p w i n d o w fills t h e e n t i r e screen. Note: Y o u c a n select this c o m m a n d o n l y if t h e T u r b o Pascal for W i n d o w s d e s k t o p w i n d o w has not b e e n m a x i m i z e d already.
Close T h e C l o s e c o m m a n d c l o s e s t h e d e s k t o p a n d t h e n u n l o a d s T u r b o Pascal for W i n d o w s f r o m m e m o r y . T h e c o m m a n d is a c t i v a t e d i n t w o d i f f e r e n t w a y s , d e p e n d i n g o n the current m o d e :
1 — G e t t i n g Started
• I n C U A ( c o m m a n d u s e r a c c e s s ) m o d e , y o u p r e s s Alt-F4 t o c l o s e t h e desktop. • In Alternate m o d e , y o u press Alt-X to close the desktop. Y o u also can click the close b o x in the upper-left corner to close the window. If y o u h a v e m o d i f i e d a n E d i t w i n d o w b u t h a v e n o t s a v e d t h e file, a d i a l o g b o x a p p e a r s s o that y o u c a n verify w h e t h e r y o u w a n t t o save t h e file b e f o r e closing.
Switch To T h e S w i t c h T o c o m m a n d d i s p l a y s t h e T a s k List d i a l o g b o x that y o u c a n u s e t o switch from o n e application to another a n d to rearrange application w i n d o w s .
The Edit Window Control Menu E a c h E d i t w i n d o w h a s a C o n t r o l m e n u w h e n t h e w i n d o w is active. T h e c o m m a n d s o n this m e n u are s i m i l a r t o t h o s e o f t h e T u r b o P a s c a l f o r W i n d o w s Control menu. T h e s e c o m m a n d s are available o n t h e E d i t W i n d o w C o n t r o l m e n u : •
Restore
•
Move
•
Size
•
Minimize
•
Maximize
•
Close
•
Next
Restore T h e R e s t o r e c o m m a n d r e t u r n s t h e Edit w i n d o w t o its d e f a u l t s i z e . If y o u h a v e m i n i m i z e d o r m a x i m i z e d t h e E d i t w i n d o w , u s e R e s t o r e t o r e t u r n it t o its p r e v i o u s ( d e f a u l t ) s i z e . If y o u h a v e n o t m i n i m i z e d o r m a x i m i z e d t h e w i n d o w , t h e R e s t o r e c o m m a n d is d i s a b l e d .
Move U s e the M o v e c o m m a n d to m o v e y o u r Edit w i n d o w with keyboard keys or by d r a g g i n g its title b a r .
9
10
P a r t i — W o r k i n g with T P W
After y o u s e l e c t M o v e , u s e t h e a r r o w k e y s t o m o v e t h e w i n d o w . W h e n y o u ' r e satisfied w i t h t h e w i n d o w ' s n e w p o s i t i o n , p r e s s E n t e r . Note:
Y o u c a n u s e M o v e o n l y w h e n y o u r E d i t w i n d o w isn't m a x i m i z e d .
Size Y o u c a n c h a n g e t h e size o f y o u r E d i t w i n d o w u s i n g t h e k e y b o a r d ; o r , if a w i n d o w h a s a R e s i z e c o r n e r , y o u c a n d r a g t h e c o r n e r t o resize t h e w i n d o w . After s e l e c t i n g S i z e , u s e t h e a r r o w k e y s t o m o v e t h e w i n d o w b o r d e r s . W h e n y o u are satisfied, p r e s s E n t e r . Note: Y o u c a n u s e S i z e o n l y w h e n y o u r E d i t w i n d o w isn't m a x i m i z e d o r minimized.
Minimize Select the M i n i m i z e c o m m a n d to shrink y o u r Edit w i n d o w to an i c o n o n the T u r b o Pascal f o r W i n d o w s d e s k t o p . Note: Y o u c a n select this c o m m a n d o n l y if t h e w i n d o w h a s n o t b e e n m i n i m i z e d already.
Maximize T h e M a x i m i z e c o m m a n d e n l a r g e s t h e E d i t w i n d o w s o that it fills t h e T u r b o Pascal f o r W i n d o w s d e s k t o p . Note: Y o u c a n select this c o m m a n d o n l y w h e n t h e w i n d o w h a s n o t b e e n m a x i m i z e d already.
Close T h e C l o s e c o m m a n d closes the Edit w i n d o w . Y o u also can double-click the C l o s e b o x in the upper-left corner to close a window. If y o u h a v e m o d i f i e d text i n t h e w i n d o w a n d h a v e n o t s a v e d t h e text, a d i a l o g b o x a p p e a r s that g i v e s y o u t h e o p t i o n o f s a v i n g t h e file b e f o r e y o u c l o s e .
Next T h e N e x t c o m m a n d activates t h e n e x t o p e n w i n d o w o r i c o n .
The File Menu T h e File m e n u offers y o u c h o i c e s f o r c r e a t i n g n e w files, o p e n i n g a n d l o a d i n g e x i s t i n g files, s a v i n g files, p r i n t i n g files, a n d e x i t i n g T u r b o P a s c a l f o r W i n d o w s . T h e File m e n u c o m m a n d s i n c l u d e t h e f o l l o w i n g :
1 — G e t t i n g Started
•
New
•
Open
•
Save
• Save As • Save All •
Print
• Printer S e t u p •
Exit
• List o f c l o s e d files
New N e w o p e n s a n e w Edit w i n d o w w i t h t h e d e f a u l t n a m e N O N A M E x x . P A S ( t h e x x s t a n d s f o r a n u m b e r f r o m 00 t o 99), a n d m a k e s t h e n e w Edit w i n d o w active. A N O N A M E file is u s e d as a t e m p o r a r y edit buffer. If y o u try t o save a N O N A M E file, T u r b o Pascal f o r Windows p r o m p t s y o u t o n a m e it b e f o r e it c a n be saved.
Open T h e O p e n c o m m a n d d i s p l a y s t h e File O p e n d i a l o g b o x . I n this d i a l o g b o x , y o u s e l e c t t h e file y o u w a n t t o o p e n , as illustrated in figure 1.4.
Figure
1.4. The File Open dialog
box.
11
12
Part I — W o r k i n g w i t h T P W
N o t e : I n t h e T u r b o Pascal f o r W i n d o w s D e s k t o p , y o u c a n w o r k in either o f t w o edit m o d e s . Y o u specify y o u r c h o i c e o f m o d e s u s i n g t h e O p t i o n s / P r e f e r e n c e s m e n u . T h e t w o m o d e s are C U A , t h e s t a n d a r d W i n d o w s m o d e , a n d A l t e r n a t e , w h i c h is c o m m a n d compatible with other Borland editors.
I n A l t e r n a t e m o d e , p r e s s F 3 t o o p e n a file.
Save T h e S a v e c o m m a n d saves t o a d i s k t h e file i n t h e active E d i t w i n d o w . If t h e file h a s a d e f a u l t n a m e ( s u c h as N O N A M E 0 0 . P A S ) , T u r b o Pascal f o r W i n d o w s o p e n s t h e File S a v e A s d i a l o g b o x s o that y o u c a n r e n a m e t h e file a n d save it i n a different d i r e c t o r y o r o n a d i f f e r e n t d r i v e . If y o u u s e a n e x i s t i n g file n a m e t o n a m e t h e file, T u r b o Pascal f o r W i n d o w s asks w h e t h e r y o u w a n t t o o v e r w r i t e t h e e x i s t i n g file. If y o u w a n t t o save all m o d i f i e d files, n o t just t h e file i n t h e active E d i t w i n d o w , s e l e c t File/Save A l l . I n A l t e r n a t e m o d e , p r e s s F 2 t o save a file.
Save As S a v e A s o p e n s t h e File S a v e A s d i a l o g b o x , w h i c h lets y o u save t h e file i n t h e active Edit w i n d o w u n d e r a different n a m e , in a different directory, or o n a different drive (see figure 1.5). A l l w i n d o w s that c o n t a i n this file are u p d a t e d w i t h t h e n e w n a m e . If y o u select a file n a m e that a l r e a d y e x i s t s , T u r b o P a s c a l f o r W i n d o w s first asks w h e t h e r y o u w a n t t o o v e r w r i t e t h e e x i s t i n g file.
Save All T h i s c o m m a n d saves all t h e files i n o p e n E d i t w i n d o w s .
Print T h e Print c o m m a n d p r i n t s t h e c o n t e n t s o f t h e active E d i t w i n d o w . T u r b o Pascal f o r W i n d o w s e x p a n d s t h e T a b s (that is, it r e p l a c e s a n y T a b c h a r a c t e r s w i t h t h e a p p r o p r i a t e n u m b e r o f s p a c e s ) a n d t h e n p r i n t s t h e file. Note: T h e Print c o m m a n d is d i s a b l e d if t h e active w i n d o w c a n n o t b e p r i n t e d ; f o r e x a m p l e , if n o p r i n t e r is c o n n e c t e d t o y o u r s y s t e m .
1 — G e t t i n g Started
Figure
1.5. The File Save As dialog box.
Printer Setup T h e Printer S e t u p c o m m a n d d i s p l a y s a S e l e c t P r i n t e r d i a l o g b o x , w h i c h lets y o u s e l e c t a p r i n t e r t y p e f o r T u r b o Pascal f o r W i n d o w s (see f i g u r e 1.6).
Figure
1.6. The Select Printer dialog box.
13
14
P a r t i — W o r k i n g with TPW
Note:
If y o u d o n o t w a n t t o alter t h e w a y y o u r p r i n t e r is n o r m a l l y
c o n f i g u r e d , y o u d o n o t h a v e t o u s e Printer S e t u p .
Exit T h e Exit c o m m a n d exits T u r b o Pascal f o r W i n d o w s a n d r e m o v e s it f r o m memory. If y o u h a v e m o d i f i e d a s o u r c e file w i t h o u t s a v i n g it, T u r b o Pascal for W i n d o w s p r o m p t s y o u t o save t h e file b e f o r e e x i t i n g . T h e Exit c o m m a n d is mode-dependent: • I n C U A m o d e , p r e s s Alt-F4 t o exit. • I n A l t e r n a t e m o d e , p r e s s A l t - X t o exit.
list of Closed Files T h i s c o m m a n d lists all t h e files that h a v e b e e n c l o s e d s i n c e s t a r t - u p . S e l e c t a n y c l o s e d file f r o m t h e m e n u t o q u i c k l y r e o p e n it.
The Edit Menu T h e Edit m e n u includes c o m m a n d s to u n d o , r e d o , cut, copy, paste, a n d clear text i n E d i t w i n d o w s . A l s o , y o u c a n o p e n a Clipboard w i n d o w t o v i e w o r edit its c o n t e n t s . T h e E d i t m e n u c o m m a n d s are •
Undo
•
Redo
•
Cut
•
Copy
•
Paste
•
Clear
Undo T h e U n d o c o m m a n d r e s t o r e s t h e m o s t r e c e n t edit o r c u r s o r m o v e m e n t . U n d o inserts a n y c h a r a c t e r s y o u d e l e t e d , d e l e t e s a n y c h a r a c t e r s y o u inserted, replaces any characters y o u overwrote, a n d m o v e s y o u r cursor back to the previous position.
1 — G e t t i n g Started
If y o u u n d o a b l o c k o p e r a t i o n , t h e file r e a p p e a r s as it d i d b e f o r e y o u executed the block operation. If y o u p r e s s U n d o m o r e t h a n o n c e , it c o n t i n u e s t o u n d o c h a n g e s as l o n g as it c a n . H o w e v e r , t h e U n d o c o m m a n d d o e s n o t c h a n g e a n o p t i o n s e t t i n g that affects m o r e t h a n o n e w i n d o w . T h e G r o u p - U n d o o p t i o n in the Options/Preferences dialog b o x specifies U n d o and Redo behavior.
Redo R e d o reverses t h e effect o f t h e m o s t r e c e n t U n d o c o m m a n d . R e d o is effective o n l y i m m e d i a t e l y after a n U n d o o r a n o t h e r R e d o . A series o f R e d o c o m m a n d s reverses t h e effects o f a series o f U n d o commands.
Cut T h e C u t c o m m a n d r e m o v e s t h e s e l e c t e d text f r o m a d o c u m e n t i n t h e E d i t w i n d o w a n d p u t s t h e text i n t h e C l i p b o a r d . Y o u c a n t h e n u s e Edit/Paste t o c o p y t h e text t o a n o t h e r d o c u m e n t o r t o a different place in the current d o c u m e n t . T h e text r e m a i n s s e l e c t e d i n t h e C l i p b o a r d u n t i l y o u r e p l a c e it w i t h o t h e r text, s o y o u c a n p a s t e it m a n y t i m e s , i n as m a n y files as y o u w a n t .
Copy T h e C o p y c o m m a n d d o e s n o t r e m o v e t h e s e l e c t e d text; it l e a v e s t h e text intact a n d p l a c e s a n e x a c t c o p y o f it i n t h e C l i p b o a r d . T o p a s t e t h e c o p i e d text i n t o a n o t h e r d o c u m e n t , select Edit/Paste. Y o u a l s o c a n c o p y text f r o m a H e l p w i n d o w : • U s i n g t h e k e y b o a r d , p r e s s Shift a n d a n a r r o w k e y t o s e l e c t t h e text y o u want to copy. • U s e t h e m o u s e t o c l i c k a n d d r a g t h e text y o u w a n t t o c o p y .
Paste T h e Paste c o m m a n d inserts t h e s e l e c t e d text f r o m t h e C l i p b o a r d i n t o t h e active w i n d o w at t h e c u r r e n t c u r s o r p o s i t i o n .
15
16
P a r t i — W o r k i n g with T P W
Clear T h e C l e a r c o m m a n d removes t h e s e l e c t e d text f r o m t h e d o c u m e n t in t h e active w i n d o w , b u t d o e s n o t m o v e it t o t h e C l i p b o a r d . T h u s , y o u c a n n o t p a s t e " c l e a r e d " text in a d o c u m e n t as y o u c a n w h e n y o u u s e C u t o r C o p y . Note: A l t h o u g h y o u c a n n o t p a s t e t h e c l e a r e d text, y o u c a n u n d o t h e C l e a r c o m m a n d with U n d o . C l e a r is handy f o r d e l e t i n g text w i t h o u t o v e r w r i t i n g t h e c u r r e n t text in the Clipboard.
The Search Menu T h e S e a r c h m e n u includes t h e c o m m a n d s t o s e a r c h f o r text a n d e r r o r l o c a t i o n s in y o u r files. T h e S e a r c h m e n u c o m m a n d s are •
Find
•
Replace
• Search Again • G o to Line N u m b e r • S h o w Last C o m p i l e E r r o r • Find Error
Find T h e F i n d c o m m a n d d i s p l a y s t h e F i n d T e x t d i a l o g b o x , w h i c h lets y o u t y p e in t h e text y o u w a n t t o s e a r c h for. S e v e r a l o p t i o n s in this d i a l o g b o x let y o u specify t h e d e t a i l s o f t h e s e a r c h (see f i g u r e 1.7).
Replace T h e R e p l a c e c o m m a n d d i s p l a y s t h e R e p l a c e T e x t d i a l o g b o x , w h i c h lets y o u t y p e in t h e text y o u w a n t t o s e a r c h f o r a n d t h e text y o u w a n t t o replace it w i t h (see f i g u r e 1.8).
Search Again T h e S e a r c h A g a i n c o m m a n d repeats t h e p r e v i o u s F i n d o r R e p l a c e c o m m a n d . T h e p r e v i o u s s e t t i n g s y o u m a d e in t h e F i n d T e x t o r R e p l a c e T e x t d i a l o g b o x are in effect w h e n y o u c h o o s e S e a r c h A g a i n . In C U A m o d e , press F3 to search again.
1 — G e t t i n g Started
Figure
1.7. The Find Text dialog box.
Figure
1.8. The Replace Text dialog box.
Go to line Number T h e G o to Line N u m b e r c o m m a n d displays the G o to Line N u m b e r dialog b o x , w h i c h p r o m p t s y o u for the line n u m b e r y o u want to find.
17
18
P a r t i — W o r k i n g with T P W
T u r b o Pascal f o r W i n d o w s d i s p l a y s t h e c u r r e n t l i n e n u m b e r a n d c o l u m n n u m b e r i n t h e lower-left c o r n e r o f e v e r y E d i t w i n d o w .
Search/Show Last Compile Error T h e S e a r c h / S h o w Last C o m p i l e E r r o r c o m m a n d l o c a t e s t h e p r e v i o u s c o m p i l e r e r r o r . T h e c u r s o r m o v e s t o t h e l i n e that c a u s e d t h e e r r o r . If t h e e r r o r is n o t i n t h e active w i n d o w , T u r b o Pascal f o r W i n d o w s m a k e s active t h e w i n d o w w i t h t h e p r e v i o u s c o m p i l e r e r r o r , o p e n i n g a c l o s e d file if n e c e s s a r y . T h e e r r o r n u m b e r a n d m e s s a g e t h e n a p p e a r o n t h e status b a r .
Search/Find Error T h e S e a r c h / F i n d E r r o r c o m m a n d b r i n g s u p t h e F i n d E r r o r d i a l o g b o x , w h i c h lets y o u specify t h e a d d r e s s o f t h e m o s t r e c e n t r u n - t i m e e r r o r .
The Run Menu T h e R u n m e n u i n c l u d e s t h e c o m m a n d s f o r r u n n i n g y o u r a p p l i c a t i o n , starting T u r b o D e b u g g e r f o r W i n d o w s , a n d s p e c i f y i n g c o m m a n d - l i n e p a r a m e t e r s . It includes the following c o m m a n d s : •
Run
•
Debugger
•
Parameters
If y o u w a n t t o u s e t h e d e b u g g e r o n a file, c h e c k t h e O p t i o n s / L i n k e r / D e b u g Info in E X E c h e c k b o x before y o u c o m p i l e a n d link y o u r application. T h e D e b u g Info in E X E o p t i o n puts the necessary information in y o u r e x e c u t a b l e file.
Run/Run T h e Run/Run c o m m a n d runs the application, using any parameters y o u pass to it t h r o u g h t h e R u n / P a r a m e t e r s c o m m a n d . If y o u r s o u r c e c o d e h a s b e e n m o d i f i e d s i n c e t h e p r e v i o u s c o m p i l a t i o n , t h e c o m p i l e r automatically "does a m a k e " a n d links y o u r application.
Run/Debugger T h e R u n / D e b u g g e r c o m m a n d starts T u r b o D e b u g g e r f o r W i n d o w s , a n d a l l o w s y o u to d e b u g the application.
1 — G e t t i n g Started
T u r b o Pascal f o r Windows tells T u r b o D e b u g g e r f o r Windows which application to debug. C h e c k t h e O p t i o n s / L i n k e r / D e b u g I n f o in t h e E X E c h e c k b o x b e f o r e y o u c o m p i l e a n d l i n k y o u r a p p l i c a t i o n if y o u w a n t t o u s e T u r b o D e b u g g e r t o d e b u g it. T h e O p t i o n s / L i n k e r / D e b u g I n f o in E X E c h e c k b o x p u t s t h e necessary d e b u g information in t h e e x e c u t a b l e file. T o get the m o s t from T u r b o D e b u g g e r ' s symbolic d e b u g g i n g capabilities, y o u also should check the Options/Compiler/Debug Information b o x a n d the Options/Compiler/Local Symbols b o x before compiling your application.
Run/Parameters T h e Run/Parameters c o m m a n d p a s s e s p a r a m e t e r s t o y o u r a p p l i c a t i o n p r o g r a m w h e n y o u run it as t h o u g h y o u w e r e running t h e a p p l i c a t i o n f r o m t h e P r o g r a m M a n a g e r ' s File/Run m e n u . When y o u select this c o m m a n d , t h e Parameters d i a l o g b o x a p p e a r s . Y o u r j o b is t o specify t h e c o m m a n d - l i n e a r g u m e n t s (see figure 1.9).
Figure
1.9. The Parameters dialog box.
The Compile Menu Y o u use the c o m m a n d s o n the C o m p i l e m e n u to compile, m a k e , or build y o u r application program.
19
20
P a r t i — W o r k i n g with T P W
T o u s e t h e Compile c o m m a n d , y o u m u s t have a file o p e n in a n active w i n d o w . T o u s e Make a n d Build, y o u m u s t have a primary file d e f i n e d . S e l e c t from these c o m m a n d s : •
Compile
•
Make
•
Build
• Primary File • C l e a r Primary File •
Information
Compile/Compile T h e C o m p i l e / C o m p i l e c o m m a n d c o m p i l e s t h e file in t h e active Edit w i n d o w . A C o m p i l e S t a t u s information b o x displays t h e c o m p i l a t i o n progress a n d results. If a n error o c c u r r e d , t h e status b a r d i s p l a y s t h e error l i n e a n d highlights t h e error. C l i c k y o u r m o u s e o r p r e s s a k e y t o clear t h e m e s s a g e s o that y o u c a n correct t h e error.
Compile/Make T h e Compile/Make c o m m a n d creates a . E X E file a c c o r d i n g t o t h e s e
rules:
• I f a primary file has b e e n n a m e d in t h e Primary File d i a l o g b o x , that file is c o m p i l e d . O t h e r w i s e , t h e file in t h e active Edit w i n d o w is c o m p i l e d . T u r b o Pascal f o r Windows c h e c k s all files affecting t h e c o m p i l e d file's p e r f o r m a n c e t o verify that t h e y exist a n d that t h e y are c u r r e n t . • I f t h e s o u r c e file f o r a u n i t has b e e n m o d i f i e d s i n c e t h e . T P U ( o b j e c t c o d e ) file w a s c r e a t e d , t h e m o d i f i e d u n i t is recompiled. • I f t h e interface
f o r a u n i t has c h a n g e d , a n y u n i t that d e p e n d s o n it is
recompiled. • I f a u n i t links in a . O B J file ( e x t e r n a l routines), a n d t h e . O B J file is n e w e r t h a n t h e u n i t ' s . T P U file, t h e u n i t is recompiled. • I f a u n i t c o n t a i n s a n I n c l u d e file a n d t h e I n c l u d e file is n e w e r t h a n that u n i t ' s . T P U file, t h e u n i t is
recompiled.
• I f t h e s o u r c e t o a u n i t ( . T P U file) c a n n o t b e l o c a t e d , t h e u n i t is n o t compiled. T h i s o p t i o n is identical t o C o m p i l e / B u i l d , e x c e p t it is c o n d i t i o n a l . B u i l d rebuilds all files, w h e t h e r o r n o t t h e y are c u r r e n t .
1 — G e t t i n g Started
Compile/Build T h e C o m p i l e / B u i l d c o m m a n d rebuilds all t h e c o m p o n e n t s o f y o u r a p p l i c a t i o n , w h e t h e r o r n o t t h e y are c u r r e n t . T h i s o p t i o n is identical t o C o m p i l e / M a k e , e x c e p t it is u n c o n d i t i o n a l . M a k e rebuilds o n l y t h o s e files that are n o t c u r r e n t . T h e C o m p i l e / B u i l d c o m m a n d recompiles all t h e files included in t h e primary file. If y o u abort a C o m p i l e / B u i l d c o m m a n d b y p r e s s i n g C t r l - B r e a k o r receive errors that t e r m i n a t e t h e b u i l d , y o u c a n restart t h e b u i l d w h e r e it w a s terminated by selecting Compile/Make.
Compfle/Primary File T h e C o m p i l e / P r i m a r y File c o m m a n d d i s p l a y s t h e Primary File d i a l o g b o x , w h i c h lets y o u specify w h i c h .PAS file w i l l b e c o m p i l e d w h e n y o u c h o o s e C o m p i l e / M a k e or C o m p i l e / B u i l d . U s e C o m p i l e / P r i m a r y File w h e n y o u are w o r k i n g o n a n a p p l i c a t i o n that u s e s several u n i t ( . T P U ) o r I n c l u d e files. R e g a r d l e s s o f t h e file y o u are e d i t i n g , C o m p i l e / M a k e a n d C o m p i l e / B u i l d always o p e r a t e o n y o u r primary file. If y o u specify a n o t h e r file as a primary file, b u t w a n t t o c o m p i l e o n l y t h e file in t h e active Edit w i n d o w , c h o o s e C o m p i l e .
Compile/Clear Primary File T h e C o m p i l e / C l e a r Primary File c o m m a n d removes t h e n a m e o f t h e primary file y o u s p e c i f i e d w i t h t h e C o m p i l e / P r i m a r y File c o m m a n d . If a primary file has n o t b e e n s p e c i f i e d , however, t h e c o m m a n d is d i s a b l e d .
Compile/Information T h e Compile/Information c o m m a n d displays t h e C o m p i l e Information b o x , t h e n a m e o f y o u r primary file (if y o u are u s i n g o n e ) , a n d t h e n a m e o f t h e p r e v i o u s file c o m p i l e d .
Compile Information Box T h e C o m p i l e I n f o r m a t i o n b o x lists: • T h e n a m e o f t h e primary file (if y o u are u s i n g o n e ) • T h e n a m e o f t h e p r e v i o u s file c o m p i l e d • T h e source compiled • C o d e size • D a t a size
21
22
P a r t i — W o r k i n g with TPW
• S t a c k size • L o c a l h e a p size
The Options Menu T h e O p t i o n s m e n u contains c o m m a n d s for viewing a n d c h a n g i n g various d e f a u l t settings in T u r b o Pascal f o r Windows. M o s t o f t h e c o m m a n d s in this m e n u initiate a d i a l o g b o x . T h e c o m m a n d s are •
Compiler
•
Linker
•
Directories
•
Preferences
•
Open
•
Save
• Save As
Compiler T h e O p t i o n s / C o m p i l e r c o m m a n d displays t h e C o m p i l e r O p t i o n s d i a l o g b o x , w h i c h lets y o u select t h e o p t i o n s that d e t e r m i n e howyour c o d e is c o m p i l e d (see figure 1.10).
Figure
1.10. The Compiler
Options dialog
box.
1 — G e t t i n g Started
Linker T h e Options/Linker c o m m a n d displays the Linker O p t i o n s dialog b o x , w h i c h lets y o u select t h e o p t i o n s that d e t e r m i n e h o w y o u r a p p l i c a t i o n files are l i n k e d , as s h o w n i n figure 1.11.
Figure
1.11. The Linker Options dialog
box.
Map File o p t i o n s T h e M a p File o p t i o n s (Off, S e g m e n t s , P u b l i c s , a n d D e t a i l e d ) d e t e r m i n e t h e t y p e o f m a p file p r o d u c e d . Link Buffer File o p t i o n s T h e L i n k B u f f e r File o p t i o n s ( M e m o r y o r D i s k ) specify t h e l o c a t i o n o f t h e l i n k buffer. D e b u g Info in E X E o p t i o n T h e D e b u g I n f o in E X E o p t i o n p u t s d e b u g information
in y o u r p r o g r a m ' s
e x e c u t a b l e file.
Directories T h e D i r e c t o r i e s c o m m a n d o p e n s t h e D i r e c t o r i e s d i a l o g b o x , w h e r e y o u specify t h e directories y o u w a n t T u r b o Pascal for Windows t o u s e w h e n running and s t o r i n g y o u r a p p l i c a t i o n p r o g r a m s , as illustrated in figure 1.12.
23
24
Part I — W o r k i n g w i t h T P W
Figure
1.12. The Directories
dialog
box.
W i t h t h e o p t i o n s i n this d i a l o g b o x , y o u d e c i d e w h e r e T u r b o Pascal f o r W i n d o w s f i n d s t h e files it n e e d s t o c o m p i l e , l i n k , a n d o u t p u t e x e c u t a b l e files. T h e E X E a n d T P U D i r e c t o r y i n p u t b o x s p e c i f i e s t h e d i r e c t o r y that s t o r e s y o u r . E X E a n d . T P U ( o b j e c t c o d e ) files. T h e I n c l u d e D i r e c t o r i e s i n p u t b o x s p e c i f i e s t h e d i r e c t o r i e s that c o n t a i n y o u r s t a n d a r d I n c l u d e files. T h e U n i t D i r e c t o r i e s i n p u t b o x s p e c i f i e s t h e d i r e c t o r i e s that c o n t a i n y o u r T u r b o Pascal f o r W i n d o w s u n i t files. T h e O b j e c t D i r e c t o r i e s i n p u t b o x s p e c i f i e s t h e d i r e c t o r i e s that c o n t a i n y o u r . O B J files ( a s s e m b l y l a n g u a g e r o u t i n e s ) . T h e Resource Directories input b o x specifies the directories in w h i c h y o u r r e s o u r c e files are k e p t .
Guidelines for Entering Directory Names Use the following guidelines w h e n y o u enter directories in the Options/ Directories input boxes: • Separate m u l t i p l e directory p a t h n a m e s (if a l l o w e d ) w i t h a s e m i c o l o n (;). • U s e a m a x i m u m o f 127 c h a r a c t e r s ( i n c l u d i n g w h i t e s p a c e ) . W h i t e s p a c e b e f o r e a n d after t h e s e m i c o l o n is a l l o w e d b u t n o t r e q u i r e d . • Relative a n d a b s o l u t e p a t h n a m e s are a l l o w e d , i n c l u d i n g p a t h n a m e s relative t o t h e l o g g e d p o s i t i o n i n drives o t h e r t h a n t h e c u r r e n t o n e .
1 — G e t t i n g Started
For example:
C:\ ; D:\TPW D:\;C:\TPW;D:\TPW
Preferences T h e Options/Preferences m e n u c o m m a n d o p e n s the Preferences dialog box, w h i c h lets y o u d e c i d e t h e b e h a v i o r a n d p h y s i c a l a p p e a r a n c e o f t h e T u r b o Pascal for W i n d o w s e n v i r o n m e n t (see figure 1.13).
Figure
1.13. The Preferences
dialog
box.
Editor Options T h e E d i t o r O p t i o n s g r o u p h a s several c h e c k b o x e s that c o n t r o l text h a n d l i n g i n Edit w i n d o w s . T h e y are • C r e a t e B a c k u p File • Auto Indent M o d e • Use Tab Character • O p t i m a l Fill • Backspace Unindents
25
26
Part I — W o r k i n g w i t h T P W
• Cursor through Tabs • Group Undo • Block Overwrite T h e A u t o S a v e o p t i o n s d e f i n e w h e n a n d h o w o f t e n T u r b o Pascal f o r W i n d o w s saves y o u r o p e n files, s e t t i n g s , a n d o p t i o n s . T h e y are • E d i t o r Files •
Desktop
•
Configuration
W h e n y o u select a n e w f o n t d i s p l a y e d i n t h e list b o x , t h e F o n t list b o x c h a n g e s t h e size a n d a p p e a r a n c e o f t h e text. T h e T a b Size input b o x controls the n u m b e r o f c o l u m n s the cursor m o v e s for each tab stop. T h e Right M o u s e B u t t o n o p t i o n s (Nothing a n d T o p i c Search) d e t e r m i n e w h e t h e r T u r b o Pascal f o r W i n d o w s u s e s t h e right b u t t o n t o initiate a t o p i c search in H e l p . T h e C o m m a n d Set o p t i o n s ( C U A o r A l t e r n a t e ) d e t e r m i n e w h e t h e r t h e editor uses C o m m o n User Access (CUA) c o m m a n d s or Alternate c o m m a n d s .
Open T h e O p t i o n s / O p e n c o m m a n d d i s p l a y s t h e O p e n C o n f i g u r a t i o n File d i a l o g b o x , w h e r e y o u c a n retrieve n e w c o n f i g u r a t i o n - f i l e s e t t i n g s . T h e File N a m e i n p u t b o x lets y o u e n t e r t h e n a m e o f t h e c o n f i g u r a t i o n file c o n t a i n i n g t h e s e t t i n g s y o u w a n t ; y o u c h o o s e O K o r p r e s s E n t e r t o l o a d that file. T h e d e f a u l t c o n f i g u r a t i o n file n a m e is T P W . C F G . T h e Files list b o x lists t h e n a m e s o f files i n t h e c u r r e n t d i r e c t o r y that m a t c h the file-name mask in the File-Name input b o x . T h e D i r e c t o r i e s list b o x lets y o u select a d i f f e r e n t d i r e c t o r y t o v i e w . Press A l t - D t o p l a c e t h e c u r s o r i n this list b o x .
Save T h e O p t i o n s / S a v e c o m m a n d saves i n t h e c u r r e n t c o n f i g u r a t i o n file t h e p r i m a r y file n a m e , t h e s e t t i n g s y o u s e l e c t e d w i t h t h e O p t i o n s m e n u , a n d t h e d e s k t o p setup. U s e O p t i o n s / S a v e A s t o save o p t i o n s t o a d i f f e r e n t c o n f i g u r a t i o n file. T h e n a m e o f t h e c u r r e n t c o n f i g u r a t i o n file a p p e a r s n e x t t o t h e O p t i o n s / S a v e command. • A l l o p t i o n s a n d t h e e d i t o r c o m m a n d t a b l e are s t o r e d i n T P W . C F G , t h e d e f a u l t s a v e d - o p t i o n s file.
1 — G e t t i n g Started
• H i s t o r y lists, t h e d e s k t o p state, a n d b r e a k p o i n t l o c a t i o n s are s t o r e d in TPW.INI.
Save As T h e Options/Save As c o m m a n d o p e n s t h e Configuration Save As dialog b o x , w h e r e y o u e n t e r a n e w n a m e f o r y o u r c o n f i g u r a t i o n file (see figure 1.14).
Figure
1.14. The Configuration
Save As dialog
box.
Y o u c a n c r e a t e a n e w c o n f i g u r a t i o n file b y s e t t i n g o p t i o n s a n d t h e n s e l e c t i n g O p t i o n s / S a v e A s a n d e n t e r i n g a n e w c o n f i g u r a t i o n file n a m e . T h e n e w l y c r e a t e d c o n f i g u r a t i o n file is n o w i n effect. I n t h e File N a m e i n p u t b o x , e n t e r a n e w n a m e f o r t h e c o n f i g u r a t i o n file. C h o o s e O K o r p r e s s E n t e r t o c r e a t e a . C F G file w i t h t h e n e w n a m e . If y o u d o n o t specify a file e x t e n s i o n , T u r b o Pascal f o r W i n d o w s a d d s a . C F G extension for y o u . For example:
YOUR becomes YOUR.CFG. A h i s t o r y list is a t t a c h e d t o t h e File N a m e i n p u t b o x . If t h e C o n f i g u r a t i o n o p t i o n is o n , s e t t i n g s m a d e t o t h e c u r r e n t c o n f i g u r a t i o n file are s a v e d w h e n y o u exit.
27
28
P a r t i — W o r k i n g with T P W
Directories List Box U s e t h e D i r e c t o r i e s list b o x t o c h a n g e t o a n o t h e r directory. Press A l t - D t o p l a c e t h e c u r s o r in t h e D i r e c t o r i e s list b o x .
The Window Menu T h e Window m e n u has c o m m a n d s f o r m a n i p u l a t i n g a n d o p e n i n g w i n d o w s . M o s t o f t h e w i n d o w s y o u o p e n f r o m this m e n u have t h e s t a n d a r d w i n d o w e l e m e n t s s u c h as scroll b a r s , M i n i m i z e a n d M a x i m i z e b u t t o n s , a n d a C o n t r o l menu box. O p e n w i n d o w s with the File/Open or File/New c o m m a n d s . At t h e b o t t o m o f t h e Window m e n u is a list o f o p e n w i n d o w s . If m o r e t h a n o n e w i n d o w is o p e n , y o u c a n s w i t c h t o a n o t h e r w i n d o w a n d m a k e it active b y s e l e c t i n g it f r o m t h e list. T h e s e are t h e Window •
Tile
•
Cascade
menu commands:
• Arrange Icons • Close All
Tile C h o o s e Window/Tile
t o tile y o u r o p e n w i n d o w s . U s i n g this c o m m a n d a r r a n g e s
t h e w i n d o w s s o that t h e y c o v e r t h e entire d e s k t o p w i t h o u t o v e r l a p p i n g o n e another.
Cascade C h o o s e Window/Cascade
t o stack all o p e n Edit w i n d o w s . C a s c a d e o v e r l a p s
o p e n w i n d o w s s o that e a c h w i n d o w is t h e s a m e size, b u t part o f e a c h u n d e r l y i n g w i n d o w is visible.
Arrange Icons S e l e c t Window/Arrange I c o n s t o rearrange t h e icons. R e a r r a n g e d icons are e v e n l y s p a c e d , b e g i n n i n g at t h e lower-left c o r n e r o n t h e d e s k t o p . T h e o p e n files m u s t b e M i n i m i z e d o r this c o m m a n d is d i s a b l e d .
1 — G e t t i n g Started
Close All C h o o s e Window/Close A l l t o c l o s e all o p e n w i n d o w s o n t h e d e s k t o p . If t h e text w a s c h a n g e d s i n c e t h e p r e v i o u s t i m e y o u s a v e d it, a d i a l o g b o x w a r n s y o u t o save t h e file b e f o r e c l o s i n g t h e w i n d o w . C h o o s e Y e s , N o , o r C a n c e l .
The Help Menu (Alt-H) T h e H e l p m e n u p r o v i d e s a c c e s s t o o n - l i n e H e l p , w h i c h a p p e a r s in a s p e c i a l H e l p w i n d o w . T h e H e l p s y s t e m p r o v i d e s information about most aspects o f the integrated e n v i r o n m e n t a n d T u r b o P a s c a l for Windows. T h e f o l l o w i n g list shows the Help m e n u commands: •
Index
• Topic Search • Using Help • C o m p i l e r Directives •
ObjectWindows
• Procedures and Functions • Reserved
Words
• Standard Units • T u r b o P a s c a l for Windows • Windows
Language
API
• A b o u t T u r b o Pascal for
Windows
Index (Shift-Fl) T u r b o P a s c a l for Windows' o n - l i n e H e l p c o m e s w i t h a c o m p r e h e n s i v e index that s u m m a r i z e s t h e o r g a n i z a t i o n a n d c o n t e n t s o f t h e H e l p s y s t e m . T o g e t into t h e H e l p s y s t e m f r o m t h e index, select o n e o f t h e highlighted words or phrases in t h e index, click it o r T a b t o it, a n d t h e n p r e s s Enter. If y o u d o n ' t k n o w how t o u s e a H e l p s y s t e m u n d e r Windows, Help/Using H e l p M e n u c o m m a n d .
choose the
Topic Search (Ctrl-Fl) If y o u p l a c e y o u r c u r s o r o n a w o r d (a " t o k e n " ) in t h e active Edit w i n d o w a n d c h o o s e H e l p / T o p i c S e a r c h , a H e l p w i n d o w o p e n s w i t h information a b o u t that token.
29
30
P a r t i — W o r k i n g with T P W
Y o u c a n set u p t h e R i g h t m o u s e b u t t o n (in t h e O p t i o n s / P r e f e r e n c e s d i a l o g b o x ) t o initiate a t o p i c s e a r c h . H e l p p r o v i d e s o n - l i n e r e f e r e n c e f o r m a n y e l e m e n t s o f t h e T u r b o Pascal f o r W i n d o w s language, including functions a n d procedures, reserved w o r d s , global variables, O b j e c t W i n d o w s , the W i n d o w s API, a n d so o n .
Help/Using Help T h e Help/Using H e l p c o m m a n d displays information o n h o w to use T u r b o P a s c a l f o r W i n d o w s ' H e l p s y s t e m (or a n y o t h e r H e l p s y s t e m u n d e r W i n d o w s ) .
Compiler Directives W h e n y o u c h o o s e this m e n u c o m m a n d , y o u s e e a n i n d e x o f c o m p i l e r d i r e c t i v e s . C o m p i l e r d i r e c t i v e s c o n t r o l s o m e o f T u r b o Pascal f o r W i n d o w s ' f e a t u r e s . • S o m e t u r n c o m p i l e r f e a t u r e s o n o r off. • S o m e specify p a r a m e t e r s that affect h o w y o u r a p p l i c a t i o n p r o g r a m is compiled. • Others control the conditional compilation of your application. A c o m p i l e r d i r e c t i v e is a c o m m e n t w i t h a s p e c i a l s y n t a x that y o u c a n p u t a n y w h e r e a c o m m e n t is a l l o w e d .
ObjectWindows W h e n y o u select this m e n u c o m m a n d , y o u s e e a h i e r a r c h y o f O b j e c t W i n d o w s types.
Procedures and Functions W h e n y o u c h o o s e this m e n u c o m m a n d , y o u s e e a n i n d e x o f t h e T u r b o Pascal f o r W i n d o w s library p r o c e d u r e s a n d f u n c t i o n s that y o u c a n u s e t o d e v e l o p applications.
Reserved Words W h e n y o u select this m e n u c o m m a n d , y o u s e e a n i n d e x o f all t h e r e s e r v e d w o r d s i n t h e T u r b o Pascal f o r W i n d o w s l a n g u a g e . R e s e r v e d w o r d s h a v e s p e c i a l m e a n i n g to the compiler. D o not use a reserved w o r d to n a m e y o u r variables, procedures, functions, objects, and so o n .
1 — G e t t i n g Started
Standard Units W h e n y o u s e l e c t this m e n u c o m m a n d , y o u s e e a n i n d e x o f T u r b o P a s c a l f o r W i n d o w s ' s t a n d a r d u n i t s . A s t a n d a r d u n i t is a c o l l e c t i o n o f p r e d e f i n e d c o n s t a n t s , d a t a t y p e s , v a r i a b l e s , p r o c e d u r e s , a n d f u n c t i o n s . Y o u tell y o u r a p p l i c a t i o n p r o g r a m t o u s e o n l y t h e u n i t s it n e e d s .
Turbo Pascal for Windows Language W h e n y o u select this m e n u c o m m a n d , y o u s e e a list o f t h e e l e m e n t s that c o m p r i s e t h e T u r b o Pascal f o r W i n d o w s l a n g u a g e .
Windows API W h e n y o u select this m e n u c o m m a n d , y o u s e e a n i n d e x o f t h e c o n s t a n t s , styles, m e s s a g e s , t y p e s , f u n c t i o n s , a n d p r o c e d u r e s that c o m p r i s e t h e W i n d o w s A p p l i c a t i o n P r o g r a m m i n g I n t e r f a c e (API). T u r b o Pascal f o r W i n d o w s d e c l a r e s all t h e W i n d o w s styles, c o n s t a n t s , a n d t y p e s i n t h e WinTypes u n i t . T h e WinProcs u n i t h a s all t h e A P I p r o c e d u r e s a n d f u n c t i o n s .
About Turbo Pascal for Windows W h e n y o u select this c o m m a n d , a d i a l o g b o x a p p e a r s w i t h c o p y r i g h t a n d version information. Press E s c o r c l i c k O K o r C a n c e l t o c l o s e t h e b o x .
Editor T h e T u r b o Pascal f o r W i n d o w s e d i t o r is a c o m p l e t e p r o g r a m m i n g e d i t o r . I n a l m o s t all c a s e s , y o u u s e it t o d e v e l o p all facets o f y o u r a p p l i c a t i o n s . I n a d d i t i o n t o b e i n g a f u l l - s c r e e n , c o m m a n d - r i c h e d i t o r , it is b a s e d o n W i n d o w s ' m u l t i d o c u m e n t i n t e r f a c e , w h i c h y o u l e a r n h o w t o u s e i n C h a p t e r 7, " M a n y W i n d o w s : A M u l t i - D o c u m e n t I n t e r f a c e . " T h e m u l t i - d o c u m e n t i n t e r f a c e e n a b l e s m a n y files t o b e o p e n s i m u l t a n e o u s l y . T h u s , y o u c a n o p e n files f o r several u n i t s a n d s w i t c h b e t w e e n t h e m easily w i t h o u t c l o s i n g a n y f i l e s — a g r e a t f e a t u r e w h e n y o u d e v e l o p large projects.
The Editor Commands T u r b o Pascal for W i n d o w s ' editor c o m m a n d s are s u m m a r i z e d in t h e following groups of commands:
31
32
Part I — W o r k i n g w i t h T P W
• Block commands • B l o c k c o m m a n d s ( C U A a n d Alternate) • B l o c k c o m m a n d s ( B o r l a n d style) • Extending selected blocks • Other commands • Cursor-movement commands • Insert a n d D e l e t e c o m m a n d s • More about editor c o m m a n d s • Miscellaneous keyboard commands
The Block Commands T h e following sections describe the block c o m m a n d s .
Copy Block This c o m m a n d copies a previously selected block to the Clipboard a n d pastes it t o t h e c u r r e n t c u r s o r p o s i t i o n . T h e o r i g i n a l b l o c k is u n c h a n g e d . If n o b l o c k is s e l e c t e d , n o t h i n g h a p p e n s .
Copy Text T h i s c o m m a n d c o p i e s s e l e c t e d text t o t h e C l i p b o a r d . Press C t r l - I n s t o u s e t h e command.
Cut Text T h i s c o m m a n d s c u t s s e l e c t e d text t o t h e C l i p b o a r d . Press S h i f t - D e l t o u s e t h e command.
Delete Block This c o m m a n d deletes a selected block. Y o u can "undelete" a block with U n d o . Press C t r l - D e l o r C t r l - K Y t o u s e this c o m m a n d .
Move Block T h i s c o m m a n d m o v e s a p r e v i o u s l y s e l e c t e d b l o c k f r o m its o r i g i n a l t h e C l i p b o a r d a n d t h e n p a s t e s it t o t h e c u r s o r p o s i t i o n . T h e b l o c k f r o m its o r i g i n a l p o s i t i o n . If n o b l o c k is m a r k e d , n o t h i n g h a p p e n s . D e l t o m o v e text t o C l i p b o a r d a n d Shift-Ins t o p a s t e text i n c u r r e n t
position to disappears Press Shiftdocument.
1 — G e t t i n g Started
PastefromClipboard T h i s c o m m a n d p a s t e s t h e c o n t e n t s o f t h e C l i p b o a r d t o c u r s o r l o c a t i o n . Press Shift-Ins t o u s e t h e c o m m a n d .
Read BlockfromDisk T h i s c o m m a n d reads a d i s k file into t h e c u r r e n t text at t h e c u r s o r p o s i t i o n e x a c t l y as t h o u g h it w a s a b l o c k . Press Shift-Ctrl-R o r C t r l - K R t o u s e this command. T h e text read is t h e n s e l e c t e d as a b l o c k . When this c o m m a n d is initiated, y o u are p r o m p t e d f o r t h e n a m e o f t h e file t o read. Y o u c a n u s e w i l d c a r d s t o select a file t o read, a n d a d i r e c t o r y is d i s p l a y e d . T h e file s p e c i f i e d c a n b e a n y l e g a l file n a m e .
WWte Block to Disk T h i s c o m m a n d w r i t e s a s e l e c t e d b l o c k t o a file. Press Shift-Ctrl-W o r C t r l - K W t o u s e this c o m m a n d . When y o u s p e c i f y t h i s c o m m a n d , T u r b o Pascal f o r Windows p r o m p t s y o u f o r t h e n a m e o f t h e file t o w r i t e t o . T h e file c a n b e g i v e n a n y l e g a l n a m e ( t h e d e f a u l t e x t e n s i o n is . P A S ) . If y o u p r e f e r t o u s e a file n a m e w i t h o u t a n e x t e n s i o n , a p p e n d a p e r i o d t o t h e e n d o f its n a m e . Note: If t h e file s p e c i f i e d a l r e a d y e x i s t s , a w a r n i n g is issued b e f o r e t h e e x i s t i n g file is o v e r w r i t t e n . If n o b l o c k is s e l e c t e d , n o t h i n g happens.
Editor-Command Tables T h e t a b l e s t h r o u g h o u t this s e c t i o n list t h e e d i t o r c o m m a n d s a n d t h e i r f u n c t i o n or meaning. Table
1.1.
The Block
Movement
commands
(CUA and
CUA
Alternate).
Both
Delete block
Ctrl-Del
Ctrl-Del
C o p y to Clipboard
Ctrl-Ins
Ctrl-Ins
Cut to Clipboard
Shift-Del
Shift-Del
Paste f r o m C l i p b o a r d
Shift-Ins
Shift-Ins
Alternate
Read block from disk
Shift-Ctrl-R
Ctrl-KR
Write b l o c k t o d i s k
Shift-Ctrl-W
Ctrl-KW
Indent block
Shift-Ctrl-I
Ctrl-KI
Unindent block
Shift-Ctrl-U
Ctrl-KU
33
34
P a r t i — W o r k i n g with TPW
Table
1.2.
The Block
commands
(Borland
style).
Command
Keys
Function
Text selection O n
Ctrl-KB
B e g i n s t h e s e l e c t i o n o f text; text s e l e c t i o n e n d s w i t h c o p y i n g (Ctrl-KK) o r c u t t i n g (Ctrl-KV) t o t h e C l i p b o a r d , o r t u r n i n g text s e l e c t i o n o f f w i t h Ctrl-KH
Text selection Off
Ctrl-KH
S t o p s t h e s e l e c t i o n o f text, a n d t h e s e l e c t e d text b e c o m e s unselected
C o p y text t o C l i p b o a r d
Ctrl-KK
C o p i e s t h e s e l e c t e d text t o t h e Clipboard
C u t text t o C l i p b o a r d
Ctrl-KV
C u t s t h e s e l e c t e d text t o t h e Clipboard
Paste f r o m C l i p b o a r d
Ctrl-KC
Pastes t h e c o n t e n t s o f t h e C l i p b o a r d i n t o y o u r active E d i t window
Extending
selected
blocks
Movement
CUA
Both
Left 1 character
Shift-Left
Shift-Left
Right 1 character
Shift-Right
Shift-Right
E n d o f line
Shift-End
Shift-End
Beginning of line
Shift-Home
Shift-Home
Same column, n e x t line
Shift-Down
Shift-Down
Same column,
Shift-Up
Shift-Up
O n e page down
Shift-PgDn
Shift-PgDn
O n e page u p
Shift-PgUp
Shift-PgUp
Left o n e w o r d
Shift-Ctrl-Left
Shift-Ctrl-Left
Right o n e w o r d
Shift-Ctrl-Right
Shift-Ctrl-Right
End of
Shift-Ctrl-End
Shift-Ctrl-End
Shift-Ctrl-PgDn
Shift-Ctrl-Home
Shift-Ctrl-Home
Shift-Ctrl-PgUp
Alternate
p r e v i o u s line
file
Beginning of
file
1 — G e t t i n g Started
N o t e : T u r b o Pascal for Windows' Borland-style block c o m m a n d s w o r k o n l y w i t h t h e A l t e r n a t e c o m m a n d set.
Table
1.3- Commands
that extend
selected
blocks.
Movement
CUA
Both
Alternate
Left 1 c h a r a c t e r
Shift-Left
Shift-Left
Right 1 character
Shift-Right
Shift-Right
E n d o f line
Shift-End
Shift-End
Beginning o f line
Shift-Home
Shift-Home
Same column, next line
Shift-Down
Shift-Down
Same column,
Shift-Up
Shift-Up
O n e page down
Shift-PgDn
Shift-PgDn
O n e page u p
Shift-PgUp
Shift-PgUp
previous line
Left o n e w o r d
Shift-Ctrl-Left
Shift-Ctrl-Left
Right o n e w o r d
Shift-Ctrl-Right
Shift-Ctrl-Right
E n d o f file
Shift-Ctrl-End
Shift-Ctrl-End
Shift-Ctrl-PgDn
B e g i n n i n g o f file
Shift-Ctrl-Home
Shift-Ctrl-Home
Shift-Ctrl-PgUp
Table
1.4. The cursor-movement
Movement
commands
CUA
(CUA and
Alternate).
Both
Alternate
C h a r a c t e r left
Left
Left
Ctrl-S
C h a r a c t e r right
Ctrl-Right
Right
Ctrl-D
W o r d left
Ctrl-Left
Ctrl-Left
Ctrl-A
Scroll d o w n 1 line
Ctrl-Z
Ctrl-Z
Ctrl-Z
Line u p
Up
Up
Ctrl-E
Line d o w n
Down
Down
Ctrl-X
Scroll u p 1 line
Ctrl-W
Ctrl-W
Ctrl-W
Scroll d o w n 1 line
Ctrl-Z
Ctrl-Z
Ctrl-Z
Page u p
PgUp
PgUp
Ctrl-R continues
35
36
P a r t i — W o r k i n g with TPW
Table
1.4.
continued
Movement
CUA
Both
Alternate
Page d o w n
PgDn
PgDn
Ctrl-C
Last c u r s o r p o s i t i o n
Ctrl-QP
Beginning of line
Home
Home End
Ctrl-QS
E n d of line
End
Top of window
Ctrl-E
Ctrl-QE
Bottom of window
Ctrl-X
Ctrl-QX
T o p o f file
Ctrl-Home
Ctrl-Home
Ctrl-QR, Ctrl-PgUp
B o t t o m o f file
Ctrl-End
Ctrl-End
Ctrl-QC, Ctrl-PgDn
Table
1.5-
The Insert
and Delete
commands
Ctrl-QD
(CUA and
Movement
CUA
Both
Delete char
Del
Ctrl-G
D e l e t e c h a r t o left
Backspace
Backspace
Delete line
Ctrl-Y
Ctrl-Y
Delete line e n d
Shift-Ctrl-Y
Alternate). Alternate
Ctrl-QY
Delete word
Ctrl-T
Insert l i n e
Ctrl-N
Insert m o d e O n / O f f
Ins
Ctrl-N Ins
Ctrl-V
Auto Indent This c o m m a n d toggles the automatic indenting o f successive lines. Y o u also can use Options/Preferences/Autolndent in the I D E to turn automatic indenting o n a n d off.
Current Compiler Options I n s e r t s t h e c u r r e n t c o m p i l e r - o p t i o n s e t t i n g s at t h e h e a d o f y o u r active E d i t window.
Cursor through Tabs T h e a r r o w k e y s m o v e t h e c u r s o r t o t h e m i d d l e o f tabs w h e n this o p t i o n is o n ; o t h e r w i s e t h e c u r s o r w o u l d j u m p several c o l u m n s w h e n it m o v e s o v e r m u l t i p l e t a b s . C t r l - O R is a t o g g l e .
1 — G e t t i n g Started
Find Place Marker T h i s c o m m a n d finds a m a x i m u m o f t e n p l a c e m a r k e r s ( N c a n b e a n y n u m b e r i n t h e r a n g e z e r o t o n i n e ) i n text. M o v e t h e c u r s o r t o a n y p r e v i o u s l y set m a r k e r b y pressing Ctrl-Q and the marker number.
Open File O p e n s a n e x i s t i n g file i n a n E d i t w i n d o w .
Optimal Fill O p t i m a l Fill b e g i n s every l i n e w i t h t h e m i n i m u m n u m b e r o f c h a r a c t e r s p o s s i b l e , u s i n g T a b s a n d s p a c e s as n e c e s s a r y . T h i s o p t i o n p r o d u c e s l i n e s w i t h f e w e r characters.
Save File T h i s c o m m a n d saves t h e file a n d r e t u r n s t o t h e e d i t o r .
Set Place T h i s c o m m a n d m a r k s a m a x i m u m o f t e n p l a c e s i n text w h e n y o u p r e s s C t r l - K , f o l l o w e d b y a s i n g l e - m a r k e r digit ( z e r o t o n i n e ) . After m a r k i n g y o u r l o c a t i o n , y o u c a n w o r k e l s e w h e r e i n t h e file a n d t h e n r e t u r n t o a m a r k e d l o c a t i o n b y u s i n g the Find Place Marker c o m m a n d (be sure to use the same marker n u m b e r ) . Y o u c a n h a v e as m a n y as t e n p l a c e s m a r k e d i n e a c h w i n d o w .
Show last Compile Error T h i s c o m m a n d h i g h l i g h t s t h e last s y n t a x e r r o r that t h e c o m p i l e r f o u n d d u r i n g t h e p r e v i o u s c o m p i l e . T h e e r r o r m e s s a g e a p p e a r s o n t h e status b a r . If y o u h a v e a l r e a d y c l o s e d that file, T u r b o P a s c a l f o r W i n d o w s r e o p e n s it a n d h i g h l i g h t s t h e error.
Tab Mode Y o u c a n specify t h e u s e o f t r u e T a b c h a r a c t e r s i n t h e I D E w i t h t h e O p t i o n s / Preferences/Use T a b Character o p t i o n .
Unindent Y o u can turn U n i n d e n t o n a n d off from the I D E with the Options/Preferences/ Backspace Unindents option.
37
38
P a r t i — W o r k i n g with T P W
Table
1.6. Miscellaneous
Movement
keyboard CUA
commands. Both
Alternate
A u t o i n d e n t on/off
Ctrl-OI
Compiler options
Ctrl-OO
Cursor through Tabs
Ctrl-OR
on/off Find place marker N
Ctrl-N*
Ctrl-Q-N*
Help
Fl
Fl
Help index
Shift-Fl
Shift-Fl
Maximize window
F5
Open
F3
file
O p t i m a l fill m o d e
Ctrl-OF
on/off Pair m a t c h i n g
Alt-[, Alt-]
Ctrl-Q
[, C t r l - Q ]
S a v e file
F2, Ctrl-KJ
Search
Ctrl-QF
Search again
F3
F3
Search and replace
Ctrl-QA
S h o w last c o m p i l e
Ctrl-QW
error Set m a r k e r
Shift-Ctrl-N*
Ctrl-K-N*
T a b s m o d e on/off
Ctrl-OT
Topic Help
Ctrl-Fl
Exit
Alt-F4
Undo
Alt-Backspace
Unindent mode on/off Insert c o n t r o l character
Ctrl-Fl Alt-X Alt-Backspace Ctrl-OU
Ctrl-P * *
Ctrl-P * *
* TV indicates a number from zero to nine. * To enter a control character, first enter Ctrl-P, and then enter the control
r
character.
The TPW Command-line Compiler T h e T u r b o Pascal f o r W i n d o w s c o m m a n d - l i n e c o m p i l e r ( T P C W . E X E ) lets y o u i n v o k e all t h e f u n c t i o n s o f t h e I D E c o m p i l e r ( T P W . E X E ) f r o m t h e D O S c o m m a n d line.
1 — G e t t i n g Started
TPCW
T u r b o Pascal f o r W i n d o w s c o m m a n d - l i n e o p t i o n s u s e this s y n t a x : [options] < f i l e name> [options]
where [ o p t i o n s ] can be o n e or m o r e options, separated by spaces. Y o u d e s i g n a t e t h e status o f t h e c o m p i l e r o p t i o n b y s p e c i f y i n g a p l u s ( + ) o r a m i n u s (-) after t h e o p t i o n . • P l a c e a + (or a s p a c e ) after a n o p t i o n t o t u r n it O n . • P l a c e a - after t h e o p t i o n t o t u r n it Off.
Table Option
1.7. Compiler
options.
Meaning Directive
/$A
Align data
/$B
Boolean evaluation
/$D
Debug
options
information
/$F
F o r c e F A R calls
/$G
Generate 286
/$!
Input/Output checking
/$L
Local Symbol
instructions
information
/$N
80x87 C o d e (numeric coprocessor)
/$R
Range checking
/$S
Stack-overflow checking
/$V
String variable c h e c k i n g
/$W
Windows
/$X
E x t e n d e d syntax
/B
B u i l d all
/F
Find error
/L
Link buffer
stack f r a m e
Mode
options
/M
Make
/Q
Quiet (no I D E equivalent)
/D
Conditional defines
Conditional
defines
option
continues
39
40
P a r t i — W o r k i n g with T P W
Table
1.7.
Option
continued Meaning Debug
options
/G
. M A P file
/V
D e b u g information in E X E o p t i o n Directory
options
/E
E X E a n d T P U directory
/I
Include directories
/O
O b j e c t Files d i r e c t o r i e s
/R
Resource directories
/T
T u r b o directory
/U
Unit directories
Most of the command-line options have equivalent m e n u c o m m a n d s . Table
1.8.
Command-line
options
and
their IDE
equivalents.
Option
IDE
Equivalent
/$A
Options/Compiler/Align data
/$B
Options/Compiler/Boolean evaluation
/$D
Options/Compiler/Debug information
/$¥
O p t i o n s / C o m p i l e r / F o r c e far calls
/$G
Options/Compiler/286 code
/$!
Options/Compiler/I/O checking
/$L
Options/Compiler/local symbols
/$M
O p t i o n s / C o m p i l e r / M e m o r y sizes
/$N
Options/Compiler/80x87 code
/$R
Options/Compiler/Range checking
/$S
Options/Compiler/Stack checking
/$V
Options/Compiler/String Variable C h e c k i n g O p t i o n s
/$W
Options/Compiler/Windows Stack Frames
/$X
Options/Compiler/Extended Syntax
/B
Compile/Build
1 — G e t t i n g Started
Option
IDE
Equivalent
ID
Options/Compiler/Conditional Defines
IE
Options/Directories/EXE and T P U Directory
/F
Search/Find Error
/G
O p t i o n s / L i n k e r / M a p File
/I
Options/Compiler/lnclude Directories
IL
Options/Linker/Link Buffer
/M
Compile/Make
/O
Options/Directories/Object Directories
/Q
(none)
/R
Options/Directories/Resource Directories
IT
(none)
/U
Options/Directories/Unit Directories
/V
Options/Linker/Debug Information in E X E
Onward, Forward, and Upward T u r b o Pascal f o r W i n d o w s is a f l e x i b l e , p o w e r f u l a p p l i c a t i o n d e v e l o p m e n t e n v i r o n m e n t for M i c r o s o f t W i n d o w s , c o m p l e t e w i t h e d i t o r , c o m p i l e r , d e b u g g e r , l i n k e r , a n d a p o w e r f u l library o f o b j e c t s a n d t o o l s . Y o u d o n ' t h a v e t o b e a W i n d o w s o r T u r b o P a s c a l e x p e r t t o u s e T u r b o Pascal for W i n d o w s ; i n s t e a d it helps y o u b e c o m e the W i n d o w s expert. A T u r b o Pascal for W i n d o w s a p p l i c a t i o n is l i m i t e d o n l y b y y o u r i m a g i n a t i o n . Y o u c a n u s e u n i t s a n d libraries t o c r e a t e l a r g e a n d p o w e r f u l W i n d o w s applications using either the I D E or the command-line compiler. I n t h e n e x t f e w h u n d r e d p a g e s , I'll s h o w y o u just h o w e a s y a n d f u n it c a n b e t o c r e a t e W i n d o w s a p p l i c a t i o n s T u r b o Pascal style, u s i n g t h e p o w e r a n d flexibility o f o b j e c t - o r i e n t e d p r o g r a m m i n g t e c h n i q u e s . S o u n d easy? It is. I n t h e n e x t c h a p t e r , y o u w i l l g o t o it!
41
2 CHAPTER
ELEMENTS OF APPLICATION DEVELOPMENT Your Windows program doesn't interact directly with the screen, keyboard, printer, or any other device. Windows does all that, and places the results in an application message queue (in a device-independent fashion). Lee and Mark Atkinson If y o u h a v e p r o g r a m m e d i n a n y l a n g u a g e , y o u u n d o u b t e d l y h a v e y o u r o w n i d e a s a b o u t h o w t o d e v e l o p a n a p p l i c a t i o n , w h e t h e r it is f o r W i n d o w s o r o t h e r w i s e . T o develop an application for W i n d o w s , y o u have to learn h o w W i n d o w s works, b u t o n l y at a n easy l e v e l . Y o u a l s o h a v e t o p r e p a r e y o u r a p p l i c a t i o n t o r u n i n a W i n d o w s w i n d o w a n d y o u h a v e t o t h i n k (at least s o m e w h a t ) i n t e r m s o f e v e n t s . T h e b e a n s a n d rice o f a W i n d o w s a p p l i c a t i o n is w h a t y o u are u s e d t o : c o d e f o r s o l v i n g p r o b l e m s — c o d e that m a n i p u l a t e s i n f o r m a t i o n (or d a t a ) . T h e biggest difference b e t w e e n developing a D O S application and a W i n d o w s a p p l i c a t i o n is that, w i t h D O S , y o u are r e q u i r e d t o c r e a t e y o u r o w n u s e r i n t e r f a c e ( u n l e s s y o u are w r i t i n g a p r i m i t i v e a p p l i c a t i o n o r o n e that d o e s n o t r e q u i r e a n i n t e r f a c e ) . If y o u are w r i t i n g a W i n d o w s a p p l i c a t i o n , y o u m u s t "connect" to the W i n d o w s G U I (graphical user interface), but y o u d o not have t o c r e a t e it. Y o u u s e t h e W i n d o w s I n t e r f a c e , a n d y o u c o n t i n u e t o u s e m o s t o f what y o u already k n o w about p r o g r a m m i n g .
44
Part I — W o r k i n g w i t h T P W
T o use a W i n d o w s application to solve a p r o b l e m , y o u have to 1. I n t e r a c t w i t h W i n d o w s ( m o s t l y u s i n g O b j e c t W i n d o w s ) . 2. G e t i n f o r m a t i o n i n t o t h e a p p l i c a t i o n (the i n p u t c o m p o n e n t ) . 3. S t o r e i n f o r m a t i o n (the d a t a c o m p o n e n t ) . 4. M a n i p u l a t e t h e i n f o r m a t i o n , u s i n g p r o c e d u r e s , f u n c t i o n s , o r o b j e c t m e t h o d s (the o p e r a t i o n s c o m p o n e n t ) . 5. G e t t h e r e s u l t s (the o u t p u t c o m p o n e n t ) . T h e s e s t e p s are s t r a i g h t f o r w a r d a n d p r o b a b l y familiar t o y o u , e x c e p t f o r the W i n d o w s connection. T o connect with W i n d o w s , use ObjectWindows, the T u r b o P a s c a l for W i n d o w s O O P library. O b j e c t W i n d o w s is a n o b j e c t - o r i e n t e d library, p a c k a g e d w i t h T u r b o Pascal for W i n d o w s , that greatly s i m p l i f i e s W i n d o w s applications development by encapsulating (packaging) c o m p l e x W i n d o w s i n f o r m a t i o n i n a s i m p l e r , m o r e easily a c c e s s i b l e f o r m . T o h a n d l e a c t i o n s 2 t h r o u g h 5, y o u s t r u c t u r e y o u r a p p l i c a t i o n a l o n g traditional "structured" p r o g r a m m i n g lines. Y o u use conditional statements ( I t s ) and l o o p s ( w h i l e s , r e p e a t s , and so o n ) . Y o u divide groups o f instructions i n t o s e c t i o n s that c a n b e r e f e r e n c e d b y n a m e ( p r o c e d u r e s , f u n c t i o n s , o b j e c t s ) . T h i s a g a i n is p r o g r a m m i n g as y o u p r o b a b l y a l r e a d y k n o w it ( w h e t h e r y o u p r o g r a m i n Pascal o r a n o t h e r similarly s t r u c t u r e d l a n g u a g e s u c h as C o r C + + ) . T u r b o Pascal for W i n d o w s , like T u r b o P a s c a l for D O S , s u p p l i e s a r i c h set o f d a t a t y p e s a n d b u i l t - i n o p e r a t o r s , c o n t r o l s , p r o c e d u r e s , a n d f u n c t i o n s for m a n i p u l a t i n g i n f o r m a t i o n . T u r b o Pascal for W i n d o w s lets y o u c r e a t e l a r g e a p p l i c a t i o n s b y d i v i d i n g a n y p r o g r a m (or a p p l i c a t i o n ) i n t o p i e c e s (units) that c a n b e c o m p i l e d separately. T h e r e m a i n d e r o f this c h a p t e r briefly c o v e r s s o m e o f t h e b a s i c a s p e c t s o f T u r b o Pascal for W i n d o w s a n d its d e v e l o p m e n t c a p a b i l i t i e s . If y o u a l r e a d y k n o w T u r b o P a s c a l , f e e l free t o s k i p this s e c t i o n a n d m o v e o n t o t h e n e x t c h a p t e r , w h e r e y o u learn h o w to develop W i n d o w s applications using the objectoriented techniques of O b j e c t W i n d o w s . (You will not see any Windows-specific c o d e u n t i l t h e n e x t c h a p t e r . ) If y o u w a n t m o r e i n f o r m a t i o n a b o u t t h e s t a n d a r d (or built-in) T u r b o Pascal for W i n d o w s p r o c e d u r e s a n d f u n c t i o n s , c h e c k o u t t h e reference section.
Units T o d e v e l o p a n y T u r b o Pascal for W i n d o w s a p p l i c a t i o n , y o u m u s t u s e at least o n e T u r b o Pascal for W i n d o w s s t a n d a r d u n i t , b u t y o u c a n u s e m a n y m o r e u n i t s if y o u h a v e t o (either s t a n d a r d o n e s o r u n i t s y o u c r e a t e ) . A unit is a c o l l e c t i o n o f c o n s t a n t s , d a t a t y p e s , v a r i a b l e s , p r o c e d u r e s , a n d f u n c t i o n s . I n a n u t s h e l l , a u n i t is t h e basis o f m o d u l a r p r o g r a m m i n g i n T u r b o Pascal for D O S a n d T u r b o Pascal for W i n d o w s . Y o u u s e u n i t s t o c r e a t e libraries a n d to divide large applications into logically related m o d u l e s .
2—Elements of Application Development
T u r b o Pascal for W i n d o w s supplies t h e following standard units: Strings System
WinCrt WinDOS WinProcs WinTypes T h e s e standard units (which are stored in TPW.TPL) support y o u r T u r b o Pascal for W i n d o w s applications in m a n y ways, taking m u c h o f the w o r k o u t o f developing applications. T h e Strings unit s u p p o r t s a type o f character strings called nullterminated strings. N u l l - t e r m i n a t e d strings a r e t h e t y p e o f strings r e q u i r e d b y t h e W i n d o w s A p p l i c a t i o n P r o g r a m m i n g I n t e r f a c e (API). (Previously, T u r b o P a s c a l d i d n o t s u p p o r t n u l l - t e r m i n a t e d strings.) T h e S y s t e m u n i t ( S Y S T E M . T P U ) is t h e T u r b o P a s c a l f o r W i n d o w s r u n - t i m e library. It i m p l e m e n t s l o w - l e v e l , r u n - t i m e s u p p o r t r o u t i n e s ( p r o c e d u r e s a n d f u n c t i o n s ) f o r all t h e b u i l t - i n T u r b o P a s c a l f o r W i n d o w s " f e a t u r e s , " s u c h as file I n p u t / O u t p u t , floating p o i n t o p e r a t i o n s , s t r i n g - h a n d l i n g , a n d d y n a m i c m e m o r y allocation. All units a n d programs automatically u s e the System unit, so y o u d o not h a v e t o s p e c i f y it i n a uses d e c l a r a t i o n . ( Y o u l e a r n m o r e a b o u t t h e uses d e c l a r a t i o n i n this s e c t i o n ) . T h e WinCrt u n i t i m p l e m e n t s a t e r m i n a l - l i k e text s c r e e n i n a w i n d o w . Y o u d o n o t h a v e t o w r i t e " W i n d o w s - s p e c i f i c " c o d e if y o u r a p p l i c a t i o n u s e s WinCrt. I n m a n y c a s e s , y o u c a n start w i t h T u r b o P a s c a l f o r W i n d o w s q u i c k l y b y t r a n s l a t i n g e x i s t i n g T u r b o P a s c a l (for D O S ) c o d e a n d u s i n g t h e WinCrt s c r e e n t o " r u n " it. Y o u w i l l l e a r n h o w t o u s e WinCrt i n t h e n e x t c h a p t e r . T h e WinDos u n i t i m p l e m e n t s o p e r a t i n g s y s t e m a n d file-handling p r o c e dures a n d functions. T h e s e p r o c e d u r e s a n d functions are specific t o T u r b o Pascal a n d are n o t d e f i n e d b y standard Pascal. T h e WinProcs u n i t d e f i n e s f u n c t i o n a n d p r o c e d u r e h e a d e r s f o r t h e W i n d o w s A P I . Y o u c a n a c c e s s e v e r y f u n c t i o n i n t h e s t a n d a r d W i n d o w s libraries t h r o u g h WinProcs. T h e WinProcs a n d WinTypes u n i t s b o t h d e f i n e t h e T u r b o Pascal for W i n d o w s i m p l e m e n t a t i o n o f t h e W i n d o w s API. T h e WinTypes u n i t d e f i n e s T u r b o P a s c a l v e r s i o n s o f all t h e t y p e s u s e d b y the W i n d o w s API functions, including simple types a n d data structures (records, a n d s o o n ) a n d all t h e s t a n d a r d W i n d o w s c o n s t a n t s , i n c l u d i n g flags, m e s s a g e s , a n d styles. Units are b o t h conceptually a n d pragmatically important because • T h e y are p r e c o m p i l e d s o y o u c a n u s e the functions, p r o c e d u r e s , a n d so o n in a unit without recompiling the unit each time y o u compile a n o t h e r part o f y o u r a p p l i c a t i o n . T h u s , u n i t s save t i m e .
45
46
Part I—Working with T P W
• U n i t s a l s o let y o u b r e a k u p f u n c t i o n a l i t y for s e p a r a t e d e v e l o p m e n t , modification, a n d u s e . Projects thus c a n b e large a n d their d e v e l o p ment a n d m a n a g e m e n t simplified. U n i t s are nifty, u s e f u l s t r u c t u r e s that c h a n g e t h e w a y y o u r T u r b o Pascal f o r W i n d o w s a p p l i c a t i o n c o d e is s t o r e d i n m e m o r y . C o n s i d e r first h o w a c o m p i l e d T u r b o Pascal for W i n d o w s a p p l i c a t i o n ( w i t h o u t u n i t s ) s t o r e s itself i n m e m o r y . It d i v i d e s itself i n t o f o u r m a i n s e c t i o n s : 1. C o d e s e g m e n t 2. D a t a s e g m e n t 3. S t a c k s e g m e n t 4.
Heap
The code segment contains the application's procedures, functions, a n d the main program body of the application. T h e d a t a segment contains the a p p l i c a t i o n ' s g l o b a l variables a n d c o n s t a n t s . T h e s t a c k s e g m e n t c o n t a i n s r e t u r n a d d r e s s e s for t h e a p p l i c a t i o n s ' f u n c t i o n s a n d p r o c e d u r e s a n d m o s t o f t h e l o c a l variables d e c l a r e d i n s i d e f u n c t i o n s a n d p r o c e d u r e s . T h e heap c o n t a i n s a n y variables y o u c r e a t e d y n a m i c a l l y u s i n g t h e T u r b o Pascal for W i n d o w s k e y w o r d , New. E a c h s e c t i o n ( c o d e , d a t a , a n d s t a c k s e g m e n t s ) c a n u s e as m u c h as 6 4 K (kilobytes) o f m e m o r y , a n d t h e h e a p c a n g r o w as l a r g e as available m e m o r y a l l o w s . F i g u r e 2.1 s h o w s a m e m o r y m a p o f this s c h e m e .
Memory Map W i t h o u t units
High Memory
Heap
?K
Stack Segment
64K
Data Segment
64K
Code Segment
64K
Low Memory
Figure
2.1. A memory map of three segments, plus the heap.
2—Elements of Application Development
Without u n i t s , a c o m p i l e d T u r b o P a s c a l f o r Windows application can be a b o u t 1 9 2 K p l u s t h e h e a p ( w h o s e size d e p e n d s o n t h e n u m b e r o f d y n a m i c a l l y allocated variables). In c o n t r a s t , t h e p r o c e d u r e s a n d f u n c t i o n s i n a u n i t are s t o r e d i n s e p a r a t e s e g m e n t s apart f r o m t h e m a i n m o d u l e . E a c h u n i t c a n u s e as m u c h as 6 4 K o f m e m o r y . T h u s , a n a p p l i c a t i o n that u s e s u n i t s c a n c o n s i s t o f as m a n y o f t h e s e 6 4 K u n i t s as m e m o r y (the s y s t e m ' s , n o t y o u r s ) a l l o w s . O f c o u r s e , a p p l i c a t i o n s that u s e u n i t s c a n b e l a r g e . F i g u r e 2.2 s h o w s a m e m o r y m a p o f a n a p p l i c a t i o n segmented into units.
Memory Map
High memory
Heap
?K
Stack Segment
64K
Data Segment
64K
Unit
64K
Unit
64K
Code Segment
with units
64K
Low memory
Figure 2.2. A memory map of units.
T o u s e a s t a n d a r d ( o r p r e c o m p i l e d ) unit, a d d a u s e s d e c l a r a t i o n at the b e g i n n i n g o f the m a i n m o d u l e o f y o u r a p p l i c a t i o n : Program
Main;
uses WinCrt; {
....
body h e r e
...
}
T o use m o r e than o n e unit, separate the units by c o m m a s : Program
Main;
uses WinTypes, Strings,
47
48
Parti—Working with T P W
WinProcs, WObjects; { ... body here ... } Y o u u s e t h e s t a n d a r d T u r b o P a s c a l for W i n d o w s u n i t s t h r o u g h o u t this b o o k , a n d t h e y a r e d i s c u s s e d i n m o r e d e t a i l as y o u m o v e a l o n g . C r e a t i n g y o u r o w n u n i t s is s i m i l a r t o c r e a t i n g t h e main m o d u l e o f a n application, with a couple of exceptions: 1. R a t h e r t h a n d e s i g n a t e t h e m o d u l e as a p r o g r a m , y o u d e s i g n a t e it as a unit:
Unit YourUnit; 2. Y o u also divide the unit into parts: Unit heading I n t e r f a c e part I m p l e m e n t a t i o n part I n i t i a l i z a t i o n part T h e unit h e a d i n g specifies t h e unit's n a m e (the n a m e y o u u s e w h e n y o u refer t o this u n i t i n a n o t h e r m o d u l e ' s Uses d e c l a r a t i o n ) . T h e i n t e r f a c e part d e c l a r e s c o n s t a n t s , t y p e s , v a r i a b l e s , p r o c e d u r e s , a n d f u n c t i o n s that a r e p u b l i c (available t o a n y m o d u l e that u s e s t h e u n i t ) . List t h e p r o c e d u r e s a n d f u n c t i o n s as h e a d i n g s o n l y i n t h e i n t e r f a c e part. T h e i m p l e m e n t a t i o n part d e f i n e s t h e b o d i e s o f all p u b l i c p r o c e d u r e s a n d f u n c t i o n s . I n a d d i t i o n , it d e c l a r e s c o n s t a n t s , t y p e s , v a r i a b l e s , p r o c e d u r e s , a n d f u n c t i o n s that a r e p r i v a t e a n d , t h u s , a r e n o t available t o u s e r s o f t h e u n i t . T h e i n i t i a l i z a t i o n part is t h e last part o f a u n i t . It c o n s i s t s o f e i t h e r : • T h e r e s e r v e d w o r d end ( n o i n i t i a l i z a t i o n c o d e ) or • A s t a t e m e n t part t o b e e x e c u t e d t o initialize t h e u n i t L i s t i n g 2.1 s h o w s t h e l a y o u t o f a u n i t . Listing
2.1. The general
Unit YourUnit; Interface { Use something here }
layout
of a
unit.
2 — E l e m e n t s o f Application D e v e l o p m e n t
{ CONST, TYPE, VAR declarations here } { PROCEDURE and FUNCTION declarations here } Implementation { Another Use here, if you want it } { Any Private LABEL, CONST, TYPE, VAR declarations here } { Procedure and function bodies here } Begin { Initialization statements } End.
49
50
Part I — W o r k i n g w i t h T P W
T u r b o P a s c a l f o r W i n d o w s h a n d l e s u n i t s i n t e l l i g e n t l y . F o r e x a m p l e , if several m o d u l e s (or u n i t s ) i n a n a p p l i c a t i o n refer t o t h e s a m e u n i t , o n l y o n e c o p y o f that u n i t — n o t s e v e r a l — i s l o a d e d i n t o m e m o r y .
Data Types and Identifiers Application d e v e l o p m e n t begins a n d e n d s with variables. W h e n e v e r d e c l a r e a v a r i a b l e , y o u m u s t specify its t y p e . T h e v a r i a b l e t y p e i n d i c a t e s
you
• T h e range o f values the variable can take • T h e o p e r a t i o n s that c a n b e p e r f o r m e d o n it W h e n y o u s p e c i f y a t y p e (in a t y p e d e c l a r a t i o n ) y o u specify a n i d e n t i f i e r that d e n o t e s a t y p e . Y o u u s e identifiers t h r o u g h o u t y o u r a p p l i c a t i o n , a n d a T u r b o Pascal f o r W i n d o w s identifier c a n d e n o t e any o f the following: •
Constants
• Fields in records •
Functions
•
Labels
•
Procedures
•
Programs
•
Types
•
Units
•
Variables
I d e n t i f i e r s c a n b e a n y l e n g t h , b u t o n l y t h e first 6 3 c h a r a c t e r s are significant ( r e c o g n i z e d b y T u r b o Pascal for W i n d o w s ) . Y o u have to f o l l o w a f e w rules w h e n y o u u s e identifiers: • T h e first c h a r a c t e r o f a n i d e n t i f i e r m u s t b e a letter. • T h e c h a r a c t e r s that f o l l o w t h e first c h a r a c t e r m u s t b e letters, d i g i t s , o r underscores (no spaces). • I d e n t i f i e r s are n o t c a s e - s e n s i t i v e . A s this c h a p t e r states, a p p l i c a t i o n s d e v e l o p m e n t b e g i n s a n d e n d s w i t h v a r i a b l e s . V a r i a b l e s m u s t b e t y p e d i n T u r b o P a s c a l . It is h e l p f u l t o d i v i d e t h e s e t y p e s i n t o six m a j o r c l a s s e s , w h i c h are c o v e r e d n e x t . F o r m o r e i n - d e p t h i n f o r m a t i o n a b o u t T u r b o Pascal for W i n d o w s t y p e s , c o n s u l t t h e T u r b o P a s c a l for Windows manuals.
2—Elements of Application Development
Qualified Identifiers W h e n your application declares several instances of the same identifier, you might have to qualify the identifier by specifying a unit identifier to select the correct instance of the identifier. The combined Unit. Identifier specification is called a identifier.
qualified
For example, the following are qualified identifiers: System. Exit
(unit = System, identifier = Exit)
Dos. Exec (unit = Dos, identifier = Exec ) Crt .Window
( unit = Crt, identifier = Window)
Y o u c a n d i v i d e t y p e s as f o l l o w s : 1. S i m p l e t y p e s that d e f i n e o r d e r e d sets o f v a l u e s : A. Ordinal types, which
include:
Integer types B o o l e a n types C h a r type E n u m e r a t e d types Subrange types B. Real types 2. String t y p e s that represent a s e q u e n c e o f characters w i t h a d y n a m i c l e n g t h attribute a n d a c o n s t a n t size attribute. 3. S t r u c t u r e d t y p e s that hold m o r e t h a n o n e v a l u e . T h e s e
include:
Array t y p e s Record types O b j e c t types Set types File t y p e s 4. P o i n t e r t y p e s that d e f i n e a set o f v a l u e s that p o i n t t o d y n a m i c variables o f s o m e t y p e . A d y n a m i c variable is o n e that is a l l o c a t e d o n t h e heap a n d m a n i p u l a t e d u s i n g p o i n t e r s . B e c a u s e t h e heap c a n b e q u i t e large ( m u c h larger t h a n a s t a c k a l l o c a t e d in t h e d a t a s e g m e n t , w h i c h is l i m i t e d t o 6 4 K ) , d y n a m i c variables a l s o c a n b e q u i t e l a r g e . 5. P r o c e d u r a l t y p e s that a l l o w p r o c e d u r e s a n d f u n c t i o n s t o b e t r e a t e d as o b j e c t s . A n o b j e c t , w h i c h y o u l e a r n m u c h m o r e a b o u t t h r o u g h o u t this
51
52
Part I — W o r k i n g w i t h T P W
b o o k , c o n s i s t s o f d a t a a n d t h e p r o c e d u r e s a n d f u n c t i o n s that y o u u s e t o m a n i p u l a t e that d a t a . F o r e x a m p l e :
AWindow = object x1, x2, y1, y2 :Integer; procedure minimize; procedure maximize; end; 6. O b j e c t t y p e s are s t r u c t u r e s that c o n s i s t o f a f i x e d n u m b e r o f c o m ponents.
Ordinal Types T u r b o Pascal h a s n i n e p r e d e f i n e d o r d i n a l t y p e s . Five o f t h e s e i n t e g e r t y p e s d e n o t e a specific subset o f the w h o l e n u m b e r s : Type
Range
Size
Shortint
1 2 8 . . 127
8-bit
Integer
-32768.32767
16-bit
Longint
-2147483648. .2147483647
32-bit
Byte
0.255
8-bit
Word
0.65535
16-bit
T h e o t h e r f o u r p r e d e f i n e d o r d i n a l t y p e s are t h e B o o l e a n s WordBool, LongBool), and Char.
(Boolean,
T w o o t h e r classes o f u s e r - d e f i n e d o r d i n a l t y p e s are e n u m e r a t e d t y p e s a n d subrange types. T h r e e s t a n d a r d f u n c t i o n s c a n b e u s e d w i t h all o r d i n a l t y p e s : 1. Ord ( w h i c h r e t u r n s t h e o r d i n a l i t y o f t h e v a l u e ) . F o r e x a m p l e : Ord(False)
= 0;
2. P r e d ( w h i c h r e t u r n s t h e p r e d e c e s s o r o f t h e v a l u e ) . F o r e x a m p l e : Pred(True)
=
False;
3. S u c c ( w h i c h r e t u r n s t h e s u c c e s s o r o f t h e v a l u e ) . F o r e x a m p l e : Succ(True)
=
False;
Boolean Types T u r b o Pascal for W i n d o w s has three p r e d e f i n e d B o o l e a n types: B o o l e a n , W o r d B o o l , a n d L o n g B o o l , w h i c h are d e f i n e d as f o l l o w s :
2—Elements of Application Development
type Boolean = (False, True); WordBool = (False, True); LongBool = (False, True); T h e s e t y p e s h a v e t h e f o l l o w i n g sizes: • Boolean is b y t e - s i z e d (8 b i t s ) . • WordBool is w o r d - s i z e d ( 1 6 b i t s ) . • LongBool is longint-sized (32 b i t s ) . B e c a u s e B o o l e a n s a r e e n u m e r a t e d o r d i n a l t y p e s , t h e following r e l a t i o n s h i p s exist a m o n g B o o l e a n t y p e s : T r u e > False Ord(False)
= 0
Ord(True) = 1 Succ(False) = T r u e Pred(True) = F a l s e A m o n g t h e " B o o l e a n s , " Boolean is t h e p r e f e r r e d t y p e a n d u s e s t h e least m e m o r y . WordBool a n d LongBool exist p r i m a r i l y for c o m p a t i b i l i t y w i t h y o u r applications in the Windows environment. I n a n e x p r e s s i o n , t h e following r e l a t i o n a l o p e r a t o r s p r o d u c e r e s u l t s o f t y p e Boolean:
<>
> <
> = < = IN For W i n d o w s compatibility, Booleans c a n assume ordinal values other t h a n z e r o a n d o n e . A B o o l e a n e x p r e s s i o n is c o n s i d e r e d false w h e n its o r d i n a l v a l u e is z e r o , a n d t r u e w h e n its o r d i n a l v a l u e is n o n z e r o .
Char Type U s e variables o f t h e o r d i n a l t y p e C h a r t o s t o r e A S C I I c h a r a c t e r s . W r i t e c h a r a c t e r c o n s t a n t s b e t w e e n s i n g l e q u o t a t i o n s , as i n t h e f o l l o w i n g :
5 3
54
Part I — W o r k i n g w i t h T P W
'9'
'A' 'L' 'i' '&' T h e s i n g l e q u o t a t i o n c h a r a c t e r is w r i t t e n as t w o s i n g l e q u o t a t i o n s w i t h i n s i n g l e q u o t a t i o n s , like t h i s : i
i
i i
T h e Chr f u n c t i o n c o n v e r t s a n i n t e g e r v a l u e i n t o a c h a r a c t e r w i t h t h e corresponding ASCII value. T h e Ord f u n c t i o n r e t u r n s a c h a r a c t e r ' s A S C I I v a l u e .
Enumerated Types E n u m e r a t e d t y p e s d e f i n e o r d e r e d sets o f v a l u e s b y e n u m e r a t i n g t h e i d e n t i f i e r s that d e n o t e t h e v a l u e s . T h e i r o r d e r i n g is d e t e r m i n e d b y t h e s e q u e n c e i n w h i c h the identifiers are e n u m e r a t e d . For example:
type Food = (Apple, Kiwi, Peach, Date); I n this d e c l a r a t i o n , Kiwi is a c o n s t a n t o f t y p e Food. T h e Ord s t a n d a r d f u n c t i o n r e t u r n s t h e o r d i n a l i t y o f a n e n u m e r a t e d c o n s t a n t . I n this e x a m p l e :
Ord (Apple) Ord(Kiwi) Ord(Peach) Ord(Date)
= = = =
0 1 2 3
T h e identifiers in the type definition b e c o m e constants o f the e n u m e r a t e d type. T h e first c o n s t a n t h a s a n o r d i n a l i t y o f z e r o , t h e s e c o n d h a s a n o r d i n a l i t y o f o n e , the third a n ordinality o f t w o , a n d s o o n .
Subrange Types A s u b r a n g e t y p e is a r a n g e o f v a l u e s f r o m a n o r d i n a l t y p e s o m e t i m e s c a l l e d t h e host type. For example:
LittleConstant .. BiggerConstant
2—Elements of Application Development
specifies t h e s m a l l e s t a n d largest v a l u e in t h e s u b r a n g e . I n this c a s e , t h e s u b r a n g e is f r o m L i t t l e C o n s t a n t t o B i g g e r C o n s t a n t . B o t h c o n s t a n t s m u s t b e o f t h e s a m e o r d i n a l t y p e , a n d t h e first c o n s t a n t m u s t b e less t h a n o r e q u a l t o t h e s e c o n d c o n s t a n t . T h e $R c o m p i l e r directive c o n t r o l s range-checking of subrange types. T h e f o l l o w i n g are s u b r a n g e e x a m p l e s :
0. .49 -128..127
Reals A real t y p e has a set o f v a l u e s that is a s u b s e t o f t h e real n u m b e r s , w h i c h c a n b e represented in f l o a t i n g - p o i n t n o t a t i o n w i t h a f i x e d n u m b e r o f digits. A v a l u e ' s floating-point n o t a t i o n n o r m a l l y c o n s i s t s o f three v a l u e s : M, B, a n d E, s u c h that M x B E = N w h e r e B is always 10, M is a rational n u m b e r , a n d E is a n integer in t h e real t y p e ' s range. T u r b o P a s c a l f o r Windows s u p p l i e s f o u r p r e d e f i n e d real t y p e s . E a c h t y p e has a specific range a n d p r e c i s i o n :
Type
Range
Digits
Bytes
Real
2.9e-39..1.7e38
11-12
6
Single
1.5e-45..3.4e38
7-8
4
Double
5.0e-324..1.7e308
15-16
8
Extended
3.4e-4932..1.1e4932
19-20
10
N o t e : T u r b o Pascal f o r W i n d o w s s u p p o r t s t w o m o d e l s o f floating-point code generation: 1. S o f t w a r e
floating
point
2. 8 0 x 8 7 floating p o i n t U s e t h e $N c o m p i l e r d i r e c t i v e t o s w i t c h b e t w e e n t h e t w o models.
Strings A T u r b o Pascal string t y p e v a r i a b l e ( n o t a n u l l - t e r m i n a t e d string t y p e ) is a s e q u e n c e o f c h a r a c t e r s w i t h a d y n a m i c l e n g t h , a n d a c o n s t a n t m a x i m u m size between 1 and 255.
5 5
56
Parti—Working with T P W
If y o u d e c l a r e a string w i t h o u t a m a x i m u m size, it a u t o m a t i c a l l y b e c o m e s a size o f 2 5 5 . S t r i n g c o n s t a n t s a r e w r i t t e n i n q u o t a t i o n s ; for e x a m p l e :
'Windows
1
'Bible' N o t i c e that t w o c o n s e c u t i v e s i n g l e q u o t a t i o n s a r e u s e d t o i n d i c a t e a s i n g l e q u o t a t i o n i n a string. T h e f o l l o w i n g o p e r a t o r s c a n b e u s e d w i t h string t y p e v a l u e s :
+
< > < = > = O p e r a t o r s c o m p a r e strings b y u s i n g t h e A S C I I c o d e s for letters a n d n u m b e r s . F o r e x a m p l e , t h e A S C I I c o d e for Af is 7 7 a n d 7* is 8 4 . T h u s , a string b e g i n n i n g w i t h a n M is less t h a n o n e b e g i n n i n g w i t h a T. T h e A S C I I c o d e for a l o w e r c a s e ra, h o w e v e r , is 1 0 9 . T h u s , a n u p p e r c a s e 7*is less t h a n a l o w e r c a s e m. K e e p this i n m i n d w h e n y o u c o m p a r e s t r i n g s .
Structured Types A structured type c a n h o l d m o r e than o n e value. Structured types are • Array (types) • File (types) • O b j e c t (types) • R e c o r d (types) • S e t (types) If a c o m p o n e n t t y p e is s t r u c t u r e d , t h e r e s u l t i n g s t r u c t u r e d t y p e h a s m o r e t h a n o n e l e v e l o f s t r u c t u r i n g a n d c a n , i n fact, h a v e u n l i m i t e d levels o f structuring (memory permitting). In other w o r d s , a structured type c a n contain other t y p e s that a r e t h e m s e l v e s s t r u c t u r e d . T h e s e o t h e r t y p e s c a n , i n t u r n , c o n t a i n m o r e t y p e s that a l s o are s t r u c t u r e d . T h e m a x i m u m size o f a n y s t r u c t u r e d t y p e i n T u r b o Pascal is 6 5 , 5 2 0 b y t e s ( a b o u t 6 4 K ) . T h e r e s e r v e d w o r d packed i n a s t r u c t u r e d t y p e ' s d e c l a r a t i o n tells t h e c o m p i l e r t o c o m p r e s s d a t a w h e n it s t o r e s t h e t y p e . Note: T u r b o Pascal for W i n d o w s a c c e p t s t h e r e s e r v e d w o r d packed, b u t i g n o r e s it.
2—Elements of Application Development
Arrays A n array is a c o l l e c t i o n o f v a l u e s o f t h e s a m e t y p e . Arrays m a k e d a t a m u c h m o r e manageable. Y o u d e c l a r e a n array as f o l l o w s : array
[index-type]
of
element-type
T h e element type c a n b e any type, b u t the i n d e x type must b e a n ordinal t y p e . Y o u c a n u s e several i n d e x t y p e s if y o u s e p a r a t e t h e m b y c o m m a s . E a c h i n d e x t y p e s e p a r a t e d b y a c o m m a r e p r e s e n t s a d i m e n s i o n o f t h e array. For example: type CharData = array[ A ' . . Z ] of Byte; NumList = array[1..600] of Integer; Matrix = array[0..21, 0..21] of real; 1
1
1
{ 1 Dimension } { 1 Dimension } { 2 Dimensions }
Records A r e c o r d c o n t a i n s a n u m b e r o f c o m p o n e n t s , o r f i e l d s , that c a n b e o f d i f f e r e n t types. A r e c o r d d e c l a r a t i o n b e g i n s w i t h t h e k e y w o r d record a n d e n d s w i t h a n end. For example: ThisRecord = Record Month: 0 .. 12; Day : 1 .. 31; Year
: Integer;
end; A r e c o r d a l s o c a n b e variant. I n o t h e r w o r d s , a g r o u p o f r e c o r d s c a n h a v e different structures d e p e n d e n t o n a c o n d i t i o n . For example: type ClassType
= (Num, Dat, Str);
Date = record D, M, Y: Integer; end; Facts = record Name: string[10];
5 7
58
Parti—Working with T P W
case Kind: Num: (N: Dat: (D: Str: (S:
ClassType of real); Date); string);
end; D e p e n d i n g o n w h e t h e r Kind is a Num, Dat, o r Str, t h e Facts r e c o r d c o n t a i n s a n N, D, o r S d a t a f i e l d .
Object Types A n o b j e c t t y p e is a d a t a s t r u c t u r e s i m i l a r t o a r e c o r d , a l s o c o n t a i n i n g a f i x e d n u m b e r o f c o m p o n e n t s . E a c h c o m p o n e n t is e i t h e r a field ( w h i c h c o n t a i n s d a t a of a particular type) o r a m e t h o d (procedure o r function), w h i c h "operates" o n an object's data. For example: GenericObject = object Fieldl : integer; Field2 : real; procedure Methodl; procedure Method2; end;
{ Object data }
{ Object behavior }
W h e n y o u d e c l a r e a f i e l d , y o u specify a n i d e n t i f i e r that n a m e s t h e fields a n d t h e i r d a t a t y p e s . W h e n y o u d e c l a r e a m e t h o d , y o u specify a p r o c e d u r e , function, constructor, or destructor heading. Here's the scenario in somewhat formal form: Field
= FieldName(s):
Method
= procedure
type; MethodName(<parameter(s)>\type);
o r = function MethodName(<parameter(s)>:type):type; o r = constructor MethodName(<parameter(s)>:type [;<parameter(s)>: type]); /"virtual/; o r = destructor MethodName[(<parameters>\ type)/;/virtual/; A n o b j e c t t y p e c a n i n h e r i t t h e d a t a a n d b e h a v i o r (its c o m p o n e n t s ) f r o m a n o t h e r o b j e c t t y p e . T h e i n h e r i t i n g o b j e c t is a d e s c e n d a n t , a n d t h e o b j e c t that s u p p l i e s t h e d a t a a n d b e h a v i o r f o r i n h e r i t a n c e is a n a n c e s t o r .
2—Elements of Application Development
59
T h e d o m a i n o f a n o b j e c t t y p e c o n s i s t s o f itself a n d all its d e s c e n d a n t s .
Sets S e t s d e f i n e c o l l e c t i o n s o f e l e m e n t s o f a s p e c i f i c scalar o r s u b r a n g e t y p e . F o r e x a m p l e , t h e f o l l o w i n g a r e set t y p e s : type Day = (Sun, Mon, Tue, Wed, Thu, Fri, Sat); CharSet = set of Char; Digits = set of 0..4; Days = set of Day; Months = (January, February, March, April, May, June, July, August, September, October, November, December); T h e b a s e t y p e o f a set m u s t b e a n o r d i n a l t y p e w i t h n o t m o r e t h a n 2 5 6 possible values. Thus, the ordinal values of the u p p e r a n d lower b o u n d s of the base type must b e in the range 0..255. A set c o n s t r u c t o r , w h i c h d e n o t e s a set t y p e v a l u e , is f o r m e d b y w r i t i n g e x p r e s s i o n s i n b r a c k e t s . E a c h e x p r e s s i o n d e n o t e s a v a l u e o f t h e set. T h e b r a c k e t n o t a t i o n [ ] d e n o t e s t h e e m p t y s e t — c o m p a t i b l e w i t h all set types. F o r e x a m p l e , t h e f o l l o w i n g a r e set c o n s t r u c t o r s : [Mon..Sat] [1, 3, I + 1 .. J - 1] ['0'..'5', 'A'..'Q', 'd'..'z',
'_']
Files A file t y p e c o n s i s t s o f a l i n e a r s e q u e n c e o f c o m p o n e n t s o f s o m e c o m p o n e n t t y p e , w h i c h c a n b e a n y t y p e e x c e p t a file t y p e . If y o u o m i t t h e c o m p o n e n t t y p e , t h e t y p e d e n o t e s a n u n t y p e d file. T h e p r e d e f i n e d file t y p e Text signifies a file c o n t a i n i n g c h a r a c t e r s o r g a nized into lines. F o r e x a m p l e , t h e f o l l o w i n g a r e File t y p e d e c l a r a t i o n s : type Employee = record ID : Integer; FirstName: string[10]; LastName : string[20]; Address : string[40]; end;
60
Parti—Working with T P W
EmployeeFile = file of Employee; NumberFile = file of Real; SwapFile = file;
Pointer Types A pointer type variable contains t h e m e m o r y address o f a d y n a m i c variable o f s o m e "specified" base type. In other words, a pointer d o e s not contain a data v a l u e ; it c o n t a i n s a m e m o r y a d d r e s s . A p o i n t e r " p o i n t s t o " a u n i q u e l o c a t i o n i n m e m o r y . P o i n t e r s c a n p o i n t t o l o c a t i o n s that c o n t a i n b y t e v a l u e s , i n t e g e r s , r e a l s , records, strings, o r any other data type. Pointers are extremely important in object-oriented p r o g r a m m i n g a n d are u s e d t h r o u g h o u t this b o o k . A l t h o u g h y o u m i g h t t h i n k that p o i n t e r s a r e c o m p l i c a t e d c r e a t u r e s ( r u m o r h a s i t ) , t h e y are n o t . K e e p i n m i n d that a p o i n t e r holds a m e m o r y address, n o t a data value. Y o u assign data values to the a d d r e s s e s h e l d i n t h e p o i n t e r b y u s i n g t h e p o i n t e r . T h e p o i n t e r is t h e o n l y w a y y o u c a n g e t at t h e d a t a . T h i s p r o c e d u r e s o u n d s a little i n d i r e c t , b u t it is i m p o r t a n t i n b o t h o b j e c t - o r i e n t e d a n d W i n d o w s p r o g r a m m i n g , a n d it is discussed in detail t h r o u g h o u t the b o o k . Y o u c a n assign a value t o a pointer variable with: • T h e NeworGetMem p r o c e d u r e s • T h e @ operator • T h e Ptr f u n c t i o n T h e r e s e r v e d w o r d nil d e n o t e s a p o i n t e r c o n s t a n t that p o i n t s n o w h e r e . T h e p r e d e f i n e d t y p e Pointer d e n o t e s a n u n t y p e d p o i n t e r (a p o i n t e r that d o e s n o t point t o any specific type). F o r a n a p p l i c a t i o n t o u s e a p o i n t e r , it m u s t first r e q u e s t m e m o r y f o r t h e t y p e o f d a t a t h e p o i n t e r p o i n t s t o . It r e q u e s t s m e m o r y b y initializing t h e p o i n t e r w i t h New:
var APointer : "Integer; begin New(APointer); end; I n this c a s e , New reserves s p a c e f o r a n i n t e g e r v a l u e .
2—Elements of Application Development
Y o u c a n t h e n store a v a l u e at t h e a d d r e s s p o i n t e d t o b y APointer, u s i n g a caret after t h e p o i n t e r n a m e :
APointer" := 28; T h e caret indicates that y o u d o n o t w a n t t h e p o i n t e r itself (as a n a d d r e s s ) , b u t t h e v a l u e at t h e a d d r e s s p o i n t e d t o b y t h e p o i n t e r . T h i s is c a l l e d dereferencing the pointer. T h e f o l l o w i n g are p o i n t e r t y p e d e c l a r a t i o n s :
type BytePtr = "Byte; WordPtr = "Word; IdentPtr = "IdentRec; IdentRec = record Ident: string[24]; RefCount: Word; Next: IdentPtr; end; If y o u are n o t u s e d t o u s i n g p o i n t e r s , y o u m i g h t w o n d e r w h y it is w o r t h g o i n g t o t h e extra t r o u b l e o f u s i n g t h e m , b e c a u s e p o i n t e r s are, b y their n a t u r e , indirect. O n e g o o d reason t o u s e p o i n t e r s is that variables p o i n t e d t o b y p o i n t e r s u s e m e m o r y that is in t h e heap, n o t in t h e data s e g m e n t . T h e heap is d y n a m i c a n d c a n g r o w as large as it has t o ( m e m o r y p e r m i t t i n g ) . T h e data s e g m e n t is a fixed size, a n d variables in t h e data s e g m e n t are o f a fixed size as w e l l . If y o u are d e s i g n i n g a p p l i c a t i o n s s u c h as a d a t a b a s e , w h i c h has t o b e flexible a b o u t how m u c h m e m o r y it e v e n t u a l l y u s e s , p o i n t e r s a d d t h e flexibility. D a t a b a s e s , s p r e a d s h e e t s , a n d a n y t h i n g e l s e that d e p e n d s o n l i n k e d lists, trees, a n d o t h e r d y n a m i c s t r u c t u r e s rest o n p o i n t e r s . A n array m u s t have p r e c i s e d i m e n s i o n s , a n d t h u s m u s t specify in a d v a n c e (at c o m p i l e t i m e ) how m u c h m e m o r y it u s e s . V a r i a b l e s a d d r e s s e d t h r o u g h p o i n t e r s d o n o t have t o specify their e x a c t size at c o m p i l e t i m e . D e c i s i o n s c a n b e d e l a y e d u n t i l run-time—a d e f i n i t e p l u s in m a n y a p p l i c a t i o n s . F o r e x a m p l e , if o n e c o m p u t e r s y s t e m has 8 M ( m e g a b y t e s ) o f m e m o r y a n d a n o t h e r 6 4 0 K , a d a t a b a s e o r s p r e a d s h e e t that u s e s p o i n t e r s t o a l l o c a t e m e m o r y c a n utilize t h e extra m e m o r y t o create larger d a t a sets o n t h e larger s y s t e m .
PChar T h e p r e d e f i n e d t y p e PChar d e n o t e s a p o i n t e r t o a n u l l - t e r m i n a t e d string. D e c l a r e PChar as f o l l o w s :
type PChar = "Char;
61
62
Part I — W o r k i n g w i t h T P W
T u r b o Pascal f o r W i n d o w s s u p p o r t s a set o f e x t e n d e d s y n t a x r u l e s ( c o n t r o l l e d b y t h e $X c o m p i l e r directive) t o facilitate h a n d l i n g o f strings u s i n g t h e PChar t y p e .
Procedural Types S t a n d a r d Pascal r e g a r d s p r o c e d u r e s a n d f u n c t i o n s strictly as p r o g r a m p a r t s that c a n b e e x e c u t e d t h r o u g h p r o c e d u r e o r f u n c t i o n calls. T u r b o P a s c a l a n d T u r b o Pascal f o r W i n d o w s h a v e m u c h b r o a d e r v i e w s o f p r o c e d u r e s a n d functions. T h r o u g h p r o c e d u r a l types, T u r b o Pascal allows y o u t o treat p r o c e d u r e s a n d f u n c t i o n s as o b j e c t s that c a n b e a s s i g n e d t o v a r i a b l e s a n d p a s s e d as p a r a m e t e r s . A p r o c e d u r a l type declaration specifies the parameters a n d , for a function, t h e result t y p e . T h e k e y d i f f e r e n c e b e t w e e n a p r o c e d u r e a n d a f u n c t i o n is that a p r o c e d u r e d o e s n o t r e t u r n a v a l u e f o r t h e p r o c e d u r e itself. A f u n c t i o n always returns a value o f s o m e type: integer, real, a n d s o o n . T h e s y n t a x f o r a p r o c e d u r a l t y p e d e c l a r a t i o n is e x a c t l y t h e s a m e as that f o r a p r o c e d u r e o r f u n c t i o n h e a d e r , e x c e p t y o u o m i t t h e i d e n t i f i e r after t h e procedure o r function k e y w o r d . For example: type AProc = procedure; ASwapProc = procedure(var A, B: Integer); AStrProc = procedure(S: String); AMathFunc = function(A: Real): Real; ADeviceFunc = function(var F: Text): Integer; AMinFunc = function(A,B: Real; F: AMathFunc): Real; T h e p a r a m e t e r n a m e s i n a p r o c e d u r a l t y p e d e c l a r a t i o n h a v e n o effect o n the meaning o f the declaration. T u r b o P a s c a l f o r W i n d o w s d o e s n o t let y o u d e c l a r e f u n c t i o n s that r e t u r n p r o c e d u r a l t y p e v a l u e s . A f u n c t i o n result v a l u e m u s t b e a String, Real, Integer, Char, Boolean, Poinfer, o r a u s e r - d e f i n e d e n u m e r a t i o n .
Turbo Pascal for Windows Reserved Words R e s e r v e d w o r d s a r e w o r d s that h a v e f i x e d m e a n i n g s i n t h e T u r b o P a s c a l f o r W i n d o w s language. I n other w o r d s , y o u cannot redefine reserved w o r d s . Y o u m u s t u s e t h e m as t h e y a r e . T u r b o Pascal f o r W i n d o w s is n o t c a s e - s e n s i t i v e , s o y o u c a n u s e u p p e r - o r l o w e r c a s e letters t o specify r e s e r v e d w o r d s .
2—Elements of Application Development
T h e T u r b o P a s c a l f o r W i n d o w s r e s e r v e d w o r d s are as f o l l o w s :
and asm array begin case const constructor destructor div do downto else end exports file for function
goto if implementation in inline interface label library mod nil not object of or packed pointer procedure
Statements A s t a t e m e n t is o n e o f t h e f o l l o w i n g : • a s s i g n m e n t (: =)
• begin..end • case..of ..else..end • f or..to/downto..do • goto • if ..then..else • inline(...) • procedure call • repeat..until • while..do • with..do
program record repeat set shl shr string then to type unit until uses var while with xor
63
64
Part I — W o r k i n g w i t h T P W
T a b l e 2.1 s h o w s t h e o p e r a t o r p r e c e d e n c e f o r t h e m a t h e m a t i c a l , r e l a t i o n a l , a n d l o g i c a l o p e r a t o r s i n T u r b o Pascal f o r W i n d o w s . Table
2.1. Operator
precedence
Operators
from
high to low. Precedence
@, not
First ( h i g h )
*, /, d i v , m o d , a n d , s h l , s h r
Second
+ , - , or, x o r
Third
= , < > , < , > , < = , > = , in
Fourth (low)
assignment (:=) A n a s s i g n m e n t o p e r a t o r (: =) assigns t h e v a l u e o f a n e x p r e s s i o n t o a variable. T h e variable m u s t b e a s s i g n m e n t - c o m p a t i b l e w i t h t h e result t y p e o f t h e e x p r e s s i o n . T h e variable that is a s s i g n e d t h e n e w v a l u e is o n t h e left o f t h e a s s i g n m e n t o p e r a t o r . T h e v a l u e its a s s i g n e d t o is o n t h e right. For example: A := B; C[I] LoopR
{ A is assigned the value B. }
:= C[I] + 1 ;
{ C[I] is assigned the value C{I} + 1 }
:= (I > 0) and (I < 30)
{ LoopR is assigned the value that } { results from the evaluation of } { the expression on the right. }
begin..end T h e begin...end c o n s t r u c t s serve as s t a t e m e n t b r a c k e t s . For example: begin Statementl; Statement2; StatementX; end;
2—Elements of Application Development
W h e n t h e y a r e b r a c k e t e d i n this w a y , a n y n u m b e r o f c o n s e c u t i v e statem e n t s c a n b e t r e a t e d as a s i n g l e s t a t e m e n t . F o r e x a m p l e :
{Compound statement used in an ' i f statement } if First < Last then begin Temp := First; First := Last; Last := Temp; end;
case..of..else..end T h e case s t a t e m e n t c o n s i s t s o f a n e x p r e s s i o n ( t h e s e l e c t o r ) a n d a list o f statements, each prefixed with a case. F o r example, a simple case:
case AnExpression of case: Statementl; case: Statement2; end; o r a case-else: case AnExpression of case: Statementl; case: Statement2; else Statement3; end; A c a s e consists o f o n e o r m o r e constants o r ranges, separated by c o m m a s . T h e else part is o p t i o n a l . F o r e x a m p l e :
case Ch of 'A'..'Z', 'a'-.'z : WriteLn('Letter'); '0'..'9': WriteLn('Digit'); '+', '-', '*', '/': WriteLn('Operator'); else WriteLn('A Special character'); end; 1
6 5
66
Part I — W o r k i n g w i t h T P W
for..to/downto..do T h e for s t a t e m e n t c a u s e s t h e s t a t e m e n t after do to b e e x e c u t e d o n c e f o r e a c h v a l u e in the range first to last. F o r e x a m p l e , a f or-to: for Var1 := First to Last do Statementl; or for Var1 := First to last do begin Statementl; Statement2: end; o r a f or-downto: for Var1
:= First downto Last do
Statementl; T h e c o n t r o l variable a n d initial a n d final v a l u e s m u s t b e o r d i n a l t y p e s . I f y o u u s e a Downto, t h e v a l u e o f t h e c o n t r o l variable falls in increments of o n e for each l o o p . With downto, t h e v a l u e o f t h e c o n t r o l variable falls in d e c r e m e n t s b y o n e for each l o o p . For example: { for
... to, for
... downto }
for I := 1 to ParamCount do WriteLn(ParamStr(I); for I := 1 to 15 do for J := 1 to 15 do begin X := 0; for K := 1 to 15 do X := X + Matrix1[I,K] Matrix[I,J] := X; end;
* Matrix2[K,J];
goto A goto s t a t e m e n t transfers p r o g r a m e x e c u t i o n t o t h e s t a t e m e n t p r e f i x e d b y t h e l a b e l referenced in t h e s t a t e m e n t .
2—Elements of Application Development
For example:
goto ALabel T h e l a b e l m u s t b e i n t h e s a m e b l o c k as t h e goto s t a t e m e n t ; y o u c a n n o t transfer e x e c u t i o n o u t o f a p r o c e d u r e o r a f u n c t i o n . For example:
label 1, 2; goto 1
1: WriteLn ('Something can happen here'); 2: WriteLn ('Something different here');
i£.then..else I f, t h e n, a n d else specify t h e c o n d i t i o n s u n d e r w h i c h a s t a t e m e n t is e x e c u t e d . F o r e x a m p l e , a s i m p l e if-then:
if AnExpression then Statementl; or
if AnExpression then begin Statementl; Statement2; end; O r a n if-then-else: if AnExpression then Statementl else Statement2; If t h e B o o l e a n e x p r e s s i o n after t h e if is t r u e , t h e s t a t e m e n t after then is e x e c u t e d . O t h e r w i s e , if t h e r e is a n else part, t h e s t a t e m e n t after else is executed. For example:
{ 'if statements } if (X < Min) or (X > Max) then X := 0;
67
68
Parti—Working with T P W
if ParamCount <> 2 then begin WriteLn('Can not execute the command l i n e ) ; Halt(1); end else begin ReadFile(ParamStr(1)); WriteFile(ParamStr(2)); end; 1
inline(...) Inline s t a t e m e n t s a n d directives a l l o w y o u t o insert m a c h i n e - c o d e i n s t r u c t i o n s directly i n t o t h e c o d e o f a m a i n p r o g r a m m o d u l e o r a u n i t . For example: inline
(data/data/...data)
If y o u u s e inline as a s t a t e m e n t , t h e inline d a t a e l e m e n t s a r e i n s e r t e d directly in the c o d e . If y o u u s e inline as a directive i n a p r o c e d u r e o r a f u n c t i o n d e c l a r a t i o n , t h e inline d a t a e l e m e n t s a r e i n s e r t e d i n t h e c o d e e a c h t i m e t h e p r o c e d u r e o r f u n c t i o n is c a l l e d . A n inline d a t a e l e m e n t c o n s i s t s o f a c o n s t a n t o r a variable identifier, o p t i o n a l l y p r e f i x e d b y a size s p e c i f i e r : < o r > . A v a r i a b l e identifier c a n b e f o l l o w e d b y a + o r a - a n d a c o n s t a n t that s p e c i f i e s a n offset f r o m t h e v a r i a b l e ' s a d d r e s s . A n inline e l e m e n t g e n e r a t e s o n e b y t e o f c o d e if it is a c o n s t a n t i n t h e r a n g e 0 . . 2 5 5 . O t h e r w i s e , it g e n e r a t e s o n e w o r d . Y o u u s e t h e < a n d > o p e r a t o r s t o o v e r r i d e t h e a u t o m a t i c size s e l e c t i o n : < m e a n s "always g e n e r a t e a b y t e . " > m e a n s "always g e n e r a t e a w o r d . " For example: { 'inline' statement } procedure FillWord(var Dest; Count: Word; Data: Word); begin inline( $C4/$7E/
2—Elements of Application Development
$8B/$4E/
(* (* (* (*
MOV MOV CLD REP
CX,Count[BP]*) AX,Data[BP] *) *) STOSW *)
end;
procedure call A p r o c e d u r e is a p r o g r a m c o m p o n e n t that d e f i n e s a s p e c i f i c a c t i o n o r o p e r a t i o n o n a variable o r g r o u p o f variables. For example: procedure
identifier;
Or, a p r o c e d u r e c a n have p a r a m e t e r s : procedure identifier
( parameters
);
T h e p r o c e d u r e heading s p e c i f i e s t h e identifier f o r t h e p r o c e d u r e a n d t h e f o r m a l p a r a m e t e r s , if there are a n y . A p r o c e d u r e is activated b y a p r o c e d u r e s t a t e m e n t . T h e p r o c e d u r e heading is f o l l o w e d b y : • A d e c l a r a t i o n part that d e c l a r e s l o c a l o b j e c t s • T h e s t a t e m e n t s b e t w e e n begin a n d end, w h i c h specify w h a t a c t i o n o c c u r s w h e n t h e p r o c e d u r e is c a l l e d R a t h e r t h a n specify t h e d e c l a r a t i o n a n d s t a t e m e n t parts, a p r o c e d u r e d e c l a r a t i o n c a n specify a f o r w a r d , e x t e r n a l , o r inline A f o r w a r d d e c l a r a t i o n indicates
directive.
that a p r o c e d u r e w i l l b e d e f i n e d later
(that is, f o r w a r d ) in t h e c o d e : procedure GetNum
(X: Integer); forward
A n e x t e r n a l d e c l a r a t i o n refers t o s e p a r a t e l y c o m p i l e d p r o c e d u r e s a n d f u n c t i o n s w r i t t e n in a s s e m b l y l a n g u a g e : procedure Copyword
(var Source, Dest,Count: Word);external;
A n inline directive a l l o w s y o u t o p u t m a c h i n e - c o d e instructions into y o u r c o d e : procedure Disablelnterrupts; inline
($FA);
directly
69
70
Parti—Working with T P W
For example:
{ A Procedure Declaration } procedure WrStr(X, Y: integer; S: string); var SaveX, SaveY: Integer; begin SaveX := X; SaveY := Y; Writeln(S); end;
repeat.until T h e s t a t e m e n t s b e t w e e n repeat a n d until a r e e x e c u t e d i n s e q u e n c e u n t i l t h e B o o l e a n e x p r e s s i o n is t r u e at t h e end o f t h e s e q u e n c e . For example:
repeat Statementl; Statement2; StatementN until AnExpression A repeat-until s e q u e n c e is e x e c u t e d at least o n c e . For example:
{ Repeat Statements } repeat Ch := GetChar until Ch <> ' '; repeat Write('Enter a value: '); ReadLn(V); until (V >= 0) and (V <= '99');
whilc.do A w h i l e s t a t e m e n t c o n t a i n s a n e x p r e s s i o n that c o n t r o l s t h e r e p e a t e d e x e c u t i o n of a statement (which can b e a c o m p o u n d statement). For example:
while AnExpression do Statementl
2—Elements of Application Development
T h e s t a t e m e n t after do is e x e c u t e d r e p e a t e d l y as l o n g as t h e B o o l e a n e x p r e s s i o n is t r u e . T h e e x p r e s s i o n is e v a l u a t e d b e f o r e t h e s t a t e m e n t is e x e c u t e d , s o if t h e e x p r e s s i o n is false at t h e b e g i n n i n g , t h e s t a t e m e n t is n o t e x e c u t e d . I n o t h e r w o r d s , t h e r e is n o c e r t a i n t y that a while-do e x e c u t e s e v e n o n c e . For example: { 'while' statements } while Ch = ' ' d o Ch := GetChar; while not Eof(InputFile) do begin
{ Eof means End of file }
ReadLn(InputFile, Line); WriteLn(OutputFile, Line); Inc(LineCount); end;
with„do T h e wit h s t a t e m e n t is a n a l t e r n a t e m e t h o d f o r r e f e r e n c i n g t h e fields o f a r e c o r d . For example: with ARecord do Statementl; I n t h e s t a t e m e n t after do, t h e fields o f o n e o r m o r e r e c o r d v a r i a b l e s c a n b e a c c e s s e d u s i n g o n l y t h e i r field i d e n t i f i e r s . For example: {
'with' statement } with Date[C] do begin Month := 1; Year end;
:= Year + 1;
T h i s is e q u i v a l e n t t o Date[C].Month
:= 1;
Date[C].Year
:= Date[C].Year + 1;
71
72
Part I — W o r k i n g w i t h T P W
Debugging Turbo Pascal for Windows Applications A l t h o u g h y o u probably never m a k e mistakes (ha, h a ) , y o u might w a n t to k n o w that if y o u d o , T u r b o P a s c a l f o r W i n d o w s c a n h e l p . Its h e l p c o m e s i n t h e f o r m o f t h e T u r b o Pascal f o r W i n d o w s D e b u g g e r . T h e T u r b o P a s c a l f o r W i n d o w s D e b u g g e r is a p o w e r f u l t o o l f o r d e b u g g i n g W i n d o w s a p p l i c a t i o n s . It g o e s a m a j o r s t e p o r t w o f u r t h e r t h a n t h e b u i l t - i n d e b u g g i n g c a p a b i l i t i e s o f t h e T u r b o Pascal f o r W i n d o w s c o m p i l e r . T h e T u r b o Pascal f o r W i n d o w s c o m p i l e r ' s b u g - d e t e c t i n g p o w e r f o c u s e s o n y o u r a p p l i c a t i o n c o d e s y n t a x . If y o u h a v e a n u n k n o w n i d e n t i f i e r o r h a v e o m i t t e d a n e c e s s a r y s e m i c o l o n , t h e c o m p i l e r finds it. It c a n n o t g u a r a n t e e m o r e t h a n c o r r e c t s y n t a x . Y o u r c o d e c a n survive c o m p i l e r b u g - d e t e c t i o n a n d still c r a s h m i s e r a b l y at r u n t i m e . R u n - t i m e e r r o r s are t h e d o m a i n o f a n o t h e r class o f b u g d e t e c t o r s : "debuggers." D e b u g g e r s h e l p y o u i s o l a t e a n d c o r r e c t m i s t a k e s that u s u a l l y are n o t d u e t o e r r o r s i n s y n t a x . T h i s is a b r o a d a n d c o m p l e x g r o u p o f e r r o r s y o u c a n m a k e i n t h e l o g i c o f y o u r c o d e , b y n o t a c c o u n t i n g f o r t h e full r a n g e o f p o s s i b l e a c t i o n s o f y o u r c o d e , a n d s o o n . D e b u g g i n g , i n this r e a l m , is a n i m p e r f e c t "art" at b e s t , a n d d e b u g g i n g W i n d o w s a p p l i c a t i o n s is e v e n m o r e i m p e r f e c t . T h e k e y t o d e b u g g i n g W i n d o w s a p p l i c a t i o n s lies i n i s o l a t i n g t h e m o r e likely e r r o r - p r o n e areas o f y o u r c o d e . A f e w s i m p l e d e v e l o p m e n t tactics h e l p : 1. C o d e i n s m a l l f r a g m e n t s . U s e o b j e c t - o r i e n t e d t e c h n i q u e s t o k e e p d a t a a n d t h e b e h a v i o r for m a n i p u l a t i n g d a t a i n o b j e c t s . 2 . D e v e l o p o b j e c t s , u n i t s , o r o t h e r s t r u c t u r a l b l o c k s o n e at a t i m e . M a k e s u r e that a n o b j e c t o r a b l o c k w o r k s b e f o r e m o v i n g o n t o o t h e r o b j e c t s o r b l o c k s , p a r t i c u l a r l y if t h e s e o b j e c t s a n d b l o c k s are i n t e r r e l a t e d . 3. R e d u c e t h e n u m b e r o f p r o c e d u r e s , f u n c t i o n s , a n d s o o n , that c a n m a n i p u l a t e d a t a . If y o u d o n o t u s e o b j e c t s , t h e n u s e l o c a l v a r i a b l e s . T h e s e tactics h e l p , b u t t h e y p r o b a b l y w i l l n o t e l i m i n a t e all y o u r b u g s . W h e n y o u d i s c o v e r a b u g i n y o u r W i n d o w s a p p l i c a t i o n , call o n T u r b o D e b u g g e r for W i n d o w s . I n effect, it s l o w s d o w n t h e e x e c u t i o n o f a n a p p l i c a t i o n a n d lets y o u e x a m i n e its s p e c i f i c a s p e c t s . Y o u c a n e x a m i n e t h e stack, v a r i a b l e v a l u e s , C P U registers, W i n d o w s messages, a n d so o n . T u r b o D e b u g g e r gives y o u seven m a i n ways to e x p l o r e y o u r c o d e : 1. T r a c i n g ( e x e c u t i n g a n a p p l i c a t i o n o n e l i n e at a t i m e ) . 2. B a c k t r a c i n g ( s t e p p i n g b a c k w a r d t h r o u g h t h e a p p l i c a t i o n c o d e o n e l i n e at a t i m e , a n d r e v e r s i n g t h e e x e c u t i o n ) .
2—Elements of Application Development
3. S t e p p i n g ( e x e c u t i n g t h e a p p l i c a t i o n c o d e o n e l i n e at a t i m e b u t " s t e p p i n g o v e r " a n y calls t o p r o c e d u r e s o r f u n c t i o n s ) . T h i s w a y t h e p r o c e d u r e o r f u n c t i o n is e x e c u t e d as a b l o c k a n d a n y v a l u e s are returned, but y o u d o not "trace" through the p r o c e d u r e or function o n e l i n e at a t i m e . 4. V i e w i n g ( o p e n i n g a w i n d o w f o r v i e w i n g t h e states o f v a r i o u s c o m p o n e n t s o f t h e a p p l i c a t i o n ) . T h e s e c o m p o n e n t s are t h e a p p l i c a t i o n ' s v a r i a b l e s , b r e a k p o i n t s y o u set, t h e stack, a T u r b o D e b u g g e r l o g , a d a t a file, a s o u r c e file, C P U c o d e , m e m o r y , r e g i s t e r s , n u m e r i c p r o c e s s o r information, object hierarchies, the application's e x e c u t i o n history, and the application's output. 5. I n s p e c t i n g d a t a s t r u c t u r e s ( s u c h as arrays). 6. C h a n g i n g ( m a n i p u l a t i n g t h e a p p l i c a t i o n b y r e p l a c i n g t h e c u r r e n t v a l u e o f a v a r i a b l e w i t h a n e w v a l u e that y o u s p e c i f y ) . 7. W a t c h i n g a p p l i c a t i o n v a r i a b l e s ( t r a c k i n g t h e c h a n g i n g v a l u e s o f variables y o u specify). A l l t h e T u r b o D e b u g g e r f o r W i n d o w s f e a t u r e s are available i n p u l l - d o w n menus. T h e s i m p l e s t w a y t o u s e T u r b o D e b u g g e r f o r W i n d o w s is t o l o a d t h e a p p l i c a t i o n y o u w a n t t o d e b u g i n t o a T u r b o P a s c a l f o r W i n d o w s edit w i n d o w , a n d t h e n select D e b u g g e r f r o m t h e T u r b o Pascal f o r W i n d o w s R u n / D e b u g g e r m e n u . M a k e s u r e , t h o u g h , that y o u s e l e c t O p t i o n s / L i n k e r / D e b u g i n f o i n t o a n e x e c u t a b l e file ( . E X E ) b e f o r e y o u r u n T u r b o D e b u g g e r . T h e specifics o f h o w y o u d e b u g y o u r application d e p e n d o n the k i n d o f application a n d possible error. In general, y o u d o not w a n t to trace t h r o u g h an e n t i r e W i n d o w s a p p l i c a t i o n . I n s t e a d , try t o isolate t h e e r r o r as b e s t y o u c a n a n d set b r e a k p o i n t s i n likely t r o u b l e d a r e a s . ( Y o u p r o b a b l y are t h i n k i n g that if y o u k n e w w h e r e t h e e r r o r w a s , y o u w o u l d n o t n e e d t h e d e b u g g e r — Y e s a n d N o . ) If y o u are d e v e l o p i n g t h e a p p l i c a t i o n o b j e c t - b y - o b j e c t o r b l o c k - b y - b l o c k , y o u c a n at least r e d u c e t h e b u g t o that a r e a . Set a b r e a k p o i n t , a n d t h e n trace t h r o u g h the application from the break point. I n m a n y s i t u a t i o n s , m a k i n g s u r e that a p r o c e d u r e , f u n c t i o n , o r m e t h o d is called, or m o n i t o r i n g a variable's values c a n locate the b u g . M o s t d e b u g sessions are started b y s e t t i n g b r e a k p o i n t s a n d a d d i n g t h e v a r i a b l e s i n t h o s e b r e a k p o i n t s u s i n g A d d W a t c h . T h e n y o u s t e p o r trace t h r o u g h t h e c o d e . If y o u g e t a r u n - t i m e e r r o r that typically l o o k s like t h i s :
Runtime error 204 at 0001:004 N o t i c e t h e a d d r e s s ( y o u p r o b a b l y w a n t t o w r i t e it d o w n ) , a n d u s e t h e F i n d E r r o r c o m m a n d o n t h e T u r b o Pascal f o r W i n d o w s S e a r c h m e n u t o l o c a t e t h e e r r o r i n y o u r s o u r c e c o d e (see f i g u r e 2.3).
73
74
Parti—Working with TPW
Figure
2.3- The Find error... command
in the Search
menu.
The Find Error dialog box appears (see figure 2 . 4 ) .
Figure
2.4, Result of selecting the Find error...
command.
2—Elements of Application Development
E n t e r t h e a d d r e s s o f t h e e r r o r i n t h e E r r o r A d d r e s s b o x . T u r b o Pascal f o r W i n d o w s t h e n r e c o m p i l e s y o u r c o d e a n d s t o p s w h e n it r e a c h e s t h e a d d r e s s y o u specify, h i g h l i g h t i n g t h e s t a t e m e n t that c a u s e d t h e e r r o r . T h e n , fix t h e e r r o r (in t h e e d i t w i n d o w ) a n d r e c o m p i l e . R e p e a t t h e p r o c e s s if y o u h a v e t o .
Begin.. A W i n d o w s a p p l i c a t i o n is c o m p l e x a n d i m p r e s s i v e . I n fact, a g o o d w a y t o i m p r e s s y o u r f r i e n d s is t o tell t h e m h o w c o m p l e x a W i n d o w s a p p l i c a t i o n is a n d t h e n s h o w t h e m a W i n d o w s a p p l i c a t i o n y o u c r e a t e d . If y o u u s e T u r b o P a s c a l f o r W i n d o w s , y o u c a n i m p r e s s y o u r f r i e n d s a n d d e v e l o p a p p l i c a t i o n s that w e r e beyond the scope of most " g o o d " programmers only o n e year ago. P r o g r e s s , at least o f a k i n d , o n e h a s t o a d m i t . S o m e t i m e s , w h e n I find myself peering through o n e w i n d o w or another, I'm not sure whether I s h o u l d be surprised by the progress.
75
3
CHAPTER
OBJECTS FOR WINDOWS So if Windows is the future, how do programmers The answer is, of course, by using object-oriented
get
there? programming. Zack Urlocker
Overture T u r b o Pascal f o r W i n d o w s m a k e s d e v e l o p i n g a M i c r o s o f t W i n d o w s ( c a l l e d W i n d o w s from n o w o n ) application affordable (mentally, I m e a n ) . Because T u r b o Pascal f o r W i n d o w s is a W i n d o w s a p p l i c a t i o n (that is, it r u n s i n a M i c r o s o f t W i n d o w s w i n d o w ) , y o u c a n w r i t e , test, a n d d e b u g s o u r c e c o d e i n W i n d o w s w i t h o u t h a v i n g t o shift b e t w e e n text a n d g r a p h i c m o d e s . T h i s p r o c e s s m a k e s d e v e l o p i n g W i n d o w s a p p l i c a t i o n s c o n v e n i e n t , efficient, a n d ( b e l i e v e it or not) enjoyable. If y o u ' r e a T u r b o Pascal p r o g r a m m e r , y o u a l r e a d y k n o w that y o u h a v e t h e niftiest c o m p i l e r i n p e r s o n a l c o m p u t i n g . It's fast, h a s a terrific u s e r i n t e r f a c e ( I D E ) , a n d , starting w i t h v e r s i o n 5 . 5 , h a s i n c l u d e d o b j e c t - o r i e n t e d e x t e n s i o n s . T h e s e e x t e n s i o n s are y o u r ticket i n t o t h e W i n d o w s d e v e l o p m e n t a r e n a . I n s h o r t , T u r b o P a s c a l for W i n d o w s is m o s t l y T u r b o P a s c a l p l u s O b j e c t W i n d o w s , a n o b j e c t - o r i e n t e d library that e n c a p s u l a t e s t h e c o m p l e x behaviors o f W i n d o w s applications in objects. These inheritable, extendable
78
Parti—Working with T P W
objects h a n d l e m o s t o f the tedious initialization required before a n application c a n c o m m u n i c a t e w i t h W i n d o w s . If y o u a l r e a d y k n o w T u r b o P a s c a l , y o u ' l l b e r u n n i n g W i n d o w s a p p l i c a t i o n s i n m i n u t e s b y u s i n g T u r b o Pascal f o r W i n d o w s . Y o u build them out of objects derived from ObjectWindows.
About Turbo Pascal Windows Until recently, a developer creating a Microsoft W i n d o w s application c o u l d e x p e c t t o l e a r n at least 5 5 0 f u n c t i o n s at a l o w l e v e l a n d w r i t e a n a p p l i c a t i o n i n e i t h e r a s s e m b l y l a n g u a g e o r M i c r o s o f t C — a difficult, t i m e - c o n s u m i n g task at b e s t . T h e latest v e r s i o n o f B o r l a n d I n t e r n a t i o n a l ' s w o r l d - c l a s s c o m p i l e r , T u r b o P a s c a l , c a l l e d T u r b o Pascal f o r W i n d o w s , m a k e s M i c r o s o f t W i n d o w s d e v e l o p m e n t m u c h , m u c h easier. T h e a d v a n t a g e s o f this c o m p i l e r / p r o g r a m m i n g e n v i r o n m e n t are several: 1. B e c a u s e its c o r e a n d I D E ( i n t e g r a t e d d e v e l o p m e n t e n v i r o n m e n t ) are similar to previous versions o f T u r b o Pascal, only a short learning i n v e s t m e n t is r e q u i r e d b y t h e m i l l i o n - p l u s c u r r e n t T u r b o Pascal programmers. 2. It abstracts t h e 5 5 0 W i n d o w s A P I ( A p p l i c a t i o n P r o g r a m m i n g I n t e r f a c e ) functions to a h i g h level t h r o u g h the use o f object-oriented t e c h n i q u e s , a n d t h u s lets a p r o g r a m m e r " i n h e r i t " e x i s t i n g W i n d o w s f u n c t i o n a l i t y (buttons, dialogue w i n d o w s , m e n u s , a n d so o n ) rather than create e a c h w i n d o w f r o m s c r a t c h . P r o g r a m m e r s call l o w - l e v e l W i n d o w s A P I functions through a high-level object-oriented unit called "ObjectWindows." 3. It lets a p r o g r a m m e r w r i t e , c o m p i l e , r u n , a n d d e b u g a p p l i c a t i o n s i n the W i n d o w s environment, without exiting to D O S . N o other p o p u l a r c o m p i l e r (including Microsoft C a n d B o r l a n d C + + ) can d o this. 4. It i n c l u d e s t h e W h i t e w a t e r R e s o u r c e C o m p i l e r , w h i c h significantly simplifies the writing of m e n u s , dialogues, controls, a n d so o n . F i g u r e 3.1 s h o w s W i n d o w s , t h e T u r b o Pascal f o r W i n d o w s I D E , a n d t h e Whitewater Resource Compiler running together.
3 — O b j e c t s for W i n d o w s
Figure
3.1. Windows, the IDE, and the compiler running together.
B e c a u s e T u r b o Pascal p r o g r a m m e r s c a n learn object-oriented p r o g r a m m i n g ( O O P , for short) without giving u p a l a n g u a g e they already k n o w , they get the best of b o t h c o m p u t i n g worlds—structured p r o g r a m m i n g a n d objects. M o r e i m p o r t a n t , b e c a u s e T u r b o Pascal is g e n e r a l - p u r p o s e a n d fast, it's p r a c t i c a l f o r c o m m e r c i a l a p p l i c a t i o n s . T u r b o Pascal f o r W i n d o w s c o m p i l e s c o d e at t h e s a m e b l a z i n g s p e e d as T u r b o P a s c a l 6 . 0 — o n m y m o d e s t l y p a c e d 3 8 6 S X , r u n n i n g at l 6 M h z : 4 0 , 0 0 0 + l i n e s p e r m i n u t e . T h e a d d i t i o n o f O b j e c t W i n d o w s t o t h e T u r b o Pascal c o r e is t h e b e s t t h i n g that h a s h a p p e n e d t o T u r b o Pascal s i n c e u n i t s , a n d T u r b o Pascal f o r W i n d o w s is t h e b e s t t h i n g that h a s h a p p e n e d t o W i n d o w s s i n c e , w e l l , W i n d o w s . I n this b o o k , I g u i d e y o u t h r o u g h t w o p a s s e s o f t h e W i n d o w s d e v e l o p m e n t p r o c e s s : 1) a q u i c k a n d c l e a n p a s s a n d 2) a d e t a i l e d a n d dirty p a s s . O n t h e first o n e , I s h o w y o u h o w t o b u i l d a B a s i c l n t e r f a c e ( o b j e c t ) that h a n d l e s m a n y o f y o u r a p p l i c a t i o n s . I g o q u i c k l y , s p a r i n g y o u t h e d e t a i l s I t h i n k y o u c a n live w i t h o u t . If y o u ' r e n o t a p r o g r a m m i n g w h i z , d o n ' t w o r r y ; y o u w o n ' t h a v e t o b e . T u r b o Pascal f o r W i n d o w s d o e s m o s t o f t h e w o r k . Y o u d o n ' t n e e d t o k n o w m o s t o f the details to create a m a j o r application. O n t h e s e c o n d p a s s , I fill i n m a n y o f t h e b l a n k s f o r y o u a f i c i o n a d o s a n d h a c k e r s . T h i s p a s s i n c l u d e s t h e f u n stuff. W i n d o w s , e v e n f o r a c o m m a n d - l i n e k i n d o f g u y like myself, is u n d e n i a b l y a p l e a s a n t , f u n e n v i r o n m e n t t o w o r k i n , e s p e c i a l l y if y o u t h i n k i n p i c t u r e s . M a n y f o l k s d o , s o a d e e p e r u n d e r s t a n d i n g o f optimization techniques, m e m o r y m a n a g e m e n t , and other juicy topics can be profitable.
79
80
Parti—Working with T P W
W i n d o w s is a n e v e n t - d r i v e n i n t e r f a c e . W i n d o w s i n t e r c e p t s e v e n t s , s u c h as a m o u s e click, a k e y p r e s s , a n d s o o n , a n d d i s p a t c h e s t h e m as m e s s a g e s t o t h e appropriate application windows. A W i n d o w s application makes the appropriate r e s p o n s e t o t h e s e m e s s a g e s t o p e r f o r m t h e f o l l o w i n g a c t i o n s : • C a r r y o u t s o m e task • Send a message back to Windows • Send a message to another application T h e o b j e c t s i n O b j e c t W i n d o w s e n c a p s u l a t e this c o m p l e x m e s s a g e e x c h a n g e i n o b j e c t s , w h i c h y o u u s e as s t o c k i t e m s o r e x t e n d b y w a y o f i n h e r i t a n c e . Y o u should understand generally h o w objects w o r k and h o w event and m e s s a g e p r o c e s s i n g o c c u r s , s o I b o t h e x p l a i n a n d s h o w y o u p i c t u r e s as y o u m o v e along. Y o u d o n ' t have to u n d e r s t a n d the specific details o f W i n d o w s event and message processing, thanks to ObjectWindows. T o d e v e l o p a W i n d o w s application with T u r b o Pascal for W i n d o w s , y o u u s e a f e w o b j e c t s i n t h e O b j e c t W i n d o w s library a n d e x t e n d t h e m h o w e v e r y o u n e e d t o . T h e B a s i c I n t e r f a c e I d e v e l o p i n C h a p t e r 4, " I n h e r i t i n g a n I n t e r f a c e , " is d e r i v e d f r o m O b j e c t W i n d o w s a n d c a n b e easily e x t e n d e d f o r y o u r s p e c i f i c n e e d s . I'll s h o w y o u h o w . As o u r interfaces, p r o g r a m m i n g languages, a n d c o m p u t i n g tools b e c o m e m o r e p o w e r f u l , t h e y b e c o m e m o r e c o m p l e x as w e l l . O n e p a t h t h r o u g h t h e c o m p l e x i t y is t h e r e p a c k a g i n g o f a p p l i c a t i o n s i n a n e v e n t - d r i v e n a r c h i t e c t u r e l i k e W i n d o w s . N o t that e v e n t - d r i v e n a r c h i t e c t u r e s a r e n ' t c o m p l e x — t h e y a r e , b u t t h e y c a n b e m a n a g e d easily w i t h O O P t e c h n i q u e s . Objects inherently communicate through messages. W h e n y o u want an o b j e c t t o d o s o m e t h i n g , y o u s e n d o n e o f its m e t h o d s ( f u n c t i o n s o r p r o c e d u r e s ) a m e s s a g e . T h e o b j e c t p e r f o r m s a task ( w h i c h c o u l d e n t a i l s e n d i n g a m e s s a g e to another object). Objects y o u derive from O b j e c t W i n d o w s also can send a n d r e c e i v e m e s s a g e s f r o m W i n d o w s . If y o u ' r e t h i n k i n g that o b j e c t s a n d W i n d o w s d o t h i n g s q u i t e a l i k e , y o u ' r e right, a n d w e l l o n y o u r w a y t o u n d e r s t a n d i n g h o w to write W i n d o w s applications with T u r b o Pascal for W i n d o w s . W i n d o w s is a g r a p h i c s e n v i r o n m e n t ; that's t h e e x c e p t i o n a l r e a s o n f o r u s i n g it. S u r e , t h e m u l t i t a s k i n g a n d s t a n d a r d i z e d i n t e r f a c e a n d d e v i c e drivers are w o n d e r f u l , b u t y o u c a n g e t t h o s e f e a t u r e s e l s e w h e r e . It's g r a p h i c s , p l u s t h o s e a t t r i b u t e s , that m a k e W i n d o w s s p e c i a l . T h e a p p l i c a t i o n s y o u d e v e l o p w i t h T u r b o Pascal f o r W i n d o w s p a y s p e c i a l a t t e n t i o n t o g r a p h i c s . I n this b o o k , I p a y t h e s a m e s p e c i a l a t t e n t i o n a n d u s e m a n y g r a p h i c s t o illustrate w h a t m i g h t o t h e r w i s e b e t o u g h t o c o n c e p t u a l i z e . Y o u ' r e g o o d at v i s u a l i z i n g , m a n i p u l a t i n g , l e a r n i n g f r o m i m a g e s — a b i g r e a s o n y o u use graphics interfaces. S o , " N u f f s a i d , " s o m e h u r r i e d h e r o s a i d . Let's g e t t o it.
3 — O b j e c t s for W i n d o w s
Why Does the World Make So Much Sense? A c t u a l l y , t h i s q u e s t i o n is m o r e t h a n a little d e b a t a b l e . Why d o e s T u r b o P a s c a l for Windows m a k e s o m u c h s e n s e ? T h a t q u e s t i o n I t a c k l e in t h e n e x t hundred or so pages, beginning with g e n e r a l c o n c e p t s s u c h as e v e n t s , m e s s a g e s , a n d o b j e c t s . I b e g i n w i t h O O P , w o r k i n g t o w a r d Windows a n d t h e O b j e c t W i n d o w s c o n n e c t i o n . T u r b o Pascal for Windows is a n o t h e r a m a z i n g d e v e l o p m e n t in t h e e v o l u t i o n o f T u r b o P a s c a l . It is the d y n a m i t e s o l u t i o n t o w h a t w a s a l m o s t a n o v e r w h e l m i n g p r o g r a m m i n g p r o b l e m : how t o m a k e s e n s e o f M i c r o s o f t Windows' development.
The Tao of Objects C h i n e s e p h i l o s o p h e r s in a n c i e n t times e x p r e s s e d a b e l i e f in a u n i f y i n g reality that they c a l l e d the T a o . T o these p h i l o s o p h e r s , the T a o w a s a w a y o f u n d e r s t a n d i n g that the w o r l d w a s n o t a static entity, b u t a d y n a m i c , everc h a n g i n g p r o c e s s . T h e o b j e c t s that m a k e u p the w o r l d reflect the d y n a m i c p r o c e s s , b e c a u s e they are e v e r - c h a n g i n g . I u s e the p h r a s e "the T a o o f o b j e c t s " to e x p r e s s the d y n a m i c n a t u r e o f p r o g r a m m i n g p r o b l e m s a n d the m o d e l i n g o f s y s t e m s b a s e d o n "the real w o r l d . " B e c a u s e the w o r l d is e v o l v i n g , y o u r p r o g r a m m i n g m o d e l s o f the w o r l d m u s t e v o l v e as w e l l . I n his introduction to m y b o o k , The Tao of Objects, Bruce Eckel wrote: O n e difficulty p e o p l e have w h e n l e a r n i n g o b j e c t - o r i e n t e d p r o g r a m m i n g is f i n d i n g a w a y t o t h i n k a b o u t it. O f t e n y o u hear s u c h u n h e l p f u l t h i n g s as "It's e a s i e r for s o m e o n e w h o d o e s n ' t k n o w how t o p r o g r a m t o l e a r n O O P t h a n for a n e x p e r i e n c e d p r o g r a m m e r " o r "You need to unlearn what you know." My personal experience hasn't s u p p o r t e d t h i s . A l t h o u g h t h i n k i n g a b o u t o b j e c t s is d i f f e r e n t f r o m t h i n k i n g a b o u t p r o c e d u r a l p r o g r a m m i n g , it's d i f f e r e n t b e c a u s e y o u ' r e s t e p p i n g into a l a r g e r w o r l d , n o t b e c a u s e e v e r y t h i n g y o u k n o w is w r o n g . T h i s is e s p e c i a l l y t r u e w i t h hybrid l a n g u a g e s like C + + a n d T u r b o P a s c a l ; y o u ' l l s e e that t h e ability t o c r e a t e userd e f i n e d [ o b j e c t ] t y p e s isn't s u c h a radical idea, s i n c e y o u u s e d a t a t y p e s s o m u c h that y o u u s u a l l y d o n ' t e v e n t h i n k a b o u t t h e m . H o w e v e r , it d o e s t e n d t o highlight t h e limitations of t h e built-in t y p e s a n d (to m y m i n d ) t h e relative p r i m i t i v e n e s s o f w h a t w e ' v e b e e n u s i n g as p r o g r a m m i n g l a n g u a g e s s o far. O n c e y o u b e g i n u s i n g a n o b j e c t - o r i e n t e d l a n g u a g e , it's hard t o g o b a c k . I c o u l d n ' t a g r e e m o r e w i t h B r u c e . If y o u start w i t h w h a t y o u k n o w (I a s s u m e T u r b o P a s c a l ) , a n d a d d k n o w l e d g e o f O O P a n d k n o w l e d g e o f Windows, y o u ' l l have Windows p r o g r a m m i n g , T u r b o P a s c a l style, d o w n . Y o u c a n start w i t h O O P .
81
82
Part I — W o r k i n g w i t h T P W
O b j e c t s a n d actions c o m p o s e our world. Objects (the n o u n s o f the g r a m m a t i c a l w o r l d ) have attributes o r characteristics. A c t i o n s ( t h e verbs o f t h e grammatical world) express behaviors. A s p r u c e s w a y s . S n o w falls. H e r e y e s o p e n . T h e a p p l i c a t i o n w i n d o w s e n d s o r receives a m e s s a g e . A u s e r responds t o a m e n u . Y o u c l i c k a m o u s e , a n d so on. I n a p r o g r a m , d a t a are t h e characteristics o f a n o b j e c t . O p e r a t i o n s are its b e h a v i o r s . A n o b j e c t - o r i e n t e d p r o g r a m m i n g l a n g u a g e like T u r b o Pascal e n c a p s u l a t e s a n o b j e c t ' s characteristics a n d its b e h a v i o r s w i t h i n a s i n g l e b l o c k o f s o u r c e c o d e . O p e r a t i o n s a n d b e h a v i o r s are in o n e p l a c e , w h i c h m a k e s g o o d s e n s e . It's c o n v e n i e n t a n d safer t h a n having t h e m s p r e a d a b o u t . P u t t i n g t o g e t h e r d a t a a n d t h e o p e r a t i o n s t o m a n i p u l a t e d a t a is encapsulation. U s i n g O O P t e c h n i q u e s , p r o g r a m m e r s c a n create their o w n o b j e c t t y p e s , w h i c h t h e c o m p i l e r treats just as it d o e s built-in t y p e s . Y o u b u i l d u p c o m p l e x t y p e s f r o m s i m p l e r t y p e s that share characteristics a n d b e h a v i o r s . T h i s d e s c r i p t i o n s h o u l d n ' t s o u n d all that n e w t o y o u . T u r b o Pascal p r o g r a m m e r s have b e e n c r e a t i n g n e w t y p e s all a l o n g — b y c o l l e c t i n g variables into records. O b j e c t s s i m p l y a d d t h e f u n c t i o n s a n d p r o c e d u r e s t o m a n i p u l a t e the data to the package. S o , n o t u n e x p e c t e d l y , a n o b j e c t t y p e l o o k s m u c h like its d a t a - o n l y c o u n t e r p a r t — a record in P a s c a l . It's just a little m o r e ; a record p l u s t h e f u n c t i o n s a n d p r o c e d u r e s ( w h i c h O O P calls m e t h o d s ) t o m a n i p u l a t e t h e d a t a fields. R e c a l l that y o u d e c l a r e a record
type recordl aRecord ID : Name: X,Y : end;
like this:
= aRecord; = record integer; string; integer;
D e f i n e a n o b j e c t like this:
type anObject = object ID : integer; X,Y : integer; procedure ManipulateX; procedure ManipulateY; end; A variable o f t y p e anObj ect l o o k s like this:
var ov: anObject;
3 — O b j e c t s for Windows
A p o i n t e r l o o k s l i k e this:
var op: "anObject; op = @ov; X a n d Y a r e d a t a fields. ManipulateX a n d ManipulateY a r e m e t h o d s f o r m a n i p u l a t i n g t h e d a t a fields, X a n d Y. T o a c c e s s m e m b e r s o f a n i n s t a n c e (a v a r i a b l e ) o f a n o b j e c t t y p e , y o u u s e t h e s a m e s e l e c t i o n o p e r a t o r s y o u u s e w i t h r e c o r d s — o r a With s t a t e m e n t :
ov.X := 256; op"ManipulateX;
{ procedure call! }
With ov do begin X:= 256; Y:= 128; ManipulateX; ManipulateY; end; A n o b j e c t t y p e c o n s i s t s o f e v e r y t h i n g that d e s c r i b e s it. Its characteristics a n d behaviors are together in o n e b l o c k o f c o d e . N o t i c e that y o u d o n ' t h a v e t o p a s s X a n d Y t o t h e m e t h o d s ManipulateX a n d ManipulateY. ManipulateX a n d ManipulateY a l r e a d y h a v e a c c e s s t o X a n d Y because they b o t h are p a c k a g e d in the same type. I n other w o r d s , they s h a r e a l o c a l s c o p e . E v e r y t h i n g i n a n o b j e c t t y p e (data fields a n d m e t h o d s ) is shared a n d thus k n o w n to everything else. F r o m a n o t h e r p e r s p e c t i v e , c o m b i n i n g d a t a a n d c o d e i n a n o b j e c t is a n e a t e x t e n s i o n o f Pascal u n i t s . P r o g r a m s c o n s i s t o f c o l l e c t i o n s o f u n i t s . U n i t s c o n t a i n d e f i n i t i o n s o f o b j e c t t y p e s , f u n c t i o n s , a n d v a r i a b l e s . S o , at o n e l e v e l , o b j e c t t y p e s s u g g e s t a w a y t o o r g a n i z e c o d e . T h e r e ' s m u c h m o r e t o it t h a n that: it's a m o r e powerful way of thinking about code. D i f f e r e n t o b j e c t s c a n s h a r e s o m e characteristics a n d b e h a v i o r s , w h i l e n o t s h a r i n g o t h e r s . S h a r e d characteristics a n d b e h a v i o r s c a n b e c o l l e c t e d i n a c o m m o n t y p e c a l l e d a base type. F o r e x a m p l e : m a n d o l i n s , g u i t a r s , d r u m s , b a n j o s , f i d d l e s , a n d flutes a r e all t y p e s o f m u s i c a l i n s t r u m e n t s . T h e y h a v e different specific characteristics, b u t e a c h has a w a y o f m a k i n g s o u n d a n d c a n be played. T h e base type, the musical instrument, encapsulates these c o m m o n c h a r a c t e r i s t i c s : it c r e a t e s s o u n d a n d it c a n b e p l a y e d . T h e act o f p l a y i n g t h e i n s t r u m e n t a n d t h e w a y t h e i n s t r u m e n t s o u n d s differ f r o m i n s t r u m e n t t o i n s t r u m e n t . Y o u p l u c k t h e strings o f a b a n j o w i t h y o u r f i n g e r s ; y o u b l o w air i n t o a flute. T h e v i b r a t i o n s o f strings c o m b i n e d w i t h w o o d c r e a t e s a g u i t a r s o u n d . T h e p r e s s u r e a n d v o l u m e o f air p r o d u c e d b y y o u r lips a n d l u n g s c o m b i n e w i t h w o o d o r m e t a l t o c r e a t e a flute s o u n d .
83
84
Part I — W o r k i n g w i t h T P W
I n t h e everyday w o r l d , y o u classify o b j e c t s into t y p e s a n d e x t e n d y o u r k n o w l e d g e b y a s s i g n i n g t h e attributes y o u k n o w (from p r e v i o u s o b j e c t t y p e s ) t o n e w o n e s . U s i n g O O P t e c h n i q u e s , y o u create a p p l i c a t i o n s in a similar manner, by creating base object types a n d deriving n e w object types from t h e m .
Inheritance E n c a p s u l a t i o n is t h e b e g i n n i n g , a n d there's m u c h m o r e t o O O P t h a n that. H o w d o y o u m o d i f y o r e x t e n d a n o b j e c t ' s f u n c t i o n a l i t y ? If y o u c a n help it, y o u d o n ' t g o in a n d m u c k a r o u n d t h e c o d e . T h i s c a n easily l e a d t o n e w b u g s , a n d y o u t o o o f t e n w i l l m e s s u p s o m e t h i n g that a l r e a d y w o r k s . A better p a t h , after y o u ' v e d e f i n e d a n e w b a s e t y p e , is t o b u i l d o n t h e b a s e t y p e u s i n g inheritance. When a n e w t y p e ( c a l l e d a derived type) inherits f r o m a b a s e t y p e , t h e n e w t y p e a u t o m a t i c a l l y receives all t h e characteristics a n d b e h a v i o r s o f t h e b a s e t y p e , w i t h o u t "lifting a finger." Y o u also c a n assemble a n e w type o f object from a g r o u p o f existing o b j e c t s . T h i s p r o c e s s is c a l l e d composition. A w o o d l a n d community, for e x a m p l e , is c o m p o s e d o f t r e e s , herbaceous plants, animals, a n d the microo r g a n i s m s that s u s t a i n t h e m . D e r i v a t i o n a n d c o m p o s i t i o n e n a b l e y o u t o reuse e x i s t i n g c o d e w i t h o u t introducing n e w bugs. Y o u c a n develop applications faster, m o r e efficiently, a n d m o r e clearly. I n a n important s e n s e , o b j e c t - o r i e n t e d p r o g r a m m i n g is a w a y t o b u i l d f a m i l y trees (or hierarchies) f o r d a t a s t r u c t u r e s . I n T u r b o P a s c a l ( u n l i k e in s o m e O O P l a n g u a g e s ) a n o b j e c t c a n have o n l y o n e immediate ancestor, o r a single inheritance ( s e e figure 3.2). ( A n o b j e c t c a n have a n y n u m b e r o f a n c e s t o r s , b u t o n l y o n e immediate ancestor.) Let's say that y o u ' v e c r e a t e d a b a s e t y p e :
base = object X,Y: integer; procedure ManipulateX; procedure ManipulateY; end; N o w y o u w a n t t o a d d s o m e s p e c i a l i z e d f u n c t i o n a l i t y t o it. T h e r e f o r e , y o u create a n e w t y p e f r o m this b a s e t y p e . Y o u w a n t t h e d e r i v e d t y p e t o b e identical to t h e base type except to extend t h e base by adding a m e t h o d called
RecalculateXandY. Y o u create t h e derived t y p e ' s characteristics b y s i m p l y inheriting characteristics f r o m t h e base t y p e .
derived = object (base) procedure RecalculateXandY; end;
the
3 — O b j e c t s for W i n d o w s
I nheritance
Object_1
(Base) Object_2
(derived from
Object_3
(derived from
Object_3 (derived from
Object_4
Figure
3 . 2 . Single
Obj_1)
Obj_2)
Obj_1)
(derived from Obj_1 )
inheritance.
B e c a u s e d e r i v e d (the n e w o b j e c t t y p e ) i n h e r i t s all t h e d a t a fields a n d m e t h o d s o f b a s e (its a n c e s t o r o b j e c t t y p e ) , y o u d o n ' t n e e d t o r e d e f i n e b a s e ' s d a t a fields a n d m e t h o d s . Y o u just tell t h e c o m p i l e r y o u w a n t t o d e r i v e a n e w t y p e from a base type—the line d e r i v e d = o b j e c t ( b a s e ) does the trick—and add the n e w method. N o w you can use M a n i p u l a t e X , M a n i p u l a t e Y , and R e c a l c u l a t e X a n d Y w i t h a n y i n s t a n c e (variable) o f t y p e d e r i v e d , just as t h o u g h all t h r e e m e t h o d s h a d b e e n defined in d e r i v e d : var d:
derived;
W i t h d do begin X:= 40; Y:= 32; ManipulateX; RecalculateXandY; ManipulateY; end; N o t i c e that y o u d o n ' t h a v e t o p a s s t h e v a r i a b l e s X a n d Y t o a n y o f d e r i v e d ' s m e t h o d s ; it i n h e r i t e d a c c e s s t o X a n d Y a l o n g w i t h b a s e ' s m e t h o d s .
85
86
Parti—Working with T P W
I n h e r i t a n c e lets y o u b u i l d c o m p l e x d a t a t y p e s w h e n y o u n e e d t o , w i t h o u t repeating a n y c o d e . A n e w o b j e c t t y p e s i m p l y inherits w h a t e v e r it n e e d s f r o m a n a n c e s t o r a n d ignores o r revises w h a t it d o e s n ' t . T h e d e r i v e d t y p e c a n u s e as m u c h o r as little o f its a n c e s t o r s ' c o d e as it w a n t s . T h e d e r i v e d t y p e c a n reimplement (or override) a n y m e t h o d it d e c i d e s t o . T h i s reimplementation of b a s e t y p e m e t h o d s in d e r i v e d t y p e s is f u n d a m e n t a l t o a n o t h e r o f O O P ' s k e y c o n c e p t s , p o l y m o r p h i s m , w h i c h I g e t t o in a m o m e n t . I n h e r i t a n c e is u s e f u l f o r t w o important reasons. T h e first is a s i m p l e o n e : w h e n y o u ' r e g i v e n a w o r k i n g o b j e c t t y p e that d o e s n ' t d o e x a c t l y w h a t y o u w a n t (let's say that y o u r n e i g h b o r in t h e n e x t c u b i c l e handed it t o y o u ) , y o u c a n create a n e w o b j e c t t y p e f r o m t h e o l d o n e w i t h inheritance, a d d i n g characteristics o r b e h a v i o r s t o suit yourself. T h i s c a p a b i l i t y e n a b l e s y o u t o p r o g r a m q u i c k l y , w h i l e isolating t h e e x i s t i n g c o d e ( w h i c h w o r k s — y o u r n e i g h b o r is trustworthy, right?) f r o m y o u r n e w , e x p e r i m e n t a l c o d e (which m a y n o t ) . T h e s e c o n d u s e o f inheritance involves t h e b e h a v i o r o f d e r i v e d o b j e c t t y p e s that d e s c e n d f r o m t h e s a m e b a s e . When y o u learn t o handle a k a y a k , y o u learn s o m e t h i n g that c a n b e a p p l i e d t o a b i c y c l e o r p i c k u p t r u c k as w e l l . When y o u steer a n y o f t h e s e v e h i c l e s , y o u d o n ' t have t o t h i n k a b o u t w h i c h t y p e o f v e h i c l e it is—you steer a n d t h e v e h i c l e m o v e s . B e c a u s e this is t r u e in t h e w o r l d , w h y s h o u l d n ' t it b e t r u e w i t h p r o g r a m m i n g as w e l l ?
Polymorphism U s i n g p o l y m o r p h i s m , y o u c a n represent this v e h i c u l a r s y s t e m w i t h a b a s e o b j e c t t y p e c a l l e d vehicle a n d d e r i v e d o b j e c t t y p e s c a l l e d kayak, bicycle, a n d pickup. T h e b a s e t y p e c o n t a i n s a generic steer m e t h o d :
vehicle = object Afield : integer; procedure Steer; virtual; end; a n d e a c h d e r i v e d t y p e c o n t a i n s a reimplemented
Steer m e t h o d :
bicycle = object Afield : integer; procedure Steer; virtual; end; A n y v e h i c l e c a n b e s t e e r e d ( b e c a u s e vehicle c o n t a i n s a steer m e t h o d ) , b u t e a c h v e h i c l e c a n steer itself differently (by o v e r r i d i n g t h e v e h i c l e steer m e t h o d ) . B e c a u s e vehicle c a n respond t o a m e s s a g e c a l l e d steer, a n y t y p e d e r i v e d f r o m vehicle a l s o c a n a c c e p t that m e s s a g e .
3 — O b j e c t s for W i n d o w s
T h u s , bicycles, kayaks, a n d pickups c a n b e steered because they're v e h i c l e s , b u t t h e m e t h o d e a c h s p e c i f i c t y p e u s e s w h e n vehicle g e t s t h e steer m e s s a g e c a n differ. I n a n u t s h e l l this is p o l y m o r p h i s m . Y o u tell t h e v e h i c l e t o s t e e r itself ( s e n d it a steer m e s s a g e ) , a n d t h e v e h i c l e f i g u r e s o u t h o w t o carry out the message. W h y is p o l y m o r p h i s m s o u s e f u l ? B e c a u s e this s y s t e m ( w h i c h u s e s p o l y m o r p h i s m ) w o n ' t h a v e t o r e l e a r n e v e r y t h i n g e a c h t i m e it e n c o u n t e r s a n e w t y p e o f vehicle. This system applies existing k n o w l e d g e to n e w situations. A n objecto r i e n t e d p r o g r a m that steers v e h i c l e s d o e s n ' t n e e d t o b e r e w r i t t e n just b e c a u s e it n e e d s t o h a n d l e a n e w t y p e o f v e h i c l e . It a l r e a d y k n o w s that a n y v e h i c l e c a n r e s p o n d t o t h e steer m e s s a g e a n d act a c c o r d i n g l y ( s e e f i g u r e 3 3 ) .
Polymorphism Steer
message
Vehicle
(object)
Bicycle (derived from
Vehicle)
Pickup truck (derived from Kayak
One
steer m e s s a g e
produces
steer b e h a v i o r in e a c h
Figure
33.
(derived from
Vehicle)
Vehicle)
specific
vehicle.
Polymorphism.
P o l y m o r p h i s m is i m p o r t a n t b e c a u s e p r o g r a m m e r s c a n ' t k n o w e v e r y t h i n g about a p r o g r a m o r the p r o b l e m a p r o g r a m n e e d s t o solve while d e v e l o p i n g the p r o g r a m . Programs s h o u l d b e able to c h a n g e their behaviors in response t o n e w information. T e x t e d i t o r s ( o r w o r d p r o c e s s o r s ) d i d n ' t k n o w a b o u t f o n t s a n d styles w h e n t h e y w e r e first c r e a t e d ; n e w f e a t u r e s h a d t o b e a d d e d as u s e r s b e c a m e m o r e s o p h i s t i c a t e d a n d t h e i r n e e d s e v o l v e d . T h e n e e d for p r o g r a m s t o c h a n g e a n d e v o l v e h a s b e e n a n e m e s i s o f s o f t w a r e d e v e l o p m e n t s i n c e t h e early d a y s . C h a n g e is b o t h e x p e n s i v e a n d n e c e s s a r y , a n d t h e inability t o c h a n g e q u i c k l y often leads to programming obsolescence.
87
88
Parti—Working with T P W
E v o l u t i o n a n d c h a n g e m u s t b e a n integral part o f a p r o g r a m . N e w information m i g h t c o m e f r o m u n d e r s t a n d i n g a s y s t e m in a n e w w a y o r b e c a u s e t h e p r o b l e m c h a n g e s in t h e real w o r l d . Either w a y , c h a n g e is inevitable. P o l y m o r p h i s m lets y o u create e x t e n s i b l e p r o g r a m s . B e h a v i o r s s u c h as s t e e r i n g a v e h i c l e o r m a k i n g m u s i c a l s o u n d s c a n b e c o m m o n t o a g r o u p o f t y p e s b u t implemented differently f o r e a c h . T h e c o n c e p t is t h e s a m e , b u t t h e implementation details m i g h t differ. U s i n g p o l y m o r p h i s m , y o u c a n create a s y s t e m w h i c h k n o w s that m u s i c a l instruments c a n b e p l a y e d , b u t n o t how a particular instrument is p l a y e d . S p e c i f i c p l a y i n g details c a n c o m e later. T h e s y s t e m is e x t e n s i b l e b e c a u s e y o u c a n a d d n e w t y p e s o f instruments (or v e h i c l e s , o r whatever) a n d n e w w a y s o f p l a y i n g w i t h o u t redesigning the program. T h e capability t o create o b j e c t t y p e s is a p o w e r f u l o n e indeed, o n e that fits in w e l l w i t h how p e o p l e v i e w t h e w o r l d . I f y o u t h i n k in t e r m s o f t y p e s , representing a real-world s y s t e m as a n a p p l i c a t i o n (or p r o g r a m ) c o m p o s e d o f base a n d derived t y p e s is a n a t u r a l p r o c e s s . I d e a l l y , t h e m o d e l o f a s y s t e m in a p r o g r a m is a direct m a p p i n g o f a s y s t e m f r o m t h e w o r l d . T h e r e f o r e , as t h e s y s t e m in t h e w o r l d c h a n g e s , it is easier t o c h a n g e t h e m o d e l in t h e c o m p u t e r .
Messages C o n v e n t i o n a l p r o g r a m m i n g s y s t e m s typically v i e w a p r o g r a m as a c o l l e c t i o n o f f u n c t i o n s a n d p r o c e d u r e s . T h e s e f u n c t i o n s a n d p r o c e d u r e s are t h e active c o m p o n e n t s o f t h e p r o g r a m ; d a t a are p a s s i v e . When y o u d e c l a r e d a t a g l o b a l l y , a n y f u n c t i o n o r p r o c e d u r e c a n a c c e s s t h e m , t h u s p l a c i n g t h e d a t a at a n y f u n c t i o n ' s o r p r o c e d u r e ' s m e r c y . T h e l i k e l i h o o d o f incorrect d a t a m a n i p u l a t i o n is high. When y o u d e c l a r e d a t a l o c a l l y (in a p r o c e d u r e ) , o n l y that p r o c e d u r e c a n g e t at t h e d a t a . T h e d a t a are safer, b u t a little t o o restricted f o r m o s t tastes. S o m e flexibility u s u a l l y is n e e d e d , a n in-between s o l u t i o n , in w h i c h d a t a c a n b e a c c e s s e d b y s o m e restricted n u m b e r o f d e f i n e d f u n c t i o n s a n d p r o c e d u r e s . I n object-oriented programming, a m e t h o d (an object's functions a n d proced u r e s ) is p r o g r a m m e d t o m a n i p u l a t e o n l y certain d a t a , a n d d a t a a c c e p t m a n i p u l a t i o n b y o n l y certain m e t h o d s . M a n i p u l a t i o n is handled t h r o u g h t h e s e n d i n g a n d receiving o f m e s s a g e s ( s e e figure 3.4). I n a p r o c e d u r a l p r o g r a m , a p r o g r a m ' s flow o f c o n t r o l is d e t e r m i n e d b y t h e o r d e r i n g o f p r o c e d u r e s a n d c o n t r o l m e c h a n i s m s s u c h as if, w h i l e , s w i t c h , a n d s o o n . T h i s o r d e r i n g implies that y o u k n o w how t o structure t h e entire p r o g r a m w h e n y o u create t h e p r o g r a m . I n p r o g r a m s d e s i g n e d to " c a p t u r e " t h e e s s e n c e o f a d y n a m i c w o r l d , this a s s u m p t i o n is unrealistic a n d c u m b e r s o m e . T h e w o r l d is e v o l v i n g , a n d o u r ideas a n d m o d e l s o f t h e w o r l d m u s t a d a p t t o survive. A b e t t e r alternative c a p t u r e s t h e d e s i g n flow in t e r m s o f t h e l o g i c a l relationships a m o n g objects.
3 — O b j e c t s for Windows
Objects encapsulate
data and
89
methods
Object Data_field1 Data_field2 Data_field3
messages
Methodi
s e n t to O b j e c t
methods
Method2
Data_field4
Methods access data
Figure
3 A.
fields.
Messages.
O O P c a p t u r e s t h e s e l o g i c a l relationships in o b j e c t s , a n d t h e flow o f c o n t r o l in a n o b j e c t - o r i e n t e d a p p l i c a t i o n is d e t e r m i n e d b y t h e m e s s a g e s s e n t t o a n d received f r o m o b j e c t s . When y o u s e n d a m e s s a g e , y o u clarify t h e c o m m u n i c a t i o n a m o n g t h e c o m p o n e n t s o f a p r o g r a m . O b j e c t s respond t o t h e m e s s a g e s sent t o t h e m a n d s e n d messages t o other objects. M e s s a g e s , n o t d a t a , m o v e t h r o u g h t h e s y s t e m . R a t h e r t h a n "invoke a function o n s o m e data" (the procedural approach), y o u "send a message t o a n object" (the object-oriented approach). T o s e n d a message t o a n object, y o u specify t h e object a n d t h e m e t h o d y o u want to invoke. S u p p o s e that y o u ' v e d e c l a r e d t h e f o l l o w i n g p o i n t t y p e : Point = object X : integer; Y : integer; constructor Init(InitX, InitY
: integer);
function IsVisible: integer; { is the point on or off? Return State. } end; P o i n t ' s characteristics are its l o c a t i o n o n - s c r e e n ( X a n d Y c o o r d i n a t e s ) . Its b e h a v i o r s are t o c o n s t r u c t itself a n d t o report (if it receives a m e s s a g e requesting this i n f o r m a t i o n ) w h e t h e r it's v i s i b l e .
90
Part I — W o r k i n g w i t h T P W
Y o u d e c l a r e a n d initialize
a n instance
o f t h e o b j e c t in a t w o - s t e p p r o c e s s
like t h i s :
var SomePoint : Point; begin SomePoint.Init(23,28); end; T h e n y o u c a n a s k SomePoint w h e t h e r it's visible b y s e n d i n g it a m e s s a g e :
var Visible : integer; begin Visible := SomePoint.IsVisible; end; S e n d i n g a message m e a n s calling a n object's m e t h o d , w h i c h manipulates or interprets t h e type's characteristics.
Static and Dynamic Binding E a c h o b j e c t t a l k e d a b o u t s o far u s e s statically b o u n d m e t h o d s . When a m e t h o d is statically b o u n d (also referred t o as early binding) t h e c o m p i l e r allocates a n d resolves all references t o t h e m e t h o d at c o m p i l e - t i m e . When y o u c a l l a statically b o u n d m e t h o d , t h e c o m p i l e r determines exactly w h i c h m e t h o d t o send a m e s s a g e t o at c o m p i l e - t i m e — a n efficient w a y t o s e a r c h f o r m e t h o d s u n l e s s y o u want to use polymorphism. With p o l y m o r p h i s m , y o u w a n t t o s e n d a m e s s a g e t o a n o b j e c t a n d let t h e object determine w h i c h m e t h o d to u s e . S o , you're asking t h e compiler to resolve s o m e references at run-time; this p r o c e s s is c a l l e d late, o r dynamic, binding. T o resolve references t o m e t h o d s at run-time, y o u c r e a t e virtual m e t h o d s . T o c r e a t e a virtual m e t h o d , a d d t h e k e y w o r d virtual t o t h e m e t h o d i n t h e b a s e o b j e c t t y p e a n d i n c l u d e a s p e c i a l p r o c e d u r e c a l l e d a const ructor i n t h e o b j e c t . After a m e t h o d is d e c l a r e d virtual i n a b a s e t y p e , this m e t h o d m u s t b e d e c l a r e d virtual i n all i n h e r i t e d t y p e s . T o m a k e AddXandY a virtual m e t h o d , f o r e x a m p l e , y o u d e c l a r e it as virtual at its earliest a n d i n all s u b s e q u e n t declarations:
3 — O b j e c t s for Windows
derived = object(base) constructor Init; procedure AddXandY; virtual; end; an0bject2 = object(derived) constructor Init; procedure AddXandY; virtual; end; Virtual m e t h o d s e n a b l e d e r i v e d t y p e s t o have their o w n distinct v e r s i o n s o f a b a s e t y p e m e t h o d . Y o u u s e this t h o r n y ( b u t q u i t e p o w e r f u l ) a s p e c t o f o b j e c t oriented programming again a n d again.
Dynamic Style M o s t folks w h o discuss object-oriented p r o g r a m m i n g emphasize o n l y three o f its a s p e c t s : e n c a p s u l a t i o n , inheritance, a n d polymorphism. T h e T a o of objects, as I've e x p l o r e d it, m u s t a l s o incorporate a n o t h e r important c o n c e p t : d y n a m i c style o r t h e u s e o f d y n a m i c o b j e c t s . A l t h o u g h y o u c a n c r e a te a n instance o f a p o l y m o r p h i c o b j e c t o n t h e s t a c k ( w i t h o u t u s i n g p o i n t e r s ) , it's c o n v e n i e n t a n d helpful t o cre a t e a n instance at run-time b y a l l o c a t i n g it o n t h e heap, u s i n g a p o i n t e r . T u r b o Pascal m a n i p u l a t e s d y n a m i c variables easily a n d efficiently t h r o u g h t h e New a n d Dispose p r o c e d u r e s in T u r b o P a s c a l . T o create a n instance o f a n o b j e c t t y p e , p a s s New a p o i n t e r t o t h e instance of the type to b e created: var ShapePointer
: "Shape;
New(ShapePointer); A s w i t h records, New a l l o c a t e s e n o u g h s p a c e o n t h e heap f o r a n instance o f t h e p o i n t e r ' s b a s e t y p e , a n d stores that s p a c e ' s a d d r e s s (in t h e p o i n t e r ) . When t h e d y n a m i c variable c o n t a i n s a n y virtual m e t h o d s , y o u m u s t u s e a c o n s t r u c tor t o initialize t h e t y p e b e f o r e s e n d i n g a n y m e s s a g e s t o t h e o b j e c t . Y o u c a n u s e New t o a l l o c a t e s p a c e a n d initialize t h e instance o f t h e t y p e in o n e s t e p , b e c a u s e New c a n t a k e t h e c o n s t r u c t o r (Init) as a p a r a m e t e r : var EllipsePtr
: "Ellipse;
New(EllipsePtr,Init(140,75,50));
{ points and radius }
91
92
Part I — W o r k i n g w i t h T P W
D y n a m i c variables are u s e f u l b e c a u s e y o u c a n a d d a n y n u m b e r o f ins t a n c e s o f t h e m at run-time w i t h o u t k n o w i n g t h e e x a c t n u m b e r o f instances at compile-time. B y d e l a y i n g s y s t e m - d e t e r m i n i n g d e c i s i o n s u n t i l run-time, y o u a l l o w c o d e to b e d i s c o n n e c t e d from a type's specific details, a n d t h e system b e c o m e s m o r e flexible. A w o r k i n g s y s t e m c a n b e m o d i f i e d , a d j u s t e d , a n d s o o n , l o n g after it's " f i n i s h e d . " I n s t a n c e s o f n e w t y p e s c a n b e a d d e d t o t h e s y s t e m easily w i t h o u t d i s r u p t i n g it. M a n y l a n g u a g e s c a n easily handle s m a l l - t o m e d i u m - s i z e p r o g r a m s , b u t t h e real p r o b l e m s b e g i n w h e n t h e p r o g r a m s g e t b i g . Windows a p p l i c a t i o n s are b i g b y d e f a u l t . T u r b o Pascal (with e x t e n s i o n s f o r s e p a r a t e c o m p i l a t i o n ) e n a b l e s y o u t o p r o g r a m "in t h e l a r g e . " T u r b o P a s c a l f o r Windows allows y o u to e n c a p s u l a t e into a n o b j e c t t h e d a t a a n d o p e r a t i o n s n e e d e d t o handle a w i n d o w .
Extended Views It's helpful t o t h i n k o f a n o b j e c t as a little p r o g r a m . A n o b j e c t has its o w n d a t a (like a p r o g r a m ) a n d a n interface f o r s e n d i n g a n d receiving m e s s a g e s . Y o u u s e p r o g r a m s s u c h as a text e d i t o r ( a n o b j e c t ) , w h i c h m a n a g e s its o w n d a t a (characters a n d w o r d s ) . U s i n g a k e y b o a r d o r a m o u s e , y o u s e n d t h e text e d i t o r m e s s a g e s s u c h as " a p p e n d a s p e c i f i c character" o r " m o v e b a c k t o t h e p r e v i o u s word." E a c h o b j e c t o f y o u r p r o g r a m handles a task. S o , a n o b j e c t - o r i e n t e d p r o g r a m is similar t o a m u l t i t a s k i n g e n v i r o n m e n t . Y o u m i g h t u s e a c o m m u n i c a t i o n p r o g r a m t o s e n d a n d receive files ( d a t a ) , a d a t a b a s e t o store it, a s p r e a d s h e e t t o a n a l y z e it, a n d a d e s k t o p p u b l i s h i n g s y s t e m t o f o r m a t it. A l t h o u g h y o u c a n (in theory at least) write s p r e a d s h e e t s a n d d a t a b a s e s y s t e m s yourself, y o u d o n ' t have t o ( n o r d o y o u u s u a l l y w a n t t o ! ) ; y o u save t i m e a n d effort b y u s i n g p r o g r a m s s o m e o n e e l s e has w r i t t e n . When y o u request s o m e d a t a o r a c t i o n (a report o r a recalculation by a spreadsheet, for e x a m p l e ) y o u probably d o n ' t want to k n o w t h e specifics o f how t h e s p r e a d s h e e t handled t h e m a t h . Y o u w a n t t h e results. Creating p r o g r a m s o u t o f o b j e c t s w o r k s similarly. I n effect, y o u "run" o b j e c t s (just as y o u "run" p r o g r a m s ) that m a n i p u l a t e their d a t a . Y o u m a y write t h e c o d e f o r t h e s e o b j e c t s or y o u m a y derive y o u r o b j e c t s f r o m s o m e o n e e l s e ' s . A n o b j e c t - o r i e n t e d p r o g r a m saves t i m e a n d effort b y e n a b l i n g y o u t o reuse e x i s t i n g o b j e c t s . O b j e c t W i n d o w s is t h e library o f e x i s t i n g o b j e c t s y o u u s e t o g e t t o Windows p r o g r a m m i n g . A l l t h e o b j e c t s y o u n e e d t o g e t started are c o d e d f o r y o u . T h e B a s i c l n t e r f a c e in C h a p t e r 4, " I n h e r i t i n g a n I n t e r f a c e , " u s e s ( a n d e x t e n d s ) t h e s e o b j e c t s . Y o u , in t u r n , u s e as m u c h o f t h e B a s i c l n t e r f a c e as y o u w a n t a n d e x t e n d it f o r y o u r o w n p u r p o s e s . Y o u c o m m u n i c a t e with objects by sending t h e m messages. A program, t h e n , c o n s i s t s o f o b j e c t s a n d t h e m e s s a g e s y o u s e n d t h e m (see figure 3 5 ) .
3 — O b j e c t s for Windows
T h i s v i e w is c o n s i s t e n t w i t h h o w y o u s h o u l d think about a Windows p r o g r a m . E a c h application (or p r o g r a m ) running i n a Windows w i n d o w is an o b j e c t that s e n d s and receives m e s s a g e s . When y o u w a n t a task d o n e , y o u s e n d a m e s s a g e to an application w i n d o w (an o b j e c t ) , and it c o m p l e t e s the task.
Windows events
Keyboard Mouse
Message Dispatcher (USER.EXE)
application message
Application window
Windows message
Windows
application
message
message
Appli cation window
Figure
3-5. Objects and messages.
About Microsoft Windows M i c r o s o f t Windows h a s b e c o m e the g r a p h i c a l u s e r i n t e r f a c e ( o r G U I ) o f c h o i c e for a majority o f P C u s e r s . C e r t a i n l y , i n the n e x t f e w y e a r s , y o u s h o u l d e x p e c t an e x p l o s i o n o f Windows u s e r s and p r o g r a m m e r s . Windows is w o n d e r f u l , p o w e r f u l , and c o m p l e x , b u t it d o e s n ' t h a v e e v e r y t h i n g yet. Its application l i n e u p still h a s m a n y p o s i t i o n s to fill. A n y p r o g r a m m e r c a n b e n e f i t b y adding Windows skills to h e r tool kit. Windows runs i n g r a p h i c s m o d e o n IBM P C s and c o m p a t i b l e s . Windows is an i n t e r f a c e , n o t an o p e r a t i n g s y s t e m , s o it d o e s n ' t replace D O S ; i n s t e a d it w o r k s w i t h it. F o r e x a m p l e , Windows utilizes D O S for file I/O (see figure 3.6).
93
94
Parti—Working with TPW
DOS + Windows
I A p p l i c a t i o n " ! | A p p l i c a t i o n || A p p l i c a t i o n !
Win dows
DOS
Memory
Files D O S
Figure
3-6. DOS plus
h a n d l e s file I/O; W i n d o w s ,
the
rest.
Windows.
T h e r e are m a n y e x c e l l e n t r e a s o n s f o r u s i n g W i n d o w s : • B e c a u s e W i n d o w s offers a s t a n d a r d , c o n s i s t e n t u s e r i n t e r f a c e , u s e r s d o not have to learn n e w cues a n d keystrokes to get u p to s p e e d with n e w applications. T h u s , they can r u n m a n y otherwise dissimilar applicat i o n s e a s i e r b e c a u s e t h e r e ' s less t o l e a r n . • W i n d o w s enables y o u to write device-independent applications. Y o u w r i t e g e n e r i c c o d e that s o l v e s t h e p r o b l e m , a n d W i n d o w s t a k e s c a r e o f r u n n i n g the application with various displays, printing to different kinds of printers, and so o n . • W i n d o w s a l l o w s a p p l i c a t i o n s t o talk t o e a c h o t h e r . N o t o n l y c a n y o u r applications send a n d receive messages to objects in themselves, but they also can s e n d messages to a n d receive t h e m from other applicat i o n s you didn't even write. Y o u r a p p l i c a t i o n c a n t a p i n t o p r o g r a m s it didn't even k n o w about w h e n the programs were written. • W i n d o w s allows m o r e than o n e application and m o r e than o n e i n s t a n c e o f a n a p p l i c a t i o n t o r u n s i m u l t a n e o u s l y . Note: M o r e t h a n o n e a p p l i c a t i o n is n o t u s i n g t h e C P U at t h e s a m e t i m e a l t h o u g h t h e y a p p e a r t o b e r u n n i n g s i m u l t a n e o u s l y ; it's a b e a u t i f u l W i n d o w s i l l u s i o n . • W i n d o w s e n a b l e s a p p l i c a t i o n s t o s h a r e m e m o r y (at least i n a p p e a r ance) by sharing c o d e .
3 — O b j e c t s for W i n d o w s
O n the d o w n side: • W i n d o w s r e q u i r e s a m o r e p o w e r f u l c o m p u t e r , m o r e m e m o r y , a faster C P U , and a better graphics adapter. • Y o u , the programmer, must learn y o u r way a r o u n d an event-driven architecture and learn h o w to c o m m u n i c a t e with the W i n d o w s m a n a g e m e n t facilities. Y o u h a v e a c c e s s t o a b e a u t i f u l a n d p o w e r f u l interf a c e , b u t t o really u s e it, y o u m u s t u n d e r s t a n d its l a n g u a g e . C a n d C + + p r o g r a m m e r s g e n e r a l l y still m u s t l e a r n h u n d r e d s a n d h u n d r e d s o f n e w f u n c t i o n calls t o m a k e t h e i r W i n d o w s p r o g r a m s s h i n e . T u r b o Pascal for W i n d o w s f o l k s c a n u s e O b j e c t W i n d o w s a n d t a k e h u n d r e d s o f shortcuts.
Windows Structure T h e functionality of W i n d o w s resides in W i n d o w s ' Application P r o g r a m m i n g I n t e r f a c e (or A P I ) , c o n t a i n e d i n t h r e e e x t e r n a l library m o d u l e s . T h e s e m o d u l e s are part o f t h e retail v e r s i o n o f W i n d o w s . T h u s , y o u r a p p l i c a t i o n s d o n o t c r e a t e W i n d o w s f u n c t i o n a l i t y , t h e y s i m p l y t a p i n t o it. W h e n y o u w r i t e a W i n d o w s a p p l i c a t i o n u s i n g T u r b o P a s c a l for W i n d o w s , y o u r a p p l i c a t i o n interacts w i t h ( a n d u s e s ) t h e m o d u l e s •
KERNEL.EXE
• GDI. EXE •
USER.EXE
behind the scenes. K E R N E L . E X E handles m e m o r y and resource management, scheduling, a n d interaction with D O S . G D I . E X E displays graphics o n the screen and printer. U S E R . E X E handles w i n d o w m a n a g e m e n t , user input, and c o m m u n i c a t i o n s . Y o u d o n ' t n e e d t o t h i n k o f t h e s e m o d u l e s as s e p a r a t e e n t i t i e s w h e n y o u write y o u r applications. F r o m y o u r application's perspective, they're together—just Windows. Although a complete W i n d o w s application has the .EXE extension ( T P W . E X E , for e x a m p l e ) , t h e . E X E isn't a t y p i c a l D O S . E X E file. B e c a u s e a Windows-compatible c o m p i l e r attaches s o m e special information to the . E X E file, W i n d o w s c a n r e c o g n i z e a n d r u n it. A n a p p l i c a t i o n d e s i g n e d t o r u n i n W i n d o w s won't run in D O S without Windows' support, but a D O S application might run in W i n d o w s . In addition to the c o d e the compiler attached to your .EXE (remember: y o u d o n ' t h a v e t o w o r r y a b o u t i t ) , e v e n t h e s i m p l e s t a p p l i c a t i o n y o u w r i t e for Windows must meet some other minimal requirements. The application must at least
95
96
Parti—Working with T P W
1. C r e a t e a m a i n w i n d o w . 2. B e a b l e t o c o m m u n i c a t e w i t h
Windows.
3. C l o s e t h e w i n d o w . 4. R e m o v e t h e w i n d o w w h e n it's n o l o n g e r n e e d e d . B e c a u s e T u r b o P a s c a l f o r Windows is Windows-compatible, even without t h e O b j e c t W i n d o w s library, y o u c a n w r i t e a Windows-compatible application without ObjectWindows' support. T o w r i t e t h e a p p l i c a t i o n , y o u m u s t h a n d l e m a n y details that O b j e c t W i n d o w s usually handles for y o u . I n general, y o u d o not want to bypass ObjectWindows, b u t b e c a u s e y o u m i g h t , y o u s h o u l d t a k e a q u i c k l o o k at t h e p r o c e s s . If y o u n e v e r b y p a s s O b j e c t W i n d o w s , it h e l p s t o a p p r e c i a t e t h e w o r k O b j e c t W i n d o w s is d o i n g f o r y o u " u n d e r t h e t a b l e . " T h e c o d e is a b o u t 100 l i n e s l o n g (the e q u i v a l e n t C c o d e is a b o u t 8 0 ) . S e e t h e c o m p l e t e c o d e i n listing 3 . 1 . If y o u are u n f a m i l i a r w i t h t h e T u r b o P a s c a l f o r Windows I D E a n d are n o t s u r e h o w t o run a p r o g r a m , review t h e d i s c u s s i o n o f t h e I D E i n C h a p t e r 1, " G e t t i n g S t a r t e d . " Listing
3.1.
Creating
a window
without
ObjectWindows.
{ Basic Windows application written in Turbo Pascal without ObjectWindows } program Basics; { $R BASICS } uses WinTypes, WinProcs;
{ to use Windows API types } { to use API processes }
const AppName =
1
Basics';
const idm_About = 1 0 0 ;
{ function About is a frill } { but shows basic wm_processing
function About(Dialog: HWnd; Message, WParam: Word; LParam: Longint): Bool; export; begin About := True; case Message of { basic wm_ processing } wm_InitDialog: Exit;
3 — O b j e c t s for W i n d o w s
wm_Command: if (WParam = i d _ 0 k ) or (WParam = id_Cancel) then begin EndDialog(Dialog, 1); Exit; end; end; About := False; end; function WindowProc(Window: HWnd; Message, WParam: Word; LParam: Longint): Longint; export; var AboutProc: TFarProc; begin WindowProc := 0 ; { intercept messages } case Message of { message responses } wm_Command: if WParam = idm_About then begin AboutProc := MakeProcInstance(@About, HInstance); DialogBox(HInstance, 'AboutBox', Window, AboutProc); FreeProcInstance(AboutProc); Exit; end; wm_Destroy: { destroy window } begin PostQuitMessage(0); Exit; end; end; WindowProc := DefWindowProc(Window, Message, WParam, LParam); end; { create a main window } procedure WinMain; var Window: HWnd; { HWnd is a handle for a window } Message: TMsg; { TMsg is in WinTypes } const WindowClass: TWndClass = ( { register window class } style: 0 ; lpfnWndProc: @WindowProc; { default window info } cbClsExtra: 0 ; cbWndExtra: 0 ; continues
97
98
Listing
Parti—Working with T P W
3.1
continued
hlnstance: 0; hlcon: 0; hCursor: 0; hbrBackground: 0; IpszMenuName: AppName; IpszClassName: AppName); begin { handle multiple instances } if HPrevInst = 0 then begin WindowClass.hlnstance := Hlnstance; { specify icon, cursor, and so on } WindowClass.hlcon := Loadlcon(0, idi_Application); WindowClass.hCursor := LoadCursor(0, idc_Arrow); WindowClass.hbrBackground :=GetStockObject(white_Brush); if not RegisterClass(WindowClass) then Halt(255); end; Window := CreateWindow( { create main window } AppName, 'Basic Windows w/o ObjectWindows', ws_OverlappedWindow, { default window } cwJJseDefault, cwJJseDefault, cw_UseDefault, cwJJseDefault, 0, 0, Hlnstance, nil); ShowWindow(Window, CmdShow); UpdateWindow(Window); while GetMessage(Message, 0,
{ note the instance } { show the window } { update when necessary } 0, 0) do { run the message loop }
begin TranslateMessage(Message); DispatchMessage(Message); end; Halt(Message.wParam); end; begin WinMain; end.
{ create a main window }
3 — Objects for Windows
Figure 3 7 shows the w i n d o w created by this code.
Figure
3.7. The created
window.
Several "general" things happen to the application in this code: • It registers the w i n d o w class, in the code beginning WindowClass: TWndClass = ( • It creates a main w i n d o w in the code beginning Window := CreateWindow(....)) using stock or default attributes. • It shows the w i n d o w ShowWindow(Window, CmdShow);. • It sets u p a message loop to process W i n d o w s messages: while GetMessage(Message, 0, 0, 0) do begin TranslateMessage(Message); DispatchMessage(Message); end;. • The application halts ( Halt (Message .wParam);. • In the beginning it used a $R (resource) file uses $R BASICS. This directive makes the compiler link into a resource file. I discuss resources in Chapter 8. For now, if you do not have the Turbo Pascal for Windows Bible disk, just link in the GENERIC.RESfilethat came with your Turbo Pascal for Windows. The file worksfinefor this example. Note: If you are using the IDE, Turbo Pascal for W i n d o w s automatically links in any resources specified with $R.
99
100
Parti—Working with T P W
It m i g h t s u r p r i s e y o u that t h e c o d e i n listing 3 1 ( d e s p i t e its m a n y l i n e s ) is h i d i n g m o s t o f W i n d o w s ' c o m p l e x i t y . W h a t ' s h a p p e n i n g i n C r e a t e W i n d o w , for example? ( H o w d o y o u s h o w a window?) T h e equivalent ObjectWindows application, with ObjectWindows d o i n g m o s t o f t h e w o r k , r e q u i r e s 16 l i n e s ( s e e listing 3 . 2 ) .
Listing
3-2. Creating
a window
with
Ob j ectWindows.
program BasicObjectWindowsAppl; { derive an application window using Object windows }
uses WObjects, WinTypes, WinProcs; { All Object Windows programs use these units; actually, this program compiles using WObjects alone } type { Derive an application object from TApplication } { you must initialize a new main window or you get a nil window } App1 = object(TApplication) procedure InitMainWindow; virtual; end; { Construct Appl's MainWindow object } procedure App1.InitMainWindow; begin { window name here } { new gets a pointer to a TWindow } MainWindow := New(PWindow, Init(nil, 'Application 1')); end; { Declare an instance of type App1 } var Instancel: App1; { Run Instancel } begin
3—Objects for Windows
Instancel.Init('App1'); Instancel.Run; Instancel.Done; end.
{ init application instance } { message loop } { clean up }
ObjectWindows gains m a n y lines for you, but more important, it is encapsulating information in objects you do not need to understand in detail. Face it, you can retain only so m u c h information in your brain for quick recall, so w h y not be spared a few details? Save yourself for the beans and potatoes of your applications.
Why OOP and Windows Object-oriented p r o g r a m m i n g (OOP) techniques hide program complexity in objects. Object-oriented libraries such as ObjectWindows package these objects. Specifically, ObjectWindows conceals the complexity of the Windows Application P r o g r a m m i n g Interface (API). With ObjectWindows, you don't need to understand the Windows API from the bottom up. Y o u don't need to learn and place dozens of function calls to create a w i n d o w . Instead, you just need to k n o w that predefined object types in ObjectWindows handle it for you. Y o u then use inheritance to extend these objects to m a k e your application special. I mentioned that another m o r e subtle link between Windows and O O P is that Windows is message based. Figure 3 8 illustrates this concept.
A Message-Driven
user messages
Windows application
programmer messages
Both user and
programmer
s e n d m e s s a g e s to a p p l i c a t i o n s .
Figure
3-8. A message-driven
architecture.
Architecture
101
102
Parti—Working with T P W
W i n d o w s treats u s e r e v e n t s ( c l i c k i n g t h e m o u s e , p r e s s i n g a k e y ) as m e s s a g e s that m u s t b e d i s p a t c h e d t o t h e c o r r e c t a p p l i c a t i o n . T h e o b j e c t s y o u derive using O b j e c t W i n d o w s c o m m u n i c a t e by r e s p o n d i n g to the messages they receive from W i n d o w s . Y o u r W i n d o w s a p p l i c a t i o n is c o m p o s e d o f o b j e c t s that r e p r e s e n t t h e c o m p l e x u s e r - i n t e r f a c e e l e m e n t s o f a W i n d o w s a p p l i c a t i o n . A w i n d o w is a n o b j e c t . A d i a l o g is a n o b j e c t . A n a p p l i c a t i o n is a n o b j e c t that sets u p t h e i n t e r f a c e to W i n d o w s , a n d s o o n (see figure 3 9 ) .
A W i n d o w is an object that contains objects. |
YourWindow YourMenu YourDialog YourListBox
Y o u r FileEdi tor
Figure
3-9- Several objects in one object.
B e c a u s e O b j e c t W i n d o w s is s o c o n c e p t u a l l y c o m p a t i b l e w i t h W i n d o w s , it simplifies the learning o f the W i n d o w s event-driven operation.
About Object Windows T h e p o w e r o f Windows lies i n the 5 5 0 o r s o f u n c t i o n s that c o m p r i s e the Windows A P I . R e c a l l a f e w f u n c t i o n s f r o m B A S I C S . P A S , required to set u p a b a s i c window: LoadIcon GetStockObj ect CreateWindow UpdateWindow TranslateMessage DefWindowProc
LoadCursor RegisterClass ShowWindow GetMessage DispatchMessage
3 — Objects for Windows
W h e n a W i n d o w s a p p l i c a t i o n w a n t s t o c h a n g e its a p p e a r a n c e , o r r e s p o n d t o u s e r i n p u t , it s e n d s a m e s s a g e t o a W i n d o w s f u n c t i o n . T y p i c a l l y , w h e n y o u w r i t e a W i n d o w s a p p l i c a t i o n w i t h o u t O b j e c t W i n d o w s (in C , f o r e x a m p l e ) , y o u s e n d m e s s a g e s t o t h e s e W i n d o w s f u n c t i o n s directly. T h e s e m e s s a g e s specify t h e n u m e r o u s parameters required o f a W i n d o w s function, a n d they handle any other protocol required o f the function. T h e following fragment, for example, s e n d s W i n d o w s a n A P I CreateWindow m e s s a g e directly: Window
:= CreateWindow(
AppName, 'Your Window Application Name', ws_OverlappedWindow, cwJJseDefault, cwJJseDefault, cwJJseDefault, cwJJseDefault, 0, 0, HInstance, nil); N o t i c e t h e c o m p l e x i t y o f t h e C r e a t e W i n d o w m e s s a g e , w h i c h r e q u i r e s 11 parameters (see figure 3.10). T h e s e parameters are, in order, the C l a s s N a m e , t h e W i n d o w N a m e , t h e W i n d o w S t y l e , t h e W i n d o w ' s initial h e i g h t a n d w i d t h ( s p e c i f i e d h e r e b y cwJJseDef ault), t h e w i n d o w ' s p a r e n t (0 h e r e b e c a u s e t h e w i n d o w h a s n o p a r e n t ) , a m e n u (0 h e r e f o r n o n e ) , t h e I n s t a n c e , a n d a p o i n t e r (nil h e r e ) f o r M D I w i n d o w s . S i m p l e ? N o ; this is o n e o f t h e m a n y r e a s o n s that y o u don't create W i n d o w s a n d applications without the h e l p o f O b j e c t W i n d o w s . T h e e q u i v a l e n t O b j e c t W i n d o w s call l o o k s s o m e t h i n g l i k e t h i s : MainWindow
:= New(PtrWindow,
Init(nil,
'Your Window Application Name')); O t h e r O b j e c t W i n d o w s object types m a n a g e the message-processing a n d other behaviors required o f a Windows program. O b j e c t W i n d o w s simplifies the calling o f W i n d o w s functions by repackagi n g t h e A P I i n a n o b j e c t - o r i e n t e d library. O b j e c t W i n d o w s e n c a p s u l a t e s all t h e W i n d o w s i n f o r m a t i o n c o n t a i n e d i n t h e A P I . O b j e c t W i n d o w s abstracts t h e Windows API functions a n d automates message response. ObjectWindows h a n d l e s a n y m e s s a g e s y o u d o n ' t w a n t t o h a n d l e d i r e c t l y , as s h o w n i n figure 3.11.
103
104
Part I — W o r k i n g w i t h T P W
Conventional
Windows call A P I
Development
directly
Windows API Load Icon LoadCursor RegisterClass Create Window ShowWindow
Figure
3 . 1 0 . Conventional
Windows
ObjectWindows
development.
Windows
Windows API
Development
ObjectWindows
Load Icon LoadCursor RegisterClass
(optional)
CreateWindow ObjectWindows ShowWindow
Figure
3-11- ObjectWindows
m a k e s it e a s i e r
to a c c e s s t h e W i n d o w s A P I .
Windows
development.
By encapsulating t h e details o f W i n d o w s in objects, O b j e c t W i n d o w s insulates y o u from m u c h o f W i n d o w s ' complexity. Most o f the parameter passing, setup, a n d s o o n occurs u n d e r cover in O b j e c t W i n d o w s . Y o u create a n
3 — O b j e c t s for W i n d o w s
i n s t a n c e o f a n o b j e c t y o u n e e d i n o r d e r t o h a n d l e a j o b ; t h e o b j e c t h a n d l e s it without y o u r worrying about the details. Y o u a l s o c a n t h i n k o f t h e O b j e c t W i n d o w s a p p r o a c h as a n i n d i r e c t o n e . I n O b j e c t W i n d o w s are t h e objects y o u u s e t o create w i n d o w s , dialogs, controls, a n d s o o n . Y o u s h o u l d k e e p i n m i n d that i n m a n y c a s e s , O b j e c t W i n d o w s is n o t a c t u a l l y i m p l e m e n t i n g m a n y o f its b e h a v i o r s itself. W h e n e v e r it c a n , it h a s W i n d o w s d o the work. S o W i n d o w s handles m a n y o f the details, another level a w a y f r o m t h e o b j e c t s y o u c r e a t e . I n fact, W i n d o w s is r e s p o n s i b l e for e v e r y physical element y o u see o n your c o m p u t e r screen. Let m e e x p l a i n . O b j e c t W i n d o w s , for e x a m p l e , d e f i n e s w i n d o w , d i a l o g , a n d c o n t r o l o b j e c t s y o u c a n u t i l i z e t o c r e a t e a p p l i c a t i o n s . O b j e c t W i n d o w s itself d o e s n o t a c t u a l l y i m p l e m e n t w i n d o w s , d i a l o g s , a n d s o o n . It o n l y r e p r e s e n t s t h e m . O b j e c t W i n d o w s requests W i n d o w s t o actually create t h e m o r r e m o v e t h e m f r o m t h e s c r e e n . It s u p p l i e s o n l y t h e s p e c i f i c b e h a v i o r a n d attributes o f t h e objects. T h i s d i s t i n c t i o n m i g h t s e e m c o n f u s i n g , b u t it's a n i m p o r t a n t o n e that helps y o u understand the O b j e c t W i n d o w s approach. T h e term used by Borland t o d e f i n e O b j e c t W i n d o w s o b j e c t s is interface objects, a n d t h e v i s u a l e l e m e n t s (what y o u s e e o n y o u r s c r e e n ) a r e c a l l e d interface elements. These two c o m p o n e n t s a r e c o n n e c t e d b y w a y o f a W i n d o w s h a n d l e (see f i g u r e 3 . 1 2 ) .
Object Windows defines object behavior.
Interface objects
Interface elements
Windows implements the physical elements.
Figure
3-12. Interface objects versus interface elements.
W h e n y o u c o n s t r u c t a n i n t e r f a c e o b j e c t , O b j e c t W i n d o w s asks W i n d o w s t o create t h e c o r r e s p o n d i n g element. W i n d o w s creates t h e e l e m e n t a n d returns a h a n d l e that i d e n t i f i e s t h e e l e m e n t t h r o u g h o u t its life. T h i s h a n d l e is u s e d
105
106
Part I — W o r k i n g w i t h T P W
any time a W i n d o w s function needs t o send a message t o the element. O b j e c t W i n d o w s s t o r e s this h a n d l e i n a TWindows o b j e c t f i e l d c a l l e d HWindow, which y o u read m u c h m o r e about in the next chapter.
Events, Messages, and Objects W i n d o w s is b a s e d o n a n e v e n t - d r i v e n a r c h i t e c t u r e . W i n d o w s h a n d l e s all u s e r i n p u t ( k e y b o a r d a n d m o u s e ) as e v e n t s , a n d g e n e r a t e s a m e s s a g e c o r r e s p o n d i n g to the event (see figure 3.13).
Windows Messages
generates a Windows mouse button message.
wm_LButtonDown
Windows routes messages to applications.
Application
Figure 3-13- Windows messages.
F o r e x a m p l e , w h e n y o u c l i c k t h e left m o u s e b u t t o n , W i n d o w s g e n e r a t e s a l e f t - b u t t o n - d o w n m e s s a g e (wmLButtonDown), w h e r e wm is a w i n d o w s message. W h e n y o u press a key, W i n d o w s generates a wmKeyDown message. T h e u s e r ' s s e l e c t i o n o f a m e n u i t e m is a l s o a n e v e n t . I n C h a p t e r 4 , "Inheriting an Interface," y o u learn h o w to define command-message response methods for responding to menus. Events trigger W i n d o w s messages t o objects. W h e n these objects are d e r i v e d f r o m O b j e c t W i n d o w s , t h e y c a n easily b e t a u g h t t o r e s p o n d t o W i n d o w s messages. T h e user also c a n u s e the m o u s e t o click various control b u t t o n s a n d select i t e m s f r o m a list b o x ( c a l l e d C o n t r o l e v e n t s ) . O b j e c t W i n d o w s m a k e s it easy f o r y o u r o b j e c t s t o r e s p o n d t o t h e s e e v e n t s a s w e l l ( a g a i n , m o r e o n this i n C h a p t e r 4, "Inheriting a n Interface").
3 — O b j e c t s for W i n d o w s
Windows Messages T h e r e are m o r e t h a n 100 s t a n d a r d W i n d o w s m e s s a g e s . W i n d o w s s e n d s m e s sages t o applications i n response t o events. T h e application responds t o these m e s s a g e s a n d acts a c c o r d i n g l y . W i n d o w s o b j e c t s r e s p o n d t o i n c o m i n g W i n d o w s m e s s a g e s (see figure 3 . 1 4 ) .
W i n d o w s objects r e s p o n d
to incoming m e s s a g e s .
generates a Windows mouse button message.
wm_LButtonDown
Windows routes messages
send m e s s a g e baok to Windows
to windovxs objects
Application
send message to other objeots.
Figure 3.14. Windows
objects respond to incoming
messages.
About WinCrt Before y o u get t o the heart o f W i n d o w s p r o g r a m m i n g ObjectWindows-style, I s h o u l d p o i n t o u t a q u i c k a n d c l e a n w a y t o g e t a T u r b o P a s c a l for W i n d o w s a p p l i c a t i o n u p a n d r u n n i n g i n n o t i m e at all. B e c a u s e W i n d o w s d o e s n ' t s u p p o r t t r a d i t i o n a l t e x t - o r i e n t e d file I/O, w h e n y o u try t o u s e y o u r e x i s t i n g T u r b o P a s c a l p r o g r a m s t o r e a d a n d w r i t e files, y o u r e c e i v e a fatal e r r o r m e s s a g e . T h e w a y to utilize y o u r existing c o d e a n d the simplest w a y to get a simple a p p l i c a t i o n r u n n i n g w i t h T u r b o Pascal for W i n d o w s is t o u s e t h e W i n C r t u n i t . W i n C r t c o n t a i n s t h e c o n t r o l l o g i c t o e m u l a t e a text s c r e e n i n a w i n d o w .
107
108
Part I — W o r k i n g w i t h T P W
T h e WinCrt u n i t e n a b l e s y o u t o r u n s t a n d a r d T u r b o Pascal p r o g r a m s i n W i n d o w s b y a d d i n g o n e l i n e o f c o d e : uses WinCrt;. Y o u c a n ' t t a k e a d v a n t a g e o f c o m p l e x W i n d o w s f e a t u r e s , b u t y o u c a n still u s e o l d c o d e that's t e x t - b a s e d . T h i s f e a t u r e m a k e s t h e t r a n s i t i o n t o W i n d o w s p r o g r a m m i n g easier. T h e f o l l o w i n g c o d e f r a g m e n t d e m o n s t r a t e s s t a n d a r d T u r b o Pascal i n p u t a n d o u t p u t , u s i n g Writeln, Readln. N o t i c e t h e repeat/until l o o p s that t h e i n p u t a n d o u t p u t e c h o u n t i l Input = quit . Quit' d o e s n o t c l o s e t h e W i n d o w . T h e w i n d o w r e m a i n s o n - s c r e e n a n d is c l o s e d just as a n y W i n d o w is b y w a y o f t h e FileMenu (see listing 3 . 3 ) . 1
Listing
33-
Using standard
Turbo Pascal
1
1
I/O.
program WindCRTex; uses WinCrt; { Allows Writeln, Readln, cursor movement, and so on. } { This program demonstrates how to use the WinCrt unit to perform "traditional" screen I/O. This is the easiest way to build text mode programs that run in a window. } var Input : string[80]; F : text; begin Assign(F,'wincrtex.pas'); { Basic FILE I/O } Reset(F); { Note: no error checking } repeat Readln(F,Input); { Read a line of the file } Write(Input); { Write it to the screen } Writeln; Writeln('What do you say?'); { Interact with user } Readln(Input); Writeln('Got it... You said ', Input); until (Input = 'quit') or EOF(F); Close(F); { Close the file. } DoneWinCrt; { Destroys the CRT window } end. { so that the user doesn't } { have to close it manually } W h e n your application doesn't n e e d to use anything m o r e than a single "frill-less" w i n d o w a n d is t e x t - b a s e d , t h e WinCrt r o u t e is d e f i n i t e l y t h e easiest route to get a W i n d o w s application going.
3 — O b j e c t s for W i n d o w s
U s i n g WinCrt e l i m i n a t e s t h e n e e d t o w r i t e s p e c i f i c W i n d o w s c o d e — a p l u s in t h e short term, b u t limiting in the l o n g term. T o u s e the m a n y features p r o v i d e d b y W i n d o w s t o t h e i r fullest e x t e n t , y o u s h o u l d g o b e y o n d t h e textb a s e d w i n d o w i n g p r o v i d e d b y WinCrt t o t h e O b j e c t W i n d o w s library. T h a t ' s w h e r e T u r b o Pascal for W i n d o w s s h i n e s .
Movin' On T h a t ' s e n o u g h i n f o r m a t i o n for a n i n t r o d u c t i o n . T h e n e x t c h a p t e r d e v e l o p s a b a s i c a p p l i c a t i o n a n d w i n d o w i n t e r f a c e that I c o n t i n u e t o u s e t h r o u g h o u t t h e b o o k . T h i s Basiclnterface c r e a t e s a m a i n w i n d o w ( t h r o u g h i n h e r i t a n c e ) a n d a t t a c h e s d i a l o g s , m e n u s , a n d c o n t r o l s t o it. U s e it as t h e starting p o i n t for all y o u r W i n d o w s a p p l i c a t i o n s (I d o ) . W i n d o w s a n d o b j e c t s a r e a great m a t c h : a n i n t e r f a c e a n d t h e t o o l s for easily m a n i p u l a t i n g that i n t e r f a c e . P u t t i n g t h e t w o t o g e t h e r r e q u i r e s a little initial effort ( a n d p e r h a p s ) a n e w p r o g r a m m i n g p o i n t o f v i e w , b u t t h e p a y o f f for a little effort is m o r e t h a n e n o u g h c o m p e n s a t i o n . O O P is a p o w e r f u l p r o g r a m m i n g t e c h n i q u e i n t h e P C a r e n a , a n d W i n d o w s is t h e m o s t p o w e r f u l p r o g r a m m i n g e n v i r o n m e n t . T u r b o P a s c a l for W i n d o w s (with its O b j e c t W i n d o w s library) l i n k s t h e t w o i n a p l e a s a n t , p o w e r f u l I D E , fit for t h e p r i n c e s a n d p r i n c e s s e s o f p r o g r a m m i n g like y o u a n d m e .
109
4 CHAPTER
INHERITING AN INTERFACE What the user and applications developer want today is a graphics-oriented user interface, multitasking capability, and hardware independence. Windows has come of age. W i l l i a m H . M u r r a y , III a n d Chris H . Pappas O b j e c t - o r i e n t e d p r o g r a m m i n g l a n g u a g e s ( s u c h as T u r b o Pascal f o r W i n d o w s ) encourage y o u to change the way y o u think about developing applications. U s i n g O O P t e c h n i q u e s , y o u c a n d e s i g n g e n e r a l (or b a s e ) o b j e c t t y p e s , a n d y o u r a p p l i c a t i o n s c a n i n h e r i t characteristics a n d b e h a v i o r s f r o m t h e s e b a s e t y p e s . T h i s i n h e r i t a n c e results i n y o u r s a v i n g significant p r o g r a m m i n g t i m e a n d effort, b e c a u s e y o u w r i t e o n l y t h e c o d e that differs f r o m t h e b a s e t y p e . O b j e c t W i n d o w s contains e n o u g h base types for y o u to create a c o m p l e t e W i n d o w s i n t e r f a c e . O b j e c t s that c r e a t e m e n u s f o r u s e r r e s p o n s e s , list b o x e s f o r u s e r selections, file d i a l o g s for o p e n i n g a n d saving files, a n d editors for m o d i fying files are a f e w O b j e c t W i n d o w s b a s e o b j e c t t y p e s that are r e a d y t o g o right out of the b o x . Eventually y o u will use most of the objects in O b j e c t W i n d o w s , s o it's w o r t h t a k i n g a l o o k at h o w t h e o b j e c t s fit t o g e t h e r h i e r a r c h i c a l l y . F i g u r e 4.1 s h o w s t h e O b j e c t W i n d o w s o b j e c t h i e r a r c h y .
112
Parti—Working with T P W
TObject (Base) TApplloation
ObjectWindows H ierarchy
TScroller T W i ndowsOb iect TDialog TDlgWindow TFileDialog Tin putDialoq TWindow TMDIWIndOW TEditWindow TFileWindow TControl TButton TMDICIient T St at ic TEdit TScrollBar TLIStBox TComboHox TQroupBox TCheckBox
TRadioButton
Figure 4.1. The ObjectWindows
hierarchy.
ObjectWindows is a terrific library: easy to use and well thought out. Y o u do have to specify the behaviors of menus, dialogs, boxes, and so on, but you don't have to specify what they look like or h o w they operate. Those details all are ready to be inherited by the objects you create using ObjectWindows. In addition, these behaviors can be defined outside your Turbo Pascal source code as resources (using the Whitewater Resource Toolkit packaged with Turbo Pascal for Windows, which is discussed in Chapter 8, "Resources and Control Objects," and in Reference O, "Object Graphics." Y o u can modify them without necessarily modifying your source c o d e — a definite plus w h e n you develop large or generic applications. T o include a m e n u , for example, your application 1. Loads a m e n u from a compiled resource file. 2. Specifies h o w the application should respond to a user's m e n u selections. T o include a list box, your application 1. Loads a list box from a resource file. 2. Specifies what should go in the list and h o w the application should respond to list selections. T o include other resources in your application, you follow a similar procedure.
4 —Inheriting an Interface
Any application you create using ObjectWindows starts from two basic objects in the library (TApplication and TWindow). Y o u derive n e w applications and windows from these base application and w i n d o w objects. Y o u don't have to reinvent the application or the window. Y o u expend virtually no energy designing the look and feel of your application's interface. It already looks and feels like any other W i n d o w s application. Y o u concentrate, instead, o n the details of your specific application, making you, your boss, and your family happy. Because each application you create using TApplication and TWindow shares the c o m m o n attributes and behaviors of other W i n d o w s applications, both you and your users benefit. A user learns h o w to use a general interface (in this case, the W i n d o w s GUI), and comes u p to speed in n e w applications m u c h m o r e quickly. Y o u concentrate o n the specific aspects of the application, not o n h o w to use the interface. Y o u don't have to rewrite an interface for each application. Y o u reuse an existing one, adding the bells and whistles you need. Everybody wins, especially marketing.
The Basiclnterfece It's worth repeating: W i n d o w s is a graphical user interface (a GUI). Everything—text, dots, fills, and pictures—are treated by W i n d o w s not as ASCII characters (DOS-style), but as pixels turned o n and off in a display context (the W i n d o w s n a m e for a painting surface). Dealing with pixels rather than characters empowers GUIs, but it also makes them difficult for application programmers. Every aspect of the applications you develop using Turbo Pascal for W i n d o w s and ObjectWindows must deal with pixels. Y o u can use the WinCrt unit (described in Chapter 3, "Objects for Windows,") for simple text-oriented W i n d o w s applications, but for anything complex, your application must translate to pixels. Fortunately, using pixels is only slightly more difficult than using text. Amazing! In this chapter, you use the O O P concepts discussed in Chapter 2 to create a useful and powerful interface. After you have this Basiclnterface in your toolbox, you use it as a starting point each time you write a W i n d o w s application. It is general enough to use as is and simultaneously customizable. Each time you write a n e w application you concentrate o n its details, and the Basiclnterface handles communications with Windows. The B a s i c l n t e r f a c e consists of two big objects derived from TApplication and TWindow: 1. A n application 2. Its main w i n d o w and the objects that are attached to it
113
114
Parti—Working with T P W
T h e B a s i c I n t e r f a c e o b j e c t (I call i t W I F , f o r W i n d o w s I n t e r F a c e ) h a n d l e s y o u r application's low-level interactions with W i n d o w s , channeling messages back and forth b e t w e e n W i n d o w s a n d the application's main w i n d o w . T h e m a i n w i n d o w , i n t u r n , c o n t r o l s o t h e r w i n d o w o b j e c t s ( s u c h as b u t t o n s , m e n u s , s c r o l l bars, a n d b o x e s ) . For c o n v e n i e n c e , y o u k e e p the B a s i c l n t e r f a c e in a unit (WIF.PAS), w h i c h y o u include in each o f y o u r applications. This unit also m a n a g e s the loading o f other basic units a n d resources required by O b j e c t W i n d o w s — a n o t h e r detail y o u d o n ' t h a v e t o b e c o n c e r n e d a b o u t . I b u i l d t h e B a s i c l n t e r f a c e a c o m p o n e n t at a t i m e , a n d s h o w t h e c o d e t o y o u i n p i e c e s . T h e c o m p l e t e B a s i c l n t e r f a c e c o d e , r e a d y t o p l u g i n t o y o u r a p p l i c a t i o n s , is i n listing 4 . 7 , at t h e e n d o f this c h a p t e r . Y o u r a p p l i c a t i o n s i n h e r i t all t h e b e h a v i o r s a n d characteristics o f t h e B a s i c l n t e r f a c e : c o m m u n i c a t i n g with W i n d o w s , creating and managing main a n d child w i n d o w s , interacting with the user, a n d so o n . Y o u sometimes n e e d t o m o d i f y t h e B a s i c l n t e r f a c e a b i t (to specify r e s p o n s e s t o d i a l o g s a n d m e n u s e l e c t i o n s , f o r e x a m p l e ) , b u t f o r m a n y g e n e r i c p u r p o s e s , it w o r k s f i n e as is. M o d i f y i n g t h e B a s i c l n t e r f a c e is easy, t h a n k s t o O O P t e c h n i q u e s . C h a p t e r s 5 t h r o u g h 13 s h o w y o u h o w t o e x t e n d t h e B a s i c l n t e r f a c e t o h a n d l e m a n y different kinds o f p r o b l e m s .
Application and Window Objects A n y W i n d o w s a p p l i c a t i o n m u s t initiate a n d m a i n t a i n a c o m m u n i c a t i o n l i n k b e t w e e n itself a n d W i n d o w s . R e c a l l f r o m C h a p t e r 3, " O b j e c t s f o r W i n d o w s , " that t o set u p t h e b a s i c m a c h i n e r y r e q u i r e d t o initialize a m a i n w i n d o w i n W i n d o w s a n d t o set u p c o m m u n i c a t i o n s b e t w e e n y o u r a p p l i c a t i o n a n d W i n d o w s r e q u i r e s a b o u t 100 l i n e s o f T u r b o P a s c a l f o r W i n d o w s c o d e , if y o u r a p p l i c a t i o n s e n d s m e s s a g e s t o t h e W i n d o w s A P I directly. A l t h o u g h y o u c a n call t h e A P I ( A p p l i c a t i o n P r o g r a m m i n g I n t e r f a c e ) directly e a c h t i m e y o u c r e a t e a n application, y o u usually don't want to because y o u can often achieve the same r e s u l t s i n far f e w e r l i n e s u s i n g O b j e c t W i n d o w s . T h r e e u n i t s p a c k a g e d w i t h T u r b o Pascal f o r W i n d o w s ( W O b j e c t s , WinTy p e s , a n d W i n P r o c s ) establish the interface b e t w e e n y o u r applications a n d W i n d o w s . W O b j e c t s is t h e O b j e c t W i n d o w s o b j e c t library. W i n T y p e s a n d W i n P r o c s d e f i n e t h e T u r b o Pascal f o r W i n d o w s f u n c t i o n t y p e s a n d p r o c e s s e s f o r s e n d i n g m e s s a g e s t o t h e W i n d o w s A P I directly. If y o u r a p p l i c a t i o n s e n d s m e s s a g e s t o t h e W i n d o w s A P I o n l y t h r o u g h O b j e c t W i n d o w s , it d o e s n ' t n e e d t o i n c l u d e t h e W i n T y p e s a n d W i n P r o c s u n i t s . T h e B a s i c l n t e r f a c e s o m e t i m e s s e n d s m e s s a g e s t o t h e A P I directly, s o it i n c l u d e s all t h r e e u n i t s . {Note: I n c l u d i n g t h e s e u n i t s d o e s n ' t i n c u r a n y e x t r a o v e r h e a d f o r t h e B a s i c l n t e r f a c e . T h e T u r b o Pascal f o r W i n d o w s c o m p i l e r is smart a n d c o m p i l e s only the c o d e actually u s e d by y o u r application.)
4 — I n h e r i t i n g a n Interface
T h e Basiclnterf ace c o n s i s t s o f t w o o b j e c t s (BasicApplication a n d MainWindow). T h e BasicApplicat ion " o w n s " t h e MainWindow, b u t t h e t w o are distinct o b j e c t s ; t h e y ' r e n o t related h i e r a r c h i c a l l y . O w n e r s h i p o f this t y p e is c a l l e d a n instance linkage. T h e BasicApplication is d e r i v e d f r o m t h e TApplication o b j e c t (in O b j e c t W i n d o w s ) . T h e MainWindow is d e r i v e d f r o m t h e TWindow o b j e c t (in ObjectWindows). T h e TApplication o b j e c t i n O b j e c t W i n d o w s a l r e a d y k n o w s h o w t o h a n d l e all o f Windows' initialization f o r y o u . T h e o n l y s p e c i f i c i n i t i a l i z a t i o n t h e BasicApplication h a s t o h a n d l e itself is t o c r e a t e a n e w MainWindow u s i n g i n h e r i t a n c e ( s e e figure 4.2).
Inheriting an
application
TApplication
Y o u rApplication
YourApplication automatically everything TApplication
Figure
4.2. Inheriting
an
knows
knows.
application.
Y o u r first o r d e r of b u s i n e s s i n creating t h e Basiclnterfaceisto d e r i v e a BasicApplication o b j e c t t y p e from a TApplication o b j e c t : type BasicApplication = object(TApplication) procedure InitMainWindow; virtual; end; T h e p r o c e d u r e InitMainWindow is virtual ( t h u s , its b e h a v i o r c a n b e o v e r r i d d e n ) , d e f i n e d originally as a TApplication m e t h o d . E a c h a p p l i c a t i o n d e r i v e d from TApplication s h o u l d o v e r r i d e this m e t h o d :
115
116
Part I — W o r k i n g w i t h T P W
procedure BasicApplication. InitMainWindow; begin MainWindow := New(PMainWindow, Init(nil, 'Basiclnterface')); end; InitMainWindow " c o n n e c t s " t h e BasicApplication t o its MainWindow, b y w a y o f a p o i n t e r (PMainWinsdow). T h e T u r b o Pascal f o r W i n d o w s e x t e n d e d s y n t a x f o r t h e New p r o c e d u r e e n a b l e s y o u t o specify t h e o b j e c t t y p e y o u w a n t t o c r e a t e (a M a i n W i n d o w ) a n d c o n s t r u c t it ( u s i n g I nit) i n o n e s t e p . T h e MainWindow's d e f a u l t c o n s t r u c t o r ( d e f i n e d i n TWindow) r e q u i r e s t w o p a r a m e t e r s : nil ( r e q u i r e d f o r initialization p u r p o s e s ) , a n d a n a m e f o r t h e application w i n d o w . This n a m e appears in the t o p border of the main window. T h e d e f a u l t Basiclnterface n a m e is s i m p l y Basiclnterface, b u t y o u c a n ( o b v i o u s l y ) c h a n g e this n a m e easily.
The Main Window T h e following c o d e shows h o w to derive a n e w m a i n w i n d o w object f r o m TWindow: type PMainWindow = "MainWindow; MainWindow = object(TWindow) end; T h i s MainWindow o b j e c t d o e s n ' t a d d a n y n e w b e h a v i o r (yet!) t o its a n c e s t o r , TWindow. T h e m a i n w i n d o w s i m p l y a p p e a r s w i t h its n a m e — h i d i n g a m e n u with close, resize, m o v e , a n d other options w h e n y o u r u n the application (see f i g u r e 4 . 3 ) . T h i s m a i n w i n d o w ( b y w a y o f its c o n n e c t i o n t o t h e BasicApplication) responds automatically to W i n d o w s messages (the keyboard, the m o u s e , a n d so o n ) a n d t o user events ( m e n u selections, check boxes, dialogs, a n d so o n ) . I n a l m o s t all c a s e s , y o u r a p p l i c a t i o n w a n t s t o i m p l e m e n t s o m e o f its o w n responses t o specific W i n d o w s messages. N o p r o b l e m . B y b e g i n n i n g with a g e n e r a l m a i n w i n d o w that c a n h a n d l e a n y W i n d o w s m e s s a g e a u t o m a t i c a l l y , y o u h a v e t o i m p l e m e n t o n l y t h e r e s p o n s e s y o u w a n t t o specify. Y o u a d d o n l y t h e behaviors y o u want t o override by a d d i n g response m e t h o d s t o the basic m a i n w i n d o w . M o r e o n this i n a m o m e n t .
4 —Inheriting an Interface 1 1 7
Figure
4.3. The default window
of Window.
Init.
Y o u can derive most ofyour applications from the Basiclnterface developed in this chapter. Your applications that need to have more than one document open at a time can use a variation of the Basiclnterface set u p for you in Chapter 5, "Putting Pictures in Windows." The variation uses a main w i n d o w as well but calls it a parent w i n d o w and attaches other windows (called children) to it. This many-window system is defined by the multi-document interface (or MDI). In sum, the Basiclnterface at its simplest is an application and a main w i n d o w object, as illustrated byfigure4 . 4 . T o use these two objects: 1. Declare an instance (for example, a variable) of object type BasicApplication (but you don't create an instance of MainWindow!): var Applicationl
: BasicApplication;
2. Construct it: Applicationl.Init('Applicationl ); 1
3. Set it in motion: Applicationl.Run; 4. Arrange for it to be destroyed w h e n you finish with it: Applicationl.Done;
118
Parti—Working with T P W
TApplication + TWindow
objects
= Window application
Y o u r application (object)
Windows applic ation y o u r w i n d o w (object)
c o n t r o l , d i a l o g , etc. o b j e c t s
Y o u link o b j e c t s t o g e t h e r t o c r e a t e a W i n d o w s a p p l i c a t i o n .
Figure
4.4. Creating a windows
application.
Listing 4.1 s h o w s t h e first p h a s e ( p r e l i m i n a r y , b u t w o r k a b l e ) o f t h e B a s i c l n t e r f a c e ( W I F 1 . P A S ) . Listing 4.2 s h o w s a little p r o g r a m y o u u s e t h r o u g h o u t this c h a p t e r t o test t h e B a s i c l n t e r f a c e . Listing
4.1.
unit WIF1;
The preliminary
version
of Basiclnterf
ace.
{ Contains Basic Windows application interface version 1 derived from ObjectWindows }
interface uses WObjects, { ObjectWindows library of objects } WinTypes, { Windows types: for accessing the API } WinProcs; { Windows processes: for accessing the API } type BasicApplication = object(TApplication) { Derive an application object } procedure InitMainWindow; virtual; {Init a main window } end; PMainWindow = "MainWindow; MainWindow = object(TWindow) end;
{ Pointer to a main window } { Derive a main window }
4 — I n h e r i t i n g a n Interface
119
implementation procedure BasicApplication.InitMainWindow; begin MainWindow := New(PWindow, Init(nil, 'Basic Windows Interface')); end; end. { end unit }
Listing
4.2. Testing
the Basiclnterf ace.
program Test_Interface; uses WIF5; var Applicationl: BasicApplication; BasicApplication }
{ A generic way to test each phase of interface development } { Basiclnterface unit } { An instance of
{ Run Applicationl } begin Applicationl.Init('Basiclnterface'); { init application instance } Applicationl.Run; Applicationl.Done; end.
{ Message loop } { Destroy application instance } { End test program }
N o t i c e that y o u d o n ' t h a v e t o w r i t e t h e Init, Run, o r Done m e t h o d s y o u r s e l f . T h e BasicApplication o b j e c t i n h e r i t e d t h e s e m e t h o d s f r o m
TApplication.
Details A l t h o u g h y o u d o n ' t n e e d t o k n o w h o w Init, Run, a n d Done w o r k , y o u m i g h t appreciate a brief explanation o f h o w they handle y o u r application for y o u . W h e n y o u c o n s t r u c t t h e b a s i c a p p l i c a t i o n (Applicationl .Init), t h e T u r b o Pascal f o r W i n d o w s c o m p i l e r c h e c k s w h e t h e r it c a n s e n d a m e s s a g e t o Applicationl's c o n s t r u c t o r . Applicationl, i n fact, d o e s n ' t h a v e its o w n c o n s t r u c t o r . It i n h e r i t e d o n e ( f r o m TApplication), s o t h e c o m p i l e r s e n d s t h e c o n s t r u c t m e s s a g e t o TApplication ( t h e a n c e s t o r o f BasicApplication). Note: Applicationl is a n i n s t a n c e o f t h e o b j e c t t y p e (BasicApplication), n o t t h e o b j e c t itself.
120
Parti—Working with T P W
T h e TApplication c o n s t r u c t o r (Init) c o n s t r u c t s t h e BasicApplication. Specifically, it s e n d s a m e s s a g e t o its a n c e s t o r TOb j ect. Init, t h e b a s e o b j e c t t y p e o r c o m m o n a n c e s t o r o f all O b j e c t W i n d o w s o b j e c t t y p e s . T h e c o n s t r u c t o r t h e n sets t h e O b j e c t W i n d o w s g l o b a l v a r i a b l e (Application) t o @Self, a n d several o f t h e BasicApplication fields. T h e s e fields, l i k e t h e c o n s t r u c t o r , w e r e i n h e r i t e d b y t h e BasicApplication f r o m TApplication. Init sets t h e BasicApplication Name field t o t h e a p p l i c a t i o n n a m e it r e c e i v e d i n t h e m e s s a g e (Applicationl .Init( 'Name here'). Init t h e n sets t o z e r o b o t h t h e BasicApplication. HAccTable (for h a n d l e t o a n a c c e l e r a t o r table) a n d BasicApplication.Status fields. T h e n it initializes t h e MainWindow a n d KBHandlerWnd (for k e y b o a r d h a n d l e r w i n d o w ) t o nil. Finally, if this is t h e first i n s t a n c e o f t h e a p p l i c a t i o n ( t h e r e c a n b e m o r e t h a n o n e i n s t a n c e — m o r e o n this later i n this c h a p t e r ) , Init s e n d s a m e s s a g e t o InitApplication ( a n o t h e r d e f a u l t TApplication m e t h o d ) t o h a n d l e a n y s p e c i f i c initialization f o r a first instance o f an application. In other words, w h e w . There's a lot going o n , and y o u don't have to think a b o u t m o s t o f it. A BasicApplication is c o n s t r u c t e d w i t h n o effort o n y o u r part. I n m o s t c a s e s , this a u t o m a t i c c o n s t r u c t i o n suffices, b u t y o u r a p p l i c a t i o n c a n always o v e r r i d e this d e f a u l t b e h a v i o r if it n e e d s t o . Applicationl.Run, t h e m e s s a g e l o o p , is w h e r e t h e a c t i o n is. Basically, t h e Run m e t h o d ( a g a i n i n h e r i t e d f r o m TApplication) is t h e d i s p a t c h m e s s a g e l o o p y o u s a w earlier i n t h e NoFrills.pas c o d e i n C h a p t e r 3, "Objects for Windows." Run s e n d s a m e s s a g e t o its MessageLoop m e t h o d , w h i c h p r o c e s s e s i n c o m i n g W i n d o w s m e s s a g e s . T h e MessageLoop w o r k s a u t o m a t i c a l l y (of c o u r s e ) , s o a g a i n y o u c a n i g n o r e t h e details o f its p r o c e s s i n g o f b a s i c W i n d o w s m e s s a g e s . Y o u c a n r e i m p l e m e n t this MessageLoop, if y o u ' r e trying t o o p t i m i z e y o u r a p p l i c a t i o n ( s e e C h a p t e r 12, " S h a r i n g L i b r a r i e s " ) . Finally, w h e n Applicationl . r e c e i v e s a n end m e s s a g e ( f r o m W i n d o w s ) , it s e n d s a m e s s a g e t o its d e s t r u c t o r (Applicationl . D o n e ) , w h i c h d e s t r o y s t h e application instance. It's w o r t h e m p h a s i z i n g that d e s t r u c t o r s d o n ' t d e s t r o y o b j e c t t y p e s , t h e y d e s t r o y i n s t a n c e s (or variables) o f t h e o b j e c t . Y o u r a p p l i c a t i o n c a n c r e a t e m o r e t h a n o n e i n s t a n c e o f a n o b j e c t t y p e . F i g u r e 4 . 5 illustrates this c o n c e p t , a n d t h e f o l l o w i n g a d j u s t m e n t t o t h e Basiclnterface h a n d l e s m u l t i p l e i n s t a n c e s : procedure BasicApplication.InitMainWindow; begin if FirstApplication then MainWindow := New(PMainWindow, Init(nil, 'Basic Windows Interface')) else MainWindow := New(PMainWindow, Init(nil,'Additional Instance of BI')); end;
4 —Inheriting an Interface
Init m u l t i p l e i n s t a n c e s
Instance MainWindow Init Instance MainWindow
MessageLoop
Run
•one
Figure 4.5. Multiple instances of
Init.
Although many, if not most, of your applications need only one instance, s o m e of them will need multiple instances. Y o u should include these adjustments in the Basiclnterface. Listing 4 . 3 shows this n e w state of the Basiclnterface (WIF2. PAS) .Throughout this chapter, use the TEST_WIF. PAS code in lis ting 4.2 to test the n e w versions of the B a s i c I n t e r f a c e. Listing
43.
A revision
unit WIF2;
of
Basiclnterface.
{ Contains Basic Windows application interface derived from ObjectWindows }
interface uses WObjects, WinTypes, WinProcs; type
{ ObjectWindows library of objects } { Windows types: for accessing the API } { Windows processes: for accessing the API }
BasicApplication = object(TApplication) { Derive an application object } FirstApplication : boolean; procedure InitMainWindow; virtual; { Init a main window } procedure InitApplication; virtual; end; continues
121
122
Part I — W o r k i n g w i t h T P W
Listing
43-
continued
PMainWindow = "MainWindow; MainWindow = object(TWindow) end; implementation { BasicApplication
method implementation }
procedure BasicApplication.InitMainWindow; begin if FirstApplication then MainWindow := New(PMainWindow, Init(nil, 'Basic Windows Interface')) else MainWindow := New(PMainWindow, Init(nil,'Additional Instance of BI')); end; procedure BasicApplication.InitApplication; begin FirstApplication := True; end; end.
Window Messages T h e BasicApplication o b j e c t ( d e r i v e d from TApplication) d o e s m a n y t h i n g s for y o u : • S e t s u p t h e i n t e r f a c e t o W i n d o w s (BasicApplication. Init) • Handles the GetMessage-Dispatch Message loop in the
(BasicApplication.Run) • C l e a n s u p (BasicApplication. Done) D u r i n g Run's m e s s a g e l o o p , m e s s a g e s s e n t t o y o u r a p p l i c a t i o n b y W i n d o w s (called " W i n d o w s messages") are processed automatically. T h e n t h e MessageLoop m e t h o d s e n d s a m e s s a g e t o its sister m e t h o d , ProcessAppMsg, w h i c h i n t u r n s e n d s m e s s a g e s t o t h r e e " t r a n s l a t i o n m e t h o d s " that g e t "first c r a c k " at p r o c e s s i n g W i n d o w s m e s s a g e s : 1. ProcessDlg h a n d l e s d i a l o g s w i t h o u t m o d e l s . 2. ProcessAccels h a n d l e s a c c e l e r a t o r s . 3. ProcessMDIAccels h a n d l e s a c c e l e r a t o r s for M D I a p p l i c a t i o n s .
4 — I n h e r i t i n g a n Interface
T h i s m e s s a g e t r a n s l a t i o n is a l s o h a p p e n i n g b e h i n d t h e s c e n e s ; a n d u n l e s s y o u n e e d t o o p t i m i z e , f o r e x a m p l e , y o u c a n i g n o r e this m e s s a g e t r a n s l a t i o n . T h e r e are w e l l o v e r 100 W i n d o w s m e s s a g e s , a n d t h e y all b e g i n w i t h t h e p r e f i x wm_. T h e y h a n d l e e v e r y t h i n g f r o m k e y b o a r d - a n d m o u s e - e v e n t p r o c e s s i n g t o u n d o i n g o p e r a t i o n s i n e d i t c o n t r o l s , t o n o t i f y i n g a w i n d o w that its size h a s c h a n g e d o r that a m e n u i t e m h a s b e e n s e l e c t e d . H e r e are a f e w e x a m p l e s : * *
wm_LButtonDown wm_RButtonDown
* wm_LButtonUp * wm_RButtonUp * wm_MouseMove * wm_ShowWindow * *
wm_Size wm_SysCommand
Y o u r a p p l i c a t i o n ' s m a i n w i n d o w o b j e c t is r e s p o n s i b l e f o r r e s p o n d i n g t o t h e s e W i n d o w s m e s s a g e s , a n d it's h a n d l e d f o r y o u a u t o m a t i c a l l y b y d e f a u l t i n a m e t h o d that MainWindow i n h e r i t e d f r o m TWindow: D e f W n d P r o c , w h i c h supplies default actions for each W i n d o w s message. I n m o s t c a s e s , y o u r a p p l i c a t i o n is d e l i g h t e d that D e f W n d P r o c is d o i n g t h e w o r k . It d o e s n ' t w a n t t o b e b o t h e r e d r e s i z i n g a n d s h o w i n g w i n d o w s , f o r e x a m p l e . Y o u d o n ' t w a n t t o b e b o t h e r e d w r i t i n g all that c o d e . Y o u ' r e c o n c e n trating o n t h e d e t a i l s o f y o u r s p e c i f i c a p p l i c a t i o n , n o t o n t h e i n t e r f a c e . S o m e t i m e s , t h o u g h , y o u w a n t t o i n t e r c e p t a W i n d o w s m e s s a g e t o specify a b e h a v i o r . F o r e x a m p l e , say that y o u w a n t t o a d d y o u r o w n m o u s e i n t e r f a c e t o y o u r a p p l i c a t i o n . T o r e s p o n d t o u s e r e v e n t s ( s u c h as t h e m o u s e a n d t h e k e y b o a r d ) , y o u r application intercepts specific W i n d o w s messages. T o i n t e r c e p t a W i n d o w s m e s s a g e , s i m p l y o v e r r i d e ( r e d e f i n e ) t h e TWindow m e t h o d s , w h i c h MainWindow i n h e r i t e d , for t h e m e s s a g e y o u w a n t y o u r a p p l i cation to r e s p o n d t o — l i k e this: p r o c e d u r e WMLButtonDown(var Msg: virtual
wm_First
TMessage);
+ wm_LButtonDown;
Y o u t h e n i m p l e m e n t t h e m e t h o d , d e t a i l i n g its b e h a v i o r : p r o c e d u r e WMLButtonDown(var Msg: begin { d e t a i l response here } end;
TMessage);
Each time y o u r application's m a i n w i n d o w receives a wmLButtonDown m e s s a g e , it r e s p o n d s w i t h w h a t e v e r b e h a v i o r is s p e c i f i e d i n t h e o v e r r i d d e n m e t h o d . T h e m e s s a g e w o n ' t r e a c h t h e d e f a u l t b e h a v i o r f o r t h e wm_LBu t t o n Down message specified by DefWndProc.
123
1 2 4 Part I — W o r k i n g w i t h T P W
W h a t a b o u t o t h e r m e s s a g e s , s u c h as a wm_RBut t o n Down? Y o u r a p p l i c a t i o n w i n d o w h a s n ' t specifically d e f i n e d a n e w r e s p o n s e m e t h o d f o r t h e m . N o p r o b l e m . Y o u override only the messages y o u want. Y o u c a n override o n e o r 5 0 m e s s a g e s ; a n y m e s s a g e y o u d o n ' t d e f i n e is p a s s e d t o D e f W i n d o w P r o c a u t o m a t i c a l l y . It's a great s y s t e m : y o u inherit all t h e b e h a v i o r o f a n o b j e c t (TWindow), a n d o v e r r i d e o n l y t h e b e h a v i o r s y o u w a n t t o o v e r r i d e . Because m o u s e events often generate messages your applications want to respond to, y o u should put them in the B a s i c l n t e r f a c e . For now, y o u only i m p l e m e n t abstract m e t h o d s f o r t h e m that y o u w i l l i m p l e m e n t (override) later.
Another Advantage of O O P Y o u can define methods for objects and compile them to test the Basiclnterf ace without implementing any of the methods. This "prototype style" is particularly handy for large p r o g r a m m i n g projects.
Y o u can add message-response methods for m o u s e clicks to the Basiclnterf ace MainWindow object. Listing 4.4 shows the n e w version of the Basiclnterface (WIF3.PAS). Listing
4A.
Version
unit WIF3;
3 of Basiclnterf
ace.
{ Contains Basic Windows application interface derived from ObjectWindows }
interface uses WObjects, WinTypes, WinProcs; type
{ ObjectWindows library of objects } { Windows types: for accessing the API } { Windows processes: for accessing the API }
BasicApplication = object(TApplication) { Derive an application object } FirstApplication : boolean; procedure InitMainWindow; virtual; { Init a main window } procedure InitApplication; virtual; end; PMainWindow = "MainWindow; MainWindow = object(TWindow)
4 — I n h e r i t i n g a n Interface
125
procedure WMLButtonDown(var Msg: TMessage); virtual wm_first + wm_LButtonDown; procedure WMLButtonUp(var Msg: TMessage); virtual wm_first + wm_LButtonUp; procedure WMRButtonDown(var Msg: TMessage); virtual wm_first + wm_RButtonDown; procedure WMRButtonllp(var Msg: TMessage); virtual wm_first + wm_RButtonUp; procedure WMMouseMove(var Msg: TMessage); virtual wm_first + wm_MouseMove; end; implementation { BasicApplication method implementation } procedure BasicApplication.InitMainWindow; begin if FirstApplication then { If instance flag is set } MainWindow := New(PMainWindow, Init(nil, 'Basic Windows Interface')) else MainWindow := New(PMainWindow, Init(nil,'Additional Instance of BI')); end; procedure BasicApplication.InitApplication; begin FirstApplication := True; { Set instance flag } end; { Abstract implementation of basic MainWindow Mouse events } procedure MainWindow.WMLButtonDown(var Msg: TMessage); begin end; procedure MainWindow.WMLButtonUp(var Msg: TMessage); begin end; procedure MainWindow.WMRButtonDown(var Msg: TMessage); begin end; procedure MainWindow.WMRButtonUp(var Msg: TMessage); begin end; procedure MainWindow.WMMouseMove(var Msg: TMessage); begin end; end.
126
Parti—Working with T P W
B e f o r e a b a n d o n i n g W i n d o w s m e s s a g e s t e m p o r a r i l y , n o t e that y o u c a n d e f i n e r e s p o n s e m e t h o d s f o r a n y W i n d o w s m e s s a g e , n o t just m o u s e e v e n t s as I've d o n e h e r e . Y o u p r o b a b l y w o n ' t w a n t t o d o s o , h o w e v e r ; m o s t o f t h e m e s s a g e s y o u r a p p l i c a t i o n h a n d l e s directly t h r o u g h O b j e c t W i n d o w s .
Display Contexts B e f o r e y o u a d d a n y t h i n g e l s e t o y o u r Basiclnterface ( d i a l o g s a n d m e n u s a r e d i s c u s s e d later i n this c h a p t e r a n d i n C h a p t e r 5, " P u t t i n g P i c t u r e s i n W i n d o w s " ) , I w a n t t o d i g r e s s a bit a n d briefly d i s c u s s several a s p e c t s o f W i n d o w s p r o g r a m m i n g that t e x t - b a s e d Pascal p r o g r a m m i n g h a s n ' t likely p r e p a r e d y o u for. T h e first o f t h e s e y o u n e e d t o k n o w a b o u t is a d i s p l a y c o n t e x t . T o d r a w text o r graphics in a w i n d o w , y o u u s e a display context. A d i s p l a y c o n t e x t is a n e l e m e n t (recall t h e e l e m e n t - o b j e c t d i c h o t o m y ) that r e p r e s e n t s t h e s u r f a c e o f a w i n d o w . It's a d a t a s t r u c t u r e m a i n t a i n e d b y t h e W i n d o w s G r a p h i c s Device Interface ( G D I ) . W i n d o w s associates each display context with a specific display device: the screen, a printer, a n d s o o n . T h e attributes o f a d i s p l a y c o n t e x t d e t e r m i n e text c o l o r , b a c k g r o u n d c o l o r , f o n t , c o o r d i n a t e m a p p i n g , a n d s o o n . W h e t h e r y o u r a p p l i c a t i o n is w r i t i n g text o r d r a w i n g p i c t u r e s , it first n e e d s t o o b t a i n a h a n d l e t o a d e v i c e c o n t e x t . T h i s h a n d l e is s i m p l y a n u m b e r that i d e n t i f i e s t h e W i n d o w s d i s p l a y c o n t e x t , a n d is d e f i n e d i n t h e W i n d o w s t y p e , HDC, i n WinTypes. W i n d o w s a c t u a l l y m a n a g e s all d i s p l a y c o n t e x t s for a p p l i c a t i o n s , b u t e a c h a p p l i c a t i o n m u s t u s e a W i n d o w s d i s p l a y c o n t e x t t o d i s p l a y text o r p i c t u r e s ( o t h e r t h a n i n a r e s o u r c e , that i s ) . B e c a u s e d e v i c e c o n t e x t s a r e m e m o r y i n t e n s i v e , t h e y n e e d t o b e r e l e a s e d as s o o n y o u r a p p l i c a t i o n finishes w i t h t h e m . W i n d o w s a l l o w s o n l y five d i s p l a y c o n t e x t s t o b e active i n a n y s i n g l e W i n d o w s session. It's a s i m p l e m a t t e r for y o u r a p p l i c a t i o n t o u s e a d i s p l a y c o n t e x t . T h e following code shows the process:
var DisplayContext : HDC; begin DisplayContext := GetDC(HWindow); { write or draw something } ReleaseDC(HWindow); end; Get Dc is a W i n d o w s A P I f u n c t i o n that a c t u a l l y g e t s t h e d i s p l a y c o n t e x t for t h e i n t e r f a c e e l e m e n t d e s i g n a t e d b y t h e O b j e c t W i n d o w s h a n d l e (HWindow). N o t e a l s o that y o u r a p p l i c a t i o n s c a n ' t u s e t h e s t a n d a r d T u r b o P a s c a l Read, Readln, Write, a n d Writeln p r o c e d u r e s t o d i s p l a y text. T h e y m u s t u s e t h e W i n d o w s f u n c t i o n TextPut t o w r i t e t o a d i s p l a y c o n t e x t :
4 — I n h e r i t i n g a n Interface
TextOut(DisplayContext,X,Y,S,StrLen(S)); w h e r e X a n d Y are t h e s c r e e n c o o r d i n a t e s a n d S is a n u l l - t e r m i n a t e d string ( r e q u i r e d b y W i n d o w s ) . I w i l l talk a b o u t n u l l - t e r m i n a t e d strings i n this c h a p t e r , i n t h e s e c t i o n c a l l e d "Pascal a n d C S t r i n g s , " a n d s h o w y o u h o w t o u s e d i s p l a y c o n t e x t s i n m a n y e x a m p l e s i n later c h a p t e r s .
Using Resources A n o t h e r n a m e f o r t h e g r a p h i c a l e l e m e n t s that c o m p r i s e y o u r W i n d o w s a p p l i c a t i o n is resources. T h e s e r e s o u r c e s ( c u r s o r s h a p e , m e n u s , i c o n s , a n d s o o n ) are similar i n all y o u r a p p l i c a t i o n s , s o it m a k e s s e n s e t o s t o r e t h e m i n files o u t s i d e your source c o d e and link them with your source c o d e w h e n y o u n e e d them. This process eases any modification without affecting y o u r application c o d e . R e c a l l f r o m C h a p t e r 3, " O b j e c t s f o r W i n d o w s , " that r e s o u r c e s are l i n k e d i n a u t o m a t i c a l l y w h e n y o u u s e t h e $R d i r e c t i v e . C h a p t e r 8, " R e s o u r c e s a n d C o n trol O b j e c t s , " also details the u s e o f resources. T h e s e p a r a t i o n o f PAS (Pascal) a n d R E S ( R e s o u r c e ) c o d e is a c r u c i a l a s p e c t o f W i n d o w s p r o g r a m m i n g . Y o u w r i t e y o u r a p p l i c a t i o n s i n P a s c a l (as u s u a l ) b y deriving applications (using O O P techniques). Y o u build a n d modify resources w i t h t h e W h i t e w a t e r R e s o u r c e T o o l k i t (that c o m e s w i t h T u r b o P a s c a l f o r W i n d o w s ) . F i g u r e 4 . 6 illustrates this c o n c e p t .
Program code + Resources = Application
code
(.PAS)(.INC) application
resources
Developing
Figure 4.6. Developing
(.RES)
a Windows
a Windows
a p p l i c a t i o n is a t w o - s t e p
application.
process.
(.EXE)
127
128
Part I — W o r k i n g w i t h T P W
B y s e p a r a t i n g c o d e a n d r e s o u r c e s , y o u transfer m a n a g e m e n t r e s p o n s i bility f o r r e s o u r c e s f r o m t h e s o u r c e c o d e t o W i n d o w s . Y o u r s o u r c e c o d e w a n t s t o f o c u s o n its s p e c i f i c s , n o t o n W i n d o w s , s o this is n e a t p a c k a g i n g . R e s o u r c e s are d a t a c h a r a c t e r i z e d b y t h e f o l l o w i n g t y p e s : •
Accelerators
• Bit m a p s •
Cursors
•
Icons
• Dialog boxes •
Menus
•
Strings
A n a c c e l e r a t o r is a k e y (or c o m b i n a t i o n o f keys) that y o u c a n u s e as a shortcut for m a k i n g m e n u selections. For e x a m p l e , y o u can define an accelerator (Shift-Delete, for example) to replace a m e n u selection (Edit-Cut, for example). A bit m a p is a p i c t u r e , o r m o r e specifically, t h e d a t a r e p r e s e n t i n g a p i c t u r e . It is m a d e u p o f p i x e l s ( d o t s ) . A c u r s o r is t h e o b j e c t o n - s c r e e n that r e p r e s e n t s t h e p o s i t i o n for t h e n e x t i n p u t . I n t e x t - b a s e d a p p l i c a t i o n s , a c u r s o r is e i t h e r a b l o c k , a l i n e , o r s o m e t h i n g i n b e t w e e n . I n W i n d o w s a p p l i c a t i o n s , a c u r s o r is a 32-by-32-pixel bit m a p . A W i n d o w s c u r s o r c a n b e o n e o f m a n y d i f f e r e n t s h a p e s , a n d is itself a bit m a p . A n i c o n is t h e g r a p h i c a l s c r e e n e l e m e n t that r e p r e s e n t s y o u r a p p l i c a t i o n p r o g r a m ' s state. Y o u select a n i c o n f r o m t h e W i n d o w s P r o g r a m M a n a g e r ' s w i n d o w t o r u n p r o g r a m s , for e x a m p l e . A n i c o n , t o o , is a bit m a p . A d i a l o g b o x , w h i c h is a bit m o r e c o m p l i c a t e d , is a n i n p u t s c r e e n (or w i n d o w ) for i n s e r t i o n o f i n f o r m a t i o n i n y o u r a p p l i c a t i o n . T h e d i a l o g b o x c a n b e baritones or contain other W i n d o w s graphical elements (called controls). T h e resource data associated with a dialog b o x specifies the dialog b o x ' s s i z e , s c r e e n l o c a t i o n , a n d text l a b e l s . A m e n u d i s p l a y s a p p l i c a t i o n o p t i o n s a n d e n a b l e s y o u t o select o n e . T h e m e n u ' s resource identifies the o r d e r a n d n u m b e r o f these o p t i o n s . S t r i n g s are text d i s p l a y e d b y a p p l i c a t i o n m e n u s , d i a l o g b o x e s , e r r o r m e s s a g e s , a n d s o o n . S t r i n g s d o n ' t h a v e t o b e s p e c i f i e d as r e s o u r c e s , b u t m a i n t a i n i n g t h e m as r e s o u r c e s h e l p s k e e p y o u r s p e c i f i c a p p l i c a t i o n c o d e a n d its v i s u a l a s p e c t s s e p a r a t e . C h a p t e r 8, " R e s o u r c e s a n d C o n t r o l O b j e c t s , " details t h e u s e o f t h e Resource Toolkit and the Resource W o r k s h o p . Until then, the B a s i c I nt e r f a c e l o a d s e x i s t i n g r e s o u r c e s that I've a l r e a d y d e s i g n e d a n d c o m p i l e d i n a B a s i c l n t e r f a c e r e s o u r c e file ( W I F . R E S ) . It s u p p l i e s t h e r e s o u r c e s y o u n e e d
4 — I n h e r i t i n g a n Interface
f o r m a n y a p p l i c a t i o n s , a n d saves y o u r h a v i n g t o l e a r n e v e r y a s p e c t o f W i n d o w s p r o g r a m m i n g at o n c e . It's a l s o a n o t h e r e x a m p l e o f n o t r e i n v e n t i n g w h e n y o u d o n ' t h a v e t o , a s u b - t h e m e o f The Tao of Objects. U n t i l C h a p t e r 8 , " R e s o u r c e s a n d C o n t r o l O b j e c t s , " all t h e r e s o u r c e s y o u n e e d t o u s e w i t h t h e Basiclnterface c a n b e l i n k e d i n t o y o u r p r o g r a m u s i n g t h e $R c o m p i l e r d i r e c t i v e :
$R WIF.RES If y o u f e e l y o u h a v e t o k n o w e v e r y t h i n g at o n c e , s k i p o v e r t o C h a p t e r 8 f o r r e s o u r c e d e s i g n d e t a i l s . T h e c o m p l e t e WIF.RES file ( c r e a t e d w i t h t h e W h i t e w a t e r R e s o u r c e T o o l k i t ) is o n t h e d i s k i n t h e b a c k o f this b o o k . Y o u d o n ' t h a v e t o u s e WIF.RES t o u s e t h e Basiclnterface, h o w e v e r . U n t i l y o u g e t t o C h a p t e r 8 , just u s e t h e COOKBOOK. RES r e s o u r c e file p a c k a g e d w i t h T u r b o Pascal f o r W i n d o w s . It d o e s just fine. T o i n c l u d e t h e COOKBOOK.RES, u s e t h e $R directive:
$R Cookbook.res
Pascal and C Strings T h e W i n d o w s A P I r e q u i r e s that strings b e n u l l - t e r m i n a t e d , t h e f o r m a t u s e d b y C . I n o t h e r w o r d s , a s t r i n g is r e p r e s e n t e d as a s e q u e n c e o f c h a r a c t e r s t e r m i n a t e d b y a NULL (#0). T u r b o P a s c a l for W i n d o w s s t o r e s n u l l - t e r m i n a t e d strings as arrays o f c h a r a c t e r s :
type NTstring = array[0..79] of Char; A n u l l - t e r m i n a t e d s t r i n g i n T u r b o Pascal for W i n d o w s c a n b e as l o n g as 6 5 , 5 3 5 c h a r a c t e r s (a l i m i t a t i o n i m p o s e d b y D O S a n d W i n d o w s ) . T u r b o Pascal s t o r e s its s t a n d a r d strings i n t h e " s t r i n g " t y p e ; a l e n g t h b y t e f o l l o w e d b y a s e q u e n c e o f as m a n y as 2 5 5 c h a r a c t e r s .
type TPstring = string[80]; B e c a u s e W i n d o w s doesn't r e c o g n i z e T u r b o Pascal strings, y o u r applicat i o n m u s t e i t h e r u s e n u l l - t e r m i n a t e d strings e x c l u s i v e l y o r c o n v e r t a n y Pascal strings t o n u l l - t e r m i n a t e d b e f o r e p a s s i n g t h e m t o W i n d o w s (to d i s p l a y , for example). T h e strings u n i t s u p p l i e d b y T u r b o Pascal for W i n d o w s p r o v i d e s t h e c o n v e r s i o n f u n c t i o n s a n d a c o m p l e t e m a n i p u l a t i o n p a c k a g e for h a n d l i n g n u l l terminated strings.
129
130
Part I — W o r k i n g w i t h T P W
S o m e o f t h e f u n c t i o n s i n t h e strings u n i t a r e • StrPas: C o n v e r t s a n u l l - t e r m i n a t e d string t o a T u r b o Pascal string • StrPCopy: C o p i e s a T u r b o P a s c a l string i n t o a n u l l - t e r m i n a t e d string • StrPos: R e t u r n s a p o i n t e r t o t h e first o c c u r r e n c e o f a s u b s t r i n g i n a n u l l - t e r m i n a t e d string (similar t o Pos f o r T u r b o P a s c a l strings) • StrLower: C o n v e r t s a n u l l - t e r m i n a t e d string t o l o w e r c a s e T w e n t y o r s o o f t h e s e f u n c t i o n s a r e i n t h e strings u n i t y o u n e e d t o u s e if y o u d i s p l a y strings i n W i n d o w s . A d d this u n i t t o t h e Basiclnterface:
uses strings
A Few Rules B e f o r e y o u g e t o n w i t h t h e Basiclnterface, let's s u m u p a f e w " r u l e s " y o u need to keep in m i n d w h e n y o u develop Windows applications. Y o u r application creates interface objects (using O b j e c t W i n d o w s ) , b u t allows W i n d o w s t o h a n d l e t h e interface e l e m e n t s they represent. Y o u r a p p l i c a t i o n a l l o w s W i n d o w s t o h a n d l e m e m o r y m a n a g e m e n t (discussed in Chapter 9, "Memory Matters"). Y o u r application must define message-response methods in order to intercept W i n d o w s messages (to process m o u s e events, for e x a m p l e ) . Y o u r applications must send a message to Windows G D I functions to draw graphics in a w i n d o w o r print. Y o u r a p p l i c a t i o n u s e s r e s o u r c e s c o m p i l e d o u t s i d e y o u r T u r b o Pascal source code to implement m e n u s , dialogs, and so o n .
Adding Dialogs Most of your applications use the important resource, a dialog. Dialogs can b e modal or modeless. W h e n W i n d o w s displays a m o d a l dialog application, execution in other w i n d o w s is s u s p e n d e d u n t i l t h e u s e r r e s p o n d s t o t h e d i a l o g . I n o t h e r w o r d s , t h e u s e r c a n n o t s e l e c t o r u s e t h e p a r e n t w i n d o w ( t h e MainWindow i n t h e Basiclnterface) u n t i l s h e c l i c k s o n t h e O K o r C a n c e l o p t i o n , w h i c h d e s t r o y s t h e d i a l o g . F o r D O S u s e r s , this s i t u a t i o n is s i m i l a r t o u s i n g a P A U S E ; n o t h i n g h a p p e n s u n t i l a n o t h e r k e y is p r e s s e d . D i s p l a y i n g a d i a l o g that is m o d e l e s s , o n t h e o t h e r h a n d , d o e s n ' t s u s p e n d a p p l i c a t i o n o p e r a t i o n , a n d t h u s c a n b e u s e d r e p e a t e d l y d u r i n g t h e life o f t h e application. I n other w o r d s , the user doesn't have t o click a b u t t o n in the dialog to continue processing in other windows.
4 —Inheriting an Interface
For now, add a modal dialog to the Basiclnterf ace, because that's the one needed most often. Adding a dialog to an application is basically a two-step process, and a simple one, thanks to ObjectWindows. In short, link a dialog resource to the Pascal application code that requests the dialog through the application's ExecDialog method. Windows actually creates the dialog box (a window) for the application. Y o u r source code just defines its behavior and uses the standard dialog resources packaged with Turbo Pascal for Windows. Thus, most of the w o r k has already been done for you. T o use a standard input dialog: 1. Include the S T D D L G S unit: uses StdDlgs 2. Construct and execute the dialog in one step that basically looks like this: var Applicationl if
: Basiclnterface;
Applicationl .ExecDialog(New(PInputDialog, Init(@Self, then { handle dialog results } A
1
ExecDialog creates the dialog's (the interface object's) corresponding element by sending a message to the dialog object's Execute method. It checks first, though, to ensure that there's enough m e m o r y to create the dialog. Listing 4.5 (WIF4. PAS) shows the n e w version of the Basiclnterf ace with modal dialog capability. Figure 4.7 shows a screen produced by the code in listing 4.5. Listing
4.5- Basiclnterf
unit WIF4;
ace with modal
dialog
capability.
{ Contains Basic Windows application interface derived from ObjectWindows }
interface uses WObjects, WinTypes, WinProcs, Strings, StdDlgs; type
{ { { { {
ObjectWindows library of objects } Windows types: for accessing the API } Windows processes: for accessing the API } Null-terminated strings unit } Standard dialogs unit }
BasicApplication = object(TApplication) continues
131
132
Parti—Working with T P W
Listing
4.5-
continued
{ Derive an application object } FirstApplication : boolean; procedure InitMainWindow; virtual; { Init a main window } procedure InitApplication; virtual; end; PMainWindow = "MainWindow; MainWindow = object(TWindow) DisplayContextl : HDC; { Handle to a display context } ButtonDown : boolean; constructor Init(AParent : PWindowsObject; ATitle: PChar); procedure WMLButtonDown(var Msg: TMessage); virtual wm_first + wm_LButtonDown; procedure WMLButtonUp(var Msg: TMessage); virtual wm_first + wm_LButtonUp; procedure WMRButtonDown(var Msg: TMessage); virtual wm_first + wm_RButtonDown; procedure WMRButtonUp(var Msg: TMessage); virtual wm_first + wm_RButtonUp; procedure WMMouseMove(var Msg: TMessage); virtual wm_first + wm_MouseMove; end; implementation { BasicApplication method implementation } procedure BasicApplication.InitMainWindow; begin if FirstApplication then MainWindow := New(PMainWindow, Init(nil, 'Basic Windows Interface')) else MainWindow := New(PMainWindow, Init(nil,'Additional Instance of BI')); end; procedure BasicApplication.InitApplication; begin FirstApplication := True; end; { New MainWindow constructor } constructor MainWindow.Init(AParent begin
: PWindowsObject; ATitle : PChar);
4 — I n h e r i t i n g a n Interface
TWindow.Init(AParent, ATitle); {Send message to ancestor's constructor} ButtonDown := False; end; { Abstract implementation of basic MainWindow Mouse events } procedure MainWindow.WMLButtonDown(var Msg: TMessage); begin end; procedure MainWindow.WMLButtonUp(var Msg: TMessage); begin end; procedure MainWindow.WMRButtonDown(var Msg: TMessage); { popup dialog if Right Button down } var InputText : array[0..15] of char; begin if not ButtonDown then begin if Application".ExecDialog(New(PInputDialog, Init(@Self,'Messagel ,'Message2', InputText, SizeOf(InputText)))) = id_0k then begin { Deal with message here } end; end; end; 1
procedure MainWindow.WMRButtonUp(var Msg: TMessage); begin end; procedure MainWindow.WMMouseMove(var Msg: TMessage); begin end; end.
133
134
Parti—Working with T P W
Figure
4.7. A basic Windows interface
screen.
Adding a File Dialog A s e c o n d t y p e of d i a l o g y o u u s e in a n y of y o u r a p p l i c a t i o n s that w o r k w i t h files is t h e file d i a l o g . A s y o u ' r e no d o u b t expecting, putting a file d i a l o g in y o u r a p p l i c a t i o n is no t r o u b l e at a l l . Y o u just u s e t h e o n e that O b j e c t W i n d o w s provides; it is a l r e a d y c o m p l e t e for m a n y p u r p o s e s . T o a d d a file d i a l o g to t h e Basiclnterf a c e : 1. U s e t h e stdlgs u n i t (which is already b e i n g u s e d in t h e Basiclnterface): uses Stdlgs 2. I n c l u d e its corresponding resource file ( t h e Basiclnterf ace is already using a resource file that handles file d i a l o g s — W I F . R E S ) : $R WIF.RES 3. Initialize t h e file d i a l o g a n d s e n d a m e s s a g e t o it in o n e s t e p ( m u c h t h e w a y y o u initialized a m o d a l d i a l o g earlier): if Applicationl .ExecDialog(New(PFileDialog, Init(@Self,PChar(sd_FileOpen),AFile))) = id_0K then begin OpenFile(AFile); end; A
4 — I n h e r i t i n g a n Interface
F i g u r e 4 . 8 s h o w s a File O p e n d i a l o g . T h e File O p e n d i a l o g u s e s a list b o x t o d i s p l a y t h e files o n t h e c u r r e n t d i r e c t o r y . T h e u s e r c a n e i t h e r t y p e t h e file t o o p e n it, o r d o u b l e - c l i c k t h e p a r t i c u l a r file. T h e file is t h e n o p e n e d w i t h O p e n F i l e .
Figure
4.8. A file dialog
example.
P F i l e D i a l o g i s a pointer to the stock dialog defined in O b j e c t W i n d o w s .
Two Kinds of File Dialogs File d i a l o g s c o m e i n t w o s t o c k f o r m s : 1. O n e f o r o p e n i n g files 2. O n e f o r s a v i n g files S p e c i f y t h e o n e y o u w a n t i n t h e name p a r a m e t e r o f t h e c o n s t r u c t o r c a l l . F o r a n o p e n file: sd_FileOpen F o r a save file: sd
FileSave
135
136
Part I — W o r k i n g w i t h T P W
Constants A n o t h e r a s p e c t o f O b j e c t W i n d o w s p r o g r a m m i n g that m a n y p r o g r a m m e r s w o r k i n g i n D O S - b a s e d e n v i r o n m e n t s o f t e n i g n o r e is t h e u s e o f c o n s t a n t s . ObjectWindows defines n u m e r o u s constants to represent c o m m a n d m e s s a g e s : b u t t o n , c h e c k b o x , a n d r a d i o - b u t t o n states; e r r o r s ; c h i l d I D m e s s a g e s ; n o t i f i c a t i o n m e s s a g e s ; s t r e a m s m e s s a g e s ; transfer flags; b i t - m a p p e d fields; a n d W i n d o w s m e s s a g e s . T h e u s e o f c o n s t a n t s i m p r o v e s p r o g r a m r e a d a b i l i t y a n d m a k e s it e a s i e r f o r a p r o g r a m to c h a n g e in response to changes in subsequent versions of Windows. T h e c o m p l e t e B a s i c l n t e r f a c e i n listing 4.7 ( W I F . P A S ) at t h e e n d o f t h e chapter defines many of the most c o m m o n l y used constants. Y o u can, of course, c o m m e n t o u t t h e o n e s that y o u r a p p l i c a t i o n d o e s n ' t n e e d a n d a d d t h e o n e s it d o e s . T h e c o n s t a n t s e c t i o n i n t h e B a s i c l n t e r f a c e serves as a h a n d y t e m p l a t e for adding y o u r o w n constants.
Controls At this p o i n t , t h e B a s i c l n t e r f a c e u s e s a s i m p l e ( a l m o s t d e f a u l t ) m a i n w i n d o w (precisely, a m a i n w i n d o w p l u s a m e n u ) . T h e m a i n w i n d o w c a n b e m u c h m o r e complicated, however, by other w i n d o w objects and controls. For example, y o u c a n vary t h e style, c o l o r s , a n d s o o n , o f t h e m a i n w i n d o w a n d a t t a c h v a r i o u s c h i l d w i n d o w s t o it. F u t u r e e x a m p l e s s h o w y o u h o w t o a d d a n d vary t h e s e w i n d o w o b j e c t s , w h i c h a r e n ' t n e c e s s a r y for t h e B a s i c l n t e r f a c e . F o r n o w , h o w e v e r , y o u s h o u l d b e a w a r e o f w h a t c o n t r o l s are a n d h o w t h e y ' r e u s e d . C o n t r o l s are u s e r i n t e r f a c e d e v i c e s . T a b l e 4.1 s h o w s t h e c o n t r o l s that ObjectWindows supports. Table
4.1.
Windows
controls
supported
Control
Object
Type
Check box Combo box Edit control Group box List b o x M D I client Push button Radio button S c r o l l bar Static c o n t r o l
TCheckBox TComboBox TEdit TGroupBox TListBox TMDIClient TButton TRadioButton TScrollBar TStatic
by
ObjectWindows.
4 —Inheriting an Interface
Figure 4.9 shows what a few of these controls look like.
Figure
4.9. Combo box
controls.
Creating a control is another two-step process: 1. Construct the control object. 2. Construct its corresponding control element. Usually, you take both of these steps in the constructor of the parent window. For example, the following fragment constructs a push button: PB1 := New(PButton, Init(@Self, id_PB1, 'AButton', 30,50,300,19,False); Controls can send messages in response to user events (a user clicking a button,forexample). By default, ObjectWindows responds to these messages, if your application doesn't. Usually you want your application to handle the message itself, however. The following fragment shows h o w your application defines a response method to a button-clicked message: AMainWindow = object(MainWindow) PB1 : PButton; procedure IDPB1(var Msg: TMessage); virtual id_First + id_PB1; { other methods here } end;
137
138
Parti—Working with T P W
T h e f o l l o w i n g f r a g m e n t i m p l e m e n t s t h e IDPB1 m e t h o d : p r o c e d u r e AMainWindow.IDPB1(var Msg: begin { response here } end;
TMessage);
T h e B a s i c l n t e r f a c e , as I s a i d , d o e s n ' t i n c l u d e e v e r y c o n t r o l b e c a u s e c o n t r o l s are fairly s p e c i a l i z e d . I n s t e a d , I s h o w y o u h o w t o u s e t h e m as y o u n e e d t h e m , as y o u g o a l o n g . O n e I u s e o f t e n is t h e list b o x , w h i c h y o u l e a r n h o w t o use next.
Adding list Boxes A list b o x is a k i n d o f w i n d o w (it's d e f i n e d b y a rectangle o n t h e s c r e e n ) that s h o w s t h e u s e r a list o f information. T h e information c a n b e integers, strings, a n d s o o n . T h e u s e r c a n click o n a list item, a n d t h e s e l e c t e d item c a n b e transferred into a n o t h e r variable o r c a n trigger o t h e r m e s s a g e s a n d a c t i o n s . F i g u r e 4 . 1 0 s h o w s a n e x a m p l e list b o x .
Figure
4.10. A list box
example.
Listing 4 . 6 s h o w s t h e c o d e r e q u i r e d t o c r e a t e t h e list b o x d i s p l a y e d i n figure 4 . 1 0 .
4 — I n h e r i t i n g a n Interface
Listing
4.6. Code
to create
a list
139
box.
unit LBWind; interface uses Strings, WObjects, WinTypes, WinProcs; const id_LB1 = 201; id_BN2 = 203; type PListBoxWindow = "ListBoxWindow; ListBoxWindow = object(TWindow) LB1: PListBox; constructor Init(AParent: PWindowsObject; ATitle: PChar); procedure SetupWindow; virtual; { override TWindow's SetUpWindow } procedure IDLB1(var Msg: TMessage); virtual id_First + id_LB1; procedure IDBN2(var Msg: TMessage); virtual id_First + id_BN2; end; implementation constructor ListBoxWindow.Init(AParent: PWindowsObject; ATitle: PChar); begin TWindow.Init(AParent, ATitle); DisableAutoCreate; Attr.Style := ws_PopupWindow or ws_Caption or ws_Visible; Attr.X := 100; Attr.Y := 100; Attr.W := 200; Attr.H := 200; LB1 := New(PListBox, Init ((aSelf, id_LB1, 20, 20, 180, 80)); end; procedure ListBoxWindow.SetupWindow; begin TWindow.SetupWindow; { Fill the list box with strings } LB1 .AddString('Alison'); LB1".AddString('Marci'); LB1".AddString('Lizzie'); LB1".AddString('Amy'); A
continues
140
Part I — W o r k i n g w i t h T P W
Listing
4.6.
continued
LB1 .AddString('Tammy ); LB1 .AddString('Susan'); LB1 .SetSelIndex(0); end; A
1
A
A
{ A generic example of doing something with the list box } procedure ListBoxWindow.IDLB1(var Msg: TMessage); var SelString: array[0..25] of Char; begin if Msg.LParamHi = lbn_DblClk then begin LB1 .GetSelString(SelString, 25); end; end; A
procedure ListBoxWindow.IDBN2(var Msg: TMessage); begin CloseWindow; { Clean up } end; end. List box is a w i n d o w o b j e c t y o u c o n s t r u c t at s p e c i f i c c o o r d i n a t e s , w i t h a s p e c i f i c style, after s e n d i n g a m e s s a g e t o t h e b a s e w i n d o w o b j e c t t y p e , TWindow, to h a n d l e default construction:
constructor ListBoxWindow.Init(AParent: PWindowsObject; ATitle: PChar); begin TWindow.Init(AParent, ATitle); DisableAutoCreate; { So that you can create your own style } Attr.Style := ws_PopupWindow or ws_Caption or ws_Visible; Attr.X := 100; Attr.Y := 100; Attr.W := 200; Attr.H := 200; LB1 := New(PListBox, Init((PSelf, id_LB1, 20, 20, 180, 80)); end; Y o u t h e n set u p t h e list b o x b y a d d i n g s t r i n g s :
procedure ListBoxWindow.SetupWindow; begin TWindow.SetupWindow; { Fill the list box }
4 — I n h e r i t i n g a n Interface
LB1 .AddString('Alison'); A
LB1*.AddString('Marci'); end; T h e e x a m p l e i n listing 4.6 l o a d s t h e strings y o u w a n t t o a d d t o t h e List Box f r o m t h e s o u r c e c o d e , b u t a m o r e g e n e r a l a p p r o a c h a d d s t h e strings i n r e s p o n s e to o n g o i n g c h a n g e s — f o r example, user input, based o n a change in the a p p l i c a t i o n itself, o r a file f c r e x a m p l e s . I n C h a p t e r 6, " P a i n t i n g , C o l l e c t i n g , a n d S t r e a m i n g , " w h e n s t r e a m s a r e d i s c u s s e d , t h e ListBox is u s e d i n a m o r e i n t e r e s t i n g m a n n e r . T h e ListBoxWindow. IDLB1 m e t h o d h a n d l e s m o u s e d o u b l e c l i c k s , b u t at this p o i n t , it d o e s n ' t d o a n y t h i n g u s e f u l . It's just a g e n e r i c e x a m p l e o f h o w y o u m i g h t u s e it. I n C h a p t e r 7, " M a n y W i n d o w s : A M u l t i - D o c u m e n t I n t e r f a c e , " y o u a d d a h e l p w i n d o w t o t h e b a s i c M D I i n t e r f a c e that u s e s t h e list b o x w i n d o w t o provide help information. T h e ListBoxWindow. IDBN2 m e t h o d d e s t r o y s t h e list b o x w h e n t h e u s e r clicks t h e C l o s e b o x i n t h e u p p e r - l e f t c o r n e r o f t h e list b o x w i n d o w : procedure ListBoxWindow.IDBN2(var begin CloseWindow; { clean up } end;
Msg: TMessage);
Message Boxes Although ObjectWindows does an amazing a m o u n t of work for y o u , sometimes y o u w a n t t o b y p a s s O b j e c t W i n d o w s a n d s e n d m e s s a g e s t o t h e A P I directly. Y o u d o this b y u s i n g t h e WinTypes a n d WinProcs u n i t s i n y o u r s o u r c e c o d e : uses WinTypes, WinProcs T h e Basiclnterface a l r e a d y u s e s t h e s e u n i t s , b u t y o u still n e e d t o i n c l u d e t h e m i n a n y n e w u n i t that n e e d s t o a c c e s s t h e m directly. A p a r t i c u l a r l y h e l p f u l e x a m p l e o f s e n d i n g m e s s a g e s t o t h e A P I is t o p u t a m e s s a g e b o x o n t h e s c r e e n . F i g u r e 4 . 1 1 s h o w s a m e s s a g e b o x that t h e f o l l o w i n g f r a g m e n t ( a d d e d t o t h e Basiclnterface) c r e a t e d : var MessageResponse begin MessageResponse end;
: integer; := MessageBox(HWindow...
141
1 4 2 Parti—Working with T P W
Figure
4.11. Popping up a message box.
Closing an Application Typically, W i n d o w s applications terminate w h e n the user double clicks the control-menu box in the upper-left corner of its main window. W h e n this happens to an application derived from the Basiclnterface, a n u m b e r of messages are sent and received by the BasicApplication and MainWindow before BasicApplication is destroyed by destructor, Done. For the most part, you can ignore the complex processing that goes o n behind the scenes. ObjectWindows does the work again. O n e addition to the Basiclnterface is helpful for double-checking whether the user of your application actually intended to quit. T o double-check, reimplement (override) the MainWindow's CanClose method (that it inherited from TWindow). The following code does the trick: function MainWindow.CanClose: Boolean; var UserResponse; begin CanClose := True; UserResponse := MessageBox(HWindow, Message"! ,Message2, mb_YesNo or mb_IconQuestion); if UserResponse = idYes then CanClose := false; end;
4 — I n h e r i t i n g a n Interface
Wrapping Up the Basiclnterface T h a t d o e s it f o r t h e b a s i c s o f W i n d o w s a p p l i c a t i o n p r o g r a m m i n g , T u r b o Pascal f o r W i n d o w s style. T h e r e ' s m u c h m o r e t o it t h a n c a n b e c o v e r e d i n t h e s e t w o c h a p t e r s , b u t t h e rest is gravy. F r o m h e r e o n I talk a b o u t v a r y i n g t h e i n t e r f a c e to h a n d l e the m u l t i - d o c u m e n t interface ( M D I ) , h o w to use other objects in the O b j e c t W i n d o w s library, a n d h o w t o c r e a t e m a n y d i f f e r e n t k i n d s o f a p p l i c a t i o n s using the B a s i c l n t e r f a c e . T h e c o m p l e t e B a s i c l n t e r f a c e consists of • A basic application • A main window • A generic m o u s e interface • A m e n u a n d other basic resources • M e t h o d s for adding dialogs • A n awareness of device contexts • A f e w time-savers s u c h as c o n s t a n t d e f i n i t i o n s , w i n d o w s m e s s a g e definitions, inclusion of key units, and so o n . Figure 4.12 s h o w s the c o m p l e t e interface on-screen.
Figure
4.12. The complete interface.
143
1 4 4 Parti—Working with T P W
Listing 4.7 (WIF5.PAS) shows the Basiclnterface on-screen. M a n y applications (as I' 11 show you) can begin with the Basiclnterface, and with little or no modification, run in Windows. By using aBasidnterface derived from ObjectWindows, you can ignore most of the hassles programmers traditionally associate with W i n d o w s development. W i n d o w s is a powerful environment, and ifyou use Turbo Pascal for Windows, you don't have to spend months and months coming u p to speed in order to write m a n y applications. Both user and programmer can have a powerful environment to work in without either of them going crazy. Let's hear it for Windows, object-oriented programming, and the language that brings them together: Turbo Pascal for Windows. W h o would have thought that programming W i n d o w s could be this easy? Listing
4.7.
Code for
unit WIF5;
the Basiclnterface
on-screen.
{ Contains Basic Windows application interface derived from ObjectWindows }
interface uses WObjects, WinTypes, WinProcs, Strings, StdDlgs, lbwind; {$R WIF.RES }
{ { { { { {
ObjectWindows library of objects } Windows types: for accessing the API } Windows processes: for accessing the API } Null-terminated strings unit } Standard dialogs unit } List box }
const cm_New cm_Open cm_Save cm_SaveAs cm_Help
= = = = =
101; 102; 103; 104; 901;
id_LB1
= 201;
type BasicApplication = object(TApplication) { Derive an application object } FirstApplication : boolean; procedure InitMainWindow; virtual; { Init a main window }
4 — I n h e r i t i n g a n Interface
145
procedure InitApplication; virtual; end; PMainWindow = "MainWindow; MainWindow = object(TWindow) DisplayContextl : HDC; { Display Context handle } ButtonDown : boolean; { Button-down status flag } constructor Init(AParent : PWindowsObject; ATitle: PChar); procedure WMLButtonDown(var Msg: TMessage); virtual wm_first + wm_LButtonDown; procedure WMLButtonUp(var Msg: TMessage); virtual wm_first + wm_LButtonUp; procedure WMRButtonDown(var Msg: TMessage); virtual wm_first + wm_RButtonDown; procedure WMRButtonUp(var Msg: TMessage); virtual wm_first + wm_RButtonUp; procedure WMMouseMove(var Msg: TMessage); virtual wm_first + wm_MouseMove; procedure ListBox(var Msg: TMessage); virtual cm_First + cm_Help; function CanClose: Boolean; end; implementation { BasicApplication method implementation } procedure BasicApplication.InitMainWindow; begin if FirstApplication then MainWindow := New(PMainWindow, Init(nil, 'Basic Windows Interface')) else MainWindow := New(PMainWindow, Init(nil,'Additional Instance of B I ) ) ; end; 1
procedure BasicApplication.InitApplication; begin FirstApplication := True; end; { New MainWindow constructor } constructor MainWindow.Init(AParent begin
: PWindowsObject; ATitle : PChar); continues
146
Part I — W o r k i n g w i t h T P W
Listing
4.7.
continued
TWindow.Init(AParent, ATitle); { Send msg to ancestor's constructor } Attr.Menu := LoadMenu(HInstance, PChar(100)); { 100 = menu ID } ButtonDown := False; { Set status flag } end; { Abstract implementation of basic MainWindow Mouse events } procedure MainWindow.WMLButtonDown(var Msg: TMessage); begin end; procedure MainWindow.WMLButtonUp(var Msg: TMessage); begin end; procedure MainWindow.WMRButtonDown(var Msg: TMessage); { popup dialog if Right Button down } var InputText : array[0..15] of char; { Vary this for input length } begin if not ButtonDown then begin if Application".ExecDialog(New(PInputDialog, Init(@Self,'Messagel','Message2', InputText, SizeOf(InputText)))) = id_Ok then begin { Deal with message here } end; end; end; procedure MainWindow.WMRButtonUp(var Msg: TMessage); begin end; procedure MainWindow.WMMouseMove(var Msg: TMessage); begin end; procedure MainWindow.ListBox(var Msg: TMessage); var ListBoxWnd: PWindow; begin
4 —Inheriting an Interface
ListBoxWnd := New(PListBoxWindow, Init(@Self, 'List B o x ) ) ; Application".MakeWindow(ListBoxWnd); end; 1
function MainWindow.CanClose: Boolean; var UserResponse; begin CanClose := True; UserResponse := MessageBox(HWindow, Messagel,Message2, mb_YesNo or mb_IconQuestion); if UserResponse = idYes then CanClose := false; end; end.
147
5
CHAPTER
PUTTING PICTURES IN WINDOWS You can no longer
think
in terms
of 25 lines
and 80 columns of text. Charles Petzold
It's w o r t h r e p e a t i n g : W i n d o w s is a c o m p l e x e n v i r o n m e n t , b u t n o t a difficult o n e i n w h i c h t o d e v e l o p a p p l i c a t i o n s if y o u u s e T u r b o Pascal f o r W i n d o w s a n d t h e o b j e c t - o r i e n t e d t e c h n i q u e s b u i l t i n t o O b j e c t W i n d o w s . T h e Basiclnterface y o u d e v e l o p e d i n C h a p t e r 4, " I n h e r i t i n g a n I n t e r f a c e , " e n c a p s u l a t e s m o s t o f t h e c o m p l e x details o f W i n d o w s p r o g r a m m i n g i n t w o o b j e c t s : a n a p p l i c a t i o n a n d its m a i n w i n d o w . A s i m p l e w a y f o r y o u t o d e v e l o p n e w W i n d o w s a p p l i c a t i o n s is t o 1. D e r i v e t h e n e w a p p l i c a t i o n ' s i n t e r f a c e f r o m t h e Basiclnterface (using inheritance). 2. A d d t h e n e w a p p l i c a t i o n ' s s p e c i f i c b e h a v i o r s t o t h e d e r i v e d i n t e r f a c e . Y o u r a p p l i c a t i o n c a n f o c u s o n its specific aspects w h i l e t h e Basiclnterface handles the underlying interface details. B e c a u s e W i n d o w s is b a s e d o n a n e v e n t - d r i v e n a r c h i t e c t u r e , it m a k e s s e n s e t o t h i n k o f y o u r a p p l i c a t i o n s r e a c t i n g t o e v e n t s ( o r e v e n as b e i n g e v e n t s ) . I n o t h e r w o r d s , a n a p p l i c a t i o n ( a n e d i t o r , a s p r e a d s h e e t , o r a n y o t h e r task)
150
Part I — W o r k i n g w i t h T P W
r e s p o n d s t o e v e n t s it l e a r n s a b o u t t h r o u g h e i t h e r W i n d o w s (wm) o r c o m m a n d (cm) m e s s a g e s . A n application's response c a n b e a single action (displaying a dialog, a m e s s a g e o r list b o x , a n d s o o n ) , o r a series o f a c t i o n s (for e x a m p l e , a task consisting o f many functions a n d procedures). In other words, a n application r u n n i n g i n a w i n d o w c a n b e h a v e e x a c t l y as it w o u l d if it w e r e n ' t r u n n i n g i n a w i n d o w . B e c a u s e y o u a l l o w t h e Basiclnterface o r O b j e c t W i n d o w s (if y o u b y p a s s t h e Basiclnterface a n d d e r i v e W i n d o w s b e h a v i o r directly) t o h a n d l e the interface details, y o u r p r o g r a m m i n g c h o r e c a n b e r e d u c e d t o t w o steps. T h e s e i n c l u d e w r i t i n g t h e a p p l i c a t i o n ( t e a c h i n g it h o w t o r e s p o n d t o e v e n t s ) a n d t e a c h i n g it w h e n t o r e s p o n d t o e v e n t s . Y o u c a n t e a c h y o u r a p p l i c a t i o n t o initiate its b e h a v i o r b y r e s p o n d i n g t o v a r i o u s k i n d s o f e v e n t s . I n C h a p t e r 4, " I n h e r i t i n g a n I n t e r f a c e , " f o r e x a m p l e , y o u t a u g h t t h e Basiclnterface t o r e s p o n d i n a g e n e r a l w a y t o m o u s e e v e n t s . O n e o f t h e s i m p l e s t a n d m o s t u s e f u l w a y s t o initiate a n a p p l i c a t i o n ' s b e h a v i o r , h o w e v e r , is t o h a v e it r e s p o n d t o a u s e r s e l e c t i n g i t e m s f r o m a m e n u . I n this c h a p t e r , I f o c u s o n this m e n u r e s p o n s e a s p e c t b y d e r i v i n g f r o m t h e Basiclnterface several a p p l i c a t i o n s that r e s p o n d t o m e n u c o m m a n d m e s s a g e s . I b e g i n b y s h o w i n g t h e b a s i c s o f this a p p r o a c h , d e v e l o p i n g a p p l i c a t i o n s that s i m u l a t e g e n e r a l tasks a n d u s i n g d i s p l a y c o n t e x t s a n d W i n d o w s f u n c t i o n s t o d i s p l a y g r a p h i c i m a g e s . I finally l e a d u p t o a m u l t i t a s k i n g v e r s i o n o f t h e
Basiclnterface. I u s e m o d e l i n g s y s t e m s , w h i c h are g e n e r a l - p u r p o s e , t o s h o w y o u h o w y o u can d e v e l o p y o u r o w n multitasking system by p l u g g i n g y o u r applications into this v e r s i o n o f t h e Basiclnterface. I n e a c h e x a m p l e i n this c h a p t e r y o u c a n associate a m e n u a n d its c o r r e s p o n d i n g m e n u c o m m a n d m e s s a g e s t o activate task w i n d o w s . M e n u s a r e a n elegant a n d simple way to allow your users to control a W i n d o w s application. I n t h e e x a m p l e s I l e a d y o u t h r o u g h , y o u find t h e u s e r d y n a m i c a l l y c r e a t i n g a n d d e s t r o y i n g task w i n d o w s at r u n - t i m e , w h e n y o u r p r o g r a m m i n g effort is l o n g gone.
Menus, IDs, and Messages E a c h m e n u is a r e s o u r c e a n d a l s o h a s a r e s o u r c e I D y o u u s e t o identify t h e m e n u . R e c a l l f r o m t h e B a s i c I n t e r f a c e that y o u a t t a c h a s p e c i f i c m e n u t o a w i n d o w b y 1. I n c l u d i n g t h e m e n u r e s o u r c e . F o r e x a m p l e :
{$R WIF.RES}
5 — P u t t i n g Pictures i n W i n d o w s
2. S e t t i n g t h e m e n u attribute variable f o r t h e w i n d o w y o u ' r e a t t a c h i n g t h e menu to: Attr.Menu
:= LoadMenu(HInstance, PChar(100));
T y p i c a l l y , y o u set t h e attribute i n t h e w i n d o w ' s c o n s t r u c t o r . F o r e x a m p l e : constructor ATask.Init(AParent: PWindowsObject; ATitle: PChar); begin TWindow.Init(AParent, ATitle); Attr.Style := ws_PopupWindow or ws_Caption or ws_Visible; Attr.Menu := LoadMenu(HInstance, P C h a r ( 9 9 ) ) ; (* details here *) end; W h e n t h e m a i n w i n d o w f o r a n a p p l i c a t i o n is d i s p l a y e d , it a p p e a r s w i t h t h e m e n u c o r r e s p o n d i n g t o Att r. Menu's I D . O p t i o n a l l y , y o u c o u l d u s e a s y m b o l i c i d e n t i f i e r t o r e p r e s e n t t h e m e n u , w h e n y o u set Attr. Menu: Attr.Menu
:= LoadMenu(HInstance,
'Taskl
Menu ); 1
W h e t h e r y o u u s e a PChar o r a s y m b o l i c identifier w i t h t h e Basic I nt e rf ace is u p t o y o u . Y o u a s s o c i a t e a n I D w i t h a m e n u u s i n g t h e W h i t e w a t e r R e s o u r c e T o o l k i t (see C h a p t e r 8, " R e s o u r c e s a n d C o n t r o l O b j e c t s , " f o r t h e details o f h o w t o set u p a m e n u a n d g i v e it a c o r r e s p o n d i n g I D ) . Y o u a l s o c r e a t e t h e s p e c i f i c s e l e c t i o n s available i n a m e n u i n t h e r e s o u r c e file a n d test t h e m e n u i n t h e W h i t e w a t e r R e s o u r c e T o o l k i t . H o w e v e r , t h e r e s p o n s e s y o u w a n t t h e a p p l i c a t i o n t o m a k e (in r e s p o n s e t o m e n u s e l e c t i o n s ) m u s t b e d e f i n e d i n y o u r T u r b o Pascal s o u r c e c o d e . I n o t h e r w o r d s , y o u specify a r e s o u r c e ' s attributes (in this c a s e , a m e n u ) i n t h e r e s o u r c e file, b u t y o u specify t h e s p e c i f i c r e s p o n s e s a n a p p l i c a t i o n m a k e s t o a m e n u i n t h e T u r b o Pascal s o u r c e c o d e file. T h i s p r o c e s s o p e n s u p t h e p o s s i b i l i t y o f c r e a t i n g a n d t e s t i n g m e n u s before y o u actually write the application. Y o u c a n d e v e l o p the l o o k a n d f e e l o f y o u r a p p l i c a t i o n ( p r o t o t y p e it) b e f o r e y o u start w r i t i n g c o d e ; a very u s e f u l p r o s p e c t i n d e v e l o p i n g l a r g e a p p l i c a t i o n s that i n v o l v e m o r e t h a n o n e programmer. W h e n a u s e r selects a m e n u , t h e w i n d o w t h e m e n u is a t t a c h e d t o r e c e i v e s a Windows c o m m a n d message. Y o u r application then processes the c o m m a n d m e s s a g e b y d e f i n i n g a r e s p o n s e m e t h o d f o r e a c h s e l e c t i o n . {Note: T h i s is similar t o h o w t h e Basiclnterface h a n d l e s W i n d o w s c o m m a n d m e s s a g e s . A l s o n o t e that W i n d o w s c o m m a n d m e s s a g e s a r e p r e f i x e d b y wm_ a n d m e n u c o m m a n d m e s s a g e s b y cm_; t h e y r e p r e s e n t e n t i r e l y different classes o f m e s s a g e s . ) A m e n u c o m m a n d m e s s a g e m i g h t l o o k like t h i s , f o r e x a m p l e : procedure CMNewMethod(var Msg: TMessage); virtual cm_First + 101;
151
152
Parti—Working with T P W
w h e r e c m F i r s t is a c o n s t a n t ( d e f i n e d b y O b j e c t W i n d o w s ) d e s i g n a t i n g t h e b e g i n n i n g o f a r a n g e o f c o m m a n d c o n s t a n t s . 101 is t h e s p e c i f i c M e n u I D f o r this m e t h o d (CmNewMethod). F o r c o n s i s t e n c y , I u s e t h e cm_ p r e f i x t o n a m e a n y m e t h o d that r e s p o n d s t o a c o m m a n d m e s s a g e , s o it s h o u l d b e e a s y t o s p o t t h e s e m e t h o d s w i t h i n objects. Y o u c a n , if y o u w a n t , u s e c o n s t a n t s t o r e p r e s e n t t h e s e M e n u I D s , a n d substitute the constant for the I D . Again for consistency, I u s e the same prefix (cm_3 t o d e s i g n a t e a n y c o m m a n d m e s s a g e c o n s t a n t . F o r e x a m p l e :
const cm_New = 101 procedure CMNewMethod(var Msg: TMessage); virtual cm_First + cm_New; T h e m e n u I s h o w e d y o u i n t h e Basiclnterf ace ( c o n t a i n e d i n W I F . R E S ) d o e s n ' t d o a n y t h i n g . It's t h e r e strictly i n t h e abstract t o s h o w y o u w h a t a w i n d o w w i t h a m e n u l o o k s l i k e . It is a s i m p l e m a t t e r t o m a k e t h e m e n u u s e f u l . T o make an application respond to m e n u selections: 1. D e f i n e a c o n s t a n t that c o r r e s p o n d s t o a m e n u m e s s a g e I D (in y o u r T u r b o Pascal c o d e ) . 2. D e f i n e a n d i m p l e m e n t a m e t h o d that r e s p o n d s t o t h e m e n u m e s s a g e (in y o u r T u r b o Pascal c o d e ) . 3. A d d t h e n e w m e n u s e l e c t i o n o p t i o n t o t h e m e n u r e s o u r c e ( u s i n g t h e Whitewater Resource Toolkit). T h e Basiclnterf ace a l r e a d y h a n d l e s t h e a p p l i c a t i o n - W i n d o w s c o n n e c tion, so y o u have to concentrate only o n h o w each n e w application works. R e s p o n d i n g t o e v e n t s ( m e n u c o m m a n d m e s s a g e s , m o u s e , a n d s o f o r t h ) is t h e o n l y W i n d o w s - s p e c i f i c a s p e c t y o u h a v e t o w o r r y a b o u t at this j u n c t u r e . B e c a u s e e a c h a p p l i c a t i o n is a s s o c i a t e d w i t h its m a i n w i n d o w , a n d b e c a u s e I ' m l e a d i n g y o u u p t o a m i n i - m u l t i t a s k i n g s y s t e m w i t h i n W i n d o w s (itself a m u l t i t a s k i n g s y s t e m ) , y o u r first r e s p o n s e t o a m e n u s e l e c t i o n s h o u l d b e t h e c r e a t i o n o f a n e w w i n d o w (call it a c h i l d w i n d o w ) that c o n t a i n s t h e a p p l i c a t i o n . I n o t h e r w o r d s , say that y o u r m e n u o p t i o n is c a l l e d " T a s k l , " a n d t h e MainWindow's r e s p o n s e t o t h e u s e r s e l e c t i n g T a s k l is t o c r e a t e a c h i l d w i n d o w that r u n s t h e task. F i g u r e 5.1 s h o w s t h e MainWindow w i t h t h e T a s k l o p t i o n . I w a n t t o k e e p t h e task s i m p l e f o r n o w . S a y , f o r e x a m p l e , that this task s i m p l y o u t p u t s s o m e text i n its w i n d o w i n r e s p o n s e t o a m e n u s e l e c t i o n . I n b a r e b o n e s n o t a t i o n , t h e a p p l i c a t i o n a c c o m p l i s h e s t h e e q u i v a l e n t o f a Write s t a t e m e n t w i t h o u t g o i n g t h r o u g h t h e WinCrt u n i t . Start w i t h t h e MainWindow y o u d e r i v e d f r o m TWindow i n C h a p t e r 4 , " I n h e r i t i n g a n I n t e r f a c e , " a n d d e r i v e f r o m it a n e w w i n d o w o b j e c t that r e s p o n d s t o m e n u c o m m a n d m e s s a g e s . ( N o t e that y o u d o n ' t h a v e t o start w i t h
5 —Putting Pictures in Windows
MainWindow—you can, of course, derive a n e w w i n d o w directly from TWindow. MainWindow inherited all TWindow's characteristics and behaviors, and in addition has a characteristic you need: the Display Context. Therefore, you derive the n e w w i n d o w from MainWindow.
Figure
5.1. MainWindow
with the Taskl
option.
This n e w w i n d o w object, called TaskWindowl, consists of its o w n constructor and destructor, two datafieldsto represent screen coordinates, and a method to iterate the task. I call the method by the general name, cm_Iterate, using the cm_ prefix to indicate that it responds to a m e n u c o m m a n d message. It looks like this: PTaskl = "Taskl; { Pointer to this task } Taskl = object(MainWindow) { A simple task } X, Y : integer; { X and Y fields } constructor Init(AParent: PWindowsObject; ATitle: PChar); { New constructor} destructor Done; virtual; { New destructor } procedure CMIterate(var Msg: TMessage); virtual cm_First + cm_Task1; end; Notice that I've also defined a pointer to the TaskWindow (object). In general, you always construct a w i n d o w using the New procedure that requires a pointer to an object, not the object itself. Because you're implementing a n e w constructor for TaskWindow, its ancestor's (TWindow) constructor is overridden, and thus not used. However,
153
154
Part I — W o r k i n g w i t h T P W
TWindow's constructor initiates s o m e b e h a v i o r y o u d o n ' t w a n t t o r e i m p l e m e n t . Y o u c a n s e n d a m e s s a g e t o it e x p l i c i t l y w i t h i n TaskWindow's constructor a n d h a v e it h a n d l e all that i n i t i a l i z a t i o n f o r y o u . T h e n y o u c a n i m p l e m e n t t h e s p e c i f i c b e h a v i o r y o u w a n t t o a d d t o TaskWindow. T h e constructor first s e n d s a m e s s a g e t o its a n c e s t o r ' s constructor, i m p l e m e n t i n g a d e f a u l t w i n d o w f o r TaskWindow, a n d t h e n l o a d s a s p e c i f i c m e n u f o r TaskWindow b y s e t t i n g t h e m e n u attribute field:
constructor Taskl.Init(AParent: PWindowsObject; ATitle: PChar); begin TWindow.Init(AParent, ATitle); { Send a message to ancestor's constructor } Attr.Menu := LoadMenu(HInstance, PChar(99)); { 99 = menu ID } end; A l t e r n a t i v e l y , t h e Taskl constructor c a n i m p l e m e n t a s p e c i f i c k i n d a n d size o f w i n d o w :
constructor Taskl.Init(AParent: PWindowsObject; ATitle: PChar); begin TWindow.Init(AParent, ATitle); { Send message to ancestor's constructor } DisableAutoCreate; { Abort default window creation } { Create a specific window } Attr.Style := ws_PopupWindow or ws_Caption or ws_Visible; Attr.Menu := LoadMenu(HInstance, PChar(99)); { 99 = menu ID} Attr.X := 100; { Set window dimensions } Attr.Y := 50; Attr.W := 300; Attr.H := 200; end; N o w i m p l e m e n t t h e task iterate m e t h o d , w h i c h h a s several r e s p o n s i bilities: 1. It m a k e s s u r e that a n y c u r s o r i n p u t is s e n t t o t h e c o r r e c t w i n d o w (TaskWindow) r e g a r d l e s s o f w h e r e t h e m o u s e is l o c a t e d . 2. It g e t s a d i s p l a y c o n t e x t f o r TaskWindow. 3. It d e c i d e s w h e r e t o w r i t e t h e text w i t h i n t h e w i n d o w . 4. It w r i t e s t h e text. 5. It r e l e a s e s t h e c a p t u r e d w i n d o w a n d d i s p l a y c o n t e x t :
procedure Taskl.CMIterate(var var S : array[0.14] of Char;
Msg: TMessage);
5 — P u t t i n g Pictures i n W i n d o w s
begin X := Attr.X + 50; Y := Attr.Y + 50; EndX := X + 50; EndY := Y + 50; SetCapture(HWindow); DC := GetDC(HWindow); TextOut(DC,X,Y,S,SizeOf(S)); ReleaseCapture; ReleaseDC(HWindow,DC); end;
{ Certify the window } { Get a display context } { Write something } { Release display context }
T h e d i s p l a y c o n t e x t is t h e s u r f a c e o f t h e w i n d o w y o u h a v e t o specify i n o r d e r t o d i s p l a y text o r g r a p h i c s i n a w i n d o w . N o t e a l s o that S is a C-style ( n u l l - t e r m i n a t e d ) string, n o t a T u r b o Pascal string. W i n d o w s f u n c t i o n s always r e q u i r e C-style s t r i n g s , s o if y o u r a p p l i c a t i o n s u s e T u r b o Pascal s t r i n g s , y o u always n e e d t o c o n v e r t t h e m b e f o r e y o u u s e t h e m w i t h W i n d o w s f u n c t i o n s . T h e T u r b o Pascal f o r W i n d o w s strings u n i t c o n t a i n s a r i c h set o f C-style s t r i n g - c o n v e r s i o n a n d - m a n i p u l a t i o n f u n c t i o n s . Part I I I , "Reference," details the functions. F i g u r e 5.2 s h o w s t h e d e f a u l t B a s i c l n t e r f a c e w i n d o w c r e a t e d b y T W i n d o w . I n i t . F i g u r e 5.3 s h o w s t h e s p e c i f i c w i n d o w c r e a t e d b y T a s k W i n d o w . I n i t . N o t i c e that t h e title a n d m e n u b a r s a r e different i n t h e t w o figures.
Figure
5.2. The default window
of TWindow.
Init.
155
156
Parti—Working with T P W
Figure 53- A specific window created by TaskWindow. Init.
Tasks It m a y s e e m o v e r l y c o m p l i c a t e d t o c r e a t e a w i n d o w just t o o u t p u t a l i n e o f text, a n d o f c o u r s e it is if that's all y o u e v e r p l a n t o task. T h e g o a l o f this b o o k is t o s h o w y o u g e n e r a l w a y s t o c r e a t e W i n d o w s a p p l i c a t i o n s easily. W h a t y o u ' v e j u s t l e a r n e d is i n fact g e n e r a l e n o u g h t o b e q u i t e u s e f u l . I f i n d it h e l p f u l t o a s s o c i a t e e a c h w i n d o w w i t h a task. Y o u m i g h t w a n t t o m o d i f y this a p p r o a c h as y o u b e c o m e m o r e e x p e r i e n c e d , b u t f o r m a n y p r o j e c t s , p a r t i c u l a r l y as y o u d i s c o v e r y o u r o w n r o u t e t h r o u g h W i n d o w s , o n e - t a s k , o n e w i n d o w works well. T h e task itself is a n o b j e c t that m a y i m p l e m e n t d o z e n s o f m e t h o d s . Taskl just w r o t e a l i n e o f text, b u t t h e m e c h a n i s m y o u ' v e just set u p t o w r i t e a l i n e o f text c a n serve as a b l u e p r i n t f o r m u c h m o r e c o m p l e x t a s k i n g . Y o u c o u l d , o f c o u r s e , r e m o d e l t h e MainWindow (in t h e Basiclnterface) t o reflect a n e w task. I n o t h e r w o r d s , r a t h e r t h a n d e r i v e a n e w Tas kWindow, y o u s i m p l y a d d t h e n e w fields (X a n d Y) a n d t h e n e w c m l t e r a t e m e t h o d t o t h e MainWindow. I n t h e s i m p l e c a s e o f w r i t i n g a l i n e o f text, that's n o d o u b t w h a t you would do. F o r m o r e c o m p l e x tasks, a d d i n g s p e c i f i c f u n c t i o n a l i t y t o t h e g e n e r a l t y p e m i s s e s e n t i r e l y t h e o b j e c t - o r i e n t e d a p p r o a c h . It is b e t t e r t o c r e a t e abstract t y p e s a n d u s e i n h e r i t a n c e t o d e r i v e n e w w i n d o w s , t h u s e n a b l i n g task f o c u s o n its o w n specific functionality.
5 — P u t t i n g Pictures i n W i n d o w s
157
I've d e s i g n e d t h e Basiclnterface w i t h this a t t i t u d e in m i n d . Y o u u s e t h e Basiclnterfaceas y o u r g e n e r a l (abstract) c o n n e c t i o n t o Windows a n d derive a S p e c i f i c I n t e r f a c e f o r y o u r n e w a p p l i c a t i o n s o r tasks. I n this s i m p l e t w o - s t e p process: 1. Y o u derive a n e w a p p l i c a t i o n f r o m t h e Basiclnterface A p p l i c a t i o n o b j e c t a n d let it k n o w w h i c h w i n d o w it n e e d s t o k n o w a b o u t a n d u s e : TaskApp = object(BasicApplication)
{ TaskApp = a kind of BasicApplication } procedure InitMainWindow; virtual; { Init a specific MainWindow } end; { for the TaskApp } implementation procedure TaskApp.InitMainWindow;
{ Init a MainWindow for the Task }
begin if FirstApplication then MainWindow := New(PTask1, Init(nil, 'Task Window Interface')) else MainWindow := New(PTask1, Init(nil,'Additional Instance of TWI')); end; 2. Derive a n e w MainWindow ( o b j e c t ) that i n c l u d e s t h e n e w task: PTaskl = "Taskl; { Pointer to this task } Taskl = object(MainWindow) (* new task methods and fields here *) end; T h e r e ' s a ( p e r h a p s ) s u b t l e p o l y m o r p h i c a s p e c t t o this p r o c e s s . N o t i c e that t h e I nit MainWindow c o n s t r u c t s a n e w w i n d o w o b j e c t t y p e t h r o u g h t h e u s e o f a p o i n t e r . B e c a u s e t h e w i n d o w is c o n s t r u c t e d t h r o u g h a p o i n t e r t h e n e w w i n d o w t y p e c a n b e a n y TWindow d e s c e n d a n t . T h e InitMainWindow m e t h o d simply sends t h e message "construct a w i n d o w p o i n t e d t o by t h e pointer." T h e f u n c t i o n a l i t y o f t h e w i n d o w c a n c h a n g e a n d InitMainWindow is u n a f f e c t e d . It s i m p l y s e n d s a g e n e r a l m e s s a g e ( s e e figure 5 . 4 ) . T h e task is set in m o t i o n w h e n t h e TaskWindow receives a c o m m a n d message generated by a m e n u selection. T h a t is it f o r t h e T u r b o Pascal s i d e o f t h i n g s . When t h e m e n u m e s s a g e matching t h e c o n s t a n t c o d e is s e n t , t h e task is p u t in m o t i o n in its o w n w i n d o w . N o t e that t h e w i n d o w has all t h e b a s i c c a p a b i l i t y o f a TWindow; it c a n b e resized, moved, minimized, and so o n . F i g u r e 5.5 s h o w s t h e task w i n d o w ( a n d task) c r e a t e d b y t h e c o d e i n listing 5.1.
158
Part I—Working with T P W
I nitMainWindow
Ptr to a window type
TWindow
MainWindow
ModelWindow
Figure
5.4. A kind of
polymorphism.
Figure
5.5. The task window (and task) created by listing 5.1.
5 —Putting Pictures in Windows
Listing
5.1.
Code
to create
a task window
and
task.
{ contains two units: Writel, a task, and TaskWnd, to set up the task and a test program } unit Writel;
{ A model task } { responds to cm_Task1
(message) }
interface uses WObjects, WinTypes, WinProcs, strings, StdDlgs, WIF5;
{ Units specific to this unit }
{ Basiclnterface : contains MainWindow } { : BasicApplication }
type PTaskl = Task1; { Pointer to this task } Taskl = object(MainWindow) { Time Series } X, Y : integer; constructor Init(AParent: PWindowsObject; ATitle: PChar); destructor Done; virtual; { Clean up } procedure cm_Iterate(var Msg: 'TMessage); virtual cm_First + cm_Task1; end; A
implementation constructor Taskl.Init(AParent: PWindowsObject; ATitle: PChar) ; begin TWindow.Init(AParent, ATitle); DisableAutoCreate; Attr.Style := ws_PopupWindow or ws_Caption or ws_Visible; Attr.Menu := LoadMenu(HInstance, PChar(99)); { 99 = menu ID } Attr.X Attr.Y Attr.W Attr.H end;
:= := := :=
100; 50; 300; 200;
{ Set window dimensions }
continues
159
160
Part I — W o r k i n g w i t h T P W
Listing
5.Kcontinued
procedure Task"! .cm_Iterate(var Msg: TMessage); { Act on menu's taskl (cm_) } begin X := Attr.X + 50; Y := Attr.Y + 50; SetCapture(HWindow); DC := GetDC(HWindow); { Get a display context } TextOut(DC,X,Y,'A writing Task',14); { Write something } ReleaseCapture; ReleaseDC(HWindow,DC); { Release display context } end; destructor Taskl.Done; begin TWindow.Done; end; end.
{ Call ancestor's destructor }
{ unit Writel }
unit TaskWnd;
{ Sets up a Task } { Responds to cm_Task1 (message) } { Responds to cm_Task2 (message) }
interface uses WObjects, WinTypes, WinProcs, strings, StdDlgs, WIF5,
writel; {$R TASKWND.RES}
{ Units specific to this unit }
{ Basiclnterface unit } { TaskList } { Task 1 } { TaskWnd resource }
5 —Putting Pictures in Windows
161
type TaskApp = object(BasicApplication)
{ ModelApp = a kind of BasicApplication } procedure InitMainWindow; virtual; { Init a specific MainWindow } end; implementation
procedure TaskApp.InitMainWindow;
{ Init a model application window }
begin if FirstApplication then MainWindow := New(PTask1, Init(nil, 'Task Window Interface')) else MainWindow := New(PTask1, Init(nil,'Additional Instance of MI')) ; end; end. { unit TaskWnd }
program Test_Interface;
uses WIF5, taskwnd;
{ A generic way to test each phase of interface development }
{ Basiclnterface unit } { contains this TaskApp }
type App = object(TaskApp) end; var Application: App;
{ An instance of BasicApplication } { Run Applicationl }
begin Application.Init('Tasklnterface'); Application.Run; Application.Done; end.
{ init application instance } { Message loop } { Destroy application instance }
162
Parti—Working with T P W
N o t e : It's n o t e s s e n t i a l , b u t it is c o n v e n i e n t , t o a s s o c i a t e o n e m e n u w i t h e a c h w i n d o w . I n o t h e r w o r d s , Taskl ( t h e w i n d o w ) h a s a n a s s o c i a t e m e n u c o n t a i n e d i n t h e Taskl r e s o u r c e file (TASK1.RES). T h i s a s s o c i a t i o n h e l p s y o u k e e p y o u r w i n d o w s a n d m e n u s f r o m straying t o o far f r o m e a c h o t h e r .
T h e o n l y d e t a i l left o u t is h o w t o a d d t h e m e n u i t e m . C h a p t e r 8 , " R e s o u r c e s a n d C o n t r o l O b j e c t s , " details r e s o u r c e c r e a t i o n , w h i c h i n t h e c a s e o f a d d i n g m e n u s e l e c t i o n s , is very s i m p l e . I n a n u t s h e l l , y o u o p e n t h e W h i t e w a t e r R e s o u r c e T o o l k i t M e n u E d i t o r , o p e n a r e s o u r c e file, a d d t h e m e n u c h o i c e , a n d a d d its c o r r e s p o n d i n g c o m m a n d c o d e .
Other Windows, Other Tasks N o w that y o u h a v e a g e n e r a l task w i n d o w , w h a t a b o u t a d d i n g m o r e tasks? Easily a d d e d . T h e p r o c e s s is m o r e o r less c r e a t i n g a n e w CMIterate m e t h o d f o r e a c h task. F o r e x a m p l e , c r e a t e a w i n d o w that d i s p l a y s text a n d d r a w s a l i n e : procedure Task2.CMIterate(var Msg: TMessage); begin X := Attr.X + 50; { Line dimensions } Y := Attr.Y + 50; EndX := X + 50; EndY := Y + 50; { Line dimensions } SetCapture(HWindow); DC := GetDC(HWindow); TextOut(DC,X,Y,'A writing T a s k , 1 4 ) ; DrawLine := LineTo(DC,EndX,EndY); ReleaseCapture; ReleaseDC(HWindow,DC); end; 1
Model Tasks Y o u ' r e n o d o u b t n o t i c i n g that text a n d g r a p h i c s c a n b e d i s p l a y e d i n a w i n d o w w i t h similar e a s e . It's all p i x e l s t o a G U I like W i n d o w s . I n g e n e r a l , y o u w a n t t o t h i n k o f y o u r a p p l i c a t i o n s p e r f o r m i n g tasks i n response to the messages they receive. T h e messages can c o m e from m e n u s , the m o u s e , t h e k e y b o a r d , p o r t s , t h e a p p l i c a t i o n itself, a n d e v e n o t h e r a p p l i c a t i o n s . I n this n e x t s e c t i o n , I s h o w y o u h o w t o set u p a n abstract m o d e l task ( o r s i m u l a t i o n ) that d e m o n s t r a t e s h o w y o u c r e a t e y o u r o w n s p e c i a l i z e d tasks. T h e n
5 — P u t t i n g Pictures i n W i n d o w s
I s h o w y o u h o w t o m u l t i t a s k b y p u t t i n g several m o d e l tasks i n w i n d o w s that can be displayed simultaneously. I n o r d e r f o r y o u t o h a v e a little f u n w i t h t h e tasks I d e v e l o p h e r e , I d i s c u s s m o d e l i n g in general a n d then eventually m o v e to o n e of the hottest topics in modeling: chaos theory.
Modeling M o d e l i n g is a w a y t o e n c a p s u l a t e s o m e part o f a s y s t e m ' s b e h a v i o r i n t e r m s o f t h e m a t h e m a t i c a l r e l a t i o n s h i p s a m o n g v a r i a b l e s . O n e h o p e s that t h e s e v a r i a b l e s e n c a p s u l a t e t h e s y s t e m ' s b e h a v i o r , a n d y o u select t h e v a r i a b l e s y o u t h i n k are i m p o r t a n t i n d e t e r m i n i n g c h a n g e s o f state i n t h e s y s t e m . T h e n y o u s t a n d b a c k a n d w a t c h t h e s y s t e m c h a n g e state. F o r e x a m p l e , i n a t w o - d i m e n s i o n a l s y s t e m , w i t h v a r i a b l e s X a n d Y, y o u m i g h t say that t h e c u r r e n t state o f Y is e q u a l t o t h r e e t i m e s t h e c u r r e n t state o f X; o r , i n m a t h e m a t i c a l t e r m s , Y = 3 X . T h i s is a s i m p l e l i n e a r m o d e l , a n d y o u c a n easily v i s u a l i z e h o w t h e s y s t e m c h a n g e s f r o m state t o state: Y is always t h r e e t i m e s as b i g as X . F i g u r e 5.6 p i c t u r e s this s y s t e m ' s c h a n g i n g state.
Figure 5.6. A linear
equation.
T o d i s p l a y this s y s t e m i n a w i n d o w , y o u c a n s i m p l y g r a p h t h e v a l u e s o f Y f o r e a c h i n c r e m e n t i n X. T o g r a p h t h e s e c h a n g e s o f state, t h e task n e e d s t o i m p l e m e n t several n e w d a t a fields t o r e p r e s e n t s c r e e n c o o r d i n a t e s , r a n g e s t o g r a p h , initial v a l u e s f o r v a r i a b l e s , a n d m e t h o d s f o r s c a l i n g a n d iterating t h e task.
163
164
Parti—Working with TPW
C a l l this task Model 1 a n d d e f i n e it this w a y , as a w i n d o w d e r i v e d f r o m
MainWindow: PModell = "Modell; Modell = object(MainWindow)
{ Pointer to this task } { A Time Series model } { Task's data fields } InitX, InitY : real; { Initial points } RangeXI, RangeX2, RangeYI, RangeY2 : real; { Range to view } X, Y : integer; { Point to plot } A, B : real; { Factors for this model task } { Task's methods } constructor Init(AParent: PWindowsObject; ATitle: PChar); procedure Scale; { Scale point to window } procedure Iterate; { Iterate model task } destructor Done; virtual; { Clean up } procedure CMIterate(var Msg: TMessage); virtual cm_First + cm_Task1; end; You
implement
the m e t h o d s in a m o m e n t .
For now,
simply
let
App. InitMainWindow c o n s t r u c t a Modell: procedure TaskApp.InitMainWindow; { Init a MainWindow for the Task } begin if FirstApplication then MainWindow := New(PModel1, Init(nil, 'Task Window Interface')) else MainWindow := New(PModel1, Init(nil,'Additional Instance of TWI')); end; Y o u h a v e a n o t h e r task (this t i m e a m o d e l ) i n a w i n d o w . N o t h i n g n e w i n this e p i s o d e , b u t s u p p o s e that y o u w a n t t o set u p a m o r e g e n e r a l i n t e r f a c e that a l l o w s y o u t o m u l t i t a s k several w i n d o w s at o n c e . T h i s r e q u i r e s t w o m a i n s t e p s : 1. A n o t h e r layer o f a b s t r a c t i o n i n t h e f o r m o f a n i n t e r m e d i a r y w i n d o w that c r e a t e s t h e v a r i o u s task w i n d o w s 2. A slightly m o r e c o m p l e x c o m m a n d m e s s a g e - r e s p o n s e s e t u p T h e i n t e r m e d i a r y (or s e t u p ) w i n d o w l o o k s l i k e t h i s :
PModelWindow = "ModelWindow;{ModelWnd is a kind of MainWnd } ModelWindow = object(MainWindow) constructor Init(AParent : PWindowsObject; ATitle : PChar); procedure CMTask1(var Msg: TMessage); virtual { run taskl } cm_First + cm_Task1; procedure CMTask2(var Msg: TMessage); virtual { run task2 } cm_First + cm_Task2; end;
5 —Putting Pictures in Windows
where CMTaskl and CMTask2 are response methods for m e n u c o m m a n d messages to construct and iterate each task. Figure 5.7 illustrates this concept.
Figure
5.7. Taskl and Task2 on model windows
interface.
ModelWindow.CMTaskl looks like this: procedure ModelWindow.CMTaskl(var Msg: TMessage); var Taskl : PModell; { Pointer to a Task } begin Taskl := New(PModel1, Init(@Self, 'TimeSeries Model')); Application".MakeWindow(Task1); Taskl .cm Iterate; { Iterate the task } end; A
Responding to the cm_task1 message, CMTaskl constructs a Modell w i n d o w and then iterates the model. ModelWindow.CMTask2 looks like this: procedure ModelWindow.CMTTask2(var Msg: TMessage); var Task2 : PModel2; { Pointer to a Task } begin Task2 := New(PModel2, Init(@Self, 'Henon Attractor')); Application".MakeWindow(Task2); Task2".Iterate; { Iterate the task } end;
165
166
Parti—Working with T P W
R e s p o n d i n g t o t h e cm_task2 m e s s a g e , CMTask2 c o n s t r u c t s a Model2 w i n d o w a n d t h e n iterates t h e m o d e l . T o set this s y s t e m i n m o t i o n , h a v e TaskApp. InitMainWindow c o n s t r u c t a ModelWindow as its MainWindow r a t h e r t h a n a s p e c i f i c m o d e l : procedure TaskApp.InitMainWindow;
{ Init a MainWindow for the Task }
begin if FirstApplication then MainWindow := New(PModelWindow, Init(nil, 'Task Window Interface')) else MainWindow := New(PModelWindow, Init(nil,'Additional Instance of TWI')); end; T h a t ' s all t h e r e is t o it. N o t e that b o t h Modell a n d t h e ModelWindow c a n r e s p o n d t o t h e s a m e c o m m a n d m e s s a g e (cm_Task1). T h e s a m e g o e s f o r Model2 a n d ModelWindow (cm_Task2). N o t e a l s o that t h e s a m e m e s s a g e s e n t t o t w o d i f f e r e n t w i n d o w s r e s u l t s i n d i f f e r e n t b e h a v i o r s : p o l y m o r p h i s m a g a i n . S e e listing 5.3 at t h e e n d o f this c h a p t e r for t h e i m p l e m e n t a t i o n d e t a i l s . If t h e ModelWindow g e t s t h e c m T a s k l m e s s a g e , it c o n s t r u c t s a m o d e l a n d iterates it. I f t h e Modell g e t s t h e cm_Task1 m e s s a g e , it iterates o n l y itself ( b e c a u s e it h a s a l r e a d y b e e n c o n s t r u c t e d ! ) . C-o-o-o-1.
Chaos and Strange Attractors N o w , just for f u n a n d b e c a u s e c h a o t i c m o d e l s a r e a f a s c i n a t i n g w a y t o e x p l o r e t h e w o r l d , I d i s c u s s s o m e o f t h e t h e o r y b e h i n d Model2. I n r e c e n t y e a r s , r e s e a r c h e r s i n v a r i o u s fields that i n v o l v e d y n a m i c s h a v e u s e d c o m p u t e r s t o m o d e l n o n l i n e a r s y s t e m s that e x h i b i t b e h a v i o r n o t easily v i s u a l i z e d n o r u n d e r s t o o d b y just l o o k i n g at t h e n u m b e r s . T h e k e y t o u n d e r s t a n d i n g m a n y o f t h e s e s y s t e m s is t o u n c o v e r t h e attractors o f t h e s y s t e m . A n attractor i s , l o o s e l y , a state t o w a r d w h i c h a s y s t e m e v o l v e s . Y o u f i n d attractors i n a c o m p u t e r - g e n e r a t e d p h a s e (or state) s p a c e . I n state s p a c e , a p o i n t r e p r e s e n t s all t h e i n f o r m a t i o n y o u k n o w a b o u t a s y s t e m ' s state, a n d t h e s p a c e itself is a p i c t u r e o f a s y s t e m ' s c u r r e n t state p l o t t e d a g a i n s t its n e x t state ( s e e figure 5.8). T h e k e y t o u n d e r s t a n d i n g t h e s y s t e m is t o d e t e r m i n e w h a t state (or states) t h e s y s t e m is e v o l v i n g t o w a r d . A t t r a c t o r s "attract" a s y s t e m . A s t h e s y s t e m e v o l v e s , t h e c o l l e c t i o n o f p o i n t s that r e p r e s e n t s u c c e s s i v e states c a n e i t h e r : 1. S e t t l e t o o n e p o i n t (a p o i n t a t t r a c t o r ) . S e e f i g u r e 5 . 9 . 2. R e p e a t e d l y r e t u r n t o a set o f p o i n t s (a p e r i o d i c a t t r a c t o r ) . See figure 5.10.
5 — P u t t i n g Pictures i n W i n d o w s
3. N o t r e t u r n t o a w e l l - d e f i n e d g r o u p o f p o i n t s , o r r e t u r n t o a s t r a n g e set o f p o i n t s (see f i g u r e 5 . 1 1 ) .
Figure 5.8. State space.
Figure 5.9. A point
attractor.
167
168
P a r t i — W o r k i n g with T P W
Figure
5.10. A periodic
attractor.
Figure
5.11. A strange attractor.
5 — P u t t i n g Pictures i n W i n d o w s
T h e s y s t e m e v o l v e s as t h e v a l u e s o f t h e c u r r e n t state b e c o m e t h e initial v a l u e s o f t h e n e x t state. E a c h t i m e , b e f o r e e a c h l o o p i n t o t h e n e x t state, t h e m o d e l r e c o r d s o r p l o t s t h e c u r r e n t s y s t e m ' s state i n p h a s e s p a c e . M o d e l i n g s y s t e m s (like t a s k i n g s y s t e m s i n g e n e r a l ) are b e s t d e s c r i b e d w i t h o b j e c t - o r i e n t e d t e c h n i q u e s f o r several r e a s o n s . It's easy t o g e n e r a l i z e t h e characteristics that m o d e l s h a v e i n c o m m o n . A n y m o d e l is a t y p e o f m o d e l , related to other m o d e l s . F r o m a c o m p u t i n g perspective, m o d e l s share low-level g r a p h i c s p r i m i t i v e s l i k e p o i n t s . T h e y ' r e all p l o t t e d i n s o m e k i n d o f s p a c e , a l t h o u g h d i f f e r i n g i n h o w t h e y g e n e r a t e states i n that s p a c e . A dynamic system, w h i c h a m o d e l represents, can be anything • Y o u c a n describe by k n o w i n g the values o f variables • W h o s e c u r r e n t state d e p e n d s o n its p r e v i o u s states T h e state o f t h e s y s t e m c a n b e s o m e t h i n g m e a s u r e d o n a c o n t i n u o u s s c a l e , s o m e t h i n g w i t h l o g i c a l c h a n g e s (Is it yes? Is it o n ? H a s s o m e t h i n g h a p p e n e d s i n c e y o u c h e c k e d last?), a n d s o o n . I n a s p e e c h - r e c o g n i t i o n s y s t e m , o n e o f m y favorite e x a m p l e s , e a c h w o r d i n t h e s e n t e n c e carries s o m e i n d i v i d u a l w e i g h t a n d affects ( a n d is a f f e c t e d by) all t h e o t h e r w o r d s i n t h e s e n t e n c e . I n a s e n s e o n e c a n c o n s i d e r a " s e n t e n c e " t o b e a d y n a m i c s y s t e m that c h a n g e s state t h r o u g h t h e a d d i t i o n o f w o r d s a n d p u n c t u a t i o n m a r k s . Initially a s e n t e n c e is e m p t y . Y o u a d d a w o r d (the o n e w o r d is t h e n e w s e n t e n c e ) . Y o u a d d a w o r d (the t w o w o r d s are t h e n e w s e n t e n c e ) . Y o u a d d a w o r d (the t h r e e w o r d s are t h e n e w s e n t e n c e ) . Y o u a d d a p u n c t u a t i o n m a r k (three w o r d s p l u s punctuation = new sentence). And so on. W h e n y o u speak, w o r d s necessarily follow each other. W h e n y o u write, t h e y f o l l o w o r d i s p l a c e o n e a n o t h e r (by r e p l a c i n g o r b e i n g i n s e r t e d b e t w e e n w o r d s ) . E a c h n e w state r e p r e s e n t s y o u r a t t e m p t s t o clarify t h e state o f t h e s e n t e n c e . (As m a n y o f y o u k n o w , e a c h n e w state c a n clarify o r c o n f u s e — o n e r e a s o n that p a r s i n g s e n t e n c e s is s o difficult.) Parsing is t h e b r e a k i n g u p o f sentences into c o m p o n e n t parts, usually for grammatical description. T h e s e n t e n c e i n its n e x t state is v e r y sensitive t o its c u r r e n t state (or c o n d i t i o n ) a n d t o its p r e v i o u s states. Y o u m i g h t say that " m e a n i n g s " are t h e attractors i n t h e d y n a m i c s y s t e m " s e n t e n c e . " At a n y state t h e s e n t e n c e m a y h a v e n o m e a n i n g (an e x t i n c t i o n s t a t e ) , o n e m e a n i n g (a s t a b l e s t a t e ) , o r m a n y m e a n i n g s ( p o s s i b l y a c h a o t i c s t a t e ) . T h e m e a n i n g of the sentence d e p e n d s o n any n u m b e r of things—point of view, r e a d i n g o r w r i t i n g skill, a n d s o o n .
169
170
Part I — W o r k i n g w i t h T P W
Mathematic Attraction S c i e n t i s t s (in m a t h e m a t i c s , p h y s i c s , e n g i n e e r i n g , b i o l o g y , c o m p u t e r s c i e n c e , b u s i n e s s , e c o n o m i c s , a n d s o o n ) a r e trying t o u n d e r s t a n d d y n a m i c s y s t e m s . T h e i r d i s c o v e r i e s h a v e l e d t o at least o n e a g r e e a b l e c o n c l u s i o n — a n y t h i n g o f interest that c h a n g e s state is b e a u t i f u l l y c o m p l e x . M a t h e m a t i c i a n s a n d c o m p u t e r scientists try t o twist m e a n i n g o u t o f c o m p l e x systems by representing t h e m with equations (or rules), a n d they visualize the system in pictures. S o m e p a r t i c u l a r l y i n t e r e s t i n g p i c t u r e s exist i n p h a s e ( o r state) s p a c e , w h e r e e a c h p o i n t h o l d s all t h e i n f o r m a t i o n n e e d e d t o d e s c r i b e a d y n a m i c s y s t e m at a n y o n e t i m e ( o r s t a t e ) . F o r e x a m p l e , s u p p o s e that a s y s t e m varies ( c h a n g e s state) d e p e n d i n g o n a v a r i a b l e — s u c h as size o r n u m b e r . C a l l t h e v a r i a b l e , X , a n d call its rate o f c h a n g e , R. T h e n e q u a t i o n s s u c h as
Nextx = R * X( * (1-X) can describe the system. I n this c a s e , t h e n u m e r a l 1 r e p r e s e n t s t h e s y s t e m at s o m e m a x i m u m state a n d 0 r e p r e s e n t s t h e s y s t e m at s o m e m i n i m u m state. E i t h e r e x t r e m e state ( w h e n Nextx = 1 o r O ) translates i n t o a n infinite state. T h e p r e v i o u s e q u a t i o n , t h e s o - c a l l e d " s t a n d a r d m a p " o~ "logistic e q u a tion," has b e e n e x p l o r e d for m a n y years by mathematically inclined folks in m a n y f i e l d s . T h e y ' v e d i s c o v e r e d that it ( a n d p r e s u m a b l y t h e d y n a m i c s y s t e m it describes) behaves unpredictably. I n general, any system y o u describe with any nonlinear equation or equations behaves unpredictably. L o g i s t i c e q u a t i o n s a r e u n p r e d i c t a b l e b e c a u s e t h e y ' r e e x t r e m e l y sensitive t o initial c o n d i t i o n s . N e a r b y v a l u e s o f X i n o n e state m a y l e a d t o v a l u e s ( o f Nextx) that a r e far apart i n t h e n e x t state. Y o u c a n complicate matters even m o r e b y increasing the n u m b e r o f v a r i a b l e s i n a s y s t e m (that is, o u r r e p r e s e n t a t i o n o f a s y s t e m ) . F o r e x a m p l e , t h e s e t w o r u l e s f o r c h a n g e s i n state
Nextx = AX - (1-(Y*Y*Y)) Nexty = 1 - BY
{ 2 coupled nonlinear equations }
c a n p r e s e n t a n " i n f i n i t e " n u m b e r o f states (Nextx v a l u e s ) r e s p o n d i n g t o infinitely s m a l l c h a n g e s i n t h e c o n d i t i o n o f t h e p r e v i o u s state ( o r X v a l u e ) . T h i s infinity o f v a l u e s is t h e c h a o t i c set f o r this d y n a m i c s y s t e m .
5 — P u t t i n g Pictures i n W i n d o w s
Y o u c a n s e e this c h a o s easily b y p l o t t i n g t h e v a l u e s o f e a c h state ( N e x t x ) i n t i m e . ( T h e X axis is t i m e . T h e Y axis is t h e v a l u e o f e a c h X. S e e f i g u r e 5.12.)
Figure 5.12.
Chaos.
Order in Chaos In even the most chaotic systems, there's an intriguing and often surprising o r d e r . O n e w a y t o s e e this o r d e r is i n p h a s e s p a c e . W h e n y o u p l o t v a l u e s o f N e x t x a g a i n s t v a l u e s o f c u r r e n t X, y o u u n c o v e r t h e attractor f o r t h e c h a o t i c set. T h i s attractor o c c u p i e s t h e p h a s e s p a c e a n d is c o m p o s e d o f all t h e p o i n t s i n t h e c h a o t i c set. B y m u t u a l a g r e e m e n t it's c a l l e d " s t r a n g e . " F i g u r e 5.13 s h o w s t h e s t r a n g e attractor c o r r e s p o n d i n g t o t h e c h a o t i c set i n f i g u r e 5 . 1 2 . Listing 5.2 s h o w s t h e task c o d e t o c r e a t e this attractor.
171
172
Parti—Working with T P W
Figure
Listing
5.13- Order in chaos.
5.2.
Code
to create
unit Attract2;
strange
attractor
in figure
5.13 >
{ Contains Henon Attractor } { Responds to cm_Task2 (message) }
interface uses WObjects, WinTypes, WinProcs, strings, StdDlgs, WIF5;
{ Units specific to this unit }
{ Basiclnterface unit }
{$R ATTRACT2.RES} const cm_ChangeFactor_A
= 303; {
1
'
}
type PModel2 = ~Model2; Model2 = object(MainWindow)
{ Henon Attractor }
5 —Putting Pictures in Windows
InitX, InitY : real; RangeXI, RangeX2, RangeYI, RangeY2 : real; X, Y : integer; A, B : real;
{ { { { {
173
Model's data fields } Initial points } Range to view } Point to plot } Factors for this model }
{ Model's methods } constructor Init(AParent: PWindowsObject; ATitle: PChar); procedure Scale; { Scale point to window } procedure Iterate; { Iterate model } destructor Done; virtual; { Clean up } procedure cm_Iterate(var Msg: TMessage); { Iterate } virtual cm_First + cm_Task2; procedure cm_ChangeFactorA(var Msg: TMessage); virtual cm_First + cm_ChangeFactor_A; end;
implementation const Iterations = 3000;
{ Number of iterations }
constructor Model2.Init(AParent: PWindowsObject; ATitle: PChar); begin TWindow.Init(AParent, ATitle); Attr.Menu := LoadMenu(HInstance, PChar(102)); DisableAutoCreate; Attr.Style := ws_PopupWindow or ws_Caption or ws_Visible; Attr.X Attr.Y Attr.W Attr.H
RangeXI RangeX2 RangeYI RangeY2
:= := := :=
:= := := :=
A := 1 .4; B := 0.3;
150; 100; 300; 200;
-1.03; 1.27; -0.3; 0.45;
{ Set ranges to view }
{ Set factors } continues
174
Listing
Parti—Working with TPW
5.2.
continued
InitX := 0.4; InitY := 0; X := 0; Y := 0; end;
{ Initial point in space }
procedure Model2.cm_Iterate(var Msg: TMessage); begin Iterate; { Iterate the model } end; procedure Model2.cm_ChangeFactorA(var Msg: TMessage); var InputText: array[0..5] of Char; New_A : real; ErrorPos : integer; begin { Use dialog to change A factor } Str(A,InputText); if Application".ExecDialog(New(PInputDialog, Init(@Self,'Factor A', Input a new A Factor: , InputText, SizeOf(InputText)))) = id_Ok then begin Val(InputText,New_A,ErrorPos); if ErrorPos = 0 then A := New_A; end; end; 1
1
procedure Model2.Scale; begin { Scale point in space to window } If (InitX = RangeXI) then { A little troubleshooting } X := Attr.X; If (InitX = RangeX2) then X := Attr.W; { And here } If (InitX = 0) then X := X; If (InitX > RangeXI) then X := round((InitX - RangeXI)/(RangeX2 - RangeXI) * (Attr.W - Attr.X)); Y := Attr.H - (round((InitY - RangeYI)/(RangeY2 - RangeYI) * (Attr.H Attr.Y))); end; destructor Model2.Done; begin
5 — P u t t i n g Pictures i n W i n d o w s
TWindow.Done; end;
{ Call ancestor's destructor }
procedure Model2.Iterate; var I : integer; TempX, TempY : real; begin SetCapture(HWindow); DC := GetDC(HWindow); { for I := 1 to Iterations do begin TempX := InitX; { TempY := InitY; { InitX := TempY + 1 - (A * InitY := B * TempX; Scale; { TextOut(DC,X,Y,'. ,1); { end; ReleaseCapture; ReleaseDC(HWindow,DC); { end; 1
Get a display context }
Save last state } Save last state } TempX * TempX); { this model } { this model } Scale new state to a window } Draw a point }
Release Display context }
end. T h e fractal ( o r self-similar) n a t u r e o f t h e s y s t e m b e c o m e s a p p a r e n t w h e n y o u z o o m i n o n a n y a r e a o f t h e attractor. T h e d e e p e r y o u g o , t h e m o r e c o m p l e x ( a n d d e t a i l e d ) t h e attractor b e c o m e s , a n d y e t t h e m o r e o r d e r l y it s e e m s .
Grand Finale Listing 5.3 s h o w s t h e c o m p l e t e c o d e f o r this multitasking m o d e l system, inc l u d i n g t h e s p e c i f i c c o d e f o r a chaotic m o d e l a n d a s t r a n g e attractor. F i g u r e 5.14 s h o w s t h e d i s p l a y p r o d u c e d b y this c o d e . Deriving y o u r o w n m u l t i t a s k i n g f r o m t h i s n e w v e r s i o n o f t h e Basiclnterface is a s i m p l e m a t t e r . A l t h o u g h a m o d e l i n g s y s t e m might n o t b e at all w h a t y o u have in m i n d f o r y o u r o w n a p p l i c a t i o n s , it's a g e n e r a l o n e that illustrates how easily y o u c a n create a m u l t i t a s k i n g s y s t e m within Windows. Y o u s i m p l y create o r derive y o u r o w n tasks, d e f i n e p o i n t e r s t o t h e m , a n d t h e n c o n s t r u c t t h o s e w i n d o w s f r o m t h e ModelWindow ( t h e MainWindow f o r t h e multitasking system).
175
1 7 6 Parti—Working with T P W
Note that I've adopted a useful convention of putting each separate task in its o w n unit. I don't k n o w about you, but I easily lose track of where I keep objects. So a task per unit in m a n y cases makes good sense to m e . Chapter 13, "Designing W i n d o w s Applications," talks again about organization in regard to W i n d o w s applications. You, of course, decide what works best for you. Chapter 5, "Putting Pictures In Windows," closes with a reflection: W i n d o w s is a multitasking interface, so doesn't it makes sense that you can create your o w n multitasking system within Windows? ...Yes!
Figure
Listing
5-14. The results of listing
53-
Code for a chaotic
53-
model
and
a strange
attractor.
{ This listing includes three units: timel attract2 modelwnd and a test interface program } { Timel } unit Timel;
interface
{ A model task } { responds to cm_Task1
(message) }
5 — P u t t i n g Pictures i n W i n d o w s
uses WObjects, WinTypes, WinProcs, strings, StdDlgs, WIF5;
{$R TIME1.RES}
{ Units specific to this unit }
{ Basiclnterface : contains MainWindow } { : contains BasicApplication } { This task's new resources }
type PModell = "Modell; { Pointer to this task } Modell = object(MainWindow) { Time Series } { Task's data fields } InitX, InitY : real; { Initial points } RangeXI, RangeX2, RangeYI, RangeY2 : real; { range to view } X, Y : integer; { Point to plot } A, B : real; { factors for this model task } { Task's methods } constructor Init(AParent: PWindowsObject; ATitle: PChar); procedure Scale; { Scale point to window } procedure Iterate; { Iterate model task } destructor Done; virtual; { Clean up } procedure cm_Iterate(var Msg: TMessage); virtual cm_First + cm_Task1; end;
implementation const Iterations = 3000;
177
{ Number of iterations for this model }
constructor Modell.Init(AParent: PWindowsObject; ATitle: PChar); begin TWindow.Init(AParent, ATitle); Attr.Menu := LoadMenu(HInstance, PChar(111)); DisableAutoCreate; Attr.Style := ws_PopupWindow or ws_Caption or ws_Visible; continues
178
Part I — W o r k i n g w i t h T P W
Listing
53-
Attr.X Attr.Y Attr.W Attr.H RangeXI RangeX2 RangeYI RangeY2
continued
:= := := := := := := :=
100; 50; 300; 200; -1.03; 1.27; -0.3; 0.45;
A := 1.4; B := 0.3; InitX := 0.4; InitY := 0; X := 0; Y := 0; end;
{ Set window dimensions }
{ Set ranges to view }
{ Set factors }
{ Initial point in space }
procedure Modell.cm_Iterate(var Msg: TMessage); begin Iterate; { Iterate the model } end; procedure Modell.Scale; begin { Scale point in space to window } If (InitX = RangeXI) then { A little troubleshooting } X := Attr.X; If (InitX = RangeX2) then X := Attr.W; { And here } If (InitX = 0) then X := X; If (InitX > RangeXI) then X := round((InitX - RangeXI)/(RangeX2 - RangeXI) * (Attr.W - Attr.X)); Y := Attr.H - (round((InitY - RangeYI)/(RangeY2 - RangeYI) * (Attr.H - Attr.Y))); end; destructor Modell.Done; begin TWindow.Done; { Call ancestor's destructor } end;
5 —Putting Pictures in Windows
procedure Modell.Iterate; var I : integer; TempX, TempY : real; begin InvalidateRect(HWindow, nil,True); SetCapture(HWindow); DC := GetDC(HWindow); { Get a display context } for I := 1 to Iterations do begin TempX := InitX; { Save last state } TempY := InitY; { Save last state } InitX := TempY + 1 - (A * TempX * TempX); {This model } InitY := B * TempX; { This model } Scale; { Scale new state to a window } X := I; TextOut(DC,X,Y,'.',1); { Draw a point } end; ReleaseCapture; ReleaseDC(HWindow,DC); { Release display context } end; end.
{ unit timel }
{ Attract 2 } unit Attract2;
{ Contains Henon Attractor } { Responds to cm_Task2 (message) }
interface uses WObjects, WinTypes, WinProcs, strings, StdDlgs, WIF5;
{ Units specific to this unit }
{ Basiclnterface unit }
{$R ATTRACT2.RES} const cm_ChangeFactor_A
=303;
{ ''
........
y continues
179
180
Parti—Working with TPW
Listing
53-
continued
type PModel2 = "Model2; Model2 = object(MainWindow)
{ Henon Attractor } { Model's data fields } InitX, InitY : real; { Initial points } RangeXI, RangeX2, RangeYI, RangeY2 : real; { Range to view } X, Y : integer; { Point to plot } A, B : real; { factors for this model } { Model's methods } constructor Init(AParent: PWindowsObject; ATitle: PChar); procedure Scale; { Scale point to window } procedure Iterate; { Iterate model } destructor Done; virtual; { Clean up } procedure cm_Iterate(var Msg: TMessage); { Iterate } virtual cm_First + cm_Task2; procedure cm_ChangeFactorA(var Msg: TMessage); virtual cm_First + cm_ChangeFactor_A; end; implementation const Iterations = 3000;
{ Number of iterations }
constructor Model2.Init(AParent: PWindowsObject; ATitle: PChar) begin TWindow.Init(AParent, ATitle); Attr.Menu := LoadMenu(HInstance, PChar(102)); DisableAutoCreate; Attr.Style := ws_PopupWindow or ws_Caption or ws_Visible; Attr.X Attr.Y Attr.W Attr.H RangeXI RangeX2 RangeYI RangeY2
:= := := := := := := :=
A := 1.4;
150; 100; 300; 200; -1.03; 1.27; -0.3; 0.45;
{ Window dimensions }
{ Set ranges to view }
{ Set factors }
5 — P u t t i n g Pictures i n W i n d o w s
B := 0.3; InitX := 0.4; InitY := 0; X := 0; Y := 0; end;
{ Initial point in space }
procedure Model2.cm_Iterate(var Msg: TMessage); begin Iterate; { Iterate the model } end; procedure Model2.cm_ChangeFactorA(var Msg: TMessage); var InputText: array[0..5] of Char; New_A : real; ErrorPos : integer; begin { Use dialog to change A factor } Str(A,InputText); if Application".ExecDialog(New(PInputDialog, Init(@Self, Factor A', Input a new A Factor:', InputText, SizeOf(InputText)))) = id_Ok then begin Val(InputText,New_A,ErrorPos); if ErrorPos = 0 then A := New_A; end; end; 1
1
procedure Model2.Scale; begin { Scale point in space to window } If (InitX = RangeXI) then { A little troubleshooting } X := Attr.X; If (InitX = RangeX2) then X := Attr.W; { And here } If (InitX = 0) then X := X; If (InitX > RangeXI) then X := round((InitX - RangeXI)/(RangeX2 - RangeXI) * (Attr.W - Attr.X)); Y := Attr.H - (round((InitY - RangeYI)/(RangeY2 - RangeYI) * (Attr.H - Attr.Y))); end; continues
181
182
Parti—Working with T P W
Listing
53-
continued
destructor Model2.Done; begin TWindow.Done; { end;
Call ancestor's destructor }
procedure Model2.Iterate; var I : integer; TempX, TempY : real; begin SetCapture(HWindow); DC := GetDC(HWindow); { Get a display context } for I := 1 to Iterations do begin TempX := InitX; { Save last state } TempY := InitY; { Save last state } InitX := TempY + 1 - (A * TempX * TempX); {This model} InitY := B * TempX; {This model} Scale; { Scale new state to a window } TextOut(DC,X,Y,'.',1); { Draw a point } end; ReleaseCapture; ReleaseDC(HWindow,DC); { Release Display context } end; end. { end unit Attract2 } { ModelWnd } unit ModelWnd;
{ Contains a Model Window } { Responds to cm_Task1 (message)} { Responds to cm_Task2 (message) }
interface uses WObjects, WinTypes, WinProcs, strings, StdDlgs, WIF5,
timel,
{ Units specific to this unit }
{ Basiclnterface unit } { TaskList } { Task 1 }
5 — P u t t i n g Pictures i n W i n d o w s
attract2; {$R M0DWND2.RES}
{ Task 2
183
}
{ ModelWnd resource }
type ModelApp = object(BasicApplication) procedure InitMainWindow; virtual;
{ ModelApp=a kind of BasicApplication } { Init a specific MainWindow }
end; PModelWindow = "ModelWindow;
{ ModelWnd is a kind of MainWnd }
ModelWindow = object(MainWindow) constructor Init(AParent : PWindowsObject; ATitle : PChar); procedure cm_Task1(var Msg: TMessage); virtual {Run Taskl } cm_First + cm_Task1; procedure cm_Task2(var Msg: TMessage); virtual {Run Task2 } cm_First + cm_Task2; end;
implementation
procedure ModelApp.InitMainWindow;
{ Init a model application window }
begin if FirstApplication then MainWindow := New(PModelWindow, Init(nil, 'Model Windows Interface')) else MainWindow := New(PModelWindow, Init(nil,'Additional Instance of MI')); end; constructor ModelWindow.Init(AParent ATitle : PChar); begin TWindow.Init(AParent, ATitle);
: PWindowsObject;
{ Send message to ancestor's constructor } Attr.Menu := LoadMenu(HInstance, PChar(99)); { 99 = menu ID } ButtonDown := False; { Set status flag } end; procedure ModelWindow.cm_Task1(var Msg: TMessage); var continues
184
Parti—Working with T P W
Listing
5-3.
continued
Taskl : PModell; { Pointer to a task } begin Taskl := New(PModell, Init(@Self, 'TimeSeries Model')); Application".MakeWindow(Task1); Taskl".cm_Iterate; { Iterate the task } end; procedure ModelWindow.cm_Task2(var Msg: TMessage); var Task2 : PModel2; { Pointer to a task } begin Task2 := New(PModel2, Init(@Self, 'Henon Attractor')); Application".MakeWindow(Task2); Task2".Iterate; { Iterate the task } end; end.
{ unit Modelwnd }
{ Main test program } program Test_Interface;
{ Generic way to test each phase of interface development }
uses WIF5, modelwnd;
{ Basiclnterface unit } { contains ModelApp, multitasking units }
type App = object(TaskApp) end; var Application: App;
{ An instance of BasicApplication }
{ Run Applicationl } begin Application.Init('Basiclnterface'); { init application instance } Application.Run; { Message loop } Application.Done; { Destroy application instance } end. { end Main test program }
6
CHAPTER
PAINTING, COLLECTING, AND STREAMING Programming in an object-oriented ing a number of objects, according predict at compile time.
language to a pattern
consists in dynamically creatwhich is usually impossible to Bertrand Meyer
A significant s h o r t c o m i n g o f all t h e w i n d o w s d i s c u s s e d s o far ( i n c l u d i n g t h e M a i n , T a s k a n d M o d e l w i n d o w s d e r i v e d f r o m TWindow i n C h a p t e r 4, " I n h e r i t i n g A n I n t e r f a c e , " a n d C h a p t e r 5, " P u t t i n g P i c t u r e s I n W i n d o w s " ) is t h e i r tentativen e s s . I n o t h e r w o r d s , a n y o f t h e text a n d g r a p h i c s d i s p l a y e d i n a w i n d o w c a n d i s a p p e a r w h e n e v e r a w i n d o w is c o v e r e d b y a n o t h e r w i n d o w (for e x a m p l e , w h e n y o u s w i t c h w i n d o w s ) . W h e n a w i n d o w is s u b s e q u e n t l y u n c o v e r e d it n e e d s t o h a v e its c o n t e n t s u p d a t e d (or P a i n t e d ) . Part o f t h e s c r e e n h a s b e e n c o v e r e d b y a n o t h e r w i n d o w , l e a v i n g a w i n d o w ( w h e n u n c o v e r e d ) o n l y partially c o r r e c t . D o t s s h o u l d h a v e filled b o t h s i d e s o f t h e s c r e e n . F i g u r e 6.1 illustrates this p o i n t .
1 8 6 Parti—Working with T P W
Figure
6.1. A time series
model.
W h e n a w i n d o w needs to update its contents, W i n d o w s sends it a Paint message. It is then the window's responsibility to paint itself because W i n d o w s does not keep track of the contents of a window. As you might expect, the mechanics of receiving that message from W i n d o w s are handled automatically by TWindow and any w i n d o w you derive from it. The TWindow Paint method automatically responds to any wm_Paint message, but it does not actually paint the window. TWindow. Paint is abstract, and if you think about it, it is abstract for a good reason; it does not k n o w what is going to be displayed in any of its descendant's windows. Thus, any derived w i n d o w needs to handle the crucial detail of painting itself. T o paint itself, the w i n d o w overrides the TWindow.Paint method to handle the paint. H o w it decides to paint itself is entirely u p to the window. Reconsider the multitasking windows from Chapter 5, "Putting Pictures in Windows," and determine h o w to go about reimplementing a Pain t method for them. The two models generate points corresponding to calculations, and display each point just after it is calculated. If the windows containing the model tasks are covered and required to respond to Paint messages, they have to recalculate each point toredisplayit— not very efficient. Calculating and displaying point-by-point worksfineonly if you do not have to consider redisplaying (Painting) the window. Y o u do have to consider this, however, and you need a classier solution. A good approach (do not hesitate to think of a better one) is to calculate a set of points and store the calculated points where they can be easily retrieved and redisplayed whenever you need them.
6—Painting, Collecting, a n d Streaming
T h e s i m p l e s t ( a n d a typical Pascal) w a y t o c o l l e c t i t e m s s u c h as p o i n t s is t o s t o r e t h e p o i n t s i n a n array. A n array, t h o u g h s i m p l e a n d d i r e c t , is a s i n g l e type, single-size s o l u t i o n , a n d O O P offers a m o r e flexible, d y n a m i c , a n d p o l y m o r p h i c s o l u t i o n — o n e with m o s t o f the details already h a n d l e d b y O b j e c t W i n d o w s . T y p i c a l l y , if y o u s t o r e d a t a i n a n array y o u h a v e t o w r i t e t h e c o d e t o c r e a t e a n d m a n i p u l a t e t h e array. S i m p l e e n o u g h , b u t still a little m o r e w o r k , m o s t o f w h i c h y o u d o n o t n e e d . O O P offers a g e n e r i c s o l u t i o n : a c o l l e c t i o n o f p o i n t e r s to objects a n d the corresponding methods for manipulating the collection.
Polymorphic Collections T h e O b j e c t W i n d o w s TCollection o b j e c t is a n abstract t y p e a n d h a s t w o significant a d v a n t a g e s o v e r arrays: TCollection o b j e c t s c a n size t h e m s e l v e s d y n a m i c a l l y at r u n - t i m e , a n d t h e y c a n b e p o l y m o r p h i c . T h u s , a c o l l e c t i o n c a n g r o w as y o u n e e d it t o , w i t h o u t c h a n g i n g a n y c o d e . B e c a u s e it is p o l y m o r p h i c as w e l l , y o u c a n p u t a n y k i n d o f o b j e c t ( a n d e v e n n o n - o b j e c t s ) i n it. Y o u c a n e v e n m i x the object types within a single collection! B e c a u s e a c o l l e c t i o n u s e s n o n t y p e d p o i n t e r s , it d o e s n o t n e e d t o k n o w a n y t h i n g a b o u t t h e o b j e c t s it's g i v e n t o p r o c e s s . It just s t o r e s t h e m a n d g i v e s t h e m b a c k ; very f l e x i b l e ( s e e f i g u r e 6.2).
A C o l l e c t i o n of P o i n t e r s
Integer
Model
String
(any T O b j e c t d e s c e n d a n t type)
Figure 6.2. A collection of pointers.
Editor
187
188
P a r t i — W o r k i n g with T P W
B e c a u s e c o l l e c t i o n s are g e n e r a l - p u r p o s e , t h e y are u s e f u l i n m a n y d i f f e r e n t kinds of situations. O n e package o f m e t h o d s designed for handling the general t y p e c a n h a n d l e a n y s p e c i f i c t y p e . T h u s , if y o u u s e a c o l l e c t i o n , y o u d o n o t reinvent data-handling m e t h o d s each time y o u change the data type. Bravo, bravo. R e t u r n i n g t o t h e m o d e l tasks o f C h a p t e r 5, " P u t t i n g P i c t u r e s i n W i n d o w s , " w h a t d o y o u n e e d t o d o t o h a n d l e t h e Paint p r o b l e m ? R e c a l l that t h e m o d e l o b j e c t h a s fields t o d e f i n e t h e X a n d Y s c r e e n c o o r d i n a t e s w h e r e p o i n t s a r e d i s p l a y e d a n d a n iterate m e t h o d f o r g e n e r a t i n g p o i n t s . Y o u c a n r e d e f i n e t h o s e c o o r d i n a t e s as a p o i n t o b j e c t , i n c l u d e that o b j e c t i n t h e ModelWindow o b j e c t , c o l l e c t t h o s e p o i n t s r a t h e r t h a n d i s p l a y t h e m i n t h e Iterate m e t h o d , a n d d e f i n e a Pain t m e t h o d f o r d i s p l a y i n g t h e p o i n t s w h e n t h e w i n d o w r e c e i v e s t h e wm_Paint m e s s a g e . First, d e f i n e a point ( o b j e c t ) :
APoint = object(TObject) X, Y: Integer; constructor Init(AX, AY: Integer); end; D e r i v e t h e point f r o m TOb j ect, t h e b a s e o b j e c t for all O b j e c t W i n d o w s o b j e c t s , b e c a u s e a n y o b j e c t that u s e s O b j e c t W i n d o w s ' s t r e a m s m u s t b e d e r i v e d f r o m ( o r trace its o r i g i n t o ) TOb j ect. T h e n i m p l e m e n t a constructor t o create each point:
constructor APoint.Init(AX, AY: Integer); begin X := AX; Y := AY; end; Y o u a l s o n e e d t o d e f i n e a p o i n t e r t o APoint b e c a u s e y o u a r e g o i n g t o c o n s t r u c t p o i n t s d y n a m i c a l l y (as y o u n e e d t h e m ) , u s i n g t h e New p r o c e d u r e a n d APoin t's c o n s t r u c t o r (I n it). B e c a u s e a c o l l e c t i o n a l r e a d y h a s a m e t h o d , c a l l e d Insert for i n s e r t i n g i t e m s i n t o t h e c o l l e c t i o n , y o u d o n o t e v e n h a v e t o w o r r y about adding the point to the collection. D e f i n e a p o i n t e r t o APoint:
PtrPoint = "APoint; C r e a t e a c o l l e c t i o n o f p o i n t s b y d e c l a r i n g a v a r i a b l e o f t y p e PCollect ion (a p r e d e f i n e d p o i n t e r t o a TCollection o b j e c t ) , a n d t h e n d y n a m i c a l l y c r e a t e t h e collection ( o b j e c t ) :
6—Painting, Collecting, and Streaming
189
var Points : PCollection; Points := New(PCollection, Init(1000, 100)); where 1000 is the size of the initial collection and 100 represents the incremental growth of the collection. In other words, you specify an initial sizeforacollection,butthecollectionis not limited to that size; it can grow dynamically by the increment you select. In fact, it can grow to a m a x i m u m size of about 16K, m e m o r y permitting, with each object requiring 4 bytes (the pointer size). If there is not enough m e m o r y to add elements to the collection, the TCollection m e t h o d — T C o l l e c t i o n . Error—automatically receives a message specifying this not-enough-memory condition. The objects you derive from TCollection mightwant to handle this error themselves. For now, do not worry too m u c h about out-of-memory errors; just leave them until Chapter 9 , "Memory Matters," which explores m e m o r y and other more complex matters. Construct and insert a point into the collection in a single step: Points".Insert(New(APoint, Init(X, Y))); Although you are only going to collect points in this collection, remember that you can insert (and retrieve) other types of objects in this same collection using the same technique.
Collecting Points N o w to change a model task from Chapter 5, "Putting Pictures in Windows": 1. A d d the collection to the object (see listing 6.1). Listing
6.1. Adding
the collection
PModell = ~Model1; Modell = object(MainWindow)
to the
object.
{ { { {
Pointer to this task } Time series } Task's data fields } InitX, InitY : real; Initial points } RangeXI, RangeX2, RangeYI, RangeY2 : real; { Range to view } A, B : real; { Factors for this model task } Points : PCollection; { Add the collection } { Task's methods } continues
190
Part I — W o r k i n g w i t h T P W
Listing
6.1.
continued
constructor Init(AParent: PWindowsObject; ATitle: PChar); procedure Scale; { Scale point to window } procedure Iterate; { Iterate model task } destructor Done; virtual; { Clean up } procedure cm_Iterate(var Msg: TMessage); virtual cm_First + cm_Task1; procedure Paint(PaintDC: HDC; { Override Paint } var Paintlnfo: TPaintStruct); virtual; end; 2. Y o u a l s o have t o c o n s t r u c t t h e c o l l e c t i o n a n d let t h e m o d e l k n o w a b o u t it. A g o o d p l a c e t o handle this detail is in t h e M o d e l ' s c o n s t r u c t o r . S e e listing 6.2. Listing
6.2.
The Models
constructor.
constructor Modell.Init(AParent: PWindowsObject; ATitle: PChar); begin TWindow.Init(AParent, ATitle); Attr.Menu := LoadMenu(HInstance, PChar(111)); DisableAutoCreate; Attr.Style := ws_PopupWindow or ws_Caption or ws_Visible; Attr.X Attr.Y Attr.W Attr.H RangeXI RangeX2 RangeYI RangeY2
:= := := := := := := :=
100; 50; 300; 200; -1.03; 1.27; -0.3; 0.45;
A := 1.4; B := 0.3; InitX := 0.4; InitY := 0;
{ Set window dimensions }
{ Set ranges to view }
{ Set factors }
6 —Painting, Collecting, a n d Streaming
X := 0; Y := 0;
191
{ Initial point in space }
Points := New(PCollection, Init(50, 50)); { Construct the collection } end; 3. T h e n , rather
t h a n ( o r after y o u ) d i s p l a y a p o i n t , insert t h e p o i n t i n t h e
c o l l e c t i o n ( s e e listing 6.3). Listing
6.3- Inserting
the point
in the
collection.
procedure Modell.Iterate; var I : integer; TempX, TempY : real; begin InvalidateRect(HWindow, nil,True); { Clear screen } SetCapture(HWindow); DC := GetDC(HWindow); { Get a display context } for I := 1 to Iterations do begin TempX := InitX; { Save last state } TempY := InitY; { Save last state } InitX := TempY + 1 - (A * TempX * TempX);{ This model InitY := B * TempX; { This model Scale; { Scale new state to a window X := I; TextOut(DC,X,Y, ,1); { Draw a point } Points".Insert(New(APoint, Init(X, Y))); { Insert it in collection end; ReleaseCapture; ReleaseDC(HWindow,DC); { Release Display context end;
} } }
1
4. T h e n d i s p l a y t h e c o l l e c t i o n i n t h e revised Paint m e t h o d u s i n g t h e b u i l t - i n TCollection m e t h o d , ForEach ( s e e listing 6.4).
}
}
192
Part I — W o r k i n g w i t h T P W
Listing
6.4. Displaying
the
collection.
procedure Modell.Paint(PaintDC: HDC; var Paintlnfo: TPaintStruct); var First: Boolean; { A where-are-you flag } procedure DisplayPoints(P: PAPoint); far; begin TextOut(PaintDC,P".X,P".Y,'. ,1); First := False; end; 1
begin First := True; Points".ForEach(@DisplayPoints); end; ForEach is o n e o f t h e m a n y TCollection iterator m e t h o d s that y o u c a n
u s e t o traverse a n d m a n i p u l a t e t h e collection. FirstThat a n d LastThat, for e x a m p l e , w o r k m u c h t h e s a m e w a y t o a l l o w a c c e s s t o s p e c i f i c i t e m s i n
t h e collection. N o t e a l s o that Paint u s e s a s p e c i f i c d i s p l a y c o n t e x t , c a l l e d PaintDC. PaintDC is o b t a i n e d a u t o m a t i c a l l y b y TWindow ( a n d its d e s c e n d a n t s ) b e f o r e t h e Paint m e s s a g e is s e n t . PaintDC is r e l e a s e d a u t o m a t i c a l l y after Paint is f i n i s h e d . ( R e m e m b e r that y o u m u s t r e l e a s e a n y d i s p l a y c o n t e x t i m m e d i a t e l y after y o u a r e finished w i t h it b e c a u s e it eats u p s o m u c h m e m o r y . ) A collection is a n a m a z i n g l y u s e f u l t o o l , a n d a n y collection, as s t a t e d earlier, c a n c o n t a i n a m i x t u r e o f o b j e c t s . S u p p o s e , for e x a m p l e , that y o u h a d two objects: • A point • A string o f text:
AString = object(TObject) S: array[0..5] of Char; constructor Init(AnS: array[0..5] of Char); end; Y o u c o u l d a d d t h e m t o t h e s a m e c o l l e c t i o n a n d p l a y t h e m b a c k o n e at a t i m e . C r e a t e t h e n e w string o b j e c t w i t h its c o n s t r u c t o r :
constructor Init(AnS: array[0..5] of Char);
6—Painting, Collecting, a n d Streaming
a n d insert it:
Points".Insert(New(PtrAStr, Init(S))); N o t e that it is y o u r r e s p o n s i b i l i t y t o m a k e s u r e that y o u g e t t h e c o r r e c t o b j e c t b a c k f r o m a collection. T h e p r e v i o u s f r a g m e n t w o r k s , b u t f o r illustrative p u r p o s e s o n l y . I n a m o r e c o m p l e x s i t u a t i o n , y o u p r o b a b l y w a n t s o m e w a y o f i d e n t i f y i n g t h e o b j e c t . If y o u d o p l a n t o u s e m i x e d collections, y o u s h o u l d i m p l e m e n t s o m e f o o l p r o o f p l a n for r e c o g n i z i n g o b j e c t s i n t h e collections. A n a p p r o a c h u s e d w i t h s u c c e s s is t o a d d a n I D field t o e a c h o b j e c t y o u w a n t t o
p u t i n t h e collection. F o r e x a m p l e :
APoint = object(TObject) ID : word; X, Y: Integer; constructor Init(AnID: word AX, AY: Integer); end; T h e n w h e n y o u insert t h e point, y o u insert its ID as w e l l :
Id := 100; { 100 indicates a point } Points".Insert(New(APoint, Init(ID,X,Y))); T h e s a m e g o e s for t h e string:
Id := 102; { 102 indicates a string } Points".Insert(New(AStr, Init(ID,S))); 5. T h e n traverse t h e collection a n d g e t o n l y t h e i t e m s y o u n e e d — f o r e x a m p l e , just t h e p o i n t s . A r e v i s e d Paint m e t h o d t o h a n d l e this s c e n a r i o m i g h t l o o k l i k e listing 6 . 5 .
Listing
6.5. The revised
Paint
method.
procedure Modell.Paint(PaintDC: HDC; var Paintlnfo: TPaintStruct); var First: Boolean; { A where-are-you flag } procedure DisplayPoints(P: PAPoint); far; begin If P".ID = 100 then begin TextOut(PaintDC,P".X,P".Y, . ,1); 1
1
continues
193
194
Part I — W o r k i n g w i t h T P W
Listing
6.5-
continued
First end;
:= False;
end; begin First := True; Points".ForEach(@DisplayPoints); end;
Streams T h e collections y o u h a v e c r e a t e d s o far h a n d l e t h e Paint p r o b l e m b e a u t i f u l l y as l o n g as y o u d o n o t t u r n o f f t h e c o m p u t e r , q u i t t h e p r o g r a m , o r fall p r e y t o s o m e u n f o r e s e e n n a t u r a l disaster, s u c h as a p o w e r f a i l u r e . T h e p r o b l e m is that t h e s e collections exist o n l y i n m e m o r y . W h a t if y o u n e e d t o p r e s e r v e t h e collection for a n o t h e r c o m p u t i n g s e s s i o n ? I n o t h e r w o r d s , h o w c a n y o u Paint a w i n d o w later, after t h e p o i n t s a r e n o l o n g e r r e t a i n e d i n m e m o r y ? Answer: by using streams. A s t r e a m is a c o l l e c t i o n o f o b j e c t s o n its w a y t o s o m e d e v i c e : a file, a p o r t , E M S , a n d s o o n . Again, O b j e c t W i n d o w s already has i m p l e m e n t e d the m e t h o d s y o u n e e d to h a n d l e streams. R e m e m b e r , streams are dynamic a n d polymorp h i c , s o they are capable o f h a n d l i n g d y n a m i c a n d p o l y m o r p h i c collections. Y o u just p u t o b j e c t s i n a s t r e a m a n d g e t t h e m b a c k ( s e e f i g u r e 6.3). A s t r e a m d o e s n o t n e e d t o k n o w t h e k i n d o f o b j e c t s it w i l l s e e , as l o n g as t h e o b j e c t s it s e e s h a v e b e e n r e g i s t e r e d as " s t r e a m a b l e " o b j e c t s . T o u s e a stream, y o u need to 1. D e f i n e a s t r e a m r e g i s t r a t i o n r e c o r d for t h e o b j e c t y o u w a n t t o m a k e streamable. 2. R e g i s t e r t h e s t r e a m b y c a l l i n g t h e g l o b a l p r o c e d u r e RegisterType w i t h t h e s p e c i f i c s t r e a m r e c o r d as its p a r a m e t e r . H e r e is h o w t o d e f i n e a s t r e a m r e c o r d for Apoint: const RPoint: TStreamRec = ( ObjType: 500; VmtLink: 0fs(Type0f(APoint)"); Load: @Point.Load; Store: @Point.Store); end;
6—Painting, Collecting, and Streaming
Streams
Put
Figure
Get
6.3- Streams.
By c o n v e n t i o n any stream constant begins with an R prefix. T h e Ob j Type field is a n u m b e r (a w o r d type) t h a t y o u d e f i n e . O b j e c t W i n d o w s reserves the registration n u m b e r s 0 t h r o u g h 9 9 , so y o u r registration n u m b e r s c a n b e a n y t h i n g f r o m 100 t h r o u g h 6 5 , 5 3 5 . T h e c h o i c e is y o u r s , a n d it c a n b e e n t i r e l y arbitrary, b u t it is a g o o d i d e a t o m a i n t a i n a file o r library o f s t r e a m r e g i s t r a t i o n n u m b e r s t o m a k e it e a s i e r t o k e e p u p w i t h t h e m . T h e V m t L i n k field l i n k s y o u r o b j e c t t o t h e V i r t u a l m e t h o d t a b l e ( V M T ) . Y o u s i m p l y a s s i g n it as t h e offset t o y o u r o b j e c t t y p e . T h e L o a d a n d S t o r e fields h o l d t h e a d d r e s s e s o f t h e L o a d a n d S t o r e methods of the object. After y o u h a v e c o n s t r u c t e d t h e s t r e a m r e g i s t r a t i o n r e c o r d , y o u r e g i s t e r t h e s t r e a m . B e c a u s e all t h e e x a m p l e s i n this c h a p t e r p u t c o l l e c t i o n s i n s t r e a m s , y o u n e e d t o r e g i s t e r t h e c o l l e c t i o n t y p e as w e l l as t h e p o i n t t y p e , w h i c h is i n t h e collection: procedure StreamRegistration; begin RegisterType(RCollection); RegisterType(RPoint); end; M o d i f y t h e m o d e l t o i n c l u d e m e t h o d s f o r h a n d l i n g t h e s t r e a m (see listing 6 . 6 ) .
195
196
Part I — W o r k i n g w i t h T P W
Listing
6.6. Stream
handling.
PModell = "Modell; Modell = object(MainWindow)
{ { { {
Pointer to this task } Time series } Task's data fields } InitX, InitY : real; Initial points } RangeXI, RangeX2, RangeYI, RangeY2 : real; { Range to view } X, Y : integer; { Point to plot } A, B : real; { Factors for this model task } Points : PCollection;
FileName: array[0..fsPathName] of Char; IsDirty, IsNewFile: Boolean; { Task's methods } constructor Init(AParent: PWindowsObject; ATitle: PChar); procedure Scale; { Scale point to window } procedure Iterate; { Iterate model task } destructor Done; virtual; { Clean up } procedure cm_Iterate(var Msg: TMessage); virtual cm_First + cm_Task1; procedure Paint(PaintDC: HDC; var Paintlnfo: TPaintStruct); virtual; procedure LoadFile; procedure SaveFile; end; D e f i n e Point's Load m e t h o d t o s p e c i f i c a l l y handle t h e reading o f t h e X a n d Y fields. Read is a n abstract m e t h o d o f TSt ream a n d m u s t b e o v e r r i d d e n t o l o a d specific o b j e c t s :
constructor Point.Load(var S: TStream); begin S.Read(X, SizeOf(X)); S.Read(Y, SizeOf(Y)); end; ^ D e f i n e t h e Store M e t h o d t o handle t h e w r i t i n g o f Point's X a n d Y fields. Write, like Read, is a n abstract TSt ream m e t h o d , w h i c h m u s t b e o v e r r i d d e n b y
a n y TStream d e s c e n d a n t : procedure Point.Store(var S: TStream); begin S.Write(X, SizeOf(X)); S.Write(Y, SizeOf(Y)); end;
6—Painting, Collecting, a n d Streaming
N e x t , a d d t h e m e n u m e s s a g e r e s p o n s e m e t h o d s t o t h e m o d e l task. A l t h o u g h y o u n e e d t o c r e a t e o n l y FileOpen a n d FileSave m e t h o d s ( t o c o r r e s p o n d t o loading a n d saving points t o a file), y o u c a n e x p a n d the m o d e l task at this p o i n t t o i n c l u d e c r e a t i n g a n e w file (FileNew) a n d s a v i n g a file u n d e r a d i f f e r e n t n a m e (FileSave As). T h e s e files m a k e spiffy a d d i t i o n s t o a n y w i n d o w o r task that n e e d s t o d o g e n e r a l file I/O. A l l t h e s e n e w m e t h o d s u s e file d i a l o g s ( d i s c u s s e d i n C h a p t e r 3, " O b j e c t s f o r W i n d o w s " ) a n d e m p l o y t h e s a m e s t r e a m m e t h o d s for saving a n d getting points. A d d these four m e t h o d s to the m o d e l object: 1. procedure CMFileNew(var Msg: TMessage); virtual cm_First + cm_New; 2. procedure CMFileOpen(var Msg: TMessage); virtual cm_First + cm_Open; 3. procedure CMFileSave(var Msg: TMessage); virtual cm_First + cm_Save; 4. procedure CMFileSaveAs(var Msg: TMessage); virtual cm_First + cm_SaveAs; A g a i n , t h e CM p r e f i x is u s e d t o d e s i g n a t e that t h e m e t h o d r e s p o n d s t o m e n u c o m m a n d m e s s a g e s . T h a t w a y , it's e a s i e r t o r e c o g n i z e t h e s e r e s p o n s e methods. T h e m e n u c o m m a n d m e s s a g e s (cm_Save, cm_SaveAs, cm_Open, a n d c m N e w ) a l r e a d y h a v e b e e n a d d e d t o t h e Basiclnterface ( C h a p t e r 4 , " I n h e r i t i n g a n I n t e r f a c e " ) , s o y o u n e e d t o just d e f i n e a n d i m p l e m e n t t h e r e s p o n s e s . File New l o o k s l i k e t h i s : procedure Modell.FileNew(var Msg: TMessage); begin Points"-FreeAll; { New collection } InvalidateRect(HWindow, nil, True); { Clear screen } IsDirty := False; { Unchanged file flag } IsNewFile := True; { New file flag } end; First FileNew d e l e t e s a n d d i s p o s e s of all t h e i t e m s i n t h e collection ( u s i n g t h e TCollection m e t h o d FreeAll). T h e n it f o r c e s a Paint m e s s a g e (InvalidateRect), which c a u s e s t h e d i s p l a y t o b e u p d a t e d , u s i n g t h e n e w Paint m e t h o d . B e c a u s e t h e r e a r e n o p o i n t s t o d i s p l a y , it c l e a r s t h e w i n d o w . Finally, it sets s o m e flags t o s p e c i f y that t h e file is n e w (IsNewFile : = True) a n d that n o t h i n g n e w h a s b e e n a d d e d t o t h e file (IsDirty : = False).
197
198
P a r t i — W o r k i n g with T P W
FileOpen l o o k s like t h i s :
procedure Modell.FileOpen(var Msg: TMessage); begin if CanClose then if Application".ExecDialog(New(PFileDialog, Init(@Self, PChar(sd_FileOpen), StrCopy(FileName, '*.PTS')))) = id_Ok then LoadFile; end; FileOpen s e n d s a m e s s a g e (ExecDialog) t o c r e a t e a n e w file d i a l o g o b j e c t , a n d t h e n o p e n s t h e file (sdOpen). If all g o e s w e l l , it l o a d s t h e file, u s i n g t h e m o d e l ' s LoadFile m e t h o d , w h i c h i n t u r n u s e s t h e s t r e a m facilities y o u h a v e just set u p . FileSave l o o k s like t h i s :
procedure Modell.FileSave(var Msg: TMessage); begin if IsNewFile then FileSaveAs(Msg) else SaveFile; end; FileSave s i m p l y d e c i d e s w h e t h e r it is d e a l i n g w i t h a NewFile, a n d if n o t , saves t h e file ( u s i n g SaveFile, w h i c h is d i s c u s s e d i n a m o m e n t ) . FileSaveAs l o o k s like t h i s :
procedure Modell.FileSaveAs(var Msg: TMessage); var FileDlg: PFileDialog; begin if IsNewFile then StrCopy(FileName, ' ' ) ; if Application".ExecDialog(New(PFileDialog, Init(@Self, PChar(sd_FileSave), FileName))) = id_0k then SaveFile; end; FileSaveAs a l s o s e n d s a m e s s a g e (ExecDialog) t o c r e a t e a file d i a l o g , a n d after it g e t s a SaveName, calls SaveFile t o a c t u a l l y save t h e file. SaveFile is i n listing 6 . 6 . N o w y o u c a n Store p o i n t s t o a file a n d Load t h e m i n t o t h e a p p l i c a t i o n m e n u w h e n e v e r y o u n e e d t o . T h e c o d e i n listing 6 . 8 at t h e e n d o f this c h a p t e r shows the completely u p d a t e d m o d e l simulation allowing storing a n d loading f r o m files.
A d d Load a n d Store M e t h o d s t o p o i n t :
6—Painting, Collecting, a n d Streaming
PAPoint = "APoint; APoint = object(TObject) X, Y: Integer; constructor Init(AX, AY: Integer); constructor Load(var S: TStream); procedure Store(var S: TStream); end; B e f o r e y o u l e a r n h o w a p o i n t ( o r a n y o b j e c t ) is p u t i n a s t r e a m , n o t e that a d d i n g c o l l e c t a b l e , s t r e a m a b l e o b j e c t s t o t h e m o d e l a l s o c o u l d b e h a n d l e d a bit differently. Y o u c a n d e r i v e a n e w m o d e l o b j e c t that o n l y a d d s t h e n e w c o l l e c t a b l e , s t r e a m a b l e d e t a i l s . T h a t m o d e l c o u l d l o o k like t h i s :
PStreamModell = "StreamModell; StreamModell = object(Modell)
{ Pointer to this task } { Time Series } { Task's data fields }
Points : PCollection; FileName: array[0..fsPathName] of Char; IsDirty, IsNewFile: Boolean; { Task's methods } constructor Init(AParent: PWindowsObject; ATitle: PChar); procedure CMIterate(var Msg: TMessage); virtual cm_First + cm_Task1; procedure Paint(PaintDC: HDC; var Paintlnfo: TPaintStruct); virtual; procedure LoadFile; procedure SaveFile; end; O n l y t h e n e w fields a n d n e w o r r e i m p l e m e n t e d m e t h o d s n e e d t o b e d e s i g n a t e d i n this n e w s t r e a m a b l e o b j e c t . T h e c h o i c e o f w h e n t o d e r i v e a n d w h e n t o a d d t o a n e x i s t i n g o b j e c t is a m a t t e r o f taste a n d , t o a c e r t a i n e x t e n t , a matter of w h e r e y o u draw the general-specific line. Because the "unstreamable" m o d e l d e v e l o p e d i n C h a p t e r 5, " P u t t i n g P i c t u r e s i n W i n d o w s , " n e e d s s t r e a m a n d c o l l e c t i o n c a p a b i l i t y t o b e g e n e r a l - p u r p o s e , a d d that f u n c t i o n a l i t y t o it r a t h e r t h a n d e r i v e n e w o b j e c t s t o r e p r e s e n t 1) a c o l l e c t a b l e a n d 2) a s t r e a m a b l e v e r s i o n . T h r o u g h o u t y o u r W i n d o w s ( O O P p r o g r a m m i n g ) life, y o u h a v e t o decide h o w to handle many such decisions.
Putting Points in a Stream D e c l a r e a variable o f a s t r e a m t y p e d e s c e n d e d f r o m TSt ream (either TDosSt ream,
TBufStream, o r TEmsStream).
199
200
P a r t i — W o r k i n g with T P W
TDosStream irriplements u n b u f f e r e d D O S file s t r e a m s . Its c o n s t r u c t o r a l l o w s y o u t o s p e c i f y a file a c c e s s m o d e (stCreate, stOpenRead, stOpenWrite, a n d stOpen). U s e a TDosSt ream if y o u d o n o t h a v e t o r e a d a n d w r i t e m a n y s m a l l chunks o f data. TBufStream i m p l e m e n t s b u f f e r e d D O S file s t r e a m s . It a l l o w s y o u t o specify t h e size o f a b u f f e r , a n d t h u s is u s e f u l f o r r e a d i n g a n d w r i t i n g s m a l l c h u n k s o f data. TEMSStream i m p l e m e n t s s t r e a m s i n E M S m e m o r y . I n this e x a m p l e , y o u u s e TDosStream: var TheFile: TDosStream; a n d initialize it: TheFile.Init(FileName, stCreate); After t h e s t r e a m is i n i t i a l i z e d , y o u c a n Put t o it a n d Get f r o m it. T h e f o l l o w i n g l i n e p u t s all t h e p o i n t s i n t h e c o l l e c t i o n i n t h e s t r e a m : TheFile.Put(Points);
How Pat Works Y o u put o b j e c t s o n a s t r e a m a n d Put d o e s all t h e w o r k . Y o u d o n o t n e e d t o k n o w h o w Put w o r k s , b u t f o r t h e p l e a s u r e o f it, t h e u n d e r l y i n g w o r k i n g s a r e covered here. First t h e s t r e a m t a k e s t h e V M T p o i n t e r f r o m offset 0 o f t h e o b j e c t ( p o i n t , i n this c a s e ) a n d tries t o m a t c h it w i t h a n o b j e c t r e g i s t e r e d w i t h it. I f it f i n d s a m a t c h i n g r e g i s t e r e d o b j e c t , it w r i t e s t h e s t r e a m ' s r e g i s t r a t i o n n u m b e r t o t h e s t r e a m ' s d e s t i n a t i o n . I n this e x a m p l e , t h e s t r e a m ' s d e s t i n a t i o n is a file, s o t h e first t h i n g it w r i t e s t o t h e file is t h e o b j e c t ' s I D n u m b e r . T h i s s t e p is i m p o r t a n t b e c a u s e it u s e s that I D later w h e n it tries t o g e t o b j e c t s f r o m t h e s t r e a m . T h e s t r e a m t h e n s e n d s a m e s s a g e t o t h e o b j e c t ' s Store m e t h o d ( w h i c h y o u h a v e t o d e f i n e w h e n y o u d e f i n e t h e o b j e c t ) , w h i c h s t o r e s t h e o b j e c t itself. Store u s e s t h e l o w - l e v e l w r i t e p r o c e d u r e f o r w r i t i n g t h e o b j e c t t o t h e s t r e a m . It is b e s t t o u s e t h e SizeOf f u n c t i o n , as y o u d i d i n s t o r i n g a p o i n t , t o m a k e s u r e that t h e c o r r e c t n u m b e r o f b y t e s a r e w r i t t e n t o t h e s t r e a m : S.Write(X, SizeOf(X)); S.Write(Y, SizeOf(Y)); T h a t is all t h e r e is t o p u t t i n g a n o b j e c t i n a s t r e a m . T h e o b j e c t d o e s n o t n e e d t o k n o w a n y t h i n g a b o u t t h e s t r e a m , just h o w t o l o a d a n d s t o r e itself. T h e
6—Painting, Collecting, a n d Streaming
s t r e a m i n g d e t a i l s (like m o s t e v e r y t h i n g e l s e i n t h e O b j e c t W i n d o w s b a g o f tricks) are handled f o r y o u . T h e o n l y o t h e r d e t a i l y o u n e e d t o t a k e care o f is e x p l i c i t l y s e n d i n g a destructor message to cleanup: TheFile.Done; B e c a u s e TheFile (in this c a s e ) is a s t r e a m t y p e d e r i v e d f r o m TDosSt ream, it a l r e a d y has a d e s t r u c t o r (TDosSt ream. Done), w h i c h t a k e s c a r e o f t h e c l e a n u p a u t o m a t i c a l l y . Y o u d o n o t n e e d t o reimplement it. T h e c o d e i n listing 6 . 7 saves all t h e p o i n t s c r e a t e d b y M o d e l l . Listing
6.7. Saving
all points
created
by Model 1.
procedure Modell.SaveFile; var TheFile: TDosStream; begin TheFile.Init(FileName, stCreate); TheFile.Put(Points); TheFile.Done; IsNewFile := False; IsDirty := False; end; Alternatively, y o u c o u l d have u s e d o t h e r s t r e a m s (TBuf Stream, a n d s o o n ) , a n d t h e i m p l e m e n t a t i o n w o u l d have b e e n similar.
Getting Points G e t t i n g p o i n t s o u t o f a s t r e a m is just as s i m p l e . Y o u d e c l a r e v a r i a b l e s t o represent t h e collection a n d t h e stream: var: TempColl: PCollection; AFile: TDosStream; Initialize t h e s t r e a m (AFile), a n d specify that y o u w a n t t o o p e n it f o r reading ( u s i n g stOpen): AFile.Init(FileName, stOpen);
201
202
P a r t i — W o r k i n g with T P W
T h e n get the objects:
TempColl := PCollection(TheFile.Get); T h e Get p r o c e s s is t h e r e v e r s e of t h e Put. First Get retrieves t h e o b j e c t ' s I D n u m b e r a n d s c a n s t h e r e g i s t e r e d s t r e a m t y p e s u n t i l it finds a m a t c h i n g I D n u m b e r . T h e r e g i s t r a t i o n r e c o r d c o n t a i n s t h e a d d r e s s of t h e Load m e t h o d f o r t h e o b j e c t . Get t h e n s e n d s a m e s s a g e t o t h e Load m e t h o d , w h i c h u s e s t h e s t r e a m ' s Read m e t h o d t o a c t u a l l y r e a d o b j e c t s f r o m t h e file o n e at a t i m e :
S.Read(X, SizeOf(X)); S.Read(Y, SizeOf(Y)); N o t e a g a i n that Read relies o n t h e SizeOf f u n c t i o n t o d e t e r m i n e t h e c o r r e c t size of t h e o b j e c t it n e e d s t o r e a d . T h e n c l e a n u p , b y s e n d i n g a Done m e s s a g e :
TheFile.Done; A g a i n , t h e destructor h a s a l r e a d y b e e n i m p l e m e n t e d f o r y o u , s o y o u d o n o t h a v e t o d o a n y t h i n g o t h e r t h a n s e n d t h e Done m e s s a g e t o TheFile (a
TDosStream). L i s t i n g 6.8 s h o w s t h e c o m p l e t e c o d e n e c e s s a r y f o r r e a d i n g t h e p o i n t s s t o r e d t o t h e s t r e a m earlier. N o t e a g a i n t h e InvalidateRect p r o c e d u r e , w h i c h f o r c e s a r e p a i n t m e s s a g e t o b e s e n t t o t h e o b j e c t . A s d i s c u s s e d earlier, t h e Paint m e s s a g e ( w h i c h is n o w d e f i n e d for t h e Model 1 o b j e c t ) c a u s e s t h e p o i n t s t o b e displayed. Listing
6.8. Reading
points
already
stored
to the
procedure Modell.LoadFile; var TempColl: PCollection; TheFile: TDosStream; begin TheFile.Init(FileName, stOpen); TempColl := PCollection(TheFile.Get); TheFile.Done; if TempColl <> nil then begin Dispose(Points, Done); Points := TempColl; InvalidateRect(HWindow, nil, True); end; IsDirty := False; IsNewFile := False; end;
stream.
{forces Paint message}
6—Painting, Collecting, a n d Streaming
P u t t i n g it all t o g e t h e r , listing 6 . 8 s h o w s h o w t o e x t e n d t h e m o d e l task f r o m C h a p t e r 5, " P u t t i n g P i c t u r e s i n W i n d o w s , " m a k i n g it c o l l e c t a b l e , s t r e a m a b l e , and repaintable.
The Sum of Streams S t r e a m s a r e p o l y m o r p h i c . A l l a s t r e a m n e e d s t o k n o w is that it is d e a l i n g w i t h a n o b j e c t d e r i v e d f r o m TOb j ect. T h u s , y o u c a n p u t d i f f e r e n t o b j e c t t y p e s i n t h e same stream. Y o u r p r o g r a m m i n g r e s p o n s i b i l i t y is s i m p l y t o d e f i n e a n d r e g i s t e r t h e kinds of objects y o u want the stream to handle. Y o u c a n then p u t objects in the stream and get t h e m b a c k u s i n g the m e t h o d s provided f o r y o u in ObjectWindows. R e g i s t e r i n g o b j e c t s , as s h o w n , is a s i m p l e m a t t e r , a l m o s t a u t o m a t i c . P u t t i n g a n d g e t t i n g o b j e c t s t o a n d f r o m a s t r e a m is a l m o s t a u t o m a t i c as w e l l . Y o u r p r i m a r y p r o g r a m m i n g task is t o r e g i s t e r o b j e c t s w i t h a s t r e a m a n d k e e p a n inventory o f y o u r registered object records. S t r e a m s a n d c o l l e c t i o n s a r e classic c a s e s o f p o t e n t i a l l y difficult p r o g r a m m i n g tasks b e c o m i n g a l m o s t trivial w i t h T u r b o P a s c a l f o r W i n d o w s . ( Y o u p r o b a b l y t h i n k that T u r b o P a s c a l f o r W i n d o w s h a s t a k e n m o s t t h e w o r k o u t o f d e v e l o p i n g W i n d o w s applications. Y o u are right.) U s i n g t h e Basiclnterface a n d its m u l t i t a s k e x t e n s i o n s d i s c u s s e d i n C h a p t e r 5, " P u t t i n g P i c t u r e s i n W i n d o w s , " y o u c a n a l m o s t r o l l i n t o a n y application p r o b l e m a n d a d d t h e n e w behaviors y o u n e e d for y o u r specific p r o b l e m . Y o u modify a n d extend, not reinvent, using O O P techniques. W i n d o w s c o m p l e x i t y is e n c a p s u l a t e d i n O b j e c t W i n d o w s o b j e c t s , f r o m w h i c h y o u derive y o u r objects, using inheritance. M a n y o f the basic p r o g r a m m i n g p r o b l e m s , s u c h as file I/O a n d d a t a c o l l e c t i n g , h a v e b e e n g e n e r a l i z e d beautifully, s o y o u u s e p o l y m o r p h i s m t o h a n d l e t h e m . Streams a n d collections are e x c e l l e n t e x a m p l e s o f h o w O O P s i m p l i f i e s , y e t e m p o w e r s , p r o g r a m m i n g tasks. W i n d o w s a n d O O P ( T u r b o Pascal f o r W i n d o w s - s t y l e ) a r e f i n e e x a m p l e s o f h o w a sophisticated graphics environment a n d a programming language can b o t h s i m p l i f y a n d e m p o w e r . If y o u h a v e t r i e d t o d e v e l o p W i n d o w s a p p l i c a t i o n s u s i n g t h e S D K o r e v e n B o r l a n d ' s C + + , y o u a l r e a d y k n o w t h i s . T u r b o Pascal f o r W i n d o w s a l l o w s y o u t o a v o i d m a n y m u s t y levels ( s e e listing 6 . 9 ) . Listing
6.9- Making
unit Time3;
a collectable,
streamable,
and repaintable
task.
{ A Model Task } { Responds to cm_Taskt (message) } { Adds streams to Time2 }
interface uses WObjects,
{ Units specific to this unit } continues
203
204
Parti—Working with TPW
Listing
6.9.
continued
WinTypes, WinProcs, strings, StdDlgs, WinDos, WIF5;
{ Basic Interface : contains MainWindow } { : BasicApplication }
{$R TIME1.RES}
{ This task's new resources }
type PModell = "Modell; Modell = object(MainWindow)
{ Pointer to this task } { Time Series } { Task's data fields } InitX, InitY : real { Initial points } RangeXI, RangeX2, RangeYI, RangeY2 : real; { Range to view } X, Y : integer; { Point to plot } A, B : real; { Factors for this model task } Points : PCollection; FileName: array[0..fsPathName] of Char; IsDirty, IsNewFile: Boolean; { Task's methods } constructor Init(AParent: PWindowsObject; ATitle: PChar); procedure Scale; { Scale point to window } procedure Iterate; { Iterate model task } destructor Done; virtual; { Clean up } procedure cm_Iterate(var Msg: TMessage); virtual cm_First + cm_Task1; procedure Paint(PaintDC: HDC; var Paintlnfo: TPaintStruct); virtual; procedure virtual procedure virtual procedure virtual
FileNew(var Msg: TMessage); cm_First + cm_New; FileOpen(var Msg: TMessage); cm_First + cm_0pen; FileSave(var Msg: TMessage); cm First + cm Save;
6—Painting, Collecting, a n d Streaming
procedure virtual procedure procedure
205
FileSaveAs(var Msg: TMessage); cm_First + cm_SaveAs; LoadFile; SaveFile;
end; PAPoint = "APoint; APoint = object(TObject) X, Y: Integer; constructor Init(AX, AY: Integer); constructor Load(var S: TStream); procedure Store(var S: TStream); end; implementation
const RAPoint: TStreamRec = ( ObjType: 500; VmtLink: Ofs(TypeOf(APoint) ); Load: @APoint.Load; Store: ^APoint.Store); A
procedure StreamRegistration; begin RegisterType(RCollection); RegisterType(RAPoint); end;
constructor APoint.Init(AX, AY: Integer); begin X := AX; Y := AY; end;
const Iterations = 3000;
{ Number of iterations for this model } continues
206
P a r t i — W o r k i n g with TPW
Listing
6.9-
continued
constructor Modell.Init(AParent: PWindowsObject; ATitle: PChar); begin TWindow.Init(AParent, ATitle); Attr.Menu := LoadMenu(Hlnstance, PChar(111)); DisableAutoCreate; Attr.Style := ws_PopupWindow or ws_Caption or ws_Visible; Attr.X Attr.Y Attr.W Attr.H RangeXI RangeX2 RangeYI RangeY2
:= := := := := := := :=
100; 50; 300; 200; -1.03; 1.27; -0.3; 0.45;
{ Set window dimensions }
{ Set ranges to view }
A := 1.4; B := 0.3; InitX := 0.4; InitY := 0;
{ Set factors }
X := 0; Y := 0;
{ Initial point in space }
Points := New(PCollection, Init(50, 50)); IsDirty := False; IsNewFile := True; StreamRegistration;
{ Register stream }
end; procedure Modell.cm_Iterate(var Msg: TMessage); begin Iterate; { Iterate the model } end; procedure Modell.Scale;
6—Painting, Collecting, and Streaming 2 0 7
begin { Scale point in space to window } If (InitX = RangeXI) then { A little troubleshooting } X := Attr.X; If (InitX = RangeX2) then X := Attr.W; { and here } If (InitX = 0) then X := X; If (InitX > RangeXI) then X := round((InitX - RangeXI)/(RangeX2 - RangeXI) * (Attr.W - Attr.X)); Y := Attr.H - (round((InitY - RangeYI)/(RangeY2 - RangeYI) * (Attr.H - Attr.Y))); end; destructor Model"!.Done; begin Dispose(Points,Done); TWindow.Done; end;
{ Clean up points } { Call ancestor's destructor }
procedure Modell.Iterate; var I : integer; TempX, TempY : real; begin InvalidateRect(HWindow, nil,True); SetCapture(HWindow); DC := GetDC(HWindow); { Get a display context } for I := 1 to Iterations do begin TempX := InitX; { Save last state } TempY := InitY; { Save last state } InitX := TempY + 1 - (A * TempX * TempX); {This model } InitY := B * TempX; {This model } Scale; { Scale new state to a window } X := I; TextOut(DC,X,Y,'.',1); { Draw a point } Points".Insert(New(PAPoint, Init(X, Y))); end; continues
208
Part I — W o r k i n g w i t h T P W
Listing
6.9-
continued
ReleaseCapture; ReleaseDC(HWindow,DC); end;
{ Release Display context }
procedure Modell.Paint(PaintDC: HDC; var Paintlnfo: TPaintStruct); var First: Boolean; procedure DisplayPoints(P: PAPoint); far; begin TextOut(PaintDC,P".X,P".Y,'.',1); First := False; end; begin First := True; Points".ForEach(@DisplayPoints); end;
procedure Modell.FileNew(var Msg: TMessage); begin Points".FreeAll; InvalidateRect(HWindow, nil, True); IsDirty := False; IsNewFile := True; end; procedure Modell.FileOpen(var Msg: TMessage); begin if CanClose then if Application".ExecDialog(New(PFileDialog, Init(@Self, PChar(sd_FileOpen), StrCopy(FileName, '*.PTS')))) = id_0k then LoadFile; end; procedure Modell.FileSave(var Msg: TMessage); begin if IsNewFile then FileSaveAs(Msg) else SaveFile; end;
6—Painting, Collecting, and Streaming
procedure Modell.FileSaveAs(var Msg: TMessage); var FileDlg: PFileDialog; begin if IsNewFile then StrCopy(FileName, ' ' ) ; if Application".ExecDialog(New(PFileDialog, Init(@Self, PChar(sd_FileSave), FileName))) = id_0k then SaveFile; end; procedure Modell.LoadFile; var TempColl: PCollection; TheFile: TDosStream; begin TheFile.Init(FileName, stOpen); TempColl := PCollection(TheFile.Get); TheFile.Done; if TempColl <> nil then begin Dispose(Points, Done); Points := TempColl; InvalidateRect(HWindow, nil, True); { Forces Paint message } end; IsDirty := False; IsNewFile := False; end;
procedure Modell.SaveFile; var TheFile: TDosStream; begin TheFile.Init(FileName, stCreate); TheFile.Put(Points); TheFile.Done; IsNewFile := False; IsDirty := False; end;
constructor APoint.Load(var S: TStream); begin S.Read(X, SizeOf(X)); continues
209
210
P a r t i — W o r k i n g with TPW
Listing
6.9-
continued
S.Read(Y, SizeOf(Y)); end; procedure APoint.Store(var S: TStream); begin S.Write(X, SizeOf(X)); S.Write(Y, SizeOf(Y)); end;
end. { Unit time3 }
PART T W O
ADVANCED TOPICS
7
CHAPTER
MANY WINDOWS: A MULTIDOCUMENT INTERFACE It's an inherent property of intelligence that it can jump out of the task which it's performing, and survey what it has done; it is always looking for, and often finding, patterns. D o u g l a s R. H o f s t a d t e r O b j e c t W i n d o w s supports the W i n d o w s M u l t i - D o c u m e n t Interface (MDI) stand a r d , w h i c h a l l o w s a n a p p l i c a t i o n o r task t o w o r k s i m u l t a n e o u s l y w i t h m a n y o p e n d o c u m e n t s . U s u a l l y y o u t h i n k o f t h e s e d o c u m e n t s as text, d a t a b a s e , o r s p r e a d s h e e t files. Y o u m i g h t t h i n k o f this as a s p e c i a l k i n d o f m u l t i t a s k i n g s y s t e m , similar yet decidedly different f r o m the multitasking version o f the B a s i c l n t e r f a c e d e v e l o p e d i n C h a p t e r 5, " P u t t i n g P i c t u r e s i n W i n d o w s . " T h e k e y d i f f e r e n c e b e t w e e n t h e B a s i c l n t e r f a c e a n d M D I is that M D I m a k e s it e a s y f o r a s i n g l e a p p l i c a t i o n w i n d o w t o w o r k w i t h m a n y o p e n files. A g o o d e x a m p l e o f this k i n d o f a p p l i c a t i o n is a m u l t i f i l e e d i t o r , d e m o n s t r a t e d later i n this c h a p t e r . T h e B a s i c l n t e r f a c e can have many applications running simultaneously, w h i c h m e a n s m a n y o p e n files, b u t it is still p r i m a r i l y a " 1 w i n d o w , 1 task, 1 o p e n file" s y s t e m . I n t h e B a s i c l n t e r f a c e , o n e file is o p e n f o r e a c h w i n d o w , a n d e a c h w i n d o w h a s its o w n m e n u .
214
Part I I — A d v a n c e d T o p i c s
I n a n M D I s y s t e m , a s i n g l e m e n u serves as t h e c o n t r o l c e n t e r f o r several w i n d o w s at o n c e . T h e T u r b o Pascal I D E a n d M i c r o s o f t E x c e l are e x c e l l e n t e x a m p l e s o f M D I i n s o p h i s t i c a t e d a c t i o n (see figure 7 . 1 ) .
Basicl nterf ace
MDI
M ain W i n d o w
MainWindow
can
control
always controls
child
Child (can have
Figure
child
Child menu)
(no
menu)
7.1. Basiclnterface versus MDI
Y o u can a d d m u l t i d o c u m e n t capability to the B a s i c l n t e r f a c e by writing m o r e c o d e t o h a n d l e a d d i t i o n a l o p e n files, b u t a n e a s i e r w a y is t o u s e a n M D I o b j e c t a n d d e r i v e f r o m it t h e s p e c i f i c a p p l i c a t i o n s y o u n e e d . T h i s c h a p t e r s h o w s y o u h o w t o c r e a t e a B a s i c MDI I n t e r f a c e , w h i c h is then u s e d to derive t w o additional M D I applications.
A Basic MDI Interface J u s t as t h e B a s i c l n t e r f a c e d o e s , t h e MDI I n t e r f a c e c o n s i s t s o f t w o basic o b j e c t s : a n A p p l i c a t i o n a n d a MainWindow. A s y o u m i g h t e x p e c t , t h e y l o o k similar. T h e M D I A p p l i c a t i o n o b j e c t (also d e r i v e d f r o m T A p p l i c a t i o n ) reimplements two methods: InitMainWindow a n d I n i t A p p l i c a t i o n (see figure 7 . 2 ) .
7 — M a n y Windows: A Multi-Document Interface 2 1 5
Using
Pointers
InitApplication
(pointer)
A
Window
(pointer)
Child
Figure
7.2. Using
Window
pointers.
T o designate between the Basiclnterface and theMDI Interface, add "MDI" to M D I object names. A Basic M D I Application object looks like this: MDIApplication = object(TApplication) { Derive an application object } FirstApplication : boolean; procedure InitMainWindow; virtual; { Init a mainwindow } procedure InitApplication; virtual; end; The MainMDIWindow looks like this: PMainMDIWindow = "MainMDIWindow; MainMDIWindow = object(TMDIWindow) function InitChild : PWindowsObject; virtual; end; There are two n e w things to notice: 1. Y o u derive the MainMDIWindow from TMDIWindow. 2. Y o u need to reimplement an InitChild method, which is responsible for constructing the specific kind of child w i n d o w you want to attach to the MainMDIWindow.
216
Part I I — A d v a n c e d T o p i c s
A c h i l d c a n b e a n y w i n d o w t y p e d e r i v e d f r o m TWindow. F o r e x a m p l e : PChildWindow = "ChildWindow; ChildWindow = object(TWindow) end; or PChildWindow = "ChildWindow; ChildWindow = object(MainWindow) end; or PChildWindow = "ChildWindow; ChildWindow = object(ModelWindow) end; A n InitChild m e t h o d that c o n s t r u c t e d a ChildWindow m i g h t l o o k l i k e this: function MainMDIWindow.InitChild : PWindowsObject; begin InitChild := New(PChildWindow, Init(@Self, 'New child')); end; T h e InitChild m e t h o d is n o t l i m i t e d , h o w e v e r , t o c o n s t r u c t i n g a ChildWindow o n l y ; it c a n just as easily c o n s t r u c t a TWindow o r MainWindow directly: function MainMDIWindow.InitChild : PWindowsObject; begin InitChild := New(PMainWindow, Init(@Self, 'New child')); end; S e v e r a l c o m p o n e n t s ( o r f e a t u r e s ) are c o m m o n t o a n y M D I a p p l i c a t i o n . Every M D I a p p l i c a t i o n h a s a m a i n w i n d o w ( c a l l e d a frame w i n d o w ) , a n d w i t h i n t h e f r a m e w i n d o w a n invisible w i n d o w c a l l e d t h e M D I c l i e n t w i n d o w , w h i c h h o l d s M D I c h i l d w i n d o w s . T h e c l i e n t w i n d o w m a n a g e s ( b e h i n d t h e s c e n e s ) its M D I c h i l d w i n d o w s . I n fact, TMDIWindow's m e t h o d s m a i n l y c o n s t r u c t a n d manage child w i n d o w s a n d process m e n u selections. E a c h M D I f r a m e w i n d o w m u s t h a v e a m e n u that c o n t r o l s its c h i l d w i n d o w s . E a c h c h i l d w i n d o w is m a i n t a i n e d i n t h e f r a m e w i n d o w ' s ChildList (a l i n k e d list). T h e f r a m e w i n d o w ' s m e n u is c a l l e d a child window menu. E a c h t i m e a c h i l d w i n d o w is c o n s t r u c t e d a n d o p e n e d , it is a p p e n d e d t o this m e n u a u t o m a t i cally, a n d t h e c u r r e n t l y s e l e c t e d c h i l d w i n d o w is m a r k e d b y a c h e c k .
7 — M a n y Windows: A Multi-Document Interface 2 1 7
Each child w i n d o w can be maximized, minimized, tiled, and cascaded (features implemented for you already). A few restrictions are placed o n a child window: 1. It cannot have a m e n u ; thus all its methods must be controlled by the frame window. This limitation is a good reason to use the Basiclnterface if you need a multitasking system in which each w i n d o w controls its o w n destiny. 2. The child w i n d o w cannot extend outside the frame window's boundaries (Basiclnterface child windows can).
Setting Up a Basic MDI Interface It is simple enough to establish a Basic MDI Interface. It consists of an application object and an MDI W i n d o w (plus its menu). Actually, you have already seen the objects you need for a bare-bones interface. See listing 7.1 for the complete "first go" at the MDI Interface. Figure 7.3 shows the application created by this "first go."
Figure
7.3. The application
created by listing 7.1.
218
Part I I — A d v a n c e d T o p i c s
Listing
7.1. The first
unit WIFmdil;
listing
for
the MDI
Interface.
{ Creates a Basic MDI Windows application interface derived from ObjectWindows; ChildWindows are derived from TWindow object }
interface uses WObjects, WinTypes, WinProcs, WIF5; {$R WIFMdil.RES } type MDIApplication = object(TApplication) { Derive an application object } FirstApplication : boolean; procedure InitMainWindow; virtual; { Init a main window } procedure InitApplication; virtual; end; PMainMDIWindow = "MainMDIWindow; MainMDIWindow = object(TMDIWindow) function InitChild : PWindowsObject; virtual; end; PChildWindow = "ChildWindow; ChildWindow = object(TWindow) end;
implementation
function MainMDIWindow.InitChild : PWindowsObject; begin InitChild := New(PChildWindow, Init(©Self, 'New child')); end;
7 — M a n y W i n d o w s : A M u l t i - D o c u m e n t Interface
{ MDIApplication method implementation } procedure MDIApplication.InitMainWindow; begin if FirstApplication then MainWindow
:= New(PMainMDIWindow,
Init('MDI
Interface',
LoadMenu(HInstance, 'MDIMenul'))) else MainWindow := New(PMainMDIWindow, Init('MDI Additional Instance ,LoadMenu(HInstance, 'MDIMenul'))); end; 1
procedure MDIApplication.InitApplication; begin FirstApplication := True; end; end. L o o k familiar? It s h o u l d — i t is a s i m p l i f i e d v e r s i o n o f t h e first v e r s i o n o f t h e Basiclnterf ace. It u s e s s i m i l a r InitApplication a n d InitMainWindow m e t h o d s . InitMainWindow, a s i n t h e Basiclnterf ace, d e c i d e s w h i c h w i n d o w to construct a n d w h i c h m e n u to load. O n e minor difference between MDIWindows a n d TWindows is that t h e s e c o n d p a r a m e t e r o f t h e LoadMenu m e t h o d m u s t b e a string.
A Model MDI A s w r i t t e n , a ChildWindow c a n b e a n y k i n d o f w i n d o w d e r i v e d f r o m TWindow. F o r e x a m p l e , y o u c o u l d c h a n g e o n e o f t h e task m o d e l s ( w i n d o w s o b j e c t s ) f r o m C h a p t e r 5, " P u t t i n g P i c t u r e s i n W i n d o w s , " t o a c h i l d w i n d o w a n d h a v e a task w i n d o w c r e a t e d e a c h t i m e y o u c r e a t e a c h i l d . L i s t i n g 7.2 s h o w s t h e c o d e t o h a n d l e it, a n d f i g u r e 7.4 s h o w s t h e result. N o t e that t h e m o d e l w i n d o w a p p e a r s , b u t w i t h o u t its m e n u b e c a u s e c h i l d w i n d o w s , r e g a r d l e s s o f t y p e , a r e e x p e c t e d t o b e c o n t r o l l e d b y t h e f r a m e w i n d o w ' s c h i l d m e n u . T h e m o d e l , as it is d e s i g n e d , w o r k s w h e n it is r e s p o n d i n g t o t h e m a i n m e n u ' s c o m m a n d m e s s a g e s , but n o t otherwise—a definite, a n d probably u n w a n t e d , variation o n the m o d e l theme.
219
220
Part I I — A d v a n c e d T o p i c s
Figure Listing
7.4. The result of listing 7*2. Creating
unit WIFmdi3;
7.2.
a task window
for
each child
window.
{ Creates a Basic MDI Windows application interface derived from ObjectWindows; ChildWindows are derived from Model2 object }
interface uses WObjects, WinTypes, WinProcs, WIF5, attract2; {$R WIFMdi3.RES } type MDIApplication = object(TApplication) { Derive an application object } FirstApplication : boolean; procedure InitMainWindow; virtual; { Init a main window } procedure InitApplication; virtual; end;
7 — M a n y W i n d o w s : A M u l t i - D o c u m e n t Interface
221
PMainMDIWindow = "MainMDIWindow; MainMDIWindow = object(TMDIWindow) function InitChild : PWindowsObject; virtual; end; PChildWindow = "ChildWindow; ChildWindow = object(Model2) end;
implementation function MainMDIWindow.InitChild : PWindowsObject; begin InitChild := New(PChildWindow, Init(@Self, 'New child')); end;
{ MDIApplication method implementation }
procedure MDIApplication.InitMainWindow; begin if FirstApplication then MainWindow := New(PMainMDIWindow, Init('MDI Interface', LoadMenu(HInstance, 'MDIMenu3'))) else MainWindow := New(PMainMDIWindow, Init('MDI Additional Instance', LoadMenu(HInstance, 'MDIMenu3'))); end; procedure MDIApplication.InitApplication; begin FirstApplication := True; end; end.
MDI Message Processing M e s s a g e p r o c e s s i n g i n M D I w i n d o w s is s i m i l a r t o that i n n o n - M D I w i n d o w s . E a c h W i n d o w s c o m m a n d m e s s a g e (cm_J g o e s first t o t h e c h i l d w i n d o w c u r r e n t l y s e l e c t e d . A c h i l d , t h e r e f o r e , g e t s t h e first c h a n c e t o r e s p o n d t o t h e
222
Part I I — A d v a n c e d T o p i c s
m e s s a g e . I f it d o e s n o t r e s p o n d , t h e m e s s a g e g o e s t o t h e M D I c l i e n t w i n d o w , a n d finally t o t h e M D I f r a m e w i n d o w . E a c h t i m e y o u select a n M D I c h i l d w i n d o w , it b e c o m e s active a n d r e c e i v e s a W i n d o w s w m M D I A c t i v a t e m e s s a g e . Y o u c a n , if y o u w a n t , d e f i n e a m e s s a g e r e s p o n s e m e t h o d for this m e s s a g e ( u s e f u l w h e n y o u n e e d t o k e e p track o f t h e active ChildWindow). M D I child windows d o not respond to c o m m a n d messages generated by t h e c h i l d w i n d o w m e n u . T h a t is a j o b f o r t h e f r a m e w i n d o w .
Editors B e f o r e y o u g e t t o t h e g r a n d f i n a l e o f this c h a p t e r , a m u l t i - d o c u m e n t text e d i t o r u s i n g t h e MDI Interface, y o u c a n i m p l e m e n t a c o u p l e o f s i m p l e e d i t o r s t o s h o w y o u h o w easy it is t o a d d p o w e r f u l t e x t - e d i t i n g c a p a b i l i t y t o a w i n d o w . O b j e c t W i n d o w s s u p p l i e s t w o d e s c e n d a n t s o f TWindow, w h i c h a r e s p e c i a l i z e d w i n d o w s for text e d i t i n g . TEditWindow is a text e d i t o r that e n a b l e s y o u t o e d i t text i n a w i n d o w : c u t , c o p y , p a s t e , a n d s o o n , t o t h e c l i p b o a r d , b u t d o e s n o t a l l o w y o u t o r e a d a n d w r i t e files. O n e o f its d e s c e n d a n t s , TFileWindow, a d d s r e a d i n g a n d w r i t i n g t o file capability. T h e s e e d i t o r s a r e r e a d y t o g o a n d a r e u s e f u l right o u t o f t h e b o x . T o u s e a n Ed i t w i n d o w r e q u i r e s n o m o r e t h a n a m e s s a g e t o its constructor w h e n y o u initialize a n a p p l i c a t i o n ' s MainWindow. T h e definition: FileWindow = "FileWindow; FileWindow = object(TFileWindow) constructor Init(AParent: PWindowsObject; ATitle: PChar); end; The Implementation: procedure begin
Application.InitMainWindow;
MainWindow end;
:= New(PEditWindow,
Init(nil,
'Edit Window Tester'));
S i m p l e , yes? L i s t i n g 7.3 s h o w s t h e c o m p l e t e c o d e for g e n e r a t i n g t h e text e d i t o r s h o w n in figure 7.5.
7 — M a n y W i n d o w s : A M u l t i - D o c u m e n t Interface
Figure Listing
7.5. The text editor generated 7 . 3 . Generating
a text
by listing
223
73.
editor.
program EditWin; {$R EditWin.RES} uses WObjects, WinTypes, WinProcs, Strings, StdWnds;
type EditApp = object(TApplication) procedure InitMainWindow; virtual; end; PEditWindow = "EditWindow; EditWindow = object(TEditWindow) constructor Init(AParent: PWindowsObject; ATitle: PChar); end; constructor EditWindow.Init(AParent: PWindowsObject; ATitle: PChar); begin continues
224
Part I I — A d v a n c e d T o p i c s
Listing
73.
continued
TEditWindow.Init(AParent, ATitle); Attr.Menu := LoadMenu(HInstance, MakeIntResource(105)); end;
procedure EditApp.InitMainWindow; begin MainWindow := New(PEditWindow, Init(nil, 'Edit Window')); HAccTable := LoadAccelerators(HInstance, MakeIntResource(100)); end; var App : EditApp; begin App.Init('EditWnd'); App.Run; App.Done; end. A d d i n g a FileWindow t o a n a p p l i c a t i o n is just as easy. J u s t d e r i v e t h e EditWindow f r o m TFileWindow r a t h e r t h a n f r o m TEditWindow:
EditWindow = "EditWindow; EditWindow = object(TFileWindow) constructor Init(AParent: PWindowsObject; ATitle: PChar); end; constructor EditWindow.Init(AParent: PWindowsObject; ATitle: PChar); begin TFileWindow.Init(AParent, ATitle, nil); Attr.Menu := LoadMenu(HInstance, 'FileCommands'); end; T h e FileWindow c o m e s c o m p l e t e w i t h a FileDialog f o r c r e a t i n g , o p e n i n g , a n d s a v i n g files; c o m p l e t e c l i p b o a r d c o n n e c t i o n s i n c l u d i n g a n U n d o c o m m a n d , a n d a s e a r c h a n d r e p l a c e facility. T h e o n l y " p r o g r a m m i n g " r e q u i r e d o f y o u is c r e a t i n g a m e n u that c o n t a i n s t h e p r e d e f i n e d I D s f o r file m a n i p u l a t i o n . A l l y o u n e e d t o a d d is a S e a r c h m e n u c h o i c e . Note: T h e T u r b o Pascal s o u r c e c o d e a n d r e s o u r c e s a r e o n t h e u s e r d i s k i n t h e b a c k o f this b o o k . C h a p t e r 8, " R e s o u r c e s a n d C o n t r o l O b j e c t s , " d e t a i l s resource creation. L i s t i n g 7.4 s h o w s t h e c o m p l e t e c o d e f o r i m p l e m e n t i n g t h e File w i n d o w e d i t o r s h o w n i n figure 7.6.
7 — M a n y Windows: A Multi-Document Interface 2 2 5
Figure
Listing
7.6. A file window editor.
7.4.
Generating
a file
window
editor.
program EditWin; {$R EditWin.RES} uses WObjects, WinTypes, WinProcs, Strings, StdWnds;
type EditApp = object(TApplication) procedure InitMainWindow; virtual; end; PEditWindow = "EditWindow; EditWindow = object(TFileWindow) constructor Init(AParent: PWindowsObject; ATitle: PChar); end; constructor EditWindow.Init(AParent: PWindowsObject; ATitle: PChar); begin TEditWindow.Init(AParent, ATitle); Attr.Menu := LoadMenu(HInstance, MakeIntResource(105)); end; continues
2 2 6 Part II—Advanced Topics
Listing
73-
continued
procedure EditApp.InitMainWindow; begin MainWindow := New(PEditWindow, Init(nil, 'Edit Window')); HAccTable := LoadAccelerators(HInstance, MakeIntResource(100)); end; var App : EditApp; begin App.Init('FileWnd'); App.Run; App.Done; end.
An MDI Editor N o w that you have created a FileWindow, you can use it as your M D I child window. It is just another w i n d o w as far as the M D I application is concerned. TFileWindow already has a rich set of methods for handling m a n y of the m e n u c o m m a n d messages an editor needs to respond to, such as cut, copy, saving afile,and so on. Table 7.1 lists the command-message response methods you use "as is," with no modification, in this example. Table
7.2. FileWindow
methods.
Method
Responds
CMEditClear
cm_First + c m E d i t C l e a r
CMEditCopy
cmFirst +
CMEditCut
cmFirst + cmJEditCut
CMEditDelete
cmFirst + cmEditDelete
CMEditPaste
cmFirst + cmEditPaste
CMEditUndo
cmFirst +
CMFileSave
cmFirst + cmFileSave
CMFileSaveAs
c m First + c m F i l e S a v e A s
to Command
cmEditCopy
cmEditUndo
Message
7 — M a n y W i n d o w s : A M u l t i - D o c u m e n t Interface
227
Y o u n e e d t o m o d i f y t h e MDI MainWindow t o h a n d l e t h e m e n u c o m m a n d m e s s a g e s t o c r e a t e a n d o p e n files. T h e n e w CMNewFile m e t h o d n e e d s t o c o n s t r u c t a n e w file e d i t o r . It l o o k s like this:
procedure MDIFileWindow.CMNewFile(var Msg: TMessage); begin Application".MakeWindow(New(PFileEditor, Init(@Self, ''))); end; T h e n e w CMOpenFile m e t h o d n e e d s t o e x e c u t e a file d i a l o g a n d c o n s t r u c t a n e w file e d i t o r . It l o o k s l i k e this:
procedure MDIFileWindow.CMOpenFile(var Msg: TMessage); var FileName: array[0..fsPathName] of Char; begin if Application".ExecDialog(New(PFileDialog, Init(@Self, PChar(sd_FileOpen), StrCopy(FileName, '*.*')))) = id_Ok then Application".MakeWindow(New(PFileEditor, Init(@Self, FileName))); end; It a l s o w o u l d b e c o n v e n i e n t if m e n u i t e m s c o u l d b e t u r n e d o n a n d off, d e p e n d i n g o n w h e t h e r a m e n u i t e m is u s a b l e at t h e t i m e . T h e easiest way t o h a n d l e this e n a b l i n g a n d d i s a b l i n g is t o o v e r r i d e MDI FileWindows' Set upWindow m e t h o d t o d i s a b l e s p e c i f i c m e n u i t e m s . T h e n w h e n a FileWindow is c r e a t e d , you enable the m e n u items. T h e n e w SetupWindow m e t h o d simply u s e s TMDIWindow's d e f a u l t Set upWindow ( w h i c h h a s b e e n c a l l e d automatically if you h a v e n o t o v e r r i d d e n it) a n d t h e n calls t h e EnableMenuItems m e t h o d .
N o t e : W h e n e v e r y o u o v e r r i d e b a s i c m e t h o d s , s u c h as SetupWindow, destructors, a n d s o o n , y o u o f t e n n e e d t o s e n d a message explicitly to the ancestor's m e t h o d to h a n d l e default p r o c e s s i n g . S e n d i n g a m e s s a g e t o a m e t h o d is s i m p l e r t h a n rewriting the default c o d e !
T h e n e w SetupWindow l o o k s l i k e this:
procedure MDIFileWindow.SetupWindow; begin TMDIWindow.SetupWindow; EnableMenuItems(Disable); end;
228
Part I I — A d v a n c e d T o p i c s
T h e EnableMenuItems i m p l e m e n t a t i o n e n s u r e s that m e n u s e l e c t i o n s a r e available o n l y w h e n a n e d i t o r is active. Its i m p l e m e n t a t i o n is s h o w n i n t h e c o d e f o r t h e e n t i r e M D I e d i t o r u n i t i n listing 7.6 at t h e e n d of this c h a p t e r . O n e o t h e r e s s e n t i a l m o d i f i c a t i o n is t o o v e r r i d e t h e d e f a u l t FileWindow destructor t o e n a b l e it t o d e s t r o y all t h e e d i t o r s c r e a t e d d u r i n g a n M D I s e s s i o n . T h e d e f a u l t destructor d o e s n o t look a u t o m a t i c a l l y f o r t h e file e d i t o r s you or your user might have created. F o r t u n a t e l y , it is a s i m p l e m a t t e r t o i m p l e m e n t this n e w destructor,
u s i n g t h e MDI ForEach m e t h o d . A n e w destructor for MDIFileWindow l o o k s like t h i s :
destructor MDIFileWindow.Done; procedure DestroyEditors(AnEditor begin PFileEditor(AnEditor) .Done; end; begin if (Edit'orCount) <> 0 then ForEach(@DestroyEditors); TMDIWindow.Done; end;
: PWindowsObject); far;
A
T h e r e a r e a l s o a f e w nifty f e a t u r e s y o u c a n a d d t o this e d i t o r t o m a k e it look e v e n m o r e s i m i l a r t o t h e T u r b o Pascal for W i n d o w s I D . Y o u c a n l o a d a n Icon
for t h e FileEditor b y m o d i f y i n g t h e GetWindowClass m e t h o d :
procedure FileEditor.GetWindowClass(var AWndClass: TWndClass); begin TFileWindow.GetWindowClass(AWndClass); AWndClass.hlcon := LoadIcon(HInstance, 'FILEICON'); end; Y o u a l s o c a n save a n d r e s t o r e states ( T u r b o Pascal for W i n d o w s style) b y w r i t i n g t h e w i n d o w ' s c u r r e n t state a n d c u r s o r p o s i t i o n t o a s t r e a m (in this c a s e , a file) a n d r e a d i n g it b a c k . T o save a state:
begin S := New(PBufStream, Init(DskFile, stCreate, 1024)); PutChildren(S ); { Handles the save } if S .Status <> stOk then { Status check } begin Dispose(S, Done); FileDelete(DskFile); MessageBox(HWindow, 'Unable to write desktop file.', 'Disk error', A
A
7 — M a n y W i n d o w s : A M u l t i - D o c u m e n t Interface
mb_0k or mb_IconExclamation); end else Dispose(S, Done); PutChildren, aTWindows o b j e c t m e t h o d , is t h e k e y t o s a v i n g t h e s t a t e . It iterates t h r o u g h t h e w i n d o w ' s c h i l d w i n d o w list, w r i t i n g t h e c o n t e n t s o f e a c h of the child w i n d o w s to the stream. T o r e s t o r e a s t a t e , u s e a n o t h e r TWindows o b j e c t m e t h o d , GetChildren, t o d o m o s t o f t h e w o r k . TWindowsObj ect .GetChildren r e a d s t h e s t o r e d contents' child w i n d o w s from the stream, a n d puts t h e m in the window's child w i n d o w list. R e s t o r e l o o k s l i k e this:
procedure MDIFileWindow.CMRestoreState(var Msg: TMessage); var S: PStream; ErrorMsg: PChar; begin ErrorMsg := nil; S := New(PBufStream, Init(DskFile, stOpenRead, 1024)); if S".Status <> stOk then { Error checking } ErrorMsg := 'Unable to open desktop file.' else begin CloseChildren; GetChildren(S'); { Handles the restore } if S".Status <> stOk then ErrorMsg := 'Error reading desktop file.'; if LowMemory then { More error checking } begin CloseChildren; ErrorMsg := 'Not enough memory to open file.' end else CreateChildren; end; if ErrorMsg <> nil then MessageBox(HWindow, ErrorMsg, 'Disk error', mb_0k or mb_IconExclamation); end; Finally, y o u c a n a d d a H e l p W i n d o w t o t h e MDI FileEditor, u s i n g a H e 1 pWn d u n i t l i k e t h e o n e i n l i s t i n g 7.5 that u s e s a list b o x , b u t t o n s , a n d a c o n t r o l to implement a sample help window.
229
230
Part I I — A d v a n c e d T o p i c s
Listing
7.5- Creating
a Help
window.
unit HelpWind; interface uses Strings, WObjects, WinTypes, WinProcs; const id_LB1 id_BN1 id_BN2 id_EC1 id_ST1
= = = = =
201; 202; 203; 204; 205;
type PHelpWindow = "THelpWindow; THelpWindow = object(TWindow) LB1: PListBox; EC1: PEdit; constructor Init(AParent: PWindowsObject; ATitle: PChar); procedure SetupWindow; virtual; procedure IDLB1(var Msg: TMessage); virtual id_First + id_LB1; procedure IDBN1(var Msg: TMessage); virtual id_First + id_BN1; procedure IDBN2(var Msg: TMessage); virtual id_First + id_BN2; procedure FillEdit(SelStringPtr: PChar); virtual; end; implementation constructor THelpWindow.Init(AParent: PWindowsObject; ATitle: PChar); var TempStat : PStatic; TempBtn: PButton; begin TWindow.Init(AParent, ATitle); DisableAutoCreate; Attr.Style := ws_PopupWindow or ws_Caption or ws_Visible; Attr.X := 100; Attr.Y := 100;
7 — M a n y W i n d o w s : A M u l t i - D o c u m e n t Interface
231
Attr.W := 300; Attr.H := 300; LB1 := New(PListBox, Init(@Self, id_LB1, 20, 20, 180, 80)); TempBtn := New(PButton, Init(@Self, id_BN1, 'Help', 220, 20, 60, 30, True)); TempBtn := New(PButton, Init(@Self, id__BN2, 'Cancel', 220, 70, 60, 30, False)); EC1 := New(PEdit, Init(@Self, id_EC1, '', 20, 180, 260, 90, 40, True)); EC1".Attr.Style := EC1 .Attr.Style or ws_Border or ws_VScroll; TempStat := New(PStatic, Init(@Self, id_ST1,'Help Information:', 20, 160, 160, 20, 0)); end; A
procedure THelpWindow.SetupWindow; begin TWindow.SetupWindow; { Fill the listbox } LB1".AddString('Helpl ); LB1".AddString('Help2'); LB1".AddString('Help3'); LB1".AddString('Help4'); LB1".SetSelIndex(0); end; 1
procedure THelpWindow.IDLB1(var Msg: TMessage); var SelString: array[0..25] of Char; begin if Msg.LParamHi = lbn_DblClk then begin LB1".GetSelString(SelString, 25); FillEdit(SelString); end; end; procedure THelpWindow.IDBN1(var Msg: TMessage); var SelString: array[0..25] of Char; begin LB1 .GetSeIString(SelString, 25); FillEdit(SelString); end; A
procedure THelpWindow.IDBN2(var Msg: TMessage); begin CloseWindow; end; continues
232
Part I I — A d v a n c e d T o p i c s
Listing
7.5-
continued
procedure THelpWindow.FillEdit(SelStringPtr: PChar); var TheString: PChar; begin if StrComp(SelStringPtr, 'List Boxes') = 0 then TheString := 'Helpl. else if StrComp(SelStringPtr, 'Buttons') = 0 then TheString := 'Help2.' else if StrComp(SelStringPtr, 'Scroll Bars') = 0 then TheString := 'Help3' else if StrComp(SelStringPtr, 'Edit Controls') = 0 then TheString := 'Help4. ; EC1 .SetText(TheString); end; 1
1
A
end. F i g u r e 7.7 s h o w s t h e c o m p l e t e M D I File E d i t o r w i t h several file e d i t o r s o p e n , a n d listing 7.6 s h o w s t h e c o m p l e t e M D I File e d i t o r c o d e that p r o d u c e d f i g u r e 7.7.
Figure
7.7. The MDI file
editor.
7 — M a n y W i n d o w s : A M u l t i - D o c u m e n t Interface
MDI map-up T h a t a b o u t w r a p s u p t h e MDI Interface a n d t h e first s t a g e o f t h e i n t r o d u c t i o n t o d e v e l o p i n g Windows a p p l i c a t i o n s u s i n g T u r b o P a s c a l for Windows. Chapter 8, " R e s o u r c e s a n d C o n t r o l O b j e c t s , " e x p l a i n s how t o d e v e l o p resources using t h e Whitewater G r o u p ' s Resource Toolkit. B y n o w y o u s h o u l d b e g e t t i n g t h e m e s s a g e that d e v e l o p i n g s o p h i s t i c a t e d a p p l i c a t i o n s for Windows is n o t a c o m p l i c a t e d , m e s s y affair, b u t a c t u a l l y a p l e a s a n t o n e if y o u u s e T u r b o P a s c a l for Windows. Windows d e v e l o p m e n t is n o t difficult if y o u u s e t h e O O P t e c h n i q u e s o u t l i n e d i n t h e s e first s e v e n c h a p t e r s . T h e c o m p l e x part o f Windows d e v e l o p m e n t is t e a c h i n g a n a p p l i c a t i o n t o interact w i t h Windows, a n d that i n t e r a c t i o n is a l r e a d y handled for y o u w h e n y o u u s e O b j e c t W i n d o w s . Y o u just n e e d t o m a k e y o u r a p p l i c a t i o n s respond to events and messages and use O O P techniques to derive y o u r applications and w i n d o w s . When y o u have l e a r n e d t o a d j u s t y o u r o w n t h i n k i n g t o O O P t e r m s , a p p l i c a t i o n d e v e l o p m e n t for Windows is just as e a s y as a p p l i c a t i o n d e v e l o p m e n t for a n y o t h e r e n v i r o n m e n t . I n fact, a p p l i c a t i o n d e v e l o p m e n t for Windows is e a s i e r b e c a u s e t h e i n t e r f a c e , i n c l u d i n g d e v i c e d r i v e r s , I/O, a n d s o f o r t h , is a l r e a d y handled for y o u . Developing one-window or many-window applications using Turbo P a s c a l for Windows is a p i e c e o f d e l i c i o u s c a k e — t o p p i n g , y o u r c h o i c e — r e a l l y . Listing
7.6.
Creating
the complete
unit mdi_ed2;
MDI
editor.
{ Adds File Editor to MDI }
{$R MDIed.RES} interface uses WObjects, WinTypes, WinProcs, WinDos, StdDlgs, StdWnds, Strings, HelpWind; const cm_SaveState = 200; cm_RestoreState = 201; cm_Help = 901; continues
233
234
Part I I — A d v a n c e d T o p i c s
Listing
7.6.
continued
const DskFile = MDI.DSK ; 1
1
type { Declare MDIApp, a TApplication descendant } MDIApp = object(TApplication) procedure InitMainWindow; virtual; procedure Initlnstance; virtual; end; { Declare MDIFileWindow, a TMDIWindow descendant } PMDIFileWindow = "MDIFileWindow; MDIFileWindow = object(TMDIWindow) destructor Done; virtual; procedure SetupWindow; virtual; procedure CMNewFile(var Msg: TMessage); virtual cm_First + cm_MDIFileNew; procedure CMOpenFile(var Msg: TMessage); virtual cm__First + cm_MDIFileOpen; procedure CMSaveState(var Msg: TMessage); virtual cm_First + cm_SaveState; procedure CMRestoreState(var Msg: TMessage); virtual cm_First + cm_RestoreState; procedure CMHelp(var Msg: TMessage); virtual cm_First + cm_Help; end;
{ Declare TFileEditor, a TFileWindow descendant } PFileEditor = "FileEditor; FileEditor = object(TFileWindow) constructor Init(AParent: PWindowsObject; AFileName: PChar); destructor Done; virtual; procedure GetWindowClass(var AWndClass: TWndClass); virtual; function GetClassName: PChar; virtual; end; const RFileEditor: TStreamRec = ( ObjType: 1000; VmtLink: Ofs(TypeOf(TFileEditor) ); Load: ^TFileEditor.Load; A
7 — M a n y Windows: A Multi-Document Interface 2 3 5
Store:
@TFileEditor.Store);
{ TFileEditor } const EditorCount: Integer = 0; type TMenuState = (Enable, Disable); implementation procedure MDIFileWindow.CMHelp(var Msg: TMessage); var HelpWnd: PWindow; begin HelpWnd := New(PHelpWindow, Init(@Self, 'Help System')); Application".MakeWindow(HelpWnd); end; procedure EnableMenuItems(State: TMenuState); procedure EnableCommand(Command: Word); var NewState: Word; begin NewState := mf_ByCommand; if State = Enable then Inc(NewState, mf_Enabled) else Inc(NewState, mf_Disabled + mf_Grayed); EnableMenuItem(PWindow(Application".MainWindow) .Attr.Menu, end; A
begin EnableCommand(cm_FileSave); EnableCommand(cm_FileSaveAs); EnableCommand(cm_ArrangeIcons); EnableCommand(cm_TileChildren); EnableCommand(cm_CascadeChildren); EnableCommand(cm_CloseChildren); EnableCommand(cm_EditCut); EnableCommand(cmJEditCopy); EnableCommand(cm_EditPaste); EnableCommand(cm_EditDelete);
Command, NewState);
{ Response methods already built-in } { To TFileWindow } { To TFileWindow }
continues
236
Part I I — A d v a n c e d T o p i c s
Listing
7.6.
continued
EnableCommand(cm_EditClear); EnableCommand(cm_EditUndo); EnableCommand(cm_EditFind); EnableCommand(cm_EditReplace); EnableCommand(cm_EditFindNext); end; procedure IncEditors; begin if EditorCount = 0 then EnableMenuItems(Enable); { New editor } Inc(EditorCount); end; procedure DecEditors; begin Dec(EditorCount); if EditorCount = 0 then EnableMenuItems(Disable); end; constructor FileEditor.Init(AParent: PWindowsObject; AFileName:PChar); begin TFileWindow.Init(AParent, ' A F i l e N a m e ) ; IncEditors; { Keep track of the number of editors } end; destructor FileEditor.Done; begin TFileWindow.Done; DecEditors; end;
{ Auto destruct using ancestor's Done }
procedure FileEditor.GetWindowClass(var AWndClass: TWndClass); begin TFileWindow.GetWindowClass(AWndClass); { Optional icon } AWndClass.hlcon := LoadIcon(HInstance, 'FILEICON'); end; function FileEditor.GetClassName: begin GetClassName := FileEditor'; end;
PChar;
1
procedure MDIFileWindow.CMNewFile(var
Msg: TMessage);
7 — M a n y W i n d o w s : A M u l t i - D o c u m e n t Interface
begin Application".MakeWindow(New(PFileEditor, end; destructor MDIFileWindow.Done;
Init(@Self,
237
'')));
{ Destroy all editors }
procedure DestroyEditors(AnEditor : PWindowsObject); far; begin PFileEditor(AnEditor) .Done; end; begin if (EditorCount) <> 0 then ForEach(@DestroyEditors); { Use ForEach to destroy all editors } TMDIWindow.Done; end; A
procedure MDIFileWindow.SetupWindow; begin TMDIWindow.SetupWindow; EnableMenuItems(Disable); { Menu items are not usable yet, so disable them } end; procedure MDIFileWindow.CMOpenFile(var Msg: TMessage); var FileName: array[0..fsPathName] of Char; begin if Application".ExecDialog(New(PFileDialog, Init(@Self, PChar(sd_FileOpen), StrCopy(FileName, '*-*')))) = id_Ok then Application".MakeWindow(New(PFileEditor, Init(@Self, FileName))); end; { Save the position and contents of the windows to a desktop file. } procedure MDIFileWindow.CMSaveState(var Msg: TMessage); var S: PStream; function FileDelete(Name: PChar): Integer; assembler; asm PUSH DS LDS DX,Name MOV AH,41H INT 21H JC (a@l XOR AX,AX continues
238
Part I I — A d v a n c e d T o p i c s
Listing
7.6.
@@1:
NEG
continued
AX POP
DS
end; begin S := New(PBufStream, Init(DskFile, stCreate, 2048)); PutChildren(S"); if S".Status <> stOk then begin Dispose(S, Done); FileDelete(DskFile); MessageBox(HWindow, 'Unable to write desktop f i l e . , 'Disk error', mb_Ok or mb_IconExclamation); end else Dispose(S, Done); end; { Read windows positions and contents from a "desktop" file. } procedure MDIFileWindow.CMRestoreState(var Msg: TMessage); var S: PStream; ErrorMsg: PChar; begin ErrorMsg := nil; S := New(PBufStream, Init(DskFile, stOpenRead, 1024)); if S".Status <> stOk then ErrorMsg := 'Unable to open desktop file.' else begin CloseChildren; GetChildren(S'); if S .Status <> stOk then ErrorMsg := 'Error reading desktop file.'; if LowMemory then begin CloseChildren; ErrorMsg := 'Not enough memory to open file.' end else CreateChildren; end; if ErrorMsg <> nil then MessageBox(HWindow, ErrorMsg, 'Disk error', mb_Ok or mb_IconExclamation); end; 1
A
7 — M a n y W i n d o w s : A M u l t i - D o c u m e n t Interface
procedure MDIApp.InitMainWindow; begin MainWindow := New(PMDIFileWindow, Init('MDI Files', LoadMenu(HInstance, 'Commands'))); PMDIFileWindow(MainWindowp.ChildMenuPos := 3; { Register types to be written to stream } RegisterType(RWindow); RegisterType(REdit); RegisterType(RFileEditor); end; procedure MDIApp.Initlnstance; begin TApplication.Initlnstance; if Status = 0 then { Optional loading of accelerator table } begin HAccTable := LoadAccelerators(HInstance, 'FileCommands ); if HAccTable = 0 then Status := em_InvalidWindow; end; end; 1
end.
239
8
CHAPTER
RESOURCES A N D CONTROL OBJECTS
Everyone agrees that the world is also full of large projects.
is full
of large
objects.
Sometimes
the
world
Andrei Codrescu T h e previous seven chapters discussed object-oriented programming in general a n d its a p p r o p r i a t e n e s s t o W i n d o w s a p p l i c a t i o n d e v e l o p m e n t i n p a r t i c u l a r . T h e T u r b o Pascal f o r W i n d o w s s i d e o f W i n d o w s a p p l i c a t i o n d e v e l o p m e n t w a s covered, using resources and control objects, but without detailing h o w you create a n d maintain resources a n d control objects. B e f o r e y o u g o a little d e e p e r i n t o r e s o u r c e s a n d c o n t r o l o b j e c t s , m a k e s u r e that y o u u n d e r s t a n d t h e Pascal s i d e o f W i n d o w s a p p l i c a t i o n d e v e l o p m e n t . I n g e n e r a l , it is a t h r e e - s t e p p r o c e s s : 1. D e r i v i n g a n a p p l i c a t i o n a n d a MainWindow ( f r o m t h e abstract o b j e c t s i n ObjectWindows). 2. C o n n e c t i n g t h e a p p l i c a t i o n a n d its MainWindow t o r e s o u r c e s . 3. T e a c h i n g t h e n e w a p p l i c a t i o n t o r e s p o n d t o e v e n t s a n d m e s s a g e s g e n e r a t e d b y W i n d o w s a n d r e s o u r c e s , s u c h as m e n u s .
242
Part I I — A d v a n c e d T o p i c s
A s it h a s b e e n s h o w n , O O P t e c h n i q u e s s i m p l i f y W i n d o w s a p p l i c a t i o n development by • Encapsulating W i n d o w s ' complexity in objects. • A l l o w i n g y o u t o d e r i v e n e w o b j e c t s f r o m e x i s t i n g o n e s ( u s i n g inheritance). • A l l o w i n g y o u r a p p l i c a t i o n s t o s e n d g e n e r a l m e s s a g e s that a n o t h e r w i n d o w o r a p p l i c a t i o n r e s p o n d s t o as it s e e s fit ( u s i n g p o l y m o r p h i s m ) . • M a k i n g it e a s y f o r a p p l i c a t i o n s t o u s e d y n a m i c o b j e c t s , c o l l e c t i o n s , a n d s t r e a m s , a n d t h u s a l l o w i n g a p p l i c a t i o n s t o m i x a n d m a t c h o b j e c t s , lists, a n d files o f v a r y i n g size a n d n u m b e r . T h e first part o f this c h a p t e r shifts g e a r s a n d e x p l a i n s h o w y o u c r e a t e a n d m a i n t a i n r e s o u r c e s . T h e s e c o n d part s h o w s y o u several m o r e w a y s t o u s e t h e user interface devices called controls o r control objects.
Resources R e s o u r c e s are t h e m e n u s , d i a l o g b o x e s (or w i n d o w s ) , bit m a p s , i c o n s , keyb o a r d a c c e l e r a t o r s , s t r i n g s , a n d c u r s o r s that y o u r T u r b o Pascal f o r W i n d o w s applications use to establish a consistent, user-friendly interface. Y o u c r e a t e r e s o u r c e s o u t s i d e o f T u r b o Pascal f o r W i n d o w s b y 1. U s i n g a r e s o u r c e e d i t o r t o g e n e r a t e a l i n k a b l e (binary) file. 2 . U s i n g a text e d i t o r t o c r e a t e a r e s o u r c e script file, w h i c h y o u " c o m p i l e " o r l i n k i n t o y o u r e x e c u t a b l e ( . E X E ) file u s i n g t h e M i c r o s o f t R e s o u r c e Compiler. R e s o u r c e c o d e a n d P a s c a l c o d e are s t o r e d i n s e p a r a t e files (with R E S a n d P A S e x t e n s i o n s ) a n d m a i n t a i n e d as s e p a r a t e e n t i t i e s . T h i s s e p a r a t i o n o f e n t i t i e s is a d v a n t a g e o u s f o r several r e a s o n s : • O n e resource, for e x a m p l e , can b e u s e d by m o r e than o n e application. • A resource or an application can be changed (and recompiled) without recompiling the other. • R e s o u r c e s a r e , b y d e f a u l t , not loaded i n t o m e m o r y w h e n t h e a p p l i c a t i o n starts. R a t h e r , t h e y are l o a d e d w h e n t h e a p p l i c a t i o n r e q u e s t s t h e m . F i g u r e 8.1 illustrates this c o n c e p t .
8—Resources and Control Objects
R e s o u r c e s aren't loaded until requested
Windows
1)
Load Resource!
Application
2) r e q u e s t
Resource2
Resource3
Figure
8.1. Resources are loaded when an application requests them.
R e s o u r c e s are t h e s p e c i f i c a t i o n s ( e x p r e s s e d as d a t a ) f o r t h e c o r r e s p o n d ing interface e l e m e n t s ( m e n u s , d i a l o g s , a n d s o forth) that Windows constructs for y o u r a p p l i c a t i o n . R e s o u r c e d a t a are s t o r e d in t h e E X E file, b u t n o t in t h e application's data segment, where y o u might expect t h e m to b e stored. R e s o u r c e d a t a a n d Pascal s o u r c e c o d e d a t a d o n o t c o m p e t e f o r t h e s a m e s p a c e . Y o u " c o n n e c t " resources
t o t h e E X E file in o n e o f t h e f o l l o w i n g w a y s :
1. C o p y i n g resources f r o m a R E S file into t h e c o m p i l e d a p p l i c a t i o n ' s E X E file u s i n g t h e Whitewater R e s o u r c e T o o l k i t (or a n o t h e r resource editor) 2. A d d i n g t h e {$R} c o m p i l e r directive t o y o u r . PAS file 3. U s i n g t h e M i c r o s o f t R e s o u r c e C o m p i l e r T h e s i m p l e s t alternative, u s e d in t h e e x a m p l e s s o far, is t o u s e t h e {$R} c o m p i l e r directive. T h i s directive tells t h e c o m p i l e r that y o u w a n t t o a d d t h e s p e c i f i e d resource file t o t h e e n d o f t h e e x e c u t a b l e file. N o t e that y o u c a n c o m p i l e Pascal s o u r c e c o d e that u s e s resources b e f o r e y o u a c t u a l l y create t h e resources. T h u s , y o u c a n write a n d test t h e P a s c a l o r resource part o f t h e a p p l i c a t i o n in either order. If y o u u s e t h e {$R} directive t o a t t a c h resources, however, it m e a n s that t h e resource a n d t h e Pascal s o u r c e c o d e are b o u n d u n l e s s y o u u n b i n d t h e m b y recompiling t h e Pascal s o u r c e c o d e . I n o t h e r w o r d s , y o u c a n n o t e l i m i n a t e a resource s p e c i f i e d b y t h e {$R} directive w i t h o u t recompiling t h e Pascal source c o d e . Y o u c a n still a d d n e w resources b y c o p y i n g n e w resources into t h e E X E
243
244
Part I I — A d v a n c e d T o p i c s
file, b u t y o u risk s o m e c o n f u s i o n b y m i x i n g r e s o u r c e s i n this m a n n e r . W h e n y o u c o m p i l e c o d e e x c l u s i v e l y f o r yourself, it is p r o b a b l y e a s i e r t o u s e t h e { $ R } d i r e c t i v e t o specify r e s o u r c e s . F o r m e , it is s i m p l e s t t o a t t a c h e a c h w i n d o w t o its o w n r e s o u r c e file. If y o u w a n t t o c h a n g e a w i n d o w ' s r e s o u r c e , y o u edit t h e r e s o u r c e file f o r that w i n d o w . A one-window, one-resource-file scenario reduces confusion. F o r e x a m p l e , i n C h a p t e r 7, " M a n y W i n d o w s : A M u l t i - D o c u m e n t Interf a c e , " y o u d e r i v e d a MainMDIWindow f r o m TMDIWindow: PMainMDIWindow = "MainMDIWindow; MainMDIWindow = object(TMDIWindow) function InitChild
: PWindowsObject; virtual;
end; a n d c o n n e c t e d it t o its r e s o u r c e , first u s i n g t h e { $ R } d i r e c t i v e t o attach its r e s o u r c e s t o t h e E X E file: {$R WIFMdil.RES } and then by attaching a m e n u MainMDIWindow: procedure begin
resource
(in M D I M a i n W i n d o w . R E S )
to
MDIApplication.InitMainWindow;
if FirstApplication then MainWindow := New(PMainMDIWindow, Init('MDI LoadMenu(HInstance, MDIMenul ))) 1
Interface , 1
1
else MainWindow := New(PMainMDIWindow, Init('MDI Additional LoadMenu(HInstance, 'MDIMenul')));
Instance ,
end; T h e r e s o u r c e e d i t o r ( t h e W h i t e w a t e r R e s o u r c e T o o l k i t ) is u s u a l l y p r e f e r r e d t o c r e a t e r e s o u r c e s interactively. T o h a v e f u n a n d t o i l l u m i n a t e w h a t a resource editor d o e s for y o u b e h i n d the scenes, however, y o u will p o k e a r o u n d a bit i n a r e s o u r c e script file. Listing 8.1 s h o w s a s i m p l e r e s o u r c e script file g e n e r a t e d w i t h t h e W h i t e w a t e r R e s o u r c e T o o l k i t (after c r e a t i n g t h e r e s o u r c e interactively) a n d t h e T u r b o Pascal f o r W i n d o w s e d i t o r . T h e r e s o u r c e Scriptfile c o n s i s t s e n t i r e l y o f a m e n u r e s o u r c e s p e c i f i c a t i o n . Later i n this c h a p t e r , y o u learn easier ways t o create resources using the Whitewater Resource Toolkit.
1
8—Resources and Control Objects
Listing
8.1. A simple
resource
script
file.
106 MENU LOADONCALL MOVEABLE PURE DISCARDABLE BEGIN POPUP "&File" BEGIN Menultem "&New", 101 Menultem "&Open", 102 Menultem "&Save", 103 Menultem "Save&As", 104 END Menultem "&WriteText", 501 Menultem "&Help", 901 END E a c h r e s o u r c e is a s h o r t b l o c k o f i n f o r m a t i o n w i t h a b e g i n n i n g a n d a n e n d . T h e m e n u resource, for example, has a n a m e :
EditMenu MENU f o l l o w e d b y a Pascal-like b l o c k o f c o d e :
BEGIN END w h i c h specifies m e n u items a n d their c o r r e s p o n d i n g c o m m a n d messages:
MENUITEM " ..." cm_F.. T h e s p e c i f i c a t i o n for a d i a l o g b o x m i g h t l o o k l i k e this i n a . R C (script) file:
AbOUtBox DIALOG 30, 35, 150,100 CAPTION "A Dialog" STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU FONT 10, "Helv" BEGIN CTEXT "A Dialog" -1, 0, 20, 160, CTEXT "More text" -1, 0, 28, 160, ICON "An Icon" -1,8, 8, 0, DEFPUSHBUTTON "OK", IDOK, 50, 45, 30, END
10 10 0 14
L i s t i n g 8.2 s h o w s a m u c h m o r e c o m p l e x r e s o u r c e ( . R C ) file. N o t e that it includes not only m e n u a n d s u b m e n u resource specifications but also m a n y o t h e r r e s o u r c e s as w e l l : d i a l o g s , bit m a p s , s t r i n g s , a c c e l e r a t o r s , a n d s o o n .
245
246
Part I I — A d v a n c e d T o p i c s
Listing
8.2.
A complex
resource
file.
#include "rwpdemoc.pas" men_Main MENU BEGIN POPUP "&File" BEGIN MENUITEM MENUITEM MENUITEM MENUITEM MENUITEM MENUITEM MENUITEM MENUITEM MENUITEM END
"&New", cm_New "&Open...", cm_Open SEPARATOR "&Save", cm_Save "Save &as...", cm_SaveAs SEPARATOR "&Print...", cm_Print SEPARATOR "E&xit", cm_Exit
POPUP "&Edit" BEGIN MENUITEM "&Undo Alt+Backspace", cmJJndo, GRAYED MENUITEM SEPARATOR MENUITEM "Cu&t Shift+Del", cm_Cut, GRAYED MENUITEM "&Copy Ctrl+Ins", cm_Copy, GRAYED MENUITEM "&Paste Shift+Ins", cm_Paste, GRAYED MENUITEM SEPARATOR MENUITEM "Cl&ear \ cm_Clear, GRAYED MENUITEM "D&elete", cm_Delete, GRAYED END POPUP "&View" BEGIN MENUITEM "&A11", cm_All, GRAYED, CHECKED MENUITEM "&Some...", cm_Some, GRAYED MENUITEM SEPARATOR MENUITEM "&By...", cm_By, GRAYED END POPUP "&Options" BEGIN MENUITEM "&Directories...", cm_Directories MENUITEM SEPARATOR POPUP "&Environment" BEGIN MENUITEM "&Preferences...", cm_Preferences
8—Resources and Control Objects
247
MENUITEM "&Mouse...", cm_Mouse END MENUITEM MENUITEM MENUITEM MENUITEM
SEPARATOR "&0pen...", cm_0ptions_0pen "&Save", cm_Options_Save "Save &as...", cm_Options_SaveAs
END POPUP "&Window" BEGIN MENUITEM "&Tile", cm_Tile MENUITEM "&Cascade", cm_Cascade MENUITEM "Arrange &icons", cm_ArrangeIcons MENUITEM "Close &all", cm_CloseAll, GRAYED END POPUP "&Help" BEGIN MENUITEM MENUITEM MENUITEM MENUITEM MENUITEM MENUITEM END
"&Index Shift+F1", cm_Index, GRAYED "&Topic Search Ctrl+F1", cm_Topic_Search, GRAYED "&Glossary", cm_Glossary, GRAYED "Using &Help", cm_Using_Help, GRAYED SEPARATOR "&About RWPDemo...", 145
END dlg_0pen DIALOG 5, 17, 165, 149 CAPTION "Open" STYLE WS_POPUP | WS_CAPTION | WS_SYSMENU BEGIN LTEXT "File &name:", -1, 5, 3, 38, 12 CONTROL "", 100, "COMBOBOX", CBS_DROPDOWN | WS_VSCROLL | WS_GROUP | WS_TABSTOP, 46, 2, 111, 44 LTEXT "Path:", - 1 , 8 , 18, 16, 8 LTEXT "", 103, 29, 18, 127, 9, SS_LEFT | WS_GROUP LTEXT "&Files:", -1, 12, 32, 16, 8 LTEXT "&Directories", -1, 96, 33, 51, 9 CONTROL "", 101, "LISTBOX", LBS_STANDARD, 6, 43, 70, 59 CONTROL "", 102, "LISTBOX", LBS_STANDARD, 92, 43, 70, 59 CONTROL "Options", -1, "button", BS_GROUPBOX | WS_GROUP, 8, 105, 150, 22 continues
248
Part I I — A d v a n c e d T o p i c s
Listing
8.2.
continued
CONTROL "&Text", 205, "BUTTON", BS_AUTORADIOBUTTON | WS_TABSTOP, 17, 113, 37, 12 CONTROL "&Scribble", 206, "BUTTON", BS_AUTORADIOBUTTON j WS_TABSTOP, 68, 113, 36, 12 CONTROL &Graph", 207, "BUTTON", BS_AUTORADIOBUTTON | WS_TABSTOP, 118, 113, 35, 12 DEFPUSHBUTTON "&0K", 1, 11, 130, 24, 14 PUSHBUTTON "&Cancel", 2, 71, 130, 28, 14 PUSHBUTTON "&Help", 210, 135, 130, 24, 14 H
END dlg_SaveAs DIALOG 10, 18, 129, 147 CAPTION "Save As" STYLE WS_POPUP | WS_CAPTION | WS_SYSMENU BEGIN LTEXT "File &name:", -1, 8, 2, 38, 12 CONTROL "", 100, "COMBOBOX", CBS_DROPDOWN | WS_VSCROLL | WS_GROUP | WS_TABSTOP, 48, 2, 76, 38 LTEXT "Path:", -1, 9, 19, 16, 8 LTEXT "", 101, 29, 21, 92, 8 LTEXT "&Directories", -1, 14, 30, 68, 9 CONTROL "", 103, "LISTBOX", LBS_STANDARD, 11, 40, 70, 59 DEFPUSHBUTTON "&OK", 1, 6, 127, 24, 14 PUSHBUTTON "&Cancel", 2, 51, 127, 28, 14 PUSHBUTTON "&Help", 210, 98, 127, 24, 14 END dlg_Print DIALOG 36, 14, 163, 133 CAPTION "Print" STYLE WS_POPUP | WS_CAPTION J WS_SYSMENU BEGIN LTEXT "Copies:", -1, 5, 11, 28, 8 LTEXT "", 211, 35, 12, 16, 8, WSJ3ROUP CONTROL "", -1, "static", SS_BLACKFRAME, 35, 10, 16, 10 CONTROL "Pages", -1, "button", BS_GROUPBOX, 4, 24, 155, 30 CONTROL "&A11", 212, "BUTTON", BS_AUTORADIOBUTTON j WS_TABSTOP, 36, 29, 28, 12 CONTROL "&Partial", 213, "BUTTON", BS_AUTORADIOBUTTON | WS_TABSTOP, 36, 41, 35, 8 CONTROL "", 214, "static", SS_GRAYFRAME, 98, 41, 12, 8 LTEXT "From:", -1, 75, 41, 19, 8 LTEXT "To:", -1, 114, 41, 16, 8 CONTROL "", 215, "static", SS_GRAYFRAME, 134, 41, 11, 8 LTEXT "Printers", -1, 6, 61, 31, 8 CONTROL "", 216, "LISTBOX", LBS_STANDARD, 3, 70, 143, 37 DEFPUSHBUTTON "P&rint", 217, 5, 114, 24, 14 PUSHBUTTON "Printer &setup...\ 218, 37, 114, 51, 14
8 — R e s o u r c e s and Control Objects
PUSHBUTTON "&Cancel", 2, 97, 114, 27, 14 PUSHBUTTON "&Help", 210, 133, 114, 24, 14 END acc_Main ACCELERATORS BEGIN VK_BACK, 24325, VIRTKEY, ALT VK_DELETE, 24320, VIRTKEY, SHIFT VK_INSERT, 24321, VIRTKEY, CONTROL VK_INSERT, 24322, VIRTKEY, SHIFT VK_F1, 141, VIRTKEY, SHIFT VK_F1, 142, VIRTKEY, CONTROL END
dlg_About DIALOG 82, 19, 121, 86 CAPTION "About CUA" STYLE WS_POPUP | WS_CAPTION | WS_SYSMENU BEGIN LTEXT "Common User Access Example", -1, 10, 5, 108, 11 LTEXT "Copyright (c) 1990, Borland International", -1, 26, 49, 70, 15 DEFPUSHBUTTON "&0K", 1, 49, 69, 24, 14 ICON "icon_1", -1, 53, 25, 16, 16 END
DIAL0G_5 DIALOG 11, 18, 177, 79 CAPTION "Directories" STYLE WS_POPUP | WS_CAPTION | WS_SYSMENU BEGIN LTEXT "&Scribble Directory", -1, 9, 5, 66, 10, SS_LEFT | WS_GROUP LTEXT "&Text Directory", -1, 9, 22, 64, 10, SS_LEFT j WS_GROUP LTEXT "&Graphics Directory", -1, 9, 40, 64, 8, SS_LEFT | WS_GROUP CONTROL "", ID_ScribbleDirectory, "COMBOBOX", CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP, 80, 4, 95, 32 CONTROL "", id_TextDirectory, "COMBOBOX", CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP, 80, 22, 95, 32 CONTROL "", id_GraphicDirectory, "COMBOBOX", CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP, 80, 40, 95, 32 continues
249
250
Part I I — A d v a n c e d T o p i c s
Listing
8.2.
continued
DEFPUSHBUTTON "&0K", id_0k, 16, 61, 24, 14 PUSHBUTTON "&Cancel", id_Cancel, 68, 61, 26, 14 PUSHBUTTON "&Help", id__Help, 122, 61, 24, 14 END dlg_Preferences DIALOG 13, 21, 210, 88 CAPTION "Preferences" STYLE WS_P0PUP | WS_CAPTION | WS_SYSMENU BEGIN CONTROL "Desktop file", -1, "button", BS_GROUPBOX, 5, 7, 88, 52 CONTROL "&None", 222, "BUTTON", BS_AUTORADIOBUTTON | WSJTABSTOP, 11, 17, 78, 11 CONTROL "C&urrent directory", 223, "BUTTON", BS_AUTORADIOBUTTON | WS_TABSTOP, 11, 28, 74, 13 CONTROL "Conf&ig file directory", 224, "BUTTON", BS_AUTORADIOBUTTON | WSJTABSTOP, 11, 41, 73, 12 CONTROL "Autosave", -1, "button", BS_GROUPBOX, 97, 7, 109, 52 CONTROL "&Editor files", 225, "BUTTON", BS_AUTOCHECKBOX i WS_TABSTOP, 102, 18, 91, 9 CONTROL "&Environment", 226, "BUTTON", BS_AUTOCHECKBOX | WS_TABSTOP, 102, 31, 88, 9 CONTROL &Desktop", 227, "BUTTON", BS_AUTOCHECKBOX | WS_TABSTOP, 102, 44, 60, 9 DEFPUSHBUTTON "&0K", 1, 23, 67, 24, 14 PUSHBUTTON "&Cancel", 2, 72, 67, 37, 14 PUSHBUTTON "&Help", 210, 134, 67, 24, 14 END H
dlg_Mouse DIALOG 14, 12, 190, 97 CAPTION "Mouse" STYLE WS_POPUP | WS__CAPTION | WS__SYSMENU BEGIN CONTROL "&Right mouse button", -1, "button", BS_GROUPBOX, 8, 5, 77, 59 CONTROL "", 231, "scrollbar", SBS_HORZ, 95, 32, 86, 9 LTEXT "Mouse Click", -1, 93, 11, 90, 9 LTEXT "Fast", -1, 95, 22, 16, 8 LTEXT "Slow", -1, 161, 22, 16, 8 CONTROL "&Reverse mouse buttons", 232, "BUTTON", BS_AUTOCHECKBOX | WSJTABSTOP, 97, 48, 90, 9 CONTROL "&Nothing", 228, "BUTTON", BS_AUTORADIOBUTTON WSJTABSTOP, 18, 19, 55, 12
8—Resources and Control Objects
CONTROL "&Clear Window", 229, "BUTTON", BS_AUTORADIOBUTTON \ WS_TABSTOP, 18, 33, 55, 12 CONTROL "&lnverse Color", 230, "BUTTON", BS_AUTORADIOBUTTON | WSJTABSTOP, 18, 47, 55, 12 DEFPUSHBUTTON "&0k", 1, 11, 76, 24, 14 PUSHBUTTON "&Cancel", 2, 64, 76, 30, 14 PUSHBUTTON "&Help", 210, 123, 76, 24, 14 END
R C D A T A J RCDATA BEGIN "\07\07Wake up!!\07\07\0" , "\11Hello world" , 25 0x05f "\07" END CURSOR 1 CURSOR rwdemo.CUR
ico RWPDemo ICON rwdemo.ICO
STRINGTABLE BEGIN sth_FileNew, "Help on New" sth_FileOpen, "Help on Open" sth_FileSave, "Help on Save" sth_FileSaveAs, "Help on SaveAs" sth_FilePrint, "Help on Print" sth_FileExit, "Help on Exit" sth_File, "Help on File" sth_EditUndo, "Help on Undo" sth_EditCut, "Help on Cut" sth_EditCopy, "Help on Copy" sth_EditPaste, "Help on Paste" sth_EditClear, "Help on Clear" sth_EditDelete, "Help on Delete" sth_Edit, "Help on Edit" sth_ViewAll, "Help on View All" sth_ViewSome, "Help on View Some" sth_ViewBy, "Help on View By" continues
251
252
Part I I — A d v a n c e d T o p i c s
Listing
8.2.
continued
sth_View, "Help on View" sth__OptionsDirectory, "Help on Directories" sth_OptionsEnvironment, "Help on Environment" sth_OptionsOpen, "Help on Options Open" sth_OptionsSave, "Help on Options Save" sth_OptionsSaveAs, "Help on Options Save As" sth_Option, "Help on Option" sth_EnvironmentPreferences, "Help on Preferences" sth_EnvironmentMouse, "Help on Mouse" sth_WindowTile, "Help on Window Tile" sth_WindowCascade, "Help on Window Cascade" sth_WindowArrange, "Help on Window Arrange" sth_WindowIcon, "Help on Window Icon" sth_WindowCloseAll, "Help on Window CloseAll" sthJA/indow, "Help on Window" sth_HelpIndex, "Help on Index" sth_HelpTopic, "Help on Topic" sth_HelpSearch, "Help on Search" sth_HelpGlossary, "Help on Glossary" sth_HelpUsing, "Help on Using Help" sth_HelpAbout, "Help on About" sth_Help, "Help on Help" END bmp_StatusLine BITMAP BEGIN '42 4D F6 02 00 00 00 '00 00 40 00 00 00 14 '00 00 80 02 00 00 00 '00 00 00 00 00 00 00 '00 00 00 80 80 00 80 '00 00 80 80 80 00 C0 '00 00 00 FF FF 00 FF '00 00 FF FF FF 00 88 '88 88 88 88 88 88 88 '88 88 88 88 88 88 87 '77 77 77 77 77 77 77 '77 77 77 77 77 F8 87 '88 88 88 88 88 88 88 '88 88 88 88 88 F8 87 '88 88 88 88 88 88 88 '88 88 88 88 88 F8 87 '88 88 88 88 88 88 88 '88 88 88 88 88 F8 87 '88 88 88 88 88 88 88
00 00 00 00 00 C0 00 88 88 77 77 88 88 88 88 88 88 88 88
00 00 00 00 00 C0 00 88 88 77 77 88 88 88 88 88 88 88 88
00 00 00 00 00 00 00 88 88 77 77 88 88 88 88 88 88 88 88
76 01 00 00 80 00 FF 88 88 77 77 88 88 88 88 88 88 88 88
00 00 00 00 00 00 00 88 88 77 77 88 88 88 88 88 88 88 88
00 04 00 80 80 FF FF 88 88 77 77 88 88 88 88 88 88 88 88
00 00 00 00 00 00 00 88 88 77 77 88 88 88 88 88 88 88 88
28 00 00 00 80 00 FF 88 88 77 77 88 88 88 88 88 88 88 88
00' 00' 00' 80' 80' FF' FF' 88' 88' 77' 77' 88' 88' 88' 88' 88' 88' 88' 88'
8—Resources and Control Objects
•88 '88 '88 '88 '88 '88 *88 '88 '88 '88 '88 '88 '88 '88 '88 '88 '88 '88 '88 '88 '88 '88 '88 '88 '88 'FF 'FF '88 '88
88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 FF FF 88 88
88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 FF FF 88 88
88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 FF FF 88 88
88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 FF FF 88 88
F8 87 88 88 F8 87 88 88 F8 87 88 88 F8 87 88 88 F8 87 88 88 F8 87 88 88 F8 87 88 88 F8 87 88 88 F8 87 88 88 F8 87 88 88 F8 87 88 88 F8 87 88 88 F8 8F FF FF F8 88 88 88 88'
88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 FF FF 88 88
88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 FF FF 88 88
88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 FF FF 88 88
88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 FF FF 88 88
88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 FF FF 88 88
88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 FF FF 88 88
88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 FF FF 88 88
88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 FF FF 88 88
88* 88' 88' 88' 88' 88' 88' 88' 88' 88' 88' 88' 88' 88' 88' 88' 88' 88' 88' 88' 88' 88' 88' 88' FF' FF 88' 88' 1
END
N o t e : These bit maps must be developer-generated, either through the use of ASCII codes (the tedious way), or through the Whitewater Resource Toolkit (the easy way).
1 FONT rwdemo.FNT dlg_FileNew DIALOG 37, 18, 130, 129 CAPTION "New" STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION BEGIN CONTROL "Text", id_Text, "BUTTON", BS_AUTORADIOBUTTON | WS_TABSTOP, 39, 17, 41, 12 continues
253
254
Part I I — A d v a n c e d T o p i c s
Listing
8.2.
continued
CONTROL "Scribble", id_Scribble, "BUTTON", BS_AUTORADIOBUTTON | WS_TABSTOP, 39, 39, 40, 12 CONTROL "Graphics", id_Graphics, "BUTTON", BS_AUTORADIOBUTTON \ WS_TABSTOP, 39, 61, 41, 12 CONTROL "", -1, "button", BS_GROUPBOX, 32, 8, 66, 74 CONTROL "OK", id_OK, "BUTTON", BS_DEFPUSHBUTTON | WS_TABSTOP, 31, 98, 30, 14 CONTROL "Cancel", id_Cancel, "BUTTON", BS_PUSHBUTTON | WS_TABSTOP, 71, 98, 31, 14 END B I T M A P J BITMAP BEGIN '42 4D 16 01 00 00 00 00 '00 00 0A 00 00 00 14 00 '00 00 A0 00 00 00 00 00 '00 00 10 00 00 00 00 00 '00 00 00 80 80 00 80 00 '00 00 80 80 80 00 C0 C0 '00 00 00 FF FF 00 FF 00 *00 00 FF FF FF 00 88 88 '87 77 77 00 00 00 88 8F '87 88 88 80 88 88 88 8F '87 88 88 00 00 00 88 8F '87 88 88 00 00 04 88 8F '87 88 88 00 00 40 88 8F '87 88 88 00 00 00 88 8F '87 88 88 00 00 00 88 8F '87 88 88 00 00 00 88 8F '87 88 88 00 00 00 FF FF '88 88 88 00 00 00' END 1000 MENU BEGIN POPUP "Color" BEGIN MENUITEM "Red", 1 MENUITEM "Green", 1 MENUITEM "Blue", 1 END POPUP "Width" BEGIN MENUITEM "Thin", 108
00 00 00 00 00 C0 00 88 87 87 87 87 87 87 87 87 8F
00 00 00 00 00 00 00 88 88 88 88 88 88 88 88 88 FF
76 01 00 00 80 00 FF 88 88 88 88 88 88 88 88 88 FF
00 00 00 00 00 00 00 08 00 44 00 00 A0 08 00 00 00
00 04 00 80 80 FF FF 88 00 00 00 10 82 00 00 00 00
00 00 00 00 00 00 00 00 00 04 00 00 02 22 00 00 00
28 00 00 00 80 00 FF 77 88 88 88 88 88 88 88 88 88
00' 00' 00' 80' 80' FF FF 7F' 8F' 8F 8F' 8F 8F' 8F 8F' 8F' 88' 1
1
1
1
1
8—Resources and Control Objects
MENUITEM MENUITEM
255
"Normal", 1 "Item", 1
END END 1001 MENU BEGIN POPUP "Shape" BEGIN MENUITEM "Circle", 1 MENUITEM "Rectangle", 1 END POPUP BEGIN
"Color" MENUITEM MENUITEM MENUITEM
"Red", 1 "Green", 1 "White", 1
END END S c r i p t files s u c h as t h e o n e s i n listing 8 . 1 a n d 8 . 2 h a v e a . R C e x t e n s i o n , a r e c o m p i l e d with the Microsoft Resource C o m p i l e r , a n d t h e n are a p p e n d e d to t h e P a s c a l a p p l i c a t i o n ( u s u a l l y u s i n g t h e { $ R } d i r e c t i v e ) . Y o u r a p p l i c a t i o n is, o f c o u r s e , still r e s p o n s i b l e f o r a t t a c h i n g t h e r e s o u r c e t o a w i n d o w ( i n t h e Pascal for W i n d o w s c o d e ) . F o r e x a m p l e , y o u load a m e n u already specified in a r e s o u r c e file b y ID 99: constructor ATaskWindow.Init(AParent : PWindowsObject; ATitle : PChar); begin TWindow.Init(AParent, ATitle); { Send message to ancestor's constructor } Attr.Menu := LoadMenu(HInstance, PChar(99)); { 99 = menu ID } end;
Resource Editors R e s o u r c e e d i t o r s , s u c h as t h e o n e s i n t h e W h i t e w a t e r R e s o u r c e T o o l k i t ( W R T ) , c a n g e n e r a t e script files ( R C ) a n d l i n k a b l e r e s o u r c e files ( R E S ) . U s i n g t h e W h i t e w a t e r R e s o u r c e T o o l k i t , y o u u s u a l l y w a n t t o g e n e r a t e R E S files, t h e d e f a u l t . I n that c a s e , y o u s e l e c t W R T ' s S a v e M e n u i t e m a n d s p e c i f y a file.
256
Part II—Advanced Topics
T o indicate that you want to generate a scriptfile(.RC) rather than a resource file (RES), use the WRT's SaveAs m e n u item and select the .RC control button from the ensuing dialog window. Notice that the dialogs, menus, keyboard accelerators, and so on, you use to interact with the Whitewater Resource Toolkit are similar to those you create for your applications. This is a beauty of the W i n d o w s interface: these resource editors are examples of the kinds of applications you can create using W i n d o w s development tools like Turbo Pascal for W i n d o w s and W R T . The way these (and other) applications use and interact with W i n d o w s resources is covered in Chapter 13, "Designing W i n d o w s Applications." T o give you a feel for using a resource editor, the Whitewater Resource Toolkit is used to create a dialog w i n d o w and m e n u for an application.
Dialog Windows A dialog box is a w i n d o w m a d e u p of controls like those you see infigure8.2.
Figure
8.2. A dialog
box.
Recall that controls are such items as list boxes, push buttons, edit fields, and so on. Each control is a child w i n d o w that acts as an input device; in other words, it is an interactive componentforcommunicating with a user. The dialog box (or window) is the parent window.
8—Resources and Control Objects
T o c r e a t e , e d i t , o r d e s i g n a d i a l o g b o x , y o u start w i t h a g e n e r i c d i a l o g b o x (with o r w i t h o u t a c a p t i o n ) . Y o u m o v e it a r o u n d a n d c h a n g e t h e t y p e , c o n t e n t , a n d location o f controls in the dialog b o x t o create t h e specific dialog b o x y o u want. T h e dialog b o x editor allows y o u to w o r k with t w o palettes: •
Tools
•
Alignment
U s e t h e T o o l s p a l e t t e t o c r e a t e a d i a l o g b o x a n d its c o n t r o l s . U s e t h e Alignment palette to align the controls within the dialog b o x . By using the controls in a dialog b o x — t h a t is, by clicking buttons, c h e c k i n g b o x e s , a n d s e l e c t i n g i t e m s f r o m a list, a u s e r c a n " c o n t r o l " a n application. Controls enable a user to 1. K n o w w h i c h f u n c t i o n s a r e available t o h i m . 2. A l t e r t h e f l o w o f a n a p p l i c a t i o n ( f r o m o b j e c t t o o b j e c t , f r o m task t o task, f r o m f u n c t i o n t o f u n c t i o n ) . G o o d u s e o f d i a l o g b o x e s ( a n d its c o n t r o l s ) c a n e l i m i n a t e a n a p p l i c a t i o n ' s m y s t e r i e s a n d i l l u m i n a t e its p u r p o s e s . T h e A p p l e M a c i n t o s h b e c a m e p o p u l a r i n l a r g e part b e c a u s e it is s o e a s y t o u s e . W i n d o w s b r i n g s that e a s e o f u s e t o t h e P C . W i n d o w s d e f i n e s a set o f m e s s a g e s that c o o r d i n a t e t h e e x c h a n g e o f i n f o r m a t i o n b e t w e e n a n a p p l i c a t i o n a n d its c o n t r o l s . F o r e x a m p l e , list b o x " r e t u r n " m e s s a g e s a r e p r e f i x e d b y lb_. C o m b o b o x " r e t u r n " m e s s a g e s a r e p r e f i x e d b y cb_. B u t t o n " r e t u r n " m e s s a g e s a r e p r e f i x e d b y bn_, a n d s o o n . I n a d i a l o g b o x (a w i n d o w ) , m e s s a g e s g o b o t h w a y s : t o t h e c o n t r o l a n d b a c k f r o m t h e c o n t r o l . T o s e n d a m e s s a g e — t o a d d a string t o a list b o x f o r e x a m p l e — y o u might d o this:
procedure ADialog.AddStrings(var Msg: TMessage); var Txt : PChar; begin Txt := 'SomeText'; SendDlgItemMsg(id_LB1, lb_AddString,0, Longlnt(Txt)); end; SendDlgltemMsg is a TDialog m e t h o d . T h u s , a n y d i a l o g w i n d o w y o u d e r i v e f r o m TDialog a u t o m a t i c a l l y k n o w s h o w t o s e n d d i a l o g m e s s a g e s . id_LB1 is a c o n s t a n t r e p r e s e n t i n g a list b o x I D . Y o u u s e it t o specify t h e c o n t r o l t o r e c e i v e t h e SendDlgltemMsg. T o g e t a result (of a u s e r click, f o r e x a m p l e ) , y o u r d i a l o g w i n d o w r e s p o n d s to a control notification message, w h i c h represents the user's action. Each c o n t r o l n o t i f i c a t i o n m e s s a g e i n c l u d e s a n o t i f i c a t i o n c o d e (sent t h r o u g h Msg. lParamHi) that s p e c i f i e s t h e c o n t r o l ' s c h a n g e o f state.
257
258
Part I I — A d v a n c e d T o p i c s
Write a response m e t h o d for any control notification message y o u want the dialog w i n d o w or application to respond to. For example:
ADialog = object(TDialog) procedure Handlel_istBox1Msg(var Msg: TMessage); virtual id_First + id_BN1; end; procedure ADialog.HandleListBoxlMsg(var Msg: TMessage); begin case Msg.lParamHi of lbn_SelChange: { Handle selection here } lbn_DblClk: { Handle a double click here } end; end; lbn_ p r e f i x e d m e s s a g e s a r e g e n e r a t e d w h e n a u s e r clicks i n t h e list b o x . T h e HandleListBoxl Msg m e t h o d t h u s c a n b e u s e d t o r e s p o n d t o t h e m e s s a g e s y o u w a n t t h e list b o x t o r e s p o n d t o . N o t i f i c a t i o n m e s s a g e s y o u d o n o t i n t e r c e p t are h a n d l e d a u t o m a t i c a l l y ( b u t w i t h o u t a n y r e s p o n s e ) b y TDialog m e t h o d s ( w h i c h ADialog i n h e r i t e d ) . A d i a l o g is t h u s a t w o - w a y c o m m u n i c a t i o n , s e n d i n g m e s s a g e s t o c o n t r o l s a n d r e s p o n d i n g t o their notification messages. F o r e x a m p l e , create a dialog w i n d o w that r e s p o n d s t o a c o n t r o l (a b u t t o n ) b y s e n d i n g a m e s s a g e t o a n o t h e r c o n t r o l (a list b o x ) . Listing 8.3 s h o w s t h e c o m p l e t e c o d e ( w h i c h is c o v e r e d i n t h e f o l l o w i n g s e c t i o n ) , a n d figure 8.3 s h o w s t h e d i s p l a y e d r e s u l t s . Listing
8.3. A dialog
box
program DialEx;
example.
{ Chapter 8, example dialog }
{$R EX_DIAL.RES} uses WinTypes, WinProcs, WObjects; const TheMenu id_LB1 id__BN1
= 100; = 151; =152;
cm_DialogEx
=101;
{ Menu command message }
type PExDialog = "ExDialog; ExDialog = object(TDialog) procedure IDBN1(var Msg: TMessage); virtual id_First + id_BN1; procedure IDLB1(var Msg: TMessage); virtual id_First + id_LB1; end;
8—Resources and Control Objects
259
PDialogWindow = "DialogWindow; DialogWindow = object(TWindow) constructor Init(AParent: PWindowsObject; ATitle: PChar); procedure CMDialogEx(var Msg: TMessage); virtual cm_First + cm_DialogEx; end; DlgApplication = object(TApplication) procedure InitMainWindow; virtual; end; { ExDialog } procedure ExDialog.IDBN1(var Msg: TMessage); var Textltem : PChar; begin Textltem := 'Menus'; SendDlgItemMsg(id_LB1, lb_AddString, 0, Longlnt(Textltem)); Textltem := 'Accelerators'; SendDlgItemMsg(id_LB1, lb_AddString, 0, Longlnt(Textltem)); Textltem := 'Bitmaps'; SendDlgItemMsg(id_LB1, lb_AddString, 0, Longlnt(Textltem)); Textltem := 'Cursors'; SendDlgItemMsg(id_LB1, lb_AddString, 0, Longlnt(Textltem)); Textltem := 'Icons'; SendDlgItemMsg(id_LB1, lb_AddString, 0, Longlnt(Textltem)); Textltem := 'Dialogs'; SendDlgItemMsg(id_LB1, lb_AddString, 0, Longlnt(Textltem)); Textltem := 'File Dialogs'; SendDlgItemMsg(id_LB1, lb_AddString, 0, Longlnt(Textltem)); end; procedure ExDialog.IDLB1(var Msg: TMessage); var Idx : Integer; SelectedText: array[0..10] of Char; begin if Msg.LParamHi = lbn_SelChange then begin Idx := SendDlgItemMsg(id_LB1, lb_GetCurSel, 0, Longlnt(O)); SendDlgItemMsg(id_LB1, lb_GetText, Idx, Longlnt(^SelectedText)); MessageBox(HWindow, SelectedText, 'List Box Notification', MB_OK); end; end; continues
260
Part I I — A d v a n c e d T o p i c s
Listing
8.3-
continued
{ DialogWindow } constructor DialogWindow.Init(AParent: PWindowsObject; ATitle: PChar); begin TWindow.Init(AParent, ATitle); Attr.Menu := LoadMenu(Hinstance, MakelntResource(TheMenu)); end; procedure DialogWindow.CMDialogEx(var Msg: TMessage); var Return : Integer; begin Return := Application".ExecDialog(New(PExDialog, Init(@Self, 'EXDialog'))); If Return = id_Cancel then MessageBox(HWindow, 'id_cancel', 'List Box Notification', MB_0K); end; { DlgApplication } procedure DlgApplication.InitMainWindow; begin MainWindow := New(PDialogWindow, Init(nil, 'Example Dialog, Chapter 8')); end; var MyApp: DlgApplication; begin MyApp.Init('Example ) ; MyApp.Run; MyApp.Done; end. 1
Details First, u s e t h e W h i t e w a t e r R e s o u r c e T o o l k i t t o c r e a t e a list b o x . U s e t h e d i a l o g editor to 1. First e x p a n d t h e size o f t h e d e f a u l t d i a l o g ( w h i c h p o p s u p w h e n e v e r y o u o p e n the dialog editor). 2. S e l e c t a list b o x f r o m t h e c o n t r o l m e n u a n d , u s i n g t h e m o u s e , p l a c e it i n t h e d i a l o g w i n d o w (see f i g u r e 8 . 4 ) .
8—Resources and Control Objects
Figure
8.3. A dialog box
example.
Figure
8.4. A list box from the control menu, placed
into a dialog
window.
3. Edit the attributes of the list box by clicking Controls/Attributes as s h o w n in figure 8.5.
261
262
Part II—Advanced Topics
Figure
8.5.
Controls/Attributes.
4. Select button objects to interact with the user and place them using the m o u s e (see figure 8.6).
Figure
8.6. Button objects placed by using the mouse.
5. Select a button for completing the dialog and place it, as in figures 8.7 and 8.8.
8—Resources and Control Objects
Figure
8.7. A button for completing
the
6. D e f i n e n o t i f i c a t i o n c o d e s .
Figure
8.8. The new button in
context.
dialog.
263
264
Part I I — A d v a n c e d T o p i c s
7. Finally, create the usual gang of objects that interact with the resources you just created. As usual, create a n e w application object (deriving it from BasicApplication) and a DlgWindow (deriving it from MainWindow), and aDialogto handle list box and button messages: type PExDialog = "ExDialog; ExDialog = object(TDialog) procedure IDBN1(var Msg: TMessage); virtual id_First + id_BN1; procedure IDLB1(var Msg: TMessage); virtual id_First + id_LB1; end; PDialogWindow = "DialogWindow; DialogWindow = object(TWindow) constructor Init(AParent: PWindowsObject; ATitle: PChar); procedure CMDialogEx(var Msg: TMessage); virtual cm_First + cm_DialogEx; end; DlgApplication = object(TApplication) procedure InitMainWindow; virtual; end; InitMainWindow should look familiar: construction of a type of w i n d o w for the DlgApplication. In this case, a DlgWindow: procedure DlgApplication.InitMainWindow; begin MainWindow := New(PDialogWindow, Init(nil, 'Example Dialog, Chapter 6' end; Construct the DlgWindow: constructor DialogWindow.Init(AParent: PWindowsObject; ATitle: PChar); begin TWindow.Init(AParent, ATitle); Attr.Menu := LoadMenu(Hinstance, MakelntResource(TheMenu)); end; Note the use ofMakelntResource, a W i n d o w s function that typecasts integers into resource names. It is equivalent to typecasting into a PChar type: Attr.Menu := LoadMenu(Hinstance, PChar(100)); which attaches the same m e n u to DialogWindow.
8—Resources and Control Objects
265
ExDialogis u s e d o n l y to interpret notification m e s s a g e s a n d has no fields. B e c a u s e it is also a standard d i a l o g , y o u d o n o t n e e d to d e f i n e a n e w constructor. TDialog's constructor is c a l l e d w h e n DialogWindow s e n d s a n " e x e c u t e d i a l o g " m e s s a g e in response to t h e CMDialogEX m e n u c o m m a n d message: procedure DialogWindow.CMDialogEx(var Msg: TMessage); var Return : Integer; begin Return := Application".ExecDialog(New(PExDialog, Init(@Self, 'EXDialog'))); If Return = id_Cancel then MessageBox(HWindow, 'id_cancel', 'List Box Notification', MB_0K); Notice in this e x a m p l e that you take a quick l o o k at the R e t u r n v a l u e of Application" .ExecDialog. S o m e t i m e s it is u s e f u l to check this result just in c a s e Application". ExecDialog fails. F o r e x a m p l e , if you specify t h e n a m e of a d i a l o g that c a n b e e x e c u t e d , ExecDialog returns zero. If the d i a l o g c a n n o t b e e x e c u t e d (for e x a m p l e , if t h e d i a l o g n a m e is m i s s p e l l e d ) , ExecDialog returns a negative v a l u e corresponding to a pred e f i n e d c o n s t a n t . T o e x p e r i m e n t with t h e s e error results, t y p e s o m e garbage into the d i a l o g n a m e field, a n d look at t h e result. For e x a m p l e , if y o u d o n o t have a dialog resource n a m e d "NoDialog," t y p e that n a m e in t h e n a m e field, where "ExDialog" is n o w . This p r o c e s s g e n e r a t e s a n error. D e f i n e t h e m e t h o d for responding to a n AddString m e s s a g e : { ExDialog } procedure ExDialog.IDBN1(var Msg: TMessage); var Textltem : PChar; begin Textltem := 'Menus'; SendDlgItemMsg(id_LB1, lb_AddString, 0, Longlnt(Textltem)); Textltem := 'Accelerators'; SendDlgItemMsg(id_LB1, lb_AddString, 0, Longlnt(Textltem)); Textltem := 'Bitmaps'; SendDlgItemMsg(id_LB1, lb_AddString, 0, Longlnt(Textltem)); Textltem := 'Cursors ; SendDlgItemMsg(id_LB1, lb_AddString, 0, Longlnt(Textltem)); Textltem := 'Icons '; SendDlgItemMsg(id_LB1, lb_AddString, 0, Longlnt(Textltem)); Textltem := 'Dialogs ; SendDlgItemMsg(id_LB1, lb_AddString, 0, Longlnt(Textltem)); Textltem := 'File Dialogs'; SendDlgItemMsg(id_LB1, lb_AddString, 0, Longlnt(Textltem)); end; 1
1
266
Part I I — A d v a n c e d T o p i c s
H e r e is a m e t h o d f o r r e s p o n d i n g t o a list-box n o t i f i c a t i o n
message
i n d i c a t i n g that t h e u s e r s e l e c t e d a n i t e m :
procedure ExDialog.IDLB1(var Msg: TMessage); var Idx : Integer; SelectedText: array[0..10] of Char; begin if Msg.LParamHi = lbn_SelChange then begin Idx := SendDlgItemMsg(id_LB1, lb_GetCurSel, 0, Longlnt(0)); SendDlgItemMsg(id_LB1, lb_GetText, Idx, Longlnt(^SelectedText)); MessageBox(HWindow, SelectedText, 'List Box Notification', MB_0K); end; end; N o t e that y o u c a n d e f i n e d i a l o g s i n s e p a r a t e files s p e c i f i e d b y . D L G e x t e n s i o n s . F o r e x a m p l e , t h e p r e v i o u s d i a l o g ' s . D L G file l o o k s like t h i s :
EXDIALOG DIALOG DISCARDABLE L0AD0NCALL PURE MOVEABLE 30, 49, 188, 100 STYLE WS_P0PUP | WS_DLGFRAME BEGIN CONTROL "Fill List Box" 152, "BUTTON", WS_CHILD | WS_VISIBLE j WS_TABSTOP, 111, 13, 68, 12 CONTROL "Cancel" 2, "BUTTON", WS_CHILD | WS_VISIBLE | WSJTABSTOP, 112, 66, 68, 12 CONTROL "LISTBOX" 151, "LISTBOX", WS_CHILD J WS_VISIBLE | WS_BORDER | WS_VSCROLL | 0x3L, 8, 8, 83, 73 END If y o u d o m a i n t a i n d i a l o g s , m e n u s , a n d s o f o r t h , i n s e p a r a t e files, y o u can combine them whenever you need to by using the Whitewater Resource T o o l k i t B r o w s e r t o c o p y r e s o u r c e s b e t w e e n files. D o this b y o p e n i n g t w o browsers a n d using the Browser C o p y c o m m a n d to c o p y resource specificat i o n s b e t w e e n files. F i g u r e 8.9 illustrates this i d e a .
N o t e : T h e W h i t e w a t e r R e s o u r c e T o o l k i t is c o m p l e t e l y m e n u driven. T o add resources (controls, boxes, button, and so o n ) , use y o u r m o u s e t o click the m e n u items, t h e n drag t h e m across the screen.
8—Resources and Control Objects 2 6 7
Figure
8.9. Using the Whitewater Resource
Toolkit to copy resources between
files.
Control Objects Dialog boxes are composed of control objects, but control objects do not have to be part of a dialog. Y o u might want to use control objects as stand-alone "windows." ObjectWindows object types m a k e it easy for you to incorporate any of ten controls in your o w n applications. These controls are listed in table 8 . 1 . Table
8.1. Controls
to incorporate
in your
Control
ObjectWindows
Check box
TCheckBox
C o m b o box
TComboBox
Edit control
TEdit
Group box
TGroupBox
List box
TListBox
M D I client
TMDIClient
Push button
TButton
own
applications. Object
Type
continues
268
Part I I — A d v a n c e d T o p i c s
Table
8.1.
continued
Control
ObjectWindows
Radio button
TRadioButton
Scroll bar
TScrollBar
Static c o n t r o l
TStatic
Object
Type
T h e O b j e c t W i n d o w s type, TControl, is t h e a n c e s t o r f o r all c o n t r o l o b j e c t s . It is b a s e t y p e , s o y o u n e v e r instantiate a TControl; y o u instantiate its descendents. TControl is d e s c e n d e d from TWindow. T h u s , a n y c o n t r o l is a k i n d o f w i n d o w that c a n d i r e c t t h e flow o f a n a p p l i c a t i o n . A l t h o u g h y o u c a n derive n e w c o n t r o l s f r o m t h e c o n t r o l s in O b j e c t W i n d o w s , y o u p r o b a b l y n e v e r w i l l ; i n s t e a d y o u m i x a n d m a t c h t h e m t o create t h e c o n t r o l w i n d o w y o u w a n t . A l s o n o t e that a c o n t r o l is a child w i n d o w t o its p a r e n t (the M a i n a p p l i c a t i o n w i n d o w ) a n d i s , i n t u r n , u n d e r t h e p a r e n t w i n d o w ' s " c o n t r o l . " It is t h e responsibility o f t h e p a r e n t w i n d o w t o create t h e c o n t r o l (its child). Derive a n e w k i n d o f MainWindow, c a l l e d a TaskControlWindow: PTaskControlWindow = "TaskControlWindow; TaskControlWindow = object(MainWindow) constructor Init(AParent: PWindowsObject; ATitle: PChar); end; a n d a d d a radio b u t t o n t o it: PTaskControlWindow = "TaskControlWindow; TaskControlWindow = object(MainWindow) Rad1: PRadioButton; end; In this e x a m p l e , t h e c o n t r o l (Rad1, a p o i n t e r t o a RadioButton) is represented b y a d a t a f i e l d . Alternatively, it c a n b e represented b y a variable in its p a r e n t ' s c o n s t r u c t o r . F o r e x a m p l e : constructor Init(AParent: PWindowsObject; ATitle: PChar); var Rad1 : PRadioButton; begin {....} end;
8—Resources and Control Objects
269
E i t h e r w a y , t h e c o n t r o l is c o n s t r u c t e d b y its p a r e n t ' s c o n s t r u c t o r . V e r s i o n 1:
constructor TaskControlWindow.Init(AParent: PWindowsObject; ATitle: PChar); begin MainWindow.Init(AParent, ATitle); Rad1 := New(PRadioButton, Init(@Self, id_Rad1, 'Task 1', 74, 64, 138, 24, Groupl)); end; O r ( V e r s i o n 2):
constructor TaskControlWindow.Init(AParent: PWindowsObject; ATitle: PChar); var Rad1 : PRadioButton; begin MainWindow.Init(AParent, ATitle); Rad1 := New(PRadioButton, Init(@Self, id_Rad1, 'Task 1', 74, 64, 138, 24, Groupl)); end; Y o u c r e a t e o t h e r c o n t r o l o b j e c t s similarly. F o r e x a m p l e , a list b o x :
constructor TaskControlWindow.Init(AParent: PWindowsObject; ATitle: PChar); begin MainWindow.Init(AParent, ATitle); ListBoxl := New(PListBox, Init(@Self, id_LB1, 74, 64, 138, 24)); end; or a c o m b o box:
constructor TaskControlWindow.Init(AParent: PWindowsObject; ATitle: PChar); begin MainWindow.Init(AParent, ATitle); ListBoxl := New(PComboBox, Init(@Self, id_CB1, 74, 64, 138, 24, cbs_DropList,40)); end; E a c h c o n t r o l s u p p o r t e d b y a n O b j e c t W i n d o w s o b j e c t is a s e l f - c o n t a i n e d o b j e c t w i t h its o w n m e t h o d s a n d d a t a . Y o u r a p p l i c a t i o n s i m p l y : 1. C o n s t r u c t s a n o b j e c t . 2. S e n d s it m e s s a g e s . 3. P r o c e s s e s t h e r e s u l t s .
270
Part I I — A d v a n c e d T o p i c s
Group Boxes O n e w a y o f u s i n g c o n t r o l s is t o p r o c e s s t h e m " a s a g r o u p , " b y u n i f y i n g t h e m i n a g r o u p b o x . A g r o u p b o x is a s p e c i a l k i n d o f i n t e r f a c e o b j e c t that c o r r e s p o n d s t o t h e g r o u p b o x e l e m e n t i n W i n d o w s . A g o o d w a y t o set u p a g r o u p b o x is t o c r e a t e it as a s t a n d - a l o n e c h i l d w i n d o w w i t h i n a n o t h e r w i n d o w ' s c l i e n t a r e a . C r e a t e a g r o u p b o x that u n i f i e s a g r o u p o f r a d i o b u t t o n s . E a c h b u t t o n e n a b l e s a u s e r t o specify a task. I n o t h e r w o r d s , t h e g r o u p b o x acts as a task c o n t r o l l e r . T h e u s e r selects a task t o e x e c u t e b y c l i c k i n g a r a d i o b u t t o n . T h e a p p l i c a t i o n r e s p o n d s b y i t e r a t i n g t h e task. R e c a l l t h e w a y y o u b u i l t t h e task m a n a g e r i n C h a p t e r s 5, 6, a n d 7 b y d e r i v i n g a n e w k i n d of m a i n w i n d o w ( c a l l e d T a s kWi n d ow), w h i c h r e s p o n d e d t o c o m m a n d m e s s a g e s ( g e n e r a t e d b y a m e n u ) . T h e TaskWindow r e s p o n d e d t o a R u n T a s k m e s s a g e b y c r e a t i n g a n i n s t a n c e of t h e w i n d o w that c o n t a i n e d t h e task. T h e p l a n h e r e is similar: 1. D e r i v e a n e w w i n d o w c a l l e d TaskControlWindow f r o m MainWindow. 2. A d d c o n t r o l s t o it: t w o r a d i o b u t t o n s (to r e p r e s e n t t w o t a s k s ) , a c o n t r o l b o x t o u n i f y t h e task b u t t o n s , a n d a m e t h o d t o m a i n t a i n t h e g r o u p :
PTaskControlWindow = "TaskControlWindow; TaskControlWindow = object(MainWindow) TaskButtonl, TaskButton2: PRadioButton; TaskGroupl: PGroupBox; constructor Init(AParent: PWindowsObject; ATitle: PChar); procedure HandleTaskGroup1Msg(var Msg: TMessage); virtual id_First + id_Group1; end; T h e TaskControlWindow c o n s t r u c t o r c r e a t e s all t h e c o n t r o l s :
constructor TaskControlWindow.Init(AParent: PWindowsObject; ATitle: PChar); begin MainWindow.Init(AParent, ATitle); TaskGroupl := New(PGroupBox, Init(@Self, id_Group1, 'Task Box', 58, 52, 176, 108)); TaskButtonl := New(PRadioButton, Init(@Self, id_Rad1, 'Task 1', 74, 64, 138, 24, Groupl)); TaskButton2 := New(PRadioButton, Init(@Self, id_Rad2, 'Task 2', 74, 84, 138, 24, Groupl)); end;
8—Resources and Control Objects
T h e g r o u p handler decides h o w to interpret the button-state c h a n g e s in the group:
procedure TaskControlWindow.HandleGroup1Msg(var Msg: TMessage); var TextBuff: array[0..20] of Char; { A button ID } Compare : integer; { Int to record comparison } Taskl : PModell; { Pointer to a task } Task2 : PModel2; { Pointer to a task } begin if Rad1 .GetCheck <> 0 { User wants a task } then GetWindowText(Rad1 .HWindow, TextBuff, SizeOf(TextBuff)) else GetWindowText(Rad2 .HWindow, TextBuff, SizeOf(TextBuff)); A
A
A
Compare := StrComp(TextBuff,'Task 1'); { Which task ID is it? } If Compare = 0 then { 0 = a match } begin Taskl := New(PModel1, Init(@Self, 'TimeSeries Model')); Application".MakeWindow(Task1); Taskl .Iterate; { Iterate the task } end else { Run the other task } begin Task2 := New(PModel2, Init(@Self, 'Henon Attractor')); Application".MakeWindow(Task2); Task2".Iterate; { Iterate the task } end; end; A
L i s t i n g 8.4 s h o w s t h e c o m p l e t e TaskCont rol a p p l i c a t i o n , a n d f i g u r e 8.10 s h o w s a s c r e e n d i s p l a y g e n e r a t e d b y t h e c o d e i n listing 8.4.
271
272
Part I I — A d v a n c e d T o p i c s
Figure 8.10. Result of the TaskControl
Listing
8.4. The complete
application.
TaskControl
application.
program TaskButtons; uses WObjects, WinTypes, WinProcs, Strings, wif5, timel, attract2;
{ Basic Interface } { Task 1 } { Task 2 }
const id_Push1 =101; id_Rad1 =102; id_Rad2 = 103; id_Check1 = 1 0 4 ; id_Group1 = 105; type TestApplication = object(TApplication) procedure InitMainWindow; virtual;
8—Resources and Control Objects
end; PTaskControlWindow = "TaskControlWindow; TaskControlWindow = object(MainWindow) Rad1, Rad2: PRadioButton; Groupl: PGroupBox; constructor Init(AParent: PWindowsObject; ATitle: PChar); procedure HandleGroup1Msg(var Msg: TMessage); virtual id_First + id_Group1; end; {
TaskControlWindow methods
}
constructor TaskControlWindow.Init(AParent: PWindowsObject; ATitle: PChar); begin MainWindow.Init(AParent, ATitle); Groupl := New(PGroupBox, Init(@Self, id_Group1, 'Task Box', 58, 52, 176, 108)); Rad1 := New(PRadioButton, Init(@Self, id_Rad1, 'Task 1', 74, 64, 138, 24, Groupl)); Rad2 := New(PRadioButton, Init(@Self, id_Rad2, 'Task 2', 74, 84, 138, 24, Groupl)); end; procedure TaskControlWindow.HandleGroup1Msg(var Msg: TMessage); var TextBuff: array[0..20] of Char; { A button ID } Compare : integer; { Int to record comparison } Taskl : PModell; { Pointer to a task } Task2 : PModel2; { Pointer to a task } begin if Rad1".GetCheck <> 0 then GetWindowText(Rad1".HWindow, TextBuff, SizeOf(TextBuff)) else GetWindowText(Rad2".HWindow, TextBuff, SizeOf(TextBuff)); Compare := StrComp(TextBuff,'Task 1'); If Compare = 0 then begin Taskl := New(PModel1, Init(@Self, 'TimeSeries M o d e l ) ) ; Application".MakeWindow(Task1); Taskl".Iterate; { Iterate the task } 1
continues
273
274
Part I I — A d v a n c e d T o p i c s
Listing
8.4.
continued
end else begin Task2 := New(PModel2, Init(@Self, 'Henon Attractor')); Application".MakeWindow(Task2); Task2".Iterate; { Iterate the task } end; MessageBox(HWindow, TextBuff, 'You have selected:', MB_OK); end; {
TestApplication Methods
}
procedure TestApplication.InitMainWindow; begin MainWindow := New(PTaskControlWindow, Init(nil, 'Task Button Controller')); end; var TestApp : TestApplication; begin TestApp.Init('ButtTest'); TestApp.Run; TestApp.Done; end. U s i n g c o n t r o l s this w a y m i g h t s e e m s i m i l a r t o u s i n g a m e n u r e s o u r c e . It is, b u t c o n t r o l s a r e m o r e f l e x i b l e a n d m o r e p o w e r f u l t h a n m e n u s . R a t h e r t h a n a m e n u , the g r o u p can b e m a d e o f pushbuttons, radio buttons, check boxes, a n d s o o n . T h u s , y o u have interesting graphics possibilities, a n d s o m e controls, s u c h as a n EditControl, f o r e x a m p l e , that a l l o w y o u t o easily m a n i p u l a t e data fields.
Controls in Combination R e v i e w t h e HelpWindow f r o m listing 7.5 i n C h a p t e r 7, " M a n y W i n d o w s : A M u l t i D o c u m e n t I n t e r f a c e . " T h e HelpWindow c o n s i s t e d o f t w o c o n t r o l o b j e c t s : a list b o x a n d a n edit c o n t r o l , a c o n s t r u c t o r (to c o n s t r u c t t h e HelpWindow), a n d several m e t h o d s f o r h a n d l i n g t h e r e s u l t s f r o m t h e c o n t r o l o b j e c t s :
8—Resources and Control Objects
275
PHelpWindow = "HelpWindow; HelpWindow = object(TWindow) LB1: PListBox; EC1: PEdit; constructor Init(AParent: PWindowsObject; ATitle: PChar); procedure SetupWindow; virtual; procedure IDLB1(var Msg: TMessage); virtual id_First + id_LB1; procedure IDBN1(var Msg: TMessage); virtual id_First + id_BN1; procedure IDBN2(var Msg: TMessage); virtual id_First + id_BN2; procedure FillEdit(SelStringPtr: PChar); virtual; end; All the control o b j e c t s for HelpWindow are c o n s t r u c t e d w h e n HelpWindow is c o n s t r u c t e d , u s i n g the New p r o c e d u r e :
constructor HelpWindow.Init(AParent: PWindowsObject; ATitle: PChar); var TempStat : PStatic; TempBtn : PButton; begin TWindow.Init(AParent, ATitle); DisableAutoCreate; Attr.Style := ws_PopupWindow or ws_Caption or ws_Visible; Attr.X := 100; Attr.Y := 100; Attr.W := 300; Attr.H := 300; LB1 := New(PListBox, Init(@Self, id_LB1, 20, 20, 180, 80)); TempBtn := New(PButton, Init(@Self, id_BN1, 'Help', 220, 20, 60, 30, True)); TempBtn := New(PButton, Init(@Self, id_BN2, 'Cancel', 220, 70, 60, 30, False)); EC1 := New(PEdit, Init(@Self, id_EC1, '', 20, 180, 260, 90, 40, True)); EC1 .Attr.Style := EC1".Attr.Style or ws_Border or ws_VScroll; TempStat := New(PStatic, Init(@Self, id_ST1,'Help Information:', 20, 160, 160, 20, 0)); end; A
Y o u f i l l e d the list b o x b y overriding TWindow's SetupWindow (in HelpWindow): procedure HelpWindow.SetupWindow; begin TWindow.SetupWindow;
276
Part I I — A d v a n c e d T o p i c s
{ Fill the listbox } LB1 .AddString( List Boxes'); LB1 .AddString('Buttons '); LB1".AddString('Scroll Bars'); LB1".AddString('Edit Controls'); LB1".AddString('Static Controls'); LB1".AddString('Combo Boxes'); LB1".SetSellndex(O); { Set to beginning of list } end; A
1
A
Y o u then specified various actions based o n messages from buttons and lists. F o r e x a m p l e , l i s t - b o x m e s s a g e 1:
procedure HelpWindow.IDLB1(var Msg: TMessage); var SelString: array[0..25] of Char; begin if Msg.LParamHi = lbn_DblClk then begin LB1".GetSelString(SelString, 25); FillEdit(SelString); end; end; B u t t o n m e s s a g e 1:
procedure THelpWindow.IDBN1(var Msg: TMessage); var SelString: array[0..25] of Char; begin LB1".GetSelString(SelString, 25); FillEdit(SelString); end;
Bit Maps Y o u a l s o c a n u s e a r e s o u r c e e d i t o r t o c r e a t e a bit m a p that c a n , i n t u r n , b e u s e d f o r v a r i o u s p u r p o s e s : f o r e x a m p l e , as a b r u s h f o r filling f i g u r e s , s u c h as rectangles, ellipses, a n d so o n . C r e a t i n g a bit m a p w i t h t h e W h i t e w a t e r R e s o u r c e T o o l k i t is straightf o r w a r d . Y o u u s e t h e B i t m a p e d i t o r a n d select t o o l s t o c r e a t e t h e s p e c i f i c a s p e c t s o f t h e bit m a p . Y o u t h e n save t h e bit m a p as a . B M P file, w h i c h y o u c a n l o a d i n t o
8—Resources and Control Objects
y o u r a p p l i c a t i o n s later. F i g u r e s 8 . 1 1 , 8 . 1 2 , a n d 8 . 1 3 s h o w v a r i o u s a s p e c t s o f a bit m a p b e i n g c r e a t e d w i t h t h e W h i t e w a t e r R e s o u r c e G r o u p ' s B i t m a p e d i t o r p a c k a g e d w i t h T u r b o Pascal f o r W i n d o w s .
Figure
8.11. One aspect of a bit map created with the Whitewater Resource Bitmap editor.
Figure
8.12. Another aspect of a bit map.
Group's
277
278
Part I I — A d v a n c e d T o p i c s
Figure
8.13. A third aspect of a bit map created with the WRG's Bitmap
editor.
Wrap-up R e s o u r c e s a n d c o n t r o l o b j e c t s a r e , i n effect, t h e i n t e r f a c e c o m p o n e n t s o f y o u r W i n d o w s a p p l i c a t i o n s . T h e y g i v e y o u r a p p l i c a t i o n t h e l o o k a n d f e e l that m a k e it a familiar, illustrative, easy-to-use G U I ( g r a p h i c a l u s e r i n t e r f a c e ) . M o s t T u r b o Pascal f o r W i n d o w s a p p l i c a t i o n s y o u w r i t e w a n t t o u t i l i z e t h e s e i n t e r f a c e c o m p o n e n t s . W h e n e v e r p o s s i b l e , let y o u r u s e r interact w i t h y o u r a p p l i c a t i o n t h r o u g h c o n t r o l s a n d r e s o u r c e s . It is e a s i e r f o r h e r a n d e a s i e r f o r y o u if y o u d e v e l o p a p p l i c a t i o n s this w a y . R e s o u r c e e d i t o r s m a k e it a s n a p f o r y o u t o interactively d e s i g n a n d m o d i f y r e s o u r c e s , a n d c o n t r o l o b j e c t s are a l m o s t p l u g - i n s , t h a n k s t o O b j e c t W i n d o w s .
9
CHAPTER
MEMORY MATTERS I have a good memory, though is a tendency to over-remember
"good" is somewhat questionable, since life rather than to look for new life to be J i m Harrison
there lived.
W i n d o w s is a c o m p l e x m u l t i t a s k i n g e n v i r o n m e n t , w i t h c o m p a r a b l y c o m p l e x m e m o r y - m a n a g e m e n t capability. B e c a u s e W i n d o w s a l l o w s a p p l i c a t i o n s t o s h a r e m e m o r y , m o r e a p p l i c a t i o n s c a n r u n effectively at t h e s a m e t i m e . F o r e x a m p l e , if y o u r u n m u l t i p l e i n s t a n c e s o f a n a p p l i c a t i o n , W i n d o w s u s e s t h e same c o d e segments a n d resources for each instance. This multi-utilization o f r e s o u r c e s ( i c o n s , m e n u s , d i a l o g s , c u r s o r s , a n d s o o n ) is a n i m p o r t a n t a d v a n t a g e in separating resources from source c o d e . In addition, W i n d o w s can " m o v e " m e m o r y y o u allocate for your a p p l i c a t i o n ' s c o d e a n d d a t a s e g m e n t s a n d r e s o u r c e s , if y o u specify t h e m e m o r y as " m o v e a b l e . " W i n d o w s m o v e s m e m o r y t o c r e a t e l a r g e r c o n t i g u o u s m e m o r y b l o c k s . C o d e s e g m e n t s a n d r e s o u r c e s a l s o c a n b e d i s c a r d e d t o free m e m o r y (if y o u d e s i g n a t e t h e s e s e g m e n t s a n d r e s o u r c e s as " d i s c a r d a b l e " ) . O n e k e y result o f W i n d o w s ' m e m o r y m a n a g e m e n t is that l a r g e a p p l i c a t i o n s c a n r u n s i m u l t a neously in a m e m o r y space m u c h smaller than w o u l d b e required without W i n d o w s . A s a n a p p l i c a t i o n d e v e l o p e r , y o u w a n t t o t a k e as m u c h a d v a n t a g e o f t h e W i n d o w s m a n a g e m e n t s y s t e m as y o u c a n . A l t h o u g h m e m o r y m a n a g e m e n t s o u n d s d a u n t i n g , it is n o t . If y o u u s e t h e h o o k s p r o v i d e d b y T u r b o P a s c a l f o r W i n d o w s , y o u c a n t a p i n t o this c o m p l e x m e m o r y - m a n a g e m e n t s y s t e m . Essentially, y o u u s e a f e w b u i l t - i n p r o c e d u r e s s u c h as New, Dispose, GetMem, FreeMem, a n d MemAlloc t o a l l o c a t e d y n a m i c
280
Part I I — A d v a n c e d T o p i c s
v a r i a b l e s , a n d t h e T u r b o Pascal f o r W i n d o w s c o m p i l e r e n s u r e s that e n o u g h m e m o r y is i n t h e W i n d o w s g l o b a l h e a p t o a l l o c a t e t h e v a r i a b l e s . ( M o r e o n this in the next section). T h e w a y y o u w r i t e a p p l i c a t i o n s is n o t a f f e c t e d m u c h b y t h e s p e c i f i c W i n d o w s m o d e y o u are u s i n g , b u t y o u s h o u l d at least b e a w a r e o f t h e m o d e s a v a i l a b l e . T h e t h r e e m o d e s (real, s t a n d a r d , a n d e n h a n c e d ) are d e p e n d e n t o n the a m o u n t of m e m o r y the system r u n n i n g W i n d o w s has. W i n d o w s r u n s o n l y i n real m o d e o n s y s t e m s h a v i n g less t h a n 1 M ( m e g a b y t e ) o f R A M . I n this m o d e , W i n d o w s r u n s i n m e m o r y b e t w e e n 6 4 0 K (kilobytes) a n d 1 M . T h i s is, o f c o u r s e , t h e m o s t l i m i t i n g m o d e p r i m a r i l y b e c a u s e W i n d o w s h a s less m e m o r y t o u s e f o r s w a p p i n g c o d e s e g m e n t s , a n d s o o n . W i n d o w s c a n u s e E M S ( L o t u s - I n t e l - M i c r o s o f t E x p a n d e d M e m o r y S p e c i f i c a t i o n ) 4 . 0 i n real m o d e . E M S specifies a standard s c h e m e for accessing a n d using m e m o r y above 6 4 0 K . B e c a u s e this " e x t r a m e m o r y " w a s n o t a c c o u n t e d f o r i n early v e r s i o n s o f D O S , a p p l i c a t i o n s d e a l t w i t h this m e m o r y i n a n y w a y t h e y s a w fit, u n t i l this s p e c i f i c a t i o n w a s i n t r o d u c e d . W i n d o w s r e q u i r e s that a p p l i c a t i o n s u s e m e m o r y i n a similar, s t a n d a r d i z e d w a y s o that t h e y c a n b e s w a p p e d , f o r e x a m p l e , a n d are generally compatible. W i n d o w s c a n r u n in either real or standard m o d e in systems with b e t w e e n 1 M a n d 2 M o f m e m o r y . I n s t a n d a r d m o d e , W i n d o w s c a n a c c e s s as m u c h as 1 6 M o f m e m o r y . Finally, W i n d o w s c a n r u n i n 386 e n h a n c e d m o d e o n systems w i t h at least 2 M o f m e m o r y . 3 8 6 e n h a n c e d m o d e is s t a n d a r d m o d e p l u s t h e ability t o i m p l e m e n t virtual m e m o r y , w h i c h , i n effect, m e a n s that W i n d o w s c a n s w a p " p a g e s " t o d i s k i n o r d e r t o free a d d i t i o n a l m e m o r y . P a g e s w a p p i n g is s o m e thing y o u normally d o not have to worry about w h e n y o u develop W i n d o w s applications. I n g e n e r a l , W i n d o w s f i g u r e s o u t t h e b e s t m o d e f o r a s y s t e m w h e n it starts. A l l t h e e x a m p l e s i n this b o o k w e r e c o m p i l e d a n d r u n u n d e r W i n d o w s i n b o t h s t a n d a r d a n d 3 8 6 e n h a n c e d m o d e s ( T u r b o Pascal f o r W i n d o w s r e q u i r e s o n e o f t h e s e m o d e s ; it d o e s n o t r u n i n real m o d e ) .
Memory Management, Windows Style T y p i c a l l y , w h e n y o u w r i t e a p p l i c a t i o n s f o r D O S (but n o t W i n d o w s ) , m e m o r y is a l l o c a t e d at f i x e d (specific) l o c a t i o n s . If y o u are u s i n g T u r b o P a s c a l (for D O S ) m e m o r y - a l l o c a t i o n a n d d e a l l o c a t i o n p r o c e d u r e s , this is h a n d l e d a u t o m a t i c a l l y f o r y o u . Y o u just u s e New, Dispose, a n d s o o n , a n d T u r b o Pascal's m e m o r y m a n a g e m e n t system ensures e n o u g h m e m o r y to allocate space for a variable. W i n d o w s , h o w e v e r , t a k e s a m o r e flexible a p p r o a c h t o m e m o r y a l l o c a t i o n . M e m o r y blocks can be fixed, but also m o v e d and discarded. By not forcing b l o c k s o f m e m o r y t o b e f i x e d , W i n d o w s c a n significantly i m p r o v e m e m o r y u s e . F o r e x a m p l e , m e m o r y that is " m o v e a b l e " c a n b e " c o m p a c t e d " t o c r e a t e a l a r g e r b l o c k o f free m e m o r y f r o m s m a l l e r b l o c k s o f free m e m o r y , as illustrated i n figure 9.1.
9 — M e m o r y Matters
M e m o r y c a n be c o m p a c t e d
Block 1
Free
Free
Free
Block 2
Block 1
Free
Block 2
before
Figure
after
9.1. Creating a larger block of free memory from smaller blocks of free memory.
Another way W i n d o w s improves m e m o r y use is compaction through "discardable" m e m o r y blocks (see figure 92).
Memory can be discarded
Block 1
Free
Free
Free
Block 2
free
Free
Block 2
before
Figure
after
9.2. Compacting through "discardable" memory blocks.
281
282
Part I I — A d v a n c e d T o p i c s
H o w d o e s y o u r T u r b o Pascal f o r Windows a p p l i c a t i o n k n o w w h a t is g o i n g o n w i t h m e m o r y ? Easy. M o s t o f t h e t i m e , it d o e s n o t e v e n b o t h e r itself w i t h t h e p h y s i c a l l o c a t i o n o f a m e m o r y b l o c k . It a c c e s s e s m e m o r y t h r o u g h a handle t o t h e m e m o r y b l o c k . I n o t h e r w o r d s , rather t h a n g e t a p o i n t e r t o a m e m o r y b l o c k (a typical n o n - W i n d o w s a p p r o a c h ) , t h e a p p l i c a t i o n g e t s a handle (a n a m e ) that represents a p o i n t e r t o a p o i n t e r t o t h e m e m o r y b l o c k (see figure 9 3 ) .
Handles -> Pointers -> Memory
Handle
Figure
Pointer
Memory block
93. A handle to access a memory block.
T o access m e m o r y m a n a g e d by W i n d o w s , y o u r application only has to d e t e r m i n e w h e r e a c h u n k o f m e m o r y is "right n o w . " I n o t h e r w o r d s , y o u m u s t still o b t a i n t h e a d d r e s s o f t h e b l o c k , b u t f o r t h e t i m e o n l y i n w h i c h y o u are u s i n g it. W h e n y o u are d o n e w i t h a b l o c k , y o u g i v e u p t h e h a n d l e t o it, f r e e i n g it s o that W i n d o w s c a n m o v e it if it n e e d s t o . T h e n , w h e n n e x t y o u n e e d t o a c c e s s t h e b l o c k o f m e m o r y , y o u ask W i n d o w s a g a i n w h e r e it is b y g e t t i n g its c u r r e n t address. F o r e x a m p l e , if G H a n d l e is a h a n d l e t o a b l o c k o f g l o b a l l y a l l o c a t e d m e m o r y , y o u g e t its a d d r e s s b y l o c k i n g t h e h a n d l e a n d a s s i g n i n g t h e r e s u l t i n g address to a pointer: var GHandle : THandle; PtrGData: { A pointer
}
begin GHandle
:= G l o b a l A l l o c ( g m e m _ M o v e a b l e ,
50000);
{ Memory t y p e a n d s i z e
}
9 — M e m o r y Matters
PtrGData:= {
GlobalLock(GHandle); }
end; I n this f r a g m e n t , P t r G D a t a " g e t s " t h e a d d r e s s o f t h e m e m o r y b l o c k . B y l o c k i n g t h e b l o c k , y o u t e m p o r a r i l y "fix" t h e b l o c k at s o m e s p e c i f i c l o c a t i o n s o that W i n d o w s c a n n o t m o v e o r d i s c a r d it u n t i l y o u " u n l o c k " t h e block using o n e of the U n l o c k procedures: GlobalUnlock(GHandle); o r , if L H a n d l e is a h a n d l e t o a l o c a l l y a l l o c a t e d m e m o r y b l o c k : LocalUnlock(LHandle); W h e n the block has b e e n u n l o c k e d , the pointer to the m e m o r y b l o c k (you just o b t a i n e d ) is n o l o n g e r v a l i d b e c a u s e W i n d o w s c a n a g a i n m o v e o r d i s c a r d t h e m e m o r y . If y o u h a v e t o k n o w w h e r e a b l o c k o f m e m o r y is t h r o u g h o u t t h e life o f t h e a p p l i c a t i o n , a l l o c a t e it as a fixed b l o c k : GHandle
:=
GlobalAlloc(gmem_fixed,10000);
T h i s s t e p " f i x e s " t h e b l o c k , p r e v e n t i n g W i n d o w s f r o m m o v i n g it a b o u t . I n g e n e r a l , t h o u g h , y o u d o n o t w a n t t o fix m e m o r y b l o c k s ; i n s t e a d y o u a l l o c a t e t h e m as m o v e a b l e : GHandle
:=
GlobalAlloc(gmem_Moveable,2000);
o r as m o v a b l e a n d d i s c a r d a b l e : GHandle
:= GlobalAlloc(gmem_Moveable or
gmem_Discardable);
T h i s l i n e m e a n s that W i n d o w s c a n " d i s c a r d " m e m o r y a n d " r e l o a d " it w h e n it is n e e d e d a g a i n as w e l l as m o v e i t — t h u s f r e e i n g u p e v e n m o r e m e m o r y w h e n necessary. Y o u n o d o u b t have noticed the prefix g l o b a l in most of the previous short examples. D e c i d i n g whether to allocate a n d use local or global m e m o r y blocks is a n i m p o r t a n t i s s u e , d i s c u s s e d in s o m e d e t a i l i n t h e n e x t s e c t i o n .
Global and Local Memory Y o u r a p p l i c a t i o n s c a n a l l o c a t e m e m o r y b l o c k s in e i t h e r o f t w o areas: t h e g l o b a l or the local heap. T h e g l o b a l h e a p is all t h e m e m o r y that W i n d o w s " c l a i m s " w h e n y o u r u n it. T h e g l o b a l h e a p is s h a r e d b y W i n d o w s , W i n d o w s a p p l i c a t i o n s , a n d t h e " g l o b a l " m e m o r y b l o c k s a l l o c a t e d b y W i n d o w s a p p l i c a t i o n s (like y o u r s ) . G l o b a l m e m o r y is fantastically p o w e r f u l b e c a u s e it is s y s t e m - s i z e d ; it c o n t a i n s m e m o r y w i t h i n a n d b e y o n d y o u r a p p l i c a t i o n s . A g l o b a l m e m o r y b l o c k c a n b e as l a r g e as 1 M i n W i n d o w s s t a n d a r d m o d e a n d 6 4 M i n 3 8 6 e n h a n c e d m o d e . A g l o b a l m e m o r y block can b e u s e d to access the data in other programs.
283
284
Part I I — A d v a n c e d T o p i c s
T h e l o c a l h e a p is m e m o r y that is a c c e s s i b l e o n l y b y a s p e c i f i c i n s t a n c e o f y o u r a p p l i c a t i o n . I n o t h e r w o r d s , it is " p r i v a t e " t o y o u r a p p l i c a t i o n a n d just like t h e h e a p y o u w e r e u s e d t o i n T u r b o Pascal ( b e f o r e W i n d o w s ) . T h e l o c a l h e a p is l i m i t e d t o w h a t e v e r is left o f t h e 6 4 K d a t a s e g m e n t after y o u r a p p l i c a t i o n h a s u s e d s o m e f o r a stack a n d its o w n g l o b a l v a r i a b l e s . T h e l o c a l h e a p is o n l y 8 K b y d e f a u l t , b u t y o u c a n a d j u s t its size u s i n g e i t h e r t h e $M c o m p i l e r d i r e c t i v e o r t h e T u r b o Pascal f o r W i n d o w ' s I D E o p t i o n / C o m p i l e r / M e m o r y S i z e m e n u s . I n a d d i t i o n , t h e m a x i m u m size o f t h e l o c a l h e a p c a n d e p e n d o n w h e t h e r y o u r a p p l i c a t i o n ' s d a t a s e g m e n t is f i x e d o r m o v a b l e . If it is f i x e d , t h e l o c a l h e a p is r e s t r i c t e d t o t h e size y o u a l l o c a t e d u s i n g t h e $M c o m p i l e r d i r e c t i v e (or t h e I D E ) at c o m p i l e t i m e . I f t h e d a t a s e g m e n t is m o v e a b l e , y o u r a p p l i c a t i o n c a n r e q u e s t a l a r g e r size t h a n t h e o n e y o u s p e c i f i e d at c o m p i l e t i m e . S o u n d s c o n v e n i e n t , b u t t h e r e is a p o s s i b l e s i d e effect: W i n d o w s m i g h t g e t a bit o f e x t r a m e m o r y f o r y o u r application b y m o v i n g the data s e g m e n t , w h i c h in turn probably invalidates any far ( o r l o n g ) p o i n t e r s t o l o c a l d a t a . W h e t h e r y o u u s e local o r global m e m o r y d e p e n d s primarily o n t w o factors: 1. H o w b i g a b l o c k y o u n e e d 2. W h e t h e r t h e b l o c k is u s e d f o r a l o c a l o r g l o b a l task If y o u n e e d o n l y a little bit o f m e m o r y ( I K o r l e s s ) , t h e n y o u p r o b a b l y w a n t t o u s e l o c a l m e m o r y b e c a u s e it is faster a n d d o e s n o t r e q u i r e t h e 2 0 b y t e s o f W i n d o w s overhead required to allocate a global m e m o r y block. G l o b a l m e m o r y is y o u r c h o i c e if y o u n e e d a b i g g e r b l o c k o r t o c o n n e c t t o s y s t e m - w i d e r e s o u r c e s , s u c h as a n o t h e r a p p l i c a t i o n ' s d a t a o r t h e C l i p b o a r d — m o r e o n this i n C h a p t e r 1 1 , " F r o m P r o g r a m t o P r o g r a m U s i n g D D E ( D y n a m i c D a t a E x c h a n g e ) . " G l o b a l m e m o r y is s o m e w h a t s l o w e r b e c a u s e it is a c c e s s e d t h r o u g h W i n d o w s g l o b a l m e m o r y h a n d l e s , b u t it c a n b e far larger.
Allocating Local Memory Blocks A l l o c a t i n g l o c a l a n d g l o b a l m e m o r y b l o c k s is similar. T h e f o l l o w i n g s e g m e n t shows h o w to allocate a moveable, local m e m o r y block o f 256K:
var ALocalHandle : THandle; begin ALocalHandle := LocalAlloc(lmem_Moveable,256); { } end; A l l o c a t e t h e l o c a l m e m o r y as e i t h e r fixed, m o v e a b l e , o r m o v e a b l e a n d d i s c a r d a b l e , u s i n g t h e W i n d o w s A P I f u n c t i o n , LocalAlloc.
9 — M e m o r y Matters
LocalAlloc r e t u r n s a m e m o r y b l o c k i d e n t i f i e r (a n u m b e r ) if it is s u c c e s s f u l a n d z e r o if it is n o t s u c c e s s f u l . T h i s i d e n t i f i e r is t h e h a n d l e t o t h e m e m o r y block. ALocalHandle is a THandle, a l r e a d y d e c l a r e d i n O b j e c t W i n d o w s , w h i c h c a n b e a c c e s s e d b y o t h e r f u n c t i o n s n e e d i n g t o find t h e h a n d l e . After y o u h a v e a s k e d t o a l l o c a t e t h e m e m o r y b l o c k , c h e c k t o s e e w h e t h e r the m e m o r y allocation has b e e n successful. If t h e allocation w a s successful, LocalAlloc r e t u r n s t h e h a n d l e t o t h e m e m o r y b l o c k . If u n s u c c e s s f u l , it r e t u r n s a zero: if ALocalHandle
<> 0 then
{..-.} If t h e a l l o c a t i o n h a s n o t b e e n s u c c e s s f u l , b a i l o u t . I f t h e a l l o c a t i o n w a s s u c c e s s f u l , l o c k t h e m e m o r y b l o c k a n d g e t its a d d r e s s : var APtrLocalData:
{ Pointer }
begin APtrLocalData {
:= LocalLock(ALocalHandle);
}
end; If t h e l o c k is s u c c e s s f u l , LocalLock r e t u r n s a p o i n t e r t o t h e b l o c k ( a n a d d r e s s ) . I f n o t , it r e t u r n s n i l . C h e c k f o r s u c c e s s b e f o r e m o v i n g o n : if APtrLocalData <> nil then {
}
If s u c c e s s f u l , p r o c e s s t h e d a t a . W h e n y o u a r e f i n i s h e d w i t h t h e b l o c k , u s e t h e W i n d o w s A P I f u n c t i o n LocalUnlock t o u n l o c k it, a n d e i t h e r free o r d i s c a r d it s o that W i n d o w s c a n r e c o v e r t h e m e m o r y if n e c e s s a r y . F r e e t h e m e m o r y b y freeing the handle: LocalUnlock(ALocalHandle); LocalFree(ALocalHandle): or discard: LocalUnlock(ALocalHandle); LocalDiscard(ALocalHandle); Y o u m u s t U n l o c k t h e b l o c k ( w h i c h sets t h e L o c k C o u n t t o z e r o ) b e f o r e y o u free o r d i s c a r d it. O t h e r w i s e , t h e free o r d i s c a r d o p e r a t i o n fails b e c a u s e it a u t o m a t i c a l l y c h e c k s t h e L o c k c o u n t t o s e e w h e t h e r it is z e r o . Z e r o i n d i c a t e s that the block c a n b e freed or discarded. F r e e i n g a m e m o r y b l o c k r e m o v e s its c o n t e n t s a n d i n v a l i d a t e s t h e h a n d l e to the m e m o r y block by r e m o v i n g the h a n d l e from a table of valid local m e m o r y handles.
285
286
Part I I — A d v a n c e d T o p i c s
D i s c a r d i n g a m e m o r y b l o c k r e a l l o c a t e s its size t o z e r o , b u t d o e s n o t remove the handle from the local m e m o r y handles table. Y o u c a n reuse the h a n d l e , u s i n g t h e LocalRealloc p r o c e d u r e , a n d r e a l l o c a t e a n e w m e m o r y b l o c k o f a different size: var ALocalHandle: THandle; begin { .... Previous allocation and use of block } LocalDiscard(ALocalHandle}; ALocalHandle := LocalReAlloc(ALocalHandle,512,lmem_Moveable); {.... more processing } end; Y o u m i g h t w a n t t o r e u s e a m e m o r y b l o c k t o save t h e u n l o c k i n g - a n d new-handle allocation steps. Y o u a l s o c a n f i n d o u t h o w l a r g e a l o c a l b l o c k is b y u s i n g LocalSize: var ALocalHandle
: THandle;
MemoryBlockSize: Word; begin ALocalHandle := LocalAlloc(lmem_Moveable,512); if ALocalHandle <> 0 then MemoryBlockSize := LocalSize(ALocalHandle); end; N o t i c e a g a i n that y o u a l l o c a t e a n d a c c e s s t h e m e m o r y b l o c k i n d i r e c t l y t h r o u g h a h a n d l e t o t h e m e m o r y block, n o t directly t h r o u g h a pointer. B e c a u s e y o u a r e a c c e s s i n g m e m o r y i n d i r e c t l y (by h a n d l e ) , W i n d o w s c a n safely m o v e m e m o r y blocks a r o u n d a n d inform y o u w h e r e they are only w h e n y o u n e e d to k n o w . M o s t o f t h e t i m e y o u d o n o t k n o w w h e r e a m e m o r y b l o c k is, a n d that is just fine. T h a n k y o u , W i n d o w s . O n e w a y y o u c a n u s e a l o c a l m e m o r y b l o c k is s i m p l y t o s t o r e a text b u f f e r o n t h e l o c a l h e a p . F o r e x a m p l e , y o u m i g h t w a n t t o s t o r e a l a r g e string f o r u s e b y a s i n g l e m o d u l e , as t h e c o d e i n listing 9.1 illustrates. N o t e that a MessageBox is u s e d t o d i s p l a y t h e status a n d r e s u l t s o f t h e l o c a l m e m o r y a l l o c a t i o n , w h i c h o c c u r s b e f o r e t h e MainWindow is d i s p l a y e d . A l s o n o t e that it is n e c e s s a r y t o c o n v e r t t h e d i s p l a y e d c h a r a c t e r i n t o a string b e f o r e u s i n g MessageBox t o d i s p l a y it. R e m e m b e r : W i n d o w s f u n c t i o n s , s u c h as MessageBox, that d i s p l a y strings r e q u i r e n u l l - t e r m i n a t e d s t r i n g s . F i g u r e 9.4 s h o w s a m e s s a g e b o x i n d i c a t i n g that t h e l o c a l m e m o r y a l l o c a t i o n h a s n o t o c c u r r e d yet. F i g u r e 95 s h o w s t h e MessageBox d i s p l a y i n g t h e first c h a r a c t e r i n t h e l o c a l l y a l l o c a t e d array o f c h a r a c t e r s , after t h e a l l o c a t i o n . F i g u r e 9.6 s h o w s t h e MainWindow d i s p l a y e d after t h e a l l o c a t i o n .
9 — M e m o r y Matters 2 8 7
Figure
9.4.
A message box showing that the local memory allocation occurred.
Figure
9.5. A message box displaying the first character of characters (after allocation).
has not yet
in the locally allocated
array
288
Part I I — A d v a n c e d T o p i c s
Figure 9.6. The MainWindow
Listing
9*1. Storing
a text buffer
displayed after
on the local
allocation.
heap.
program localjnem; uses WObjects, WinTypes, WinProcs, StdDlgs, Strings, WIF5;
{ Basic Interface }
type PLocalArray = "TLocalArray; TLocalArray = array[0..1000] of char; LocalApplication = object(TApplication) { Derive an application object } FirstApplication : boolean; procedure InitMainWindow; virtual; { Init a main window } procedure InitApplication; virtual; end; PLocalWindow = "LocalWindow;
9 — M e m o r y Matters
289
LocalWindow = object(MainWindow) LocalHandle: THandle; PtrLocalData: PBigArray; Value: Char; S : array[0..9] of char; constructor Init(AParent : PWirfdowsObject; ATitle : PChar); procedure AllocateBlock; end;
{ LocalApplication method implementation } procedure LocalApplication.InitMainWindow; begin if FirstApplication then MainWindow := New(PLocalWindow, Init(nil, Local Windows Interface')) else MainWindow := New(PLocalWindow, Init(nil,'Additional Instance of BI')); end; 1
procedure LocalApplication.InitApplication; begin FirstApplication := True; end; constructor LocalWindow.Init(AParent : PWindowsObject; ATitle : PChar); begin MainWindow.Init(AParent, ATitle); { Send message to ancestor's constructor Attr.Menu := LoadMenu(HInstance, PChar(100)); { 100 = menu ID } ButtonDown := False; { Set status flag } MessageBox(HWindow,' Here before Local call', 'Local Status 1', mb_0k); AllocateBlock; { Allocate the block } end; procedure LocalWindow.AllocateBlock; begin LocalHandle := LocalAlloc(gmem_Moveable,1000); if LocalHandle <> 0 then begin PtrLocalData := LocalLock(LocalHandle); if PtrLocalData <> nil then begin continues
290
Part II—Advanced Topics
Listing
9.1.
continued
PtrLocalData"[0] := 'L'; Value := PtrLocalData"[0]; { Value = char } S[0] := Value; { Convert to a string for viewing } MessageBox(HWindow,S, 'AllocateBlock , mb_0k); LocalUnlock(LocalHandle); 1
end else MessageBox(HWindow,
1
Local Fail', 'LF', mb_0k);
end else end; var Applicationl: LocalApplication;
{ An instance of BasicApplication } { Run Applicationl }
begin Applicationl.Init( Local Interface'); { Init application instance } Applicationl.Run; { Message loop } Applicationl.Done; { Destroy application instance } end. 1
Global Memory Blocks Working with global m e m o r y blocks is similar. The following segment shows h o w to allocate a moveable, global m e m o r y block of 256K: var AGlobalHandle : THandle; begin AGlobalHandle := GlobalAlloc(gmem_Moveable,1024); { } end; Allocate the global m e m o r y as either fixed, moveable, or moveable or discardable, using the W i n d o w s API function GlobalAlloc. GlobalAlloc returns a m e m o r y block identifier (a number) if it is successful and zero if not successful. This identifier is the handle to the m e m o r y block:
9 — M e m o r y Matters
A G l o b a l H a n d l e i s a T H a n d l e , already declared in O b j e c t W i n d o w s , w h i c h c a n b e a c c e s s e d b y o t h e r f u n c t i o n s n e e d i n g t o find t h e h a n d l e . After y o u h a v e a s k e d that t h e m e m o r y b l o c k b e a l l o c a t e d , c h e c k t o s e e w h e t h e r t h e m e m o r y a l l o c a t i o n h a s b e e n s u c c e s s f u l . If t h e a l l o c a t i o n w a s s u c c e s s f u l , G l o b a l A l l o c r e t u r n s t h e h a n d l e t o t h e m e m o r y b l o c k . If u n s u c c e s s f u l , it r e t u r n s a z e r o : if
AGlobalHandle
<> 0 t h e n
{••••} If t h e a l l o c a t i o n h a s n o t b e e n s u c c e s s f u l , b a i l o u t . If t h e a l l o c a t i o n w a s s u c c e s s f u l , l o c k t h e m e m o r y b l o c k a n d g e t its a d d r e s s : var APtrGlobalData: { Pointer } begin APtrGlobalData {
:=
GlobalLock(AGlobalHandle);
}
end; If t h e l o c k is s u c c e s s f u l , G l o b a l L o c k , like L o c a l L o c k , r e t u r n s a p o i n t e r t o t h e b l o c k (an a d d r e s s ) . If n o t , it r e t u r n s n i l . C h e c k f o r s u c c e s s b e f o r e moving on: if
APtrGlobalData {
<> n i l
then
}
If s u c c e s s f u l , p r o c e s s t h e d a t a . W h e n y o u are finished w i t h t h e b l o c k , u s e t h e W i n d o w s A P I f u n c t i o n G l o b a l U n l o c k t o u n l o c k it, a n d e i t h e r free o r d i s c a r d it s o that W i n d o w s c a n r e c o v e r t h e m e m o r y if n e c e s s a r y . F r e e t h e m e m o r y b y freeing the handle: GlobalUnlock(AGlobalHandle); GlobalFree(AGlobalHandle): or discard: GlobalUnlock(AGlobalHandle); GlobalDiscard(AGlobalHandle); A g a i n , as w i t h l o c a l m e m o r y a l l o c a t i o n , y o u m u s t u n l o c k t h e b l o c k (setting t h e L o c k C o u n t t o z e r o ) b e f o r e y o u free o r d i s c a r d it. O t h e r w i s e t h e free o r d i s c a r d o p e r a t i o n fails b e c a u s e it a u t o m a t i c a l l y c h e c k s t h e L o c k c o u n t t o s e e w h e t h e r it is z e r o . F r e e i n g a m e m o r y b l o c k r e m o v e s its c o n t e n t s a n d i n v a l i d a t e s t h e h a n d l e to the m e m o r y b l o c k by removing the h a n d l e from a table of valid global memory handles.
291
292
Part I I — A d v a n c e d T o p i c s
D i s c a r d i n g a g l o b a l m e m o r y b l o c k r e a l l o c a t e s its size t o z e r o , b u t d o e s n o t remove the handle from the global m e m o r y handles table. Y o u c a n reuse the h a n d l e , u s i n g t h e GlobalRealloc p r o c e d u r e , a n d r e a l l o c a t e a n e w m e m o r y b l o c k o f a different size:
var AGlobalHandle: THandle; begin { .... Previous allocation and use of block } GlobalDiscard(AGlobalHandle}; AGlobalHandle := GlobalReAlloc(AGlobalHandle,512,gmem_Moveable); {.... more processing } end; Y o u a l s o c a n d e t e r m i n e h o w l a r g e a g l o b a l b l o c k is b y u s i n g GlobalSize:
var AGlobalHandle : THandle; MemoryBlockSize: Word; begin AGlobalHandle := GlobalAlloc(gmem_Moveable,1024); if AGlobalHandle <> 0 then MemoryBlockSize := GlobalSize(AGlobalHandle); end; W h e n e v e r y o u n e e d t o u s e a large block, u s e g l o b a l m e m o r y . Listing 9 2 s h o w s y o u h o w t o c r e a t e a l a r g e g l o b a l b u f f e r . F i g u r e 9 7 s h o w s a MessageBox d i s p l a y e d b e f o r e t h e g l o b a l a l l o c a t i o n . F i g u r e 9 8 s h o w s t h e v a l u e o f t h e first s i x c h a r a c t e r s o f t h e g l o b a l array. F i g u r e 9 9 s h o w s t h e MainWindow (GlobalWindow) d i s p l a y e d after t h e g l o b a l a l l o c a t i o n . If t h e g l o b a l a l l o c a t i o n d o e s n o t s u c c e e d , a MessageBox i n d i c a t e s t h e global failure. T h e user must a c k n o w l e d g e the failure, a n d t h e n processing continues.
9 — M e m o r y Matters
Figure
9.7. A message box showing that the global allocation
Figure
9.8. A message box displaying the first six characters array after global allocation.
has not
occurred.
in the globally
allocated
293
294
Part I I — A d v a n c e d T o p i c s
Figure
Listing
9-2.
93.
The MainWindow
Creating
(GlobalWindow)
a large global
after the global
allocation.
buffer.
program glob_mem; uses WObjects, WinTypes, WinProcs, StdDlgs, Strings, WIF5; { Basic Interface } type PGlobalArray = "TGlobalArray; TGlobalArray = array[0..1024] of char; GlobalApplication = object(TApplication) { Derive an application object } FirstApplication : boolean; procedure InitMainWindow; virtual; { Init a main window } procedure InitApplication; virtual; end; PGlobalWindow = "GlobalWindow;
9 — M e m o r y Matters
295
GlobalWindow = object(MainWindow) GlobalHandle: THandle; PtrGlobalData: PGlobalArray; Value: Char; S : array[0..9] of char; constructor Init(AParent : PWindowsObject; ATitle : PChar); procedure AllocateBlock; end;
{ BasicApplication method implementation } procedure GlobalApplication.InitMainWindow; begin if FirstApplication then MainWindow := New(PGlobalWindow, Init(nil, 'Global Windows Interface')) else MainWindow := New(PGlobalWindow, Init(nil,'Additional Instance of GI')); end;
procedure GlobalApplication.InitApplication; begin FirstApplication := True; end; constructor GlobalWindow.Init(AParent : PWindowsObject; ATitle : PChar); begin MainWindow.Init(AParent, ATitle); { Send message to ancestor's constructor } Attr.Menu := LoadMenu(HInstance, PChar(100)); { 100 = menu ID } ButtonDown := False; { Set status flag } MessageBox(HWindow, Here before Global call', 'GF', mb_Ok); AllocateBlock; end; 1
procedure GlobalWindow.AllocateBlock; var I : integer; begin GlobalHandle := GlobalAlloc(gmem_Moveable,1024); if GlobalHandle <> 0 then continues
296
Part I I — A d v a n c e d T o p i c s
Listing
9.2.
continued
begin PtrGlobalData := GlobalLock(GlobalHandle); if PtrGlobalData <> nil then begin PtrGlobalData"[0] := 'G'; PtrGlobalData"[1] := 'L'; PtrGlobalData"[2] := '0'; PtrGlobalData"[3] := 'B'; PtrGlobalData"[4] := 'A'; PtrGlobalData"[5] := 'L'; For I := 0 to 5 do begin Value := PtrGlobalData"[I]; S[I] := Value; end; MessageBox(HWindow,S, AllocateBlock , mb_0k); GlobalUnlock(GlobalHandle); 1
1
end else MessageBox(HWindow,
1
Global Fail', ' G F , mb_0k); 1
end else end;
var Applicationl: GlobalApplication; { An instance of BasicApplication } { Run Applicationl } begin Applicationl.Init('Global Interface'); { Init application instance } Applicationl.Run; { Message loop } Applicationl.Done; { Destroy application instance } end. W h e t h e r t o u s e g l o b a l o r l o c a l m e m o r y d e p e n d s b o t h o n t h e size o f t h e m e m o r y b l o c k y o u are a l l o c a t i n g a n d w h o n e e d s t o a c c e s s it. I n C h a p t e r 1 1 , y o u use global m e m o r y blocks to exchange data with the clipboard and other applications through D D E (Dynamic Data Exchange).
9 — M e m o r y Matters
A Few Advanced Memory Matters A s a r u l e o f t h u m b , w h e n i n d o u b t , a l l o c a t e m e m o r y as m o v e a b l e r a t h e r t h a n f i x e d . A m e m o r y b l o c k s h o u l d b e a l l o c a t e d as fixed o n l y if y o u m u s t k e e p a m e m o r y b l o c k i n a s i n g l e l o c a t i o n t h r o u g h o u t t h e life o f y o u r a p p l i c a t i o n . If y o u fix a m e m o r y b l o c k , y o u sacrifice m u c h o f t h e s o p h i s t i c a t i o n o f W i n d o w s ' memory-management system. T h e r e are a c o u p l e o f n o t a b l e v a r i a t i o n s o n t h e fixer t h e m e y o u m i g h t w a n t t o b e a w a r e of: • A l l s e g m e n t s are m o v e a b l e i n s t a n d a r d (or 2 8 6 p r o t e c t e d ) m o d e b e c a u s e W i n d o w s can m o v e segments without c h a n g i n g their addresses. W i n d o w s changes the base address in the segment descript o r t a b l e , n o t t h e s e g m e n t a d d r e s s . N o t s o , o f c o u r s e , i n real m o d e . • A l s o , w h e n e v e r y o u r a p p l i c a t i o n g e t s a far p o i n t e r f r o m W i n d o w s , t h e far p o i n t e r r e f e r e n c e s a fixed d a t a s e g m e n t . F o r e x a m p l e , e a c h t i m e y o u r a p p l i c a t i o n starts u p , it g e t s a far p o i n t e r t o a l o c a t i o n i n m e m o r y that h o l d s a c o m m a n d - l i n e a r g u m e n t f o r y o u r a p p l i c a t i o n . For a m o r e in-depth discussion of h o w W i n d o w s manages c o d e and data s e g m e n t s , c h e c k o u t C h a r l e s P e t z o l d ' s e x c e l l e n t Programming Windows, a g u i d e to p r o g r a m m i n g W i n d o w s using C (Microsoft Press). A l t h o u g h Petzold's e x a m p l e s a n d a t t e n t i o n are a l m o s t e n t i r e l y C - o r i e n t e d , h e p r o v i d e s a n i n c r e d ible a m o u n t o f useful a n d general information about W i n d o w s p r o g r a m m i n g .
Direct Memory Access T u r b o P a s c a l f o r W i n d o w s h a s t h r e e p r e d e f i n e d arrays (Mem, MemW, a n d MemL) that e n a b l e y o u t o a c c e s s m e m o r y directly. U s i n g t h e s e arrays, y o u c a n c h a n g e the values o f a byte o f m e m o r y . This b o o k d o e s not detail h o w to manipulate m e m o r y directly, b e c a u s e it is p r o b a b l y n o t a g o o d i d e a t o d o s o . B y d i r e c t l y m a n i p u l a t i n g m e m o r y , y o u interfere with the W i n d o w s m e m o r y - m a n a g e m e n t s y s t e m a n d s e r i o u s l y j e o p a r d i z e t h e life e x p e c t a n c y o f y o u r a p p l i c a t i o n s . U n l e s s y o u h a v e a n o u t s t a n d i n g r e a s o n f o r a c c e s s i n g m e m o r y directly, let W i n d o w s d o it.
Data Segments E a c h a p p l i c a t i o n r u n n i n g i n W i n d o w s h a s its o w n 6 4 K d a t a s e g m e n t . T h i s d a t a s e g m e n t is t h e o n e p o i n t e d t o b y t h e d a t a s e g m e n t ( D S ) register. It c o n s i s t s o f four parts:
297
298
Part I I — A d v a n c e d T o p i c s
1. A l o c a l h e a p ( y o u specify size) 2. A stack (for l o c a l v a r i a b l e s — t h e o n e s a l l o c a t e d i n p r o c e d u r e s a n d functions) 3. A stack d a t a a r e a f o r g l o b a l v a r i a b l e s a n d t y p e d c o n s t a n t s 4. A task h e a d e r that i d e n t i f i e s t h e s e g m e n t E a c h d y n a m i c l i n k library ( D L L ) r u n n i n g i n W i n d o w s h a s its o w n 6 4 K d a t a s e g m e n t as w e l l , w h i c h c o n s i s t s o f a task h e a d e r a n d a l o c a l h e a p , b u t n o t a stack o r stack d a t a a r e a . D L L p r o c e d u r e s a n d f u n c t i o n s u s e t h e stack o f t h e a p p l i c a t i o n that c a l l e d t h e m .
Heap Errors S o m e t h i n g e l s e y o u m i g h t w a n t t o t h i n k a b o u t a r e h e a p e r r o r s . If t h e T u r b o Pascal f o r W i n d o w s h e a p m a n a g e r c a n n o t a l l o c a t e t h e m e m o r y b l o c k y o u r e q u e s t ( u s i n g New o r Get Mem), it g e n e r a t e s a r u n - t i m e e r r o r . A r u n - t i m e e r r o r is p r o b a b l y n o t d e s i r a b l e f o r y o u r a p p l i c a t i o n . M o r e likely, y o u w a n t y o u r a p p l i c a t i o n t o c o n t i n u e p r o c e s s i n g , e v e n if it c a n n o t a l l o c a t e t h e m e m o r y b l o c k . T h e s o l u t i o n i s a H e a p E r r o r v a r i a b l e . U s e t h e H e a p E r r o r v a r i a b l e t o install a h e a p e r r o r f u n c t i o n that is s e n t a m e s s a g e w h e n e v e r t h e h e a p m a n a g e r c a n n o t a l l o c a t e t h e m e m o r y b l o c k y o u r e q u e s t . T h e H e a p E r r o r v a r i a b l e is a p o i n t e r t o a f u n c t i o n (in t h e s y s t e m u n i t ) w i t h a h e a d e r s u c h as t h i s :
function HeapFunc(Size: Word): Integer; far; Install t h e HeapFunc b y a s s i g n i n g its a d d r e s s t o t h e HeapError v a r i a b l e :
HeapError := @HeapFunc; HeapFunc is c a l l e d a u t o m a t i c a l l y w h e n e v e r a New o r GetMem r e q u e s t fails. T h e Size p a r a m e t e r c o n t a i n s t h e size o f t h e m e m o r y b l o c k that c o u l d n o t b e a l l o c a t e d . T h e HeapFunc s h o u l d r e t u r n a z e r o , o n e , o r t w o . A z e r o i n d i c a t e s a m e m o r y - a l l o c a t i o n failure a n d c a u s e s a r u n - t i m e e r r o r . A o n e i n d i c a t e s f a i l u r e , but d o e s n o t generate a run-time error. A t w o indicates success. T o guarantee that y o u r a p p l i c a t i o n d o e s n o t c r a s h after a n u n s u c c e s s f u l m e m o r y - a l l o c a t i o n a t t e m p t , h a v e t h e HeapFunc r e t u r n a o n e :
function HeapFunc(Size: Word): Integer; far; begin HeapFunc := 1; end; W h e n t h e HeapFunc r e t u r n s a o n e , it f o r c e s New o r GetMem t o r e t u r n a n i l pointer rather than crash the p r o g r a m .
9 — M e m o r y Matters
T h e HeapError v a r i a b l e a l s o c a n b e u s e d t o install a c o n s t r u c t o r error-recovery system.
Code Segments E a c h u n i t , library, o r m a i n p r o g r a m h a s its o w n c o d e s e g m e n t . E a c h o f t h e s e c o d e s e g m e n t s c a n b e u p t o 6 4 K i n s i z e , l i m i t e d o n l y b y available m e m o r y . E a c h c o d e s e g m e n t c a n b e m o v e a b l e o r fixed, p r e l o a d e d o r d e m a n d l o a d e d , d i s c a r d a b l e o r p e r m a n e n t . ( T h e d e f a u l t attributes f o r a c o d e s e g m e n t are m o v e a b l e , p r e l o a d e d , a n d p e r m a n e n t . U n l e s s y o u a r e d o i n g s o m e n o n ordinary programming, y o u d o not have to change these defaults. This minid i s c u s s i o n is i n c l u d e d just i n c a s e . ) If a c o d e s e g m e n t is m o v e a b l e it c a n b e m o v e d b y W i n d o w s t o free m e m o r y b l o c k s . I f a c o d e s e g m e n t is fixed, W i n d o w s c a n n o t m o v e it. T o m a k e y o u r a p p l i c a t i o n flexible f o r W i n d o w s , it s h o u l d r e s i d e i n m o v e a b l e c o d e s e g m e n t s . If a c o d e s e g m e n t is p r e l o a d e d , it is a u t o m a t i c a l l y l o a d e d w h e n y o u activate t h e a p p l i c a t i o n . I f a c o d e s e g m e n t is d e m a n d - l o a d e d , it is l o a d e d o n l y w h e n a r o u t i n e that r e s i d e s i n t h e s e g m e n t is c a l l e d . If a c o d e s e g m e n t is d i s c a r d a b l e , it b e h a v e s m u c h like a n o v e r l a i d s e g m e n t . W i n d o w s c a n t e m p o r a r i l y d i s c a r d it a n d free its m e m o r y w h e n it n e e d s t o . Windows then reloads the segment w h e n a procedure or function in the code s e g m e n t is n e e d e d . R e l o a d i n g a s e g m e n t is o b v i o u s l y m o r e t i m e - c o n s u m i n g . T h e trade-off: y o u r a p p l i c a t i o n t a k e s u p less r o o m a n d a g a i n is m o r e flexible a n d c a n b e m o v e d around by Windows.
wm_Compacting O n e o t h e r i m p o r t a n t m a t t e r y o u m i g h t w a n t t o i n f o r m y o u r a p p l i c a t i o n s o f is t h e wm_Compacting m e s s a g e . W i n d o w s b r o a d c a s t s this m e s s a g e t o all h i g h l e v e l w i n d o w s w h e n it b e g i n s t o s p e n d m o r e t h a n 12.5 p e r c e n t o f its t i m e compacting memory. B e c a u s e c o m p a c t i n g m e m o r y is o b v i o u s l y a t i m e - c o n s u m i n g task f o r t h e W i n d o w s m a n a g e m e n t s y s t e m , it s e n d s this m e s s a g e t o i n d i c a t e that it is s p e n d i n g t o o m u c h time "managing" rather than r u n n i n g applications. W h e n a n a p p l i c a t i o n r e c e i v e s this m e s s a g e , it s h o u l d a t t e m p t t o free as m u c h m e m o r y as it c a n . Y o u r a p p l i c a t i o n r e s p o n d s t o this m e s s a g e t h e s a m e w a y it r e s p o n d s t o a n y W i n d o w s m e s s a g e : w i t h a W i n d o w s m e s s a g e - r e s p o n s e method. For example:
299
300
Part I I — A d v a n c e d T o p i c s
AnObjectInstance.WMCompacting(var Msg: TMessage); begin { Handle compaction message by freeing memory here } end;
Wrap-up That discussion covers the general m e m o r y issues y o u n e e d to k n o w in order t o w r i t e s e n s i b l e W i n d o w s a p p l i c a t i o n s . W i n d o w s is a d y n a m i c s y s t e m i n various ways, and object-oriented techniques can help y o u use and appreciate this d y n a m i c quality. I n g e n e r a l , y o u s h o u l d let W i n d o w s h a n d l e a n y t h i n g it c a n h a n d l e f o r y o u b e c a u s e (frankly) it is g o i n g t o b e b e t t e r at it. Y o u a l s o c a n e a s e t h e p r o c e s s f o r W i n d o w s by letting the blocks o f m e m o r y y o u allocate (whether local or global) b e m o v e a b l e a n d d i s c a r d a b l e , if p o s s i b l e . T h i s t a k e s t h e b e s t a d v a n t a g e o f t h e W i n d o w s m e m o r y - m a n a g e m e n t system. Y o u a l s o m u s t c h a n g e y o u r t r a d i t i o n a l t h i n k i n g w h e n y o u refer t o m e m o r y b l o c k s i n t e r m s o f p o i n t e r s a n d a d d r e s s e s . W i t h W i n d o w s , m e m o r y b l o c k s are just a little m o r e i n d i r e c t . Y o u g e t t h e a d d r e s s f r o m a h a n d l e first b e c a u s e W i n d o w s has a built-in system for manipulating m e m o r y t h r o u g h handles. By u s i n g h a n d l e s , o t h e r a p p l i c a t i o n s c a n "get a h a n d l e " o n t h e m e m o r y that a n o t h e r a p p l i c a t i o n is u s i n g . T h i s c r e a t e s t h e u s e f u l p o s s i b i l i t y o f e x c h a n g i n g data b e t w e e n applications, w h i c h y o u learn about in detail in C h a p t e r 11.
10 CHAPTER
DISPLAY CONTEXTS AND DRAWING TOOLS / wanted the audience to know that a computer was making the drawings. People would stand there for a long time watching the computer produce drawings. The pen would pause and people would say, "Gee, it's thinking of what to do next." Aaron C o h e n A l t h o u g h y o u have already u s e d the Graphics Device Interface in most of the p r e v i o u s c h a p t e r s , this c h a p t e r s p e n d s a little t i m e d e s c r i b i n g its f e a t u r e s . T o h e l p t h e G D I m a k e m o r e s e n s e , several e x a m p l e s o f h o w y o u m i g h t u s e it t o c r e a t e c o m p l e x g r a p h i c s - o r i e n t e d a p p l i c a t i o n s are c o v e r e d . T h e W i n d o w s G D I is a r e m a r k a b l e a s p e c t o f W i n d o w s b e c a u s e it a l l o w s y o u t o w r i t e a p p l i c a t i o n s that d i s p l a y a n d m a n i p u l a t e g r a p h i c s , i n d e p e n d e n t o f a s p e c i f i c d i s p l a y d e v i c e . Y o u c a n , f o r e x a m p l e , w r i t e a p p l i c a t i o n s that u s e t h e s a m e c o d e yet c a n b e d i s p l a y e d i n E G A , V G A , o r H e r c u l e s m o d e s . W i n d o w s a c h i e v e s d e v i c e i n d e p e n d e n c e b y u s i n g v a r i o u s d e v i c e drivers that translate G D I f u n c t i o n calls i n t o c o m m a n d s that m a k e s e n s e t o t h e s p e c i f i c o u t p u t d e v i c e b e i n g u s e d . Y o u w r i t e c o d e as t h o u g h t h e o u t p u t d e v i c e d o e s n o t m a t t e r , w h i c h (in g e n e r a l ) is h o w it is.
302
Part I I — A d v a n c e d T o p i c s
Handling a Display Context A d i s p l a y c o n t e x t is the surface of a n a p p l i c a t i o n w i n d o w ' s client area, or m o r e precisely, it represents the surface of a n a p p l i c a t i o n w i n d o w ' s client area. A n y d i s p l a y c o n t e x t has attributes that represent c o l o r s , w i n d o w p o s i t i o n , d r a w i n g t o o l s , a n d s o o n . (These attributes are set t o d e f a u l t v a l u e s b y O b j e c t W i n d o w s , w h i c h is w h y y o u have n o t had t o set a n y o f t h e s e attributes in t h e e x a m p l e s s o far.) A d i s p l a y c o n t e x t u s e s a l o t o f m e m o r y , s o Windows l i m i t s a n y Windows s e s s i o n t o a total o f five c o n c u r r e n t in-use d i s p l a y c o n t e x t s . It is important, therefore, that y o u r a p p l i c a t i o n release a n y d i s p l a y c o n t e x t it is u s i n g as s o o n as it n o l o n g e r n e e d s the d i s p l a y c o n t e x t . This a c t i o n results in a repetitive, s e e m i n g l y inefficient ( b u t necessary) p o s s e s s i n g a n d releasing o f display c o n t e x t s , a n d it d o e s have a d r a w b a c k . It m e a n s f o r e m o s t that y o u r a p p l i c a t i o n d o e s n o t maintain control over a display context. When a n a p p l i c a t i o n releases a d i s p l a y c o n t e x t , it is giving it u p t o a n y other a p p l i c a t i o n that n e e d s it. T h e n e w a p p l i c a t i o n c a n , in t u r n , m a n i p u l a t e its attributes. E a c h t i m e a n a p p l i c a t i o n releases a d i s p l a y c o n t e x t , the d i s p l a y c o n t e x t ' s attributes are reset t o the d e f a u l t s . T h u s , y o u r a p p l i c a t i o n m u s t set a n y d i s p l a y c o n t e x t attributes for c h a n g i n g e a c h t i m e it receives a d i s p l a y c o n t e x t . I n a d d i t i o n , y o u r a p p l i c a t i o n m u s t reselect a n y d r a w i n g t o o l ( p e n , b r u s h , f o n t ) for u s e e a c h t i m e it receives a d i s p l a y c o n t e x t . F o r e x a m p l e , derive a d r a w i n g w i n d o w that resets a specific k i n d o f p e n (a d r a w i n g t o o l ) e a c h t i m e it o b t a i n s a d i s p l a y c o n t e x t . I n a d d i t i o n , let the u s e r m o d i f y b o t h the p e n size (the w i d t h o f the l i n e it draws) a n d the p e n style. This e x a m p l e s h o w s how t o • O b t a i n a n d release
a display context.
• U s e m e n u - c o m m a n d m e s s a g e s t o invoke
a dialog.
• Create, modify, a n d delete drawing tools. B e g i n , as u s u a l , b y deriving a n Application ( o b j e c t ) : type DrawingApplication = object(BasicApplication) procedure InitMainWindow; virtual; end; a n d its MainWindow (a DrawingWindow): type PDrawingWindow = "DrawingWindow; DrawingWindow = object(MainWindow) DragDC: HDC; { A new display context } ThePen: HPen; { A drawing tool }
10—Display Contexts a n d Drawing Tools
PenSize: Integer; { Pen variables } PenStyle: Integer; constructor Init(AParent: PWindowsObject; ATitle: PChar); destructor Done; virtual; function CanClose: Boolean; virtual; { New mouse methods } procedure WMLButtonDown(var Msg: TMessage); virtual wm_First + wm_LButtonDown; procedure WMLButtonUp(var Msg: TMessage); virtual wm_First + wm_LButtonUp; procedure WMMouseMove(var Msg: TMessage); virtual wm_First + wm_MouseMove; { Menu-response methods } procedure CMPenStyle(var Msg: TMessage); virtual cm_First + cm_PenStyle; procedure CMPenSize(var Msg: TMessage); virtual cm_First + cm_PenSize; { Pen modifiers } procedure SetPenSize(NewSize: Integer); procedure SetPenStyle(NewStyle: Integer); end; T h e CMPenSize a n d CMPenStyle m e t h o d s a r e m e n u - r e s p o n s e m e t h o d s , w h i c h r e s p o n d t o t h e m e n u c o m m a n d s cm_PenSize a n d cmPenStyle. D e clare t h e s e t w o c o m m a n d s i n t h e const s e c t i o n :
const cm_PenStyle = 401; cm_PenSize = 402; T h e s e c o n s t a n t s c o r r e s p o n d t o t h e m e n u i t e m s i n t h e r e s o u r c e file, P E N . R E S . F i g u r e 10.1 s h o w s t h e c r e a t i o n a n d t e s t i n g o f P E N . R E S . N o t i c e t h e matching constants. W h e n y o u c o n s t r u c t t h e DrawingWindow: 1. L o a d t h e m e n u ( P E N . R E S ) that c o n t a i n s t h e PenSize a n d PenStyle m e n u items. 2. S e t t h e d e f a u l t p e n size a n d style. 3. C r e a t e t h e p e n , u s i n g CreatePen:
constructor DrawingWindow.Init(AParent: PWindowsObj ect; ATitle: PChar); begin TWindow.Init(AParent, ATitle); Attr.Menu := LoadMenu(HInstance, PChar(109));
303
304
Part I I — A d v a n c e d T o p i c s
ButtonDown := False; PenSize := 1; { Size increases with integer value } PenStyle := ps_DashDot; { Refers to a pen constant, an integer } ThePen := CreatePen(PenStyle, PenSize, 0); end;
Figure
10.1. Creation and testing of PEN. RES.
N o t i c e that t h e d r a w i n g t o o l (the p e n ) is n o t a s s o c i a t e d w i t h a d i s p l a y c o n t e x t . Y o u d o n o t o b t a i n a d i s p l a y c o n t e x t u n t i l y o u d e c i d e t o u s e o n e . I n this e x a m p l e , t h e u s e r c a n d r a w i n t h e w i n d o w w h e n s h e p r e s s e s t h e left m o u s e button down:
procedure DrawingWindow.WMLButtonDown(var Msg: TMessage); begin (* InvalidateRect(HWindow, nil, True); if you want the window cleared *) if not ButtonDown then begin ButtonDown := True; SetCapture(HWindow); DragDC := GetDC(HWindow); SelectObject(DragDC, ThePen); { Select the pen created in Init } MoveTo(DragDC, Msg.LParamLo, Msg.LParamHi); { Use the pen } end; end;
10—Display Contexts a n d Drawing Tools
S h e r e l e a s e s t h e d i s p l a y c o n t e x t w h e n s h e is f i n i s h e d d r a w i n g :
procedure DrawingWindow.WMLButtonUp(var Msg: TMessage); begin if ButtonDown then begin ButtonDown := False; ReleaseCapture; ReleaseDC(HWindow, DragDC); end; end; N o t i c e that, a l t h o u g h t h e d i s p l a y c o n t e x t h a s b e e n r e l e a s e d s o that o t h e r a p p l i c a t i o n s c a n u s e t h e i r o w n d i s p l a y c o n t e x t s , t h e DrawingWindow is still o p e n , a n d y o u c a n still d r a w i n t h e w i n d o w . E a c h t i m e y o u c l i c k t h e left m o u s e button, the application grabs a display context for y o u to u s e . N o w w r i t e t h e m e n u - r e s p o n s e m e t h o d s f o r m o d i f y i n g t h e p e n ' s size a n d style. W h e n t h e u s e r s e l e c t s t h e PenSize m e n u i t e m , a d i a l o g w i n d o w a p p e a r s that a l l o w s h e r t o c h a n g e t h e p e n size:
procedure DrawingWindow.CMPenSize(var Msg: TMessage); var InputText: array[0..5] of Char; NewSize, ErrorPos: Integer; begin if not ButtonDown then begin Str(PenSize, InputText); if Application".ExecDialog(New(PInputDialog, Init(@Self, 'Line Thickness', 'Input a new thickness:', InputText, SizeOf(InputText)))) = id_0k then begin Val(InputText, NewSize, ErrorPos); if ErrorPos = 0 then SetPenSize(NewSize); end; end; end; A p r o c e d u r e for actually creating the n e w p e n in t h e n e w size:
procedure DrawingWindow.SetPenSize(NewSize: Integer); begin DeleteObject(ThePen); ThePen := CreatePen(PenStyle, NewSize, 0); PenSize := NewSize; end;
305
306
Part I I — A d v a n c e d T o p i c s
T h e s a m e g o e s for PenStyle. A response a l l o w t h e u s e r t o m o d i f y t h e p e n ' s style is
m e t h o d that u s e s a d i a l o g t o
procedure DrawingWindow.CMPenStyle(var Msg: TMessage); var InputText: array[0..5] of Char; NewStyle, ErrorPos: Integer; begin if not ButtonDown then begin Str(PenStyle, InputText); if Application".ExecDialog(New(PInputDialog, Init(@Self, 'Pen Style', 'New Pen Style: 0 = solid 1 = dash 2 = dot, and so on, InputText, SizeOf(InputText)))) = id_0k then begin Val(InputText, NewStyle, ErrorPos); if ErrorPos = 0 then SetPenStyle(NewStyle); end; end; end; A SetPenStyle m e t h o d to actually create t h e n e w p e n is procedure DrawingWindow.SetPenStyle(NewStyle: begin DeleteObject(ThePen); ThePen := CreatePen(NewStyle, PenSize, 0); PenStyle := NewStyle; end;
Integer);
N o t i c e that t h e DrawingWindow d o e s n o t " o w n " a d i s p l a y c o n t e x t w h i l e the p e n ' s size a n d style are m o d i f i e d . Y o u d o n o t n e e d it t o create a n d m o d i f y d r a w i n g t o o l s (objects) that are u s e d t o d r a w o n t h e display c o n t e x t . A l s o , n o t i c e that b e c a u s e t h e t w o variables PenStyle a n d PenSize m a i n t a i n t h e status of t h e d r a w i n g t o o l s , e a c h t i m e t h e DrawingWindow o b t a i n s a d i s p l a y c o n t e x t it u s e s the current settings for the p e n . T h e p e n (with its current v a l u e s ) is s e l e c t e d just after the d i s p l a y c o n t e x t is o b t a i n e d : DragDC := GetDC(HWindow); SelectObject(DragDC, ThePen);
{ Get a display context } { Select the pen created in Init }
When y o u finish with the DrawingWindow (notthe d i s p l a y context), d e l e t e the drawing tool (the p e n ) u s i n g DeleteObj ect:
10—Display Contexts and Drawing Tools
destructor begin
DrawingWindow.Done;
DeleteObject(ThePen); TWindow.Done; end; B e c a u s e t h e d r a w i n g t o o l ( o b j e c t ) is n o t part o f t h e d i s p l a y c o n t e x t , it is n o t d e l e t e d a u t o m a t i c a l l y w h e n t h e d i s p l a y c o n t e x t is r e l e a s e d . Listing 1 0 . 1 s h o w s t h e c o m p l e t e Pen m o d i f i c a t i o n e x a m p l e , a n d f i g u r e 1 0 . 2 s h o w s t h e D r a w i n g W i n d o w c r e a t e d b y this c o d e .
Figure
Listing
10.2. The DrawingWindow
10.1.
The complete
created by listing 10.1.
pen-modification
example.
program Pen; uses Strings, WinTypes, WinProcs, WObjects, WIF5, StdDlgs;
{ Basic Interface }
{$R Pen.Res } continues
307
308
Part I I — A d v a n c e d T o p i c s
Listing
10.1.
continued
const cm_PenStyle = 401; cm_PenSize = 402; type DrawingApplication = object(BasicApplication) procedure InitMainWindow; virtual; end; PDrawingWindow = "DrawingWindow; DrawingWindow = object(MainWindow) DragDC: HDC; ThePen: HPen; PenSize: Integer; PenStyle: Integer; constructor Init(AParent: PWindowsObject; ATitle: PChar); destructor Done; virtual; function CanClose: Boolean; virtual; procedure WMLButtonDown(var Msg: TMessage); virtual wm_First + wm_LButtonDown; procedure WMLButtonUp(var Msg: TMessage); virtual wm_First + wm_LButtonUp; procedure WMMouseMove(var Msg: TMessage); virtual wm_First + wm_MouseMove; procedure CMPenStyle(var Msg: TMessage); virtual cm_First + cm_PenStyle; procedure CMPenSize(var Msg: TMessage); virtual cm_First + cm_PenSize; procedure SetPenSize(NewSize: Integer); procedure SetPenStyle(NewStyle: Integer); end; { { DrawingWindow's method implementations:
} }
{
}
constructor DrawingWindow.Init(AParent: PWindowsObject; ATitle: PChar); begin TWindow.Init(AParent, ATitle); Attr.Menu := LoadMenu(HInstance, PChar(109)); ButtonDown := False; PenSize := 1; PenStyle := ps_DashDot;
10—Display Contexts and Drawing Tools
ThePen := CreatePen(PenStyle, PenSize, 0); end;
destructor DrawingWindow.Done; begin DeleteObject(ThePen); TWindow.Done; end; procedure DrawingWindow.CMPenStyle(var Msg: TMessage); var InputText: array[0..5] of Char; NewStyle, ErrorPos: Integer; begin if not ButtonDown then begin Str(PenStyle, InputText); if Application".ExecDialog(New(PInputDialog, Init(@Self, 'Pen Style', 'New Pen Style: 0 = solid 1 = dash 2 = dot, etc.', InputText, SizeOf(InputText)))) = id_0k then begin Val(InputText, NewStyle, ErrorPos); if ErrorPos = 0 then SetPenStyle(NewStyle); end; end; end; procedure DrawingWindow.SetPenStyle(NewStyle: Integer); begin DeleteObject(ThePen); ThePen := CreatePen(NewStyle, PenSize, 0); PenStyle := NewStyle; end;
function DrawingWindow.CanClose: Boolean; var Reply: Integer; begin CanClose := True; continues
309
310
Part I I — A d v a n c e d T o p i c s
Listing
10.1.
continued
Reply := MessageBox(HWindow, 'Do you want to save?', 'Drawing has changed', mb_YesNo or mb_IconQuestion); if Reply = id_Yes then CanClose := False; end; procedure DrawingWindow.WMLButtonDown(var Msg: TMessage); begin (* InvalidateRect(HWindow, nil, True); *) if not ButtonDown then begin ButtonDown := True; SetCapture(HWindow); DragDC := GetDC(HWindow); SelectObject(DragDC, ThePen); MoveTo(DragDC, Msg.LParamLo, Msg.LParamHi); end; end; procedure DrawingWindow.WMMouseMove(var Msg: TMessage); begin if ButtonDown then LineTo(DragDC, Integer(Msg.LParamLo), Integer(Msg.LParamHi)); end; procedure DrawingWindow.WMLButtonUp(var Msg: TMessage); begin if ButtonDown then begin ButtonDown := False; ReleaseCapture; ReleaseDC(HWindow, DragDC); end; end; procedure DrawingWindow.CMPenSize(var Msg: TMessage); var InputText: array[0..5] of Char; NewSize, ErrorPos: Integer; begin if not ButtonDown then begin Str(PenSize, InputText); if Application".ExecDialog(New(PInputDialog,
10—Display C o n t e x t s a n d D r a w i n g T o o l s
Init(@Self, 'Line Thickness', 'Input a new thickness:', InputText, SizeOf(InputText)))) = id_0k then begin Val(InputText, NewSize, ErrorPos); if ErrorPos = 0 then SetPenSize(NewSize); end; end; end; procedure DrawingWindow.SetPenSize(NewSize: Integer); begin DeleteObject(ThePen); ThePen := CreatePen(PenStyle, NewSize, 0); PenSize := NewSize; end; { { DrawingApplication's
method implementations:
{
} } }
procedure DrawingApplication.InitMainWindow; begin MainWindow := New(PDrawingWindow, Init(nil, end;
'Drawing
{ { Main program:
} }
{
}
Window'));
var App :
DrawingApplication;
begin App.Init('DrawProgram ); App.Run; App.Done; end. 1
Y o u a l s o c a n t h i n k o f a d i s p l a y c o n t e x t ( D C ) as a s t o r a g e o f t h e attributes that d e t e r m i n e h o w W i n d o w s G D I f u n c t i o n s o p e r a t e i n a w i n d o w ' s c l i e n t a r e a . A d i s p l a y c o n t e x t " h o l d s " 19 attributes (a m a p p i n g m o d e , p e n , f o n t , text c o l o r , a n d s o o n ) . E a c h t i m e y o u r a p p l i c a t i o n asks f o r a d i s p l a y c o n t e x t f r o m W i n d o w s , W i n d o w s creates a n e w o n e with a default value for each attribute. Y o u d o not h a v e t o set e a c h o f t h e 19 attributes e a c h t i m e y o u r e c e i v e a D C . T a b l e 10.1 s h o w s t h e d e v i c e c o n t e x t a t t r i b u t e a n d its d e f a u l t .
311
312
Part I I — A d v a n c e d T o p i c s
Table DC
10.1.
Device
context
Attribute
attributes
with their
defaults.
Default
Mapping mode
MMTEXT
Window
0,0
origin
Viewport origin
0,0
Window
1,1
extents
Viewport extents
1,1
Pen
BLACK_PEN
Brush
WHITE
JBRUSH
Font
SYSTEMFONT
Bit m a p
—
Current pen position
0,0
Background mode
Opaque
Background color
White
Text color
Black
Drawing mode
R2COPYPEN
Stretching m o d e
BLACK-ONWHITE
P o l y g o n filling m o d e
Alternate
Intercharacter spacing
0
Brush origin
0,0
C l i p p i n g region
—
Y o u c a n o v e r r i d e a n y o f t h e d i s p l a y c o n t e x t ' s d e f a u l t a t t r i b u t e s if y o u w a n t . W i n d o w s provides a f u n c t i o n for setting o r selecting e a c h attribute a n d for g e t t i n g t h e v a l u e o f a n a t t r i b u t e . F o r e x a m p l e , t o set t h e m a p p i n g m o d e attribute:
var ADCHandle : HDC; AMapMode : Integer; begin
end;
SetMapMode(ADCHandle, AMapMode); {...}
10—Display Contexts and Drawing Tools
T o set t h e Windows
origin:
var ADCHandle : HDC; X, Y : Integer; begin SetWindowOrg(ADCHandle,X,Y); {
}
end; T o g e t t h e text color: var TxtColor : Longlnt; ADCHandle : HDC; begin TxtColor := GetTextColor(ADCHandle); {••-.} end;
T a b l e 10.2 s h o w s t h e f u n c t i o n s t o set o r select e a c h o f t h e d i s p l a y c o n t e x t
attributes. Table
10.2. Functions
to set or select
display
context
attributes.
Set/Select
Get
Mapping mode
SetMapMode
GetMapMode
Window
SetWindowOrg
GetWindowOrg
V i e w p o r t origin
SetViewportOrg
GetViewportOrg
Window
SetWindowExt
GetWindowExt
Viewport extents
SetViewportExt
GetViewportExt
Pen
SelectObject
SelectObject
Brush
SelectObject
SelectObject
Font
SelectObject
SelectObject
Bit m a p
SelectObject
SelectObject
Current p e n position
MoveTo; LineTo
GetCurrentPosition
Background mode
SetBkMode
GetBkMode
Background color
SetBkColor
GetBkColor
DC
Attribute
origin
extents
continues
313
314
Part I I — A d v a n c e d T o p i c s
Table
10.2.
continued Set/Select
Get
Text color
SetTextColor
GetTextColor
Drawing m o d e
SetROP2
GetROP2
Stretching m o d e
SetPolyFiUMode
GetPolyFillMode
P o l y g o n filling m o d e
SetPOlyFillMode
GetPolyFillMode
Intercharacter spacing
SetTextCharacterExtra
GetTextChar..
B r u s h origin
SetBrushOrg
GetBrushOrg
DC
Attribute
C l i p p i n g region
SelectClipRgn
GetClipBox
SelectObject
SelectObject
T h e s u r f a c e o f t h e d i s p l a y c o n t e x t itself is a bit m a p that c o r r e s p o n d s t o s o m e s p e c i f i c d e v i c e . T h u s , a n y d e v i c e c o n t e x t ' s bit m a p is s p e c i f i c t o t h e c u r r e n t d i s p l a y c o n t e x t that r e p r e s e n t s t h e v i d e o a d a p t e r y o u r a p p l i c a t i o n is u s i n g . T h i s s u g g e s t s t h e p r o b l e m o f m a k i n g t h e d e v i c e - c o n t e x t bit m a p u s a b l e by different adapters. T h e s o l u t i o n is f o r y o u r a p p l i c a t i o n t o c r e a t e d e v i c e - i n d e p e n d e n t bit m a p s using the following Windows G D I functions: CreateCompatibleDC, CreateCompatible Bitmap, CreateDIBitmap. For example: procedure var
SomeWindow.SetupWindow;
HandleDC: HDC; begin TNoIconWindow.SetupWindow; HandleDC := GetDC(HWindow); ABitmap := CreateCompatibleBitmap(HandleDC, 80, 80); ABkgnd := CreateCompatibleBitmap(HandleDC, 1000, 1000); ReleaseDC(HWindow, HandleDC); end; Y o u r application c a n decide w h e t h e r drawings are clipped in t h e display context b y modifying t h e clipping-region attribute in t h e display context. Usually, y o u want t o u s e the default clipping region, the client area o f the window.
10—Display Contexts and Drawing Tools
Set the clipping region w h e n you select an object: SelectObj ect(ADCHandle,ARegionHandle); or use SelectClipRgn: SelectClipRgn(ADCHandle,ARegionHandle);
Mapping Modes O n e of the attributes you might find useful to change is the mapping mode. W i n d o w s defines eight mapping m o d e s (the default MM_TEXT, MM_L0METRIC, and so on). Table 10.3 shows these mapping modes. Table
10.3-
Mapping
Windows
Mode
mapping
modes.
Logical
Unit
MMTEXT
pixel
MMLOMETRIC
0.1 m m
MMHIMETRIC
0.01 m m
MMLOENGLISH
0.01
MMHIENGLISH
0.001
MM_TWIPS
1/1440 inch
MMJSOTROPIC
Arbitrary ( x = y )
MM ANISOTROPIC
Arbitrary ( x < > y )
inch inch
The default mapping m o d e is MM_TEXT, which moves X and Y values a pixel at a time. Its origin (0,0) is the upper-left corner of the window's client area. If you have difficulty understanding h o w a screen, window, and window's client areas differ, see figure 10.3. In short, the screen is the entire display. The w i n d o w is an entire window, including the caption bar, scroll bars, w i n d o w frame, and any m e n u . The w i n d o w client area is the part of a w i n d o w excluding the caption bar, m e n u , and so forth. Generally, w h e n you use display contexts, you use the w i n d o w client area (which is what is used in the examples). Y o u should be aware, however, that there are W i n d o w s functions for converting coordinates between client area and screen, screen and window, and so on.
315
316
Part I I — A d v a n c e d T o p i c s
A s s u m i n g that y o u are w o r k i n g i n t h e w i n d o w ' s c l i e n t a r e a (the d e f a u l t ) , a n d a s s u m i n g that y o u are w o r k i n g i n MM_TEXT m a p p i n g m o d e (the d e f a u l t ) , y o u are u s i n g a p i x e l - b a s e d c o o r d i n a t e s y s t e m b e g i n n i n g i n t h e u p p e r - l e f t c o r n e r (see figure 1 0 . 4 ) .
Figure 10.3- A screen, window,
and window's
client
M M _ T E X T Mapping
areas.
Mode
+x
+
y
Figure 10.4. A pixel-based
coordinate
system beginning
in the upper-left
comer.
10—Display Contexts and Drawing Tools
If y o u are u s e d t o w o r k i n g w i t h m a t h e m a t i c a l c o o r d i n a t e s y s t e m s , y o u m i g h t w o n d e r w h y t h e o r i g i n is t h e u p p e r - l e f t c o r n e r . It is t h e r e b e c a u s e text flows f r o m left t o right, f r o m t o p t o b o t t o m . T h u s , a d d i t i o n a l text o n a s c r e e n is s h o w n b y i n c r e a s i n g X a n d Y ( + X , + Y ) c o o r d i n a t e s — c o n v e n i e n t f o r text, b u t backward for most mathematical coordinate systems. If y o u n e e d a m o r e intuitive c o o r d i n a t e s y s t e m f o r p l o t t i n g g r a p h s a n d o t h e r s , h o w e v e r , y o u c a n c h a n g e t h e m a p p i n g m o d e t o o n e o f five d i f f e r e n t m o d e s that h a v e t h e i r o r i g i n (0,0) i n t h e lower-left c o r n e r . T h e s e lower-left m a p p i n g m o d e s are s o m e t i m e s c a l l e d metric mapping modes. T h e y are n o t p i x e l - b a s e d (like M M T E X T ) ; i n s t e a d t h e y i n c r e m e n t t h e i r X a n d Y c o m p o n e n t s b y l o g i c a l u n i t s ( 0 . 2 5 4 m m , 0 . 1 m m , a n d s o f o r t h ) . F i g u r e 10.5 s h o w s a m e t r i c mapping mode.
Metric Mapping
Modes
+x
-y
Figure
10.5. A metric mapping mode.
T o set a M M _ L 0 E N G L I S H m e t r i c m a p p i n g m o d e , f o r e x a m p l e , SetMapMode: SetMapMode(DC,
use
MM_L0ENGLISH)
N o t i c e that if y o u u s e a m e t r i c m a p p i n g m o d e , a n y t h i n g y o u d i s p l a y i n t h e c l i e n t a r e a m u s t b e l o c a t e d u s i n g n e g a t i v e v a l u e s o f Y . N o t spifiy. Y o u p r o b a b l y w a n t t o t h i n k i n b o t h p o s i t i v e X a n d Y . F o r t u n a t e l y , W i n d o w s offers a s o l u t i o n : y o u c a n c h a n g e the "logical" origin o f the client area u s i n g the W i n d o w s function S e t V i e w p o r t O r g and S e l e c t C l i p R g n :
317
318
Part I I — A d v a n c e d T o p i c s
SetView(ADCHandle,ClientX/2,ClientY/2); SelectClipRgn(ADCHandle,AClipregion); w h i c h c h a n g e s the coordinate system t o l o o k like figure 10.6.
Resetting the Viewport Origin
Figure
10.6. The result of changing from the "logical" origin.
Listing 10.2 s h o w s a little a p p l i c a t i o n that shirts t h e o r i g i n f r o m t h e u p p e r left t o t h e u p p e r - r i g h t c o r n e r o f t h e c l i e n t w i n d o w i n r e s p o n s e t o a m e n u i t e m selection. T h e key m e n u - r e s p o n s e m e t h o d s are CMUpperLef t , w h i c h uses the default upper-left origin: procedure MoveOriginWindow.CMUpperLeft(var begin
Msg: TMessage);
DragDC := GetDC(HWindow); SetMapMode(DragDC,MM_TEXT); { U s e MM_TEXT mode } StrLCopy(S,'Hello',Size0f(S) - 1); TextOut(DragDC,10,20,S,SizeOf(S)); ReleaseDC(HWindow,DragDC); end; and CMUpperRight, which moves the origin to the upper-right corner o f the client w i n d o w : procedure MoveOriginWindow.CMUpperRight(var begin DragDC := GetDC(HWindow); SetMapMode(DragDC,MM_TEXT);
Msg: TMessage);
{ S e t map mode }
10—Display Contexts and Drawing Tools
SetViewportOrg(DragDC,Attr.W,0); StrLCopy(S,'Hello',SizeOf(S) - 1); TextOut(DragDC,-60,20,S,SizeOf(S)); ReleaseDC(HWindow,DragDC);
{ Shift origin } { Note -X coordinate }
end; Y o u d o n o t have to e x p l i c i t l y set t h e MM_TEXT m a p p i n g m o d e b e c a u s e it is t h e d e f a u l t . It is d o n e here f o r c o m p l e t e n e s s . Listing
10.2.
Setting
the MM_ TEXT mapping
mode.
program MoveOrigin; uses Strings, WinTypes, WinProcs, WObjects; {$R Pen.Res }{Pen resource is just used for convenience} const cm_Upperl_ef t cmJJpperRight
= 401; = 402;
type MoveOriginApplication = object(TApplication) procedure InitMainWindow; virtual; end; PMoveOriginWindow = "MoveOriginWindow; MoveOriginWindow = object(TWindow) S : array[0..5] of Char; DragDC: HDC; constructor Init(AParent: PWindowsObject; ATitle: PChar); destructor Done; virtual; procedure CMUpperLeft(var Msg: TMessage); virtual cm_First + cm_UpperLeft; procedure CMUpperRight(var Msg: TMessage); virtual cm_First + cmJJpperRight; end; { { MoveOriginWindow's method implementations:
} }
{
} continues
319
320
Part I I — A d v a n c e d T o p i c s
Listing
10.2.
continued
constructor MoveOriginWindow.Init (AParent: PWindowsObject; ATitle: PChar); begin TWindow.Init(AParent, ATitle); Attr.Menu := LoadMenu(HInstance, PChar(109)); DisableAutoCreate; Attr.Style := ws_PopupWindow or ws_Caption or ws_Visible; Attr.X Attr.Y Attr.W Attr.H
:= := := :=
50; 50; 200; 200;
end; destructor MoveOriginWindow.Done; begin TWindow.Done; end; procedure MoveOriginWindow.CMUpperLeft(var Msg: TMessage); begin DragDC := GetDC(HWindow); SetMapMode(DragDC,MM_TEXT); { Use MM_TEXT mode } StrLCopy(S,'Hello',SizeOf(S) - 1); TextOut(DragDC,10,20,S,SizeOf(S)); ReleaseDC(HWindow,DragDC); end; procedure MoveOriginWindow.CMUpperRight(var begin DragDC := GetDC(HWindow); SetMapMode(DragDC,MM_TEXT); { SetViewportOrg(DragDC,Attr.W,0); { StrLCopy(S,'Hello',SizeOf(S) - 1); TextOut(DragDC,-60,20,S,SizeOf(S)); { ReleaseDC(HWindow,DragDC); end;
Msg: TMessage);
Set map mode } Shift origin } Note -X coordinate }
{ { MoveOriginApplication s method implementations:
} }
{
}
1
10—Display Contexts and Drawing Tools
procedure MoveOriginApplication.InitMainWindow; begin MainWindow := New(PMoveOriginWindow, Init(nil, 'Origin Window')); end; { { Main program:
} }
{
}
var App : MoveOriginApplication; begin App.Init('MoveOriginProgram'); App.Run; App.Done; end. F i g u r e 1 0 . 7 s h o w s t h e resulting
Figure
10.7. The result of listing
10.2.
text d i s p l a y .
321
322
Part I I — A d v a n c e d T o p i c s
Drawing Figures W i n d o w s h a s a r i c h , b u i l t - i n set o f t o o l s f o r d r a w i n g l i n e s a n d v a r i o u s s h a p e s ; including lines, circles, ellipses, rectangles, r o u n d rectangles, chords, pies, polygons, and poly polygons. Y o u can draw these figures individually or in c o m b i n a t i o n . T o draw any figure, y o u r application uses a p e n , either the default p e n (BLACKPEN) or a c u s t o m p e n that y o u r a p p l i c a t i o n c r e a t e s . F o r e x a m p l e , t h e little e x a m p l e i n listing 10.3 s h o w s h o w t o c r e a t e a n a p p l i c a t i o n that r e s p o n d s t o u s e r m e n u - i t e m s e l e c t i o n s b y d r a w i n g e i t h e r a r e c t a n g l e , a filled r e c t a n g l e , o r a n e l l i p s e i n a D a s h D o t p e n style. It c r e a t e s t h e p e n , retrieves a d i s p l a y c o n t e x t , selects t h e p e n , d r a w s t h e figure, r e l e a s e s t h e display context, and deletes the object using m e n u - c o m m a n d messageresponse methods. N o t i c e that filling a r e c t a n g l e is s o m e w h a t d i f f e r e n t t h a n s i m p l y d r a w i n g t h e r e c t a n g l e . T h e k e y d i f f e r e n c e lies i n t h e d r a w i n g t o o l y o u u s e t o p r o d u c e t h e r e c t a n g l e . W h e n y o u d r a w a r e c t a n g l e , y o u u s e a p e n . W h e n y o u d r a w a n d fill a r e c t a n g l e , y o u u s e a b r u s h that c a n b e e i t h e r a s t o c k o b j e c t ( s u c h as a GRAY_BRUSH) o r a b r u s h b a s e d o n a bit m a p . T h e C M F i l l e d R e c t a n g l e m e t h o d i n listing 10.3 u s e s a s t o c k b r u s h : procedure FigsWindow.CMGrayFilledRectangle(var begin SetCapture(HWindow); DragDC := GetDC(HWindow);
Msg:
TMessage);
SelectObject(DragDC, GetStockObject(GRAY_BRUSH)); Rectangle(DragDC,20,20,200,200); ReleaseCapture; ReleaseDC(HWindow, DragDC); end; W i n d o w s provides seven stock brushes and three stock pens, which y o u c a n u s e effectively t o c r e a t e filled figures. T a b l e 10.4 s h o w s t h e s t o c k d r a w i n g tools you can use with the G e t S t o c k O b j e c t function. Table
10.4.
Windows
stock
drawing
Constant
Brush/Pen
Type
BlackBrush
Black brush
DkGrayBrush
D a r k gray b r u s h
GrayBrush
Gray brush
HollowBrush
Hollow brush
LtGrayBrush
Light gray b r u s h
tools.
10—Display Contexts and Drawing Tools
Constant
Brush/Pen
NullBrush
Null brush
WhiteBrush
White
BlackPen
Black p e n
NullPen
Null pen
White
White
Pen
Type
brush
pen
T h e f o l l o w i n g r e s p o n s e m e t h o d s h o w s h o w t o c r e a t e a n d select a h a t c h e d b r u s h , w h i c h is t h e n u s e d t o fill a r e c t a n g l e . N o t i c e that t h e b r u s h n e e d s t o b e d e l e t e d w h e n y o u are d o n e w i t h it:
procedure FigsWindow.CMHatchedRectangle(var Msg: TMessage); begin SetCapture(HWindow); DragDC := GetDC(HWindow); TheBrush := CreateHatchBrush(hs_Vertical, RGB(0,255,0)); SelectObject(DragDC,TheBrush); Rectangle(DragDC,20,20,200,200); DeleteObject(TheBrush); ReleaseCapture; ReleaseDC(HWindow, DragDC); end;
Listing
103-
A figure-drawing
and
-filling
program.
program Figs; uses Strings, WinTypes, WinProcs, WObjects, WIF5, { Basic Interface } StdDlgs;
{$R FIGS.RES }
const cm_Rectangle cm_Ellipse
= 401; = 402; continues
323
324
Part I I — A d v a n c e d T o p i c s
Listing
10.3-
continued
cm_GrayFilledRectangle cmJHatchedRectangle
= 403; = 404;
type FigsApplication = object(BasicApplication) procedure InitMainWindow; virtual; end; PFigsWindow = "FigsWindow; FigsWindow = object(MainWindow) DragDC: HDC; TheBrush: HBrush; ThePen: HPen; PenSize: Integer; PenStyle: Integer; constructor Init(AParent: PWindowsObject; ATitle: PChar); destructor Done; virtual; procedure CMRectangle(var Msg: TMessage); virtual cm_First + cm_Rectangle; procedure CMGrayFilledRectangle(var Msg: TMessage); virtual cm_First + cm_GrayFilledRectangle; procedure CMHatchedRectangle(var Msg: TMessage); virtual cm_First + cm_HatchedRectangle; procedure CMEllipse(var Msg: TMessage); virtual cm_First + cm_Ellipse; end; { { FigsWindow s method implementations:
} }
{
}
1
constructor FigsWindow.Init(AParent: PWindowsObject; ATitle: PChar); begin TWindow.Init(AParent, ATitle); Attr.Menu := LoadMenu(HInstance, PChar(109)); PenSize := 1; PenStyle := ps_DashDot; ThePen := CreatePen(PenStyle, PenSize, 0); end; destructor FigsWindow.Done; begin DeleteObject(ThePen);
10—Display Contexts and Drawing Tools
325
TWindow.Done; end; procedure FigsWindow.CMRectangle(var Msg: TMessage); begin SetCapture(HWindow); DragDC := GetDC(HWindow); SelectObject(DragDC, ThePen); Rectangle(DragDC,20,20,200,200); ReleaseCapture; ReleaseDC(HWindow, DragDC); end; procedure FigsWindow.CMGrayFilledRectangle(var Msg: TMessage); begin SetCapture(HWindow); DragDC := GetDC(HWindow); SelectObj ect(DragDC, GetStockObj ect(GRAY_BRUSH)); Rectangle(DragDC,20,20,200,200); ReleaseCapture; ReleaseDC(HWindow, DragDC); end; procedure FigsWindow.CMHatchedRectangle(var Msg: TMessage); begin SetCapture(HWindow); DragDC := GetDC(HWindow); TheBrush := CreateHatchBrush(hs_Vertical, RGB(0,255,0)); SelectObject(DragDC,TheBrush); Rectangle(DragDC,20,20,200,200); DeleteObject(TheBrush); ReleaseCapture; ReleaseDC(HWindow, DragDC); end; procedure FigsWindow.CMEllipse(var Msg: TMessage); begin SetCapture(HWindow); DragDC := GetDC(HWindow); SelectObject(DragDC, ThePen); Ellipse(DragDC,20,20,200,200); ReleaseCapture; ReleaseDC(HWindow, DragDC); end; continues
326
Part I I — A d v a n c e d T o p i c s
Listing
10.3-
continued
{
}
{ FigsApplication s 1
method implementations:
}
{
}
procedure FigsApplication.InitMainWindow; begin MainWindow := New(PFigsWindow, Init(nil, end;
'Drawing
Window'));
{ { Main program:
} }
{
}
var App
: FigsApplication;
begin App.Init('FigsProgram'); App.Run; App.Done; end. Figure 10.8, 10.9 a n d 10.10 s h o w several o f t h e s h a p e s created b y t h e display: a gray-filled rectangle, a gray-filled rectangle w i t h a n e l l i p s e inside it, a n d a hatched rectangle.
Figure
10.8. A gray-filled
rectangle.
10—Display Contexts and Drawing Tools
A Stranger Graphics Function Demo T o illustrate h o w s o m e o f t h e s e f u n c t i o n s w o r k , u s e a m e n u t o s e l e c t v a r i o u s drawing functions (MoveToLineTo, S p l o t c h , S t r a n g e A r c s , S t r a n g e P i e s , a n d R o u n d R e c t ) that u t i l i z e m a n y o f t h e W i n d o w s p r i m i t i v e g r a p h i c s f u n c t i o n s for drawing lines, arcs, pies, a n d so o n .
Figure
10.9. A gray-filled
Figure
10.10. A hatched
rectangle with an
rectangle.
ellipse.
327
328
Part I I — A d v a n c e d T o p i c s
E a c h d r a w i n g f u n c t i o n d i s p l a y s i n its o w n w i n d o w . B y u s i n g o n e w i n d o w per function, y o u can maintain many drawings simultaneously, switching b e t w e e n t h e m . E a c h w i n d o w c o n s t r u c t s itself, m a i n t a i n s d a t a fields s p e c i f i c t o it, a n d h a s its o w n Paint p r o c e d u r e f o r u p d a t i n g its d i s p l a y . T h e splotch w i n d o w l o o k s like this:
type PSplotchWindow = "SplotchWindow; SplotchWindow = object(TWindow) Points: array[0..MaxPoints] of APoint; constructor Init(AParent: PWindowsObject; ATitle: PChar); procedure Paint(PaintDC: HDC; var Paintlnfo: TPaintStruct); virtual; end; A r o u n d r e c t a n g l e w i n d o w l o o k s similar:
type PRRectangleWindow = "RRectangleWindow; RRectangleWindow = object(TWindow) Points: array[0..MaxPoints] of APoint; constructor Init(AParent: PWindowsObject; ATitle: PChar); procedure Paint(PaintDC: HDC; var Paintlnfo: TPaintStruct); virtual; end; N o t i c e that n o n e o f t h e w i n d o w s that m a i n t a i n d r a w i n g s is t h e a p p l i c a t i o n ' s MainWindow. T h e a p p l i c a t i o n ' s MainWindow, as u s u a l , is c o n s t r u c t e d at start-up b y t h e Application ( o b j e c t ) :
type GDIExApp = object(TApplication) procedure InitMainWindow; virtual; end;
procedure GDIExApp.InitMainWindow; begin { Create a main window of type TGDIWindow. } MainWindow := New(PGDIExWindow, Init('GDI Example', LoadMenu(HInstance,MakeIntResource(MenuID)))); end; T h e GDIExApp's MainWindow, i n t u r n , m a i n t a i n s e a c h o f t h e d r a w i n g w i n d o w s as a c h i l d w i n d o w . B e c a u s e t h e MainWindow (GDIExWindow) m a i n tains a g r o u p o f c h i l d w i n d o w s , y o u c a n m a k e it e a s y t o m a i n t a i n t h e c h i l d r e n
by derivingGDIExWindowfrom TMDIWindow, t h e b a s e MDI W i n d o w (TMDIWindow),
10—Display Contexts and Drawing Tools
in O b j e c t W i n d o w s . R e c a l l f r o m C h a p t e r 7, " M a n y Windows: A M u l t i - D o c u m e n t I n t e r f a c e , " that a TMDIWindow a l r e a d y k n o w s how t o m a i n t a i n c h i l d w i n d o w s , w h i c h saves y o u t o n s o f w o r k . GDIExWindow l o o k s like this:
type PGDIExWindow = "GDIExWindow; GDIExWindow = object(TMDIWindow) procedure CMStrangeArcs(var Msg: TMessage); virtual cm_First + cm_StrangeArcs; procedure CMStrangePies(var Msg: TMessage); virtual cm_First + cm_StrangePies; procedure CMRoundRect(var Msg: TMessage); virtual cm_First + cm_RoundRect; procedure CMMoveToLineTo(var Msg: TMessage); virtual cm_First + cm_MoveToLineTo; procedure CMSplotch(var Msg: TMessage); virtual cm_First + cm_Splotch; procedure CMQuit(var Msg: TMessage); virtual cm_First + cm_Quit; procedure WMDestroy(var Msg: TMessage); virtual wm_First + wm_Destroy; end; It c o n s i s t s m o s t l y o f m e s s a g e - r e s p o n s e m e t h o d s f o r handling Windows m e s s a g e s a n d m e n u - c o m m a n d m e s s a g e s , w h i c h indicate that t h e u s e r has s e l e c t e d a d r a w i n g w i n d o w f o r display. H e r e are t h e c o r r e s p o n d i n g m e n u - c o m m a n d m e s s a g e c o n s t a n t s f o r
GDIExWindow: const MenuID cm_Quit cm_MoveToLineTo cm_Splotch cm_StrangeArcs cm_StrangePies cm_Roundrect
= = = = = = =
100; { Resource ID of the menu } 100; { File->Quit ID } 201; { Shapes } 202; 203; 204; 205;
T h e s e c o n s t a n t s c o r r e s p o n d t o t h e m e n u items in t h e resource file, G D I _ E X . R E S . Figure 10.11 shows a n aspect o f t h e creation a n d testing o f GDIJEX.RES. Notice the matching constants. I n response t o e a c h m e n u item s e l e c t i o n , t h e GDIExWindow m e n u response m e t h o d c o n s t r u c t s t h e c o r r e s p o n d i n g w i n d o w .
329
330
Part I I — A d v a n c e d T o p i c s
Figure
10.11.
An aspect of the creation and testing
ofGDI_EX.RES.
For example, a SplotchWindow: p r o c e d u r e G D I E x W i n d o w . C M S p l o t c h ( v a r Msg: T M e s s a g e ) ; begin Application".MakeWindow(New(PSplotchWindow, Init(@Self, 'Splotch Window'))); end; or a RoundRectWindow: procedure GDIExWindow.CMRoundRect(var begin
Msg:
TMessage);
Application".MakeWindow(New(PRRectangleWindow, 'Round R e c t a n g l e W i n d o w ' ) ) ) ; end;
Init(@Self,
T h e same applies for the other drawing w i n d o w s . Listing 10.4 c o n t a i n s t h e c o m p l e t e c o d e f o r t h e G D I e x a m p l e , a n d f i g u r e s 1 0 . 1 2 a n d 1 0 . 1 3 s h o w this MDI a p p l i c a t i o n r u n n i n g i n different s t a g e s .
N o t e : O n e particularly interesting a n d useful aspect o f the M D I o b j e c t s that c o m p o s e t h e M D I i n t e r f a c e is that M D I w i n d o w s are r e p a i n t e d a u t o m a t i c a l l y w h e n t h e y are u n c o v e r e d after b e i n g c o v e r e d , u n l i k e n o n - M D I w i n d o w s ( u n t i l y o u w r i t e Paint m e t h o d s for redisplay).
10—Display Contexts and Drawing Tools
Figure
10.12.
One stage of running the MDI application of listing 10.4.
Figure
10.13- Another stage during the MDI application
execution.
331
332
Part II—Advanced Topics
Listing
10.4.
A GDI
example.
program GDI_EX; uses WinProcs, WinTypes, WObjects, Strings; {$R GDI_EX.RES} { Menu bar constants } const MenuID = 100; { Resource ID of the menu } cm_Quit = 1 0 0 ; { File->Quit ID } cm_MoveToLineTo = 201; { Shapes } cm_Splotch = 202; cm_StrangeArcs = 203; cm_StrangePies = 204; cm_Roundrect = 205;
{ Shape constant } const MaxPoints
=
15; { Number of points to be drawn in MoveToLineToDemo }
{ Global function } function Min(X, Y: Integer): Integer; begin if X > Y then Min := Y else Min := X; end;
type APoint = record X, Y : Real; end; { NoIconWindow } type PNoIconWindow = "NoIconWindow;
10—Display Contexts and Drawing Tools
333
NoIconWindow = object(TWindow) procedure GetWindowClass(var AWndClass: TWndClass); virtual; function GetClassName: PChar; virtual; end; procedure NoIconWindow.GetWindowClass(var AWndClass: TWndClass); begin TWindow.GetWindowClass(AWndClass); AWndClass.hbrBackground := GetStockObject(Black_Brush); AWndClass.hlcon := 0; end; { No need to call the ancestor's method here, because you want to provide an entirely new window class name. } function NoIconWindow.GetClassName: PChar; begin GetClassName := 'NoIconWindow'; end; { Splotch window } type PSplotchWindow = "SplotchWindow; SplotchWindow = object(TWindow) Points: array[0..MaxPoints] of APoint; constructor Init(AParent: PWindowsObject; ATitle: PChar); procedure Paint(PaintDC: HDC; var Paintlnfo: TPaintStruct); virtual; end; constructor SplotchWindow.Init(AParent: PWindowsObject; ATitle: PChar); var I: Integer; StepAngle: Integer; Radians: Real; begin TWindow.Init(AParent, ATitle); StepAngle := 360 div MaxPoints; for I := 0 to MaxPoints - 1 do begin Radians := (StepAngle * I) * PI / 180; Points[I].x := Cos(Radians); continues
334
Part I I — A d v a n c e d T o p i c s
Listing
10.4.
continued
Points[I].y := Sin(Radians); end; end; procedure SplotchWindow.Paint(PaintDC: HDC; var Paintlnfo: TPaintStruct); var TheRect: TRect; I, J: Integer; CenterX, CenterY: Integer; Radius, StepAngle: Word; Radians: real; begin GetClientRect(HWindow,TheRect); { Get the client window's coordinates } CenterX := TheRect.Right div 2; CenterY := TheRect.Bottom div 2; Radius := Min(CenterY, CenterX); Rectangle(PaintDC,CenterX - Radius, CenterY - Radius, CenterX + Radius, CenterY + Radius); for I := 0 to MaxPoints - 1 do begin for J := I + 1 to MaxPoints - 1 do begin MoveTo(PaintDC, CenterX + Round(Points[I].X / Radius * Radius), CenterY + Round(Points[I].Y / Radius *Radius)); LineTo(PaintDC, CenterX + Round(Points[J].X * Radius), CenterY + Round(Points[J].Y * Radius)); end; end; end; { End splotch window }
{ Round rectangle window } type PRRectangleWindow = "RRectangleWindow; RRectangleWindow = object(TWindow) Points: array[0..MaxPoints] of APoint;
10—Display Contexts and Drawing Tools
335
constructor Init(AParent: PWindowsObject; ATitle: PChar); procedure Paint(PaintDC: HDC; var Paintlnfo: TPaintStruct); virtual; end; constructor RRectangleWindow.Init(AParent: PWindowsObject; ATitle: PChar); var I: Integer; StepAngle: Integer; Radians: Real; begin TWindow.Init(AParent, ATitle); StepAngle := 360 div MaxPoints; for I := 0 to MaxPoints - 1 do begin Radians := (StepAngle * I) * PI / 180; Points[I].x := Cos(Radians); Points[I].y := Sin(Radians); end; end; procedure RRectangleWindow.Paint(PaintDC: HDC; var Paintlnfo: TPaintStruct); var TheRect: TRect; I, J: Integer; CenterX, CenterY: Integer; Radius, StepAngle: Word; Radians: real; begin GetClientRect(HWindow,TheRect); { Get the client window's coordinates } CenterX := TheRect.Right div 2; CenterY := TheRect.Bottom div 2; Radius := Min(CenterY, CenterX); RoundRect(PaintDC,CenterX - Radius, CenterY - Radius, CenterX + Radius, CenterY + Radius,9,11); for I := 0 to MaxPoints - 1 do begin for J := I + 1 to MaxPoints - 1 do continues
336
Part I I — A d v a n c e d T o p i c s
Listing
10A.
continued
begin MoveTo(PaintDC, CenterX + Round(Points[I].X / Radius * Radius), CenterY + Round(Points[I].Y / Radius * Radius)); RoundRect(PaintDC, CenterX + Round(Points[J].X * Radius), CenterY + Round(Points[J].Y * Radius),9,11,9,11); end; end; end; { End round rectangle } { Strange arcs window } type PStrangeArcsWindow = "StrangeArcsWindow; StrangeArcsWindow = object(TWindow) procedure Paint(PaintDC: HDC; var Paintlnfo: TPaintStruct); virtual; end; procedure StrangeArcsWindow.Paint(PaintDC: HDC; var Paintlnfo: TPaintStruct); var X, EndX : integer; begin For X := 1 to 400 do begin EndX := X + 50; Arc(PaintDC, X,15,EndX,250,50,0,0,0); end; end; { End strange arcs } { Strange pie window } type PStrangePiesWindow = "StrangePiesWindow; StrangePiesWindow = object(TWindow) procedure Paint(PaintDC: HDC; var Paintlnfo: end; TPaintStruct); virtual;
10—Display Contexts and Drawing Tools
procedure StrangePiesWindow.Paint(PaintDC: HDC; var Paintlnfo: TPaintStruct); var X, EndX : integer; begin For X := 1 to 400 do begin EndX := X + 50; Pie(PaintDC, X,15,EndX,250,50,0,0,0); end; end; { End strange pies }
{ MoveToLineToWindow
}
type PMoveToLineToWindow = "MoveToLineToWindow; MoveToLineToWindow = object(TWindow) Points: array[0..MaxPoints] of APoint; constructor Init(AParent: PWindowsObject; ATitle: PChar); procedure Paint(PaintDC: HDC; var Paintlnfo: TPaintStruct); virtual; end; constructor MoveToLineToWindow.Init(AParent: PWindowsObject; ATitle: PChar); var I: Integer; StepAngle: Integer; Radians: Real; begin TWindow.Init(AParent, ATitle); StepAngle := 360 div MaxPoints; for I := 0 to MaxPoints - 1 do begin Radians := (StepAngle * I) * PI / 180; Points[I].x := Cos(Radians); Points[I].y := Sin(Radians); end; end; continues
337
338
Part I I — A d v a n c e d T o p i c s
Listing
10.4.
continued
procedure MoveToLinetoWindow.Paint(PaintDC: HDC; var Paintlnfo: TPaintStruct); var TheRect: TRect; I, J: Integer; CenterX, CenterY: Integer; Radius, StepAngle: Word; Radians: real; begin GetClientRect(HWindow,TheRect); CenterX := TheRect.Right div 2; CenterY := TheRect.Bottom div 2; Radius := Min(CenterY, CenterX); Ellipse(PaintDC,CenterX - Radius, CenterY - Radius, CenterX + Radius, CenterY + Radius); for I := 0 to MaxPoints - 1 do begin for J := I + 1 to MaxPoints - 1 do begin MoveTo(PaintDC, CenterX + Round(Points[I].X * Radius), CenterY + Round(Points[I].Y * Radius)); LineTo(PaintDC, CenterX + Round(Points[J].X * Radius), CenterY + Round(Points[J],Y * Radius)); end; end; end; { GDIExWindow type PGDIExWindow = "GDIExWindow; GDIExWindow = object(TMDIWindow) procedure CMStrangeArcs(var Msg: TMessage); virtual cm_First + cm_StrangeArcs; procedure CMStrangePies(var Msg: TMessage); virtual cm_First + cm_StrangePies; procedure CMRoundRect(var Msg: TMessage); virtual cm_First + cm_RoundRect; procedure CMMoveToLineTo(var Msg: TMessage); virtual cm_First + cm_MoveToLineTo;
}
10—Display Contexts and Drawing Tools
procedure CMSplotch(var Msg: TMessage); virtual cm_First + cm_Splotch; procedure CMQuit(var Msg: TMessage); virtual cm_First + cm_Quit; procedure WMDestroy(var Msg: TMessage); virtual wm_First + wm_Destroy; end; procedure GDIExWindow.CMMoveToLineTo(var Msg: TMessage); begin Application".MakeWindow(New(PMoveToLineToWindow, Init(@Self, 'MoveTo/LineTo Window'))); end; procedure GDIExWindow.CMSplotch(var Msg: TMessage); begin Application".MakeWindow(New(PSplotchWindow, Init(@Self, 'Splotch Window'))); end; procedure GDIExWindow.CMRoundRect(var Msg: TMessage); begin Application".MakeWindow(New(PRRectangleWindow, Init(@Self, 'Round Rectangle Window ))); end; 1
procedure GDIExWindow.CMStrangeArcs(var Msg: TMessage); begin Application".MakeWindow(New(PStrangeArcsWindow, Init(@Self, 'Strange Arcs Window'))); end; procedure GDIExWindow.CMStrangePies(var Msg: TMessage); begin Application".MakeWindow(New(PStrangePiesWindow, Init(@Self, 'Strange Pie Window'))); end;
procedure GDIExWindow.CMQuit(var Msg: TMessage); begin CloseWindow; end; continues
339
340
Part I I — A d v a n c e d T o p i c s
Listing
10.4.
continued
procedure GDIExWindow.WMDestroy(var begin TMDIWindow.WMDestroy(Msg); end;
Msg: TMessage);
{ GDIExApp
}
type GDIExApp = object(TApplication) procedure InitMainWindow; end;
virtual;
procedure GDIExApp.InitMainWindow; begin { Create a main window of type GDIExWindow. } MainWindow := New(PGDIExWindow, Init('GDI Example , LoadMenu(HInstance,MakeIntResource(MenuID)))); end; 1
var ExApp: GDIExApp; begin ExApp.Init('GDIExample ) ; ExApp.Run; ExApp.Done; end. 1
Wrap-up T h e g r a p h i c s p o s s i b i l i t i e s w i t h t h e W i n d o w s G D I a r e virtually e n d l e s s ( p l e a s e e x c u s e t h e p u n ) . Y o u c a n c r e a t e d r a w i n g s a n d s h a p e s o f a l m o s t every k i n d , a n d , w i t h a bit o f effort, c r e a t e s o p h i s t i c a t e d g r a p h i c s a p p l i c a t i o n s that u t i l i z e v a r i o u s f o n t s , i c o n s , c u r s o r s , bit m a p s , a n d t h e l i k e . Y o u c a n c r e a t e this m y r i a d o f s h a p e s o n a n y d e v i c e s u p p o r t e d b y W i n d o w s without writing c o d e for a specific device. A l t h o u g h y o u might s p e n d s o m e time learning the ins a n d outs o f W i n d o w s functions, y o u are m o r e than c o m p e n s a t e d w h e n y o u d o n o t h a v e t o w r i t e d e v i c e drivers o r d e v i c e - s p e c i f i c c o d e . W i n d o w s is i n d e e d t h e m o s t u n i v e r s a l i n t e r f a c e t o c o m e d o w n t h e D O S p i k e , a n d it b e c o m e s m o r e u s e f u l a n d m o r e p o w e r f u l as y o u l e a r n m o r e a b o u t it.
10—Display Contexts and Drawing Tools
For additional information about G D I definitions, functions, and the ObjectGraphics T o o l b o x (from the Whitewater G r o u p ) , check the reference s e c t i o n i n t h e s e c o n d h a l f o f this b o o k .
341
11 CHAPTER
FROM PROGRAM TO PROGRAM USING DDE (DYNAMIC DATA EXCHANGE) As I look across my desk to the "computer museum" in the corner of my office, I can see the progress hardware has made in the past decade. We 've gone from 64KZ80 CP/M machines like the Osborne I that ran Ron Cain's Small-C and Turbo Pascal 1.0 (and had room to spare!), to my new four-megabyte 386SX that runs Turbo C+ + and Turbo Pascal 6.0. And I'm not at all surprised by the fact that the Osborne cost more than the 386. Zack Urlocker
O n e o f t h e m o s t a m a z i n g a n d u s e f u l f e a t u r e s o f M i c r o s o f t W i n d o w s is its facility f o r l e t t i n g a p p l i c a t i o n s s h a r e d a t a . W i n d o w s a c c o m p l i s h e s this d a t a - s h a r i n g t h r o u g h a p r o t o c o l c a l l e d D D E ( d y n a m i c d a t a e x c h a n g e ) . T u r b o Pascal f o r W i n d o w s compiles D D E b e t w e e n applications—those y o u write a n d even t h o s e y o u d o n ' t w r i t e y o u r s e l f — r e a d i l y a c c e s s i b l e at a h i g h l e v e l . In general, to e x c h a n g e data with other applications a n d programs through D D E , y o u have to learn: • T h e W i n d o w s m e s s a g e s (wm_pref ixed) that u s e D D E • H o w to use global m e m o r y to buffer the data e x c h a n g e
344
Part I I — A d v a n c e d T o p i c s
This chapter explains h o w D D E works with examples, including exchanges with the Clipboard and the Windows Program Manager. Although e x c h a n g e s w i t h t h e c l i p b o a r d a r e n o t " t e c h n i c a l l y " part o f D D E b e c a u s e y o u d o not send D D E messages to access the clipboard, the chapter l u m p s together the e x c h a n g e o f c l i p b o a r d a n d D D E d a t a . C a l l t h e l u m p s o m e t h i n g like " W i n d o w s global data e x c h a n g e " because both the clipboard a n d D D E require the u s e o f global m e m o r y buffers. Y o u a l s o c a n " l u m p " D D E a n d D L L b e c a u s e t h e y are c o n c e p t u a l l y similar. T h e y differ significantly, h o w e v e r , i n that D D E is t h e s h a r i n g o f d a t a b e t w e e n a p p l i c a t i o n s , a n d D L L is t h e s h a r i n g o f c o d e . Y o u r a p p l i c a t i o n s s h a r e c o d e b y s t o r i n g it i n d y n a m i c l i n k a b l e libraries. T h e capability t o share data a n d c o d e has m a n y advantages a n d possibilities. S h a r i n g r e d u c e s m e m o r y u s e ( b e c a u s e a s i n g l e c o p y , r a t h e r t h a n t w o o r m o r e c o p i e s , o f a s e g m e n t o f c o d e o r d a t a saves s p a c e ) . A l s o , b y s h a r i n g d a t a i n real t i m e , y o u r a p p l i c a t i o n s c a n save t i m e a n d interact s e n s i b l y w i t h e a c h o t h e r . Applications using either the clipboard o r D D E c a n r e s p o n d to each other immediately, thus leading to a future o f independently developed programs that d e p e n d o n t h e o u t p u t f r o m e a c h o t h e r . This chapter focuses o n data e x c h a n g e s b e t w e e n T u r b o Pascal for W i n d o w s applications a n d the clipboard a n d between applications using D D E . C h a p t e r 12 c o v e r s D L L .
The Clipboard T h e s i m p l e s t w a y f o r y o u r a p p l i c a t i o n s t o e x c h a n g e d a t a is w i t h t h e c l i p b o a r d . A l t h o u g h y o u m i g h t t h i n k o f t h e c l i p b o a r d as t h e C l i p b o a r d p r o g r a m p a c k a g e d w i t h W i n d o w s , it isn't. T h e C l i p b o a r d is a c l i p b o a r d v i e w e r y o u u s e t o d i s p l a y a n d m a n i p u l a t e t h e c u r r e n t c o n t e n t s o f t h e c l i p b o a r d . T h e c l i p b o a r d , p e r s e , is a f u n c t i o n a l W i n d o w s u n i t y o u u s e t o e x c h a n g e d a t a b e t w e e n p r o g r a m s . It i s , i n fact, invisible u n l e s s y o u c h o o s e t o " v i e w " it. W h e n y o u r applications are using the O p e n , C l o s e , Write t o , a n d Read c o m m a n d s f r o m t h e c l i p b o a r d , t h e y are " c o n v e r s i n g " w i t h t h e c l i p b o a r d u n i t — not t h e C l i p b o a r d p r o g r a m . If y o u w a n t t o see t h e actual e x c h a n g e o f data b e t w e e n y o u r a p p l i c a t i o n s that u s e t h e c l i p b o a r d , o p e n t h e C l i p b o a r d p r o g r a m . Figure 11.1 shows a C l i p b o a r d p r o g r a m "view" o f a data e x c h a n g e b e t w e e n a T u r b o P a s c a l f o r W i n d o w s a p p l i c a t i o n (details a n d c o d e a r e d e s c r i b e d later i n this s e c t i o n ) . M a n y o f the W i n d o w s applications are u s e d t o cut, copy, a n d paste data t o a n d f r o m t h e c l i p b o a r d . T h e O b j e c t W i n d o w s ' E d i t c o n t r o l , EditWindow, a n d FileWindow o b j e c t s , w h i c h y o u h a v e a l r e a d y u s e d , a c c e s s t h e c l i p b o a r d through these m e n u c o m m a n d s .
1 1 — F r o m Program to Program Using D D E
Figure
11.1. "View" of a data exchange.
"Hello" is pasted at various mouse
locations.
T h e C l i p b o a r d c a n a c c e p t a variety o f d a t a f o r m a t s : text, bit m a p s , s y m b o l i c l i n k f o r m a t t e d d a t a , tiff f o r m a t , a n d m e t a f i l e p i c t u r e f o r m a t . T a b l e 11.1 s h o w s the clipboard format a n d the associated data. Table
11.1.
Clipboard
format
and associated
data.
Format
Format
Explanation
cf_Text
N u l l - t e r m i n a t e d array o f c h a r a c t e r s
cfBitmap
W i n d o w s ' bit m a p f o r m a t
cfSylk
Microsoft symbolic link format
cfTiff
T a g i m a g e file f o r m a t
cfMetafilePict
W i n d o w s metafile picture format
T h e s e c l i p b o a r d f o r m a t s are m o r e o r less i n d u s t r y s t a n d a r d s , w h i c h m a n y applications recognize. T h u s , by using o n e or m o r e of these formats to p u t data i n t h e c l i p b o a r d , y o u c a n s e n d d a t a t o a n y a p p l i c a t i o n that c a n interact w i t h t h e clipboard. T o place data in the Clipboard: 1. O p e n t h e c l i p b o a r d ( u s i n g t h e W i n d o w s f u n c t i o n OpenClipboard). 2. E m p t y t h e c l i p b o a r d ( u s i n g EmptyClipboard).
345
346
Part II-—Advanced T o p i c s
3. S e t a d a t a h a n d l e t o t h e c l i p b o a r d (SetClipboardData). 4. C l o s e t h e c l i p b o a r d (CloseClipboard). T o o p e n the clipboard, use OpenClipboard(HWindow); w h e r e HWindow is a w i n d o w h a n d l e a s s o c i a t e d w i t h t h e w i n d o w that w a n t s contact with the clipboard. EmptyClipboard e m p t i e s t h e c l i p b o a r d a n d frees a n y h a n d l e s t o d a t a i n t h e c l i p b o a r d , a s s i g n i n g o w n e r s h i p t o t h e w i n d o w ( d e s i g n a t e d b y HWindow) that o p e n e d t h e c l i p b o a r d : EmptyClipboard;
N o t e : A l l t h e i n f o r m a t i o n r e s e a r c h e d f o r this b o o k that refers t o t h e c l i p b o a r d d e s i g n a t e s that y o u m u s t u s e EmptyClipboard before y o u copy data to the clipboard. Various experiments s u g g e s t that e m p t y i n g t h e c l i p b o a r d isn't a b s o l u t e l y n e c e s s a r y . F o r e x a m p l e , if y o u o m i t EmptyClipboard f r o m t h e c o d e i n listing 1 1 . 1 , t h e d a t a e x c h a n g e b e t w e e n t h e T u r b o Pascal f o r W i n d o w s a p p l i c a t i o n a n d t h e c l i p b o a r d still w o r k s .
SetClipboardData r e q u i r e s t w o p a r a m e t e r s : a cf _ clipboard c o n s t a n t that s p e c i f i e s t h e f o r m a t of t h e d a t a t o b e c o p i e d t o t h e c l i p b o a r d a n d a h a n d l e t o a g l o b a l m e m o r y b l o c k that c o n t a i n s t h e d a t a t o b e c o p i e d . F o r e x a m p l e : SetClipboardData(cf_Text,AStringGlobalHandle); R e c a l l f r o m C h a p t e r 9 , " M e m o r y M a t t e r s , " that a g l o b a l m e m o r y b l o c k is a special kind o f system-wide m e m o r y shared by W i n d o w s applications. Y o u r application c a n create these global m e m o r y blocks in the W i n d o w s global h e a p , and Windows can manage them. In general, an application does not have to use g l o b a l m e m o r y b l o c k s ; u s u a l l y it's a m a t t e r o f c h o i c e ( s e e C h a p t e r 9 f o r a discussion o f global versus local m e m o r y ) . Applications using the clipboard, however, must use global memory. T o a d d c l i p b o a r d - a c c e s s c a p a b i l i t y t o a w i n d o w , you d e r i v e a n e w w i n d o w ( c a l l e d ClipWindow) f r o m MainWindow a n d a d d a CopyText f e a t u r e . First, d e r i v e a n e w application: ClipApp = object(BasicApplication) BasicApplication }
{ ModelApp=a kind of
procedure InitMainWindow; virtual; { Init a specific MainWindow } end;
1 1 — F r o m Program to Program Using D D E
N e x t , a d d a n e w m a i n w i n d o w that c a n interact w i t h t h e C l i p b o a r d :
PClipWindow = "ClipWindow; ClipWindow = object(MainWindow) constructor Init(AParent : PWindowsObject; ATitle : PChar); procedure CMCopyText(var Msg: TMessage); virtual cm_First + cm_CopyText; function CopyText(Txt: PChar): boolean; end; ClipWindow h a s t w o k e y m e t h o d s : 1. CMCopyText r e s p o n d s t o t h e m e n u - c o m m a n d m e s s a g e (cm_CopyText). 2. CopyText a c t u a l l y h a n d l e s t h e c o p y i n g o f text t o t h e c l i p b o a r d .
cm_CopyText is a c o n s t a n t :
const cm_CopyText = 501; is d e f i n e d i n t h e m e n u r e s o u r c e i n W I F 1 0 6 :
{$R ....} CMCopyText r e s p o n d s t o t h e cm_CopyText m e s s a g e b y c o p y i n g a string ( " H e l l o " ) t o a n u l l - t e r m i n a t e d string (S). Recall that w h e n e v e r y o u p a s s strings t o W i n d o w s f u n c t i o n s t h e y m u s t b e a PCh a r t y p e (a p o i n t e r t o a n u l l - t e r m i n a t e d s t r i n g ) . T h e n t h e string s e n d s a m e s s a g e t o CopyText a n d p a s s e s it t o t h e string to copy to the clipboard:
procedure ClipWindow.CMCopyText(var Msg: TMessage); var Stat : boolean; S : array[0..15] of char; begin StrCopy(S,'Hello'); Stat := CopyText(S); end; CopyText t h e n sets a g l o b a l m e m o r y h a n d l e , c o p i e s t h e s t r i n g t o g l o b a l m e m o r y , o p e n s a n d e m p t i e s t h e c l i p b o a r d , sets t h e c l i p b o a r d d a t a , a n d c l o s e s the clipboard:
function ClipWindow.CopyText(Txt: PChar): boolean; var AStrGlobalHandle: THandle; AStrGlobalPtr: PChar;
347
348
Part I I — A d v a n c e d T o p i c s
begin CopyText := False; AStrGlobalHandle := GlobalAlloc(gmem_Moveable,StrLen(Txt) if AStrGlobalHandle <> 0 then begin AStrGlobalPtr := GlobalLock(AStrGlobalHandle); if AStrGlobalPtr <> nil then begin StrCopy(AStrGlobalPtr,Txt); GlobalUnlock(AStrGlobalHandle); OpenClipboard(HWindow); EmptyClipboard; SetClipboardData(cf_Text,AStrGlobalHandle); CloseClipboard; CopyText := True; GlobalFree(AStrGlobalHandle); end; end; end;
Pastingfromthe Clipboard P a s t i n g text f r o m t h e c l i p b o a r d i n t o y o u r a p p l i c a t i o n is o n l y slightly m o r e c o m p l i c a t e d t h a n c o p y i n g text t o t h e c l i p b o a r d . Listing
11.1.
Paste
text.
function ClipWindow.PasteText(TxtString: PChar; TxtSize:Integer): Integer; var AStrGlobalHandle: THandle; AStrGlobalPtr: PChar; AStrGlobalSize : Longint; begin PasteText := -1; OpenClipboard(HWindow); IsClipboardFormatAvailable(cf_Text); AStrGlobalHandle := GetClipboardData(cf_Text); if AStrGlobalHandle <> 0 then begin
+1);
11—From Program to Program Using D D E
AStrGlobalSize := GlobalSize(AStrGlobalHandle); AStrGlobalPtr := GlobalLock(AStrGlobalHandle); if AStrGlobalPtr <> nil then begin if TxtSize < AStrGlobalSize then AStrGlobalSize := TxtSize; StrLCopy(TxtString,AStrGlobalPtr,AStrGlobalSize); GlobalUnlock(AStrGlobalHandle); PasteText := StrLen(TxtString); end; end; CloseClipboard; end; T h e e x a m p l e p r o g r a m i n listing 11.2 c o p i e s text t o t h e c l i p b o a r d a n d a l l o w s t h e u s e r t o p a s t e text f r o m t h e c l i p b o a r d t o a s p e c i f i c l o c a t i o n i n t h e w i n d o w . T h e l o c a t i o n is d e t e r m i n e d b y c l i c k i n g t h e m o u s e . Listing
11.2.
Pasting
text from
clipboard
to the
window.
unit ClipWnd; interface uses WObjects, WinTypes, WinProcs, strings, WIF5;
{ Basic Interface }
{$R wif106.res} const cm_CopyText = 501; cm_PasteText = 502; type ClipApp = object(BasicApplication)
{ ModelApp=a kind of BasicApplication } procedure InitMainWindow; virtual; { Init a specific MainWindow } end; continues
349
350
Part I I — A d v a n c e d T o p i c s
Listing
11.2.
continued
PClipWindow = "ClipWindow; ClipWindow = object(MainWindow) Lo, Hi : Word; constructor Init(AParent : PWindowsObject; ATitle : PChar); procedure WMLButtonDown(var Msg: TMessage); virtual wm_First + wm_LButtonDown; procedure WMLButtonUp(var Msg: TMessage); virtual wm_First + wm_LButtonllp; procedure CMCopyText(var Msg: TMessage); virtual cm_First + cm_CopyText; procedure CMPasteText(var Msg: TMessage); virtual cm_First + cm_PasteText; function CopyText(Txt: PChar): boolean; function PasteText(TxtString: PChar; TxtSize: Integer): Integer; end;
implementation
procedure ClipApp.InitMainWindow; { Init a model application window } begin if FirstApplication then MainWindow := New(PClipWindow, Init(nil, 'Model Windows Interface')) else MainWindow := New(PClipWindow, Init(nil,'Additional Instance of MI')); end; constructor ClipWindow.Init(AParent : PWindowsObject; begin TWindow.Init(AParent, ATitle); { Send message to Attr.Menu := LoadMenu(HInstance, PChar(106)); { ButtonDown := False; { Set status flag end;
procedure ClipWindow.WMLButtonDown(var Msg: TMessage); begin if not ButtonDown then begin ButtonDown := True; SetCapture(HWindow);
ATitle: PChar); ancestor's constructor } 99 = menu ID } }
1 1 — F r o m Program to Program Using D D E
351
DC := GetDC(HWindow); end; end; procedure ClipWindow.WMLButtonUp(var Msg: TMessage); begin if ButtonDown then begin ButtonDown := False; { Determine mouse location } Lo := Msg.lParamLo; Hi := Msg.lParamHi; TextOut(DC,Lo,Hi, . ,1); { Put a dot at current mouse location } ReleaseCapture; ReleaseDC(HWindow,DC); end; end; 1
1
procedure ClipWindow.CMCopyText(var Msg: TMessage); var Stat : boolean; S : array[0..15] of char; begin StrCopy(S,'Hello'); Stat := CopyText(S); end;
procedure ClipWindow.CMPasteText(var Msg: TMessage); var Stat : integer; TxtStr: PChar; TxtSize: Integer; S : array[0..256] of Char; begin New(TxtStr); TxtSize := 256; Stat := PasteText(TxtStr, TxtSize); DC := GetDC(HWindow); TextOut(DC,Lo,Hi,TxtStr,Stat); { Paste to mouse location } ReleaseDC(HWindow,DC); end; continues
352
Part I I — A d v a n c e d T o p i c s
Listing
11.2.
continued
function ClipWindow.CopyText(Txt: PChar): boolean; var AStrGlobalHandle: THandle; AStrGlobalPtr: PChar; begin CopyText := False; AStrGlobalHandle := GlobalAlloc(gmem_Moveable, StrLen(Txt) + 1 ) ; if AStrGlobalHandle <> 0 then begin AStrGlobalPtr := GlobalLock(AStrGlobalHandle); if AStrGlobalPtr <> nil then begin StrCopy(AStrGlobalPtr,Txt); GlobalUnlock(AStrGlobalHandle); OpenClipboard(HWindow); EmptyClipboard; SetClipboardData(cf_Text,AStrGlobalHandle); CloseClipboard; CopyText := True; end; end;
function ClipWindow.PasteText(TxtString: Integer): Integer; var AStrGlobalHandle: THandle; AStrGlobalPtr: PChar; AStrGlobalSize : Longlnt;
PChar; TxtSize:
begin PasteText := -1; OpenClipboard(HWindow); IsClipboardFormatAvailable(cf_Text); AStrGlobalHandle := GetClipboardData(cf_Text); if AStrGlobalHandle <> 0 then begin AStrGlobalSize := GlobalSize(AStrGlobalHandle);
1 1 — F r o m Program to Program Using D D E
AStrGlobalPtr := GlobalLock(AStrGlobalHandle); if AStrGlobalPtr <> nil then begin if TxtSize < AStrGlobalSize then AStrGlobalSize := TxtSize; StrLCopy(TxtString,AStrGlobalPtr,AStrGlobalSize); GlobalUnlock(AStrGlobalHandle); PasteText := StrLen(TxtString); end; end; CloseClipboard; end;
end.
{ Unit clipwnd }
program Test_Clip;
{ A generic way to test each phase of interface development }
uses WIF5, clipwnd;
{ Basic Interface unit } { Contains ClipApp }
type App = object(ClipApp) end; var Application: App;
{ An instance of BasicApplication } { Run Applicationl }
begin Application.Init('Cliplnterface'); { Init application instance } Application.Run; { Message loop } Application.Done; { Destroy application instance } end.
Sharing Data Between Applications D y n a m i c d a t a e x c h a n g e ( D D E ) is a p r o t o c o l that e n a b l e s a p p l i c a t i o n s t o s h a r e data. Applications share data by way of a "conversation" in w h i c h they "post" m e s s a g e s t o e a c h o t h e r . T h e t w o a p p l i c a t i o n s s h a r i n g d a t a are c a l l e d t h e client
353
354
Part I I — A d v a n c e d T o p i c s
( w h o initiates t h e c o n v e r s a t i o n b y b r o a d c a s t i n g a D D E m e s s a g e ) a n d t h e server (who responds to the message). D D E l i n k s b e t w e e n a p p l i c a t i o n s a r e e i t h e r very c o l d , c o l d , h o t , o r w a r m , d e p e n d i n g o n t h e c o m p l e x i t y o f t h e link. A very cold l i n k is s i m p l e s t ; a c l i e n t b r o a d c a s t s a WM_DDE_INITIATE m e s s a g e i d e n t i f y i n g t h e a p p l i c a t i o n a n d t o p i c o f interest. A n y a p p l i c a t i o n ( p o t e n t i a l server) c a n r e s p o n d t o this m e s s a g e , a n d it is u p t o t h e c l i e n t w i n d o w t o t e r m i n a t e all servers e x c e p t t h e o n e it w a n t s . {Remember: use one window for each DDE link!) After t h e u n w a n t e d servers are t e r m i n a t e d , t h e c l i e n t s e n d s t h e d a t a t o t h e server. A cold l i n k is n e x t s i m p l e s t : a c l i e n t b r o a d c a s t s a WM_DDE_INITIATE m e s s a g e that i d e n t i f i e s t h e a p p l i c a t i o n a n d t h e a p p l i c a t i o n t o p i c it w a n t s . A n y p o t e n t i a l server w h o c a n r e s p o n d t o this a p p l i c a t i o n t o p i c r e s p o n d s t o t h e c l i e n t b y s e n d i n g a WM_DDE_ACK m e s s a g e . W h e n t h e c l i e n t d e t e r m i n e s a l i n k , it t e r m i n a t e s a n y o t h e r a c k n o w l e d g m e n t s o f its b r o a d c a s t m e s s a g e . It t h e n r e q u e s t s t h e a p p l i c a t i o n w i t h a WM_DDE_REQUEST m e s s a g e (if it w a n t s d a t a ) o r s e n d s d a t a t o t h e server (if it wants to send data). T h e c l i e n t a n d t h e server c a n c o n t i n u e t o " t a l k , " e i t h e r a c k n o w l e d g i n g the other's requests o r not, until o n e o f the linked applications posts a WM_DDE_TERMINATE m e s s a g e . E i t h e r t h e c l i e n t o r t h e server c a n p o s t t h e terminate message. A hot l i n k is m o r e s o p h i s t i c a t e d . After t h e a p p l i c a t i o n s h a v e l i n k e d , a c l i e n t p o s t s a c o n d i t i o n a l m e s s a g e (WM_DDE_ADVISE), a s k i n g t h e server t o i n f o r m t h e c l i e n t w h e n t h e v a l u e o f a d a t a field c h a n g e s . T h a t is w h e n t h e c l i e n t wants the data. This scenario allows the client to b e u p d a t e d regarding the status o f a d a t a f i e l d , a h a n d y s i t u a t i o n i n p a r t i c u l a r if t h e a p p l i c a t i o n is p r o c e s s i n g i n real t i m e . F o r e x a m p l e , y o u r a p p l i c a t i o n m i g h t w a n t t o r e c a l c u l a t e a s p r e a d s h e e t o r d a t a b a s e c o l u m n e a c h t i m e a v a l u e c h a n g e s a n d , i n t u r n , act if t h e n e w c a l c u l a t e d v a l u e e x c e e d s a t h r e s h o l d . D u r i n g a h o t l i n k , a c l i e n t c a n d e c i d e that it n o l o n g e r w a n t s d a t a u p d a t e s a n d " u n a d v i s e " t h e server b y s e n d i n g a n " UNADVISE" m e s s a g e . A n a p p l i c a t i o n also c a n maintain a hot a n d cold link simultaneously by requesting the data f r o m s o m e fields u n c o n d i t i o n a l l y a n d f r o m o t h e r s c o n d i t i o n a l l y . A warm l i n k is a partly h o t , partly c o l d l i n k . I n this s c e n a r i o , t h e c l i e n t m a k e s its c o n n e c t i o n t o a server, s e n d s a WM_DDE_ADVISE m e s s a g e , b u t i n d i c a t e s w i t h a flag c o n t a i n i n g t h e WM_DDE_ADVISE m e s s a g e that it w a n t s t o b e i n f o r m e d o n l y o f c h a n g e s i n a d a t a f i e l d ; it d o e s n ' t w a n t t h e d a t a s e n t . I f t h e c l i e n t d o e s d e c i d e that it w a n t s t h e d a t a , it r e q u e s t s it (WM_DDE_R EQUEST). T h e c l i e n t a l s o c a n c h a n g e this a d v i s e status b y s e n d i n g a n "UNADVISE" m e s s a g e .
Atoms, and So On C l i e n t a n d server a p p l i c a t i o n s identify d a t a w i t h c h a r a c t e r strings r e p r e s e n t i n g the application, topic in the application, a n d data in the application. These
1 1 — F r o m Program to Program Using D D E
c h a r a c t e r strings a r e r e p r e s e n t e d b y " a t o m s , " c a s e - i n s e n s i t i v e w o r d v a l u e s that refer t o t h e character strings. T h e a t o m c h a r a c t e r string is r e c o r d e d i n a n a t o m t a b l e , w h i c h is s t o r e d i n a s h a r e d d a t a s e g m e n t i n a d y n a m i c l i n k library i n W i n d o w s . Y o u d o n ' t h a v e t o k n o w t h e d e t a i l s o f h o w this s h a r e d a t o m t a b l e w o r k s , b u t y o u d o h a v e t o u s e it t o e s t a b l i s h a D D E l i n k . Specifically, w h e n t h e c l i e n t a p p l i c a t i o n w a n t s t o initiate a D D E c o n v e r s a t i o n , it a d d s t h e a p p l i c a t i o n , t o p i c , a n d i t e m n a m e s (if necessary) to the a t o m table: ApplicationAtom TopicAtom
:= GlobalAddAtom('Application
Name');
:= GlobalAddAtom( Topic Name'); 1
T h e D D E applications e n g a g e d in the conversation u s e the a t o m table t o establish their link. W h e n y o u r a p p l i c a t i o n h a s e s t a b l i s h e d t h e l i n k , it d e l e t e s t h e n a m e s f r o m the table: GlobalDeleteAtom(ApplicationAtom); GlobalDeleteAtom(TopicAtom); T h e wm_DDE_Initiate m e s s a g e , which y o u r a p p l i c a t i o n u s e s t o e s t a b l i s h a D D E c o n v e r s a t i o n , is a c t u a l l y b r o a d c a s t ( o r s e n t ) t o all t o p - l e v e l ( o r p a r e n t ) w i n d o w s . A n y a p p l i c a t i o n c a n r e s p o n d t o this DDE_Initiate m e s s a g e , s o it is u p t o t h e c l i e n t a p p l i c a t i o n t o t e r m i n a t e all t h e s e u n w a n t e d l i n k s . Y o u r a p p l i c a t i o n h a n d l e s this d u t y with a WMDDE m e s s a g e - r e s p o n s e m e t h o d , which p o s t s a m e s s a g e t o all u n w a n t e d r e s p o n d e e s , t e r m i n a t i n g t h e l i n k : procedure TDDEWindow.WMDDEAck(var
Msg: TMessage);
begin {
}
PostMessage(Msg.WParam, wm_DDE_Terminate, HWindow, 0); { .... } end; T o initiate a D D E c o n v e r s a t i o n , b r o a d c a s t a m e s s a g e that i d e n t i f i e s t h e a p p l i c a t i o n . I n t h e n e x t e x a m p l e , y o u e s t a b l i s h a very c o l d l i n k t o t h e P r o g r a m M a n a g e r , e v e n t u a l l y u s i n g t h e l i n k t o c r e a t e a p r o g r a m g r o u p that c a n , i n t u r n , b e u s e d b y a n y a p p l i c a t i o n s that a c c e s s t h e P r o g r a m M a n a g e r . T h e InitiateDDE m e t h o d l o o k s like this: procedure var
DDEWindow.InitiateDDE;
AppAtom, TopicAtom: TAtom; lParam : Word; begin PostedMessage := wm_DDE_Initiate;
{ Global atoms } { Message parameter } { Initiate DDE }
355
356
Part I I — A d v a n c e d T o p i c s
AppAtom := GlobalAddAtom( PROGMAN'); { Specify server application TopicAtom := GlobalAddAtom( PROGMAN'); { Specify server topic } SendMessage(HWnd(-1), wm_DDE_Initiate, HWindow, MakeLong(AppAtom, TopicAtom)); GlobalDeleteAtom(AppAtom); { Done with global atoms } GlobalDeleteAtom(TopicAtom); PostedMessage := 0; if ServerWindow = 0 then { DDE failed if ServerWindow = 0 } begin MessageBox(HWindow, 'Cannot establish DDE link to Program Manager.', 'Error', mb_IconExclamation or mb_Ok); EndDDE; { EndDDE if no successful DDE contact } end; end; 1
1
Notice that you cancel the D D E link if the Program Manager is not available. A message is displayed indicating the lack of success, and EndDDE is called, like this: procedure TDDEWindow.EndDDE; var Msg :TMessage; begin WMDestroy(Msg); end; WMDestroy sends messages to TerminateDDE and to TDlgWindow. WMDestroy destroys the additional dialog w i n d o w you created: procedure DDEWindow.WMDestroy(var Msg: TMessage); begin TerminateDDE; TDlgWindow.WMDestroy(Msg); end; WMDDETerminate uses the W i n d o w s function TerminateDDE to break the D D E link, as such: procedure TDDEWindow.WMDDETerminate(var Msg: TMessage); begin if Msg.WParam = ServerWindow then TerminateDDE; end; Listing 11.3 shows the complete procedure of a unit and test program used for linking to the Program Manager and creating a program group. Figure 11.2 shows the dialog w i n d o w in add-an-item-to-the-list m o d e created by the
1 1 — F r o m Program to Program Using D D E
c o d e . F i g u r e 11.3 s h o w s a g r o u p list. F i g u r e 11.4 s h o w s t h e C r e a t e G r o u p m o d e . F i g u r e 11.5 s h o w s a g r o u p c r e a t e d u s i n g this c o d e . Listing
11.3* Linking
to the Program
Manager.
unit MakeGroup; { This unit based on BI's progtalk.pas } interface uses WinTypes, WinProcs, WObjects, Strings; {$R MAKEGROU} const { Resource IDs } id_DDEDialog = 100; id_AddDialog = 101; id_CreateDialog = 102; { DDE dialog item IDs } id_ListBox id_AddItem id_DeleteItem id_ClearItems id_CreateGroup
= 100; =101; = 102; = 103; = 104;
{ Add and Create dialog item IDs } id_InputLine = 100; type { DDEDialog is the object type used to represent the Add Item and Create Group dialogs. } PDDEDialog = "DDEDialog; DDEDialog = object(TDialog) Buffer: PChar; continues
357
358
Part I I — A d v a n c e d T o p i c s
Listing
11.3>
continued
BufferSize: Word; constructor Init(AParent: PWindowsObject; AName, EditBuffer: PChar; EditBufferSize: Word); procedure SetupWindow; virtual; function CanClose: Boolean; virtual; procedure Inputl_ine(var Msg: TMessage); virtual id_First + id_Inputl_ine; end; { DDEWindow is the Application's MainWindow. It maintains a DDE conversation with the Program Manager, and allows a user to create program groups containing a user-specified list of program items. } PDDEWindow = "DDEWindow; DDEWindow = object(TDlgWindow) { DDEWindow is a kind of TDlgWindow } ListBox: PListBox; { List box for setting up group } ServerWindow: HWnd; { The server's handle } ContactMessage: Word; constructor Init; procedure SetupWindow; virtual; function GetClassName: PChar; virtual; procedure InitiateDDE; { DDE contact messages } procedure TerminateDDE; procedure EndDDE; procedure virtual procedure virtual procedure virtual procedure virtual procedure virtual procedure virtual procedure virtual end;
Addltem(var Msg: TMessage); { Make group messages } id_First + id_AddItem; Deleteltem(var Msg: TMessage); id_First + id_DeleteItem; Clearltems(var Msg: TMessage); id_First + id_ClearItems; CreateGroup(var Msg: TMessage); id_First + id_CreateGroup; WMDDEAck(var Msg: TMessage); { Windows messages } wm_First + wm_DDE_Ack; WMDDETerminate(var Msg: TMessage); wm_First + wm_DDE_Terminate; WMDestroy(var Msg: TMessage); wm_First + wm_Destroy;
1 1 — F r o m Program to Program Using D D E
{ DDEApp is the application object. It constructs a DDEWindow (its MainWindow) } DDEApp = object(TApplication) procedure InitMainWindow; virtual; end;
implementation
{ DDEDialog } { Input dialog constructor. Save the input buffer pointer and size for copying the contents of the EditControl } constructor DDEDialog.Init(AParent: PWindowsObject; AName, EditBuffer: PChar; EditBufferSize: Word); begin TDialog.Init(AParent, AName); Buffer := EditBuffer; BufferSize := EditBufferSize; end; { SetupWindow is called right after the dialog is created. The Edit control is limited to the maximum length of the input buffer. Disable the Ok button by setting EnableWindow to false. } procedure DDEDialog.SetupWindow; begin SendDlgltemMessage(HWindow, id_InputLine, em_LimitText, BufferSize - 1, 0); EnableWindow(GetDlgItem(HWindow, id_Ok), False); end; { Copy the contents of the edit control to the input buffer and return True, which allows the dialog to close. } function DDEDialog.CanClose: Boolean; begin GetDlgltemText(HWindow, id_Inputl_ine, Buffer, BufferSize); CanClose := True; end; continues
359
360
Part I I — A d v a n c e d T o p i c s
Listing
11.3'
continued
{ Edit control response method. Enable the Ok button if the edit control contains text, else disable the Ok button. } procedure DDEDialog.InputLine(var Msg: TMessage); begin if Msg.LParamHi = en_Change then EnableWindow(GetDlgItem(HWindow, id_0k), SendMessage(Msg.LParamLo, wm_GetTextLength, 0, 0) <> 0); end; { DDEWindow } { DDE window constructor. Create a TListBox object to represent the dialog's list box. Clear the DDE server window handle and the pending DDE message ID. } constructor DDEWindow.Init; begin TDlgWindow.Init(nil, PChar(id_DDEDialog)); ListBox := New(PListBox, InitResource(@Self, id_ListBox)); ServerWindow := 0; { No server yet. } ContactMessage := 0; end; { SetupWindow is called right after the DDE window is created. Initiate the DDE conversation. }
procedure DDEWindow.SetupWindow; begin TDlgWindow.SetupWindow; InitiateDDE; end;
{ Return window class name. This name corresponds to the class name specified for the DDE dialog in the resource file. } function DDEWindow.GetClassName: PChar; begin GetClassName := 'DDEWindow'; end;
1 1 — F r o m Program to Program Using D D E
{ Initiate a DDE conversation with the Program Manager. Bring up a message box if the Program Manager doesn't respond to the wm_DDE_Initiate message. } procedure DDEWindow.InitiateDDE; var AppAtom, TopicAtom: TAtom; lParam : Word; begin ContactMessage := wm_DDE_Initiate; AppAtom := GlobalAddAtom('PROGMAN'); TopicAtom := GlobalAddAtom('PROGMAN'); lParam := AppAtom or (TopicAtom shl 16); (* Either of the following SendMessage procedures works, but don't use both. SendMessage(HWnd(-1), wm_DDE_Initiate, HWindow, MakeLong(AppAtom, TopicAtom)); *)
SendMessage(HWnd(-1), wm_DDE_Initiate,HWindow,lParam); GlobalDeleteAtom(AppAtom); GlobalDeleteAtom(TopicAtom); ContactMessage := 0; if ServerWindow = 0 then begin MessageBox(HWindow, 'Cannot establish DDE link to Program Manager.', 'Error', mb_IconExclamation or mb_Ok); EndDDE; { Bail out if no DDE } end; end;
procedure DDEWindow.EndDDE; var Msg :TMessage; begin WMDestroy(Msg); end; continues
3
61
362
Part I I — A d v a n c e d T o p i c s
Listing
11.3>
continued
{ Terminate the DDE conversation. Send the wm_DDE_Terminate message only if the server window still exists. } procedure DDEWindow.TerminateDDE; var W: HWnd; begin W := ServerWindow; ServerWindow := 0; if IsWindow(W) then PostMessage(W, wm_DDE_Terminate, HWindow, 0); end; { Add item button response method. Bring up the Add item dialog to input a program item string, and add that item to the list box. } procedure DDEWindow.AddItem(var Msg: TMessage); var Name: array[0..63] of Char; begin if Application".ExecDialog(New(PDDEDialog, Init(@Self, PChar(id_AddDialog), Name, SizeOf(Name)))) <> id_Cancel then ListBox".AddString(Name); end; { Delete item button response method. Delete the currently selected item in the list box. } procedure DDEWindow.DeleteItem(var Msg: TMessage); begin ListBox".DeleteString(ListBox .GetSellndex); end; A
{ Clear items button response method. Clear the list box. } procedure DDEWindow.ClearItems(var Msg: TMessage); begin ListBox".ClearList; end; { Create group button response method. Initiate the Create Group dialog to input the program group name. Then, if a DDE link has been established (ServerWindow <> 0) and there is no DDE message currently pending (ContactMessage = 0), build
1 1 — F r o m Program to Program Using D D E
363
a list of Program Manager commands, and submit the commands using a wm_DDE_Execute message. To build the command list, first calculate the total length of the list, then allocate a global memory block of that size, and finally store the command list as a null-terminated string in the memory block. } procedure DDEWindow.CreateGroup(var Msg: TMessage); const sCreateGroup = [CreateGroup(%s)]'; sAddltem = '[Addltem(%s)] ; var Executed: Boolean; I, L: Integer; HCommands: THandle; PName, PCommands: PChar; Name: array[0..63] of Char; begin if Application".ExecDialog(New(PDDEDialog, Init(@Self, PChar(id_CreateDialog), Name, SizeOf(Name)))) <> id_Cancel then begin Executed := False; if (ServerWindow <> 0) and (ContactMessage = 0) then begin L := StrLen(Name) + (Length(sCreateGroup) - 1); for I := 0 to ListBox".GetCount - 1 do Inc(L, ListBox".GetStringLen(I) + (Length(sAddltem) - 2)); HCommands := GlobalAlloc(gmem_Moveable or gmemJDDEShare, L); { Must be DDEShare memory } if HCommands <> 0 then begin PName := Name; PCommands := GlobalLock(HCommands); WVSPrintF(PCommands, sCreateGroup, PName); for I := 0 to ListBox".GetCount - 1 do begin ListBox".GetString(Name, I); PCommands := StrEnd(PCommands); WVSPrintF(PCommands, sAddltem, PName); end; GlobalUnlock(HCommands); if PostMessage(ServerWindow, wm_DDE_Execute, HWindow, Makel_ong(0, HCommands)) then 1
1
continues
364
Part I I — A d v a n c e d T o p i c s
Listing
11.3'
continued
begin ContactMessage := wm_DDE_Execute; Executed := True; end else GlobalFree(HCommands); end; end; if not Executed then MessageBox(HWindow, 'Program Manager DDE execute failed.', 'Error , mb_IconExclamation or mb_0k); end; end; 1
{ wm_DDE_Ack message response method. If the current DDE message is a wm_DDE_Initiate, store off the window handle of the window that responded. If more than one window responds, terminate all conversations but the first. If the current DDE message is a wm_DDE_Execute, free the command string memory block, focus the window, and clear the list box. } procedure DDEWindow.WMDDEAck(var Msg: TMessage); begin case ContactMessage of wm_DDE_Initiate: begin if ServerWindow = 0 then ServerWindow := Msg.WParam else PostMessage(Msg.WParam, wm_DDE_Terminate, HWindow, 0); GlobalDeleteAtom(Msg.LParamLo); GlobalDeleteAtom(Msg.LParamHi); end; wm_DDE_Execute: begin GlobalFree(Msg.LParamHi); ContactMessage := 0; SetFocus(HWindow); ListBox".ClearList; end; end; end;
1 1 — F r o m Program to Program Using D D E
{ wm_DDE_Terminate message response method. If the window signaling termination is the server window (the Program Manager), terminate the DDE conversation. Otherwise ignore the wm_DDE_Terminate. } procedure DDEWindow.WMDDETerminate(var Msg: TMessage); begin if Msg.WParam = ServerWindow then TerminateDDE; end; { wm_Destroy message response method. Terminate the DDE link and call the inherited WMDestroy. } procedure DDEWindow.WMDestroy(var Msg: TMessage); begin TerminateDDE; TDlgWindow.WMDestroy(Msg); end; { TDDEApp } { Create a DDE window as the application's main window. } procedure DDEApp.InitMainWindow; begin MainWindow := New(PDDEWindow, Init); end; end.
{ end MakeGrou unit }
program Test_Interface;
{ A generic way to test each phase of interface development }
uses WIF5, makegrou;
{ Basic Interface unit } { Contains DDEApp } continues
365
366
Part I I — A d v a n c e d T o p i c s
Listing
11.3>
continued
type App = object(DDEApp) end; var Application: App;
{ An instance of BasicApplication }
{ Run Applicationl } begin Application.Init('Basiclnterface'); { Init application instance } Application.Run; { Message loop } Application.Done; { Destroy application instance } end.
Figure
11.2. The dialog window listing 11.3.
in add-an-item-to-the-list
mode created
by
1 1 — F r o m Program to Program Using D D E
Figure
11.3- A group list.
Figure
11.4. The Create Group
mode.
367
368
Part I I — A d v a n c e d T o p i c s
Figure
11.5. A group created using listing
113.
Wrap-up D D E is o n e o f t h e m a n y f e a t u r e s that m a k e s W i n d o w s s i n g . If y o u r a p p l i c a t i o n k n o w s h o w t o l i n k t o t h e D D E , it c a n act a n d react t o t h e b e h a v i o r o f m a n y o t h e r programs. A l t h o u g h this c h a p t e r h a s f o c u s e d o n t h e a p p l i c a t i o n - c l i p b o a r d c o n n e c tion a n d the very c o l d link b e t w e e n a n application a n d the Program M a n a g e r , t h e p o s s i b i l i t i e s f o r m a k i n g m o r e d r a m a t i c c o n n e c t i o n s are virtually e n d l e s s . Y o u r applications can 1. M o d i f y t h e d a t a fields i n o t h e r p r o g r a m s . 2. H a v e t h e i r o w n d a t a fields m o d i f i e d o r b e h a v i o r m a n i p u l a t e d i n response to the behavior of another program. 3. D i r e c t l y c o m m a n d a n o t h e r p r o g r a m t h r o u g h t h e u s e o f a p r o g r a m ' s M A C R O language. For e x a m p l e , y o u can access Microsoft W o r d , Excel, a n d other sophisticated programs t h r o u g h their M A C R O languages. For advanced information about D D E contacts, check the Reference s e c t i o n i n Part III o f this b o o k .
12 CHAPTER
SHARING LIBRARIES: USING DLL (DYNAMIC LINK LIBRARIES) When a child draws shape were like a
a tree, a green Popsicle.
mass sits atop a brown
trunk,
as if the
basic
James Gleick
D y n a m i c l i n k libraries are e x e c u t a b l e m o d u l e s o f c o d e l i n k e d i n t o a n a p p l i c a t i o n at r u n - t i m e . D L L s a l l o w a p p l i c a t i o n d e v e l o p e r s t o c r e a t e a n d m a i n t a i n i n d e p e n d e n t application c o m p o n e n t s . Similar to units in their modularity, D L L s are m o r e p o w e r f u l b e c a u s e t h e y 1. C a n b e l i n k e d i n t o a n a p p l i c a t i o n at r u n - t i m e . 2. C a n b e s h a r e d b y m a n y c o n c u r r e n t l y e x e c u t i n g a p p l i c a t i o n s . 3. C a n b e w r i t t e n i n a variety o f l a n g u a g e s , r e g a r d l e s s o f t h e l a n g u a g e u s e d to access the D L L .
370
Part I I — A d v a n c e d T o p i c s
D y n a m i c a l l y l i n k e d libraries ( D L L s ) p e r m i t several a p p l i c a t i o n s t o s h a r e c o d e a n d r e s o u r c e s . T h e s e a p p l i c a t i o n s (also c a l l e d clients) s h a r e a s i n g l e c o p y o f a p r o c e d u r e o r f u n c t i o n . T h e D L L file h a s t o b e p r e s e n t w h e n t h e c l i e n t application executes. D L L s are s i m i l a r t o u n i t s , e x c e p t t h e p r o c e d u r e s a n d f u n c t i o n s i n u n i t s are l i n k e d i n t o a p p l i c a t i o n s at l i n k t i m e (in o t h e r w o r d s , t h e y are statically linked), a n d t h e p r o c e d u r e s a n d f u n c t i o n s i n D L L s are a c c e s s i b l e t o t h e a p p l i c a t i o n at r u n - t i m e (in o t h e r w o r d s , t h e y are dynamically linked). T h e W i n d o w s p r o g r a m l o a d e r d y n a m i c a l l y l i n k s t h e p r o c e d u r e a n d f u n c t i o n calls i n t h e a p p l i c a t i o n t o t h e i r e n t r y p o i n t s i n t h e D L L s , w h i c h t h e n are u s e d b y t h e a p p l i c a t i o n . D L L s are e s p e c i a l l y p o w e r f u l b e c a u s e a T u r b o P a s c a l f o r W i n d o w s a p p l i c a t i o n c a n u s e D L L s that w e r e n o t w r i t t e n u s i n g T u r b o Pascal f o r W i n d o w s , a n d applications written in o t h e r l a n g u a g e s c a n u s e D L L s written with T u r b o Pascal for W i n d o w s . A D L L c o n s i s t s o f i n d e x e d f u n c t i o n s a n d p r o c e d u r e s , a n d is a m o r e o r less straightforward aspect of W i n d o w s ' application d e v e l o p m e n t . This chapter briefly s h o w s y o u h o w t o c r e a t e a n d a c c e s s a D L L i n T u r b o P a s c a l f o r W i n d o w s . F o r m o r e e x t e n s i v e details a b o u t D L L s , s e e t h e M i c r o s o f t S o f t w a r e D e v e l o p e r s Kit ( S D K ) .
DLL Details First, a f e w D L L r u l e s : • For an application to u s e a p r o c e d u r e or f u n c t i o n c o n t a i n e d in a D L L , the application must import the procedure or function using an external declaration. • I n i m p o r t e d p r o c e d u r e s a n d functions, the external directive replaces t h e d e c l a r a t i o n a n d s t a t e m e n t p a r t s that o t h e r w i s e w o u l d b e p r e s e n t i n the application. • I m p o r t e d p r o c e d u r e s a n d f u n c t i o n s b e h a v e similarly t o n o r m a l o n e s , e x c e p t t h e y m u s t u s e far calls (either a far p r o c e d u r e d i r e c t i v e o r a { $ F+} compiler directive). T u r b o Pascal lets y o u i m p o r t p r o c e d u r e s a n d f u n c t i o n s i n D L L s i n t h r e e different ways: • By name • By new name • By ordinal
1 2 — S h a r i n g Libraries: U s i n g D L L
A l t h o u g h a D L L c a n have variables, y o u cannot import t h e m into other m o d u l e s . A n y access t o a DLL's variables m u s t o c c u r t h r o u g h a p r o c e d u r a l interface. For example, the following external declaration imports the function GlobalAlloc f r o m t h e D L L c a l l e d K E R N E L ( t h e W i n d o w s k e r n e l ) : function GlobalAlloc(Flags: Word; Bytes: Longint): THandle; far; external 'KERNEL' index 15; N o t i c e that t h e D L L n a m e y o u specify after t h e e x t e r n a l k e y w o r d a n d t h e n e w n a m e y o u specify i n a n a m e c l a u s e d o n o t h a v e t o b e string literals. A n y c o n s t a n t string e x p r e s s i o n w i l l d o . A l s o , t h e o r d i n a l n u m b e r s p e c i f i e d i n a n index clause can b e any constant integer expression. For example: const ALib = 'ALIB'; Ordinal = 8;
procedure ImportByName; external ALib; procedure ImportByNewName; external ALib name 'REALNAME'; procedure ImportByOrdinal; external ALib index Ordinal;
Using DLLs U s i n g a D L L is basically a t w o - s t e p p r o c e s s : 1. C r e a t e t h e d y n a m i c l i n k library o f f u n c t i o n s a n d p r o c e d u r e s , w h i c h includes an export procedure a n d function section. 2. C r e a t e t h e a p p l i c a t i o n that u s e s t h e library. F o r e x a m p l e , d e s i g n a t e a library w i t h t h e library identifier: library BitBtn; or library DLLStuff; A n y f u n c t i o n y o u w a n t t o e x p o r t i n t h e library h a s t o b e s p e c i f i e d b y a n export identifier. F o r e x a m p l e : function BitButWinFn(HWindow:
HWnd; Message: Word; wParam:
Word; lParam: Longint): Longint; export; A n d at t h e e n d o f t h e library, y o u h a v e t o s p e c i f y t h e f u n c t i o n s that c a n b e exported. For example:
371
372
Part I I — A d v a n c e d T o p i c s
exports BitButWinFn; T h e a p p l i c a t i o n t h e n u s e s t h e f u n c t i o n s i n t h e library m o r e o r less n o r m a l l y , w i t h a c o u p l e o f e x c e p t i o n s . First, t h e a p p l i c a t i o n h a s t o l o a d t h e library b e f o r e it u s e s it. F o r e x a m p l e : constructor ABitApp.Init(AName: begin
PChar);
L i b := LoadLibrary(DLLName); i f L i b < 32 t h e n S t a t u s : = em_DLLNotFound; TApplication.Init(AName); end; A n d it h a s t o free t h e library w h e n it is f i n i s h e d w i t h it. F o r e x a m p l e : destructor begin
ABitApp.Done;
TApplication.Done; FreeLibrary(Lib); end; T h e e x a m p l e i n listing 12.1 d e m o n s t r a t e s a u s e o f D L L s . I n this e x a m p l e , a n a p p l i c a t i o n i m p o r t s c u s t o m c o n t r o l s f r o m a D L L . F i g u r e 12.1 s h o w s t h e w i n d o w and custom controls created by the c o d e .
Figure
12.1. A window and its custom controls created by listing 12.1.
1 2 — S h a r i n g Libraries: U s i n g D L L
Listing
12.1.
A dynamic
link
library
(DLL)
example.
{ A DLL library example that accesses Borland International's BitBtn.DLL. }
library ABitBtn; uses WinTypes, WinProcs; {$R ABITBTN.RES} const ofState ofDownBits ofUpBits ofFocUpBits ofSize
= = = = =
0; 2; 4; 6; 8; { Amount of window extra bytes to use }
= = = = = =
$0001; $0002; $0004; $0008; $0010; $0020;
const bdBorderWidth = 1; const bsDisabled bsFocus bsKeyDown bsMouseDown bsMouseUpDown bsDefault
function BitButtonWinFn(HWindow: HWnd; Message: Word; wParam: Word; lParam: Longint): Longint; export; var DC: HDC; BitsNumber: Integer; Bitmap: TBitmap; Rect: TRect; Pt: TPoint; PS: TPaintStruct; continues
373
374
Part I I — A d v a n c e d T o p i c s
Listing
12.1.
continued
function Get(Ofs: Integer): Word; begin Get := GetWindowWord(HWindow, Ofs); end; procedure SetWinWord(Ofs: Integer; Val: Word); begin SetWindowWord(HWindow, Ofs, Val); end; function State: Word; begin State := Get(ofState); end; function DownBits: Word; begin DownBits := Get(ofDownBits); end; function UpBits: Word; begin UpBits := Get(ofUpBits); end; function FocUpBits: Word; begin FocUpBits := Get(ofFocUpBits); end; function GetState(AState: Word): Boolean; begin GetState := (State and AState) = AState; end; procedure Paint(DC: HDC); var MemDC: HDC; Bits, Oldbitmap: HBitmap; BorderBrush, OldBrush: HBrush; Frame: TRect; Height, Width: Integer;
1 2 — S h a r i n g Libraries: U s i n g D L L
375
begin if (State and (bsMouseDown + bsKeyDown) <> 0) and not GetState(bsMouseUpDown) then Bits := DownBits else if GetState(bsFocus) then Bits := FocUpBits else Bits := UpBits; { Draw a border } GetClientRect(HWindow, Frame); Height := Frame.bottom - Frame.top; Width := Frame.right - Frame.left; if GetState(bsDefault) then BorderBrush := GetStockObject(Black_Brush) else BorderBrush := GetStockObject(White_Brush); OldBrush := SelectObject(DC, BorderBrush); PatBlt(DC, Frame.left, Frame.top, Width, bdBorderWidth, PatCopy); PatBlt(DC, Frame.left, Frame.top, bdBorderWidth, Height, PatCopy); PatBlt(DC, Frame.left, Frame.bottom - bdBorderWidth, Width, bdBorderWidth, PatCopy); PatBlt(DC, Frame.right - bdBorderWidth, Frame.top, bdBorderWidth, Height, PatCopy); SelectObject(DC, OldBrush); { Draw a bit map } MemDC := CreateCompatibleDC(DC); OldBitmap := SelectObject(MemDC, Bits); GetObject(Bits, Sizeof(Bitmap), ^Bitmap); BitBlt(DC, bdBorderWidth, bdBorderWidth, Bitmap.bmWidth, Bitmap.bmHeight, MemDC, 0, 0, srcCopy); SelectObject(MemDC, OldBitmap); DeleteDC(MemDC); end; procedure Repaint; var DC: HDC; begin DC := GetDC(HWindow); Paint(DC); ReleaseDC(HWindow, DC); end; continues
376
Part I I — A d v a n c e d T o p i c s
Listing
12.1.
continued
procedure SetState(AState: Word; Enable: Boolean); var OldState: Word; begin OldState := State; if Enable then SetWinWord(ofState, State or AState) else SetWinWord(ofState, State and not AState); if State <> OldState then Repaint; end; function InMe(lPoint: Longint): Boolean; var R: TRect; Point: TPoint absolute lPoint; begin GetClientRect(HWindow, R); InflateRect(R, -bdBorderWidth, -bdBorderWidth); InMe := PtInRect(R, Point); end; procedure ButtonPressed; begin SetState(bsMouseDown + bsMouseUpDown + bsKeyDown, False); SendMessage(GetParent(HWindow), wm_Command, GetDlgCtrllD(HWindow), Longint(HWindow)); end; begin BitButtonWinFn := 0; case Message of { Message responses } wm_Create: begin DC := GetDC(0); if (GetSystemMetrics(sm_CYScreen) < 480) or (GetDeviceCaps(DC, numColors) < 16) then BitsNumber := 2000 + Get(gww_ID) else BitsNumber := 1000 + Get(gww_ID); ReleaseDC(0, DC); SetWinWord(ofUpBits, LoadBitmap(hlnstance, PChar(BitsNumber)));
12—Sharing Libraries: Using DLL
377
SetWinWord(ofDownBits, LoadBitmap(hInstance, pChar(BitsNumber + 2000))); SetWinWord(ofFocUpBits, LoadBitmap(hinstance, pChar(BitsNumber + 4000))); GetObject(DownBits, SizeOf(Bitmap), ^Bitmap); GetWindowRect(HWindow, Rect); Pt.X := Rect.Left; Pt.Y := Rect.Top; ScreenToClient(PCreateStruct (lParam) .hwndParent, Pt); MoveWindow(HWindow, Pt.X, Pt.Y, Bitmap.bmWidth + bdBorderWidth * 2, Bitmap.bmHeight + bdBorderWidth * 2, False); if (PCreateStruct(lParam)".style and $1F) = bs_DefPushButton then SetState(bsDefault, True); end; wm_NCDestroy: begin BitButtonWinFn := DefWindowProc(HWindow, Message, wParam, lParam); DeleteObject(UpBits); DeleteObject(DownBits); DeleteObject(FocUpBits); end; wm_Paint: begin BeginPaint(HWindow, PS); Paint(PS.hDC); EndPaint(HWindow, PS); end; wm_EraseBkGnd: begin end; wm_Enable: SetState(bsDisabled, wParam <> 0); wm_SetFocus: SetState(bsFocus, True); wm_KillFocus: SetState(bsFocus, False); wm_KeyDown: if (wParam = $20) and not GetState(bsKeyDown) and not GetState(bsMouseDown) then SetState(bsKeyDown, True); wm_KeyUP: if (wParam = $20) and GetState(bsKeyDown) then ButtonPressed; A
continues
378
Part I I — A d v a n c e d T o p i c s
Listing
12.1.
continued
wm_LButtonDblClk, wm_LButtonDown: if InMe(lParam) and not GetState(bsKeyDown) then begin if GetFocus <> HWindow then SetFocus(HWindow); SetState(bsMouseDown, True); SetCapture(HWindow); end; wm__MouseMove: if GetState(bsMouseDown) then SetState(bsMouseUpDown, not InMe(lParam)); wm_LButtonUp: if GetState(bsMouseDown) then begin ReleaseCapture; if not GetState(bsMouseUpDown) then ButtonPressed else SetState(bsMouseDown + bsMouseUpDown, False); end; wm_GetDlgCode: if GetState(bsDefault) then BitButtonWinFn:= dlgc_DefPushButton else BitButtonWinFn := dlgcJJndefPushButton; bm_SetStyle: SetState(bsDefault, wParam = bs_DefPushButton); else BitButtonWinFn := DefWindowProc(HWindow, Message, wParam, lParam); end; end; exports BitButtonWinFn;
{ Export qualifier }
var Class: TWndClass; begin with Class do begin IpszClassName hCursor IpszMenuName style lpfnWndProc
:= := := :=
'ABitButton'; LoadCursor(0, idc_Arrow); nil; cs_HRedraw or cs_VRedraw or csJDblClks or cs_GlobalClass; := TFarProc(@BitButtonWinFn);
1 2 — S h a r i n g Libraries: U s i n g D L L
hlnstance := System.hlnstance; hlcon := 0; cbWndExtra := ofSize; cbClsExtra := 0; hbrBackground := 0; end; RegisterClass(Class); end. { End DLL }
{ Main application uses the custom controls in the DLL: ABITBTN.PAS. }
program BitBnApp; {$R BitBnApp.RES} uses WinTypes, WinProcs, WObjects; const DLLName = ABITBTN.DLL'; 1
{ The DLL }
const em_DLLNotFound = 1; type PABitWindow = "ABitWindow; ABitWindow = object(TDlgWindow) { A dialog window } { Button response methods } procedure Yes(var Msg: TMessage); virtual id_First + id_Yes; procedure No(var Msg: TMessage); virtual id_First + id_No; procedure Ok(var Msg: TMessage); virtual id_First + id_0K; procedure Cancel(var Msg: TMessage); virtual id_First + id_Cancel; end; continues
379
380
Part I I — A d v a n c e d T o p i c s
Listing
12.1.
continued
PABitApp = ABitApp; ABitApp = object(TApplication) Lib: THandle; { A library handle } constructor Init(AName: PChar); destructor Done; virtual; procedure InitMainWindow; virtual; procedure Error(ErrorCode: Integer); virtual; end; A
{ ABitApp } constructor ABitApp.Init(AName: PChar); begin Lib := LoadLibrary(DLLName); { Load the DLL } if Lib < 32 then Status := em_DLLNotFound; TApplication.Init(AName); end; destructor ABitApp.Done; begin TApplication.Done; FreeLibrary(Lib); end;
{ Release the DLL }
procedure ABitApp.InitMainWindow; begin MainWindow := New(PABitWindow, Init(nil, MakeIntResource(100))); { Use resource } end; procedure ABitApp.Error(ErrorCode: Integer); begin case ErrorCode of em_DLLNotFound: MessageBox(0, DLLName + not found. ', 'Fatal error', mb_0k or mb_IconStop); else TApplication.Error(ErrorCode); end; end; 1
{ ABitWindow methods }
1 2 — S h a r i n g Libraries: U s i n g D L L
procedure ABitWindow.Yes(var Msg: TMessage); begin CloseWindow; end; procedure ABitWindow.No(var Msg: TMessage); begin { Cancel close } end; procedure ABitWindow.Ok(var Msg: TMessage); begin CloseWindow; end; procedure ABitWindow.Cancel(var Msg: TMessage); begin { Cancel close } end; var App: ABitApp; { Main loop } begin App.Init('Uses ABITBTN.DDL'); App.Run; App.Done; end.
381
13 CHAPTER
DESIGNING WINDOWS APPLICATIONS My roads will not be exactly the same as yours, but, with our separate maps, we can each get from a particular place to another. D o u g l a s R. H o f s t a d t e r T u r b o Pascal f o r W i n d o w s offers a p p l i c a t i o n d e v e l o p e r s a n e x c e p t i o n a l w a y t o d e s i g n a p p l i c a t i o n s f o r W i n d o w s that c a n e v o l v e as t h e n e e d s o f u s e r s e v o l v e . If y o u b u i l d y o u r W i n d o w s a p p l i c a t i o n s o u t o f o b j e c t s ( u s i n g t h e O b j e c t W i n d o w s library): 1. Y o u r a p p l i c a t i o n d o e s n o t h a v e t o b o t h e r w i t h t h e d e t a i l s o f i n t e r a c t i n g w i t h W i n d o w s at a l o w l e v e l . 2. Y o u r a p p l i c a t i o n c o n s i s t s o f easily m o d i f i a b l e o b j e c t s . T h e n e t result is easily m o d i f i a b l e a n d e x t e n d a b l e W i n d o w s a p p l i c a t i o n s . O n e i m p o r t a n t w a y o f e x t e n d i n g o b j e c t s , as this b o o k h a s s h o w n , is t h r o u g h i n h e r i t a n c e . W h e n y o u w a n t a n e w o b j e c t s i m i l a r t o o n e that O b j e c t W i n d o w s (or y o u r o b j e c t library) a l r e a d y c o n t a i n s , y o u c a n d e r i v e a n e w object from the o n e y o u have, a n d create n e w behavior or override s o m e existing behavior y o u must c h a n g e . W h y is this i m p o r t a n t ? B e c a u s e p r o b l e m s a n d t h e n e e d s o f c o m p u t e r u s e r s c h a n g e , a n d g o o d a p p l i c a t i o n s always c h a n g e i n r e s p o n s e t o u s e r s . W i n d o w s is a g e n e r a l - p u r p o s e , f l e x i b l e i n t e r f a c e ; u s e r - f r i e n d l y a n d (with t h e h e l p o f T u r b o Pascal f o r W i n d o w s ) d e v e l o p e r - f r i e n d l y .
384
Part I I — A d v a n c e d T o p i c s
T h i s c h a p t e r r e s h a p e s t h e i d e a s d i s c u s s e d s o far i n t o a m o r e o r less g e n e r a l W i n d o w s design philosophy. This philosophy emphasizes two primary themes f o r d e s i g n i n g efficient, e x p a n d a b l e W i n d o w s a p p l i c a t i o n s : 1. M a k e n e w a p p l i c a t i o n s c o n s i s t e n t w i t h e x i s t i n g W i n d o w s a p p l i c a t i o n s . I n o t h e r w o r d s , if y o u are g o i n g t o u s e W i n d o w s as y o u r u s e r i n t e r f a c e , t a k e full a d v a n t a g e o f it b y u s i n g its s t r e n g t h s ; f o r e x a m p l e , t h e c o n s i s t e n c y o f its i n t e r f a c e . I B M h a s p u b l i s h e d g u i d e l i n e s that a d d r e s s this i s s u e , c a l l e d t h e C o m m o n U s e r A c c e s s ( C U A ) , w h i c h this b o o k u s e s as a basis. 2 . T a k e a d v a n t a g e o f o b j e c t - o r i e n t e d t e c h n i q u e s that are flexible e n o u g h t o let y o u e x t e n d a n d m o d i f y t h e m as p a i n l e s s l y as p o s s i b l e . T h e object-oriented t e c h n i q u e s built t h o r o u g h l y into T u r b o Pascal for W i n d o w s (that is, O b j e c t W i n d o w s ) c a n save y o u a n e n o r m o u s a m o u n t o f t i m e a n d effort, as t h e p r e v i o u s 12 c h a p t e r s h a v e d e m o n s t r a t e d . T h e s e c o n d part o f this c h a p t e r d e s c r i b e s m o r e a b o u t d i s c o v e r i n g a n d e x t e n d i n g o b j e c t s as a p r i m a r y s t e p i n a p p l i c a t i o n d e s i g n . Discussing consistency in the l o o k and feel of applications a n d highlighti n g s o m e o f t h e i m p o r t a n t a s p e c t s o f t h e C o m m o n U s e r A c c e s s is a g o o d w a y t o start.
Common User Access T h e C o m m o n U s e r A c c e s s ( C U A ) is a set o f g u i d e l i n e s that h e l p y o u d e v e l o p applications consistent with IBM's (and probably Microsoft's) ideas about h o w a W i n d o w s application s h o u l d l o o k a n d feel. T h e C U A emphasizes two primary ideas: 1. U s e r s s h o u l d f e e l c o m f o r t a b l e w i t h a n a p p l i c a t i o n a n d c o n f i d e n t i n t h e results o f an action. 2. U s e r s s h o u l d c o n t r o l t h e flow o f e v e n t s . L o o k i n g o u t f o r u s e r s ' c o m f o r t a n d b u i l d i n g t h e i r c o n f i d e n c e is a b i g j o b . Making your application consistent with other W i n d o w s applications they m i g h t h a v e u s e d , a n d m a k i n g it c o n s i s t e n t w i t h its o w n b e h a v i o r c a n d o t h e j o b . E a c h o p e n i n g o f a w i n d o w s h o u l d b e less m y s t e r i o u s a n d m o r e familiar. S i m i l a r tasks s h o u l d r u n i n s i m i l a r - l o o k i n g w i n d o w s . I n a d d i t i o n , if p o s s i b l e , try t o u s e m e t a p h o r s w i t h w h i c h t h e u s e r is familiar. A classic e x a m p l e is a card-filing a p p l i c a t i o n o n a c o m p u t e r that r e s e m b l e s a card-filing s y s t e m u s e d i n b u s i n e s s e s .
13—Designing W i n d o w s Applications
Also, avoid limiting users whenever y o u can. I n other words, avoid restricting u s e r s ' a c c e s s t o parts o f a n a p p l i c a t i o n . U s e r s s h o u l d b e a b l e t o m o v e anywhere they want w h e n they want. Y o u c a n t h i n k o f this p r o c e s s as e v e n t - f l o w . I n o t h e r w o r d s , let t h e u s e r s c o n t r o l as m u c h o f t h e flow o f t h e a p p l i c a t i o n as p o s s i b l e . T h i s b u i l d s u s e r s ' c o n f i d e n c e a n d lets t h e m o v e r c o m e t h e all-too-typical fear o f a p p l i c a t i o n s a n d thus, of the computer. W h e n y o u c a n , let u s e r s d e c i d e t h i n g s f o r t h e m s e l v e s u s i n g v i s u a l c u e s ( i c o n s , s h a p e s , m e n u s , lists, a n d s o o n ) . E n c o u r a g e t h e m t o e x p l o r e t h e application. D o not m a k e t h e m pay t o o dearly for mistakes. Provide a n U n d o , B a c k o u t , Feedback, a n d H e l p . T h e best application includes a context- a n d situation-sensitive H e l p system that p r o v i d e s n o t o n l y g e n e r a l b u t also s p e cific h e l p . E a c h a p p l i c a t i o n s h o u l d h a v e t h e s t a n d a r d a p p e a r a n c e o f a MainWindow, m e n u , a n d event-driven object-action cycle. Users' d o u b l e o r single m o u s e clicks s h o u l d d o similar t h i n g s i n a p p l i c a t i o n s . T h e s a m e r u l e a p p l i e s t o t h e k e y b o a r d : if t h e a p p l i c a t i o n s y o u u s e a l r e a d y specify F l , S h i f t - F l , o r C o n t r o l - F l t o call u p c e r t a i n k i n d s o f H e l p , c o n s i d e r u s i n g t h o s e k e y s y o u r s e l f . M a k e t h e a p p l i c a t i o n f e e l as familiar as y o u c a n . U s e w i n d o w s s p a r i n g l y , b u t w e l l . D o n o t m a k e a w i n d o w b i g g e r t h a n it h a s t o b e , a n d k e e p i n m i n d that t h e MainWindow r e p r e s e n t s t h e a p p l i c a t i o n . W h e n it is m i n i m i z e d t h e a p p l i c a t i o n virtually d i s a p p e a r s . W h e n y o u c a n , n o t i c e t h e s e l e c t i o n o f a n o b j e c t visually. S h o w that a n object has b e e n selected o r deselected. A n excellent u s e o f visual selection a n d d e s e l e c t i o n is t h e i c o n d i s p l a y u s e d b y m a n y d r a w i n g a p p l i c a t i o n s t o r e p r e s e n t pens, brushes, and so o n . D o n o t restrict t h e m o u s e p o i n t e r . I n o t h e r w o r d s , always m a k e s u r e that it is free t o m o v e f r o m w i n d o w t o w i n d o w o r f r o m a p p l i c a t i o n t o a p p l i c a t i o n . U s e t h e k e y b o a r d s e l e c t i o n c u r s o r , a n d m a r k t h e i n p u t f o c u s w h e r e i n p u t is occurring o n the screen. M a k e t h e m e n u s ' styles c o n f o r m t o t h e k i n d o f m e n u s typically u s e d b y a p p l i c a t i o n s s u c h as t h e P r o g r a m M a n a g e r . T h e P r o g r a m M a n a g e r , b y t h e w a y , is a n e x c e l l e n t e x a m p l e t o c o m p a r e t o y o u r a p p l i c a t i o n s w h e n y o u try t o m a k e them conform to the C o m m o n User Access. C U A a l s o r e c o m m e n d s specific m e n u i t e m s f o r c o m m o n l y u s e d t o p i c s , s u c h as F i l e , Edit, V i e w , H e l p , a n d s o o n . I n a d d i t i o n , t h e C U A r e c o m m e n d s specific keyboard accelerators for u s e with m a n y c o m m o n l y u s e d topics. S e e the I B M C U A specification for m o r e details. M a k e d i a l o g a n d file b o x e s , list v i e w e r s , e n t r y w i n d o w s , a n d o t h e r s as c o n s i s t e n t as p o s s i b l e . D o n o t m i x t o o m a n y e l e m e n t s i n o n e a p p l i c a t i o n . R e m e m b e r : y o u w a n t y o u r a p p l i c a t i o n t o b e as easy t o k n o w a n d u s e as p o s s i b l e .
385
386
Part I I — A d v a n c e d T o p i c s
Objects and Windows P r o g r a m s (that is, a p p l i c a t i o n s ) b e c o m e m o r e p o w e r f u l a n d m o r e difficult t o d e s i g n a n d c o d e a l m o s t daily, it s e e m s . W a s n o t t h e r e a n early m y t h that s o f t w a r e w o u l d e v e n t u a l l y b e e a s y t o u s e , p o w e r f u l , and easy t o d e v e l o p ? ( H a , h a . ) Application ease of use and p o w e r might be keeping pace with each other, b u t e a s e o f d e v e l o p m e n t is still d e s p e r a t e l y s t r u g g l i n g t o k e e p u p . T h e W i n d o w s - O O P c o n n e c t i o n is a s t e p i n t h e right d i r e c t i o n . E v e n t s a n d o b j e c t s ; objects a n d actions. Point, click, a n d a n object r e s p o n d s to an event by carrying o u t a n a c t i o n . W i n d o w s is b o t h p o w e r f u l a n d e a s y t o u s e . O O P a l s o m a k e s it easier to create a n d , in particular, to maintain applications. W h y is m a i n t e n a n c e s o i m p o r t a n t ? C o n s i d e r h o w o n e g o e s a b o u t d e s i g n ing an application. B e f o r e o b j e c t - o r i e n t e d d e s i g n , first-rate a p p l i c a t i o n d e v e l o p e r s p r i m a r i l y u s e d something called "structured programming" or "structured design," a p h i l o s o p h y w h i c h a d v o c a t e s that y o u d e t e r m i n e all t h e d e t a i l s o f a n a p p l i c a t i o n (in o t h e r w o r d s , its s t r u c t u r e ) b e f o r e y o u b e g i n c o d i n g it. M o s t d e v e l o p e r s , i n fact, still u s e s o m e s t r u c t u r e d p h i l o s o p h y as t h e i r d e s i g n m o d e l . Y o u s t r u c t u r e t h e a p p l i c a t i o n b y b r e a k i n g it i n t o s m a l l e r s t r u c t u r e s o f i n f o r m a t i o n , o r g a n i z e d b y levels o f c o m p l e x i t y . T h e m o s t s p e c i f i c a s p e c t s o f t h e s t r u c t u r e are i n c o r p o r a t e d i n t o l a r g e r , less s p e c i f i c s t r u c t u r e s . In addition to "structuring" aspects of the application, y o u describe the a p p l i c a t i o n i n t e r m s o f " d a t a - f l o w d i a g r a m s . " A data-flow diagram is a c o l l e c t i o n o f b l o c k s (the s t r u c t u r e d , u s u a l l y f u n c t i o n a l , parts) a n d a r r o w s . E a c h b l o c k represents a process for accepting, using, a n d often transforming data items, w i t h a r r o w s r e p r e s e n t i n g t h e flows f r o m b l o c k t o b l o c k . F i g u r e 13.1 illustrates this s c e n a r i o . A c o m p l e t e s y s t e m (or a p p l i c a t i o n ) o r s u b s e t o f a n a p p l i c a t i o n c a n b e represented by a single block. Arranging an application into a hierarchy o f dataflow d i a g r a m s is c a l l e d leveling ( b e c a u s e t h e a p p l i c a t i o n is o r g a n i z e d i n t o levels o f c o m p l e x i t y ) . T h e d a t a - f l o w d i a g r a m m o d e l i n g p r o c e s s l e a d s t o a c o m p l e t e set o f d i a g r a m s that r e p r e s e n t t h e s y s t e m a n d its flow t h r o u g h v a r i o u s levels o f complexity. Using these structured blocks, y o u can view, use, or analyze an application from m a n y perspectives—from overview (represented by a single diagram with a s i n g l e b l o c k , a n d n o t m u c h d e t a i l ) , t o fine d e t a i l ( r e p r e s e n t e d b y m a n y different diagrams, each with multiple b l o c k s ) . After y o u h a v e g e n e r a t e d , c h e c k e d , a n d a g r e e d o n t h e d e t a i l e d d a t a - f l o w d i a g r a m s , y o u o f t e n g e n e r a t e a h i e r a r c h i c a l s t r u c t u r e chart f r o m t h e m (see figure 1 3 2 ) .
13—Designing W i n d o w s Applications
Processes & Transformations
Input P r o c e s s block
Output
Input
Figure
13.1. A data-flow
diagram.
Hierarchical structure chart
Executive
Input
Figure
13.2. A hierarchical
P r o c e s s block
structure
Output
chart.
T h e h i e r a r c h i c a l chart s h o w s t h e f l o w o f d a t a i n a n d o u t o f t h e b l o c k s . T h e blocks either transform the data or don't, and then return t h e m (represented b y t h e o u t g o i n g a r r o w ) . T h e chart s h o w s h o w b l o c k s interact w i t h o t h e r b l o c k s .
387
388
Part I I — A d v a n c e d T o p i c s
F r o m this h i e r a r c h i c a l chart a n d f r o m i n f o r m a t i o n a b o u t t h e d a t a structures a n d transformations, y o u c a n c o d e the specific c o m p o n e n t s o f the a p p l i c a t i o n o n e b l o c k at a t i m e , i n d e p e n d e n t o f o t h e r b l o c k s . F r o m a c o d i n g perspective, each block represents a function or procedure, and m o v i n g data f r o m in a n d out o f the b l o c k represents the function's or p r o c e d u r e ' s parameters a n d r e t u r n v a l u e s . This structured design has b e e n a r o u n d a l o n g time, and makes m u c h s e n s e b e c a u s e it s e e m s t o c a p t u r e t h e e l e m e n t s o f t h e a p p l i c a t i o n i n o n e s w o o p . A n a p p l i c a t i o n s t r u c t u r e d i n this w a y is p o w e r f u l a n d relatively easy t o understand. Y e t , t h e s t r u c t u r e d a p p r o a c h is n o t a p e r f e c t d e s i g n s o l u t i o n f o r at least o n e i m p o r t a n t r e a s o n — a r e a s o n that s e e m s t o g r o w i n i m p o r t a n c e w i t h t i m e . Applications change, usually in response to the changing needs of users. A s t r u c t u r e that m a d e m u c h s e n s e i n t h e b e g i n n i n g m i g h t n o t m a k e s e n s e further d o w n the line. Structured design supplies m u c h - n e e d e d organization at t h e b e g i n n i n g o f a n a p p l i c a t i o n ' s life, b u t t h e s t r u c t u r e itself m i g h t resist c h a n g e . M o s t a p p l i c a t i o n d e v e l o p e r s h a v e s t r u g g l e d w i t h t h e "difficult t o c h a n g e " p r o b l e m , e v e n w h e n t h e i r initial d e s i g n s s e e m e d c o r r e c t o r e v e n exceptional. T h e d e s i g n o f a n a p p l i c a t i o n m i g h t b e c l e a r . It m i g h t b e c l e a r , i n part, b e c a u s e it is b a s e d o n a s i n g l e s o l u t i o n t o a s i n g l e p r o b l e m . A h a r d - c o d e d s i n g l e s o l u t i o n t o a s i n g l e p r o b l e m is a l m o s t always c l e a r e r t h a n a g e n e r a l - s o l u t i o n o r a g e n e r a l - p r o b l e m s o l u t i o n . T h e g e n e r a l s o l u t i o n , b y n a t u r e , is m o r e c o m p l e x b e c a u s e it c o n s i d e r s m o r e t h a n o n e p r o b l e m a n d s o l u t i o n . O b j e c t - o r i e n t e d t e c h n i q u e s s u g g e s t a d e s i g n a p p r o a c h that a d d r e s s e s b o t h t h e s p e c i f i c a n d g e n e r a l n a t u r e o f p r o b l e m s . T h e a p p r o a c h is s p e c i f i c i n that a n o b j e c t c a n b e d e s i g n e d t o s o l v e s p e c i f i c a s p e c t s o f a p r o b l e m o r a s p e c i f i c p r o b l e m a n d yet b e derivative o f a b a s e o b j e c t that c o n t a i n s t h e g e n e r a l b e h a v i o r for handling general problems of a type. In an object-oriented design, the idea of the "flow of data" between blocks is d i m i n i s h e d . M e s s a g e s m o v e a b o u t t h e a p p l i c a t i o n , b u t o b j e c t s k e e p d a t a t o themselves a n d operate o n their o w n data. T h e potential c o n f u s i o n o f the w r o n g p r o c e d u r e s a n d f u n c t i o n s a c t i n g o n t h e right d a t a a n d v i c e v e r s a is virtually e l i m i n a t e d . M e t h o d s c a n o p e r a t e o n l y o n t h e d a t a s p e c i f i e d f o r t h e m b y t h e o b j e c t d e f i n i t i o n . A l s o , t h e p o t e n t i a l c o m p l e x i t y that arises f r o m t h e c o n n e c t i o n s o f b l o c k s t r a n s f o r m i n g d a t a is d i m i n i s h e d . Objects have the n o t i o n o f c h a n g e built into t h e m . Extension, modificat i o n , a n d a s e n s e o f g e n e r a l p u r p o s e are f e a t u r e s i n O O P . T h u s , a p p l i c a t i o n s that u s e o b j e c t s as t h e " s t r u c t u r e d b l o c k s " c a n i n c o r p o r a t e t h e n o t i o n o f c h a n g e i n their "structures" from the b e g i n n i n g .
13—Designing Windows Applications
Note: Object-oriented programming techniques d o not attempt to eliminate structure; instead they attempt to incorporate c h a n g e in structure. T h e best o f b o t h worlds? Perhaps.
Designing for Change Object-oriented design anticipates the evolution o f real-world systems a n d applications. Object-oriented W i n d o w s d e s i g n utilizes the consistency o f the W i n d o w s G U I . T h e interface remains similar a l t h o u g h the application e n c a p s u lates its r e s p o n s e t o b o t h t h e r e a l w o r l d a n d W i n d o w s i n m o d i f i a b l e o b j e c t s . A n y a p p l i c a t i o n o f e v e n m o d e s t c o m p l e x i t y c h a n g e s , s o a n t i c i p a t i n g c h a n g e is o n l y natural. In general, change c o m e s in o n e of two forms: external or internal to the a p p l i c a t i o n . A n e x t e r n a l c h a n g e is a c h a n g e i n t h e o u t s i d e w o r l d that r e q u i r e s a change in the application's behavior, so the application can continue to accurately represent the outside w o r l d . Simple e x a m p l e s include: 1. A d d i n g n e w p r i n t e r s o r g r a p h i c s t e r m i n a l s t o a n a p p l i c a t i o n ' s c a p a bility t o c o m m u n i c a t e w i t h d e v i c e s . 2. A d d i n g d e s k t o p p u b l i s h i n g b e h a v i o r t o a w o r d - p r o c e s s i n g a p p l i c a t i o n . S t r u c t u r e d d e s i g n t e c h n i q u e s , e v e n w i t h o u t O O P , are e x p e r t at f o c u s i n g o n t h e s e k i n d s o f c h a n g e s . N o t i c e that W i n d o w s a l r e a d y s p e c i a l i z e s i n t h e s e k i n d s o f p r o b l e m s f o r a n a p p l i c a t i o n . D e v i c e - i n d e p e n d e n c e is a c e n t r a l t e n e t o f Windows. A n i n t e r n a l c h a n g e is a c h a n g e i n t h e w a y y o u ( a n d s u b s e q u e n t l y t h e application) handle a p r o b l e m . N o t h i n g has to c h a n g e in the outside w o r l d for y o u to have a better idea h o w an application works or handles the p r o b l e m . This c h a n g e is b e t w e e n y o u a n d t h e a p p l i c a t i o n , s e p a r a t e f r o m t h e p r o b l e m itself. Y o u r r e a l i z a t i o n o f a p r o b l e m m i g h t s i m p l y arise f r o m y o u r u s i n g t h e a p p l i c a t i o n , f r o m r e s e a r c h , o r (in v e r y s p e c i a l c a s e s ) f r o m a s t r o k e o f d e s i g n g e n i u s . F o r e x a m p l e , y o u m i g h t r e w r i t e a sort a l g o r i t h m t o i n c r e a s e its s o r t i n g speed w h e n the n u m b e r of items exceeds s o m e threshold. Y o u also might r e o r g a n i z e y o u r c o d e s o that it m a k e s m o r e s e n s e t o a n o t h e r p r o g r a m m e r . Finally, y o u m i g h t d e c i d e that a n e n t i r e l y d i f f e r e n t d e s i g n a p p r o a c h is b e t t e r . Y o u m i g h t d i s c o v e r (by r e u s i n g a n a p p l i c a t i o n i n a n e w s i t u a t i o n ) that a t y p e y o u c r e a t e d f o r a n a p p l i c a t i o n c a n b e i m p r o v e d b y r e d e s i g n i n g it o r b y r e c o m p o s i n g it i n t o a d i f f e r e n t g r o u p o f o b j e c t s . S t r u c t u r e d t e c h n i q u e s (witho u t O O P ) i m p l i c i t l y a s s u m e that y o u h a v e a c o m p l e t e u n d e r s t a n d i n g o f t h e a p p l i c a t i o n a n d t h e w o r l d it r e p r e s e n t s b e f o r e y o u b e g i n c o d i n g it, a n d that t h e
389
390
Part I I — A d v a n c e d T o p i c s
p r o g r a m m e r or designer either d o e s not m a k e mistakes or learns from those mistakes. I n short, structured techniques d o not l e n d themselves well to internal changes. O b j e c t - o r i e n t e d p r o g r a m m i n g l a n g u a g e s s u c h as T u r b o P a s c a l f o r W i n d o w s a t t e m p t t o offer t h e b e s t o f b o t h w o r l d s , w i t h t e c h n i q u e s f o r c r e a t i n g a p p l i c a t i o n s that c a n a d a p t easily t o e x t e r n a l o r i n t e r n a l c h a n g e s . If y o u ' r e u s i n g O O P f o r y o u r a p p l i c a t i o n d e s i g n , y o u a n d y o u r i d e a s c a n g r o w easily as t h e needs of the users of your application grows. Y o u d o not p r e s u m e to k n o w e v e r y t h i n g a b o u t t h e a p p l i c a t i o n a n d its " u n k n o w n " u s e r s b e f o r e y o u b e g i n t o c o d e . Y o u c a n n o t k n o w e v e r y t h i n g a b o u t a n y t h i n g that is t h e least bit c o m p l e x . Y e t that is e x a c t l y w h a t m a n y a p p l i c a t i o n d e s i g n p h i l o s o p h i e s h a v e a s s u m e d all a l o n g . A p p l i c a t i o n p r o j e c t s d o n o t u s u a l l y b e c o m e disasters d u r i n g a p p l i c a t i o n development. Afterward, w h e n the worlds, the users, or the designers' and programmers' understanding of the application changes, they can b e c o m e d i s a s t e r s . T y p i c a l l y , a p p l i c a t i o n s d o n o t e v o l v e ; t h e y drift t o w a r d o b s o l e s c e n c e as t h e y b e c o m e less a n d less a p p r o p r i a t e f o r t h e n e w v e r s i o n o f t h e p r o b l e m s t h e y w e r e s u p p o s e d t o s o l v e . If a p p l i c a t i o n s are a p p r o p r i a t e l y d e s i g n e d a r o u n d objects, they have a g o o d c h a n c e to survive. F o r e x a m p l e , c o n s i d e r y o u r s e l f a n d h o w y o u interact w i t h t h e w o r l d . Y o u b e g i n by collecting the best information y o u can, a n d t h e n y o u create (suppose d l y i n y o u r b r a i n ) a m o d e l o f t h e w o r l d b a s e d o n that i n f o r m a t i o n . (This p r o c e s s is h a p p e n i n g , o f c o u r s e , at b r a i n - w a v e s p e e d . T h e n y o u b e h a v e b a s e d o n the m o d e l . Y o u r m o d e l is n o d o u b t f l a w e d ; m o r e o r less a p p r o p r i a t e o r g o o d e n o u g h for y o u t o survive ( s o u n d s i m p e r f e c t , scary, b u t a l m o s t a s s u r e d l y t r u e ) . A s y o u p r o c e e d t h r o u g h y o u r life, y o u g a i n e x p e r i e n c e ( e x t e r n a l factors) a n d h a v e n e w t h o u g h t s ( i n t e r n a l factors) that l e a d y o u t o c h a n g e y o u r c a r e f u l l y b u i l t , f l a w e d m o d e l . Y o u might even develop multiple models to represent the world's various aspects a n d complexities. M a n y of these m o d e l s y o u regularly update in response to n e w technology, n e w programming techniques. For example, y o u r perception of h o w a compiler works or the ways y o u c o m m u n i c a t e can l e a d y o u t o c h a n g e y o u r m o d e l . O t h e r m o d e l s , p e r h a p s less d e p e n d e n t o n n e w t e c h n i q u e s , m i g h t c o n t i n u e t o w o r k , a n d y o u m i g h t s e l d o m (if ever) u p d a t e them. I n this s c e n a r i o , y o u r life c o n s i s t s o f m o d i f y i n g p a r t s o f y o u r m o d e l (in response to n e w external and internal information), a n d not modifying other p a r t s . Y o u are c o n t i n u a l l y l e a r n i n g f r o m y o u r m o d e l , a n d y o u c h a n g e t h e m o d e l a c c o r d i n g l y . T y p i c a l l y , if a n y m o d e l s t o p s c h a n g i n g , c h a n c e s are that it n o l o n g e r is i n s t e p w i t h t h e w o r l d . I n o n e s e n s e , a m o d e l is a n i n d i c a t o r o f l e a r n i n g and process.
1 3 — D e s i g n i n g W i n d o w s Applications
A n a p p l i c a t i o n is a n e x p r e s s i o n o f y o u r c u r r e n t u n d e r s t a n d i n g o f a n e x t e r n a l p r o b l e m a n d y o u r ability t o r e p r e s e n t it w i t h its s o l u t i o n s . T h u s , t h e d e s i g n a n d t h e e x p r e s s i o n o f t h e d e s i g n are i n e x o r a b l y c o n n e c t e d . T h e p r o b l e m c h a n g e s ; y o u r v i e w o f t h e p r o b l e m c h a n g e s ; a n d y o u r ability t o d e s i g n a n d develop an application changes. A g o o d design philosophy (whether for W i n d o w s or not) must support a v i e w that a n t i c i p a t e s c h a n g e . H e r e are a f e w i d e a s t o k e e p i n m i n d w h e n y o u are d e s i g n i n g a p p l i c a t i o n s : 1. A c k n o w l e d g e that y o u c a n n o t k n o w e v e r y t h i n g a b o u t a p r o b l e m o r a n a p p l i c a t i o n b e f o r e y o u d e s i g n it. D o n o t e v e n try. A c c e p t that t h e r e are s o m e t h i n g s a b o u t a n a p p l i c a t i o n that y o u c a n l e a r n o n l y b y d e s i g n i n g a n d u s i n g it. 2. T r y t o g e t s o m e f o r m o f t h e a p p l i c a t i o n w o r k i n g as s o o n as p o s s i b l e , and use each application forerunner to improve your understanding of the p r o b l e m and application. Y o u r early v e r s i o n s o f t h e a p p l i c a t i o n m i g h t b e o n l y v a g u e i m i t a t o r s o f f u t u r e — m o r e p e r f e c t — v e r s i o n s . Let y o u r a p p l i c a t i o n s reflect t h e e v o l u t i o n o f y o u r i d e a s . R e f i n e a n d m o d i f y as y o u l e a r n m o r e . O b j e c t oriented programming encourages change. Use objects to explore. A n a d d i t i o n a l , a n d p e r h a p s s u b t l e , a s p e c t o f o b j e c t - o r i e n t e d d e s i g n is that it e n c o u r a g e s y o u n o t t o s p e n d t o o m u c h t i m e c r e a t i n g a n a p p l i c a t i o n . It e n c o u r a g e s y o u n o t t o try t o s o l v e p r o b l e m s that n e v e r arise. A l s o , o b j e c t - o r i e n t e d d e s i g n t e n d s t o i s o l a t e t h e effects o f o n e part o f a s y s t e m f r o m o t h e r s s o that c h a n g i n g o n e part o f a n a p p l i c a t i o n s h o u l d not disrupt other parts. 3. P l a n t o c h a n g e t h e d e s i g n , n o t just t h e a p p l i c a t i o n , as y o u g o . T h i s d o e s n o t m e a n " t h r o w a w a y parts r e c k l e s s l y , " b u t r a t h e r "start s o m e p l a c e r e a s o n a b l e , a n d let t h e d e s i g n g r o w as y o u l e a r n a b o u t t h e p r o b l e m a n d t h e a p p l i c a t i o n . " I n o t h e r w o r d s , a v o i d static d e s i g n s . A s s u m e f r o m t h e b e g i n n i n g that t h e a p p l i c a t i o n h a s t o c h a n g e . 4. E x p e c t t o m a k e m i s t a k e s . T h e b e s t w a y t o f i n d o u t w h e t h e r y o u h a v e m a d e a m i s t a k e is t o u s e t h e a p p l i c a t i o n . C h a n c e s are that y o u r m i s t a k e s c a n b e i s o l a t e d i n s i n g l e o b j e c t s , a n d t h u s y o u d o n o t h a v e t o t h r o w e v e r y t h i n g a w a y at o n c e . I n s t e a d , y o u m o d i f y t h e a p p l i c a t i o n , part b y part, t o reflect t h e e v o l u t i o n o f y o u r l e a r n i n g a b o u t t h e a p p l i c a t i o n a n d its u s e r s .
391
392
Part I I — A d v a n c e d T o p i c s
Object-Oriented Application Design It w o u l d b e s o - o - o n i c e , b u t u n f o r t u n a t e l y s o - o - o u n e x p e c t e d , if p r o g r a m m e r s a n d users h a d perfect k n o w l e d g e about a n application o r the p r o b l e m the a p p l i c a t i o n a d d r e s s e s . U n f o r t u n a t e l y , this is s e l d o m t h e c a s e . First, y o u p r o b a b l y c a n n o t d e l u d e y o u r s e l f i n t o b e l i e v i n g that y o u k n o w everything about a n application o r p r o b l e m . S e c o n d , the application y o u are developing a n d the techniques (the compilers, the languages, the hardware) y o u a r e u s i n g t o d e s i g n t h e a p p l i c a t i o n a r e e v o l v i n g as w e l l . Y o u a p p r o x i m a t e , a n t i c i p a t e , s p e c u l a t e , a n d a d d n e w t o o l s t o y o u r t o o l b o x at e v e r y t u r n . N a t u r a l l y , y o u w a n t y o u r a p p l i c a t i o n s t o reflect y o u r n e w p o w e r t o o l s . O n the m o r e personal side, y o u often make two convenient (and probably erroneous) approximations: 1. Y o u , t h e d e s i g n e r , c o m p l e t e l y u n d e r s t a n d t h e p r o b l e m b e f o r e b e g i n ning the design. 2. U s e r s r e a d w h a t e v e r i n f o r m a t i o n y o u g i v e t h e m b e f o r e u s i n g t h e a p p l i c a t i o n , a n d t h u s k n o w t h e a p p l i c a t i o n w e l l b e f o r e firing it u p . ( D e m a n d i n g this k i n d o f p e r f e c t i o n f r o m yourself, t h e a p p l i c a t i o n , o r t h e u s e r s s i m p l y is n o t s e n s i b l e . ) During development, object-oriented design encourages y o u to a d d , c h a n g e , a n d d e l e t e o b j e c t s at a n y t i m e — w h e n e v e r t h e m o o d m o v e s y o u . It's a s s u m e d t h a t , b e c a u s e e v e r y p r o b l e m is i n p r o g r e s s , e v e r y a p p l i c a t i o n a d d r e s s i n g a p r o b l e m is i n p r o g r e s s ; it's d y n a m i c . F o r e x a m p l e , s u p p o s e that y o u a r e d e s i g n i n g a n e d i t o r . Y o u b e g a n ( s e n s i b l y e n o u g h ) b y c r e a t i n g a w i n d o w e d i t o r t y p e , w h i c h c a n p r o c e s s text t h r o u g h a b u f f e r , m o v e a c u r s o r a r o u n d i n t h e b u f f e r , f i n d text, insert a n d d e l e t e text, a n d s o o n . A s t h e a p p l i c a t i o n p r o g r e s s e s ( a n d t h e t y p e d e f i n i t i o n d e v e l o p s ) , s o d o e s t h e n e e d t o test it. Y o u d e c i d e that t h e s i m p l e s t w a y t o test t h e a p p l i c a t i o n is t o w r i t e t h e text i n t h e b u f f e r t o a file a n d r e a d it b a c k f r o m t h e file t o t h e b u f f e r . T o m a k e a w i n d o w e d i t o r file a w a r e , y o u m u s t g i v e it s o m e k n o w l e d g e o f i n s e r t i n g a n d r e t r i e v i n g text f r o m files. T h e file h a s t o u n d e r s t a n d h o w t o o p e n a n d c l o s e files, h o w t o r e c o g n i z e t h e e n d o f l i n e s a n d t h e e n d o f files, a n d so o n . Y o u c a n a d d streams a n d whatever else y o u want t o t h e editor. T h e n y o u s h o u l d b e g i n t e s t i n g t h e f e a t u r e s o f t h e f ile_editor, o n e b y o n e . S e v e r a l t h i n g s o c c u r . First, b y u s i n g t h e a p p l i c a t i o n (as a file e d i t o r ) , y o u (the d e s i g n e r " t u r n e d " u s e r ) b e g i n t o s e e p o s s i b i l i t i e s y o u h a d n o t i m a g i n e d b e f o r e . Y o u m i g h t d e c i d e that m o r e t h a n o n e file c a n b e o p e n e d at a t i m e , that t h e files c a n e x c h a n g e i n f o r m a t i o n , a n d that t h e size o f t h e files is i m p o r t a n t . I n s h o r t , t h e f i l e e d i t o r t y p e is u n d e r g o i n g a " r e u s e test."
13—Designing Windows Applications
I n a r e u s e test, y o u a s k , " D o e s t h e a p p l i c a t i o n a d a p t easily t o n e w s i t u a t i o n s ? " If y o u d e c i d e that it d o e s n o t , y o u b e g i n m o d i f y i n g t h e t y p e t o m a k e it m o r e g e n e r a l . I n this s c e n a r i o , t h e a p p l i c a t i o n b e c o m e s t o o g e n e r a l a n d fails t h e " c o m p l e x i t y test." Y o u h a v e e x p a n d e d t h e a p p l i c a t i o n t o o m u c h ; it is t o o c o m p l e x . S u d d e n l y , b e c a u s e y o u a r e r u n n i n g o u t o f m e m o r y , y o u h a v e t o k e e p b e t t e r tabs o n m e m o r y u s e . K e e p i n g tabs m e a n s that y o u h a v e t o c h a n g e s o m e t h i n g e l s e , w h i c h c a u s e s a f e w m o r e p r o b l e m s that affect o t h e r p a r t s o f t h e a p p l i c a t i o n . T h e f ile_editor t y p e n o w is failing t h e " o v e r a m b i t i o u s o b j e c t test." It tries t o d o t o o m u c h , a n d as a result c a n n o t b e r e u s e d . A n e v o l v e d t y p e , e s p e c i a l l y o n e that h a s s u r v i v e d several r e d e s i g n s , o f t e n b e c o m e s t o o c o m p l e x f o r f u r t h e r e v o l u t i o n . I f t h e o b j e c t b e g i n s t o c o n f u s e y o u , it p r o b a b l y h a s a d e s i g n p r o b l e m . C h e c k it o u t a n d r e d e s i g n it, if y o u h a v e t o . I n this e x a m p l e , y o u d i s c o v e r t h e s i m p l e , t i g h t e r d e s i g n that y o u s h o u l d h a v e c r e a t e d ; a t e x t b u f f er t y p e that c a n h a n d l e b i g c h u n k s o f text a n d k e e p track o f t h e m e m o r y safety p o o l . F o r e x a m p l e , it c h e c k s f o r l o w m e m o r y c o n d i t i o n s b e f o r e it r e a d s t h e e n t i r e file. Y o u d e c i d e t o m a k e this l o w - l e v e l m e m o r y a w a r e n e s s a part o f t h e b a s e file e d i t o r . N o w y o u d e r i v e a m u l t i p l e file e d i t o r f r o m this s m a r t e r , still single-file e d i t o r that c a n k e e p track o f m e m o r y u s e . T h i s t y p e n o w c a n b e u s e d as a b a s e t y p e f o r o t h e r k i n d s o f file e d i t o r s . T h e p o i n t o f this h y p o t h e t i c a l r a m b l e is t h i s : y o u d e s i g n , e x p e r i m e n t , a n d c r e a t e every t i m e y o u interact w i t h t h e a p p l i c a t i o n o r p r o b l e m . O n l y i n t h e simplest cases are y o u able to u n d e r s t a n d the p r o b l e m completely a n d get t h e d e s i g n right t h e first t i m e .
A Tao of Windows Y o u m i g h t n o t k n o w h o w t o p u t a p a r t i c u l a r d a t a field o r m e t h o d i n a t y p e . Y o u m i g h t t h i n k that it t a k e s y e a r s o f e x p e r i e n c e t o d e s i g n t y p e s p r o p e r l y . T o h e l p d i s p e l this m y t h a n d t o k e e p y o u f r o m w a s t i n g t o o m u c h t i m e o n early d e s i g n d e c i s i o n s , t h e b o o k c o v e r s a relatively s i m p l e , b u t g o o d b e g i n n i n g t e c h n i q u e f o r describing the creation and d e v e l o p m e n t of types. This technique (based o n the d e s i g n p h i l o s o p h y r e c o m m e n d e d i n The Tao of Objects, m y first b o o k ) r e c o g n i z e s five s t a g e s o f o b j e c t d e s i g n : 1. Object discovery. Try t o determine w h i c h objects solve the p r o b l e m s your application addresses. B e m o r e concerned with the boundaries and the gross interactions b e t w e e n objects than with h o w the objects work. 2. Object construction. A s y o u start c r e a t i n g o b j e c t s , y o u d i s c o v e r that y o u w a n t d a t a fields a n d m e t h o d s t o m a k e t h e o b j e c t w o r k p r o p e r l y . Y o u a l s o m i g h t d i s c o v e r that y o u w a n t o t h e r o b j e c t s e i t h e r as s u b j e c t s
393
394
Part I I — A d v a n c e d T o p i c s
(object m e m b e r s o f y o u r object), or to w o r k with s o m e object in y o u r a p p l i c a t i o n . A n e x c e l l e n t t e c h n i q u e d u r i n g o b j e c t c r e a t i o n is t o d e v e l o p test a p p l i c a t i o n s ( m i n i - a p p l i c a t i o n s ) for e a c h t y p e y o u c r e a t e . A s y o u w r i t e t h e test a p p l i c a t i o n s , y o u m i g h t u n c o v e r f u r t h e r t y p e r e q u i r e ments. 3. Application construction. As y o u collect objects in the application, the needs o f the application might require n e w behavior in existing objects, or entirely n e w objects. 4. Application extension. A p p l i c a t i o n e x t e n s i o n is a n i n t e g r a l part o f a p p l i c a t i o n d e v e l o p m e n t . B e h a v i o r is f o c u s e d i n o b j e c t s . O b j e c t s c h a n g e in order to c h a n g e applications. 5. Object reuse. W h e n y o u u s e o l d o b j e c t t y p e s t o b u i l d n e w a p p l i c a t i o n s , n e w n e e d s b e n d a n d s t r e t c h t h e d e s i g n o f y o u r o l d o b j e c t t y p e s . If a n o l d t y p e d o e s n o t fit easily i n t o a n e w s i t u a t i o n , it s h o w s u p i n t h e s e p r o s p e c t i v e n e w a p p l i c a t i o n s , a n d y o u s e e t h e p a r t s that h a v e t o b e c h a n g e d . T h e m o s t u s e f u l o b j e c t s are u s u a l l y t h e " e v o l v e d " o n e s that h a v e g o n e t h r o u g h several p r o j e c t s . N o t i c e that at e a c h s t a g e o f a p p l i c a t i o n d e v e l o p m e n t y o u g e t n e w i n f o r m a t i o n t o g u i d e y o u t h r o u g h t y p e d e s i g n . A l t h o u g h it w o u l d b e difficult a n d t i m e - c o n s u m i n g t o a n t i c i p a t e this i n f o r m a t i o n i n a " p r e - p r e e m p t i v e " d e s i g n , it c o m e s t o y o u n a t u r a l l y as y o u p a s s t h r o u g h t h e a p p r o p r i a t e s t a g e . A l t h o u g h this style o f O O P d e s i g n u s e s a d i f f e r e n t p h i l o s o p h y t h a n p a s t s t r u c t u r e d m e t h o d o l o g i e s , it is n o t a b i g d e a l t o i m p l e m e n t . ( M a n y p r o g r a m m e r s t e n d t o w o r k this w a y r e g a r d l e s s o f w h a t m e t h o d o l o g y t h e y are s u p p o s e d t o b e f o l l o w i n g . ) A s a g u i d e l i n e : d o n ' t f o r c e y o u r s e l f t o k n o w e v e r y t h i n g at t h e b e g i n n i n g . I n s t e a d , a l l o w y o u r s e l f t o l e a r n as y o u g o a l o n g .
Object Discovery T h e first o f t h e five s t a g e s , t h e i c e b r e a k e r , d e s e r v e s a c l o s e r l o o k . W h a t m e t h o d s s h o u l d y o u u s e t o d i s c o v e r o b j e c t s ? H e r e are a f e w g u i d e l i n e s : • L o o k for t h e " e x t e r n a l f a c t o r s " that are n e c e s s a r y for i n t e r a c t i o n s between objects and the world outside the application. Y o u might d i s c o v e r s o m e d a t a f i e l d s a n d m e t h o d s at this p o i n t , b u t y o u m o s t l y just d i s c o v e r t h e o b j e c t s t h e m s e l v e s . • F i n d n a t u r a l b o u n d a r i e s . If y o u t h i n k o f s o m e t h i n g w i t h b o u n d a r i e s i n t h e w o r l d , c h a n c e s are that it s h o u l d b e a b o u n d a r y i n a n o b j e c t as w e l l . F o r e x a m p l e , t h e b o u n d a r y b e t w e e n m e m o r y a n d d i s k is o f t e n r e f l e c t e d as a b o u n d a r y i n y o u r a p p l i c a t i o n .
13—Designing Windows Applications
• S e e k t h e b e h a v i o r a n d d a t a that are d u p l i c a t e d i n t h e a p p l i c a t i o n . F o r e x a m p l e , a k e y b o a r d is a c o l l e c t i o n o f b u t t o n s , s o " b u t t o n " is a n obvious object. A simulation m i g h t consist o f customers a n d b a n k tellers. A t r u c k has f o u r w h e e l s , a s p a r e , f o u r d o o r s , a n d s o o n . • F l e s h o u t t h e least c o m m o n d e n o m i n a t o r s o f a n a p p l i c a t i o n (its s m a l l e s t u n i t s ) . F o r e x a m p l e , if y o u are m a n i p u l a t i n g text, t h e s m a l l e s t u n i t is e i t h e r a character, a w o r d , a l i n e , o r a g r o u p o f text w i t h t h e s a m e a t t r i b u t e s ; d e p e n d i n g o n how y o u i n t e n d t o u s e t h e text. • Try t o i m a g i n e n e w s i t u a t i o n s i n w h i c h y o u m i g h t u s e t h e t y p e . D o y o u t h i n k it w o r k s t h e r e a n d a d a p t s easily? F o r e x a m p l e , c o n s i d e r a b i g g e r v e r s i o n o f y o u r a p p l i c a t i o n . D o e s it w o r k ? • S e p a r a t e t h e a s p e c t s o f t h e a p p l i c a t i o n that c h a n g e f r o m t h o s e that probably will not c h a n g e . • M a k e a list o f t h e d a t a that y o u r a p p l i c a t i o n has t o k n o w a b o u t . L o o k f o r d a t a that s e e m s t o b e l o n g t o g e t h e r . C o l l e c t t h e s e d a t a e l e m e n t s into an object. • L o o k for b e h a v i o r y o u w a n t t o hide o r d a t a y o u w a n t t o p r o t e c t f r o m careless m a n i p u l a t i o n . This k i n d o f behavior a n d data usually b e l o n g s inside an object. • L o o k for t h e c o m m o n i n t e r f a c e s b e t w e e n o b j e c t s . F i n d o u t w h a t o b j e c t s have i n c o m m o n . P u t c o m m o n a s p e c t s i n t o a n abstract b a s e type. • L o o k for i n i t i a l i z a t i o n a n d c l e a n u p activities. T h e s e activities s h o u l d b e handled b y c o n s t r u c t o r s a n d d e s t r u c t o r s . I n i t i a l i z a t i o n a n d c l e a n u p m i g h t help y o u d i s c o v e r t y p e s .
Star Wars and Dances: The Sequel As a n e x a m p l e , c o n s i d e r a v i d e o - s t o r e m a n a g e m e n t a p p l i c a t i o n that w a s d i s c u s s e d i n The Tao of Objects. C o n s i d e r this v e r s i o n a s e q u e l t o that o n e , b e c a u s e t h e r e has b e e n a l o n g t i m e t o reconsider t h e p r o b l e m a n d g i v e it a n e w Windows f a c e . If y o u have n o t read t h e b o o k , d o n ' t w o r r y , this c h a p t e r w i l l b r i n g y o u u p t o snuff. T h e v i d e o - s t o r e m a n a g e m e n t a p p l i c a t i o n tries t o s o l v e t h e p r o b l e m s i n h e r e n t i n s e t t i n g u p a u s e r - d r i v e n v i d e o s t o r e . T h e v i d e o b u f f (that is, t h e user) c o m e s i n t o t h e store w i t h a t y p e o f v i d e o i n m i n d , b u t he d o e s n o t k n o w t h e title o f any specific v i d e o .
395
396
Part I I — A d v a n c e d T o p i c s
T y p i c a l l y i n this s c e n a r i o , t h e u s e r w a l k s a r o u n d t h e s t o r e a n d c h e c k s t h e various video boxes, w h i c h contain a three- or four-paragraph description of w h a t t h e m o v i e d i s t r i b u t o r w a n t s t h e u s e r t o t h i n k . (MovieMagic, Part3 is a Star Wars c l o n e , w i t h o v e r t o n e s o f Lawrence of Arabia a n d Dances with Wolves r o l l e d i n t o o n e fine p i c t u r e . E v e r y s i n g l e r e v i e w e r , at least all t h e o n e s m e n t i o n e d o n t h e b o x , l o v e d it.) W h a t t h e u s e r u n f o r t u n a t e l y d o e s n o t l e a r n f r o m t h e b o x is w h a t t h e v i d e o is a b o u t , t h e l e v e l o f v i o l e n c e , w h e t h e r o t h e r f o l k s h a v e e n j o y e d t h e v i d e o , a n d n o t just w h a t a f e w c a r e f u l l y s e l e c t e d , a n d c a r e f u l l y q u o t e d , critics t h o u g h t . N o w c o n s i d e r a n alternative s c e n a r i o . S u p p o s e that t h e u s e r c a n w a l k i n t o a v i d e o s t o r e i n w h i c h t h e r e are n o s h e l v e s filled w i t h v i d e o b o x e s . I n s t e a d , s h e s t e p s u p t o a c o m p u t e r (or t o a p e r s o n o p e r a t i n g a c o m p u t e r ) a n d says, " T o d a y I a m i n t h e m o o d f o r a m o v i e w i t h a r o m a n t i c t h e m e set i n t h e n e a r f u t u r e , w h i c h m y favorite r e v i e w e r l i k e d , a n d w h i c h h a s n o v i o l e n c e , a n d w h i c h h a s a s o c i a l t h e m e w i t h m o d e r a t e levels o f n u d i t y . " T h e c o m p u t e r t h e n c h e c k s t h e u s e r ' s file t o s e e w h a t s h e h a s v i e w e d o r l i k e d i n t h e past a n d retrieves t h e v i d e o titles that s h e h a s n o t c h e c k e d o u t b e f o r e , m i n u s t h e o n e s that are a l r e a d y c h e c k e d o u t . T h e c o m p u t e r n u m b e r s t h e m corresponding to her personal profile. S h e c a n g e t e v e n m o r e i n f o r m a t i o n a b o u t e a c h o f t h e titles; i n c l u d i n g t h e actors, directors, a n d so o n ; reviews o f the videos; biographies o f the p e o p l e i n v o l v e d i n m a k i n g t h e m o v i e ; a n d e v e n g r a p h i c d e s c r i p t i o n s (bit m a p s , a n d s o on) depicting s o m e aspect of the video. In other words, the user gets a m o r e detailed view o f the videos in the store based o n the information users supply. (It m i g h t e v e n b e s o m u c h f u n t o p l a y a r o u n d w i t h t h e v i d e o l o o k - u p s y s t e m that v i d e o l o o k - u p b e c o m e s an arcade fad.) W h e n t h e u s e r d e c i d e s o n a v i d e o , t h e c l e r k g e t s it f r o m a stack ( n o t i c e that t h e s h e l f s p a c e r e q u i r e d f o r a s t o r e like this is s m a l l e r ) a n d u s e s a b a r - c o d e reader to enter the n u m b e r into the computer, w h i c h generates a receipt a n d d o e s all t h e n e c e s s a r y b o o k k e e p i n g . Part o f this is o b v i o u s l y a n e l a b o r a t e d a t a b a s e s y s t e m ( w h i c h h a s t o b e easily u p d a t e d at r e g u l a r i n t e r v a l s , f r o m v a r i o u s s o u r c e s i n c l u d i n g t h e c u s t o m ers t h e m s e l v e s ) . Part o f it is t h e u s e r i n t e r f a c e , part t h e b a r - c o d e i n t e r f a c e , a n d part t h e b o o k k e e p i n g s y s t e m . Try t o d e s c r i b e this a p p l i c a t i o n u s i n g O O P . First, m a k e f o u r lists that r e p r e s e n t : 1.
Data
2.
Events
3.
Behavior
4. O b v i o u s o b j e c t s
13—Designing Windows Applications
T h e d a t a list c o n s i s t s o f i n f o r m a t i o n t h e a p p l i c a t i o n h a s t o k n o w o r r e m e m b e r . T h e e v e n t list c o n s i s t s o f e v e n t s that t h e a p p l i c a t i o n h a s t o r e s p o n d t o . T h e b e h a v i o r list is w h a t t h e a p p l i c a t i o n h a s t o d o . T h e o b v i o u s - o b j e c t s list i n c l u d e s a n y t h i n g that i m m e d i a t e l y s p r i n g s t o m i n d . F o r e x a m p l e , y o u k n o w f r o m t h e start y o u w a n t t o u s e a s t a n d a r d W i n d o w s a p p l i c a t i o n i n t e r f a c e that u s e s m e n u s a n d s t a n d a r d m o u s e clicks t o s e l e c t i t e m s f r o m t h e m e n u s . D o n o t try t o p e r f e c t t h e s e lists i n t h e b e g i n n i n g ; just w r i t e d o w n w h a t y o u c a n t h i n k of. R e m e m b e r that t h e act o f c r e a t i n g t h e a p p l i c a t i o n ( n o t t h e c r e a t i o n o f lists) e n s u r e s that t h e a p p l i c a t i o n is c o m p l e t e . T h e lists o n l y act as "instigators" to h e l p y o u discover the objects for y o u r application. By l o o k i n g at t h e lists, y o u s e e p a t t e r n s that s u g g e s t o b j e c t s . W h e n y o u d i s c o v e r e n o u g h o b j e c t s t o d e s c r i b e t h e a p p l i c a t i o n w i t h o u t t h e lists, t h r o w t h e lists away. F o r s o m e a p p l i c a t i o n s , t h e d a t a list g i v e s y o u t h e m o s t i n f o r m a t i o n , a n d it is easiest t o t h i n k o f i n f o r m a t i o n f o r that list. B e c a u s e W i n d o w s a p p l i c a t i o n s are p r i m a r i l y e v e n t - d r i v e n , y o u s h o u l d a n t i c i p a t e e v e n t s a n d r e s p o n s e s t o e v e n t s i n t h e s e lists. H o w y o u d e f i n e t h e s e lists d e p e n d s o n h o w y o u t h i n k a b o u t a p r o b l e m . I n g e n e r a l , h o w e v e r , it d o e s n o t m a t t e r m u c h h o w y o u o r d e r o r a s s e m b l e t h e s e lists, b e c a u s e all y o u are trying t o d o is d i s c o v e r t h e o b j e c t s f o r y o u r a p p l i c a t i o n s . S o m e o f t h e i t e m s o n t h e list m i g h t n o t e v e n h e l p y o u d i s c o v e r a n y objects, so y o u discard t h e m mercifully. A g a i n , r e m e m b e r : it is O K t o m a k e m i s t a k e s , a n d it is O K t o o m i t t h i n g s y o u m i g h t w a n t later. A n o b j e c t - o r i e n t e d a p p l i c a t i o n a l l o w s y o u t o easily m o d i f y t h e application w h e n y o u discover inconsistencies. B e c a u s e objects k e e p their data a n d behaviors to themselves, changes in the application tend to localize t h e m s e l v e s — a m a j o r p l u s as t h e a p p l i c a t i o n e v o l v e s . W h e n y o u m a k e t h e d a t a list, g r o u p t o g e t h e r d a t a i t e m s that y o u are fairly sure s h o u l d b e an object. For e x a m p l e , a "person" object probably contains data f i e l d s f o r n a m e , a d d r e s s , a g e , s e x , m e m b e r s h i p n u m b e r , a n d a list o f v i d e o s this p e r s o n h a s c h e c k e d o u t . It m i g h t m a k e s e n s e t o c o l l e c t all t h e s e f i e l d s i n a n object. W i n d o w s e v e n t s are a l m o s t as o b v i o u s as d a t a o r b e h a v i o r . A m o u s e , f o r e x a m p l e , g e n e r a t e s a n e v e n t that W i n d o w s r o u t e s t o t h e c o r r e c t w i n d o w . A m e n u s e l e c t i o n is a n e v e n t , a n d s o o n . B e c a u s e W i n d o w s a p p l i c a t i o n s d e p e n d s o m u c h o n e v e n t s s u c h as t h e m o u s e a n d m e n u s , it m a k e s s e n s e t o always k e e p events in the forefront. Behavior s h o u l d be responses to events. For e x a m p l e , y o u can i m p l e m e n t a context-sensitive h e l p system d e p e n d i n g o n t h e a p p l i c a t i o n ' s c u r r e n t c o n t e x t (or s t a t e ) . Every t i m e t h e u s e r c h a n g e s c o n t e x t (by m a k i n g a s e l e c t i o n f r o m a m e n u , f o r e x a m p l e ) , t h e " h e l p state c o n t e x t " c h a n g e s . W h e n t h e u s e r asks f o r h e l p , t h e t y p e o f h e l p g i v e n d e p e n d s o n t h e state (that is, t h e c o n t e x t ) . L o o k i n g at a c o l l e c t i o n o f e v e n t s o f t e n h e l p s y o u discover appropriate objects.
397
398
Part I I — A d v a n c e d T o p i c s
R e m e m b e r that this is a n p r o c e s s o f i t e r a t i o n ; a n a p p r o a c h i n t e n d e d o n l y to give y o u a f r a m e w o r k — s t e p s to f o l l o w to get y o u started. T h e framework m i g h t c h a n g e as y o u s k e t c h o u t t h e a p p l i c a t i o n , b u t i n t h e e n d it is u n i m p o r t a n t . Y o u r g o a l is t o d e t e r m i n e w h a t y o u r o b j e c t s s h o u l d b e a n d w h a t y o u w a n t . A s y o u fill i n t h e d e t a i l s , y o u d i s c o v e r n e w o b j e c t s a n d n e w r e l a t i o n s h i p s b e t w e e n o b j e c t s . T h a t ' s fine; that is h o w it is s u p p o s e d t o w o r k . For example, the video-store application might begin with the following f o u r lists:
Data List:
User Name Address User ID Video List (videos checked out in the past) User's Video Preference List
Video Name Quantity Price Structure Video Evaluation List
Rental Transaction Date User Video List
Business Report Date Range Data List Data Format Calculations
Event List:
User asks for some specific range of videos
13—Designing W i n d o w s Applications
User asks for further data on a specific video's Reviews Local opinions Box description/pictures Personnel: actors, directors, and so on. Theater runs and receipts User checks out video(s). User asks for computer-generated video selection based on the user's profile. User asks for best selling selection based on some level of popularity. User returns some or all checked out videos; possibly checks out more. User 'reviews' video just viewed. New videos arrive. New video data arrives. Old videos are discarded/replaced.
Behavior List:
Create new user profile. Create new video profile. Create video request profile; combine with user profile and search for appropriate videos. Create management report. Check out video. Check in video. Update profiles.
399
400
Part I I — A d v a n c e d T o p i c s
Obvious Objects:
Objects for connecting to Windows Database
(use collections)
Error Handler Time & Date Menus
(use ObjectWindows for these)
(use Error)
(use System)
(use ObjectWindows)
Dialogs
(use ObjectWindows)
File Dialogs
(use ObjectWindows)
Other controls, list boxes, buttons, and so on (use ObjectWindows)
Begin Discovering Objects B y this j u n c t u r e , y o u m i g h t h a v e g l i m p s e d s o m e o b j e c t s ; f o r e x a m p l e , i n t h e D a t a List w h e r e s o m e d a t a o b v i o u s l y b e l o n g s t o g e t h e r . I n t h e v i d e o e x a m p l e , User, V i d e o , R e n t a l T r a n s a c t i o n , B u s i n e s s R e p o r t , a n d s o o n , s u g g e s t o b j e c t s . B e h a v i o r u s u a l l y requires m o r e w o r k . T o h e l p y o u v i s u a l i z e , y o u m i g h t w a n t t o p u t t h e b e h a v i o r i n a " b l o c k c h a r t " as s h o w n i n f i g u r e 1 3 . 3 . N o w c o n s i d e r a n i n d i v i d u a l p a r t a n d b e g i n a n a l y z i n g it f o r o b j e c t s . T h i n k about: • What y o u w a n t that part t o p r o d u c e . (Will t h e b e h a v i o r l e a d t o t h e p r o d u c t i o n o f a n object; will the p r o d u c e r b e a n object?) • What parts d o y o u w a n t t o b e p o r t a b l e , o r at least retargetable (for e x a m p l e , u s e r i n t e r f a c e , o t h e r h a r d w a r e , o p e r a t i n g s y s t e m interface)? Put these in a n object. • D o e s t h e b l o c k d i a g r a m s u g g e s t a n y n e w b o u n d a r i e s that m i g h t reveal n e w o b j e c t s ? F o r e x a m p l e , i n a n e t w o r k i n g s y s t e m , t h e n e t w o r k is a boundary. Y o u might want t o create "transaction objects" t o s e n d across the network. • As y o u discover objects, consider what those objects have to know. S h o u l d t h e y m a i n t a i n this i n f o r m a t i o n t h e m s e l v e s , o r g e t it f r o m a n o t h e r o b j e c t ? T a k e n o t e o f a n y o b j e c t that g i v e s i n f o r m a t i o n , e v e n if it b e l o n g s i n a n o t h e r part.
13—Designing Windows Applications
Block D i a g r a m
Create
user
profile Check
Create video
out
profile C h e c k in
Create
Figure
video
video
video
request
13-3. A block chart.
Y o u don't want your objects to b e c o m e too complex. Just because you w a n t a p a r t i c u l a r o b j e c t d o e s n o t m e a n that t h e o b j e c t s h o u l d b e part o f a s i n g l e t y p e rather t h a n part o f a t y p e hierarchy. If y o u r o b j e c t s are t o o c o m p l e x , y o u w i l l n o t i c e this p r o b l e m d u r i n g t h e o b j e c t - c r e a t i o n p h a s e . A s y o u a d d a n d test f u n c t i o n s , t h i n g s s e e m t o " g o haywire" a n d "get o u t o f hand." It b e c o m e s difficult t o a d d n e w b e h a v i o r b e c a u s e t h e t y p e is m a n a g i n g t o o m u c h itself. T h i s is a n indication that t h e t y p e has t o b e f a c t o r e d into s m a l l e r s e c t i o n s a n d a s s e m b l e d t h r o u g h e i t h e r inheritance or composition. B y f a c t o r i n g t h e t y p e , y o u e n d u p w i t h several t y p e s , a n y o f w h i c h is e a s i e r t o implement b e c a u s e it is e a s i e r t o t h i n k a b o u t .
Wrap-up B y n o w y o u s h o u l d b e t h i n k i n g that d e s i g n i n g Windows a p p l i c a t i o n s is b o t h a n art a n d a s c i e n c e . C r e a t i n g a p p l i c a t i o n s , like art, requires m u c h interpretation o n t h e part o f t h e d e s i g n e r a n d artist. F i n d i n g , c r e a t i n g , a n d recasting objects requires b o t h artistic a n d e n g i n e e r i n g skills. O n t o p o f that, Windows is a G U I : ready-to-roll graphics. Y o u c r e a t e y o u r o b j e c t s f r o m t h e t i m e y o u start t h i n k i n g a b o u t t h e m . Writing t h e m is o n l y t h e o b v i o u s p h a s e o f c r e a t i o n . Y o u start w i t h t h e t y p e f r a m e w o r k , a n d t h e n a d d a n d test b e h a v i o r . D u r i n g a p p l i c a t i o n c o n s t r u c t i o n and extension, y o u may add more to t h e type.
401
402
Part I I — A d v a n c e d T o p i c s
T h u s , object design occurs t h r o u g h o u t the lifetime o f an application in all five p h a s e s o f a p p l i c a t i o n d e v e l o p m e n t : 1. O b j e c t d i s c o v e r y 2. O b j e c t c r e a t i o n 3. A p p l i c a t i o n c o n s t r u c t i o n 4. A p p l i c a t i o n e x t e n s i o n 5. O b j e c t r e u s e U s e r s o n l y p r e t e n d that t h e y c a n f o r c e d e s i g n t o o c c u r w h e n it is c o n v e n i e n t — i n t h e first p h a s e s o f a p r o j e c t — a n d n o t later. T h a t w r a p s u p this part o f t h e i n t r o d u c t o r y s t u d y o f W i n d o w s a p p l i c a t i o n d e v e l o p m e n t u s i n g t h e o b j e c t - o r i e n t e d t e c h n i q u e s o f T u r b o Pascal for W i n d o w s . I h o p e that y o u h a v e l e a r n e d at least this s m a l l p o i n t : t h e s o p h i s t i c a t e d t e c h n i q u e s i n T u r b o Pascal for W i n d o w s c a n h e l p y o u c r e a t e p r o d u c t i v e , c r e a t i v e , a n d flexible W i n d o w s a p p l i c a t i o n s that h a v e t h e b u i l t - i n c a p a c i t y t o e v o l v e as t h e p r o b l e m s t h e y a t t e m p t t o s o l v e i n e v i t a b l y e v o l v e . O b j e c t - o r i e n t e d p r o g r a m m i n g is b o t h a m e t h o d a n d a p h i l o s o p h y , a n d a n i m p o r t a n t t e c h n i q u e for d e v e l o p i n g e v e n t - d r i v e n W i n d o w s a p p l i c a t i o n s . W i n d o w s a n d o b j e c t s ( T u r b o Pascal style) a r e , s o m e say, a d r a m a t i c o n e two punch.
PART T H R E E
REFERENCES
A
REFERENCE
OBJECTWINDOWS OBJECTS T h i s r e f e r e n c e c h a p t e r is a n a l p h a b e t i c a l listing o f t h e O b j e c t W i n d o w s o b j e c t s :
TApplication TBufStream TButton TCheckBox TCollection TComboBox TControl TDialog TDlgWindow TDosStream TEdit TEmsStream TGroupBox
TListBox TMDIClient TMDIWindow TObject TRadioButton TScrollBar TScroller TSortedCollection TStatic TStrCollection TStream TWindow TWindowsObject
406
Part I I I — R e f e r e n c e s
TApplication TApplication is t h e b a s e a p p l i c a t i o n o b j e c t f o r all O b j e c t W i n d o w s a p p l i c a tions. E a c h O b j e c t W i n d o w s application derives a n application object type f r o m TAp plication i n o r d e r t o c o n s t r u c t a s p e c i f i c m a i n w i n d o w f o r t h e a p p l i c a t i o n .
Fields HAccTable KBHandlerWnd MainWindow Name Status
Methods Init CanClose Error ExecDialog InitApplication Initlnstance InitMainWindow MakeWindow MessageLoop ProcessAccels ProcessAppMsg ProcessDlgMsg ProcessMDIAccels Run SetKBHandler ValidWindow
Fields TApplication.HAccTable HAccTable: THandle; (read/write) HAccTable h o l d s a h a n d l e t o a W i n d o w s a c c e l e r a t o r - t a b l e r e s o u r c e ify o u d e f i n e o n e for t h e a p p l i c a t i o n .
A—ObjectWindows Objects
TApplication.KBHandlerWnd KBHandlerWnd: PWindowsOb j e c t ; ( r e a d o n l y ) KBHandle rWnd p o i n t s t o t h e c u r r e n t l y active w i n d o w if t h e w i n d o w ' s k e y b o a r d h a n d l e r m e c h a n i s m is e n a b l e d . ( T h e k e y b o a r d h a n d l e r m e c h a n i s m lets a w i n d o w c o n t a i n i n g controls process keyboard input in dialog fashion. If the k e y b o a r d h a n d l e r m e c h a n i s m is d i s a b l e d f o r t h e active w i n d o w , KBHandler is n i l .
TAppUcation.MainWindow MainWindow: PWindowsOb j e c t ;
(read/write)
MainWindow p o i n t s t o t h e a p p l i c a t i o n ' s m a i n w i n d o w , w h i c h s h o u l d b e i n s t a n t i a t e d b y y o u r a p p l i c a t i o n t y p e ' s InitMainWindow m e t h o d .
TApplication.Name Name h o l d s t h e a p p l i c a t i o n ' s n a m e .
TApplication.Status Status: Integer; Status i n d i c a t e s t h e c u r r e n t state o f a n a p p l i c a t i o n . If Status is g r e a t e r t h a n or e q u a l t o 0 , t h e n t h e a p p l i c a t i o n is o p e r a t i n g s u c c e s s f u l l y .
Methods TApplication.Init constructor Init(AName: PChar); (Override: sometimes) Constructs the application object. • C a l l s TOb j ect. Init • S e t s t h e g l o b a l v a r i a b l e Application t o @Self • S e t s t h e Name field t o AName • S e t s t h e HAccTable field a n d t h e Status field t o 0 • Initializes t h e MainWindow a n d t h e KBHandlerWnd fields t o n i l
407
408
Part I I I — R e f e r e n c e s
If t h e c u r r e n t i n s t a n c e is t h e first i n s t a n c e o f a n a p p l i c a t i o n , Init s e n d s a m e s s a g e t o InitApplication. I f InitApplication s u c c e e d s , Init s e n d s a m e s s a g e t o Initlnstance.
TApplication.CanClose function CanClose: Boolean; virtual; ( O v e r r i d e : s e l d o m ) R e t u r n s T r u e if it's O K f o r t h e a p p l i c a t i o n t o close. B y d e f a u l t , CanClose s e n d s a m e s s a g e t o t h e CanClose m e t h o d o f its m a i n w i n d o w a n d returns that m e t h o d ' s return v a l u e . Rather t h a n override TApplication. CanClose, o v e r r i d e y o u r a p p l i c a t i o n ' s m a i n w i n d o w ' s CanClose method.
TApplication.Error procedure Error(ErrorCode: Integer); virtual; ( O v e r r i d e : s o m e t i m e s ) TApplication.Error p r o c e s s e s t h e e r r o r s i d e n t i f i e d b y t h e e r r o r v a l u e p a s s e d i n ErrorCode. T h e s e e r r o r s a r e g e n e r a t e d b y t h e a p p l i c a t i o n o b j e c t , a w i n d o w , o r a d i a l o g o b j e c t . E r r o rCod e c a n b e a n e r r o r y o u define o r o n e o f t h e following errors, w h i c h are detected a n d reported b y ObjectWindows: em_0ut0fMemory em_InvalidClient em_InvalidChild em_InvalidMainWindow em_InvalidWindow If t h e r e ' s a n e r r o r , TApplication.Error d i s p l a y s t h e e r r o r c o d e i n a m e s s a g e b o x a n d asks t h e u s e r w h e t h e r it's O K t o p r o c e e d . I f n o t , a p p l i c a t i o n e x e c u t i o n halts.
TApplication.ExecDialog function ExecDialog(ADialog: PWindowsObject): Integer; virtual ( O v e r r i d e : n e v e r ) After c h e c k i n g ValidWindow, ExecDialog e x e c u t e s t h e m o d a l d i a l o g o b j e c t p a s s e d i n ADialog b y s e n d i n g a m e s s a g e t o t h e d i a l o g o b j e c t ' s Execute m e t h o d . If m e m o r y is l o w o r t h e d i a l o g c a n n o t b e e x e c u t e d , ExecDialog d i s p o s e s o f the object a n d returns a negative error status.
A—ObjectWindows Objects
TApplication.InitApplication procedure
InitApplication;
virtual;
( O v e r r i d e : s o m e t i m e s ) H a n d l e s i n i t i a l i z a t i o n f o r t h e first i n s t a n c e o f a n application. Because T A p p l i c a t i o n . I n i t A p p l i c a t i o n doesn't d o anything, your a p p l i c a t i o n o b j e c t t y p e o v e r r i d e s T A p p l i c a t i o n . I n i t A p p l i c a t i o n if it n e e d s t o initialize a n y a p p l i c a t i o n - s p e c i f i c b e h a v i o r .
TAppUcation.InitMainWindow procedure
InitMainWindow;
virtual;
( O v e r r i d e : always) Y o u r a p p l i c a t i o n always o v e r r i d e s I n i t M a i n W i n d o w construct a main w i n d o w object. For example: procedure
to
MyApplication.InitMainWindow;
begin MainWindow end;
: = New(PMainWindow,
Init('Window
Caption'));
B y d e f a u l t , I n i t M a i n W i n d o w c r e a t e s a TWindow o b j e c t w i t h o u t a title.
TApplication.MakeWindow f u n c t i o n MakeWindow(AWindowsObject: PWindowsObj e c t ; v i r t u a l ;
PWindowsObject):
( O v e r r i d e : n e v e r ) After c h e c k i n g t h e safety p o o l , T A p p l i c a t i o n . MakeWindow tries t o c r e a t e a w i n d o w o r m o d e l e s s d i a l o g e l e m e n t a s s o c i a t e d w i t h t h e o b j e c t p a s s e d i n AWindowsOb j e c t . If m e m o r y is l o w , o r if t h e w i n d o w o r d i a l o g c a n n o t b e c r e a t e d , MakeWindow d i s p o s e s o f t h e o b j e c t a n d r e t u r n s n i l . If s u c c e s s f u l , it r e t u r n s AWindowsOb j e c t .
TApplication.MessageLoop procedure
MessageLoop;
virtual;
( O v e r r i d e : n e v e r ) C o n t r o l s a n a p p l i c a t i o n ' s g e n e r a l m e s s a g e l o o p that r u n s t h r o u g h o u t the lifetime of the application. T A p p l i c a t i o n . M e s s a g e L o o p sends a message to P r o c e s s A p p M s g , which handles the special messages required for modeless dialogs, accelerators, and M D I accelerators.
409
410
Part I I I — R e f e r e n c e s
TApplication.ProcessAccels function
ProcessAccels(var
Message:
TMsg):
Boolean;
virtual;
( O v e r r i d e : s o m e t i m e s ) H a n d l e s s p e c i a l a c c e l e r a t o r m e s s a g e p r o c e s s i n g . If a n application doesn't use accelerator resources, y o u can improve performance by o v e r r i d i n g this m e t h o d t o r e t u r n F a l s e .
TApplication.ProcessAppMsg function
ProcessAppMsg(var
Message:
TMsg):
Boolean;
virtual;
(Override: sometimes) C h e c k s for special processing for modeless dialog, accelerator, and M D I accelerator messages. Sends messages to P r o c e s s D l g M s g , P r o c e s s M D I A c c e l s , and P r o c e s s A c e e l s , a n d r e t u r n s T r u e if it e n c o u n t e r s a n y o f t h e s e s p e c i a l p r o c e s s ing messages. If y o u r a p p l i c a t i o n d o e s n ' t c r e a t e m o d e l e s s d i a l o g s , d o e s n ' t r e s p o n d t o a c c e l e r a t o r s , a n d isn't a n M D I a p p l i c a t i o n , y o u c a n i m p r o v e p e r f o r m a n c e b y o v e r r i d i n g this m e t h o d t o r e t u r n F a l s e .
TApplication.ProcessDlgMsg function
ProcessDlgMsg(var
Message:
TMsg): Boolean;
virtual;
(Override: sometimes) Handles special modeless dialog and w i n d o w message processing for keyboard input for controls. If y o u r a p p l i c a t i o n d o e s n ' t c r e a t e m o d e l e s s d i a l o g s o r w i n d o w s w i t h c o n t r o l s , y o u c a n i m p r o v e p e r f o r m a n c e b y o v e r r i d i n g this m e t h o d t o r e t u r n False.
TApplication.ProcessMDIAccels function
ProcessMDIAccels(var
Message:
TMsg): Boolean;
virtual;
H a n d l e s special accelerator message processing for M D I - c o m p l i a n t applications. If y o u r a p p l i c a t i o n isn't a n M D I a p p l i c a t i o n , y o u c a n i m p r o v e p e r f o r m a n c e b y o v e r r i d i n g this m e t h o d t o r e t u r n F a l s e .
TApplication.Run procedure
Run;
virtual;
( O v e r r i d e : s e l d o m ) If a n a p p l i c a t i o n i n i t i a l i z a t i o n is s u c c e s s f u l , Run sets t h e application in m o t i o n by sending a message t o M e s s a g e L o o p .
A—ObjectWindows Objects
TApplication.SetKBHandler procedure SetKBHandler(AWindowsObject: PWindowsObject); ( O v e r r i d e : n e v e r ) Activates k e y b o a r d h a n d l i n g b y s e t t i n g KBHandlerWnd t o AWindowsObject.
TApplication.ValidWindow function ValidWindow(AWindowsObj ect: PWindowsObj ect):PWindowsObj ect; D e t e r m i n e s w h e t h e r AWindowsOb j ect is a v a l i d o b j e c t . I f AWindowsOb j ect is v a l i d , ValidWindow r e t u r n s a p o i n t e r t o it. O t h e r w i s e , it r e t u r n s n i l . AWindowsOb j ect is i n v a l i d if • A l l o c a t i o n o f t h e o b j e c t d i s t u r b e d t h e safety p o o l • T h e status field o f AWindowsOb j ect is n o n z e r o
TBufStream TBuf St ream i m p l e m e n t s a b u f f e r e d v e r s i o n o f TDosSt ream. Its a d d i t i o n a l fields specify t h e size a n d l o c a t i o n o f t h e b u f f e r a n d t h e c u r r e n t a n d last p o s i t i o n s within the buffer. TBufStream o v e r r i d e s t h e e i g h t m e t h o d s o f TDosStream a n d d e f i n e s t h e abstract TStreamFlush m e t h o d . T h e TBufStream c o n s t r u c t o r c r e a t e s a n d o p e n s a file b y s e n d i n g a m e s s a g e t o TDosSt ream. I n it (the c o n s t r u c t o r ) . T h e n it c r e a t e s t h e b u f f e r w i t h Get Mem. TBufStream is m o r e efficient t h a n TDosStream w h e n a l a r g e n u m b e r o f s m a l l d a t a transfers o c c u r o n a s t r e a m ; f o r e x a m p l e , if y o u ' r e l o a d i n g a n d s t o r i n g o b j e c t s u s i n g TStream. Get a n d TStream. Put u s e TBufStream t o i m p r o v e p e r f o r m a n c e .
Fields Buffer BufSize BufPtr BufEnd
411
412
Part I I I — R e f e r e n c e s
Methods Init Done Flush GetPos GetSize Read Seek Truncate Write
Fields TBufStream.Buflfer Buffer: Pointer; ( r e a d o n l y ) A p o i n t e r t o t h e start o f a s t r e a m ' s b u f f e r .
TBufStream.BufSize BufSize: W o r d ; ( r e a d o n l y ) H o l d s t h e b u f f e r size i n b y t e s .
TBufStream.BufPtr BufPtr: W o r d ; ( r e a d o n l y ) A n offset f r o m t h e Buffer p o i n t e r that i n d i c a t e s t h e c u r r e n t p o s i t i o n w i t h i n t h e buffer.
TBufStream.BufEnd BufEnd: W o r d ; ( r e a d o n l y ) I f t h e b u f f e r isn't f u l l , BufEnd h o l d s a n offset f r o m t h e Buffer p o i n t e r t o t h e last u s e d byte in the buffer.
A—ObjectWindows Objects
Methods TBufStream.Init constructor Init(FileName: FNameStr; Mode, Size: Word); C r e a t e s a n d o p e n s a file w i t h a c c e s s Mode b y c a l l i n g TDosStream. Init. Init c r e a t e s a b u f f e r of Size b y t e s u s i n g Get Mem a n d initializes t h e Handle, Buffer, a n d Buf Size f i e l d s . A l t h o u g h b u f f e r s i z e s u s u a l l y r a n g e f r o m 512 t o 2,048 b y t e s , larger buffers are s o m e t i m e s useful.
TBufStream.Done destructor Done; virtual; ( O v e r r i d e : n e v e r ) C l o s e s a n d d i s p o s e s o f t h e file s t r e a m a n d f l u s h e s a n d d i s p o s e s o f its b u f f e r .
TBufStream.Hush procedure Flush; virtual; ( O v e r r i d e : n e v e r ) If t h e s t r e a m is stOK, Flush f l u s h e s t h e c a l l i n g file s t r e a m ' s buffer.
TBufStream.GetPos function GetPos: Longint; virtual; ( O v e r r i d e : n e v e r ) R e t u r n s t h e v a l u e of t h e c a l l i n g s t r e a m ' s c u r r e n t p o s i t i o n .
TBufStream.GetSi2e function GetSize: Longint; virtual; ( O v e r r i d e : n e v e r ) F l u s h e s t h e b u f f e r a n d t h e n r e t u r n s t h e t o t a l size i n b y t e s of the calling stream.
TBufStream.Read procedure Read(var Buf; Count: Word); virtual; ( O v e r r i d e : n e v e r ) If stOK, r e a d s Count b y t e s i n t o t h e Buf b u f f e r starting at t h e c a l l i n g s t r e a m ' s c u r r e n t p o s i t i o n . N o t e that Buf isn't t h e s t r e a m ' s b u f f e r b u t a n e x t e r n a l b u f f e r that h o l d s t h e d a t a r e a d i n f r o m t h e s t r e a m .
413
414
Part I I I — R e f e r e n c e s
TBufStream.Seek procedure Seek(Pos: Longint); virtual; ( O v e r r i d e : n e v e r ) F l u s h e s t h e b u f f e r a n d t h e n resets t h e c u r r e n t p o s i t i o n t o Pos b y t e s f r o m t h e start o f t h e c a l l i n g s t r e a m . T h e start o f a s t r e a m is p o s i t i o n 0 .
TBufStream.Thincate procedure Truncate; virtual; ( O v e r r i d e : n e v e r ) F l u s h e s t h e b u f f e r a n d t h e n d e l e t e s all d a t a o n t h e c a l l i n g s t r e a m f r o m t h e c u r r e n t p o s i t i o n t o t h e e n d . T h e c u r r e n t p o s i t i o n is set t o t h e n e w e n d o f the stream.
TBufitream.Write procedure Write(var But; Count: Word); virtual; ( O v e r r i d e : n e v e r ) I f stOK, w r i t e s Count b y t e s f r o m t h e Buf b u f f e r t o t h e c a l l i n g s t r e a m , starting at t h e c u r r e n t p o s i t i o n . N o t e that Buf isn't t h e s t r e a m ' s b u f f e r b u t a n e x t e r n a l b u f f e r that h o l d s t h e d a t a b e i n g w r i t t e n t o t h e s t r e a m . W h e n Write is c a l l e d , Buf p o i n t s t o t h e v a r i a b l e w h o s e v a l u e is b e i n g w r i t t e n .
TButton TButton is a n i n t e r f a c e o b j e c t that c o r r e s p o n d s t o a p u s h - b u t t o n e l e m e n t i n Windows. Y o u u s u a l l y d o n ' t u s e TButton o b j e c t s i n d i a l o g b o x e s (TDialog) o r d i a l o g w i n d o w s (TDlgWindow). R a t h e r , u s e t h e m w h e n y o u w a n t t o d i s p l a y a s t a n d - a l o n e b u t t o n as a c h i l d w i n d o w i n a n o t h e r w i n d o w ' s c l i e n t a r e a . There are t w o types o f p u s h buttons: • A regular button appears with a thin border. • A default b u t t o n appears with a thick border a n d represents the default action o f the window. E a c h w i n d o w is a l l o w e d o n l y o n e d e f a u l t p u s h b u t t o n .
Fields None.
A—ObjectWindows Objects
415
Methods Init InitResource GetClassName
Methods TButton.Init constructor Init(AParent: PWindowsObject; Anld: Integer; AText: PChar; X,Y,W,H: Integer; IsDefault: Boolean); Constructs a button object with the • P a s s e d p a r e n t w i n d o w (AParent)
• C o n t r o l ID (Anld) • A s s o c i a t e d text (AText) • P o s i t i o n (X, Y) relative t o t h e o r i g i n o f t h e p a r e n t w i n d o w ' s c l i e n t a r e a • W i d t h (W) • H e i g h t (H) S e n d s a m e s s a g e toTControl.Init a n d t h e n a d d s b s_De f PushButton to t h e Attr. S t y l e field if IsDefault is T r u e . If not, it a d d s bs_PushButton.
TButton.InitResource constructor InitResource(AParent:
PWindowsObject,
ResourcelD: Word);
C o n s t r u c t s a n O b j e c t W i n d o w s o b j e c t that c o r r e s p o n d s t o a b u t t o n e l e m e n t created by a dialog resource definition. S e n d s m e s s a g e s t o TControl. InitResource a n d TWindowsObject. B e c a u s e b u t t o n s h a v e n o d a t a t o transfer, y o u c a n u s e DisableTransf er t o e x c l u d e t h e b u t t o n f r o m t h e transfer m e c h a n i s m .
TButton.GetClassName function GetClassName:
PChar;
virtual;
( O v e r r i d e : n e v e r ) R e t u r n s t h e n a m e o f TButton's w i n d o w c l a s s , Button.
416
Part I I I — R e f e r e n c e s
TCheckBox TCheckBox is a n i n t e r f a c e o b j e c t that c o r r e s p o n d s t o a c h e c k - b o x e l e m e n t i n W i n d o w s . Y o u u s u a l l y d o n ' t u s e TCheckBox o b j e c t s i n d i a l o g b o x e s (TDialog) o r d i a l o g w i n d o w s (TDlgWindow). R a t h e r , u s e t h e m t o d i s p l a y a s t a n d - a l o n e c h e c k b o x as a c h i l d w i n d o w i n a n o t h e r w i n d o w ' s c l i e n t a r e a . C h e c k b o x e s h a v e t w o states: c h e c k e d a n d u n c h e c k e d . TCheckBox m e t h o d s p r i m a r i l y m a n a g e t h e c h e c k b o x ' s state. O p t i o n a l l y , a c h e c k b o x c a n b e part o f a g r o u p (TGroupBox) that v i s u a l l y a n d f u n c t i o n a l l y " g r o u p s " its c o n t r o l s .
Fields Group
Methods Init InitResource Load BNClicked Check GetCheck SetCheck Store Toggle Transfer Uncheck
Fields TCheckBox.Group Group: PGroupBox; ( r e a d o n l y ) Group p o i n t s t o t h e TGroupBox c o n t r o l o b j e c t that u n i f i e s t h e c h e c k b o x w i t h o t h e r c h e c k b o x e s a n d r a d i o b u t t o n s (TRadioButton). Group is e q u a l t o n i l if t h e c h e c k b o x isn't part o f a g r o u p .
A—ObjectWindows Objects
417
Methods TCheckBox.Init constructor Init(AParent: PWindowsObject; AnID: Integer; ATitle: PChar; X,Y,W,H: Integer; AGroup: PGroupBox); (Override: sometimes) Constructs a check b o x object with the • P a s s e d p a r e n t w i n d o w (AParent)
• C o n t r o l I D (AnId) • A s s o c i a t e d text (ATitle) • P o s i t i o n (X, Y) relative t o t h e o r i g i n o f t h e p a r e n t w i n d o w ' s c l i e n t a r e a • W i d t h (W) • H e i g h t (H) • A s s o c i a t e d g r o u p b o x (AGroup)
Init sets t h e c h e c k b o x ' s Att r .Style field to ws_Child o r ws_Visible
o r ws_TabStop o r bs_AutoCheckBox.
TCheckBox.InitResource constructor InitResource(AParent: PWindowsObject; ResourcelD: Word); A s s o c i a t e s aTCheckBox o b j ect w i t h t h e r e s o u r c e n a m e d b y ResourcelD. It t h e n e n a b l e s t h e transfer m e c h a n i s m b y s e n d i n g a m e s s a g e toEnableTransfer.
TCheckBoxIoad constructor Load(var S: TStream); C o n s t r u c t s a n d l o a d s a c h e c k b o x f r o m t h e s t r e a m S b y first s e n d i n g a m e s s a g e to TButton. Load a n d t h e n r e a d i n g t h e a d d i t i o n a l field (Group) i n t r o d u c e d b y
TCheckBox.
TCheckBox.BNCUcked procedure BNClicked(var Msg: TMessage); virtual nf_First + bn_Clicked; ( O v e r r i d e : s o m e t i m e s ) A u t o m a t i c a l l y r e s p o n d s to t h e notification m e s s a g e s ( w h i c h i n d i c a t e that t h e c h e c k b o x w a s c l i c k e d ) b y t o g g l i n g its state. If t h e c h e c k b o x ' s Group isn't n i l , BNClicked n o t i f i e s t h e TGroupBox b y s e n d i n g a m e s s a g e
to its SelectionChanged m e t h o d .
418
Part I I I — R e f e r e n c e s
TCheckBox.Check procedure Check; virtual; ( O v e r r i d e : s e l d o m ) F o r c e s t h e c h e c k box i n t o t h e c h e c k e d state by s e n d i n g a m e s s a g e t o SetCheck.
TCheckBox.GetCheck function GetCheck: Word; virtual; (Override: seldom) Returns o n e o f the following: bfJJnchecked bf_Checked bf _Grayed
(0) if t h e c h e c k box is u n c h e c k e d
(1) if t h e c h e c k box is c h e c k e d (2) if t h e c h e c k box is g r a y e d
TCheckBox.SetCheck procedure SetCheck(CheckFlag: Word); virtual; ( O v e r r i d e : s e l d o m ) F o r c e s t h e c h e c k b o x i n t o t h e state s p e c i f i e d byCheckFlag. • I f CheckFlag is 0 , t h e state is u n c h e c k e d . • I f CheckFlag is 1, t h e state is c h e c k e d . • If CheckFlag is 2, t h e state is g r a y e d . SetCheck a l s o i n f o r m s t h e c h e c k box's g r o u p that t h e s e l e c t i o n h a s c h a n g e d .
TCheckBox.Store procedure Store(var S: TStream); S t o r e s t h e c h e c k box o n t h e s t r e a m , S, by first s e n d i n g a m e s s a g e t o TControl. Store a n d t h e n w r i t i n g t h e a d d i t i o n a l field (Group) i n t r o d u c e d by TCheckBox.
TCheckBox.Toggle procedure Toggle; virtual; ( O v e r r i d e : s e l d o m ) T o g g l e s t h e state o f t h e c h e c k b o x by c a l l i n g Check o r Uncheck. F o r a 3-state c h e c k b o x , it t o g g l e s t h r o u g h all t h r e e states: u n c h e c k e d , checked, a n d grayed.
A — O b j e c t W i n d o w s Objects
419
TCheckBox.Transfer function Transfer(DataPtr: Pointer; TransferFlag: Word): Word; virtual; ( O v e r r i d e : s o m e t i m e s ) T r a n s f e r s t h e state o f a c h e c k b o x i n a Word t y p e v a l u e to or from the m e m o r y location pointed to by D a t a P t r . • I f Transf erFlag is tf_GetData, t h e c h e c k b o x ' s state d a t a is transferred to the m e m o r y location. • If Transf erFlag is tf_SetData, t h e c h e c k b o x is set t o t h e state indicated in the m e m o r y location. Transfer returns the n u m b e r o f bytes stored in o r retrieved f r o m the m e m o r y l o c a t i o n . I f y o u p a s s tf_SizeData, Transfer r e t u r n s t h e size o f t h e transfer d a t a .
TCheckBox.Uncheck procedure Uncheck; virtual; ( O v e r r i d e : s e l d o m ) F o r c e s t h e c h e c k b o x i n t o t h e u n c h e c k e d state b y s e n d i n g a m e s s a g e t o SetCheck.
TCollection TCollection is a n abstract t y p e f o r i m p l e m e n t i n g a c o l l e c t i o n o f i t e m s . T h e c o l l e c t i o n c a n c o n t a i n v a r i o u s d a t a t y p e s , i n c l u d i n g o b j e c t s . B e c a u s e it c a n i n c l u d e m i x e d d a t a t y p e s , TCollection is a m o r e g e n e r a l w a y o f h a n d l i n g d a t a t h a n t h e t r a d i t i o n a l array, set, o r list t y p e s . TCollection o b j e c t s size t h e m s e l v e s d y n a m i c a l l y at r u n - t i m e a n d c a n b e a b a s e t y p e f o r m a n y s p e c i a l i z e d t y p e s , s u c h as TSortedCollection a n d TStrCollection. I n a d d i t i o n t o m e t h o d s f o r a d d i n g a n d d e l e t i n g i t e m s , TCollection offers several u s e f u l iterator r o u t i n e s that call a p r o c e d u r e o r f u n c t i o n f o r e a c h i t e m in the collection.
Fields Count Delta Items Limit
420
Part I I I — R e f e r e n c e s
Methods Init Load Done AtDelete AtFree Atlnsert AtPut At Delete DeleteAll Error FirstThat ForEach FreeAll Freeltem Free Getltem IndexOf Insert LastThat Pack Putltem SetLimit Store
Fields TCollection.Count Count: Integer; ( r e a d o n l y ) T h e current n u m b e r o f items in the collection, u p to (and including)
MaxCollectionSize.
TCollection.Delta Delta: Integer; ( r e a d o n l y ) T h e n u m b e r o f i t e m s t o i n c r e a s e t h e Items list b y w h e n e v e r t h e list b e c o m e s f u l l . I f Delta is 0, t h e c o l l e c t i o n c a n n o t g r o w b e y o n d t h e size set b y Limit.
A — O b j e c t W i n d o w s Objects
I n c r e a s i n g t h e size o f a c o l l e c t i o n r e d u c e s p e r f o r m a n c e . T o m i n i m i z e t h e n u m b e r o f t i m e s t h e c o l l e c t i o n i n c r e a s e s its s i z e , set t h e initial Limit t o a v a l u e that a c c o m m o d a t e s all t h e i t e m s y o u m i g h t w a n t t o c o l l e c t , a n d set Delta t o a v a l u e that a l l o w s a r e a s o n a b l e a m o u n t o f e x p a n s i o n .
TCollectionJtems Items: PItemList; ( r e a d o n l y ) A p o i n t e r t o a n array o f i t e m p o i n t e r s .
TCollection.Iimit Limit: Integer; ( r e a d o n l y ) T h e c u r r e n t l y a l l o c a t e d size (in e l e m e n t s ) o f t h e Items list.
Methods TCollection.Init constructor Init(ALimit, ADelta: Integer); C r e a t e s a c o l l e c t i o n w i t h Limit set t o ALimit a n d Delta set t o ADelta. T h e initial n u m b e r o f i t e m s is l i m i t e d t o ALimit, b u t t h e c o l l e c t i o n c a n g r o w i n i n c r e m e n t s o f ADelta u n t i l m e m o r y r u n s o u t o r t h e n u m b e r o f i t e m s r e a c h e s MaxCollectionSize.
TCollectionload constructor Load(var S: TStream); C r e a t e s a n d l o a d s a c o l l e c t i o n f r o m a s t r e a m . Load s e n d s a m e s s a g e t o Get It em for e a c h i t e m i n t h e c o l l e c t i o n .
TCollection.Done destructor Done; virtual; ( O v e r r i d e : o f t e n ) D e l e t e s a n d d i s p o s e s o f all i t e m s i n a c o l l e c t i o n b y s e n d i n g a m e s s a g e t o FreeAll a n d s e t t i n g Limit t o 0.
421
422
Part III—References
TCoUectionAtDelete procedure AtDelete(Index: Integer); Deletes the item at the Index'th position and moves the ensuing items u p by one position. Co u n t is decremented by 1, but the m e m o r y allocated to the collection (as specified by Limit) isn't reduced. If I n d e x is less than 0 or greater than or equal to Co u n t, the Error method is sent a message with an argument of eolndexError.
TCollectionAtFree procedure AtFree(Index: Integer); Disposes of and deletes the item at the Index'th position.
TCoUectionAtlnsert procedure Atlnsert(lndex: Integer; Item: Pointer); Inserts Item at the Index'th position and moves the following items d o w n by one position: • If Index is less than 0 or greater than Count, the Error method is sent a message with an argument of eolndexError and the n e w Item isn't inserted. • If Count is equal to Limit before the call to Atlnsert, the allocated size of the collection is expanded by Delta items via a message sent to SetLimit. • If the SetLimit call fails to expand the collection, the Error method is sent a message with an argument of coOverf low, and the n e w Item isn't inserted.
TCoUectionAtPut procedure AtPut(Index: Integer; Item: Pointer); Replaces the item at Index position with the item specified by Item. If Index is less than 0 or greater than or equal to Count, the Error method is sent a message with an argument of eolndexError.
A—ObjectWindows Objects
TCollectionAt function At(Index: Integer): Pointer; R e t u r n s a p o i n t e r t o t h e i t e m i n d e x e d b y Index i n t h e c o l l e c t i o n . T h i s m e t h o d lets y o u m a n i p u l a t e a c o l l e c t i o n as t h o u g h it w e r e a n i n d e x e d array. I f I ndex is less t h a n 0 o r g r e a t e r t h a n o r e q u a l t o Count, t h e Error m e t h o d is s e n t a m e s s a g e w i t h a n a r g u m e n t ofcoIndexError, a n d a v a l u e o f n i l is r e t u r n e d .
TCollection.Delete procedure Delete(Item: Pointer); D e l e t e s t h e i t e m s p e c i f i e d b y Item f r o m t h e c o l l e c t i o n . E q u i v a l e n t t o AtDelete(IndexOf(Item)).
TCollection.DeleteAll procedure DeleteAll; D e l e t e s all i t e m s f r o m t h e c o l l e c t i o n b y s e t t i n g Count t o 0.
TCollection.Eiror procedure Error(Code, Info: Integer); virtual; ( O v e r r i d e : s o m e t i m e s ) Receives a m e s s a g e w h e n e v e r a c o l l e c t i o n error is e n c o u n t e r e d . B y default, this m e t h o d p r o d u c e s a r u n - t i m e error o f 212 - C o d e ) .
TCollection.FirstThat function FirstThat(Test: Pointer): Pointer; FirstThat a p p l i e s a B o o l e a n f u n c t i o n ( s u p p l i e d b y t h e f u n c t i o n p o i n t e r T e s t ) t o e a c h i t e m i n t h e c o l l e c t i o n u n t i l T e s t r e t u r n s T r u e . T h e result is t h e i t e m p o i n t e r u s e d w h e n T e s t r e t u r n e d T r u e , o r n i l if t h e T e s t f u n c t i o n r e t u r n e d F a l s e f o r all i t e m s . T e s t m u s t p o i n t t o a far l o c a l f u n c t i o n t a k i n g o n e P o i n t e r p a r a m e t e r a n d returning a Boolean value. For example: function Matches(Item: Pointer): Boolean; far; T h e Test f u n c t i o n c a n n o t b e a g l o b a l f u n c t i o n .
423
424
Part I I I — R e f e r e n c e s
A s s u m i n g that List is a TCollection, t h e s t a t e m e n t
P :=
List.FirstThat(@Matches);
corresponds to I
: = 0;
while
(I < List.Count)
and not Matches(List.At(I))
do
Inc(I);
if I < List.Count
then P := List.At(I)
else P := nil;
TCollection.ForEach procedure
ForEach(Action:
Pointer);
For Each a p p l i e s a n a c t i o n ( s u p p l i e d b y t h e p r o c e d u r e p o i n t e r Action) t o e a c h i t e m i n t h e c o l l e c t i o n . Action m u s t p o i n t t o a far l o c a l p r o c e d u r e t a k i n g o n e Pointer p a r a m e t e r ; f o r e x a m p l e :
function
Printltem(ltem:
Pointer); far;
T h e Action p r o c e d u r e c a n n o t b e a g l o b a l p r o c e d u r e . A s s u m i n g that List is a TCollection, t h e s t a t e m e n t
List.ForEach(@PrintItem); corresponds to
for I := 0 to List.Count
- 1 do
PrintItem(List.At(I));
TCollection.FreeAll procedure
FreeAll;
D e l e t e s a n d d i s p o s e s o f all i t e m s i n t h e c o l l e c t i o n .
TCollection.FreeItem procedure
Freeltem(ltem:
Pointer);
virtual;
( O v e r r i d e : s o m e t i m e s ) T h e Freeltem m e t h o d m u s t d i s p o s e o f t h e Item. T h e d e f a u l t Freeltem a s s u m e s that Item is a p o i n t e r t o a d e s c e n d a n t o f TOb j ect a n d s e n d s a m e s s a g e t o t h e Done d e s t r u c t o r :
if Item <> nil then Dispose(PObject(Item),
Done);
Freeltem r e c e i v e s m e s s a g e s f r o m Free a n d FreeAll, b u t s h o u l d n e v e r b e s e n t m e s s a g e s directly.
A — O b j e c t W i n d o w s Objects
TCollection.Free procedure Free(Item: Pointer); D e l e t e s a n d d i s p o s e s o f a s p e c i f i e d Item. E q u i v a l e n t t o Delete(Item); Freeltem(Item);
TCollection.GetItem function TCollection.Getltem(var
S: TStream): Pointer; virtual;
( O v e r r i d e : s o m e t i m e s ) S e n t a m e s s a g e b y Load f o r e a c h i t e m i n t h e c o l l e c t i o n . Y o u c a n o v e r r i d e this m e t h o d , b u t y o u s h o u l d n ' t s e n d it m e s s a g e s directly. T h e d e f a u l t Get I tern a s s u m e s that t h e i t e m s i n t h e c o l l e c t i o n a r e d e s c e n d a n t s o f TObject a n d s e n d s a m e s s a g e t o TStream.Get t o l o a d t h e i t e m : Getltem
:= S.Get;
TCollection.IndexOf function IndexOf(Item: Pointer): Integer; virtual; ( O v e r r i d e : n e v e r ) R e t u r n s t h e i n d e x o f a s p e c i f i e d Item. T h e c o n v e r s e o p e r a t i o n o f At. I f Item isn't i n t h e c o l l e c t i o n , IndexOf r e t u r n s - 1 .
TCollection.Insert procedure Insert(Item: Pointer); virtual; ( O v e r r i d e : n e v e r ) I n s e r t s Item i n t o t h e c o l l e c t i o n a n d a d j u s t s o t h e r i n d i c e s if n e c e s s a r y . B y d e f a u l t , i n s e r t i o n s a r e m a d e at t h e e n d o f t h e c o l l e c t i o n b y w a y of a message to Atlnsert(Count,
Item);
TCollectionlastThat function LastThat(Test: Pointer): Pointer; LastThat a p p l i e s a B o o l e a n f u n c t i o n ( s p e c i f i e d b y t h e f u n c t i o n p o i n t e r Test) t o e a c h i t e m i n t h e c o l l e c t i o n i n r e v e r s e o r d e r u n t i l Test r e t u r n s T r u e . T h e result is t h e i t e m p o i n t e r u s e d w h e n Test r e t u r n e d T r u e , o r n i l if t h e Test f u n c t i o n r e t u r n e d F a l s e f o r all i t e m s .
425
426
Part III—References
Test must point to a far local function that takes aPointer parameter and returns a Boolean; for example: function Matches(Item: Pointer): Boolean; far; The Test function cannot be a global function. Assuming that List is a TCollection, the statement: P := List.LastThat(@Matches); corresponds to: I := List.Count - 1; while (I >= 0) and not Matches(List.At(I)) do Dec(I); if I >= 0 then P := List.At(I) else P := nil;
TCollection.Pack procedure Pack; Deletes all nil pointers in the collection.
TCollection.PutItem procedure Putltem(var S: TStream; Item: Pointer); virtual; (Override: sometimes) Put Item receives a message from Store for each item in the collection. Y o u can override this method, but you shouldn't send it a message directly. The default Put Item assumes that the items in the collection are descendants ofTObj ect, and thus sends a message to TStream. Put to store the item: S.Put(Item);
TCollection.SetLimit procedure SetLimit(ALimit: Integer); virtual; (Override: seldom) Expands or shrinks the collection by changing the allocated size to ALimit. If ALimit is less than Count, ALimit is set to Count. If ALimit is greater than MaxCollectionSize, ALimit is set to MaxCollectionSize. Then, if ALimit is different from the current Limit, a n e w Items array of ALimit elements is allocated. The old Items array then is copied into the n e w array, and the old array is disposed.
A — O b j e c t W i n d o w s Objects
TCollection.Store procedure Stbre(var S: TStream); S t o r e s t h e c o l l e c t i o n a n d all its i t e m s o n t h e s t r e a m S. Store s e n d s a m e s s a g e t o Put I tern f o r e a c h i t e m i n t h e c o l l e c t i o n .
TComboBox TComboBox is a n i n t e r f a c e o b j e c t that c o r r e s p o n d s t o a c o m b o b o x e l e m e n t i n W i n d o w s . U s u a l l y y o u d o n ' t u s e TComboBox o b j e c t s i n d i a l o g b o x e s (TDialog) o r d i a l o g w i n d o w s (TDlgWindow). R a t h e r , u s e a c o m b o b o x o b j e c t t o d i s p l a y a s t a n d - a l o n e c o m b o b o x as a c h i l d w i n d o w i n a n o t h e r w i n d o w ' s c l i e n t a r e a . C o m b o b o x o b j e c t s i n h e r i t m o s t o f t h e i r f u n c t i o n a l i t y f r o m TListBox. T h e t h r e e styles o f c o m b o b o x e s a r e •
Simple
• Drop down • D r o p d o w n list T h e s e styles a r e c o n t r o l l e d b y t h e W i n d o w s style c o n s t a n t s c b s S i m p l e , cbs_DropDown, a n d cbs DropDownList. T h e s e c o n s t a n t s a r e p a s s e d t o t h e Init c o n s t r u c t o r , which i n t u r n tells W i n d o w s which t y p e o f c o m b o b o x element to create.
Fields TextLen
Methods Init InitResource Load GetClassName GetMsgID (private) HideList SetupWindow ShowList Store Transfer
427
428
Part I I I — R e f e r e n c e s
Fields TComboBox.TextLen TextLen: W o r d ; (read o n l y ) Text Len c o n t a i n s t h e l e n g t h o f t h e c h a r a c t e r b u f f e r i n t h e e d i t p a r t o f t h e c o m b o b o x . T h e c h a r a c t e r b u f f e r is e q u a l t o t h e n u m b e r o f b y t e s t r a n s f e r r e d b y
Transfer. TextLen is set b y Init.
Methods TComboBox.Init constructor Init(AParent: PWindowsObject; AnID: Integer; X,Y,W,H: Integer; CanDropList: Boolean; HasStaticControl: Boolean); ( O v e r r i d e : s o m e t i m e s ) S e n d s a m e s s a g e t o TListBox. Init a n d c o n s t r u c t s a c o m b o b o x object with the following parameters: • P a s s e d p a r e n t w i n d o w (AParent)
• C o n t r o l I D (Anld) • P o s i t i o n (X, Y) relative t o t h e o r i g i n o f t h e p a r e n t w i n d o w ' s c l i e n t a r e a • W i d t h (W) • H e i g h t (H)
Sets TextLen t o ATextLen. Sets Attr .Style t o (Attr.Style and not lbs_Notify) or AStyle or cbs_Sort or ws_VScroll or ws_HScroll.
TComboBox.InitResource constructor InitResource(AParent: PWindowsObj ect; ResourcelD: Integer; ATextLen: Word); A s s o c i a t e s a TComboBox o b j e c t w i t h t h e r e s o u r c e i n d i c a t e d b y ResourcelD w i t h a m a x i m u m text l e n g t h o f ATextLen -1.
TComboBoxload constructor Load(var S: TStream);
A—ObjectWindows Objects
C o n s t r u c t s a n d l o a d s a c o m b o b o x f r o m t h e s t r e a m , S, b y first s e n d i n g a m e s s a g e toTListBox. Load a n d t h e n r e a d i n g t h e a d d i t i o n a l fields (I sDropDown, IsList) i n t r o d u c e d b y TComboBox.
TComboBox.GetClassName function GetClassName:
PChar;
virtual;
( O v e r r i d e : n e v e r ) R e t u r n s t h e n a m e o f TComboBox's w i n d o w class, ComboBox.
TComboBox.GetMsgID function GetMsgID(AMsg : TMsgName): word; virtual; Private m e t h o d ; u s e d i n t e r n a l l y b y TComboBox.
TComboBox.HideList procedure HideList;
virtual;
( O v e r r i d e : s e l d o m ) H i d e s t h e d r o p d o w n list o f a d r o p d o w n o r d r o p - d o w n list combo box.
TComboBox.SetUpWindow H a n d l e s s o m e o f t h e TComboBox w i n d o w s e t u p ,
procedure SetupWindow; virtual;
TComboBox.ShowIist procedure ShowList;
virtual;
( O v e r r i d e : s e l d o m ) D i s p l a y s t h e d r o p d o w n list o f a d r o p d o w n o r d r o p - d o w n list c o m b o b o x .
TComboBox.Store procedure Store(var S: TStream); S t o r e s t h e c o m b o b o x o n t h e s t r e a m , S, b y first s e n d i n g a m e s s a g e t o TListBox. Store a n d t h e n w r i t i n g t h e a d d i t i o n a l field (TextLen) i n t r o d u c e d
b y TComboBox.
429
430
Part III—References
TComboBox.Transfer function
Transfer(DataPtr:
Pointer;
TransferFlag:
Word);virtual
Transfers data to or from the record p o i n t e d to by D a t a P t r . T h e r e c o r d s h o u l d first b e a p o i n t e r t o a string c o l l e c t i o n that h o l d s t h e e n t r i e s o f t h e c o m b o b o x ' s list. T h e n a n array o f c h a r a c t e r s h o l d i n g t h e c u r r e n t l y s e l e c t e d e n t r y is t r a n s f e r r e d . • If T r a n s f e r F l a g is t f G e t D a t a , t h e c o m b o b o x ' s d a t a is t r a n s f e r r e d t o t h e D a t a P t r r e c o r d . T r a n s f e r r e t u r n s t h e size o f t h e d a t a t r a n s f e r r e d . • If T r a n s f e r F l a g is t f _ S e t D a t a , t h e d a t a is t r a n s f e r r e d t o t h e c o m b o b o x f r o m t h e r e c o r d . T r a n s f e r r e t u r n s t h e size o f t h e d a t a t r a n s f e r r e d . • If T r a n s f e r F l a g is t f _ S i z e D a t a , T r a n s f e r r e t u r n s t h e size o f t h e transfer d a t a .
TControl T C o n t r o l is a n abstract o b j e c t t y p e that u n i f i e s all c o n t r o l o b j e c t t y p e s , s u c h as T S c r o l l B a r a n d T B u t t o n . It's a l s o t h e a n c e s t o r t o T M D I C l i e n t , a s p e c i a l i z e d control for MDI-compliant applications. Y o u generally w o n ' t use control objects in dialog b o x e s ( T D i a l o g ) or d i a l o g w i n d o w s ( T D l g W i n d o w ) , o n l y as s t a n d - a l o n e c o n t r o l s i n t h e c l i e n t a r e a of other windows.
Methods Init GetClassName InitResource Register WMPaint
Methods TControLMt constructor Init(AParent: A T i t l e : PChar; X,Y,W,H:
PWindowsObject; Integer);
Anld:
Integer;
A—ObjectWindows Objects
431
Constructs a control object with the following parameters: • A s s o c i a t e d p a r e n t w i n d o w (AParent) • C o n t r o l ID (AnId) • A s s o c i a t e d text (ATitle) • P o s i t i o n (X, Y) relative t o t h e o r i g i n o f t h e p a r e n t w i n d o w ' s c l i e n t area • W i d t h (W) • H e i g h t (H) U s i n g t h e s e p a r a m e t e r s , Init fills t h e c o n t r o l ' s Att r field i n h e r i t e d f r o m TWindow. B y d e f a u l t , Init sets Attr.Style t o ws_Child o r ws_Visible o r ws_Group o r w s T a b S t o p ; t h u s , all c o n t r o l o b j e c t s a r e visible c h i l d w i n d o w s .
TControLGetClassName function GetClassName: PChar; virtual; ( O v e r r i d e : always) A b s t r a c t m e t h o d always o v e r r i d d e n b y d e s c e n d a n t o b j e c t s .
TControLlnitResource constructor InitResource(AParent:
PWindowsObject;
ResourcelD: Word); Associates a control object with the control element in the resource specified b y ResourcelD. S e n d s a m e s s a g e t o TWindow. InitResource a n d EnableTransf er t o e n a b l e t h e transfer m e c h a n i s m .
TControLRegister function Register: Boolean; virtual; ( O v e r r i d e : n e v e r ) R e t u r n s T r u e t o i n d i c a t e that TControl d e s c e n d a n t s u s e preregistered w i n d o w classes.
TControLWMPaint procedure WMPaint(var Msg: TMessage); virtual; wm_First + wm_Paint; ( O v e r r i d e : s e l d o m ) S e n d s a m e s s a g e t o Def WndProc e n a b l i n g s t a n d a r d r e p a i n t i n g of c o n t r o l o b j e c t s .
432
Part I I I — R e f e r e n c e s
TDialog T D i a l o g d e f i n e s o b j e c t s t o serve as t h e m o d a l a n d m o d e l e s s d i a l o g b o x e s u s e d in W i n d o w s applications. A T D i a l o g object has a n associated dialog resource that d e s c r i b e s t h e a p p e a r a n c e a n d p l a c e m e n t o f its c o n t r o l s . S p e c i f y t h e d i a l o g resource in the message to I n i t . Y o u c a n associate dialog b o x objects with either m o d a l o r m o d e l e s s dialog e l e m e n t s b y w a y o f m e s s a g e s t o E x e c u t e (for m o d a l d i a l o g s ) o r C r e a t e (for m o d e l e s s d i a l o g s ) . Note: W h e n y o u c r e a t e a m o d a l d i a l o g , y o u d i s a b l e t h e o p e r a t i o n o f its p a r e n t w i n d o w u n t i l t h e m o d a l d i a l o g is f i n i s h e d .
Fields Attr DialogProc IsModal
Methods Init Load Done Cancel Create DefWndProc EndDlg Execute GetltemHandle Ok SendDlgltemMsg Store WMClose WMInitDialog WMQueryEndSession
A — O b j e c t W i n d o w s Objects
Fields TDialogAttr Attr: TDialogAttr; Attr h o l d s t h e d i a l o g b o x ' s c r e a t i o n a t t r i b u t e s . Attr is d e f i n e d as f o l l o w s : TDialogAttr = record Name: PChar; Param: Longint; end; T h e Name field c o n t a i n s t h e n a m e o r I D o f t h e d i a l o g r e s o u r c e . T h e Param f i e l d c o n t a i n s a p a r a m e t e r s e n t t o t h e d i a l o g p r o c e d u r e w h e n t h e d i a l o g is created.
TDialog.DialogProc DialogProc: TFarProc; (read o n l y ) DialogProc p o i n t s t o t h e p r o c e d u r e - i n s t a n c e a d d r e s s o f t h e d i a l o g f u n c t i o n .
TDialog.IsModal IsModal: Boolean; ( r e a d o n l y ) IsModal is T r u e if t h e d i a l o g is m o d a l a n d F a l s e if t h e d i a l o g is m o d e l e s s .
Methods TDialog.Init constructor Init(AParent: PWindowsObject; AName: PChar); (Override: sometimes) Constructs the dialog object by sending a message to TWindowsOb j ect. Init, p a s s i n g it t h e p a r e n t w i n d o w , AParent. N e x t , Init sets t h e Att r. Name f i e l d t o AName. AName c a n b e t h e s y m b o l i c n a m e o f t h e d i a l o g r e s o u r c e o r a n i n t e g e r I D cast t o t y p e PChar. Init a l s o s e n d s a m e s s a g e t o TWindowsOb j ect. DisableAutoCreate t o prevent dialogs from being created a n d displayed automatically along with their parent w i n d o w s .
433
434
Part III—References
TDialogload constructor
Load(var S:
TStream);
C o n s t r u c t s a n d l o a d s a d i a l o g b o x f r o m t h e s t r e a m , S, b y first s e n d i n g a m e s s a g e t o T W i n d o w s O b j e c t . L o a d a n d t h e n r e a d i n g t h e a d d i t i o n a l fields ( A t t r a n d I s M o d a l ) introduced by T D i a l o g .
TDialog.Done destructor
Done;
virtual;
(Override: sometimes) Disposes of the dialog b o x object. Sends a message to TWindowsObj e c t . D o n e .
TDialog.Cancel p r o c e d u r e C a n c e l ( v a r Msg: T M e s s a g e ) ; v i r t u a l ;
id_First
+
id_Cancel
(Override: sometimes) Automatically responds to a dialog's Cancel button (when pressed) by sending a message to EndDlg with the value i d C a n c e l .
TDialog.Create function
Create:
Boolean;
virtual;
(Override: never) Creates a modeless dialog object's corresponding dialog e l e m e n t . C r e a t e r e t u r n s T r u e if t h e c r e a t i o n w a s s u c c e s s f u l . If u n s u c c e s s f u l , it sends a message to E r r o r with the error c o d e e m _ I n v a l i d W i n d o w .
TDialog.DefWndProc procedure DefWndProc(var
Msg:
TMessage);
virtual;
(Override: never) Forces W i n d o w s default-message processing by setting the result o f t h e p a s s e d m e s s a g e e q u a l t o 0.
TDialog.EndDlg procedure EndDlg(ARetValue:
Integer);
virtual;
( O v e r r i d e : n e v e r ) D e s t r o y s m o d a l a n d m o d e l e s s d i a l o g b o x e s . A R e t V a l u e is p a s s e d b a c k as t h e r e t u r n v a l u e f r o m E x e c u t e f o r m o d a l d i a l o g b o x e s .
A—ObjectWindows Objects
TDialog-Execute function Execute: Integer; virtual; (Override: never) Creates a n d displays a m o d a l dialog object's c o r r e s p o n d i n g d i a l o g e l e m e n t . T h i s m e t h o d e x e c u t e s w h i l e t h e d i a l o g b o x is o n - s c r e e n , u n t i l its EndDlg m e t h o d is s e n t a m e s s a g e . B e f o r e t h e m e t h o d f i n i s h e s , it resets HWindow t o 0. Execute r e t u r n s t h e i n t e g e r v a l u e r e t u r n e d b y EndDlg if s u c c e s s f u l . If u n s u c c e s s f u l , Execute s e n d s Error a m e s s a g e w i t h t h e e r r o r c o d e em_InvalidWindow.
TDialog-GetltemHandle function GetItemHandle(DlgItemID:
Integer): HWnd;
(Override: never) Returns the handle to the dialog's control identified by the p a s s e d I D , DlgltemlD.
TDialog.Ok procedure 0k(var Msg: TMessage); virtual; id_First + id_0K; (Override: sometimes) Automatically responds to a dialog's O K button (when p r e s s e d ) b y s e n d i n g m e s s a g e s t o CanClose a n d EndDlg w i t h t h e v a l u e id_0K. A l s o s e n d s a m e s s a g e t o Transf e rDat a t o transfer d a t a f r o m t h e c o n t r o l s t o t h e transfer b u f f e r .
TDialog.SendDlgltemMsg function SendDlgItemMsg(DlgItemID:
Integer; AMsg, WParam: Word;
LParam: Longint): Longint; ( O v e r r i d e : n e v e r ) S e n d s a W i n d o w s c o n t r o l m e s s a g e , i d e n t i f i e d b y AMsg, t o t h e d i a l o g ' s c o n t r o l i d e n t i f i e d b y DlgltemlD. WParam a n d LParam b e c o m e p a r a m e t e r s i n t h e W i n d o w s m e s s a g e . SendDlgltemMsg r e t u r n s t h e v a l u e r e t u r n e d b y t h e c o n t r o l o r 0 if t h e c o n t r o l I D is i n v a l i d .
TDialog.Store procedure Store(var S: TStream); S t o r e s t h e d i a l o g b o x o n t h e s t r e a m , S, b y first s e n d i n g a m e s s a g e t o TWindowsObject .Store a n d t h e n w r i t i n g t h e a d d i t i o n a l fields (Attr a n d IsModal) i n t r o d u c e d b y TDialog.
435
436
Part I I I — R e f e r e n c e s
TDialog.WMClose p r o c e d u r e WMClose(var Msg:
TMessage);
virtual;
wm_First
+ wm_Close
If t h e d i a l o g b o x is m o d a l , WMClose s e n d s a m e s s a g e t o E n d D l g t o c l o s e t h e dialog box. If t h e d i a l o g b o x is m o d e l e s s , WMClose s e n d s a m e s s a g e t o its WMClose m e t h o d inherited f r o m TWindowsObj e c t .
TDialog.WMInitDialog procedure WMInitDialog(var wm_First
+
Msg:
TMessage);
virtual;
wm_InitDialog;
( O v e r r i d e : n e v e r ) W M I n i t D i a l o g a u t o m a t i c a l l y r e c e i v e s a m e s s a g e just b e f o r e t h e d i a l o g is d i s p l a y e d . It s e n d s a m e s s a g e t o S e t u p W i n d o w t o h a n d l e a n y i n i t i a l i z a t i o n n e e d e d f o r t h e d i a l o g o r its c o n t r o l s .
TDialog.WMQueryEndSession p r o c e d u r e W M Q u e r y E n d S e s s i o n ( v a r Msg wm_First + wm_QueryEndSession
: TMessage);
virtual;
T h i s p r o c e d u r e e n d s t h e q u e r y s e s s i o n b y first a s k i n g e a c h a p p l i c a t i o n w h e t h e r the query session should e n d . Uses the W i n d o w s API.
TDlgWindow D i a l o g w i n d o w s d e f i n e d b y T D l g W i n d o w c o m b i n e s o m e o f t h e characteristics o f dialogs a n d s o m e characteristics o f w i n d o w s . A d i a l o g w i n d o w h a s a n a s s o c i a t e d d i a l o g r e s o u r c e that d e s c r i b e s t h e a p p e a r a n c e a n d p o s i t i o n o f its c o n t r o l s . It a l s o h a s a w i n d o w class that c a n specify i c o n s a n d c u r s o r s . T o create a n d display dialog w i n d o w s , use the m o d e l e s s dialog C r e a t e m e t h o d s . D o n ' t use the E x e c u t e m e t h o d .
Fields None.
A — O b j e c t W i n d o w s Objects
Methods Init Create GetWindowClass
Methods TDlgWindow.Init constructor Init(AParent: PWindowsObject; AName: PChar); C o n s t r u c t s a n e w TDlgWindow o b j e c t b y s e n d i n g TDialog. Init a m e s s a g e . Init a l s o s e n d s a m e s s a g e t o EnableAutoCreate t o e n s u r e that t h e TDlgWindow o b j e c t a u t o m a t i c a l l y is c r e a t e d a n d d i s p l a y e d a l o n g w i t h its p a r e n t window.
TDlgWindow.Create function Create: Boolean; virtual; ( O v e r r i d e : n e v e r ) R e g i s t e r s t h e d i a l o g w i n d o w ' s class a n d s e n d s a m e s s a g e t o
TDialog.Create. Create r e t u r n s T r u e if s u c c e s s f u l .
TDlgWindow.GetWindowClass procedure GetWindowClass(var AWndClass: TWndClass); virtual; ( O v e r r i d e : o f t e n ) D e f i n e s t h e d e f a u l t w i n d o w class r e c o r d a n d p a s s e s it b a c k i n AWndClass. T h i s w i n d o w class s p e c i f i e s a s t a n d a r d i c o n a n d c u r s o r .
R e d e f i n e GetWindowClass ( a n d GetClassName) f o r a n y TDlgWindow descendants. A l s o , m a k e s u r e that y o u r GetWindowClass m e t h o d s e n d s a m e s s a g e t o GetWindowClass b e f o r e m o d i f y i n g a n y TWndClass f i e l d s .
TDosStream TDosStream is a s p e c i a l i z e d TStream i m p l e m e n t i n g u n b u f f e r e d D O S file s t r e a m s . Its c o n s t r u c t o r , Init, lets y o u c r e a t e o r o p e n a D O S file b y s p e c i f y i n g its n a m e a n d a c c e s s m o d e : e i t h e r stCreate, stOpenRead, stOpenWrite, o r
stOpen.
437
438
Part I I I — R e f e r e n c e s
T D o s S t r e a m h a s o n e f i e l d n e w f i e l d , Handle, w h i c h r e p r e s e n t s t h e D O S file h a n d l e u s e d t o a c c e s s a n o p e n file. M o s t a p p l i c a t i o n s u s e t h e b u f f e r e d derivative o f T D o s S t r e a m c a l l e d TBuf S t r e a m . T D o s S t r e a m o v e r r i d e s all t h e abstract m e t h o d s o f T S t r e a m e x c e p t f o r T S t r e a m . Flush.
Fields Handle
Methods Init Done GetPos GetSize Read Seek Truncate Write
Fields TDosStream.Handle Handle: Word (read o n l y ) Handle is t h e D O S file h a n d l e u s e d to a c c e s s a n o p e n file s t r e a m .
Methods TDosStream.Init constructor Init(FileName: FNameStr; Mode: Word); C r e a t e s a D O S file s t r e a m w i t h FileName a n d a c c e s s Mode. I f s u c c e s s f u l , t h e Handle is set w i t h t h e D O S file h a n d l e . F a i l u r e is i n d i c a t e d b y a m e s s a g e t o Error w i t h a n a r g u m e n t of stlnitError. T h e Mode a r g u m e n t m u s t b e s e t e i t h e r : stCreate, stOpenRead, stOpenWrite, or stOpen.
A—ObjectWindows Objects
TDosStream.Done destructor Done; virtual; ( O v e r r i d e : n e v e r ) C l o s e s a n d d i s p o s e s o f t h e D O S file s t r e a m .
TDosStream.GetPos function GetPos: Longint; virtual; (Override: never) Returns the value o f the calling stream's current position.
TDosStream.GetSize function GetSize: Longint; virtual; ( O v e r r i d e : n e v e r ) R e t u r n s t h e size i n b y t e s o f t h e c a l l i n g s t r e a m .
TDosStream.Read procedure Read(var Buf; Count: Word); virtual; ( O v e r r i d e : n e v e r ) R e a d s Count bytes i n t o t h e Buf b u f f e r starting at t h e c a l l i n g stream's current position.
TDosStream.Seek procedure Seek(Pos: Longint); virtual; ( O v e r r i d e : n e v e r ) R e s e t s t h e c u r r e n t p o s i t i o n t o Pos b y t e s f r o m t h e b e g i n n i n g o f the calling stream.
TDosStream.Thincate procedure Truncate; virtual; ( O v e r r i d e : n e v e r ) D e l e t e s all d a t a o n t h e c a l l i n g s t r e a m f r o m t h e c u r r e n t position to the e n d o f the stream.
TDosStream.Write procedure Write(var Buf; Count: Word); virtual; W r i t e s Count b y t e s f r o m t h e Buf b u f f e r t o t h e c a l l i n g s t r e a m , starting at t h e current position.
439
440
Part I I I — R e f e r e n c e s
TEdit TEdit is a n i n t e r f a c e o b j e c t that c o r r e s p o n d s t o a n e d i t c o n t r o l e l e m e n t i n Windows. Y o u u s u a l l y d o n ' t u s e TEdit o b j e c t s i n d i a l o g b o x e s (TDialog) o r d i a l o g w i n d o w s (TDlgWindow). R a t h e r , y o u u s e t h e m t o d i s p l a y a s t a n d - a l o n e e d i t c o n t r o l as a c h i l d w i n d o w i n a n o t h e r w i n d o w ' s c l i e n t a r e a . T h e r e are t w o styles o f e d i t c o n t r o l o b j e c t s : s i n g l e - a n d m u l t i l i n e . M u l t i l i n e e d i t c o n t r o l s c a n u s e vertical s c r o l l b a r s a n d a l l o w t h e e d i t i n g o f m u l t i p l e l i n e s . M o s t o f TEdit's m e t h o d s m a n a g e t h e e d i t c o n t r o l ' s text. TEdit i n c l u d e s several c o m m a n d - b a s e d m e s s a g e - r e s p o n s e m e t h o d s f o r r e s p o n d i n g a u t o m a t i c a l l y t o C u t , C o p y , Paste, D e l e t e , C l e a r , a n d U n d o m e n u selections f r o m the edit control's parent w i n d o w . GetText a n d SetText a r e i n h e r i t e d f r o m TEdit's a n c e s t o r , TStatic.
Fields None.
Methods Init CanUndo ClearModify CMEditClear CMEditCopy CMEditCut CMEditDelete CMEditPaste CMEditUndo Copy Cut DeleteLine DeleteSelection DeleteSubText GetClassName GetLine GetLineFromPos GetLinelndex GetLineLength GetNumLines
A—ObjectWindows Objects
GetSelection GetSubText Insert IsModified Paste Scroll Search SetSelection SetupWindow Transfer Undo
Methods TEditlnit constructor Init(AParent: A T i t l e : PChar; X,Y,W,H:
PWindowsObject; A n l d : I n t e g e r ; Integer; Multiline : Boolean);
( O v e r r i d e : s o m e t i m e s ) C o n s t r u c t s a n edit c o n t r o l o b j e c t w i t h a p a r e n t w i n d o w (AParent). It fills its A t t r f i e l d s w i t h t h e f o l l o w i n g i n f o r m a t i o n : • Passed control I D (Anld) • Initial text ( A T i t l e ) • P o s i t i o n (X, Y) relative t o t h e o r i g i n o f t h e p a r e n t w i n d o w ' s c l i e n t a r e a • W i d t h (W) • H e i g h t (H) If M u l t i l i n e is T r u e , t h e edit c o n t r o l is a m u l t i l i n e e d i t c o n t r o l w i t h h o r i z o n t a l a n d vertical s c r o l l b a r s . I n this c a s e , t h e A t t r . S t y l e field i n c l u d e s the Windows s t y l e c o n s t a n t s e s _ M u l t i l i n e , e s _ A u t o V S c r o l l , e s _ A u t o H S c r o l l , e s _ L e f t, w s _ V S c r o l l , and w s _ H S c r o l l . If M u l t i l i n e is F a l s e , t h e edit c o n t r o l h a s a s i n g l e l i n e o f text a n d a b o r d e r ( w s _ B o r d e r ) , a n d is left-justified ( e s _ L e f t ) .
TEditCanUndo function
CanUndo:
Boolean;
virtual;
( O v e r r i d e : s e l d o m ) R e t u r n s T r u e if it's p o s s i b l e t o u n d o t h e last edit.
441
442
Part I I I — R e f e r e n c e s
TEdit.ClearModify procedure ClearModify; virtual; ( O v e r r i d e : s e l d o m ) R e s e t s t h e c h a n g e s flag f o r t h e edit c o n t r o l .
TEdit.CMEditClear procedure CMEditClear(var Msg: TMessage); virtual; cm_First + cm_EditClear; (Override: never) Automatically responds to a m e n u selection with a m e n u I D o f cm_EditClear b y s e n d i n g a m e s s a g e t o t h e Clear m e t h o d .
TEdit.CMEditCopy procedure CMEditCopy(var Msg: TMessage); virtual; cm_First + cm_EditCopy; (Override: never) Automatically responds to a m e n u selection with a m e n u I D o f cm_EditCopy b y s e n d i n g a m e s s a g e t o t h e Copy m e t h o d .
TEdit.CMEditCut procedure CMEditCut(var Msg: TMessage); virtual; cm_First + cm_EditCut; (Override: never) Automatically responds to a m e n u selection with a m e n u I D o f cm_EditCut b y s e n d i n g a m e s s a g e t o t h e Cut m e t h o d .
TEdit.CMEditDelete procedure CMEditDelete(var Msg: TMessage); virtual; cm_First + cm_EditDelete; (Override: never) Automatically responds t o a m e n u selection with a m e n u I D o f c m E d i t D e l e t e b y s e n d i n g a m e s s a g e t o t h e DeleteSelection m e t h o d .
TEdit.CMEditPaste procedure CMEditPaste(var Msg: TMessage); virtual; cm_First + cm_EditPaste; ( O v e r r i d e : n e v e r ) A u t o m a t i c a l l y r e s p o n d s t o a m e n u s e l e c t i o n w i t h a m e n u ID o f cm_EditPaste b y s e n d i n g a m e s s a g e t o t h e Paste m e t h o d .
A—ObjectWindows Objects
443
TEdit.CMEditUndo procedure CMEditUndo(var cm_First
Msg:
TMessage);
virtual;
+ cm_EditUndo;
(Override: never) Automatically responds to a m e n u selection with a m e n u I D o f c m E d i t U n d o b y s e n d i n g a m e s s a g e t o t h e Undo m e t h o d .
TEditCopy procedure Copy;
virtual;
( O v e r r i d e : s e l d o m ) C o p i e s a n y c u r r e n t l y s e l e c t e d text i n t o t h e c l i p b o a r d .
TEditCut procedure Cut;
virtual;
( O v e r r i d e : s e l d o m ) C u t s (that is, c o p i e s a n d d e l e t e s ) a n y c u r r e n t l y s e l e c t e d text into the clipboard.
TCditDeleteline function
DeleteLine{LineNumber:
Integer):
Boolean;
virtual;
( O v e r r i d e : s o m e t i m e s ) D e l e t e s t h e text i n t h e l i n e s p e c i f i e d b y L i n e N u m b e r i n a m u l t i l i n e edit c o n t r o l . D e l e t e L i n e d o e s n ' t d e l e t e t h e l i n e b r e a k a n d h a s n o effect o n o t h e r l i n e s . D e l e t e L i n e r e t u r n s T r u e if s u c c e s s f u l .
TEdit.DeleteSelection function
DeleteSelection:
Boolean;
virtual;
( O v e r r i d e : s e l d o m ) C l e a r s t h e c u r r e n t l y s e l e c t e d text a n d r e t u r n s F a l s e if n o text is s e l e c t e d .
TEdit.DeleteSubText function
DeleteSubText(StartPos,
EndPos:
Integer):
Boolean;
virtual;
( O v e r r i d e : s e l d o m ) D e l e t e s t h e text b e t w e e n t h e starting a n d e n d i n g p o s i t i o n s specified by S t a r t P o s and EndPos. T h e first c h a r a c t e r is at p o s i t i o n 0 , a n d t h e p o s i t i o n n u m b e r s c o n t i n u e s e q u e n t i a l l y t h r o u g h o u t all l i n e s i n a m u l t i l i n e e d i t c o n t r o l . L i n e b r e a k s are c o u n t e d as t w o c h a r a c t e r s . D e l e t e S u b T e x t r e t u r n s T r u e if s u c c e s s f u l .
444
Part I I I — R e f e r e n c e s
TEdit.GetClassName function GetClassName: PChar; virtual; ( O v e r r i d e : n e v e r ) R e t u r n s t h e n a m e o f TEdit's w i n d o w c l a s s , Edit.
TEditGetLine function GetLine(ATextString: PChar; StrSize, LineNumber: Integer): Boolean; virtual; ( O v e r r i d e : s e l d o m ) G e t s a m u l t i l i n e edit c o n t r o l ' s text f r o m t h e l i n e s p e c i f i e d b y LineNumber a n d r e t u r n s it i n ATextString. StrSize i n d i c a t e s t h e n u m b e r o f c h a r a c t e r s t o retrieve. GetLine r e t u r n s False if it's u n a b l e t o retrieve t h e text o r if t h e text is t o o long.
TEdit.GetIineFromPos function GetLineFromPos(CharPos: Integer): Integer; virtual; (Override: s e l d o m ) Returns f r o m a multiline edit control the line n u m b e r w h e r e t h e c h a r a c t e r p o s i t i o n s p e c i f i e d byCharPos o c c u r s . T h e p o s i t i o n o f t h e first c h a r a c t e r is 0 a n d t h e n u m b e r s c o n t i n u e s e q u e n t i a l l y t h r o u g h o u t all t h e l i n e s . L i n e b r e a k s are c o u n t e d as t w o c h a r a c t e r s .
TEdit.GetIineIndex function GetLineIndex(LineNumber: Integer): Integer; virtual; (Override: s e l d o m ) Returns f r o m a multiline edit control the n u m b e r o f c h a r a c t e r s that a p p e a r b e f o r e t h e l i n e n u m b e r s p e c i f i e d b y LineNumber. L i n e b r e a k s a r e c o u n t e d as t w o c h a r a c t e r s . If t h e l i n e d o e s n ' t exist, GetLinelndex r e t u r n s t h e n u m b e r o f c h a r a c t e r s in t h e edit control.
TEdit.GetIineLength function GetLineLength(LineNumber: Integer): Integer; virtual; (Override: s e l d o m ) Returns f r o m a multiline edit control the n u m b e r o f c h a r a c t e r s i n t h e l i n e s p e c i f i e d b y LineNumber. Note: S e n d GetLine a m e s s a g e b e f o r e y o u s e n d GetLineLength a m e s s a g e .
A — O b j e c t W i n d o w s Objects
445
TEdit.GetNumIines function GetNumLines: Integer; virtual; ( O v e r r i d e : s e l d o m ) R e t u r n s t h e n u m b e r of l i n e s that h a v e b e e n e n t e r e d i n a multiline edit control. ( S e n d GetNumLines a m e s s a g e b e f o r e y o u s e n d GetLinea m e s s a g e . )
TEdit.GetSelection procedure GetSelection(var StartPos, EndPos: Integer); virtual; ( O v e r r i d e : s e l d o m ) G e t s t h e starting a n d e n d i n g p o s i t i o n s of t h e c u r r e n t l y s e l e c t e d text a n d r e t u r n s t h e m i n t h e StartPos a n d EndPos a r g u m e n t s . T h e first c h a r a c t e r is at p o s i t i o n 0. I n a m u l t i l i n e edit c o n t r o l , t h e p o s i t i o n s are c o u n t e d s e q u e n t i a l l y t h r o u g h all l i n e s , a n d l i n e b r e a k s a r e c o u n t e d as t w o c h a r a c t e r s . U s e GetSelection w i t h GetSubText t o g e t t h e c u r r e n t l y s e l e c t e d text.
TEditGetSubText procedure GetSubText(ATextString:
PChar; StartPos, EndPos: Integer); virtual;
( O v e r r i d e : s e l d o m ) G e t s (in ATextString) t h e text i n a n e d i t c o n t r o l f r o m t h e i n d i c e s StartPos t o EndPos. T h e first c h a r a c t e r is at i n d e x 0. I n a multiline edit control, the characters are c o u n t e d sequentially t h r o u g h all t h e l i n e s , a n d l i n e b r e a k s a r e c o u n t e d as t w o c h a r a c t e r s .
TEditlnsert procedure Insert(ATextString: PChar); virtual; ( O v e r r i d e : s e l d o m ) I n s e r t s t h e text p a s s e d i n AText St r ing i n t o t h e e d i t c o n t r o l at t h e c u r r e n t t e x t - i n s e r t i o n p o i n t , r e p l a c i n g a n y c u r r e n t l y s e l e c t e d text. Insert is s i m i l a r t o Paste, b u t d o e s n ' t affect t h e c l i p b o a r d .
TEditJsModified function IsModified: Boolean; virtual; ( O v e r r i d e : s e l d o m ) I f t h e u s e r h a s c h a n g e d t h e text i n t h e e d i t c o n t r o l , IsModified r e t u r n s T r u e .
446
Part III—References
TEditPaste procedure Paste;
virtual;
( O v e r r i d e : s e l d o m ) Inserts text f r o m t h e c l i p b o a r d i n t o t h e e d i t c o n t r o l at t h e current insertion point.
TEdit.Scroll procedure S c r o l l ( H o r i z o n t a l U n i t ,
VerticalUnit:
Integer);
virtual;
( O v e r r i d e : s e l d o m ) S c r o l l s a m u l t i l i n e e d i t c o n t r o l h o r i z o n t a l l y a n d vertically b y the n u m b e r s of characters specified by H o r i z o n t a l U n i t a n d V e r t i c a l U n i t . Positive v a l u e s s c r o l l t o t h e right o r d o w n , a n d n e g a t i v e v a l u e s s c r o l l t o t h e left o r u p .
TEditSearch procedure S e a r c h ( S t a r t P o s : I n t e g e r ; AText: CaseSensitive: Boolean): Integer;
PChar;
S e a r c h s e a r c h e s t h e e d i t c o n t r o l ' s text ( b e g i n n i n g w i t h t h e c h a r a c t e r at S t a r t P o s ) u n t i l it f i n d s a m a t c h f o r A T e x t . • If t h e text is f o u n d , t h e m a t c h i n g text is s e l e c t e d , a n d S e a r c h r e t u r n s t h e p o s i t i o n o f t h e start o f t h e m a t c h e d text. • If A T e x t isn't f o u n d , S e a r c h r e t u r n s - 1 . Pass - 1 i n S t a r t P o s t o b e g i n t h e s e a r c h at t h e c u r r e n t p o s i t i o n .
TEditSetSelection function
SetSelection(StartPos,
EndPos:
Integer):
Boolean;
virtual
( O v e r r i d e : s e l d o m ) F o r c e s s e l e c t i o n o f t h e text b e t w e e n t h e p o s i t i o n s s p e c i f i e d b y S t a r t P o s a n d E n d P o s , b u t n o t i n c l u d i n g t h e c h a r a c t e r at E n d P o s . T h e first c h a r a c t e r is at p o s i t i o n 0, a n d t h e p o s i t i o n n u m b e r s c o n t i n u e s e q u e n t i a l l y t h r o u g h all l i n e s i n a m u l t i l i n e edit c o n t r o l . L i n e b r e a k s are c o u n t e d as t w o c h a r a c t e r s .
A—ObjectWindows Objects
447
TEdit.SetupWindow procedure SetupWindow;
virtual;
L i m i t s t h e n u m b e r o f c h a r c t e r s that c a n b e e n t e r e d i n t o t h e edit c o n t r o l b y sending a message to T S t a t i c . SetupWindow. I f t h e T e x t L e n f i e l d is n o n z e r o , t h e v a l u e T e x t L e n -1 is s e n t t o W i n d o w s though an e m _ L i m i t T e x t message.
TEdit.Transfer function
Transfer(DataPtr:
Pointer;
TransferFlag:
W o r d ) : Word;
( O v e r r i d e : s o m e t i m e s ) T r a n s f e r s T e x t L e n c h a r a c t e r s o f t h e c u r r e n t text o f t h e edit control to or f r o m the m e m o r y location p o i n t e d to by D a t a P t r . • If T r a n s f e r F l a g is t f _ G e t D a t a , t h e text is t r a n s f e r r e d t o t h e m e m o r y location. • If T r a n s f e r F l a g is t f _ S e t D a t a , t h e edit c o n t r o l ' s text is set t o t h e text at t h e m e m o r y l o c a t i o n . T r a n s f e r r e t u r n s T e x t L e n (the n u m b e r o f bytes stored in o r retrieved f r o m the m e m o r y location). • If T r a n s f e r F l a g is t f _ S i z e D a t a , T r a n s f e r r e t u r n s t h e size o f t h e transfer d a t a .
TEditUndo procedure
Undo;
virtual;
( O v e r r i d e : s e l d o m ) U n d o e s t h e last edit.
TEmsStream TEmsSt rearn is a s p e c i a l i z e d T S t ream f o r i m p l e m e n t i n g s t r e a m s i n E M S m e m o r y . T E m s S t ream's n e w fields set u p a n E M S h a n d l e , a p a g e c o u n t , s t r e a m s i z e , a n d c u r r e n t p o s i t i o n . T E m s S t r e a m o v e r r i d e s t h e six abstract m e t h o d s o f T S t r e a m a n d i m p l e m e n t s its o w n s p e c i a l i z e d c o n s t r u c t o r a n d d e s t r u c t o r . W h e n y o u d e b u g an application using E M S streams, the I D E cannot r e c o v e r E M S m e m o r y a l l o c a t e d b y a p p l i c a t i o n s if a n a p p l i c a t i o n t e r m i n a t e s p r e m a t u r e l y o r if y o u d o n ' t s e n d a m e s s a g e t o t h e (Done) d e s t r u c t o r f o r a n E M S s t r e a m . O n l y t h e Done m e t h o d ( o r r e b o o t i n g ) c a n r e l e a s e t h e E M S p a g e s o w n e d by the stream.
virtual;
448
Part I I I — R e f e r e n c e s
Fields Handle PageCount Size Position
Methods Init Done GetPos GetSize Read Seek Truncate Write
Fields TEmsStream.Handle Handle: Word; ( r e a d o n l y ) T h e E M S handle for the stream.
TEmsStream.PageCount PageCount: W o r d ; (read o n l y ) T h e n u m b e r o f allocated pages for the stream: 16K p e r page.
TEmsStream.Size Size: Longint; ( r e a d o n l y ) T h e size o f t h e s t r e a m i n b y t e s .
TEmsStream.Position Position: Longint; (read o n l y ) T h e c u r r e n t p o s i t i o n w i t h i n t h e s t r e a m . T h e first p o s i t i o n is 0.
A—ObjectWindows Objects
Methods TEmsStream.Init constructor Init(MinSize: Longint); C r e a t e s a n E M S s t r e a m w i t h t h e MinSize ( i n b y t e s ) . S e n d s a m e s s a g e t o Init a n d t h e n sets Handle, Size a n d PageCount. S e n d s a m e s s a g e t o Error w i t h a n a r g u m e n t of st I nit Error if i n i t i a l i z a t i o n fails.
TEmsStream.Done destructor Done; virtual; (Override: never) Disposes o f the E M S stream a n d releases E M S pages u s e d .
TEmsStream.GetPos function GetPos: Longint; virtual; (Override: never) Returns the value o f the calling stream's current position.
TEmsStream.GetSize function GetSize: Longint; virtual; ( O v e r r i d e : n e v e r ) R e t u r n s t h e size o f t h e c a l l i n g s t r e a m .
TEmsStream.Read procedure Read(var Buf; Count: Word); virtual; ( O v e r r i d e : n e v e r ) R e a d s Count b y t e s i n t o t h e Buf b u f f e r starting at t h e c a l l i n g stream's current position.
TEmsStream.Seek procedure Seek(Pos: Longint); virtual; ( O v e r r i d e : n e v e r ) R e s e t s t h e c u r r e n t p o s i t i o n t o Pos bytes f r o m t h e start of t h e calling stream.
449
450
Part I I I — R e f e r e n c e s
TEmsStream.Truncate procedure Truncate; virtual; ( O v e r r i d e : n e v e r ) D e l e t e s all d a t a o n t h e c a l l i n g s t r e a m f r o m t h e c u r r e n t p o s i t i o n t o t h e e n d . T h e c u r r e n t p o s i t i o n is set t o t h e n e w e n d o f t h e s t r e a m .
TEmsStream.Write procedure Write(var Buf; Count: Word); virtual; ( O v e r r i d e : n e v e r ) W r i t e s Count b y t e s from t h e Buf b u f f e r t o t h e c a l l i n g s t r e a m , starting at t h e c u r r e n t p o s i t i o n .
TGroupBox TGroupBox is a n i n t e r f a c e o b j e c t that c o r r e s p o n d s t o a g r o u p b o x e l e m e n t i n Windows. N o r m a l l y , y o u d o n ' t u s e TGroupBox o b j e c t s i n d i a l o g b o x e s (TDialog) o r d i a l o g w i n d o w s (TDlgWindow). R a t h e r , y o u u s e t h e m w h e n y o u w a n t t o d i s p l a y a s t a n d - a l o n e g r o u p b o x as a c h i l d w i n d o w i n a n o t h e r w i n d o w ' s c l i e n t a r e a . G r o u p b o x e s unify a g r o u p o f selection boxes (check b o x e s a n d radio b u t t o n s ) a n d m a n a g e t h e states o f t h e i r s e l e c t i o n b o x e s .
Fields NotifyParent
Methods Init Load GetClassName InitResource SelectionChanged Store
A—ObjectWindows Objects
Fields TGroupBox.NotifyParent NotifyParent: Boolean;
(read/write)
I n d i c a t e s w h e t h e r t h e p a r e n t w i l l b e n o t i f i e d w h e n t h e state o f t h e g r o u p b o x ' s selection boxes has changed.
Methods TGroupBox.Init constructor Init(AParent: PWindowsObject; AnID: Integer; AText: PChar; X,Y,W,H: Integer); (Override: sometimes) Constructs a g r o u p b o x object with the following information: • P a s s e d p a r e n t w i n d o w (AParent) • C o n t r o l ID (AnId) • A s s o c i a t e d text (AText) • P o s i t i o n (X, Y) relative t o t h e o r i g i n o f t h e p a r e n t w i n d o w ' s c l i e n t a r e a • W i d t h (W) • H e i g h t (H) S e n d s a m e s s a g e t o TControl. Init a n d t h e n a d d s t h e W i n d o w s style bs_Grou pBox t o t h e g r o u p b o x ' s At t r. Style field. R e m o v e s t h e style ws_TabSt op f r o m t h e g r o u p b o x ' s Attr. Style field. S e t s Notif yParent t o T r u e . B y d e f a u l t , t h e g r o u p b o x ' s p a r e n t is n o t i f i e d w h e n t h e state o f its s e l e c t i o n b o x e s c h a n g e .
TGroupBoxIoad constructor Load(var S: TStream); C o n s t r u c t s a n d l o a d s a g r o u p b o x f r o m t h e s t r e a m , S, b y s e n d i n g a m e s s a g e t o TControl. Load a n d r e a d i n g t h e a d d i t i o n a l field (Notif yParent) i n t r o d u c e d b y TGroupBox.
451
452
Part I I I — R e f e r e n c e s
TGroupBox.GetClassName function GetClassName: PChar; virtual; ( O v e r r i d e : s o m e t i m e s ) R e t u r n s t h e n a m e o f TGroupBox's w i n d o w class, Button.
TGroupBox.InitResource constructor InitResource(AParent: PWindowsObject; ResourcelD: Word); Subclasses the g r o u p b o x by constructing an ObjectWindows object to corres p o n d to a g r o u p b o x element created by a dialog resource definition. S e n d s a m e s s a g e t o T C o n t r o l . I n i t R e s o u r c e as w e l l as TWindowsObject.DisableTransferto e x c l u d e g r o u p b o x e s f r o m t h e transfer m e c h a n i s m because they have n o data to b e transferred.
TGroupBox.SelectionChanged procedure SelectionChanged(ControlId: Integer); virtual; ( O v e r r i d e : s o m e t i m e s ) If Notif yParent is T r u e , SelectionChanged notifies t h e p a r e n t w i n d o w o f t h e g r o u p b o x that o n e o f its s e l e c t i o n s h a s c h a n g e d b y s e n d i n g it a c h i l d - I D - b a s e d m e s s a g e . Y o u c a n o v e r r i d e this m e t h o d t o let t h e g r o u p b o x r e s p o n d t o its s e l e c t i o n s .
TGroupBox.Store procedure Store(var S: TStream); S t o r e s t h e g r o u p b o x o n t h e s t r e a m , S, b y first s e n d i n g a m e s s a g e t o TControl. Store a n d t h e n w r i t i n g t h e a d d i t i o n a l field (Notif yParent) i n t r o d u c e d b y TGroupBox.
TlistBox TListBox is a n i n t e r f a c e o b j e c t that c o r r e s p o n d s t o a list b o x e l e m e n t i n Windows. U s u a l l y , y o u d o n ' t u s e TListBox o b j e c t s i n d i a l o g b o x e s (TDialog) or d i a l o g w i n d o w s (TDlgWindow). R a t h e r , y o u d i s p l a y a s t a n d - a l o n e list b o x as a c h i l d w i n d o w i n a n o t h e r w i n d o w ' s c l i e n t area. TListBox's m e t h o d s a l s o serve o b j e c t i n s t a n c e s o f its d e s c e n d a n t , TComboBox.
A—ObjectWindows Objects
453
Fields None.
Methods Init AddString ClearList DeleteString GetClassName GetCount GetMsgID GetSellndex GetSelString GetStringLen GetString InsertString SetSellndex SetSelString Transfer
Methods TIistBox.Init constructor Init(AParent: PWindowsObject; Anld: Integer; X,Y, W,H: Integer); ( O v e r r i d e : s o m e t i m e s ) C o n s t r u c t s a list b o x o b j e c t w i t h t h e f o l l o w i n g parameters: • P a s s e d p a r e n t w i n d o w (AParent) • Control I D (Anld) • P o s i t i o n (X, Y) relative t o t h e o r i g i n o f t h e p a r e n t w i n d o w ' s c l i e n t a r e a • W i d t h (W) • H e i g h t (H) I nit s e n d s a m e s s a g e t o TCont rol. I nit a n d a d d s t o t h e list b o x o b j e c t ' s Att r. Style field t h e W i n d o w s style c o n s t a n t lbs_Standard, w h i c h s u p p l i e s the scroll b a r with the following
454
Part I I I — R e f e r e n c e s
• A b o r d e r (ws_Border) • A vertical s c r o l l b a r (ws_VScroll) • A u t o m a t i c a l p h a b e t i c s o r t i n g o f list i t e m s (lbs_Sort) • P a r e n t w i n d o w n o t i f i c a t i o n u p o n s e l e c t i o n (lbsNotif y) Y o u c a n o v e r r i d e t h e s e styles i n a d e s c e n d a n t c l a s s , o r i n t h e Init c o n s t r u c t o r o f t h e list b o x ' s p a r e n t w i n d o w o b j e c t .
TlistBoxAddString function AddString(AString: PChar): Integer; virtual; ( O v e r r i d e : s o m e t i m e s ) A d d s AString as a list i t e m i n t h e list b o x o b j e c t , a n d r e t u r n s t h e i t e m ' s p o s i t i o n i n d e x (starting at 0) o r a n e g a t i v e v a l u e i n c a s e o f an error. List i t e m s a r e s o r t e d a u t o m a t i c a l l y u n l e s s t h e style l b s S o r t is r e m o v e d f r o m t h e list b o x o b j e c t ' s Attr. Style field b e f o r e t h e list b o x is c r e a t e d .
TIistBox.ClearList procedure ClearList; virtual; ( O v e r r i d e : s o m e t i m e s ) R e m o v e s all (list) i t e m s f r o m t h e list b o x .
TIistBox.DeleteString function DeleteString(Index:
Integer): Integer; virtual;
( O v e r r i d e : s o m e t i m e s ) R e m o v e s t h e list i t e m at t h e p o s i t i o n i n d e x (starting at 0) p a s s e d i n Index. DeleteString r e t u r n s t h e n u m b e r o f r e m a i n i n g list i t e m s , or a negative value in case o f a n error.
TListBox.GetClassName function GetClassName: PChar; virtual; ( O v e r r i d e : n e v e r ) R e t u r n s t h e n a m e o f t h e TListBox w i n d o w class, List Box.
TListBox.GetCount function GetCount: Integer; virtual; ( O v e r r i d e : s e l d o m ) R e t u r n s t h e n u m b e r o f list i t e m s i n t h e list b o x , o r a n e g a t i v e value in case o f a n error.
A—ObjectWindows Objects
455
TListBox.GetMsgID function GetMsgID(AMsg: TMsgName): virtual; T r a n s l a t e s list b o x m e s s a g e s f o r TComboBox o b j e c t s . T h i s m e t h o d is private available t o t h e p r o g r a m m e r ) .
(not
TListBox.SelIndex function GetSellndex: Integer; virtual; ( O v e r r i d e : s e l d o m ) R e t u r n s t h e p o s i t i o n i n d e x (starting at 0) o f t h e c u r r e n t l y s e l e c t e d list i t e m , o r a n e g a t i v e v a l u e i n c a s e n o i t e m is s e l e c t e d .
TListBox.GetSelString function GetSelString(AString:
PChar; MaxChars: Integer):
Integer; virtual; ( O v e r r i d e : s e l d o m ) G e t s t h e c u r r e n t l y s e l e c t e d list i t e m (in AString), if it's s h o r t e r t h a n MaxChars. GetSelString r e t u r n s t h e string l e n g t h o r a n e g a t i v e v a l u e i n c a s e o f a n error.
TListBox.GetStringLen function GetStringLen(Index:
Integer): Integer; virtual;
( O v e r r i d e : s e l d o m ) R e t u r n s t h e l e n g t h o f t h e list i t e m (a string) at t h e p o s i t i o n Index, o r a n e g a t i v e v a l u e i n c a s e o f a n e r r o r .
TListBox.GetString function GetString(AString: PChar; Index: Integer): Integer; virtual; ( O v e r r i d e : s e l d o m ) G e t s i n AString t h e list i t e m at t h e p o s i t i o n Index, a n d returns t h e string length o r a negative value in case o f a n error.
TListBox.InsertString function InsertString(AString:
PChar; Index: Integer): Integer; virtual;
( O v e r r i d e : s o m e t i m e s ) I n s e r t s AString as a list i t e m i n t h e list b o x at t h e p o s i t i o n I n d e x , a n d r e t u r n s t h e i t e m ' s p o s i t i o n (starting at 0) o r a n e g a t i v e v a l u e i n c a s e o f a n e r r o r . T h e list b o x i t e m s a r e n ' t r e s o r t e d . I f Index is - 1 , t h e string is a d d e d t o t h e e n d o f t h e list.
456
Part I I I — R e f e r e n c e s
TListBox.SetSelIndex function
SetSelIndex(Index:
Integer):
Integer;
virtual;
( O v e r r i d e : s e l d o m ) F o r c e s s e l e c t i o n o f t h e list i t e m at t h e p o s i t i o n I n d e x . If I n d e x is - 1 , t h e list b o x is c l e a r e d o f a n y s e l e c t i o n . S e t S e l l n d e x returns a negative n u m b e r in case o f an error.
TIistBox.SetSelString function
SetSelString(AString:
PChar;
AIndex:
Integer):
Integer;
virtual;
( O v e r r i d e : s e l d o m ) F o r c e s s e l e c t i o n o f t h e first list i t e m m a t c h i n g A S t r i n g that a p p e a r s after t h e p o s i t i o n i n d e x ( b e g i n n i n g at 0) p a s s e d i n A I n d e x . If A I n d e x i s - 1 , t h e e n t i r e list is s e a r c h e d from t h e b e g i n n i n g . S e t S e l S t r i n g returns the position index of the newly selected item, or a negative value in case o f an error.
TIistBox.Thnsfef function
Transfer(DataPtr:
Pointer;
TransferFlag:
W o r d ) : Word;
T r a n s f e r s t h e list o f e n t r i e s a n d s e l e c t e d i t e m ( s ) t o o r f r o m t h e transfer r e c o r d pointed to by D a t a P t r . • If T r a n s f e r F l a g is t f _ G e t D a t a , t h e list b o x ' s d a t a is t r a n s f e r r e d t o t h e m e m o r y l o c a t i o n . T h e n u m b e r o f b y t e s t r a n s f e r r e d is r e t u r n e d . • If T r a n s f e r F l a g is t f _ S e t D a t a , t h e list b o x is l o a d e d w i t h t h e data from the m e m o r y location. T h e n u m b e r o f bytes transferred is r e t u r n e d . • If T r a n s f e r F l a g is t f _ S i z e D a t a , T r a n s f e r r e t u r n s t h e size o f t h e transfer d a t a . D e p e n d i n g o n where the b o x allows multiple items to be selected, the transfer r e c o r d v a r i e s . T h e first i t e m t r a n s f e r r e d is always a p o i n t e r t o a collection o f strings. • F o r s i n g l e - s e l e c t i o n list b o x e s , t h e p o i n t e r is f o l l o w e d b y a n i n t e g e r index to the selected item. • F o r m u l t i p l e - s e l e c t i o n list b o x e s , t h e c o l l e c t i o n is f o l l o w e d b y a p o i n t e r t o a T M u l t i S e l R e c r e c o r d , w h i c h c o n t a i n s a n array o f i n t e g e r s , e a c h indicating a selected item.
virtual;
A — O b j e c t W i n d o w s Objects
TMDIClient Multiple D o c u m e n t Interface ( M D I ) client w i n d o w s (represented by TMDIClient) a r e c o n t r o l s that m a n a g e t h e M D I c h i l d w i n d o w s o f a n M D I a p p l i c a t i o n . TMDIClient's m e t h o d s m a n a g e M D I c h i l d w i n d o w s .
Fields ClientAttr
Methods Init Load Arrangelcons CascadeChildren GetClassName Store TileChildren
Fields TMDIClient.ClientAttr ClientAttr:
TClientCreateStruct;
ClientAttr m a i n t a i n s a r e c o r d o f t h e M D I c l i e n t w i n d o w ' s a t t r i b u t e s . T h e r e c o r d (TClientCreateStruct) is d e f i n e d as f o l l o w s :
type PClientCreateStruct = "TClientCreateStruct; TClientCreateStruct = record hWindowMenu: THandle; idFirstChild: Word; end;
457
458
Part I I I — R e f e r e n c e s
Methods TMDICUent.Init constructor Init(AParent: PMDIWindow); ( O v e r r i d e : s e l d o m ) C o n s t r u c t s t h e M D I c l i e n t w i n d o w o b j e c t w i t h AParent as t h e p a r e n t w i n d o w . Init s e t s t h e f i e l d s o f ClientAttr. T h e n s e n d s TControl. Init a m e s s a g e a n d a d d s t h e W i n d o w s style ws_ClipChildren t o t h e w i n d o w o b j e c t ' s Attr. Style field. Init a l s o r e m o v e s t h e c l i e n t w i n d o w f r o m its p a r e n t ' s c h i l d w i n d o w list s o that t h e c l i e n t w i n d o w isn't t r e a t e d like o t h e r c h i l d w i n d o w s , s u c h as list boxes and buttons.
TMDIClient.Load constructor Load(var S: TStream); C o n s t r u c t s a n d l o a d s a n M D I c l i e n t w i n d o w f r o m t h e s t r e a m , S, b y first s e n d i n g TControl. Load a m e s s a g e a n d t h e n r e a d i n g t h e a d d i t i o n a l f i e l d (ClientAttr) i n t r o d u c e d b y TMDIClient.
TMDIClient.ArrangeIcons procedure Arrangelcons; virtual; (Override: seldom) Arranges the m i n i m i z e d M D I child w i n d o w s into a neat r o w at t h e b o t t o m o f t h e M D I c l i e n t w i n d o w .
TMDIClient.CascadeChildren procedure CascadeChildren; virtual; ( O v e r r i d e : s e l d o m ) S i z e s a n d a r r a n g e s all o f t h e n o n m i n i m i z e d MDI c h i l d w i n d o w s w i t h i n t h e MDI c l i e n t w i n d o w .
TMDIClient.GetClassName function GetClassName: PChar; virtual; R e t u r n s TControl's w i n d o w class n a m e , MDIClient.
A — O b j e c t W i n d o w s Objects
TMDIClientStore procedure Store(var S: TStream); S t o r e s t h e M D I c l i e n t w i n d o w o n t h e s t r e a m , S, b y s e n d i n g TControl. Store a m e s s a g e a n d t h e n w r i t i n g t h e a d d i t i o n a l field (ClientAttr) i n t r o d u c e d b y TMDIClient.
TMDIClientTileChildren procedure TileChildren; virtual; ( O v e r r i d e : s e l d o m ) S i z e s a n d a r r a n g e s all t h e n o n m i n i m i z e d MDI c h i l d w i n d o w s w i t h i n t h e M D I c l i e n t w i n d o w u s i n g all available s p a c e w i t h o u t l e t t i n g t h e windows overlap.
TMDIWindow Multiple D o c u m e n t Interface (MDI) frame w i n d o w (defined by TMDIWindow)— the main w i n d o w o f MDI-compliant applications. TMDIWindow o b j e c t s ownaTMDIClient o b j e c t a n d store it i n t h e ClientWnd field. T h e c h i l d w i n d o w m e n u p r e s e n t s m a n i p u l a t i o n o p t i o n s f o r t h e a p p l i c a t i o n ' s M D I c h i l d w i n d o w s . T h i s w i n d o w is m o d i f i e d a u t o m a t i c a l l y t o reflect all displayed M D I child windows.
Fields ChildMenuPos ClientWnd
Methods Init Load Done Arrangelcons CascadeChildren CMCloseChildren CMCreateChild CMTileChildren
459
460
Part I I I — R e f e r e n c e s
CreateChild DefWndProc GetClassName GetClient GetWindowClass InitChild InitClientWindow SetupWindow Store TileChildren
Fields TMDIWindow.ChildMenuPos ChildMenuPos:
Integer;
(read/write)
C h i l d M e n u P o s specifies an i n d e x identifying the position o f the child-window m a n a g e m e n t m e n u . T h e i n d e x c o u n t s o n l y t o p - l e v e l m e n u i t e m s . T h e top-left i t e m is at p o s i t i o n 0.
TMDIWindow.ClientWnd ClientWnd:
PMDIClient;
(read
only)
C l i e n t W n d points to the M D I frame w i n d o w ' s M D I client w i n d o w , an object instance of T M D I C l i e n t .
Methods TMDIWindow.Init constructor
Init(ATitle:
PChar;
AMenu:
HMenu);
(Override: often) Constructs an M D I frame w i n d o w object using the caption p a s s e d i n A T i t l e a n d t h e m e n u p a s s e d i n AMenu. M D I frame w i n d o w s must have m e n u s . A n M D I frame w i n d o w has n o parent w i n d o w , a n d must b e the m a i n w i n d o w of the application. By default, I n i t sets C h i l d M e n u P o s t o 0, i n d i c a t i n g that t h e c h i l d w i n d o w m e n u is t h e t o p left m e n u . T o modify C h i l d M e n u P o s , override I n i t in y o u r descendant types. For example:
A—ObjectWindows Objects
constructor NewMDIWindow.Init(ATitle: PChar; AMenu: HMenu); begin TMDIWindow.Init(ATitle, AMenu); ChildMenuPos := 3; end;
TMDIWindow.Load constructor Load(var S: TStream); C o n s t r u c t s a n d l o a d s a n M D I frame w i n d o w from t h e s t r e a m , S, b y c a l l i n g TWindow.Load a n d t h e n g e t t i n g a n d r e a d i n g t h e fields (ClientWnd a n d
ChildMenuPos) d e f i n e d b y TMDIWindow.
TMDIWindow.Done destructor Done; virtual; (Override: sometimes) Disposes o f the M D I client w i n d o w object stored in ClientWnd b e f o r e s e n d i n g a m e s s a g e t o TWindow. Done t o d i s p o s e o f t h e M D I frame w i n d o w object.
TMDIWindow.ArrangeIcons procedure Arrangelcons; (Override: seldom) Arranges the minimized M D I child windows into a n e a t r o w at t h e b o t t o m o f t h e M D I c l i e n t w i n d o w . S e n d s a m e s s a g e t o
ClientWnd".Arrangelcons.
TMDIWindow.CascadeChildren procedure CascadeChildren; ( O v e r r i d e : s e l d o m ) S i z e s a n d a r r a n g e s all o f t h e n o n m i n i m i z e d M D I c h i l d w i n d o w s w i t h i n t h e M D I c l i e n t w i n d o w m a k i n g t h e m o v e r l a p . D i s p l a y s t h e title b a r o f e a c h o n e . S e n d s a m e s s a g e t o ClientWnd" .CascadeChildren.
mDIWindow.CMCloseChildren procedure CMCloseChildren(var Msg: TMessage); virtual cm_First + cm_CloseChildren; (Override:
seldom)
Responds
to a menu
selection
with
cm_CloseChildren b y s e n d i n g a m e s s a g e t o CloseChildren.
an ID of
461
462
Part I I I — R e f e r e n c e s
mDIWindow.CMCreateCWld procedure CMCreateChild(var Msg: TMessage); virtual cm_First + cm_CreateChild; (Override: never) Responds to a m e n u selection with a m e n u I D of cm_CreateChild b y s e n d i n g a m e s s a g e t o CreateChild t o c r e a t e a n e w c h i l d window.
TMDIWindow.CMTileChildren procedure CMTileChildren(var Msg: TMessage); virtual cm_First + cm_TileChildren; ( O v e r r i d e : s e l d o m ) R e s p o n d s t o a m e n u s e l e c t i o n w i t h a n I D o f cmTileChild ren b y s e n d i n g a m e s s a g e t o TileChildren.
TMDIWindow.CreateChild function CreateChild:
PWindowsObject;
virtual;
Constructs a n d creates a n e w M D I child w i n d o w by s e n d i n g messages t o InitChild a n d MakeWindow. Y o u d o n ' t h a v e t o o v e r r i d e CreateChild t o handle descendant M D I child w i n d o w types. CreateChild r e t u r n s a p o i n t e r t o t h e n e w M D I c h i l d w i n d o w .
TMDIWindow.DefWndProc procedure DefWndProc(var Msg: TMessage);
virtual;
O v e r r i d e s TWindow's d e f a u l t W i n d o w s m e s s a g e p r o c e s s i n g b y s e n d i n g a m e s s a g e t o t h e W i n d o w s f u n c t i o n Def FrameProc r a t h e r t h a n DefWindowProc.
TMDIWindow.GetClassName function GetClassName:
PChar;
virtual;
( O v e r r i d e : s o m e t i m e s ) R e t u r n s t h e n a m e o f TMDI Window's w i n d o w class n a m e ,
TurboMDIWindow.
TMDIWindow.GetClient function GetClient: PMDIClient;
virtual;
(Override: never) Returns a pointer t o the M D I client w i n d o w stored in
ClientWnd.
A — O b j e c t W i n d o w s Objects
TMDIWindow.GetWindowClass procedure GetWindowClass(var AWndClass: TWndClass); virtual; ( O v e r r i d e : s o m e t i m e s ) M o d i f i e s t h e d e f a u l t w i n d o w class r e c o r d a n d s e n d s it b a c k i n AWndClass. GetWindowClass sets t h e style f i e l d t o 0 t o r e m o v e t h e
styles set b y TWindow.GetWindowClass.
TMDIWindow.InitChad function InitChild: PWindowsObject; virtual; ( O v e r r i d e : o f t e n ) C o n s t r u c t s a n M D I c h i l d w i n d o w o b j e c t (TWindow) w i t h a d e f a u l t c a p t i o n of " M D I C h i l d " a n d r e t u r n s a p o i n t e r t o it. If y o u d e f i n e a n M D I c h i l d w i n d o w t y p e d e s c e n d i n g f r o m TWindow, o v e r r i d e InitChild t o c o n s t r u c t a w i n d o w u s i n g t h e n e w d e f i n e d M D I c h i l d w i n d o w type. For example:
function NewMDIWindow.InitChild: PWindowsObject; begin InitChild := New(PNewMDIChild, Init(@Self, 'New MDI Child Window')); end;
TMDIWindow.InitClientWindow procedure InitClientWindow; virtual; ( O v e r r i d e : s o m e t i m e s ) C o n s t r u c t s t h e M D I c l i e n t w i n d o w as a TMDIClient o b j e c t a n d s t o r e s it i n ClientWnd.
TMDIWindow.SetupWindow procedure SetupWindow; virtual; ( O v e r r i d e : o f t e n ) C o n s t r u c t s t h e M D I c l i e n t w i n d o w (ClientWnd) o b j e c t ' s c o r r e s p o n d i n g w i n d o w e l e m e n t b y s e n d i n g a m e s s a g e t o I nitClientWindow. SetupWindow s e n d s MakeWindow a m e s s a g e t o c r e a t e t h e M D I c l i e n t w i n d o w . If y o u o v e r r i d e SetupWindow i n a d e s c e n d a n t t y p e , s e n d a m e s s a g e t o TMDIWindow.SetupWindow e x p l i c i t l y b e f o r e i m p l e m e n t i n g y o u r a p p l i c a t i o n window's n e w behavior.
463
464
Part I I I — R e f e r e n c e s
TMDIWindow.Store procedure Store(var S: TStream); S t o r e s t h e M D I f r a m e w i n d o w o n t h e s t r e a m , S, b y s e n d i n g a m e s s a g e t o TWindow.Store. It t h e n w r i t e s t h e a d d i t i o n a l f i e l d s (ClientWnd a n d ChildMenuPos) d e f i n e d b y TMDIWindow.
mDIWindowTileCMdren procedure TileChildren; ( O v e r r i d e : s e l d o m ) S i z e s a n d a r r a n g e s all t h e n o n m i n i m i z e d M D I c h i l d w i n d o w s w i t h i n t h e M D I c l i e n t w i n d o w , u s i n g all available w i n d o w s p a c e w i t h o u t o v e r l a p p i n g t h e w i n d o w s . S e n d s a m e s s a g e t o ClientWnd" .TileChildren.
TObject TOb j ect is t h e starting p o i n t o f t h e O b j e c t W i n d o w s o b j e c t h i e r a r c h y . W i t h t h e e x c e p t i o n o f TPoint a n d TRect, all O b j e c t W i n d o w s s t a n d a r d o b j e c t s a r e d e r i v e d (directly o r indirectly) from TOb j ect. A n y o b j e c t that u s e s O b j e c t W i n d o w s s t r e a m s m u s t trace its a n c e s t r y b a c k t o TOb j ect.
Fields None.
Methods Init Free Done
Methods TObjectlnit constructor Init; Allocates space o n the heap for an object. R e c e i v e s a m e s s a g e f r o m all its d e s c e n d a n t o b j e c t s ' c o n s t r u c t o r s .
A — O b j e c t W i n d o w s Objects
TObjectFree procedure Free; D i s p o s e s o f t h e o b j e c t a n d s e n d s a m e s s a g e t o t h e Done d e s t r u c t o r .
TObjectDone destructor Done; virtual; Handles cleanup a n d disposal for dynamic objects.
TRadioButton TRadioButtonisan i n t e r f a c e o b j e c t that c o r r e s p o n d s t o a r a d i o b u t t o n e l e m e n t in W i n d o w s . Y o u n o r m a l l y d o n ' t u s e TRadioButton o b j e c t s i n d i a l o g b o x e s (TDialog) o r d i a l o g w i n d o w s (TDlgWindow). I n s t e a d , u s e t h e m w h e n y o u w a n t t o d i s p l a y a s t a n d - a l o n e r a d i o b u t t o n as a c h i l d w i n d o w i n a n o t h e r w i n d o w ' s c l i e n t a r e a . A r a d i o b u t t o n is i n o n e o f t w o states: c h e c k e d o r u n c h e c k e d . TRadioButton i n h e r i t s its s t a t e - m a n a g e m e n t m e t h o d s f r o m its a n c e s t o r , TCheckBox. A c h e c k b o x c a n a l s o b e part o f a g r o u p (TGroupBox), w h i c h v i s u a l l y a n d c o n c e p t u a l l y g r o u p s its c o n t r o l s .
Fields None.
Methods Init
Methods TRadioButton.Init constructor Init(AParent: PWindowsObject; AnID: Integer; ATitle: PChar; X,Y,W,H: Integer; AGroup: PGroupBox);
465
466
Part I I I — R e f e r e n c e s
(Override: sometimes) Constructs a radio button object with the following arguments: • P a s s e d p a r e n t w i n d o w (AParent) • C o n t r o l I D (Anld) • A s s o c i a t e d text (ATitle) • P o s i t i o n (X, Y) relative t o t h e o r i g i n o f t h e p a r e n t w i n d o w ' s c l i e n t a r e a • W i d t h (W) • H e i g h t (H) • A s s o c i a t e d g r o u p b o x (AGroup) Init sets t h e c h e c k b o x ' s Att r. Style field t o ws_Child or ws_Visible or bs_RadioButton.
TScrollBar T S c r o l l B a r o b j e c t s r e p r e s e n t s t a n d - a l o n e s c r o l l b a r c o n t r o l s . {Note: T h e s e d o n o t i n c l u d e t h e s c r o l l b a r s that a r e a t t a c h e d t o w i n d o w s . ) S c r o l l b a r s c a n b e vertical ( s c r o l l i n g u p a n d d o w n ) o r h o r i z o n t a l ( s c r o l l i n g right a n d left). M o s t o f T S c r o l l B a r ' s m e t h o d s m a n a g e t h e s c r o l l b a r ' s t h u m b position a n d range. TSc rollBa r m a i n t a i n s a set of m e t h o d s that r e s p o n d a u t o m a t i c a l l y t o t h e W i n d o w s s c r o l l b a r m e s s a g e s wm_HScroll a n d w m V S c r o l l . T h e m e t h o d s , s u c h as SBLineUp a n d SBPageDown, a r e d e f i n e d as notifybased m e t h o d s . T h e y automatically adjust the scroll bar's t h u m b position.
Fields LineMagnitude PageMagnitude
Methods Init Load DeltaPos GetClassName GetPosition GetRange
A—ObjectWindows Objects
SBBottom SBLineDown SBLineUp SBPageDown SBPageUp SBThumbPosition SBThumbTrack SBTop SetPosition SetRange SetupWindow Store Transfer
Fields TScrollBar.IineMagnitude LineMagnitude: Integer; (read/write) LineMagnitude is t h e n u m b e r o f r a n g e u n i t s t o s c r o l l t h e s c r o l l b a r w h e n t h e u s e r clicks o n a s c r o l l b a r ' s a r r o w s t o r e q u e s t a s m a l l (that is, l i n e ) m o v e m e n t . B y d e f a u l t , Init sets LineMagnitude t o 1. A l s o , b y d e f a u l t , SetupWindow sets t h e s c r o l l r a n g e f r o m 0 t o 1 0 0 .
TScrollBar.PageMagnitude PageMagnitude: Integer; (read/write) PageMagnitude is t h e n u m b e r o f r a n g e u n i t s t o s c r o l l t h e s c r o l l b a r w h e n t h e u s e r r e q u e s t s a l a r g e (that i s , p a g e ) m o v e m e n t b y c l i c k i n g i n t h e s c r o l l b a r ' s scrolling area. B y d e f a u l t , Init sets PageMagnitude t o 1 0 . ( B y d e f a u l t , t h e s c r o l l r a n g e is set t o f r o m 0 t o 1 0 0 . )
Methods TScrollBar.Init constructor Init(AParent: PWindowsObject; AnID: Integer; X,Y,W,H: Integer; IsHScrollBar: Boolean);
467
468
Part I I I — R e f e r e n c e s
C o n s t r u c t s a n d initializes a TScrollBar o b j e c t w i t h t h e f o l l o w i n g i n f o r m a t i o n : • Parent w i n d o w (AParent) • An ID as a c o n t r o l I D • A p o s i t i o n o f (X, Y) • A width of W • A height of H T h e s c r o l l b a r is h o r i z o n t a l (style sbs_Horz) if IsHScrollBar is T r u e a n d vertical (style sbs_Vert) if IsHScrollBar is F a l s e . If t h e r e q u e s t e d h e i g h t f o r a h o r i z o n t a l s c r o l l b a r o r t h e r e q u e s t e d w i d t h f o r a vertical s c r o l l b a r is 0, d e f a u l t v a l u e s are set. LineMagnitude is initialized t o 1 a n d PageMagnitude t o 1 0 .
TScrollBar.Load constructor Load(var S: TStream); C o n s t r u c t s a n d l o a d s a s c r o l l b a r c o n t r o l f r o m t h e s t r e a m , S, b y first s e n d i n g TControl. Load a m e s s a g e a n d t h e n r e a d i n g t h e a d d i t i o n a l fields (LineMagnitude a n d PageMagnitude) d e f i n e d b y TScrollBar.
TScrollBar.DeltaPos function DeltaPos(Delta: Integer): Integer; virtual; ( O v e r r i d e : s e l d o m ) C h a n g e s t h e s c r o l l bar's t h u m b p o s i t i o n b y t h e Delta v a l u e . It s e n d s SetPosition a m e s s a g e . A n e g a t i v e v a l u e m o v e s t h e t h u m b u p o r left. T h e n e w t h u m b p o s i t i o n is returned.
TScrollBar.GetClassName function GetClassName: PChar; virtual; ( O v e r r i d e : n e v e r ) R e t u r n s t h e n a m e ofTScrollBar's w i n d o w class, Scrollbar.
TScrollBar.GetPosition function GetPosition: Integer; virtual; ( O v e r r i d e : s e l d o m ) R e t u r n s t h e s c r o l l bar's c u r r e n t t h u m b p o s i t i o n .
A—ObjectWindows Objects
469
TScrollBar.GetRange procedure GetRange(var LoVal, HiVal: Integer); virtual; (Override: s e l d o m ) G e t s the allowed range o f scroll bar t h u m b positions in
LoVal a n d HiVal.
TScrollBar.SBBottom procedure SBBottom(var Msg: TMessage); virtual nf_First + sb_Bottom; ( O v e r r i d e : s e l d o m ) I n r e s p o n s e t o a u s e r r e q u e s t , SBBottom sets t h e t h u m b position to the highest allowable value. This m e t h o d receives a message in response to a scroll-based message
carrying t h e c o d e sb_Bottom. S e n d s a m e s s a g e t o SetPosition.
TScrollBar.SBIineDown procedure SBLineDown(var Msg: TMessage); virtual; nf__First + sb_LineDown; ( O v e r r i d e : s e l d o m ) M o v e s t h e t h u m b p o s i t i o n d o w n o r right byLineMagnitude. SBLineDown r e c e i v e s a m e s s a g e automatically i n r e s p o n s e t o a scrollb a s e d m e s s a g e carrying t h e c o d e sbLineDown. S e n d s SetPositiona m e s s a g e .
TScrollBar.SBLineUp procedure SBLineUp(var Msg: TMessage); virtual; nf_First + sb_Line(Jp; ( O v e r r i d e : s e l d o m ) M o v e s t h e t h u m b p o s i t i o n u p o r left b y t h e LineMagnitude. s b L i n e U p r e c e i v e s a m e s s a g e automatically i n r e s p o n s e t o a s c r o l l - b a s e d m e s s a g e carrying t h e c o d e s b L i n e U p . S e n d s a m e s s a g e t o SetPosition.
TScrollBar.SBPageDown procedure SBPageDown(var Msg: TMessage); virtual; nf_First + sb_PageDown; ( O v e r r i d e : s e l d o m ) M o v e s t h e t h u m b p o s i t i o n d o w n o r right b y Pag eMag n i t u d e. SBPageDown r e c e i v e s a m e s s a g e automatically i n r e s p o n s e t o a s c r o l l b a s e d m e s s a g e carrying t h e c o d e sb_PageDown. S e n d s a m e s s a g e t o SetPosition.
TScrollBar.SBPageUp procedure SBPageUp(var Msg: TMessage); virtual; nf_First + sb_PageUp; ( O v e r r i d e : s e l d o m ) M o v e s t h e t h u m b p o s i t i o n u p o r left byPageMagnitude. SBPageUp r e c e i v e s a m e s s a g e automatically i n r e s p o n s e t o a s c r o l l - b a s e d m e s s a g e carrying t h e c o d e sb_Pagelip. S e n d s a m e s s a g e t o SetPosition.
470
Part I I I — R e f e r e n c e s
TScrollBar.SBThumbPosition procedure SBThumbPosition(var Msg: TMessage); virtual; nf_First + sb_ThumbPosition; (Override: seldom) C h a n g e s the t h u m b position to position chosen by the user a n d p a s s e d i n a scroll-based m e s s a g e c a r r y i n g t h e c o d e sb_ThumbPosition. S e n d s SetPosition a m e s s a g e .
TScrollBar.SBThumbTrack procedure SBThumbTrack(var Msg: TMessage); virtual; nf__First + sb_ThumbTrack; ( O v e r r i d e : s o m e t i m e s ) C h a n g e s t h e t h u m b p o s i t i o n as t h e u s e r d r a g s t h e t h u m b . S e n d s a m e s s a g e t o SetPosition. SBThumbTrack r e c e i v e s a m e s s a g e i n r e s p o n s e t o a scroll-based m e s s a g e c a r r y i n g t h e c o d e sb_ThumbTrack.
TScrollBar.SBTop procedure SBTop(var Msg: TMessage); virtual; nf_First + sb_Top; ( O v e r r i d e : s e l d o m ) I n r e s p o n s e t o a u s e r r e q u e s t , SBTop sets t h e t h u m b position to the lowest allowable value. SBTop r e c e i v e s a m e s s a g e i n r e s p o n s e t o a scroll-based m e s s a g e c a r r y i n g t h e c o d e s b T o p . S e n d s a m e s s a g e t o SetPosition.
TScrollBar.SetPosition procedure SetPosition(ThumbPos: Integer); virtual; ( O v e r r i d e : s o m e t i m e s ) S e t s t h e scroll bar's t h u m b p o s i t i o n t o ThumbPos. • If ThumbPos is h i g h e r t h a n t h e a l l o w a b l e r a n g e , t h e t h u m b p o s i t i o n is set t o t h e h i g h e s t p o s s i b l v a l u e . • If ThumbPos is l o w e r t h a n t h e a l l o w a b l e r a n g e , t h e t h u m b is set t o t h e lowest possible value.
TScroIlBar.SetRange procedure SetRange(LoVal, HiVal: Integer); virtual; ( O v e r r i d e : s e l d o m ) S e t s t h e s c r o l l bar's a l l o w a b l e r a n g e o f t h u m b p o s i t i o n s f r o m LoVal t o HiVal.
A — O b j e c t W i n d o w s Objects
471
TScrollBar.SetupWindow procedure SetupWindow;
virtual;
( O v e r r i d e : s o m e t i m e s ) Initializes t h e s c r o l l b a r ' s r a n g e f r o m 0 to 1 0 0 . T o o v e r r i d e this r a n g e , s e n d a m e s s a g e toSetRange.
TScrollBar.Store procedure Store(var S: TStream); S t o r e s t h e s c r o l l b a r c o n t r o l o n t h e s t r e a m , S, b y s e n d i n g a m e s s a g e to TControl. Store a n d t h e n w r i t i n g t h e fields (LineMagnitude a n d PageMagnitude) d e f i n e d b y TScrollBar.
TScrollBar.Transfer function Transfer(DataPtr: Pointer; TransferFlag: Word): Word; virtual; ( O v e r r i d e : s o m e t i m e s ) T r a n s f e r s t h e s c r o l l b a r ' s r a n g e a n d c u r r e n t p o s i t i o n to o r f r o m t h e m e m o r y l o c a t i o n p o i n t e d to b y DataPtr. • I f Transf erFlag is tf _GetData, a transfer r e c o r d h o l d i n g t h e r a n g e a n d p o s i t i o n is t r a n s f e r r e d to t h e m e m o r y l o c a t i o n . • If Transf erFlag is tf_SetData, t h e transfer r e c o r d at t h e m e m o r y l o c a t i o n c o n t a i n s v a l u e s that a r e u s e d to set t h e r a n g e a n d p o s i t i o n o f the scroll bar. I n b o t h c a s e s , Transfer r e t u r n s t h e n u m b e r o f b y t e s i n t h e m e m o r y location. T h e transfer r e c o r d is d e f i n e d as f o l l o w s : ScrollBarTransferRec = record LowValue: Integer; HighValue: Integer; Position: Integer; end;
TScroller TScroller o b j e c t s a r e part o f t h e Scroller field o f TWindow a n d d e s c e n d a n t objects. A TScroller o b j e c t a d d s a n a u t o m a t i c w i n d o w s c r o l l i n g m e c h a n i s m t o a window. U s u a l l y , y o u c o n s t r u c t a n d m a n i p u l a t e TScroller o b j e c t s f r o m t h e m e t h o d s o f their o w n e r w i n d o w objects.
472
Part I I I — R e f e r e n c e s
Fields AutoMode AutoOrg HasHScrollBar HasVScrollBar TrackMode Window XLine XPage XPos XRange XUnit YLine YPage YPos YRange YUnit
Methods AutoScroll BeginView EndView HScroll Init IsVisibleRect Load ScrollBy ScrollTo SetPageSize SetRange SetSBarRange SetUnits Store VScroll XRangeValue (private) XScrollValue (private) YRangeValue (private) YScrollValue (private)
A—ObjectWindows Objects
Fields TScrollerAutoMode AutoMode:
Boolean;
(read/write)
A u t o M o d e is T r u e if t h e s c r o l l e r is i n a u t o - s c r o l l i n g m o d e . B y d e f a u l t , A u t o M o d e is T r u e .
TScrollerAutoOrg AutoOrg:
Boolean;
A u t o O r g controls the automatic adjustment of the origin of the display context u s e d for painting the w i n d o w . • If A u t o O r g is T r u e (the d e f a u l t ) , t h e o r i g i n o f t h e P a i n t m e t h o d ' s d i s p l a y c o n t e x t is set t o t h e o r i g i n o f t h e s c r o l l e r . • If F a l s e , t h e d i s p l a y c o n t e x t ' s o r i g i n is (0,0) a n d P a i n t m u s t r e a d t h e s c r o l l b a r offsets t o d e t e r m i n e h o w t o p o s i t i o n o b j e c t s o n t h e d i s p l a y context.
TScfoller.HasHScrollBar HasHScrollBar:
Boolean;
(read/Write)
If t h e o w n e r w i n d o w h a s a h o r i z o n t a l w i n d o w s c r o l l b a r , H a s H S c r o l l B a r is True.
TScroller.HasVScrollBar HasVScrollBar:
Boolean;
(read/write)
If t h e o w n e r w i n d o w h a s a vertical w i n d o w s c r o l l b a r , H a s V S c r o l l B a r i s F a l s e .
TScroller.ThckMode TrackMode:
Boolean;
(read/write)
T r a c k M o d e is T r u e if t h e s c r o l l e r a u t o m a t i c a l l y tracks scroll-bar t h u m b m o v e ments by scrolling the w i n d o w . B y d e f a u l t , T r a c k M o d e is T r u e .
473
474
Part I I I — R e f e r e n c e s
TScroller.Window Window: PWindow; ( r e a d o n l y ) W i n d o w p o i n t s t o t h e TScroller's o w n e r w i n d o w .
TScroller.XLine XLine: Integer; (readAvrite) XLine is t h e n u m b e r o f XUnit u n i t s t o s c r o l l h o r i z o n t a l l y i n r e s p o n s e t o a c l i c k o n the scroll bar arrow. T h e d e f a u l t is 1.
TScroller.XPage XPage: Integer; (read/write) XPage is t h e n u m b e r o f XUnit u n i t s t o s c r o l l h o r i z o n t a l l y i n r e s p o n s e t o a c l i c k o n t h e s c r o l l bar's t h u m b a r e a . B y d e f a u l t , XPage is e q u a l t o t h e c u r r e n t w i d t h o f t h e w i n d o w i n XUnit u n i t s . R e s i z i n g t h e w i n d o w u p d a t e s this v a l u e .
TScroller.XPos XPos: Longint; ( r e a d o n l y ) XPos is t h e scroller's c u r r e n t h o r i z o n t a l p o s i t i o n i n t e r m s o f XUnit u n i t s .
TScroUer.XRange XRange: Longint; (read o n l y ) XRange is t h e t o t a l n u m b e r o f h o r i z o n t a l XUnit u n i t s y o u c a n s c r o l l a w i n d o w . A l t h o u g h y o u specify XRange v a l u e s i n t h e Init c o n s t r u c t o r , y o u c a n m o d i f y t h e m later.
TScroller.XUnit XUnit: Integer; ( r e a d o n l y ) XUnit is t h e s m a l l e s t n u m b e r o f d e v i c e u n i t s (pixels) that t h e w i n d o w c a n b e scrolled horizontally. A l t h o u g h y o u specify XUnit v a l u e s i n t h e Init c o n s t r u c t o r , y o u c a n m o d i f y t h e m later.
A — O b j e c t W i n d o w s Objects
TScrollef.YIine YLine: Integer; (read/write) YLine is t h e n u m b e r o f YUnit u n i t s t o s c r o l l vertically i n r e s p o n s e t o a c l i c k o n the scroll bar arrow. T h e d e f a u l t is 1.
TScroller.YPage YPage: Integer; (read/write) YPage is t h e n u m b e r o f YUnit u n i t s t o s c r o l l vertically i n r e s p o n s e t o a c l i c k o n the scroll bar's t h u m b area. B y d e f a u l t , YPage is e q u a l t o t h e c u r r e n t h e i g h t o f t h e w i n d o w i n YUnit u n i t s . R e s i z i n g t h e w i n d o w u p d a t e s this v a l u e .
TScroller.YPos YPos: Longint; ( r e a d o n l y ) Y P o s is t h e s c r o l l e r ' s c u r r e n t vertical p o s i t i o n i n t e r m s o f Y U n i t u n i t s .
TScroller.YRange YRange: Longint; ( r e a d o n l y ) YRange is t h e total n u m b e r o f vertical YUnit u n i t s t h e w i n d o w c a n b e s c r o l l e d . A l t h o u g h y o u specify YRange v a l u e s i n t h e Init c o n s t r u c t o r , y o u c a n m o d i f y t h e m later.
TScroller.YUnit YUnit: Integer; ( r e a d o n l y ) YUnit is t h e s m a l l e s t n u m b e r o f d e v i c e u n i t s (pixels) that t h e w i n d o w c a n b e vertically s c r o l l e d . A l t h o u g h y o u specify YUnit v a l u e s i n t h e Init c o n s t r u c t o r , y o u c a n m o d i f y t h e m later.
475
476
Part I I I — R e f e r e n c e s
Methods TScroller.Init constructor Init(TheWindow: PWindow; TheXUnit, TheYUnit: Integer; TheXRange, TheYRange: Longint); C o n s t r u c t s a n e w TScroller o b j e c t w i t h TheWindow as t h e o w n e r w i n d o w ,
a n d TheXUnit, TheYUnit, TheXRange, a n d TheYRange fields u s i n g XUnit,
YUnit, XRange a n d YRange. Sets AutoMode a n d TrackMode t o T r u e a n d sets HasHScrollBar a n d HasVSc rollBa r, d e p e n d i n g o n t h e scroll b a r a t t r i b u t e s o f t h e o w n e r w i n d o w .
TScrollerload constructor Load(var S: TStream); C o n s t r u c t s a n d l o a d s a s c r o l l e r f r o m t h e s t r e a m , S, b y s e n d i n g a m e s s a g e t o TOb j ect. Init a n d t h e n r e a d i n g t h e TScroller f i e l d s , w i t h t h e e x c e p t i o n o f
XPage, YPage, XPos, a n d YPos.
TScroUerAutoScroll procedure AutoScroll; virtual; (Override: sometimes) D e p e n d i n g o n the position o f the m o u s e performs auto-scrolling.
cursor,
TScroller.BeginView procedure BeginView(PaintDC: HDC; var Paintlnfo: TPaintStruct); virtual; (Override: sometimes) Sets the origin o f the o w n e r w i n d o w ' s paint display c o n t e x t (PaintDC) a c c o r d i n g t o t h e c u r r e n t s c r o l l e r p o s i t i o n .
TScroller.EndView procedure EndView; virtual; ( O v e r r i d e : s o m e t i m e s ) U p d a t e s t h e p o s i t i o n o f t h e o w n e r w i n d o w ' s scroll b a r s s y n c h r o n i z i n g t h e m w i t h t h e p o s i t i o n o f t h e TScroller.
A—ObjectWindows Objects
477
TScroller.HScroll procedure HScroll(ScrollRequest: Word; ThumbPos: Integer); virtual; (Override: never) R e s p o n d s t o horizontal scroll bar events b y c h a n g i n g the position o f the scroller a n d t h e horizontal scroll bar.
TScrollerisVisibleRect function IsVisibleRect(X, Y: Longint; XExt, YExt: Integer): Boolean; virtual; ( O v e r r i d e : s e l d o m ) R e t u r n s T r u e if a n y part o f t h e r e c t a n g l e s p e c i f i e d b y t h e p a s s e d a r g u m e n t s is c u r r e n t l y v i s i b l e i n t h e o w n e r w i n d o w .
TScroller.ScrollBy procedure ScrollBy(Dx, Dy: Longint); virtual; ( O v e r r i d e : s e l d o m ) S c r o l l s b y t h e a m o u n t s s p e c i f i e d b y Dx a n d Dy. A l s o u p d a t e s the w i n d o w ' s display.
TScroller.ScrollTo procedure ScrollTo(X, Y: Longint); virtual; ( O v e r r i d e : s o m e t i m e s ) S c r o l l s t o t h e p o s i t i o n s p e c i f i e d b y X a n d Y. A l s o u p d a t e s the w i n d o w ' s display.
TScroller.SetPageSize procedure SetPageSize; virtual; ( O v e r r i d e : s o m e t i m e s ) S e t s t h e XPage a n d YPage fields t o b e t h e o w n e r window's current width a n d height.
TScroller.SetRange procedure SetRange(TheXRange, TheYRange: Longint); virtual; ( O v e r r i d e : n e v e r ) O v e r r i d e s t h e XRange a n d YRange v a l u e s s e n t i n t h e m e s s a g e t o Init b y s e t t i n g t h e m t o TheXRange a n d TheYRange. SetRange t h e n s e n d s a m e s s a g e t o SetSBarRange t o set t h e r a n g e of t h e o w n e r w i n d o w ' s scroll bars.
478
Part I I I — R e f e r e n c e s
TScroller.SetSBarRange procedure SetSBarRange; virtual; (Override: never) Sets t h e range o f the o w n e r w i n d o w ' s scroll bars b y putting t h e m i n s y n c w i t h t h e r a n g e o f t h e TScroller.
TScroller.SetUnits procedure SetUnits(TheXUnit, TheYUnit: Longint);virtual; Sets t h e XUnit a n d YUnit fields t o TheXUnit a n d TheYUnit.
TScroller.Store procedure Store(var S: TStream); S t o r e s t h e s c r o l l e r o n t h e s t r e a m S b y w r i t i n g t h e TScroller fields, w i t h t h e
e x c e p t i o n o f XPage, YPage, XPos a n d YPos.
TScroller.VScroll procedure VScroll(ScrollRequest: Word; ThumbPos: Integer); virtual; ( O v e r r i d e : n e v e r ) R e s p o n d s t o vertical s c r o l l b a r e v e n t s b y c h a n g i n g t h e p o s i t i o n o f t h e s c r o l l e r a n d t h e vertical s c r o l l b a r .
TScroller.XRangeValue Function XRangeValue (AScrollUnit : Integer) : Longint; Private m e t h o d ; u s e d i n t e r n a l l y b y TScroller O b j e c t .
TScroller.XScrollValue function XScrollValue(ARangeUnit
: LongUnit) : Integer;
Private m e t h o d ; u s e d i n t e r n a l l y b y TScroller
Object.
TScroller.YRangeValue function YRangeValue(AScrollUnit
: Integer): Longint;
Private m e t h o d ; u s e d i n t e r n a l l y b y TScroller O b j e c t .
A—ObjectWindows Objects
TScroller.YScrollValue function YScrollValue(ARangeUnit
: Longint): Integer;
Private m e t h o d ; u s e d i n t e r n a l l y b y TScroller O b j e c t .
TSortedCollection TSortedCollection is a d e s c e n d a n t o f TCollection f o r i m p l e m e n t i n g collections sorted by key without duplicates. S o r t i n g is i m p l i e d b y a virtual TSortedCollection. Compare m e t h o d that y o u override in order to define your o w n element-ordering behavior. N e w i t e m s a r e i n s e r t e d a u t o m a t i c a l l y i n t h e o r d e r d e f i n e d b y t h e Compare method. Y o u c a n locate Items using the binary search method, TSortedCollection.Search. Y o u c a n a l s o o v e r r i d e t h e virtual KeyOf m e t h o d that r e t u r n s a p o i n t e r f o r Compare if Compare n e e d s a d d i t i o n a l i n f o r m a t i o n .
Fields Duplicates
Methods Init Load Compare IndexOf Insert KeyOf Search Store
Fields TSortedCollection.Duplicates Duplicates: Boolean; T h e Duplicates field d e t e r m i n e s w h e t h e r i t e m s w i t h d u p l i c a t e s k e y s a r e accepted by the stream.
479
480
Part I I I — R e f e r e n c e s
• I f Duplicates is T r u e , d u p l i c a t e - k e y e n t r i e s a r e i n s e r t e d i n t o t h e collection. • I f Duplicates is F a l s e , a n e w d u p l i c a t e - k e y i t e m r e p l a c e s t h e e x i s t i n g i t e m w i t h that k e y . T h e d e f a u l t v a l u e is false.
Methods TSortedCollection.Init constructor Init(ALimit, ADelta: Integer); C o n s t r u c t s t h e TSortedCollection b a s e d o n ALimit a n d ADelta.
TSortedCollection.Load constructor Load(var S: TStream); C o n s t r u c t s a n d l o a d s a s o r t e d c o l l e c t i o n f r o m t h e s t r e a m , S, b y first s e n d i n g a m e s s a g e t o TCollection. Load. It t h e n r e a d s t h e Duplicates f i e l d .
TSortedCollection.Compare function Compare(Key1, Key2: Pointer): Integer; virtual; ( O v e r r i d e : always) Compare is a n abstract m e t h o d that y o u m u s t o v e r r i d e i n all descendant types. Compare s h o u l d c o m p a r e t h e t w o k e y v a l u e s a n d r e t u r n o n e o f t h e following results: -1 if Key 1 < Key2 Oif Key1 = Key2 1 if Key1 > Key2 Key1 a n d Key2 a r e p o i n t e r v a l u e s , e x t r a c t e d f r o m t h e i r c o r r e s p o n d i n g c o l l e c t i o n i t e m s b y t h e KeyOf m e t h o d . T h e Search m e t h o d i m p l e m e n t s a b i n a r y s e a r c h t h r o u g h t h e c o l l e c t i o n ' s i t e m s u s i n g Compare t o c o m p a r e t h e items.
A — O b j e c t W i n d o w s Objects
481
TSortedCollection.IndexOf function IndexOf(Item: Pointer): Integer; virtual; ( O v e r r i d e : n e v e r ) IndexOf u s e s TSortedCollection.Search t o find t h e i n d e x of Item. I f Item isn't i n t h e c o l l e c t i o n , IndexOf r e t u r n s - 1 . F o r e x a m p l e :
if Search(KeyOf(Item), I) then IndexOf := I else IndexOf := -1;
TSortedCollection.Insert procedure Insert(Item: Pointer); virtual; ( O v e r r i d e : n e v e r ) I f t h e target i t e m isn't f o u n d i n t h e s o r t e d c o l l e c t i o n , it's i n s e r t e d at t h e c o r r e c t i n d e x p o s i t i o n . Insert s e n d s a m e s s a g e t o Search t o d e t e r m i n e w h e t h e r t h e i t e m e x i s t s , a n d if n o t , w h e r e t o insert it. F o r e x a m p l e :
if not Search(KeyOf(Item), I) then AtInsert(I, Item);
TSortedCollection.KeyOf function KeyOf(Item: Pointer): Pointer; virtual; ( O v e r r i d e : s o m e t i m e s ) I f it g e t s a n Item f r o m t h e c o l l e c t i o n , KeyOf s h o u l d r e t u r n t h e c o r r e s p o n d i n g k e y of t h e i t e m . T h e d e f a u l t KeyOf r e t u r n s Item. O v e r r i d e KeyOf w h e n t h e k e y of t h e i t e m isn't t h e i t e m itself.
TSortedCollection.Search function Search(Key: Pointer; var Index: Integer): Boolean; virtual; ( O v e r r i d e : s e l d o m ) R e t u r n s T r u e if Item ( i d e n t i f i e d b y Key) is f o u n d i n t h e sorted collection.
If Search finds Item, Index is set t o t h e f o u n d i n d e x ; o t h e r w i s e , Index is set t o t h e i n d e x w h e r e t h e i t e m w o u l d b e p l a c e d if i n s e r t e d .
TSortedCollection.Store procedure Store(var S: TStream); S t o r e s t h e s o r t e d c o l l e c t i o n a n d all its i t e m s o n t h e s t r e a m , S, b y s e n d i n g TCollection.Store a m e s s a g e t o w r i t e t h e c o l l e c t i o n . It t h e n w r i t e s t h e Duplicates field t o t h e s t r e a m .
482
Part I I I — R e f e r e n c e s
TStatic T S t a t i c is a n i n t e r f a c e o b j e c t that c o r r e s p o n d s t o a static c o n t r o l e l e m e n t i n W i n d o w s . Usually, y o u don't use T S t a t i c objects in dialog b o x e s ( T D i a l o g ) o r dialog w i n d o w s (TDlgWindow). Instead, y o u u s e t h e m to display a stand-alone static c o n t r o l as a c h i l d w i n d o w i n a n o t h e r w i n d o w ' s c l i e n t a r e a .
Fields TextLen
Methods Init InitResorce Load Clear GetClassName GetText SetText Store Transfer
Fields TStaticTextLen TextLen: Word; TextLen h o l d s t h e size o f t h e text b u f f e r f o r static c o n t r o l s . B e c a u s e o f t h e n u l l t e r m i n a t o r at t h e e n d o f t h e string, t h e n u m b e r o f c h a r a c t e r s that c a n b e s t o r e d i n t h e static c o n t r o l is o n e less t h a n TextLen. TextLen is a l s o t h e n u m b e r o f b y t e s t r a n s f e r r e d b y t h e Transf er m e t h o d .
Methods TStaticInit constructor Init(AParent: PWindowsObject; AnID: Integer; ATitle: PChar; X,Y,W,H: Integer);
A — O b j e c t W i n d o w s Objects
( O v e r r i d e : s e l d o m ) C o n s t r u c t s a static c o n t r o l o b j e c t w i t h t h e f o l l o w i n g information: • P a r e n t w i n d o w (AParent) • C o n t r o l ID (AnID) • T e x t (ATitle) • P o s i t i o n (X, Y) relative t o t h e o r i g i n o f t h e p a r e n t w i n d o w ' s c l i e n t a r e a • W i d t h (W) • H e i g h t (H) • T e x t l e n g t h (ATextLen) T h e static c o n t r o l is left-justified b e c a u s e Init a d d s t h e W i n d o w s style ss_Lef t t o t h e o b j e c t ' s Attr. Style field. Init a l s o r e m o v e s t h e wsJTabStop style. Init t h e n s e n d s a m e s s a g e t o DisableTransf er t o e x c l u d e TStatic o b j e c t s f r o m t h e transfer m e c h a n i s m .
TStaticInitResource constructor InitResource(AParent: PWindowsObject; ATextLen: Word);
ResourcelD,
A s s o c i a t e s a TStatic o b j e c t w i t h t h e static c o n t r o l r e s o u r c e s p e c i f i e d b y ResourcelD a n d sets t h e TextLen field t o ATextLen. S e n d s a m e s s a g e t o TControl. InitResource t o c o n s t r u c t a n d a s s o c i a t e t h e o b j e c t w i t h its static c o n t r o l r e s o u r c e .
TStatic.Load constructor Load(var S: TStream); C o n s t r u c t s a n d l o a d s a static c o n t r o l f r o m t h e s t r e a m , S, b y s e n d i n g a m e s s a g e t o TControl. Load a n d t h e n r e a d i n g t h e TextLen
TStaticClear procedure Clear; virtual; ( O v e r r i d e : s e l d o m ) C l e a r s t h e static c o n t r o l ' s text.
field.
483
484
Part I I I — R e f e r e n c e s
TStaticGetText function GetText(ATextString: PChar; MaxChars: Integer): Integer; virtual; ( O v e r r i d e : s e l d o m ) G e t s t h e static c o n t r o l ' s text a n d stores it i n ATextString. MaxChars s p e c i f i e s t h e m a x i m u m size o f ATextString. GetText r e t u r n s t h e size o f t h e r e t r i e v e d string.
TStaticSetText procedure SetText(ATextString: PChar); virtual; ( O v e r r i d e : s e l d o m ) Sets t h e static c o n t r o l ' s text t o t h e string p a s s e d i n
ATextString.
TStaticStore procedure Store(var S: TStream); Stores t h e static c o n t r o l o n t h e s t r e a m , S, b y s e n d i n g a m e s s a g e t o TCont rol. St o re a n d t h e n w r i t i n g t h e TextLen f i e l d .
TStaticTransfer function Transfer(DataPtr: Pointer; TransferFlag: Word): Word; virtual; ( O v e r r i d e : s o m e t i m e s ) T r a n s f e r s TextLen c h a r a c t e r s o f t h e c u r r e n t text o f t h e static c o n t r o l t o o r f r o m t h e m e m o r y l o c a t i o n p o i n t e r t o b y D a t a P t r .
• If Transf erFlag is tf_GetData, t h e text is transferred t o t h e m e m o r y location.
• I f Transf erFlag is tf_SetData, t h e static c o n t r o l ' s text is set t o t h e text at t h e m e m o r y l o c a t i o n . Transfer r e t u r n s TextLen ( t h e n u m b e r o f bytes stored in o r retrieved f r o m the m e m o r y location).
• I f Transf erFlag is tf_SizeData, Transfer r e t u r n s t h e size o f t h e transfer d a t a .
TStrCoUection TStrCollection is a d e s c e n d a n t o f TSortedCollection f o r i m p l e m e n t i n g a s o r t e d list o f A S C I I s t r i n g s .
A—ObjectWindows Objects
O v e r r i d e t h e Compare m e t h o d t o p r o v i d e c o n v e n t i o n a l l e x i c o g r a p h i c A S C I I string o r d e r i n g . Y o u c a n o v e r r i d e Compare t o a l l o w f o r o t h e r o r d e r i n g s , s u c h as those for n o n - E n g l i s h character sets.
Fields None.
Methods Compare Freeltem Getltem Putltem
Methods TStrCollection.Compare function Compare(Key1, Key2: Pointer): Integer; virtual; ( O v e r r i d e : s o m e t i m e s ) C o m p a r e s t h e strings Key1" a n d Key2" as f o l l o w s : Return Return Return
-1 if Key 1 < Key2 0 if Key 1 = Key2 + lifKey1 > Key2
TStrCollection.FreeItem procedure Freeltem(ltem: Pointer); virtual; ( O v e r r i d e : s e l d o m ) R e m o v e s t h e string I t e n T f r o m t h e s o r t e d c o l l e c t i o n a n d d i s p o s e s o f t h e string.
TStrCollection.GetItem function Getltem(var S: TStream): Pointer; virtual; ( O v e r r i d e : s e l d o m ) B y d e f a u l t , r e a d s a string from t h e TStream b y s e n d i n g S.ReadStr a m e s s a g e .
485
486
Part I I I — R e f e r e n c e s
TStrCollection.PutItem procedure Putltem(var S: TStream; Item: Pointer); virtual; ( O v e r r i d e : s e l d o m ) B y d e f a u l t , w r i t e s t h e string Item" o n t o t h e TStream b y s e n d i n g S. WriteStr a m e s s a g e .
TStream TStream is a n abstract o b j e c t that h a n d l e s p o l y m o r p h i c I/O t o a n d f r o m a storage device. T o c r e a t e y o u r o w n d e r i v e d s t r e a m o b j e c t s , o v e r r i d e t h e virtual m e t h o d s :
GetPos, GetSize, Read, Seek, Truncate, a n d Write. For example, ObjectWindows
overrides these m e t h o d s to derive
TDosStream a n d TEmsStream. F o r b u f f e r e d d e r i v e d s t r e a m s , y o u m u s t a l s o o v e r r i d e Flush.
Fields Errorlnfo Status
Methods CopyFrom Error Flush Get GetPos GetSize Init Put Read ReadStr Reset Seek StrRead StrWrite Truncate Write WriteStr
A — O b j e c t W i n d o w s Objects
Fields TStream.EfforInfo Errorlnfo: Integer; (read/write) Errorlnf o c o n t a i n s a d d i t i o n a l i n f o r m a t i o n w h e n Status isn't stOk: Status
Error
Values
stError stlnitError stReadError stWriteError stGetError stPutError
Information
D O S o r E M S e r r o r c o d e ; if available D O S o r E M S e r r o r c o d e ; if available D O S o r E M S e r r o r c o d e ; if available D O S o r E M S e r r o r c o d e ; if a v a i l a b l e object type I D o f unregistered object type V M T d a t a s e g m e n t offset o f u n r e g i s t e r e d object type
TStream.Status Status: Integer; (read/write) I n d i c a t e s t h e c u r r e n t status o f t h e s t r e a m u s i n g t h e f o l l o w i n g e r r o r c o d e s : TStream
error
codes:
stOk
N o error
stError stlnitError stReadError
Access error C a n n o t initialize s t r e a m Read b e y o n d e n d o f stream
stWriteError stGetError stPutError
C a n n o t e x p a n d stream G e t o f unregistered object type Put o f unregistered object type
If Status isn't stOk, all o p e r a t i o n s o n t h e s t r e a m a r e s u s p e n d e d u n t i l Reset is s e n t a m e s s a g e .
Methods TStream.CopyFrom procedure CopyFrom(var S: TStream; Count: Longint); C o p y Count bytes from s t r e a m , S, t o t h e c a l l i n g s t r e a m o b j e c t . F o r e x a m p l e :
487
488
Part I I I — R e f e r e n c e s
{Create a copy of entire stream} ANewStream := New(TEmsStream, Init(AnOldStreanT .GetSize)); AnOldStreanT .Seek(0); ANewStream".CopyFrom(An01dStream, AnOldStreanT .GetSize);
TStfeam.Error procedure Error(Code, Info: Integer); virtual; (Override: sometimes) Receives a message w h e n e v e r a stream error occurs. T h e d e f a u l t Error s t o r e s Code a n d Info i n t h e Status a n d Errorlnf o f i e l d s . T h e n , if t h e g l o b a l v a r i a b l e St reamE r r o r isn't n i l , it s e n d s a m e s s a g e t o t h e p r o c e d u r e p o i n t e d t o b y StreamError. A f t e r a n e r r o r h a s o c c u r r e d , all s t r e a m o p e r a t i o n s o n t h e s t r e a m a r e s u s p e n d e d u n t i l a m e s s a g e is s e n t t o Reset.
TStream.Fhish procedure Flush; virtual; ( O v e r r i d e : s o m e t i m e s ) A n abstract m e t h o d y o u m u s t o v e r r i d e if y o u r d e s c e n d a n t i m p l e m e n t s a b u f f e r . T h i s m e t h o d c a n flush a n y b u f f e r s b y c l e a r i n g t h e r e a d buffer, by writing the write buffer, o r b o t h . T h e d e f a u l t Flush d o e s n ' t d o a n y t h i n g .
TStream.Get function Get: PObject; Reads an object from the stream. T h e object must have b e e n written previously t o t h e s t r e a m b y Put. • Get first r e a d s a n o b j e c t t y p e I D (a word) f r o m t h e s t r e a m . • T h e n it finds t h e c o r r e s p o n d i n g o b j e c t t y p e b y c o m p a r i n g t h e I D t o t h e Ob j Type field of all r e g i s t e r e d o b j e c t t y p e s . • Finally, it s e n d s t h e Load c o n s t r u c t o r of that o b j e c t t y p e a m e s s a g e t o create a n d load the object. If t h e o b j e c t t y p e I D r e a d f r o m t h e s t r e a m is 0, Get r e t u r n s a n i l p o i n t e r . If t h e o b j e c t t y p e I D h a s n ' t b e e n r e g i s t e r e d ( u s i n g RegisterType), Get s e n d s a m e s s a g e t o Error a n d r e t u r n s a n i l p o i n t e r . O t h e r w i s e , Get r e t u r n s a p o i n t e r to the newly created object.
A — O b j e c t W i n d o w s Objects
TStream.GetPos function GetPos: Longint; virtual; ( O v e r r i d e : always) R e t u r n s t h e v a l u e o f t h e c a l l i n g s t r e a m ' s c u r r e n t p o s i t i o n . Y o u m u s t o v e r r i d e this abstract m e t h o d .
TStream.GetSize function GetSize: Longint; virtual; ( O v e r r i d e : always) R e t u r n s t h e total size o f t h e c a l l i n g s t r e a m . Y o u m u s t o v e r r i d e this abstract m e t h o d .
TStream.Init constructor Init; C r e a t e s a TStream.
TStream.Put procedure Put(P: PObject); W r i t e s a n o b j e c t t o t h e s t r e a m . Y o u c a n later r e a d t h e o b j e c t f r o m t h e s t r e a m u s i n g Get. • First Put finds t h e t y p e - r e g i s t r a t i o n r e c o r d o f t h e o b j e c t b y c o m p a r i n g t h e o b j e c t ' s V M T offset t o t h e VmtLink field o f all r e g i s t e r e d o b j e c t t y p e s ( s e e t h e TStreamRec t y p e ) . • T h e n it w r i t e s t h e o b j e c t t y p e I D ( t h e Ob j Type field o f t h e r e g i s t r a t i o n record) to the stream. • F i n a l l y it s e n d s a m e s s a g e t o t h e Store m e t h o d o f that o b j e c t t y p e i n order t o write the object. If t h e P a r g u m e n t s e n t t o Put is n i l , Put w r i t e s a w o r d c o n t a i n i n g 0 t o t h e s t r e a m . If t h e o b j e c t t y p e o f P h a s n ' t b e e n r e g i s t e r e d ( u s i n g R e g i s t e r T y p e ) , Put s e n d s a m e s s a g e t o Error a n d d o e s n ' t w r i t e a n y t h i n g t o t h e s t r e a m .
TStream.Read procedure Read(var Buf; Count: Word); virtual; ( O v e r r i d e : always) Y o u m u s t o v e r r i d e this abstract m e t h o d i n all d e s c e n d a n t types.
489
490
Part I I I — R e f e r e n c e s
Read s h o u l d r e a d Count b y t e s f r o m t h e s t r e a m i n t o Buf a n d a d v a n c e t h e c u r r e n t p o s i t i o n o f t h e s t r e a m b y Count b y t e s . If a n e r r o r o c c u r s , Read s h o u l d s e n d Error a m e s s a g e , a n d fill Buf w i t h Count b y t e s o f 0.
TStream.ReadStr function ReadStr: PString; R e a d s a string f r o m t h e c u r r e n t p o s i t i o n o f t h e c a l l i n g s t r e a m , r e t u r n i n g a PString p o i n t e r . ReadStr s e n d s a m e s s a g e t o GetMem t o a l l o c a t e (Length+1) b y t e s f o r t h e string.
TStream.Reset procedure Reset; R e s e t s a n y s t r e a m e r r o r c o n d i t i o n b y s e t t i n g Status a n d Errorlnf o t o 0. T h i s m e t h o d lets y o u c o n t i n u e s t r e a m p r o c e s s i n g f o l l o w i n g a n e r r o r c o n d i t i o n that you've corrected.
TStream.Seek procedure Seek(Pos: Longint); virtual; ( O v e r r i d e : always) Y o u m u s t o v e r r i d e this abstract m e t h o d i n all d e s c e n d a n t s . Seek sets t h e c u r r e n t p o s i t i o n t o Pos b y t e s f r o m t h e start o f t h e c a l l i n g s t r e a m . T h e b e g i n n i n g o f a s t r e a m is p o s i t i o n 0.
TStream.StrRead function StrRead: PChar; R e a d s a n u l l - t e r m i n a t e d string f r o m t h e s t r e a m b y first r e a d i n g t h e l e n g t h o f t h e string a n d t h e n r e a d i n g that n u m b e r o f c h a r a c t e r s . R e t u r n s a p o i n t e r t o t h e n u l l t e r m i n a t e d string r e a d .
TStream.StfWrite function StrWrite(P: PChar); W r i t e s t h e n u l l - t e r m i n a t e d string, P, t o t h e s t r e a m b y first w r i t i n g t h e l e n g t h o f t h e string a n d t h e n w r i t i n g t h e n u m b e r o f c h a r a c t e r s .
A — O b j e c t W i n d o w s Objects
TStream.Thincate procedure Truncate; virtual; ( O v e r r i d e : always) Y o u m u s t o v e r r i d e this abstract m e t h o d i n all d e s c e n d a n t s . Truncate d e l e t e s all d a t a o n t h e c a l l i n g s t r e a m f r o m t h e c u r r e n t p o s i t i o n to the e n d .
TStream.Write procedure Write(var Buf; Count: Word); virtual; ( O v e r r i d e : always) Y o u m u s t o v e r r i d e this abstract m e t h o d i n all d e s c e n d a n t types. W r i t e s h o u l d w r i t e Count b y t e s f r o m Buf o n t o t h e s t r e a m a n d a d v a n c e t h e c u r r e n t p o s i t i o n o f t h e s t r e a m b y Count b y t e s . If a n e r r o r o c c u r s , Write s h o u l d s e n d Error a m e s s a g e .
TStream.WriteStr procedure WriteStr(P: PString); W r i t e s t h e string P" t o t h e c a l l i n g s t r e a m , b e g i n n i n g at t h e c u r r e n t p o s i t i o n .
TWindow TWindow d e f i n e s f u n d a m e n t a l b e h a v i o r f o r all w i n d o w a n d c o n t r o l o b j e c t s . O b j e c t i n s t a n c e s o f TWindow a r e e m p t y g e n e r i c w i n d o w s , w h i c h c a n define m e n u s , cursors, a n d icons.
Fields Attr DefaultProc FocusChildHandle Scroller
491
492
Part I I I — R e f e r e n c e s
Methods Init InitResource Load Done Create DefWndProc GetID GetWindowClass Paint SetCaption SetupWindow Store WMActivate WMCreate WMHScroll WMLButtonDown WMMove WMPaint WMSize WMVScroll
Fields TWindow Attr Attn
TWindowAttr;
Attr h o l d s a TWindowAttr r e c o r d , w h i c h d e f i n e s a w i n d o w ' s attributes. T h e s e attributes i n c l u d e :
creation
• T h e w i n d o w ' s a s s o c i a t e d text, style, e x t e n d e d style, p o s i t i o n , a n d size • The window handle • T h e control I D T h e s e attributes t r a d i t i o n a l l y a r e set t o d e f a u l t s i n t h e o b j e c t ' s Init c o n s t r u c t o r , b u t c a n b e o v e r r i d d e n i n a d e s c e n d a n t t y p e ' s Init c o n s t r u c t o r . H e r e ' s t h e r e c o r d d e f i n i t i o n f o r TWindowAttr:
A—ObjectWindows Objects
TWindowAttr = record Title: PChar; Style: Longint; ExStyle: Longint; X, Y, W, H: Integer; Param: Pointer; case Integer of 0: (Menu: HMenu); { window menu's handle or... } 1: (Id: Integer); { control's child identifier } end;
TWindow.DefaultProc DefaultProc: TFarProc; ( r e a d o n l y ) Def aultProc h o l d s t h e a d d r e s s o f t h e d e f a u l t w i n d o w p r o c e d u r e , w h i c h defines the W i n d o w s default processing for W i n d o w s messages.
TWindow.FocusChildHandle FocusChildHandle: THandle; ( r e a d o n l y ) FocusChildHandle s t o r e s t h e W i n d o w s h a n d l e t o t h e w i n d o w ' s c h i l d w i n d o w that h a d t h e f o c u s t h e last t i m e t h e w i n d o w w a s a c t i v a t e d .
TWindow.Scroller Scroller: PScroller; (read/write) Scroller h o l d s a p o i n t e r t o a TScroller o b j e c t , w h i c h is t h e w i n d o w ' s scroller, if it h a s a s c r o l l e r . Y o u s h o u l d c o n s t r u c t a scroller i n t h e w i n d o w ' s Init constructor.
Methods TWindow.Init constructor Init(AParent: PWindowsObject; ATitle: PChar); (Override: often) Constructs a w i n d o w object with the parent w i n d o w sent in AParent a n d t h e a s s o c i a t e d text ( c a p t i o n f o r w i n d o w s ) s e n t i n ATitle. AParent s h o u l d b e n i l f o r m a i n w i n d o w s b e c a u s e t h e y h a v e n o p a r e n t .
493
494
Part I I I — R e f e r e n c e s
T h e object's Attr.Style field is set to ws_OverlappedWindow u n l e s s t h e w i n d o w is a n MDI c h i l d w i n d o w , w h e n t h e Attr.Style field is set to ws_ClipSiblings. T h e p o s i t i o n a n d e x t e n t fields i n t h e Attr r e c o r d a r e set to d e f a u l t s s u i t a b l e f o r o v e r l a p p e d a n d p o p - u p w i n d o w s . Y o u c a n o v e r r i d e Init i n y o u r d e s c e n d a n t t y p e s as l o n g as y o u first e x p l i c i t l y s e n t Init a m e s s a g e . T h e n y o u c a n reset t h e Attr f i e l d s . B y d e f a u l t , Scroller is set to n i l .
T\Wndow.InitResource constructor InitResource(AParent: PWindowsObject; ResourcelD: Word); C o n s t r u c t s a n O b j e c t W i n d o w s o b j e c t that is a s s o c i a t e d w i t h a n i n t e r f a c e e l e m e n t (usually a c o n t r o l ) c r e a t e d by a r e s o u r c e d e f i n i t i o n . S e n d s a m e s s a g e to TWindowsOb j ect. Init.
TWindowIoad constructor Load(var S: TStream); C o n s t r u c t s a n d l o a d s a w i n d o w f r o m t h e s t r e a m , S, by first s e n d i n g TWindowsOb j ect. Load a m e s s a g e . T h e n it r e a d s a n d g e t s t h e a d d i t i o n a l fields (Attr a n d Scroller) c r e a t e d b y TWindow.
TWindow.Done destructor Done; virtual; ( O v e r r i d e : o f t e n ) D i s p o s e s o f t h e TScroller object i n Scroller, if a n y , b e f o r e s e n d i n g a m e s s a g e to TWindowsOb j ect. Done to d i s p o s e o f t h e object.
TWindow.Create function Create: Boolean; virtual; Creates the w i n d o w object's c o r r e s p o n d i n g interface e l e m e n t unless the object w a s c o n s t r u c t e d w i t h InitResource. I f t h e o b j e c t w a s c r e a t e d w i t h InitResource, t h e i n t e r f a c e e l e m e n t a l r e a d y e x i s t s . Create first s e n d s a m e s s a g e to Register to r e g i s t e r t h e w i n d o w class if it's n o t a l r e a d y r e g i s t e r e d .
A—ObjectWindows Objects
495
C r e a t e t h e n creates the w i n d o w a n d sends a message to SetupWindow, w h i c h y o u c a n d e f i n e t o initialize t h e n e w l y c r e a t e d w i n d o w . If s u c c e s s f u l , C r e a t e r e t u r n s T r u e . If u n s u c c e s s f u l , it r e t u r n s F a l s e a n d calls E r r o r .
TWindow.DelWndProc procedure
DefWndProc(var
Msg:
TMessage);
virtual;
(Override: never) Sends a message to the w i n d o w ' s default procedure, w h i c h h a n d l e s d e f a u l t p r o c e s s i n g f o r i n c o m i n g W i n d o w s m e s s a g e s . It s t o r e s t h e result o f this m e s s a g e i n t h e R e s u l t field o f t h e m e s s a g e r e c o r d , Msg.
TWindow.GetID function
Getld:
Integer;
virtual;
( O v e r r i d e : s e l d o m ) R e t u r n s t h e w i n d o w i d e n t i f i e r , s u c h as a c o n t r o l I D .
TWindow.GetWindowClass procedure GetWindowClass(var
AWndClass:
TWndClass);virtual;
( O v e r r i d e : o f t e n ) Fills a w i n d o w class r e c o r d , p a s s e d i n A W n d C l a s s , w i t h d e f a u l t v a l u e s f o r its r e g i s t r a t i o n a t t r i b u t e s . T h e r e g i s t r a t i o n a t t r i b u t e s a n d d e f a u l t v a l u e s are s h o w n i n t h e f o l l o w i n g table: Attribute
Default
Value
Style f i e l d Icon Cursor Background
c s H R e d r a w or c s V R e d r a w Generic icon Stock arrow cursor C o l o r system's w i n d o w b a c k g r o u n d color
R e t r i e v e t h e n a m e o f t h e class t o b e r e g i s t e r e d b y s e n d i n g a m e s s a g e GetClassName.
TWindow.Paint procedure virtual;
Paint(PaintDC:
HDC; v a r P a i n t l n f o :
TPaintStruct);
to
496
Part I I I — R e f e r e n c e s
( O v e r r i d e : o f t e n ) A c t s as a p l a c e h o l d e r f o r d e s c e n d a n t t y p e s that d e f i n e Paint m e t h o d s . Paint r e c e i v e s a m e s s a g e a u t o m a t i c a l l y i n r e s p o n s e t o a r e q u e s t (wm_Paint) f r o m W i n d o w s t o r e d i s p l a y t h e w i n d o w ' s c o n t e n t s . U s e PaintDC as t h e d i s p l a y c o n t e x t b e c a u s e it's o b t a i n e d b e f o r e t h e m e s s a g e is s e n t t o Paint, a n d r e l e a s e d after Paint. T h e Paintlnfo p a i n t structure sent contains information about the paint request.
TWindow.SetCaption procedure SetCaption
(ATitle
: PChar);
S e t s a TWindow c a p t i o n .
TWindow.SetupWindow procedure SetupWindow;
virtual;
( O v e r r i d e : o f t e n ) Sets u p t h e n e w l y c r e a t e d w i n d o w . I f t h e w i n d o w is a n MDI c h i l d w i n d o w , SetupWindow s e n d s a m e s s a g e t o SetFocus t o g i v e t h e n e w w i n d o w t h e f o c u s . I f t h e w i n d o w h a s a s c r o l l e r o b j e c t , SetupWindow s e n d s a m e s s a g e t o SetSBarRange t o set t h e r a n g e o f its s c r o l l b a r s .
TWindow.Store procedure Store(var S: TStream); S t o r e s t h e w i n d o w o n t h e s t r e a m , S, b y s e n d i n g a m e s s a g e t o TWindowsOb j ect .Store a n d t h e n w r i t i n g a n d p u t t i n g t h e a d d i t i o n a l fields (Attr a n d Scroller) i n t r o d u c e d b y TWindow.
TWindow.WMActivate procedure WMActivate(var Msg: TMessage); virtual wm_First + wm_Activate; ( O v e r r i d e : s o m e t i m e s ) F o r w i n d o w s that i n t e r c e p t k e y b o a r d m e s s a g e s f o r its c o n t r o l s , WMAc t i vat e r e s p o n d s t o t h e w i n d o w that l o s e s a n d r e c e i v e s t h e f o c u s b y s a v i n g t h e h a n d l e o f t h e c h i l d c o n t r o l that c u r r e n t l y h a s t h e f o c u s i n FocusChildHandle a n d r e s t o r i n g t h e f o c u s .
A—ObjectWindows Objects
497
TWindow.WMCreate p r o c e d u r e WMCreate(var Msg:
TMessage);
virtual;
wm_First
+ wm_Create;
R e s p o n d s t o t h e w m C r e a t e m e s s a g e b y s e n d i n g m e s s a g e s first t o S e t u p W i n d o w a n d t h e n D e f W n d P r o c . B e c a u s e w i n d o w c r e a t i o n is h a n d l e d differently u n d e r ObjectWindows than u n d e r W i n d o w s , the w m C r e a t e message needs to b e t r a p p e d a n d u s e d t o set u p w i n d o w o b j e c t a t t r i b u t e s .
TWindow.WMHScroll procedure WMHScroll(var wm_First
Msg:
TMessage);
virtual;
+ wm_HScroll;
(Sometimes) For w i n d o w s with scrollers, WMHScroll r e s p o n d s to horizontalw i n d o w s c r o l l b a r e v e n t s b y s e n d i n g m e s s a g e s t o t h e s c r o l l e r ' s HSc r o l l m e t h o d and DefWndProc.
TWindow.WMLButtonDown p r o c e d u r e WMLButtonDown(var Msg: w m _ F i r s t + wm_LButtonDown;
TMessage);
virtual;
( O v e r r i d e : s o m e t i m e s ) F o r w i n d o w s w i t h auto-scrolling scrollers, WMLButtonDown r e s p o n d s t o a left m o u s e - b u t t o n c l i c k b y c a p t u r i n g all f u t u r e m o u s e i n p u t u n t i l t h e m o u s e b u t t o n is r e l e a s e d . It a l s o instructs W i n d o w s t o s e n d w m T i m e r m e s s a g e s w h i l e t h e m o u s e b u t t o n is d o w n . If y o u p l a n t o o v e r r i d e this m e t h o d t o p r o c e s s m o u s e c l i c k s , b u t still p l a n t o u s e a u t o - s c r o l l i n g , b e s u r e t o s e n d a m e s s a g e t o this m e t h o d f r o m y o u r WMLButtonDown m e t h o d .
TWindow.WMMove p r o c e d u r e WMMove(var M s g :
TMsg);
virtual;
wm_First
+ wm_Move;
U p d a t e s A t t r . X a n d A t t r . Y w h e n t h e wm_Move m e s s a g e is r e c e i v e d . If t h e w i n d o w is i c o n i c o r z o o m e d , t h e m e s s a g e is i g n o r e d .
498
Part III—References
TWindow.WMPaint p r o c e d u r e W M P a i n t ( v a r Msg:
TMessage);
virtual;
wm_First
+ wm_Paint
(Override: seldom) R e s p o n d s to the W i n d o w s wm_Paint message by sending a message to the w i n d o w object's P a i n t m e t h o d . If the w i n d o w has a scroller, WMPaint sends a message t o B e g i n V i e w before sending messages to P a i n t a n d EndView after sending P a i n t a message.
TWindow.WMSize p r o c e d u r e W M S i z e ( v a r Msg:
TMessage);
virtual;
wm_First
+
wm_Size; (Override: sometimes) For w i n d o w s with scrollers, WMSize responds to a window-sizing event by sending a message to S e t P a g e S i z e to adjust in response to the n e w w i n d o w size.
TWindow.WMVScroll p r o c e d u r e W M V S c r o l l ( v a r Msg: wm_VScroll;
TMessage);
virtual;
wm_First
+
(Override: sometimes) For w i n d o w s with scrollers, W M V S c r o l l responds to vertical-window scroll bar events by sending messages to the scroller's V S c r o l l m e t h o d and DefWndProc.
B REFERENCE
OBJECTWINDOWS CONSTANTS
bfXXXX Constants Buttons, check boxes, and radio-button objects use bf _ constants to define t h e i r t h r e e p o s s i b l e states. ObjectWindows defines the following button-flag constants: Constant
Value
bfJUnchecked bf_Checked bf_Grayed
0 1 2
Meaning I t e m is u n c h e c k e d I t e m is c h e c k e d I t e m is g r a y e d
cmXXXX Constants O b j e c t W i n d o w s c o n t a i n s several c o n s t a n t s that d e f i n e t h e r a n g e s o f c o m m a n d message constants:
500
Part I I I — R e f e r e n c e s
Constant
Value
Meaning
cmJFirst
$A000
Beginning of c o m m a n d
cm_Count
$6000
messages Number of command
cmlnternal
$FF00
messages Beginning of c o m m a n d messages reserved for internal use. cm_Internal - c m F i r s t
cmJReserved
O b j e c t W i n d o w s defines cm_ constants for three standard m e n u s ; File, Edit, a n d W i n d o w : Constant
Value
cmReserved cmEditCut cmEditCopy cmEditPaste cm_EditDelete cmEditClear cmEditUndo cm_EditFind cmEditReplace cmEditFindNext cmFileNew cm_FileOpen cmMDIFileNew cmMDIFileOpen cm_FileSave cm_FileSaveAs cm_ArrangeIcons
cmlnternal cmReserved cmReserved cmReserved cmReserved cmReserved cmReserved cmReserved cmReserved cmReserved cmReserved cmReserved cmReserved cmReserved cmReserved cm_Reserved cmReserved
Menu cmFirst; + 0 4- 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 +11 + 12 +13 + 14 +15
Equivalent
cm_TileChildren
c m R e s e r v e d + 16
None Edit | C u t Edit | C o p y Edit | Paste Edit | D e l e t e Edit | C l e a r Edit | U n d o Search | Find Search | Replace Search | Search Again File | N e w File | O p e n File | N e w File | O p e n File | S a v e File | S a v e A s Window | A r r a n g e Icons Window | T i l e
cmCascadeChildren cmCloseChildren cmCreateChild c m Exit
cmReserved cmReserved cmReserved c m Reserved
Window | C a s c a d e Window | C l o s e A l l Window | O p e n File I Exit
+ + + +
17 18 19 20
B — ObjectWindows Constants
coXXXX Constants c o X X X X c o n s t a n t s are s e n t as t h e C o d e p a r a m e t e r t o t h e T C o l l e c t i o n . E r r o r m e t h o d w h e n a T C o l l e c t i o n object detects an error during an operation. O b j e c t W i n d o w s d e f i n e s t h e f o l l o w i n g s t a n d a r d e r r o r c o d e s f o r all ObjectWindows collections: Error
Code
Value
Meaning
Error
Origin
eolndexError
-1
Index out of range
coOverflow
-2
Collection overflow
The I n f o parameter passed to the E r r o r m e t h o d contains the invalid index. S e t L i m i t failed to expand the collection to the requested size.
The I n f o parameter passed to the E r r o r m e t h o d contains the requested size.
emXXXX Constants S e v e r a l s t a n d a r d e r r o r c o n d i t i o n s are f l a g g e d b y O b j e c t W i n d o w s c o n s t a n t s starting w i t h e m _ . O b j e c t W i n d o w s d e f i n e s t h e f o l l o w i n g e r r o r flags: Constant
Value
em_OutOfMemory
-2
em_InvalidClient
-3
emlnvalidChild
-4
em_InvalidWindow
-1
emlnvalidMainWindow
-5
Meaning A memory allocation used the safety p o o l . A n M D I client w i n d o w c o u l d not be created. O n e or more of the window's c h i l d r e n is n o t v a l i d . Window is invalid b e c a u s e C r e a t e did not succeed. Main w i n d o w could not be created.
501
502
Part I I I — R e f e r e n c e s
id XXXX Constants O b j e c t W i n d o w s has several c o n s t a n t s that d e f i n e t h e ranges
o f child I D
messages: Constant
Value
Meaning
id_First
$8000
Start o f c h i l d I D m e s s a g e s
id_Count
$ 1000
idReserved idlnternalOffset idFirstMDIChild id_MDIClient
$8F00 idlnternal - idFirst; id_InternalOffset + 1 id J n t e r n a l O f f s e t + 2
N u m b e r o f child I D messages R e s e r v e d f o r internal u s e I n t e r n a l offset Base for child I D numbers Child I D number of the M D I client w i n d o w
nf XXXX Constants O b j e c t W i n d o w s h a s several c o n s t a n t s that d e f i n e t h e r a n g e s o f n o t i f i c a t i o n messages: Constant
Value
nfFirst nfCount nflnternal
$9000 $1000 $9F00
Meaning Beginning o f notification messages N u m b e r o f notification messages Beginning o f notification messages reserved for internal u s e
stXXXX Constants T w o sets o f c o n s t a n t s b e g i n w i t h S t . T h e s e are u s e d b y t h e O b j e c t W i n d o w s streams system. TDosStream a n d TBufStream u s e t h e f o l l o w i n g s t r e a m - a c c e s s - m o d e c o n s t a n t s t o d e t e r m i n e t h e file-access m o d e f o r a file that is o p e n e d f o r a n ObjectWindows stream: Constant
Value
stCreate stOpenRead stOpenWrite stOpen
$3C00 $3D00 $3D01 $3D02
Meaning C r e a t e n e w file O p e n a file f o r reading o n l y O p e n a file for w r i t i n g o n l y O p e n a file for reading a n d w r i t i n g
B — ObjectWindows Constants
T h e f o l l o w i n g v a l u e s are returned b y T S t r e a m . E r r o r in t h e T S t r e a m . E r r o r l n f o field w h e n a s t r e a m error o c c u r s : Error
Code
Value
stOk
0
Meaning N o error
stError
-1
A c c e s s error
stlnitError stReadError stWriteError stGetError stPutError
-2 -3 -4 -5 -6
C a n n o t initialize t h e s t r e a m Read b e y o n d e n d of stream C a n n o t e x p a n d the stream G e t unregistered object type Put unregistered object type
tfXXXX Constants T h e T r a n s f e r m e t h o d u s e s flag c o n s t a n t s b e g i n n i n g w i t h t f _ . O b j e c t W i n d o w s d e f i n e s t h e f o l l o w i n g transfer f u n c t i o n c o n s t a n t s : Constant
Value
tfSizeData
0
tfGetData tf_SetData
1 2
Meaning D e t e r m i n e t h e size o f d a t a t r a n s f e r r e d b y t h e object G e t data from the object S e n d d a t a t o set t h e v a l u e o f t h e o b j e c t
wb_XXXX Constants T h e F l a g s field in TWindowsOb j e c t is a b i t - m a p p e d field. Y o u c a n a c c e s s t h e s e bits w i t h c o n s t a n t s b e g i n n i n g w i t h wb_. ObjectWindows defines the following values: Constant
Value
Meaning
wbKeyboardHandler
$01
Window
wbFromResource wbAutoCreate
$02 $04
wb_MDIChild wbTransfer
$08 $10
If
Set
handles
k e y e v e n t s like a
dialog. Dialog was loaded from a resource. Window is c r e a t e d w h e n p a r e n t w i n d o w is c r e a t e d . Window is a n M D I c h i l d w i n d o w . Window participates in t h e T r a n s f e r m e c h a n i s m . B y d e f a u l t , this bit is set b y I n i t R e s o u r c e a n d c l e a r e d b y Init.
503
504
Part I I I — R e f e r e n c e s
wmXXXX Constants O b j e c t W i n d o w s h a s several c o n s t a n t s related to s t a n d a r d Windows messages. T h e s e d e f i n e the ranges o f m e s s a g e s that are reserved f o r Windows. O b j e c t W i n d o w s d e f i n e s the f o l l o w i n g w i n d o w m e s s a g e c o n s t a n t s : Constant
Value
wmFirst wm_Count
$0000 $8000
Meaning B e g i n n i n g o f Windows messages N u m b e r o f Windows messages
c
REFERENCE
OBJECTWINDOWS PROCEDURES AND FUNCTIONS
O b j e c t W i n d o w s h a s a n u m b e r o f p r o c e d u r e s a n d f u n c t i o n s that are separate f r o m t h e O b j e c t W i n d o w s o b j e c t s . T h e s e p r o c e d u r e s a n d f u n c t i o n s are d e f i n e d in this r e f e r e n c e c h a p t e r . Abstract AllocMultiSel DisposeStr FreeMultiSel GetObj ectPtr LongDiv LongMul LowMemory MemAlloc NewStr RegisterType RegisterWObj ects RestoreMemory
procedure function procedure procedure function function function function function function procedure procedure procedure
506
Part I I I — R e f e r e n c e s
Abstract C a l l i n g this p r o c e d u r e t e r m i n a t e s t h e p r o g r a m w i t h r u n - t i m e e r r o r 2 1 1 . procedure Abstract; U s e t h e Abstract p r o c e d u r e w h e n y o u i m p l e m e n t abstract o b j e c t t y p e s t o e n s u r e that d e s c e n d a n t t y p e s o v e r r i d e virtual a n c e s t o r b e h a v i o r .
AllocMultiSel A l l o c a t e s a TMultiSelRec w i t h Count s e l e c t i o n s a n d sufficient s p a c e i n t h e Selections f i e l d t o h o l d Count s e l e c t i o n s (O..Count-l). function AllocMultiSel(Count:
Integer): PMultiSelRec;
R e t u r n s n i l if t h e r e is n o t e n o u g h m e m o r y t o a l l o c a t e t h e e n t i r e r e c o r d .
DisposeStr A m e m o r y - m a n a g e m e n t p r o c e d u r e ; d e s t r o y s t h e string p o i n t e d t o b y P. procedure DisposeStr(P: PString);
FreeMultiSel F r e e s a TMultiSelRec r e c o r d a l l o c a t e d b y AllocMultiSel. procedure FreeMultiSel(P: PMultiSelRec);
GetObjectPtr A memory-management function. Returns a pointer to the Windows object specified by H W i n d o w . function GetObjectPtr(HWindow:
HWnd): PWindowsObject;
C — O b j e c t W i n d o w s Procedures a n d Functions
LongDiv A n optimized inline assembly-coded function for handling integer division. R e t u r n s t h e i n t e g e r v a l u e X/Y. function LongDiv(X: Longint; Y: Integer): Integer; inline($59/$58/$5A/$F7/$F9);
LongMul A n o p t i m i z e d , in-line assembly-coded multiplication f u n c t i o n . Returns the l o n g i n t e g e r v a l u e X * Y. function longmul(X, Y: Integer): Longint; inline($5A/$58/$f7/$EA);
LowMemory If a m e m o r y a l l o c a t i o n u s e s m e m o r y i n t h e safety p o o l at t h e e n d o f t h e h e a p , LowMemory r e t u r n s T r u e . T h e safety p o o l size is d e t e r m i n e d b y t h e Saf etyPoolSize v a r i a b l e . R e s o u r c e s a n d a p p l i c a t i o n s that u s e m u c h m e m o r y ( s u c h as c o m p l e x d i a l o g b o x e s ) s h o u l d b e p r o g r a m m e d t o c h e c k LowMemory t o e n s u r e that t h e i r m e m o r y d e m a n d d o e s n o t e x c e e d available m e m o r y . function LowMemory: Boolean;
MemAlloc A l l o c a t e s Size b y t e s o f m e m o r y o n t h e h e a p a n d r e t u r n s a p o i n t e r t o t h e a l l o c a t e d b l o c k . I f t h e r e q u e s t e d b l o c k c a n n o t b e a l l o c a t e d , MemAlloc r e t u r n s nil. function MemAlloc(Size: Word): Pointer; MemAlloc d o e s n o t a l l o w t h e a l l o c a t i o n t o u s e t h e safety p o o l . Y o u c a n d i s p o s e o f a b l o c k a l l o c a t e d b y MemAlloc u s i n g t h e s t a n d a r d p r o c e d u r e FreeMem.
507
508
Part I I I — R e f e r e n c e s
NewStr A m e m o r y - m a n a g e m e n t f u n c t i o n . C r e a t e s s p a c e f o r a n e w string a n d r e t u r n s a p o i n t e r t o it. function Newstr(S: String): PString;
RegisterType If a n O b j e c t W i n d o w s t y p e is u s e d i n s t r e a m i n p u t a n d o u t p u t , y o u m u s t r e g i s t e r t h e o b j e c t t y p e u s i n g this m e t h o d . procedure RegisterType(var S: TStreamRec); S t a n d a r d object t y p e s a r e p r e r e g i s t e r e d w i t h Ob j Type v a l u e s i n t h e reserved range 0..99. RegisterType c r e a t e s a n e n t r y i n a l i n k e d list o f TStreamRec r e c o r d s .
RegisterWObjects A stream p r o c e d u r e u s e d t o register W O b j e c t s . procedure
RegisterWObjects;
RestoreMemory A m e m o r y - m a n a g e m e n t p r o c e d u r e . R e - e s t a b l i s h e s t h e m e m o r y state that existed before a n attempt to execute another program (using W i n E x e c ) . procedure
RestoreMemory;
D
REFERENCE
OBJECTWINDOWS RECORDS
LongRec PtrRec TDialogAttr TMessage TMultiSelRec TScrollBarTransferRec TStreamRec TWindowAttr WordRec
LongRec L o n g R e c i s a record
type f o r h a n d l i n g d o u b l e - w o r d - l e n g t h v a r i a b l e s .
LongRec = record Lo, Hi: Word; end;
510
Part III—References
PtrRec PtrRec holds the offset and segment values of a pointer. PtrRec = record Ofs, Seg: Word; end;
TDialogAttr TDialogAttr holds attribute values for TDialog objects. TDialogAttr = record Name: PChar; Param: Longint; end;
TMessage T h e m e s s a g e - p r o c e s s i n g l o o p in TApplication stores Windows message information in TMessage records. This information is p a s s e d to t h e a p p r o p r i a t e message-response method. TMessage = record Receiver: HWnd; Message: Word; case Integer of 0: (WParam: Word; LParam: Longint; Result: Longint); 1: (WParamLo: Byte; WParamHi: Byte; LParamLo: Word; LParamHi: Word; ResultLo: Word; ResultHi: Word); end;
D — O b j e c t W i n d o w s Records
TMultiSelRec TMultiSelRec h o l d s a list o f s e l e c t e d i t e m s for transfer t o or f r o m a m u l t i p l e s e l e c t i o n list box.
TMultiSelRec = record Count: Integer; Selections: array[0..0] of Integer; end; • Count i n d i c a t e s t h e n u m b e r o f s e l e c t e d i t e m s .
• Selections is a n o p e n - e n d e d array o f i n t e g e r s . U s i n g AllocMultiSel, y o u c a n a l l o c a t e a r e c o r d w i t h e n o u g h s e l e c t i o n i t e m s t o a c c o m m o d a t e all list-box i t e m s .
TSaollBarHransferRec B e f o r e y o u c a n l o a d or s t o r e o b j e c t s o n a TStream, y o u m u s t r e g i s t e r a n y O b j e c t W i n d o w s o b j e c t t y p e s u s i n g a TStreamRec.
{ TScrollBar transfer record } TScrollBarTransferRec = record LowValue: Integer; HighValue: Integer; Position: Integer; end;
TStreamRec T h e Regist erType p r o c e d u r e registers a n o b j e c t t y p e b y s e t t i n g a TSt reamRec r e c o r d for it.
TStreamRec = record ObjType: Word; VmtLink: Word; Load: Pointer; Store: Pointer; Next: Word; end;
511
512
Part III—References
T h e fields i n t h e s t r e a m - r e g i s t r a t i o n r e c o r d are d e f i n e d as f o l l o w s : Field
Contents
ObjType
U n i q u e n u m e r i c a l ID f o r t h e o b j e c t t y p e
VmtLink
Link to the object type's virtual-method table entry
Load
Pointer to the object type's Load constructor
Store
P o i n t e r t o t h e o b j e c t t y p e ' s Store m e t h o d
Next
P o i n t e r t o t h e n e x t TSt reamRec
O b j e c t W i n d o w s reserves o b j e c t - t y p e I D s ( O b j T y p e ) w i t h v a l u e s f r o m 0 t o 9 9 9 for its o w n u s e . Y o u c a n d e f i n e y o u r o w n o b j e c t - t y p e I D s i n t h e r a n g e 1,000 to 65,535. B y c o n v e n t i o n , a TSt reamRec f o r a Txxxx o b j e c t t y p e is c a l l e d Rxxxx. F o r e x a m p l e , t h e TStreamRec f o r a TCalculator t y p e is c a l l e d RCalculator:
type TCalculator = object(TDialog) constructor Load(var S: TStream); procedure Store(var S: TStream); end; const RCalculator: TStreamRec = ( ObjType: 2099; VmtLink: Ofs(TypeOf(TCalculator) ); Load: @TCalculator.Load; Store: @TCalculator.Store); begin A
RegisterType(RCalculator); end;
TWindowAttr TWindow o b j e c t s d e f i n e t h e i r attributes i n TWindowAttr r e c o r d s .
TWindowAttr = record Title: PChar; Style: Longint; ExStyle: Longint; X, Y, W, H: Integer;
D—ObjectWindows Records
Param: Pointer; case Integer of 0: (Menu: HMenu); 1: (Id: Integer); end;
{ window menu's handle or... } { control's child identifier }
WordRec WordRec is a utility record that lets you access the Lo and Hi bytes of a word. WordRec = record Lo, Hi: Byte; end;
513
E REFERENCE
THE
WINCRT UNIT
T h e T u r b o Pascal f o r Windows W i n C r t u n i t implements a t e r m i n a l - l i k e text s c r e e n in a w i n d o w . If y o u r a p p l i c a t i o n u s e s W i n C r t , it d o e s n o t have t o c o n t a i n a n y Windows-specific c o d e . T h i s u n i t is u s e f u l f o r reimplementing existing T u r b o Pascal t e x t - b a s e d a p p l i c a t i o n s i n Windows, w i t h o u t a d d i n g m u c h extra code. T o u s e t h e W i n C r t u n i t , i n c l u d e it i n y o u r a p p l i c a t i o n ' s u s e s c l a u s e : uses
WinCrt;
Table
E.l.
WinCrt procedures
Procedure
or Function
and
functions.
Value
AssignCrt
A s s o c i a t e s a text file w i t h t h e C R T window
ClrEol
C l e a r s all c h a r a c t e r s f r o m t h e c u r r e n t cursor position to t h e e n d of t h e line
ClrScr
C l e a r s t h e s c r e e n a n d returns c u r s o r t o t h e u p p e r - l e f t c o r n e r o f the s c r e e n
CursorTo
M o v e s the c u r s o r to the s p e c i f i e d c o o r d i n a t e s i n a virtual s c r e e n
DoneWinCrt
D e s t r o y s the C R T w i n d o w continues
516
Part I I I — R e f e r e n c e s
Table
E.l.
Procedure
continued or
Function
GotoXY
Value Moves t h e cursor to t h e specified c o o r d i n a t e s in a virtual s c r e e n
InitWinCrt
Creates the C R T w i n d o w
KeyPressed
Returns True w h e n t h e user presses a key
ReadBuf
Inputs o n e line from t h e C R T w i n d o w
ReadKey
Reads o n e character from t h e keyboard
ScrollTo
Scrolls t h e C R T w i n d o w to a specific screen location Scrolls t h e C R T w i n d o w to k e e p cursor visible
TrackCursor WhereX
Returns t h e X coordinate o f t h e current cursor location
WhereY
Returns the Y coordinate of t h e current cursor location
WriteBuf
Writes a b l o c k o f c h a r a c t e r s t o t h e C R T window
WriteChar
Writes
o n e character to t h e C R T w i n d o w
AssignCrt A s s o c i a t e s a text file w i t h t h e C R T w i n d o w .
procedure AssignCrt(var F: Text); For example:
program sample; uses WinCrt; var AScreenFile: Text; begin AssignCRT(AScreenFile);
E — T h e WinCrt Unit
Rewrite(AScreenFile); Writeln(AScreenFile, AScreenFile to screen.'); Close(AScreenFile); end. 1
ClrEol C l e a r s all t h e c h a r a c t e r s f r o m t h e c u r s o r p o s i t i o n t o t h e e n d o f t h e l i n e w i t h o u t moving the cursor.
procedure ClrEol; For example:
program sample; uses WinCrt; begin Writeln('String here.'); Writeln('Press a k e y . . . ) ; Readln; CursorTo(16,10); ClrEol; end. 1
ClrScr Clears the screen a n d returns the cursor to the upper-left corner o f the screen.
procedure ClrScr; For example:
program sample; uses WinCrt; begin Writeln('Hi. Press a key...'); Readln; ClrScr; end.
517
518
Part I I I — R e f e r e n c e s
CursorTo M o v e s t h e c u r s o r t o t h e s p e c i f i e d c o o r d i n a t e s i n a virtual s c r e e n .
procedure CursorTo(X, Y: Integer); T h e u p p e r - l e f t c o r n e r o f t h e C R T w i n d o w is r e p r e s e n t e d b y t h e c o o r d i n a t e s 0,0. CursorTo sets t h e Cursor v a r i a b l e t o (X,Y). F o r e x a m p l e :
program sample; uses WinCrt; begin CursorTo(18,15); Writeln( 18/15 coordinates. ); end. 1
1
DoneWinCrt Destroys any existing C R T .
procedure DoneWinCrt; C a l l i n g DoneWinCrt b e f o r e a n a p p l i c a t i o n t e r m i n a t e s p r e v e n t s t h e C R T w i n d o w f r o m e n t e r i n g a n i n a c t i v e state. F o r e x a m p l e :
program sample; uses WinCrt; begin Writeln('This is a CRT window.'); Writeln('Return. ); Readln; DoneWinCRT; Writeln('This is another CRT window.'); end. 1
E — T h e WinCrt Unit
GotoXY M o v e s t h e c u r s o r t o t h e s p e c i f i e d c o o r d i n a t e s w i t h a virtual s c r e e n .
procedure GotoXY(X, Y: Integer); T h e upper-left corner o f the virtual screen corresponds to the c o o r d i n a t e s 1,1. U s e CursorTo r a t h e r t h a n GotoXY w h e n y o u d e v e l o p n e w W i n d o w s a p p l i c a t i o n s . GotoXY is available strictly f o r c o m p a t i b i l i t y w i t h t h e C r t u n i t o f D O S - b a s e d T u r b o Pascal. F o r e x a m p l e :
program sample; uses WinCrt; begin GotoXY(20,20); Writeln('Hi'); end.
InitWinCrt Creates the C R T window.
procedure InitWinCrt; Ifyou u s e Read, Readln, Write, o r Writ eln i n a file that h a s b e e n a s s i g n e d t o t h e C R T , InitWinCrt is c a l l e d automatically f o r you. F o r e x a m p l e :
program sample; uses Strings, WinCrt, WinDOS; begin StrCopy(WindowTitle,'CRT Window created by InitWinCRT.'); InitWinCRT; end.
519
520
Part I I I — R e f e r e n c e s
KeyPressed D e c i d e s w h e t h e r t h e u s e r has p r e s s e d a k e y . function KeyPressed: Boolean; U s e Re ad Key t o read t h e k e y . Return
Value
True
I f a k e y has b e e n p r e s s e d
False
I f a k e y has n o t b e e n p r e s s e d
For example: program sample; uses WinCrt; begin repeat Write('A continuous string'); until KeyPressed; end.
ReadBuf I n p u t s a l i n e from t h e C R T w i n d o w . function ReadBuf(Buffer: PChar; Count: Word): Word; Buffer p o i n t s t o a l i n e b u f f e r that has s p a c e for Count n u m b e r o f c h a r a c t e r s . Count holds t h e n u m b e r o f c h a r a c t e r s t o read in t h e b u f f e r . U p t o Count - 2 c h a r a c t e r s c a n b e inserted. A n e n d - o f - l i n e m a r k e r (a # 1 3 f o l l o w e d b y a # 10) is a u t o m a t i c a l l y a p p e n d e d t o t h e l i n e w h e n t h e u s e r p r e s s e s E n t e r ( R e t u r n ) . T h e c o m m a n d returns t h e n u m b e r o f c h a r a c t e r s read, including t h e e n d - o f - l i n e o r end-of-file m a r k e r . F o r e x a m p l e : program sample; uses WinCrt; var
E — T h e WinCrt Unit
Chars: PChar; begin GetMem(Chars, 20); Chars := #20#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0; Writeln( Enter a phrase:'); ReadBuf(Chars, 20); Writeln(' You entered: '); Writeln(Chars); end. 1
ReadKey Reads a character from the keyboard.
function ReadKey: Char; T h e c h a r a c t e r is n o t e c h o e d o n t h e s c r e e n . F o r e x a m p l e :
program sample; uses WinCrt; var AChar: Char; begin Writeln('Press a key'); AChar := Readkey; Writeln(' You pressed ', AChar, ' . ' ) ; end.
ScrollTo S c r o l l s t h e C R T w i n d o w t o d i s p l a y t h e virtual s c r e e n l o c a t i o n s p e c i f i e d b y X,Y in the upper-left corner.
procedure ScrollTo(X, Y: Integer); T h e upper-left corner of the virtual screen c o r r e s p o n d s coordinates 0,0. For e x a m p l e :
to
the
521
522
Part I I I — R e f e r e n c e s
program sample; uses WinCrt; begin GotoXY(10,20); Writeln('Hi'); Writeln( Enter a line and Return.'); Readln; ScrollTo(0,8); end. 1
TrackCursor S c r o l l s t h e C R T w i n d o w if n e c e s s a r y t o m a k e t h e c u r s o r v i s i b l e .
procedure TrackCursor; For example:
program sample; uses WinCrt; var I: integer; begin for I := 1 to 20 do Write('CursoR'); TrackCursor; Readln; end.
WhereX Returns the X coordinate of the current cursor position,
function WhereX: Integer;
E — T h e WinCrt Unit
For example: program sample; uses WinCrt; begin Writeln(WhereX,
'WhereX. ); 1
end.
WhereY Returns the Y coordinate o f the current cursor position. function WhereY:
Integer;
For example: program sample; uses WinCrt; begin Writeln(WhereY,
'WhereY. ); 1
end.
ffiiteBuf Writes a specified b l o c k o f characters t o the C R T w i n d o w , procedure WriteBuf(Buffer:
PChar;
Count:
Word);
B u f f e r p o i n t s t o t h e first c h a r a c t e r i n t h e b l o c k . C o u n t h o l d s t h e n u m b e r of characters to write to the buffer. If A u t o T r a c k i n g is o n , t h e C R T w i n d o w scrolls t o m a k e c e r t a i n that t h e c u r s o r is visible after w r i t i n g t h e b l o c k o f c h a r a c t e r s . F o r e x a m p l e :
523
524
Part I I I — R e f e r e n c e s
program sample; uses WinCrt; var ABuffer: PChar; begin GetMem(ABuffer, 100); ABuffer := 'WriteBuf'; WriteBuf(ABuffer, 100); end.
WtiteChar Writes o n e character to the C R T w i n d o w .
procedure WriteChar(Ch: Char); For example:
program sample; uses WinCrt; begin WriteChar( F ); end. 1
1
F REFERENCE
A WINCRT EXAMPLE T h e f o l l o w i n g a p p l i c a t i o n i m p l e m e n t s a m i n i b r o w s e r that traces a h i e r a r c h y o f o b j e c t s i n e i t h e r T u r b o Pascal o r C + + . It w a s o r i g i n a l l y w r i t t e n i n T u r b o Pascal f o r D O S , b u t r e q u i r e d a l m o s t n o c h a n g e s t o b e c o m p i l e d w i t h T u r b o Pascal f o r W i n d o w s a n d r u n as a W i n d o w s a p p l i c a t i o n . T h e m a i n a d d i t i o n t o this v e r s i o n is t h e W i n C r t u n i t , w h i c h i m p l e m e n t s a text w i n d o w i n W i n d o w s f o r t h e a p p l i c a t i o n ' s o u t p u t . T h e a p p l i c a t i o n is far f r o m c o m p l e t e a n d c o u l d u s e m a n y a d d i t i o n s t o b e u s e f u l as a b r o w s e r , b u t it illustrates h o w a t y p i c a l T u r b o Pascal D O S - b a s e d ( a n d o b j e c t - o r i e n t e d ) a p p l i c a t i o n c a n b e r u n (with little m o d i f i c a t i o n ) i n W i n d o w s . It u s e s o b j e c t - o r i e n t e d t e c h n i q u e s , b u t n o t t h e O b j e c t W i n d o w s library. T h e application consists o f a m a i n m o d u l e a n d t w o units (nodes2 a n d cell list), w h i c h are p r i n t e d h e r e . This minibrowser m o d u l e reconstructs an object hierarchy from either Pascal or C + + source c o d e . T h e reconstruction p r o b l e m c a n b e dissected into several s m a l l e r p r o b l e m s : • Getting a "key" object from a user • S e a r c h i n g a s p e c i f i e d p r o j e c t ' s files f o r k e y w o r d s that r e c o n s t r u c t a h i e r a r c h y f o r that " k e y " o b j e c t • D i s p l a y i n g t h e r e s u l t s o r a l l o w i n g a u s e r t o edit t h e files c o n t a i n i n g objects in the hierarchy
526
Part I I I — R e f e r e n c e s
A u s e r s p e c i f i e s a n o b j e c t s h e w a n t s to k n o w a b o u t . T h e m i n i b r o w s e r then reads a p r o j e c t file (to l e a r n the files f o r u s e i n b u i l d i n g a h i e r a r c h y ) . It then reconstructs e i t h e r a C + + o r T u r b o Pascal h i e r a r c h y , d e p e n d i n g o n the l a n g u a g e y o u specify at run-time. T h e m e t h o d s Init_f iles a n d Init_Types h a n d l e file- a n d h i e r a r c h y - t y p e i n i t i a l i z a t i o n . T h e m i n i b r o w s e r ( t h r o u g h t h e Hierarchy o b j e c t ) t h e n s e a r c h e s t h e files s p e c i f i e d i n t h e p r o j e c t file, first f o r b a s e t y p e s — " o b j e c t s " o r " c l a s s e s " — (through the base m e t h o d ) , a n d then for derived types (through the derived m e t h o d ) . I f it f i n d s a d e r i v e d t y p e , it d e t e r m i n e s its a n c e s t o r ( t h r o u g h t h e a n c e s t o r m e t h o d ) a n d t h e n recursively b a c k t r a c k s t o its a n c e s t o r , a d d i n g t h e o b j e c t n a m e t o a list as it g o e s . It t h e n s e a r c h e s f o r w a r d a g a i n f o r b a s e a n d d e r i v e d t y p e s . If it finds a b a s e t y p e , t h e s e a r c h is over, a n d it s e n d s a m e s s a g e t o B a c k T r a c k t o display the constructed hierarchy. D e p e n d i n g o n w h e t h e r y o u w a n t t o d i s p l a y o r e d i t , it t h e n s e n d s a m e s s a g e t o t h e a p p r o p r i a t e o b j e c t — DisplayStr o r Editor. E a c h part o f t h e m i n i b r o w s e r is i m p l e m e n t e d as a n " o b j e c t , " s o y o u c a n easily m o d i f y a n d e x t e n d t h e b i g o b j e c t ( t h e m i n i b r o w s e r m o d u l e ) w i t h o u t c h a n g i n g its o v e r a l l d e s i g n b y reimplementing selective objects. F o r e x a m p l e , t h e Editor o b j e c t i n t h e m a i n m o d u l e o b t a i n s file, l i n e , a n d p o s i t i o n i n f o r m a t i o n . T o e x t e n d this m o d u l e , a d d a m e t h o d that p a s s e s this i n f o r m a t i o n t o y o u r e d i t o r o f c h o i c e . O n e l i n e o f c o d e ( a n d a n e d i t o r library) d o e s t h e trick. unit nodes2; { Contains abstract cell and cell-list types } interface uses CRT, DOS, cellist; type AnyTypePtr = "AnyType; AnyType = object(Node) constructor init; destructor done; virtual; procedure DSAction; virtual; procedure BTAction; virtual; procedure EditAction; virtual; end; AnyTypeListPtr = "AnyTypeList; AnyTypeList = object(List) constructor init; destructor Done; virtual;
{ Type Action { Type Action { Type Action
} } }
F — A WinCrt Example
procedure GetNodes; virtual; end; implementation { constructors } constructor AnyType.init; constructor AnyTypeList.Init;
{ Process AnyTypeList }
begin end; begin end;
{ abstract } { abstract }
begin end; begin end;
{ abstract } { abstract }
{ destructors } destructor AnyType.done; destructor AnyTypeList.Done; { methods } procedure procedure procedure procedure
AnyType.DSAction; AnyType.BTAction; AnyType.EditAction; AnyTypeList.GetNodes;
begin begin begin begin
end; end; end; end;
{ { { {
abstract abstract abstract abstract
end. { unit nodes2 } unit cellist; { Contains base, node, and list types } {$S-} interface type { Abstract base object type } BasePtr = "Base; Base = object destructor Done; virtual; end; { Abstract linked list node type } NodePtr = "Node; Node = object(Base) Next: NodePtr; end; { Simplified Linked list type } ListPtr = "List; List = object(base)
} } } }
527
528
Part III—References
Last: NodePtr; procedure Append(N: NodePtr); procedure Clear; function First: NodePtr; function Next(N: NodePtr): NodePtr; end; implementation { destructor } destructor Base.Done; begin end; { List methods } procedure List.Append(N: NodePtr); begin if Last = nil then Last := N else N".Next := Last".Next; Last".Next := N; Last := N; end; procedure List.Clear; begin Last := nil; end; function List.First: NodePtr; begin if Last = nil then First := nil else First := Last".Next; end; function List.Next(N: NodePtr): NodePtr; begin if N = Last then Next := nil else Next := N".Next; end; end. { Unit cell list } { Main module } program browser; uses WINCRT, nodes2, cellist;
{ Contains specific browser } { Key unit needed for Windows }
F — A WinCrt Example
type StringPtr = "String; BrowserListPtr = "BrowserList; BrowserList = object(AnyTypeList) constructor init; destructor done; virtual; procedure GetNodes; virtual; end; DisplayStrPtr = "DisplayStr; DisplayStr = object(AnyType) Value: StringPtr; constructor Init(V: String); destructor Done; virtual; procedure DSAction; virtual; end; BackTrackPtr = "BackTrack; BackTrack = object(AnyType) Value: StringPtr; constructor Init(V: String); destructor Done; virtual; procedure BTAction; virtual; end;
{ Process a StrCell }
{ Process a BTCell }
EditPtr = "Editor; Editor = object(AnyType) FileName : String; Line : String; LineNo : word; Position : word; constructor Init(F: string; L: string; Ln: word; P: word); destructor Done; virtual; procedure EditAction; virtual; { Edit } end; TextFile = object(base) F : Text; FileName : String; Line : String; Buf : array[0..8191] of char; { Buffer for faster I/O }
529
530
Part III—References
LineNo : word; Position : word; function open_file: boolean; end; HierarchyPtr = "hierarchy; Hierarchy = object(TextFile) Recurse : boolean; Method : String; Language_type : char; End_type, Base_type, Derived_type : string[30]; Object_type, Search_type, Ancestor_type : String[30]; function base : boolean; { Looks for base types } function derived : boolean; { Looks for derived types } function ancestor : boolean; { Looks for ancestors } constructor init; destructor done; virtual; procedure init_types; { Sets types for C++ or Pascal } procedure init_files; { Sets files for C++ or Pascal } procedure construct; { Flow controller } procedure Reconstruct; { Calls construct and simplifies recursion} procedure update_backtrack_list; { Keeps track of types } procedure find_methods; { Finds methods } end; var Display, H : L : P :
{ Globals } Edit : boolean; HierarchyPtr; BrowserListPtr; AnyTypePtr;
{ Constructors } constructor DisplayStr.Init(V: String); begin GetMem(Value, Length(V) + 1 ) ; Value" := V; end; constructor BackTrack.Init(V: String); begin GetMem(Value, Length(V) + 1 ) ; Value" := V; end;
F — A WinCrt Example
constructor begin FileName Line LineNo Position end;
Editor.Init(F: string; L: string; Ln: word; P: word); := := := :=
F; L; Ln; P;
constructor Hierarchy.init; begin end; constructor BrowserList.init; begin end; {destructors } destructor Editor.Done; begin end; destructor DisplayStr.Done; begin
FreeMem(Value, Length(Value") + 1 ) ; end;
destructor BackTrack.Done; begin FreeMem(Value, Length(Value") + 1 ) ; end; destructor Hierarchy.done; begin end; destructor BrowserList.done; begin end; { Methods }
procedure DisplayStr.DSAction; var Ch : char; begin writeln(Value"); Ch := readkey; end; procedure BackTrack.BTAction; begin writeln(Value"); end; procedure Editor.EditAction; var Ch : char; begin writeln(#13, #10,'File
{ Show the object hierarchy }
= ',FileName);
531
532
Part I I I — R e f e r e n c e s
writeln( Line = ',Line); writeln('LineNumber= ',LineNo); writeln('Position = ,Position); { Call editor here and pass it appropriate information. } end; 1
1
procedure hierarchy.init_types; begin case Language_type of •p*: begin { Pascal } Base_type := ' = object'; Derived_type := ' = object('; End_type := 'end'; end; 'c': begin { C++ } Base_type := 'class '; Derived_type := ' :'; End_type := '}'; end; end; { case } end; procedure hierarchy.init_files; begin case Language_type of 'p': FileName := 'cltest2.pas'; { Pascal } 'c': FileName := 'cltest.cpp'; { C++ } end; { case } { Add functions here to read a project's files } end; procedure hierarchy.find_methods; var NextLine : string; TempPosition : word; begin Method := ''; NextLine := Line; TempPosition := 0; While (TempPosition = 0) do begin TempPosition := Pos(End_type,NextLine); Method := Method + NextLine + #13 + #10; readln(F,NextLine);
F — A WinCrt Example
end; L".Append(New(DisplayStrPtr,Init(Method))); L".Append(New(EditPtr,Init(FileName,Line,LineNo,Position))); end; function hierarchy.base: boolean; begin LineNo := 1; case Language_type of 'p': Search_type := Object_type + Base_type; 'c': Search_type := Base_type + Object_type; end; { case } while not eof(F) do begin readln(F,Line); Position := Pos(Search_type,Line); If (Position > 0) then begin Position := Pos(Derived_type,Line); If (Position = 0) then begin findjnethods; base := true; exit; end; end; inc(LineNo); end; base := false; end; function hierarchy.derived: boolean; begin case Language_type of 'p': Search_type := Object_type + Derived_type; 'c': Search_type := Base_type + Object_type + Derived_type; end; { case } LineNo := 1; while not eof(F) do begin readln(F,Line); Position := Pos(Search_type,Line); If (Position > 0) then
533
534
Part III—References
begin If ancestor then begin find_methods; derived := true; exit; end; end; inc(LineNo); end; derived := false; end; function hierarchy.ancestor: boolean; var T_Ancestor_type : string[30]; I,J,L : integer; begin Ancestor_type := ''; T_Ancestor_type := '; I := Length(Line); { Start while (Line[I] = #32) do { Space dec(I); while (Line[I] = ) ) do { Empty dec(I); case Language_type of 'c' : while (Line[I] <> #32) do { Space begin T_Ancestor_type := T_Ancestor_type dec(I); end; 'P': while (Line[IJ <> ' ( ) do begin T_Ancestor_type := T_Ancestor_type dec(l); end; end; { case } 1
1
1
at the end of the line } } in C++ }
} + Line[I];
1
+ Line[I];
L := Length(T_Ancestor_type); for I := L downto 1 do { Reverse the list } Ancestor_type := Ancestor__type + T_Ancestor_type[I]; end;
F — A WinCrt Example
535
procedure hierarchy.update_backtrack_list; begin L".Append(New(BackTrackPtr, Init(Object_type))); end; function TextFile.open_file: boolean; begin {$1-} { Test for I/O error } assign(F,FileName); Reset(f); {$1+}
Open_file := (IOResult = 0); end; procedure hierarchy.Reconstruct; var Count : integer; begin Count := 1; Recurse := true; While Count < 10 do While Recurse do begin construct; inc(Count); end; end;
{ Still more ancestors } { Recursively backtrack for ancestors }
procedure hierarchy.construct; begin If Open_file then { If open successful } begin SetTextBuf(F,buf); update_backtrack_list; Close(F); If Open_file then If Derived then { If derived class, find its ancestor } begin Object_type := ancestor_type; { Set up for backtrack } Close(F); Recurse := true; { Still more ancestors } end ELSE
536
Part III—References
Close(F); IF Open_file then If Base then begin Close(F); Recurse := false; end; end; end;
{ If base type, you are done. }
{ No more ancestors }
procedure display_mode; var Ch : char; begin write('e-Edit or d-display '); Ch := Readkey; writeln; If Ch = 'e' then Edit := true Else Display := true; end; procedure BrowserList.GetNodes; begin P := AnyTypePtr(First); while P <> nil do begin P .BTAction; P := AnyTypePtr(Next(P)); end;
{ Display/edit option }
{ Process the browser list } { Set pointer to first node }
A
If Display = true then begin P := AnyTypePtr(First); while P <> nil do begin P .DSAction; P := AnyTypePtr(Next(P)); end; end;
{ Is it displaying ? }
If Edit = true then begin P := AnyTypePtr(First); while P <> nil do begin
{ Editing ? }
A
F — A WinCrt Example
P .EditAction; P := AnyTypePtr(Next(P)); end; end; end; A
{ main } begin Clrscr; Edit := false; { Initializations } Display := false; New(L,init); { Initialize a new browser list } L".clear; New(H,init); { Initialize a new hierarchy list } write('Enter Language — p or c : '); readln(H .Language_type); write('Enter Object: '); readln(H".Object_type); writeln; ! - r .Init_files; H .Init_types; H".Reconstruct; display_mode; { Set display or edit } L".GetNodes; { Process the browser list } Dispose(L,Done); { Clean up } Dispose(H,Done); A
A
end. { main }
537
G
REFERENCE
THE
STRINGS UNIT
T h e S t r i n g s u n i t s u p p o r t s a class o f c h a r a c t e r strings t e r m i n a t e d b y a n u l l b y t e , c a l l e d null-terminated strings. T h e W i n d o w s A p p l i c a t i o n P r o g r a m m i n g Interface (API) r e q u i r e s this f o r m a t . N u l l - t e r m i n a t e d strings differ f r o m typical T u r b o P a s c a l s t r i n g s , w h o s e l e n g t h is d e t e r m i n e d b y a l e n g t h b y t e . A T u r b o Pascal string is l i m i t e d t o 2 5 5 c h a r a c t e r s . T h e size o f a n u l l t e r m i n a t e d string is l i m i t e d b y t h e d a t a s e g m e n t ( 6 4 K ) . T h e Strings unit has m a n y functions a n d p r o c e d u r e s for manipulating n u l l - t e r m i n a t e d strings a n d f o r c o n v e r t i n g n u l l - t e r m i n a t e d strings t o T u r b o Pascal s t r i n g s . T a b l e G . l lists t h e f u n c t i o n s a n d p r o c e d u r e s i n t h e strings u n i t . Table
G. 1. Strings
Function
Name
unit
functions. Description
StrCat
A p p e n d s a c o p y o f o n e string t o t h e e n d o f a n o t h e r a n d r e t u r n s t h e c o n c a t e n a t e d string
StrComp
C o m p a r e s t w o strings
StrCopy
C o p i e s o n e string t o a n o t h e r
StrDispose
D i s p o s e s o f a p r e v i o u s l y a l l o c a t e d string
StrECopy
C o p i e s o n e string t o a n o t h e r a n d r e t u r n s a p o i n t e r t o t h e e n d o f t h e r e s u l t i n g string continues
540
Part III — R e f e r e n c e s
Table
G.l.
Function
continued Name
Description
StrEnd
Returns a p o i n t e r to the e n d o f a string
StrlComp
C o m p a r e s t w o strings w i t h o u t c a s e sensitivity
StrLCat
A p p e n d s characters f r o m a string to the e n d o f a n o t h e r a n d returns
the c o n c a t e n a t e d string
StrLComp
C o p i e s characters f r o m o n e string to a n o t h e r
StrLCopy
C o m p a r e s t w o strings, u p to a m a x i m u m length
StrLen
Returns the n u m b e r o f characters in S t r
StrLIComp
C o m p a r e s t w o strings, u p to a m a x i m u m length, w i t h o u t c a s e sensitivity
StrLower
C o n v e r t s a string t o l o w e r c a s e
StrMove
C o p i e s characters f r o m o n e string to a n o t h e r
StrNew
Allocates a string o n the h e a p
StrPas
C o n v e r t s a n u l l - t e r m i n a t e d string t o a Pascal style string
StrPCopy
C o p i e s a Pascal style s t r i n g t o a n u l l - t e r m i n a t e d string
StrPos
R e t u r n s a p o i n t e r t o t h e first o c c u r r e n c e o f a s t r i n g i n a n o t h e r string
StrRScan
R e t u r n s a p o i n t e r t o t h e first o c c u r r e n c e o f a string in a n o t h e r string
StrScan
R e t u r n s a p o i n t e r t o t h e first o c c u r r e n c e o f a c h a r a c t e r i n a string
StrUpper
C o n v e r t s a string to u p p e r c a s e
StrCat A p p e n d s a c o p y o f o n e string t o t h e e n d o f a n o t h e r string a n d r e t u r n s t h e c o n c a t e n a t e d string.
function StrCat(Test, Source: PChar): PChar;
G — T h e Strings U n i t
St rCat d o e s n o t c h e c k t h e string l e n g t h . T h e d e s t i n a t i o n b u f f e r m u s t h a v e s p a c e f o r at least StrLen(Test) + Strl_en(Source) + 1 c h a r a c t e r s . F o r example:
program Sample; uses Strings, WinCrt; const Windows: PChar = 'Windows'; Bible : PChar = 'Bible'; var S: array[0..15] of Char; begin StrCopy(S, Windows); StrCat(S, ' '); StrCat(S, Bible); Writeln(S); end.
StrComp C o m p a r e s t w o strings.
function StrComp(Str1, Str2 : PChar): Integer; Return
Values:
<0ifStr1 < Str2 = 0 if Str1 = Str2 > 0 if Str1 > Str2 For example:
program Sample; uses Strings, WinCrt; var C: Integer; Result: PChar; S1, S2: array[0..79] of Char; begin
541
542
Part III — R e f e r e n c e s
Readln(S1); Readln(S2); C := StrComp(S1, S2); if C < 0 then Result := ' is less than ' else if C > 0 then Result := ' is greater than else Result := ' is equal to '; Writeln(S1, Result, S2); end. 1
StrCopy C o p i e s o n e string t o a n o t h e r .
function StrCopy(Test, Source: PChar): PChar; StrCopy d o e s n o t c h e c k t h e s t r i n g l e n g t h . T h e d e s t i n a t i o n b u f f e r m u s t h a v e r o o m f o r at least St rLen (Source) + 1 c h a r a c t e r s . F o r e x a m p l e :
program Sample; uses Strings, WinCrt; var S: array[0..15] of Char; begin StrCopy(S, 'Windows Bible'); Writeln(S); end.
StrDispose D i s p o s e s o f a string o n a h e a p .
function StrDispose(Str: PChar); StrDispose d i s p o s e s o f a s t r i n g that w a s p r e v i o u s l y a l l o c a t e d w i t h StrNew. I f Str is n i l , StrDispose d o e s n o t d o a n y t h i n g . F o r e x a m p l e :
program Sample; uses Strings, WinCrt;
G — T h e Strings U n i t
var P: PChar; S: array[0..79] of Char; begin Readln(S); P := StrNew(S); Writeln(P); StrDispose(P); end.
StrECopy C o p i e s o n e s t r i n g t o a n o t h e r s t r i n g a n d returns a p o i n t e r t o t h e e n d o f t h e n e w string.
function StrECopy(Test, Source: Pchar): PChar; StrECopy d o e s n o t c h e c k t h e s t r i n g l e n g t h . T h e d e s t i n a t i o n b u f f e r m u s t have s p a c e for at least St rLen (Source) + 1 characters. F o r e x a m p l e :
program Sample; uses Strings, WinCrt; const Windows: PChar = 'Windows'; Bible : PChar = 'Bible'; var S: array[0..15] of Char; begin StrECopy(StrECopy(StrECopy(S, Windows), ' '), Bible); Writeln(S); end.
StrEnd Returns a p o i n t e r t o t h e e n d o f a string,
function StrEnd(Str: PChar): Pchar;
543
544
Part III — R e f e r e n c e s
For example:
program Sample; uses Strings, WinCrt; var S: array[0..79] of Char; begin Readln(S); Writeln('String length is ', StrEnd(S) - S); end.
StrlComp C o m p a r e s t w o strings w i t h o u t c a s e sensitivity.
function StrIComp(Str1, Str2:PChar): Integer; For example:
program Sample; uses Strings, WinCrt; var Result: PChar; S1, S2: array[0..79] of Char; begin Readln(S1); Readln(S2); if Strl_Comp(S1, S2, 8) = 0 then Result := 'equal' else Result := 'not equal'; Writeln('The first eight characters are ', Result); end.
StrLCat A p p e n d s c h a r a c t e r s f r o m o n e string t o t h e e n d o f a n o t h e r s t r i n g a n d r e t u r n s t h e c o n c a t e n a t e d string.
G — T h e Strings U n i t
function StrLCat(Test, Source: PChar; MaxLen: Word): PChar; For example:
program Sample; uses Strings, WinCrt; var S: array[0..9] of Char; begin StrLCopy(S, 'This', SizeOf(S) - 1) StrLCat(S, ', SizeOf(S) - 1); StrLCat(S, 'String , SizeOf(S) - 1); Writeln(S); end. 1
1
StrLComp C o m p a r e s t w o strings, u p to a m a x i m u m length.
function StrLComp(Str1, Str2: PChar; MaxLen: Word): Integer; For example:
program Sample; uses Strings, WinCrt; var Result: PChar; S1, S2: array[0..79] of Char; begin Readln(S1); Readln(S2); if StrLComp(S1, S2, 8) = 0 then Result := 'equal' else Result := 'not equal'; Writeln('The first eight characters are ', Result); end.
545
546
Part III — R e f e r e n c e s
StrLCopy C o p i e s c h a r a c t e r s f r o m o n e string t o a n o t h e r string.
function StrLCopy(Test, Source: PChar; MaxLen: Word): PChar; For example:
program Sample; uses Strings, WinCrt; var S: array[0..9] of Char; begin StrLCopy(S, 'A string', SizeOf(S) - 1); Writeln(S); end.
StrLen R e t u r n s t h e n u m b e r of c h a r a c t e r s i n Str.
function StrLen(Str: PChar): Word; For example:
program Sample; uses Strings, WinCrt; var S: array[0..79] of Char; begin Readln(S); Writeln('String length is ', StrLen(S)); end.
G — T h e Strings U n i t
StrUComp C o m p a r e s t w o s t r i n g s , u p t o a m a x i m u m l e n g t h , w i t h o u t c a s e sensitivity.
function StrLIComp(Str1, Str2: PChar; MaxLen: Word): Integer; For example:
program Sample; uses Strings, WinCrt; var C: Integer; Result: PChar; S1, S2: array[0..79] of Char; begin Readln(S1); Readln(S2); C := StrComp(S1, S2); if C < 0 then Result := ' is less than else if C > 0 then Result := ' is greater than ' else Result := ' is equal to ; Writeln(S1, Result, S2); end. 1
1
StrLower C o n v e r t s a string t o l o w e r c a s e .
function StrLower(Str: PChar): PChar; For example:
program Sample; uses Strings, WinCrt; var S: array[0..79] of Char; begin Readln(S); Writeln(StrUpper(S)); Writeln(StrLower(S)); end.
547
548
Part III — R e f e r e n c e s
StrMove C o p i e s c h a r a c t e r s f r o m o n e string t o a n o t h e r string.
function StrMove(Test,
Source:
PChar; Count: Word):
PChar;
For example:
program Sample; uses Strings, WinCrt; { Allocate a string on the heap } function StrNew(S: PChar): PChar; var L: Word; P: PChar; begin if (S = nil) or (S = #0) then StrNew := nil else begin L := StrLen(S) + 1; GetMem(P, L); StrNew := StrMove(P, S, L); end; end; { Dispose the string allocated on the heap } procedure StrDispose(S: PChar); begin if S <> nil then FreeMem(S, StrLen(S) + 1 ) ; end; A
StrNew A l l o c a t e s a string o n t h e h e a p .
function StrNew(Str: PChar):
PChar;;
StrNew a l l o c a t e s a c o p y o f S t r o n t h e h e a p . If S t r is n i l or p o i n t s t o a n e m p t y string, St rNew r e t u r n s n i l a n d d o e s n o t a l l o c a t e s p a c e o n t h e h e a p f o r t h e string. O t h e r w i s e , StrNew m a k e s a d u p l i c a t e o f S t r , d e t e r m i n i n g t h e s p a c e n e e d e d b y a call t o t h e GetMem s t a n d a r d p r o c e d u r e . It r e t u r n s a p o i n t e r t o t h e d u p l i c a t e d string. T h e a l l o c a t e d s p a c e is S t r L e n ( S t r ) + 1 bytes long.
G — T h e Strings U n i t
For example:
program Sample; uses Strings, WinCrt; function StrNew(S: PChar): PChar; var L: Word; P: PChar; begin if (S = nil) or (S" = #0) then StrNew := nil else begin L := StrLen(S) + 1; GetMem(P, L); StrNew := StrMove(P, S, L); end; end;
StrPas C o n v e r t s a n u l l - t e r m i n a t e d string t o a T u r b o P a s c a l string. F o r e x a m p l e :
program Sample; uses Strings, WinCrt; function StrPas(Str: PChar): PChar; uses Strings, WinCrt; var A: array[0..79] of Char; S: string[79]; begin Readln(A); S := StrPas(A); Writeln(S); end.
549
550
Part III — R e f e r e n c e s
StrPCopy C o p i e s a T u r b o Pascal string t o a n u l l - t e r m i n a t e d string.
function StrPCopy(Test: PChar; Source: String); StrPCopy d o e s n o t c h e c k t h e string l e n g t h . T h e d e s t i n a t i o n b u f f e r m u s t h a v e s p a c e f o r at least Length(Source)
+ 1 c h a r a c t e r s . For e x a m p l e :
program Sample; uses Strings, WinCrt; var A: array[0..79] of Char; S: string[79]; begin Readln(S); StrPCopy(A, S); Writeln(A); end.
StrPos R e t u r n s a p o i n t e r t o t h e first o c c u r r e n c e o f a string i n a n o t h e r string,
function StrPos(Str1, Str2: PChar): PChar; Return
Value:
0 if Str2 d o e s n o t o c c u r i n Str1. F o r e x a m p l e :
program Sample; uses Strings, WinCrt; var P: PChar; S, SubStr: array[0..79] of Char; begin Readln(S); Readln(SubStr);
G — T h e Strings U n i t
P := StrPos(S, SubStr); if P = nil then Writeln('String not found'); else Writeln('String found at index ', P - S); end.
StrRScan R e t u r n s a p o i n t e r t o t h e first o c c u r r e n c e o f a s t r i n g i n a n o t h e r string,
function StrRScan(Str: PChar; Chr: Char): PChar; Return Value: 0 if Chr d o e s n o t o c c u r i n Str. F o r e x a m p l e :
program Sample; uses Strings, WinCrt; {Return a pointer to the name part of a full path name } function NamePart(FileName: PChar): PChar; var P: PChar; begin P := StrRScan(FileName, ' \ ' ) ; if P = nil then begin P := StrRScan(FileName, ' : ' ) ; if P = nil then P := FileName; end; NamePart := P; end;
StrScan R e t u r n s a p o i n t e r t o t h e first o c c u r r e n c e o f a c h a r a c t e r i n a string,
function StrScan(Str: PChar; Chr: Char): PChar;
551
552
Part III — R e f e r e n c e s
Return
Value:
0 if Chr d o e s n o t o c c u r i n Str. F o r e x a m p l e :
program Sample; uses Strings, WinCrt; { Return true if file name has wild cards in it } function HasWildcards(FileName: PChar): Boolean; begin HasWildcards := (StrScan(FileName, '*') <> nil) or (StrScan(FileName, '?') <> nil); end;
StrUpper C o n v e r t s a string t o u p p e r c a s e .
function Strllpper(Str: PChar): PChar; For example:
Program sample; uses Strings, WinCrt; var S: array[0..79] of Char; begin Readln(S); Writeln(StrUpper(S)); Writeln(Strl_ower(S)); end.
H REFERENCE
THE TURBO PASCAL FOR WINDOWS SYSTEM UNIT T h e S y s t e m u n i t ( S Y S T E M . T P U ) is t h e T u r b o Pascal r u n - t i m e library. It i m p l e m e n t s l o w - l e v e l , r u n - t i m e s u p p o r t r o u t i n e s f o r all b u i l t - i n f e a t u r e s , s u c h as file I/O, s t r i n g - h a n d l i n g , f l o a t i n g p o i n t , a n d d y n a m i c m e m o r y a l l o c a t i o n . B e c a u s e all u n i t s a n d p r o g r a m s a u t o m a t i c a l l y u s e t h e S y s t e m u n i t , y o u n e v e r n e e d t o refer t o it i n a Uses c l a u s e . T a b l e H . l lists t h e S y s t e m u n i t ' s v a r i a b l e s a n d c o n s t a n t s . T a b l e H . 2 is a n a l p h a b e t i c a l i n d e x o f all t h e p r o c e d u r e s a n d functions in the System unit. Table
H. 1. System
unit variables Variables
and typed
constants.
(Uninitialized)
Variable
Type
Description
Input
Text
I n p u t s t a n d a r d file
Output
Text
O u t p u t s t a n d a r d file continues
554
Part I I I — R e f e r e n c e s
Table
H.l.
continued Constants
(Initialized
Variables)
Variable
Type
Value
Description
CmdLine
PChar
nil
C o m m a n d line pointer
CmdShow
Integer
0
CmdShow p a r a m e t e r s for CreateWindow
ErrorAddr
Pointer
nil
R u n - t i m e error a d d r e s s
ExitCode
Integer
0
Exit c o d e
ExitProc
Pointer
nil
Exit p r o c e d u r e
FileMode
Byte
2
File o p e n m o d e
HeapBlock
Word
8192
H e a p b l o c k size
HeapError
Word
nil
H e a p error f u n c t i o n
HeapLimit
Word
1024
H e a p s m a l l b l o c k limit
HeapList
Word
0
H e a p s e g m e n t list
HInstance
Word
0
H a n d l e o f this
HPrevInst
Word
0
H a n d l e of previous
instance
instance InOutRes
Integer
0
I/O result
PrefixSeg
Word
0
RandSeed
Lonelnt
0
Program segment prefix (PSP) R a n d o m seed
Table
H.2.
System
procedures
and
buffer
functions.
Procedure/Function
Type
Use
Abs
Func
Returns the absolute value of the argument
Addr
Func
Returns the address of a specified object
Append
Proc
O p e n s a n e x i s t i n g file for appending
ArcTan
Func
Returns the arctangent of the argument
H — T h e T u r b o Pascal for W i n d o w s S y s t e m U n i t
Procedure/Function
Type
Use
Assign
Proc
Assigns the n a m e of an e x t e r n a l file t o a file variable
BlockRead
Proc
Reads o n e or more into a variable
records
BlockWrite
Proc
Writes o n e o r m o r e f r o m a variable
records
Chr
Func
R e t u r n s a character w i t h a specified ordinal n u m b e r
Close
Proc
C l o s e s a n o p e n file
Concat
Func
Concatenates a sequence of strings
Copy
Func
Returns a substring of a string
Cos
Func
Returns the cosine of the a r g u m e n t (x is a n a n g l e , in radians)
CSeg
Func
Returns t h e current value o f the C S
register
Dec
Proc
C l o s e s a n o p e n file
Delete
Proc
Deletes a substring from a string
Dispose
Proc
D i s p o s e s a d y n a m i c variable
DSeg
Func
Returns the current value o f the D S
register
Eof
Func
R e t u r n s t h e e n d - o f - f i l e status
Eoln
Func
Returns the end-of-line status o f a text file
Erase
Proc
Erases a n e x t e r n a l file
Exit
Proc
Exp
Func
Exits immediately from the current b l o c k Returns the exponential of the argument
continues
555
556
Part I I I — R e f e r e n c e s
Table
H.2.
continued
Procedure/Function
Type
FilePos
Func
FileSize
Func
Use R e t u r n s t h e c u r r e n t file p o s i t i o n o f a file R e t u r n s t h e c u r r e n t size o f a file
FillChar
Proc
Fills a s p e c i f i e d n u m b e r (count) o f c o n t i g u o u s bytes with a specified value (can b e type B y t e or C h a r )
Flush
Proc
F l u s h e s t h e b u f f e r o f a text file o p e n f o r o u t p u t
Frac
Func
R e t u r n s t h e fractional part o f the argument
FreeMem
Proc
D i s p o s e s a d y n a m i c variable o f a s p e c i f i e d size
GetDir
Proc
R e t u r n s t h e c u r r e n t directory o f s p e c i f i e d drive
GetMem
Proc
C r e a t e s a d y n a m i c variable of t h e s p e c i f i e d size a n d p u t s t h e a d d r e s s o f t h e b l o c k in a p o i n t e r variable
Halt
Proc
Stops program execution a n d returns system
Hi
Func
to the operating
R e t u r n s t h e high-order
byte
of the argument Inc
Proc
I n c r e m e n t s a variable
Insert
Proc
Inserts a s u b s t r i n g into a string
Int
Func
R e t u r n s t h e integer
part o f
the argument IOResult
Func
R e t u r n s t h e status o f t h e last I/O o p e r a t i o n p e r f o r m e d
Length
Func
Returns the dynamic length o f a string
Ln
Func
Returns the natural logarithm o f t h e a r g u m e n t
H — T h e T u r b o Pascal f o r W i n d o w s S y s t e m U n i t
Procedure/Function
Type
Use
Lo
Func
Returns t h e low-order byte of the argument
MaxAvail
Func
R e t u r n s t h e size o f t h e largest c o n t i g u o u s free b l o c k in t h e heap
MemAvail
Func
R e t u r n s t h e a m o u n t o f all free m e m o r y in t h e
heap
MkDir
Proc
Creates a subdirectory
Move
Proc
C o p i e s bytes f r o m source to destination
New
Proc
Creates a n e w dynamic v a r i a b l e a n d sets a p o i n t e r v a r i a b l e t o p o i n t t o it
Odd
Func
Tests w h e t h e r t h e argument is a n o d d n u m b e r
Ofs
Func
Tests w h e t h e r t h e argument is a n o d d n u m b e r
Ord
Func
Returns the ordinal n u m b e r of an ordinal-type value
ParamCount
Func
Returns the n u m b e r of parameters passed to the program on the command line
ParamStr
Func
Returns a specified command-line parameter
Pi
Func
Returns the value of pi
Pos
Func
S e a r c h e s f o r a s u b s t r i n g in a string
Pred
Func
Returns the predecessor of the argument
Ptr
Func
Converts a segment base and a n offset a d d r e s s t o a pointer-type value
Random
Func
R e t u r n s a random
number continues
557
558
Part I I I — R e f e r e n c e s
Table
H.2.
continued
Procedure/Function
Type
Randomize
Proc
Read
Proc
Use Initializes t h e b u i l t - i n random n u m b e r g e n e r a t o r w i t h a random v a l u e (obtained from the system clock) F o r t y p e d files, reads a file c o m p o n e n t into a variable. F o r text files, reads o n e o r m o r e values into o n e or m o r e variables
Readln
Proc
Executes the Read proced u r e , t h e n skips to the next l i n e o f t h e file
Rename
Proc
R e n a m e s a n e x t e r n a l file
Reset
Proc
O p e n s a n e x i s t i n g file
Rewrite
Proc
C r e a t e s a n d o p e n s a n e w file
Round
Func
R o u n d s a real-type
value to
a n integer-type value RunError
Proc
Halts program execution
ScrollTo
Proc
Scrolls the C R T w i n d o w to s h o w virtual s c r e e n l o c a t i o n
Seek
Proc
Moves the current position o f a file t o a s p e c i f i e d component
SeekEof
Func
R e t u r n s t h e end-of-file status o f a file
SeekEoln
Func
Returns the end-of-line status o f a file
Seg
Func
Returns the segment of a specified object
SetTextBuf
Proc
A s s i g n s a n I/O b u f f e r t o a text file
Sin
Func
Returns the sine of the argument
H — T h e T u r b o Pascal for W i n d o w s S y s t e m U n i t
Procedure/Function
Type
SizeOf
Func
SPtr
Func
Use Returns t h e n u m b e r o f bytes occupied by t h e argument Retruns the current value of the SP
Sqr
Func
register
Returns t h e square of t h e argument
Sqrt
Func
R e t u r n s t h e s q u a r e root
of
the argument SSeg
Func
Returns the current value of t h e S S register
Str
Proc
Converts a numeric value to a string
Succ
Func
Returns the successor of the argument
Swap
Func
S w a p s t h e high- a n d l o w o r d e r bytes o f t h e a r g u m e n t
Trunc
Func
T r u n c a t e s a real-type
value
to an integer-type value Truncate
Proc
T r u n c a t e s t h e file at t h e c u r r e n t file p o s i t i o n
UpCase
Func
Converts a character to uppercase
Val
Proc
C o n v e r t s a s t r i n g v a l u e t o its numeric representation
Write
Proc
F o r t y p e d files, w r i t e s a v a r i a b l e i n t o a file c o m p o n e n t ; f o r text files, w r i t e s o n e or more values to t h e file
Writeln
Proc
Executes the W r i t e procedure, then outputs an endo f - l i n e m a r k e r t o t h e file
559
I REFERENCE
THE
T U R B O PASCAL F O R
WINDOWS WINDOS UNIT
Constants WinDos Constants include the following: • Flag constants • File-mode constants • File-attribute c o n s t a n t s • F i l e - n a m e c o m p o n e n t string l e n g t h s •
F i l e S p l i t r e t u r n flags
Flag Constants T h e F l a g c o n s t a n t s test i n d i v i d u a l flag bits i n t h e F l a g s register after a call t o I n t r o r Ms D o s . T h e y i n c l u d e t h e f o l l o w i n g :
562
Part I I I — R e f e r e n c e s
Constant
Value
fCarry fParity fAuxiliary
$0001 $0004 $0010
fZero fSign fOverflow
$0040 $0080 $0800
File-mode Constants F i l e - h a n d l i n g p r o c e d u r e s u s e f mXXXX c o n s t a n t s w h e n d i s k files a r e o p e n e d and closed. T h e m o d e fields o f T u r b o P a s c a l f o r W i n d o w s ' v a r i a b l e s c o n t a i n o n e o f the following values: Constant
Value
fmClosed
$D7B0
fmlnput
$D7B1
fmOutput
$D7B2
fmlnOut
$D7B3
File-attribute Constants T h e f aXXXX c o n s t a n t s test, set, a n d c l e a r
file-attribute
bits i n c o n j u n c t i o n w i t h
the GetFAttr, SetFAttr, FindFirst, a n d FindNext p r o c e d u r e s . T h e f aXXXX c o n s t a n t s a r e a d d i t i v e . T h e f aAnyFile c o n s t a n t is t h e s u m o f all a t t r i b u t e s . T h e f aXXXX c o n s t a n t s c a n b e a n y o f t h e f o l l o w i n g : Constant
Value
faReadOnly faHidden
$01 $02
faSysFile faVolumelD faDirectory faArchive faAnyFile
$04 $08 $10 $20 $3F
I — T h e T u r b o Pascal for W i n d o w s W i n D o s U n i t
File-name Component String Length Constants T h e f sXXXX c o n s t a n t s a r e t h e m a x i m u m f i l e - n a m e c o m p o n e n t s t r i n g l e n g t h s u s e d b y t h e FileSearch a n d FileExpand f u n c t i o n s . T h e y c a n b e a n y o f t h e following: Constant fsPathName fsDirectory fsFileName fsExtension
Value 79 67 8 4
FileSplit Return Flag Constants T h e FileSplit f u n c t i o n u s e s t h e f cXXXX c o n s t a n t s . T h e r e t u r n e d v a l u e is a c o m b i n a t i o n o f t h e fcDirectory, fcFileName, a n d t h e fcExtension bit masks. T h e value indicates w h i c h c o m p o n e n t s w e r e in the path. If t h e n a m e o r e x t e n s i o n c o n t a i n s a n y w i l d - c a r d c h a r a c t e r s (* o r ? ) , t h e fcWildcards flag is set. P o s s i b l e c o n s t a n t v a l u e s a r e Constant
Value
fcExtension
$0001
fcFileName fcDirectory fcWildcards
$0002 $0004 $0008
Types T y p e s i n t h e WinDos u n i t : • File r e c o r d •
TRegisters
•
TDateTime
•
TSearchRec
File Record Type T h e record definitions u s e d internally b y T u r b o Pascal for W i n d o w s are also d e c l a r e d i n t h e WinDos u n i t .
563
564
Part I I I — R e f e r e n c e s
TFileRecis u s e d f o r b o t h t y p e d a n d u n t y p e d files. TTextRecis u s e d internally file t y p e , text. T h e records
b y a n y variable o f t h e p r e d e f i n e d T u r b o Pascal
l o o k like t h e f o l l o w i n g :
type { Typed and untyped files } TFileRec = record Handle: Word; Mode: Word; RecSize: Word; Private: array[1..26] of Byte; UserData: array[1..16] of Byte; Name: array[0..79] of Char; end;
{ Textfile record } PTextBuf = "TTextBuf; TTextBuf = array[0..127] of Char; TTextRec = record Handle: Word; Mode: Word; BufSize: Word; Private: Word; BufPos: Word; BufEnd: Word; BufPtr: "TTextBuf; OpenFunc: Pointer; InOutFunc: Pointer; FlushFunc: Pointer; CloseFunc: Pointer; UserData: array[1..16] of Byte; Name: array[0..79] of Char; Buffer: TTextBuf; end;
I — T h e T u r b o Pascal f o r W i n d o w s W i n D o s U n i t
TRegisters Type T h e I n t r a n d M s D o s p r o c e d u r e s use variables o f type T R e g i s t e r s to specify the input register contents and e x a m i n e the o u t p u t register contents o f a software interrupt. T R e g i s t e r s looks like this: type T R e g i s t e r s = record c a s e I n t e g e r of 0: ( A X , B X , C X , D X , B P , S I , D I , D S , E S , F l a g s : 1: ( A L , A H , B L , B H , C L , C H , D L , D H : B y t e ) ; end;
Word);
N o t e : A variant record is u s e d to m a p the 8-bit registers o n t o p o f their 16-bit equivalents.
TDateTime Type Variables o f TDateTime type are u s e d with the UnpackTime and PackTime procedures to examine and construct 4-byte, p a c k e d date-and-time values for the G e t F T i m e , S e t F T i m e , F i n d F i r s t , a n d F i n d N e x t procedures. TDateTime looks like the following: type TDateTime = r e c o r d Year,Month,Day,Hour,Min,Sec: end; T h e valid ranges o f its fields are Year Month Day Hour Min Sec
1980..2099 1..12 1..31 0..23 0..59 0..59
Word;
565
566
Part I I I — R e f e r e n c e s
TSearchRec Type T h e FindFirst and FindNext procedures use variables of type TSearchRec to scan directories. TSearchRec looks like the following: type TSearchRec = record Fill: array[1..21] of Byte; Attr: Byte; Time: Longint; Size: Longint; Name: array[0..12] of Char; end; T h e information for each file found by one of these procedures is reported in a TSearchRec. Attr contains the file's attributes (constructed from file-attribute constants). Time contains its packed date and time. Size contains its size in bytes. Name contains its name. Fill is reserved by D O S and should not be modified.
An Index of WinDos Procedures and Functions by Function (or Category) Date and Time Procedures
GetDate GetFTime GetTime PackTime SetDate SetFTime SetTime UnpackTime
procedure procedure procedure procedure procedure procedure procedure procedure
I — T h e T u r b o Pascal for W i n d o w s W i n D o s U n i t
Directory-handling Procedures and Functions CreateDir GetCurDir RemoveDir SetCurDir D i s k status DiskFree DiskSize
procedure function procedure procedure function function function
Environment-handling Functions GetArgCount GetArgStr GetEnvVar
function function function
File-handling P r o c e d u r e s a n d Functions FileExpand function FileSearch function FileSplit
function
FindFirst FindNext GetFAttr SetFAttr
procedure procedure procedure procedure
Interrupt Support Procedures GetlntVec procedure Intr procedure MsDos procedure SetlntVec procedure Miscellaneous Procedures and Functions DosVersion function GetCBreak GetVerify SetCBreak SetVerify
procedure procedure procedure procedure
DosError Variable Dos E r r o r is u s e d b y m a n y o f t h e p r o c e d u r e s a n d f u n c t i o n s i n t h e W i n D o s u n i t t o r e p o r t e r r o r s . It l o o k s like this: var DosError:
Integer;
T h e v a l u e s s t o r e d i n D o s E r r o r are D O S e r r o r c o d e s .
567
568
Part I I I — R e f e r e n c e s
A value o f 0 indicates n o error; o t h e r possible error c o d e s are as follows: Error
Code
Meaning
2
File n o t f o u n d
3 5 6 8 10 11 18
Path n o t f o u n d Access denied Invalid h a n d l e Not enough memory Invalid environment Invalid format N o m o r e files
Date and Time Procedures T u r b o P a s c a l for W i n d o w s s u p p l i e s a c o m p l e t e set o f d a t e a n d t i m e p r o c e d u r e s . These include: GetDate GetFTime GetTime PackTime SetDate SetFTime SetTime UnpackTime
GetDate Returns the current date in the operating system. procedure GetDate(var Year, Month, Day, DayOfWeek: Word);
GetFTime R e t u r n s t h e d a t e a n d t i m e a file w a s last w r i t t e n . procedure GetFTime(var F; var Time: Longint); F m u s t b e a file v a r i a b l e ( t y p e d , u n t y p e d , o r text file) that h a s b e e n a s s i g n e d a n d o p e n e d . T h e t i m e r e t u r n e d i n Time c a n b e u n p a c k e d t h r o u g h a call t o UnpackTime.
I — T h e T u r b o Pascal for W i n d o w s W i n D o s U n i t
GetTime Returns the current time in the operating system,
procedure GetTime(var Hour, Minute, Second, Sec100: Word); For example:
uses WinDos, WinCrt; var H, M, S, Hund : Word; function LeadingZero(W : Word) : String; var S : String; begin Str(W:0,S); if Length(S) = 1 then S := '0' + S; LeadingZero := S; end; begin GetTime(H,M,S,Hund); Writeln('It's ',LeadingZero(H),': , LeadingZero(M), : ,LeadingZero(S), '.',LeadingZero(Hund)); end. 1
1
1
Packlime C o n v e r t s a TDateTime r e c o r d .
procedure PackTime(var T: DateTime; var Time: Longint); C o n v e r t s t h e r e c o r d i n t o a 4-byte, p a c k e d d a t e - a n d - t i m e Longint u s e d b y
SetFTime. F o r e x a m p l e : uses WinDos, WinCrt; var F: text; H, M, S, Hund : Word; { For GetTime} Ftime : Longint; { For Get/SetFTime}
569
570
Part I I I — R e f e r e n c e s
Dt : TDateTime; { For Pack/UnpackTime} function LeadingZero(W : Word) : String; var S : String; begin Str(W:0,S); if Length(S) = 1 then S := '0' + S; LeadingZero := S; end; begin Assign(F, 'File.txt ); GetTime(H,M,S,Hund); Rewrite(F); { Create a new file } GetFTime(F,Ftime); { Get the creation time } Writeln( File created @ ,LeadingZero(H), ': ,LeadingZero(M),':', LeadingZero(S)); UnpackTime(Ftime,Dt); with Dt do begin Writeln( File timestamp = ', LeadingZero(Hour), ' : ' , LeadingZero(Min), : ', LeadingZero(Sec)); Hour := 0; Min := 10; Sec := 0; PackTime(Dt,Ftime); Writeln('Setting file timestamp 'to 12:10 AM'); Reset(F); { Reopen file for reading } { Else close will update time } SetFTime(F,Ftime); end; Close(F); { Close file } end. 1
1
1
1
1
1
SetDate Sets the current date in the operating system,
procedure SetDate(Year, Month, Day: Word); For example:
I — T h e T u r b o Pascal for W i n d o w s W i n D o s U n i t
uses WinDos; begin { Set the system date to 5/8/58 } SetDate(1958,5,8); end.
SetFIime S e t s t h e d a t e a n d t i m e a file w a s last w r i t t e n .
procedure SetFTime(var F; Time: Longint); A n y e r r o r s a r e r e p o r t e d i n DosError. T h e o n l y e r r o r c o d e is 6, a n I n v a l i d File H a n d l e . Note: F m u s t b e o p e n .
SetTime Sets t h e current time in the operating system,
procedure SetTime(Hour, Minute, Second, Sec100: Word); For example:
uses WinDos; begin { Set system clock to 12:01 AM } SetTime(0,1,0,0); end.
Unpackfime C o n v e r t s a Longint t o a r e c o r d .
procedure UnpackTime(Time: Longint; var DT: TDateTime); C o n v e r t s a 4-byte, p a c k e d d a t e - a n d - t i m e Longint r e t u r n e d b y GetFTime,
FindFirst, or FindNext i n t o a n u n p a c k e d DateTime r e c o r d .
Directory-handling Procedures and Functions T u r b o Pascal for W i n d o w s s u p p l i e s a c o m p l e t e set of d i r e c t o r y - h a n d l i n g procedures and functions:
571
572
Part I I I — R e f e r e n c e s
CreateDir GetCurDir RemoveDir SetCurDir DiskFree DiskSize
CreateDir Creates a n e w subdirectory.
procedure CreateDir(Dir: PChar) E x e c u t e s t h e s a m e f u n c t i o n s as MkDir, b u t u s e s a T u r b o Pascal style s t r i n g r a t h e r t h a n a n u l l - t e r m i n a t e d string. F o r e x a m p l e :
uses WinCrt, WinDOS; const Create: PChar = 'C:\MyDir'; CDrive: Byte = 3; begin CreateDir(ADir); Writeln('Creating new directory @ ', ADir,'.'); end.
GetCurDir Returns the current directory o f a specified drive.
function GetCurDir(Dir: PChar; Drive: Byte): PChar; T h e following values represent their respective drives. This p r o c e d u r e c o n t i n u e s u n t i l all drives h a v e a n a m e : 0 = D e f a u l t drive 1 = Drive A 2 = Drive B 3 = Drive C For example:
I — T h e T u r b o Pascal f o r W i n d o w s W i n D o s U n i t
uses WinCrt, WinDOS; const CDrive:Byte = 3; var CurDir: PChar; begin GetMem(CurDir, 80); GetCurDir(CurDir, CDrive); Writeln('Current directory = ', CurDir,'.'); end.
RemoveDir Removes an empty subdirectory,
procedure Remove(Dir: PChar); For example:
uses WinCrt, WinDos; const Remove: PChar = 'C:\01dDir'; CDrive: Byte = 3; begin RemoveDir(ADir); Writeln('Directory removed @ ', ADir,'.'); end.
SetCurDif C h a n g e s the current directory to the specified path,
procedure SetCurDir(Dir: PChar) If Dir s p e c i f i e s a drive letter, t h e d r i v e is a l s o c h a n g e d . F o r e x a m p l e :
uses WinCrt,
573
574
Part III—References
WinDOS; const ChangeTo: PChar = 'C:\'; CDrive: Byte = 3; var CurDir:
PChar;
begin GetMem(CurDir, 80); SetCurDir(ChangeTo); GetCurDir(CurDir, CDrive); Writeln('Current directory = ', CurDir,'.'); end.
DiskFree R e t u r n s t h e n u m b e r of free b y t e s o n a d i s k d r i v e . If t h e d r i v e n u m b e r is i n v a l i d , it r e t u r n s -1; o t h e r w i s e it r e t u r n s t h e n u m b e r of k i l o b y t e s (K) f r e e .
function where 0 1 2 3
= = = =
DiskFree(Drive:
Byte):
Longint;
D e f a u l t drive Drive A Drive B Drive C
and so on. For example:
uses WinDos, WinCrt; begin Writeln(DiskFree(0) end.
div 1024,
' K f r e e ');
DiskSize R e t u r n s t h e total s i z e , i n b y t e s , of s p e c i f i e d d i s k d r i v e ,
function DiskSize(Drive: where
Byte):
Longint;
I — T h e T u r b o Pascal for W i n d o w s W i n D o s U n i t
0 1 2 3
= = = =
575
D e f a u l t drive Drive A Drive B Drive C
a n d s o o n . D i s k S i z e r e t u r n s t h e v a l u e - 1 if t h e d r i v e n u m b e r is i n v a l i d . For example:
uses WinDos, WinCrt; begin Writeln(DiskSize(0) div 1024, K ) ; end. 1
1
Environment-handling Functions T u r b o Pascal f o r W i n d o w s s u p p l i e s a c o m p l e t e set o f e n v i r o n m e n t - h a n d l i n g functions:
GetArgCount GetArgStr GetEnvVar
GetArgCount Returns the n u m b e r of parameters passed to the application by the c o m m a n d line.
function GetArgCount: Integer For e x a m p l e :
uses WinCrt, WinDOS; var ArgCount:
Integer;
begin ArgCount := GetArgCount; Writeln('There were ', ArgCount,' arguments on the command line'); end.
576
Part III—References
GetArgStr Returns the c o m m a n d - l i n e parameter specified by I n d e x . function
GetArgStr(Test:
PChar;
Index:
Integer;
MaxLen: W o r d ) :
T h e return value d e p e n d s o n the parameter: Parameter
Return
Value
I n d e x < 0 or > G e t A r G C o u n t
E m p t y string
Index = 0
File n a m e o f current m o d u l e ; T e s t = returned value
For example: uses WinCrt, WinDos; var ArgN:
PChar;
begin GetMem(ArgN, 2 0 ) ; G e t A r g S t r ( A r g N , 1, 1 9 ) ; W r i t e l n ( ' T h e 1 s t argument was end.
''',
ArgN,
'''.');
GetEnvVar Returns a pointer to the value o f a specified environment variable. function
GetEnvVar(VarName:
PChar):
PChar;
Returns value 0 if the specified environment variable d o e s not exist. For example: uses WinCrt, WinDos; var EnvironVar:
PChar;
begin GetMem(EnvironVar,
255);
PChar
I — T h e T u r b o Pascal f o r W i n d o w s W i n D o s U n i t
EnvironmentVar := GetEnvVar( Path ) ; Writeln('The current path is: '); Writeln(EnvironVar); end. 1
1
File-handling Procedures and Functions T u r b o Pascal f o r W i n d o w s s u p p l i e s a c o m p l e t e set o f f i l e - h a n d l i n g p r o c e d u r e s and functions:
FileExpand FileSearch FileSplit FindFirst FindNext GetFAttr SetFAttr
FileExpand E x p a n d s a file n a m e i n t o a fully q u a l i f i e d file n a m e ,
function FileExpand(Test, Name: PChar): PChar; For example:
uses WinCrt, WinDOS; const MyFile: PChar = 'File.txt'; var Location: PChar; begin GetMem(Location, 80); FileExpand(Location, MyFile); Writeln(MyFile, ' is @ , Location, ' . ' ) ; end. 1
577
578
Part I I I — R e f e r e n c e s
FileSearch S e a r c h e s f o r a file.
function FileSearch(Test, Name, List: PChar): PChar; S e a r c h e s i n a list o f d i r e c t o r i e s (DirList). T h e d i r e c t o r i e s i n DirList must be separated by semicolons. For example:
uses WinCrt, WinDos; var S: array[0..fsPathName] of Char; begin FileSearch(S, 'Turbo.Exe', GetEnvVar('Path ) ) ; if S[0] = #0 then Writeln('Turbo.Exe wasn't found') else Writeln('Found as ', FileExpand(S, S)); end. 1
FileSplit Splits a file n a m e i n t o its t h r e e c o m p o n e n t s ,
function FileSplit(Path, Dir, Name, Ext: PChar): Word; For example:
uses Strings, WinCrt, WinDos; var Path: array[0..fsPathName] of Char; Dir: array[0..fsDirectory] of Char; Name: array[0..fsFileName] of Char; Ext: array[0..fsExtension] of Char; begin Write('Filename (Work.pas): '); Readln(Path); FileSplit(Path, Dir, Name, Ext); if Name[0] = #0 then StrCopy(Name, 'Work');
I — T h e Turbo PascalforWindows WinDos Unit
if Ext[0] = #0 then StrCopy(Ext, '.PAS'); StrECopy(StrECopy(StrECopy(Path, Dir), Name), Ext); Writeln('New name = ', Path); end.
FindFirst Searches the specified directory for the matching file, procedure FindFirst(Path: PChar; Attr: Word; var F: TSearchRec); For example: uses WinDos, WinCrt; var Dirlnfo: TSearchRec; begin FindFirst('*.PAS', Archive, Dirlnfo); while DosError = 0 do begin Writeln(Dirlnfo.Name); FindNext(Dirlnfo); end; end.
FindNext Finds the next entry that matches the n a m e and attributes specified in an earlier call to FindFirst. procedure FindNext(var F: TSearchRec); Errors are reported in DosError. The only possible error code is 18: no more files. For example: uses WinDos, WinCrt; var Dirlnfo: TSearchRec; begin
579
580
Part I I I — R e f e r e n c e s
Fine-First( *.PAS' , Archive, Dirlnfo); while DosError = 0 do begin Writeln(DirInfo.Name); FindNext(Dirlnfo); end; end. 1
GetFAttr R e t u r n s t h e attributes o f a file.
procedure GetFAttr(var F; var Attr: Word); F m u s t b e a file v a r i a b l e ( t y p e d , u n t y p e d , o r text file) that h a s b e e n assigned but has not b e e n o p e n e d . For example:
uses WinDos, WinCrt; var F: file; Attr: Word; begin { Get file name from command line } Assign(F, ParamStr(1)); GetFAttr(F, Attr); Writeln(ParamStr(1)); if DosError <> 0 then Writeln('DOS error code = ', DosError) else begin Write('Attribute = ', Attr); { Determine file attribute type using the flags in the WinDos unit } if Attr and faReadOnly <> 0 then Writeln( Read only file'); if Attr and faHidden <> 0 then Writeln('Hidden file'); if Attr and faSysFile <> 0 then Writeln('System file'); if Attr and faVolumelD <> 0 then Writeln('Volume ID'); if Attr and faDirectory <> 0 then Writeln( Directory name'); if Attr and faArchive <> 0 then Writeln('Archive (normal f i l e ) ) ; end; { else } end. 1
1
1
I — T h e T u r b o Pascal f o r W i n d o w s W i n D o s U n i t
SetFAttr S e t s t h e a t t r i b u t e s o f a file.
procedure SetFAttr(var F; Attr: Word); E r r o r s are r e p o r t e d i n DosError. T h e p o s s i b l e e r r o r c o d e s a r e : 3
(Invalid path)
5
(File a c c e s s d e n i e d )
Note:
T h e file c a n n o t b e o p e n . F o r e x a m p l e :
uses WinDos; var F: file; begin Assign(F, 'C:\Myfile.txt'); SetFAttr(F, faHidden); Readln; SetFAttr(F, faArchive); end.
Interrupt Support Procedures T u r b o P a s c a l f o r W i n d o w s s u p p l i e s a c o m p l e t e set o f i n t e r r u p t procedures:
GetlntVec Intr MsDos SetlntVec
GetlntVec Returns the address stored in a specified interrupt vector,
procedure GetIntVec(IntNo: Byte; var Vector: Pointer);
support
581
582
Part III—References
For example: uses WinDos, WinCrt; var Int1 : Pointer; {$F+} procedure TimerHandler; interrupt; begin { Timer ISR } end; {$F-} begin GetIntVec($1C,Int1); SetIntVec($1C,Addr(TimerHandler)); Writeln( Press a key to e x i t ) ; repeat until Keypressed; SetIntVec($01C,Int1); end. 1
1
Intr Executes a specified software interrupt. procedure Intr(IntNo: Byte; var Regs: TRegisters); where IntNo is the software interrupt n u m b e r (0...255). TRegisters is a record defined in D O S .
N o t e : D o not use software interrupts that 1. D e p e n d o n specific values in SP or SS for entry 2. Modify SP or SS o n exit.
For example: uses WinCrt, WinDos; var
I — T h e T u r b o Pascal for W i n d o w s W i n D o s U n i t
Date, Year, Month, Day : String; Regs : TRegisters; begin Regs.ah := $2a; with Regs do intr($21,Regs); with Regs do begin Str(cx,Year); Str(dh,Month); Str(dl,Day); end; Date := Month+'/'+Day+'/'+Year; writeln('Date = ', Date); end.
MsDos Executes a D O S function call.
procedure MsDos(var Regs: TRegisters); R e m e m b e r n o t t o u s e s o f t w a r e i n t e r r u p t s that e i t h e r d e p e n d o n s p e c i f i c v a l u e s i n SP or SS for e n t r y or that m o d i f y SP or SS o n exit. For e x a m p l e :
uses WinCrt, WinDos; var Date, Year, Month, Day : String; Regs : TRegisters; begin Regs.ah := $2a; with Regs do msdos(Regs); with Regs do
583
584
Part I I I — R e f e r e n c e s
begin Str(cx,Year); Str(dh,Month); Str(dl,Day); end; Date := Month+'/'+Day+'/'+Year; Writeln('Date = , Date); end. 1
SetlntVec Sets a specified interrupt vector to a specified address,
procedure SetIntVec(IntNo: Byte; Vector: Pointer);
Miscellaneous Procedures and Functions T u r b o P a s c a l f o r W i n d o w s s u p p l i e s several m i s c e l l a n e o u s p r o c e d u r e s a n d functions:
DosVersion GetCBreak GetVerify SetCBreak SetVerify
DosVersion Returns the D O S version number.
function DosVersion: Word; T h e r e s u l t ' s l o w b y t e is t h e m a j o r v e r s i o n n u m b e r , a n d t h e h i g h b y t e is the minor version number. For example:
uses WinDos; var Ver: Word; begin Ver := DosVersion; Writeln('DOS version = ', Lo(Ver), '.', Hi(Ver)); end.
I — T h e T u r b o Pascal for W i n d o w s W i n D o s U n i t
GetCBreak R e t u r n s t h e state of Ctrl-Break c h e c k i n g i n D O S .
procedure GetCBreak(var Break: Boolean); For e x a m p l e :
uses WinDos, WinCrt; const OffOn ('off
: array [Boolean] of String[3] = Von');
var cb : Boolean; begin GetCBreak(cb); Writeln('Control-Break checking is ', OffOn[cb]); cb := not(cb); Writeln('Turning Control-Break checking ', 0ff0n[cb]); SetCBreak(cb); end.
GetVerify R e t u r n s t h e state of t h e verify flag i n D O S .
procedure GetVerify(var Verify: Boolean); For e x a m p l e :
uses WinDos, WinCrt; const OffOn : array [Boolean] of String[3] = var Boo : Boolean;
( off','on ) ; 1
1
585
586
Part I I I — R e f e r e n c e s
begin GetVerify(Boo); Writeln('Write verify = OffOn[Boo]); Boo := not(Boo); Writeln('Turning write verify ', OffOn[Boo]); SetVerify(Boo); end.
SetCBreak S e t s t h e state o f C t r l - B r e a k c h e c k i n g i n D O S .
procedure SetCBreak(Break: Boolean);
SetVerify S e t s t h e state o f t h e verify flag i n D O S .
procedure SetVerify(Verify: Boolean);
J
REFERENCE
DEBUGGING TURBO PASCAL FOR WINDOWS
APPUGfflONS
T h e T u r b o P a s c a l f o r W i n d o w s D e b u g g e r is a p o w e r f u l t o o l f o r d e b u g g i n g W i n d o w s a p p l i c a t i o n s . It g o e s a m a j o r s t e p o r t w o f u r t h e r t h a n t h e b u i l t - i n d e b u g g i n g c a p a b i l i t i e s o f t h e T u r b o Pascal f o r W i n d o w s c o m p i l e r . T h e T u r b o Pascal f o r W i n d o w s c o m p i l e r ' s b u g - d e t e c t i n g p o w e r f o c u s e s o n m a k i n g s u r e that y o u r a p p l i c a t i o n c o d e m a k e s syntactic s e n s e . If y o u h a v e a n u n k n o w n i d e n t i f i e r o r h a v e o m i t t e d a n e c e s s a r y s e m i c o l o n , it'll f i n d it. B u t it c a n n o t g u a r a n t e e m o r e t h a n c o r r e c t syntax. Y o u r c o d e c a n survive c o m p i l e r b u g d e t e c t i o n a n d still c r a s h m i s e r a b l y (at r u n - t i m e ) . R u n - t i m e e r r o r s are t h e d o m a i n o f a n o t h e r class o f b u g d e t e c t o r s , " d e b u g g e r s . " D e b u g g e r s h e l p y o u i s o l a t e a n d c o r r e c t m i s t a k e s that u s u a l l y are n o t d u e t o e r r o r s i n s y n t a x . T h i s is a b r o a d a n d c o m p l e x g r o u p o f e r r o r s that y o u c a n m a k e i n t h e l o g i c o f y o u r c o d e , b y n o t a c c o u n t i n g f o r t h e full r a n g e o f p o s s i b l e a c t i o n s o f y o u r c o d e , a n d s o o n . D e b u g g i n g , i n this r e a l m , is a n i m p e r f e c t "art" at b e s t , a n d d e b u g g i n g W i n d o w s a p p l i c a t i o n s is m o r e i m p e r f e c t yet. T h e k e y , I t h i n k , t o d e b u g g i n g W i n d o w s a p p l i c a t i o n s lies i n i s o l a t i n g t h e m o r e likely e r r o r - p r o n e areas o f y o u r c o d e .
588
Part I I I — R e f e r e n c e s
A f e w s i m p l e d e v e l o p m e n t tactics w i l l h e l p : 1. C o d e i n s m a l l f r a g m e n t s . U s e o b j e c t - o r i e n t e d t e c h n i q u e s t o k e e p d a t a a n d the behavior for manipulating data in objects. 2. D e v e l o p o b j e c t s , u n i t s , o r o t h e r s t r u c t u r a l b l o c k s o n e at a t i m e . M a k e s u r e that a n o b j e c t o r a b l o c k w o r k s b e f o r e m o v i n g o n t o o t h e r o b j e c t s o r b l o c k s , p a r t i c u l a r l y if t h e s e o b j e c t s a n d b l o c k s are i n t e r r e l a t e d . 3. R e d u c e t h e n u m b e r o f p r o c e d u r e s , f u n c t i o n s , a n d s o o n that c a n m a n i p u l a t e d a t a . If y o u d o n ' t u s e o b j e c t s , u s e l o c a l v a r i a b l e s . T h e s e tactics w i l l h e l p , b u t t h e y p r o b a b l y w o n ' t e l i m i n a t e all y o u r b u g s . W h e n y o u d i s c o v e r a b u g i n y o u r W i n d o w s a p p l i c a t i o n , call o n T u r b o D e b u g g e r f o r W i n d o w s . I n effect, it s l o w s d o w n t h e e x e c u t i o n o f a n a p p l i c a t i o n a n d lets y o u e x a m i n e its s p e c i f i c a s p e c t s . Y o u c a n e x a m i n e t h e stack, v a r i a b l e v a l u e s , C P U registers, W i n d o w s messages, a n d so o n . T u r b o D e b u g g e r gives y o u seven m a i n ways to explore: 1. T r a c i n g ( e x e c u t i n g a n a p p l i c a t i o n o n e l i n e at a t i m e ) . 2. B a c k t r a c i n g ( s t e p p i n g b a c k w a r d t h r o u g h t h e a p p l i c a t i o n c o d e a l i n e at a time, a n d reversing the e x e c u t i o n ) . 3. S t e p p i n g ( e x e c u t i n g t h e a p p l i c a t i o n c o d e o n e l i n e at a t i m e b u t " s t e p p i n g o v e r " a n y calls t o p r o c e d u r e s o r f u n c t i o n s ) . T h i s w a y , t h e p r o c e d u r e o r f u n c t i o n is e x e c u t e d as a b l o c k a n d a n y v a l u e s are returned, but y o u don't "trace" through the procedure or function a l i n e at a t i m e . 4. V i e w i n g ( o p e n i n g a w i n d o w f o r v i e w i n g t h e states o f v a r i o u s c o m p o n e n t s o f t h e a p p l i c a t i o n ) . T h e s e c o m p o n e n t s are t h e a p p l i c a t i o n ' s v a r i a b l e s , b r e a k p o i n t s y o u set, t h e stack, a T u r b o D e b u g g e r l o g , a d a t a file, a s o u r c e file, C P U c o d e , m e m o r y , registers, n u m e r i c p r o c e s s o r i n f o r m a t i o n , o b j e c t h i e r a r c h i e s , t h e a p p l i c a t i o n ' s e x e c u t i o n history, and the application's output. 5. I n s p e c t i n g d a t a s t r u c t u r e s ( s u c h as arrays). 6. C h a n g i n g ( m a n i p u l a t i n g t h e a p p l i c a t i o n b y r e p l a c i n g t h e c u r r e n t v a l u e o f a v a r i a b l e w i t h a n e w v a l u e that y o u s p e c i f y ) . 7. W a t c h i n g a p p l i c a t i o n v a r i a b l e s ( t r a c k i n g t h e c h a n g i n g v a l u e s o f variables y o u specify). A l l t h e T u r b o D e b u g g e r f o r W i n d o w s f e a t u r e s are available i n p u l l - d o w n menus. T h e s i m p l e s t w a y t o u s e T u r b o D e b u g g e r f o r W i n d o w s is l o a d t h e application y o u w a n t to d e b u g into a T u r b o Pascal for W i n d o w s edit w i n d o w , a n d t h e n select D e b u g g e r f r o m t h e T u r b o Pascal f o r W i n d o w s R u n / D e b u g g e r
J — D e b u g g i n g T u r b o Pascal f o r W i n d o w s A p p l i c a t i o n s
m e n u . M a k e s u r e , t h o u g h , that y o u select O p t i o n s / L i n k e r / D e b u g i n f o i n E X E before you run Turbo Debugger. T h e specifics o f h o w y o u d e b u g y o u r application d e p e n d o n the k i n d o f application a n d possible error. In general, y o u d o n ' t want to trace t h r o u g h a n e n t i r e W i n d o w s a p p l i c a t i o n . I n s t e a d , try t o i s o l a t e t h e e r r o r as b e s t y o u c a n a n d set b r e a k p o i n t s i n likely t r o u b l e d a r e a s . (I k n o w , I k n o w ; if y o u k n o w w h e r e t h e e r r o r is, y o u p r o b a b l y d o n ' t n e e d t h e d e b u g g e r — y e s a n d n o . ) If y o u ' r e d e v e l o p i n g t h e a p p l i c a t i o n o b j e c t b y o b j e c t o r b l o c k b y b l o c k , y o u c a n at least r e d u c e t h e b u g t o that a r e a . Set a b r e a k p o i n t a n d t h e n trace t h r o u g h t h e application from the breakpoint. I n m a n y s i t u a t i o n s , m a k i n g s u r e that a p r o c e d u r e , f u n c t i o n , o r m e t h o d g e t s c a l l e d , o r m o n i t o r i n g a v a r i a b l e ' s v a l u e s , c a n l o c a t e t h e b u g . I u s u a l l y start any d e b u g session by setting breakpoints a n d a d d i n g the variables within those b r e a k p o i n t s u s i n g A d d W a t c h . T h e n I s t e p o r trace t h r o u g h t h e c o d e . If y o u g e t a r u n - t i m e e r r o r that typically l o o k s like t h i s :
Runtime error 204 at 0002:018 n o t e t h e a d d r e s s ( y o u p r o b a b l y w i l l w a n t t o w r i t e it d o w n ) , a n d u s e t h e F i n d Error c o m m a n d o n the T u r b o Pascal for W i n d o w s Search m e n u to locate the error in your source c o d e . T h e Find Error dialog b o x appears. Enter the address o f the error in the Error Address b o x . T u r b o Pascal for W i n d o w s t h e n r e c o m p i l e s y o u r c o d e a n d s t o p s w h e n it r e a c h e s t h e a d d r e s s y o u specify, h i g h l i g h t i n g t h e s t a t e m e n t that caused the error. T h e n , fix t h e e r r o r (in t h e edit w i n d o w ) a n d r e c o m p i l e . R e p e a t t h e p r o c e s s if y o u h a v e t o .
589
K REFERENCE
TURBO PASCAL FOR WINDOWS ERROR MESSAGES T u r b o Pascal f o r W i n d o w s g e n e r a t e s t w o k i n d s o f e r r o r m e s s a g e s : c o m p i l e r error messages and run-time error messages. If y o u ' r e u s i n g t h e I D E t o c o m p i l e y o u r s o u r c e c o d e a n d a c o m p i l e r e r r o r o c c u r s , T u r b o Pascal f o r W i n d o w s m a k e s t h e E d i t w i n d o w active a n d m o v e s t h e c u r s o r t o t h e l o c a t i o n w h e r e it d e t e c t e d t h e e r r o r i n y o u r s o u r c e c o d e . If t h e e r r o r o c c u r s w h e n y o u ' r e u s i n g t h e c o m m a n d - l i n e c o m p i l e r , T u r b o Pascal for W i n d o w s displays the error message a n d n u m b e r a n d the o f f e n d i n g s o u r c e l i n e . A caret ( ^ ) i n t h e d i s p l a y e d s o u r c e l i n e i n d i c a t e s t h e error's location. If y o u r a p p l i c a t i o n g e n e r a t e s a n e r r o r at r u n - t i m e , it w i l l t e r m i n a t e , a n d t h e f o l l o w i n g m e s s a g e is d i s p l a y e d :
Runtime error at < x x x x : y y y y > where: • nurn is t h e r u n - t i m e e r r o r n u m b e r •
x x x x : y y y y i s the run-time error address
592
Part I I I — R e f e r e n c e s
Compiler Error Messages C o m p i l e r e r r o r m e s s a g e s are n u m b e r e d f r o m 1 t o 168. T h e f o l l o w i n g e r r o r m e s s a g e s are c u r r e n t l y i m p l e m e n t e d i n T u r b o Pascal f o r W i n d o w s 1.0.
N o t e : N o t all n u m b e r s h a v e a c o r r e s p o n d i n g e r r o r m e s s a g e .
Error
Number
Error
Message
1
Out of memory
2
Identifier e x p e c t e d
3
U n k n o w n identifier
4
D u p l i c a t e identifier
5
Syntax error
6
E r r o r i n real c o n s t a n t
7
Error in integer constant
8
String constant exceeds line
9
T o o m a n y n e s t e d files
10
U n e x p e c t e d e n d o f file
11
Line t o o l o n g
12
T y p e identifier e x p e c t e d
13
T o o m a n y o p e n files
14
I n v a l i d file n a m e
15
File n o t f o u n d
16
D i s k full
17
Invalid c o m p i l e r directive
18
T o o m a n y files
19
U n d e f i n e d type in pointer definition
20
Variable identifier e x p e c t e d
21
Error in type
22
Structure t o o large
K — T u r b o Pascal for W i n d o w s Error M e s s a g e s
Error
Number
Error
Message
23
Set base type out of range
24
F i l e c o m p o n e n t s m a y n o t b e files o r o b j e c t s
25
I n v a l i d string l e n g t h
26
Type mismatch
27
Invalid subrange base type
28
Lower b o u n d > than upper b o u n d
29
Ordinal type expected
30
Integer constant expected
31
Constant expected
32
I n t e g e r o r real c o n s t a n t e x p e c t e d
33
Pointer type identifier e x p e c t e d
34
I n v a l i d f u n c t i o n result t y p e
35
Label identifier e x p e c t e d
36
B E G I N expected
37
E N D expected
38
Integer expression expected
39
Ordinal expression expected
40
Boolean expression expected
41
O p e r a n d types d o not match operator
42
Error in expression
43
Illegal assignment
44
Field identifier e x p e c t e d
45
O b j e c t file t o o l a r g e
46
Undefined external
47
I n v a l i d o b j e c t file r e c o r d
48
C o d e segment t o o large
49
D a t a s e g m e n t t o o large
50
D O expected continues
593
594
Part I I I — R e f e r e n c e s
Error
Number
Error
Message
51
Invalid P U B L I C definition
52
Invalid E X T R N definition
53
T o o many E X T R N definitions
54
O F expected
55
INTERFACE expected
56
Invalid relocatable reference
57
T H E N expected
58
T O or D O W N T O expected
59
Undefined forward
61
Invalid typecast
62
Division by zero
63
I n v a l i d file t y p e
64
C a n n o t r e a d o r w r i t e v a r i a b l e s o f this t y p e
65
Pointer variable e x p e c t e d
66
String variable e x p e c t e d
67
String expression e x p e c t e d
68
Circular unit reference
69
Unit n a m e mismatch
70
Unit version mismatch
72
U n i t file f o r m a t e r r o r
73
IMPLEMENTATION expected
74
C o n s t a n t a n d case types don't m a t c h
75
R e c o r d variable e x p e c t e d
76
Constant out of range
77
File v a r i a b l e e x p e c t e d
78
Pointer expression expected
79
I n t e g e r o r real e x p r e s s i o n e x p e c t e d
80
Label not within current block
81
Label already defined
K — T u r b o Pascal for W i n d o w s Error M e s s a g e s
Error
Number
Error
Message
82
U n d e f i n e d l a b e l i n p r e c e d i n g s t a t e m e n t part
83
Invalid @ argument
84
UNIT expected
85
";" e x p e c t e d
86
":" e x p e c t e d
87
"," expected
88
"(" expected
89
" ) " expected
90
" = " expected
91
" : = " expected
92
"[" or "(." expected
93
" ] " or " . ) " expected
94
"." expected
95
expected
96
T o o m a n y variables
97
Invalid F O R control variable
98
Integer variable e x p e c t e d
99
File a n d p r o c e d u r e t y p e s are n o t a l l o w e d h e r e
100
String length mismatch
101
I n v a l i d o r d e r i n g o f fields
102
String constant expected
103
I n t e g e r o r real v a r i a b l e e x p e c t e d
104
O r d i n a l variable e x p e c t e d
105
I N L I N E error
106
Character expression expected
112
C A S E constant out of
113
Error in statement
114
C a n n o t call a n i n t e r r u p t p r o c e d u r e
range
continues
595
596
Part I I I — R e f e r e n c e s
Error
Number
Error
Message
116
Must be in 8087 m o d e to compile
117
Target address not f o u n d
118
I n c l u d e files are n o t a l l o w e d h e r e
120
NIL expected
121
Invalid qualifier
122
Invalid variable reference
123
T o o many symbols
124
S t a t e m e n t part t o o l a r g e
126
Files m u s t b e v a r p a r a m e t e r s
127
T o o many conditional symbols
128
M i s p l a c e d conditional directive
129
E N D I F directive missing
130
E r r o r i n initial c o n d i t i o n a l d e f i n e s
131
H e a d e r does not match previous definition
132
Critical disk error
133
C a n n o t e v a l u a t e this e x p r e s s i o n
136
Invalid indirect reference
137
S t r u c t u r e d v a r i a b l e s are n o t a l l o w e d h e r e
140
Invalid
142
Procedure or function variable e x p e c t e d
143
Invalid p r o c e d u r e or function reference
146
File a c c e s s d e n i e d
147
Object type e x p e c t e d
148
L o c a l o b j e c t t y p e s are n o t a l l o w e d
149
VIRTUAL expected
150
M e t h o d identifier e x p e c t e d
151
V i r t u a l c o n s t r u c t o r s are n o t a l l o w e d
152
C o n s t r u c t o r identifier e x p e c t e d
floating-point
operation
K — T u r b o Pascal f o r W i n d o w s Error M e s s a g e s
Error
Number
Error
Message
153
Destructor identifier e x p e c t e d
154
Fail o n l y a l l o w e d w i t h i n c o n s t r u c t o r s
155
Invalid c o m b i n a t i o n o f o p c o d e a n d operands
156
M e m o r y reference expected
157
C a n n o t a d d o r subtract relocatable symbols
158
Invalid register c o m b i n a t i o n
159
286/287 i n s t r u c t i o n s are n o t e n a b l e d
160
Invalid symbol reference
161
C o d e generation error
162
ASM expected
163
Duplicate dynamic method index
164
D u p l i c a t e resource identifier
165
Duplicate or invalid export i n d e x
166
Procedure or function identifier e x p e c t e d
167
C a n n o t e x p o r t this s y m b o l
168
Duplicate export name
T h e following section provides m o r e detailed explanations of the compiler e r r o r m e s s a g e s . W h e n p o s s i b l e , s u g g e s t i o n s f o r c o r r e c t i n g t h e e r r o r s are supplied.
Compiler error 1: Out of memory This error occurs w h e n the compiler runs out o f m e m o r y . T o s o l v e this p r o b l e m , y o u m i g h t : • T r y t o i n c r e a s e t h e a m o u n t o f available m e m o r y i n W i n d o w s . • Set O p t i o n s / L i n k e r / L i n k b u f f e r t o d i s k . • If y o u ' r e n o t u s i n g t h e I D E a n d are u s i n g t h e c o m m a n d - l i n e c o m p i l e r , u s e t h e /L o p t i o n t o p l a c e t h e l i n k b u f f e r o n d i s k . If n o n e o f t h e s e s o l u t i o n s h e l p s , y o u r a p p l i c a t i o n (or u n i t ) m i g h t b e t o o l a r g e t o c o m p i l e i n t h e a m o u n t o f m e m o r y available o n y o u r s y s t e m . T r y d i v i d i n g t h e a p p l i c a t i o n o r u n i t that w o n ' t c o m p i l e i n t o t w o o r m o r e s m a l l e r units.
597
598
Part I I I — R e f e r e n c e s
Compiler error 2: Identifier expected T h e c o m p i l e r e x p e c t e d a n i d e n t i f i e r at this p o i n t . O n e p o s s i b i l i t y is that y o u ' r e trying t o r e d e c l a r e a r e s e r v e d w o r d . A n o t h e r p o s s i b i l i t y is t h e e x i s t e n c e o f misplaced syntax p r e c e d i n g the location o f the error.
Compiler error 3: Unknown identifier M o s t likely, this i d e n t i f i e r h a s n ' t b e e n d e c l a r e d o r isn't visible w i t h i n t h e c u r r e n t scope.
Compiler error 4: Duplicate identifier T h e i d e n t i f i e r is a l r e a d y b e i n g u s e d w i t h i n t h e c u r r e n t b l o c k . Y o u ' r e e i t h e r actually duplicating the identifier or possibly misspelling o n e o f the duplicated identifiers.
Compiler error 5: Syntax error T h e c o m p i l e r d e t e c t e d a n illegal c h a r a c t e r .
Compiler error 6: Error in real constant Y o u s h o u l d specify a real c o n s t a n t i n t h e f o l l o w i n g f o r m : const RealConst
= 3.5688855;
Compiler error 7: Error in integer constant Y o u s h o u l d specify a n i n t e g e r c o n s t a n t i n t h e f o l l o w i n g f o r m : const IntConst
= 380;
N o t e : Whole
real n u m b e r s greater t h a n t h e m a x i m u m
integer
allowed must be followed by a decimal point and a zero. For example: 84,245,567,797.0
K — T u r b o Pascal f o r W i n d o w s Error M e s s a g e s
Compiler error 8: String constant exceeds line Y o u p o s s i b l y o m i t t e d t h e c l o s i n g q u o t e i n a string c o n s t a n t o r m i s t y p e d it.
Compiler error 9: Too many nested files T h e c o m p i l e r p e r m i t s a m a x i m u m o f 15 n e s t e d s o u r c e - c o d e files. O n e p o s s i b i l e s o u r c e o f e r r o r is a n e x c e s s i v e n u m b e r o f n e s t e d I n c l u d e files.
Compiler error 10: Unexpected end of file T h i s e r r o r is g e n e r a t e d w h e n : • Y o u r s o u r c e c o d e file e n d s b e f o r e t h e final End o f t h e m a i n s t a t e m e n t part. I n this c a s e , t h e begins a n d ends a r e p r o b a b l y u n b a l a n c e d . • A n I n c l u d e file e n d s i n t h e m i d d l e o f a s t a t e m e n t part. E v e r y s t a t e m e n t part m u s t b e c o n t a i n e d i n o n e file. • Y o u didn't close a c o m m e n t .
Compiler error 11: line too long T h e m a x i m u m l e n g t h o f a l i n e is 126 c h a r a c t e r s .
Compiler error 12: Type identifier expected T h e identifier doesn't d e n o t e a type correctly.
Compiler error 13: Too many open files T h i s e r r o r u s u a l l y m e a n s that: 1. Y o u h a v e n ' t s p e c i f i e d a FILES n u m b e r i n y o u r C O N F I G . S Y S
file.
2. Y o u h a v e s p e c i f i e d t o o f e w files i n y o u r C O N F I G . S Y S . I n c r e a s e t h e n u m b e r o f files i n y o u r C O N F I G . S Y S t o 20 o r m o r e u s i n g t h e FILES s t a t e m e n t :
FILES = 30;
599
600
Part I I I — R e f e r e n c e s
Compiler error 14: Invalidfilename T h e file n a m e is i n v a l i d o r s p e c i f i e s a n o n e x i s t e n t p a t h .
Compiler error 15: File not found T h e file c o u l d n ' t b e l o c a t e d i n t h e c u r r e n t d i r e c t o r y o r i n a n y o f t h e s e a r c h directories you've specified in the Directories path.
Compiler error 16: Disk fidl D e l e t e files, u s e a n e w d i s k , a n d s o o n , t o free u p s o m e a d d i t i o n a l d i s k s p a c e .
Compiler error 17: Invalid compiler directive U s u a l l y , o n e o f t h e f o l l o w i n g p r o b l e m s exists: • T h e c o m p i l e r d i r e c t i v e letter is u n k n o w n . • O n e o f t h e c o m p i l e r - d i r e c t i v e p a r a m e t e r s is i n v a l i d . • Y o u ' r e u s i n g a global c o m p i l e r directive w h e n c o m p i l a t i o n o f the application's main b o d y has b e g u n .
Compiler error 18: Too many files Y o u ' r e u s i n g t o o m a n y files w h e n y o u c o m p i l e t h e p r o g r a m o r u n i t . O n e s o l u t i o n is t o c o m b i n e I n c l u d e files o r u n i t s .
Compiler error 19: Undefined type in pointer definition W h e n y o u d e c l a r e d t h e p o i n t e r t y p e , y o u r e f e r e n c e d a t y p e that h a s n ' t b e e n declared.
Compiler error 20: Variable identifier expected T h e identifier doesn't d e n o t e a variable correctly.
Compiler error 21: Error in type T h e s y m b o l y o u ' r e u s i n g c a n n o t b e g i n a type d e f i n i t i o n .
K — T u r b o Pascal for W i n d o w s Error M e s s a g e s
Compiler error 22: Structure too large I n T u r b o P a s c a l for W i n d o w s , s t r u c t u r e d t y p e s m u s t b e n o l a r g e r t h a n 6 5 5 2 0 bytes (64K).
Compiler error 23: Set base type out of range T h e b a s e t y p e o f a set m u s t b e a s u b r a n g e b e t w e e n 0 a n d 2 5 5 o r a n e n u m e r a t e d type with fewer than 257 possible values.
Compiler error 24: File components may not be files or objects T h e c o m p o n e n t t y p e o f a file t y p e c a n n o t b e a n o b j e c t t y p e o r a file t y p e , n o r c a n it b e a n y s t r u c t u r e d t y p e w i t h i n a n o b j e c t t y p e o r file t y p e .
Compiler error 25: Invalid string length T h e m a x i m u m l e n g t h o f a string m u s t b e i n t h e r a n g e 1 . . 2 5 5 .
Compiler error 26: Type mismatch U s u a l l y , this e r r o r r e s u l t s f r o m o n e o f t h e
following:
• I n c o m p a t i b l e types o f the variable a n d the expression in a n assignment statement. • I n c o m p a t i b l e t y p e s o f t h e a c t u a l a n d f o r m a l p a r a m e t e r i n a call t o a procedure or function. • A n e x p r e s s i o n t y p e that's i n c o m p a t i b l e w i t h t h e i n d e x t y p e i n array indexing. • Incompatible types o f o p e r a n d s in an expression.
Compiler error 27: Invalid subrange base type O r d i n a l t y p e s are t h e o n l y v a l i d b a s e t y p e s .
601
602
Part I I I — R e f e r e n c e s
Compiler error 28: Lower bound > than upper bound W h e n y o u declared the subrange type, y o u specified a lower b o u n d greater than the u p p e r b o u n d .
Compiler error 29: Ordinal type expected P o i n t e r , r e a l , string, a n d s t r u c t u r e d t y p e s a r e n ' t a l l o w e d i n this s i t u a t i o n .
Compiler error 30: Integer constant expected O n l y a n i n t e g e r c o n s t a n t is p e r m i t t e d i n this s i t u a t i o n .
Compiler error 31: Constant expected O n l y a c o n s t a n t is p e r m i t t e d i n this s i t u a t i o n .
Compiler error 32: Integer or real constant expected O n l y a n u m e r i c c o n s t a n t is p e r m i t t e d i n this s i t u a t i o n .
Compiler error 33: Pointer type identifier expected T h e identifier doesn't d e n o t e a type properly.
Compiler error 34: Invalid Junction result type V a l i d f u n c t i o n result t y p e s c a n b e o n l y s i m p l e t y p e s , string t y p e s , a n d p o i n t e r types.
Compiler error 35: Label identifier expected T h e identifier doesn't d e n o t e a label properly.
Compiler error 36: BEGIN expected A b e g i n w a s e x p e c t e d at this p o i n t , o r t h e r e ' s a n e r r o r i n t h e b l o c k s t r u c t u r e o f the unit or program.
K — T u r b o PascalforWindows Error Messages
Begin
End T h e begin. . .end b l o c k c o n s t i t u t e s a c o n s t r u c t , w h i c h is a c o m p o u n d s t a t e m e n t . T h e begin a n d end reserved w o r d s act as s t a t e m e n t b r a c k e t s . For example:
{ Compound statement used within an "if" statement } if First < Last then begin Temp := First; First := Last; Last := Temp; end;
Compiler error 37: END expected A n end was expected here, or there's an error in the block structure of the unit or program. Use end with: • begin to form c o m p o u n d statements • case to form case statements • record to declare record types • obj ect to declare object types • asm to call the inline assembler For example: { with "begin" to form compound statement } if First < Last then begin Temp := First; First := Last; Last := Temp; end; { with "case" statement }
603
604
Part III—References
case Ch of 'A'.-'Z , 'a'.-'z': WriteLn('Letter'); '0'..'9': WriteLn('Digit'); ' + ', '-', '*', '/': WriteLn('Operator'); else WriteLn('Special character'); end; 1
{ with record type definitions } type Class = (Num, Dat, Str); Date = record D, M, Y: Integer; end; Facts = record Name: string[10]; case Kind: Class of Num: (N: real); Dat: (D: Date); Str: (S: string); end; { with object type definitions } type LocationPtr = "Location; Location = object X, Y: Integer; procedure Init(PX, PY: Integer); function GetX: Integer; function GetY: Integer; end; { with asm } asm mov ax,1 mov cx, 100 end;
Compiler error 38: Integer expression expected A n Integer type was expected.
K — T u r b o Pascal f o r W i n d o w s Error M e s s a g e s
Compiler error 39: Ordinal expression expected The expression must b e o f an ordinal type.
Compiler error 40: Boolean expression expected T h e e x p r e s s i o n m u s t b e o f t y p e Boolean.
Compiler error 41: Operand types do not match operator T h e o p e r a t o r c a n n o t b e u s e d o n o p e r a n d s o f this type; f o r e x a m p l e , 'C
d i v '6'.
Compiler error 42: Error in expression T h i s s y m b o l c a n n o t p a r t i c i p a t e i n this e x p r e s s i o n . Possibly, y o u ' v e o m i t t e d a n operator between two operands.
Compiler error 43: Illegal assignment Y o u c a n n o t a s s i g n v a l u e s t o files a n d u n t y p e d v a r i a b l e s . Y o u c a n a s s i g n v a l u e s t o a f u n c t i o n i d e n t i f i e r o n l y w i t h i n t h e s t a t e m e n t part o f t h e f u n c t i o n .
Compiler error 44: Field identifier expected T h e i d e n t i f i e r d o e s n ' t d e n o t e a field i n t h e r e c o r d v a r i a b l e .
Compiler error 45: Objectfiletoo large T u r b o Pascal f o r W i n d o w s c a n n o t l i n k i n O B J files l a r g e r t h a n 6 4 K .
Compiler error 46: Undefined external T h e e x t e r n a l p r o c e d u r e o r f u n c t i o n d o e s n ' t h a v e a m a t c h i n g PUBLIC d e f i n i t i o n i n a n o b j e c t file. C h e c k t o m a k e s u r e that y o u ' v e s p e c i f i e d all o b j e c t files i n $L f i l e - n a m e d i r e c t i v e s , a n d verify that y o u ' v e c o r r e c t l y s p e l l e d t h e p r o c e d u r e o r f u n c t i o n i d e n t i f i e r i n t h e . A S M file. T h e $L ( L i n k O b j e c t File) d i r e c t i v e i n s t r u c t s t h e c o m p i l e r t o l i n k t h e n a m e d file w i t h t h e p r o g r a m o r u n i t b e i n g c o m p i l e d . U s e t h e $L d i r e c t i v e t o l i n k in c o d e written in assembly language for subprograms declared to b e external.
605
606
Part I I I — R e f e r e n c e s
Compiler error 47: Invalid objectfilerecord T h e O B J file c o n t a i n s a n i n v a l i d o b j e c t r e c o r d .
Compiler error 48: Code segment too large T h e m a x i m u m size o f a p r o g r a m ' s o r u n i t ' s c o d e is 6 5 5 2 0 b y t e s ( 6 4 K ) . T o b r e a k a c o d e s e g m e n t correctly, d o the following: • If y o u ' r e c o m p i l i n g a p r o g r a m , r e c o n s t r u c t t h e p r o g r a m b y m o v i n g s o m e o f its p r o c e d u r e s o r f u n c t i o n s i n t o a u n i t . • If y o u ' r e c o m p i l i n g a u n i t , d i v i d e it i n t o t w o o r m o r e u n i t s .
Compiler error 49: Data segment too large T h e m a x i m u m size o f a p r o g r a m ' s d a t a s e g m e n t is 6 5 5 2 0 b y t e s ( 6 4 K ) , i n c l u d i n g t h e d a t a d e c l a r e d b y t h e u s e d u n i t s . If y o u n e e d m o r e g l o b a l d a t a t h a n t h i s , d e c l a r e t h e l a r g e r s t r u c t u r e s as p o i n t e r s , a n d a l l o c a t e t h e m d y n a m i c a l l y u s i n g t h e New p r o c e d u r e . T h e New p r o c e d u r e c r e a t e s a n e w d y n a m i c v a r i a b l e a n d s p e c i f i e s a p o i n t e r v a r i a b l e t o p o i n t t o it. F o r e x a m p l e :
New(P, Init(326, 243));
Compiler error 50: DO expected T h e r e s e r v e d w o r d do h a s n ' t b e e n u s e d c o r r e c t l y . do (a r e s e r v e d w o r d ) is u s e d i n while, for, a n d with s t a t e m e n t s . F o r e x a m p l e :
while Ch = ' do Ch := GetChar; for Ch := 1 to 100 do Ch := GetChar; with Date[C] do month := 1; 1
Compiler error 51: Invalid PUBIJC definition T h i s e r r o r c a n o c c u r if: • T w o or m o r e PUBLIC directives in assembly l a n g u a g e c o d e define the s a m e identifier. • T h e O B J file d e f i n e s P U B L I C s y m b o l s that a r e n ' t i n t h e CODE s e g m e n t .
K — T u r b o Pascal for W i n d o w s Error M e s s a g e s
Compiler error 52: Invalid EXTRN definition T h i s e r r o r c a n o c c u r if: • T h e i d e n t i f i e r w a s r e f e r r e d t o t h r o u g h a n EXTRN d i r e c t i v e i n a s s e m b l y l a n g u a g e , b u t wasn't declared in the T u r b o Pascal for W i n d o w s p r o g r a m o r u n i t , n o r i n t h e i n t e r f a c e part o f a n y o f t h e u s e d u n i t s . • T h e identifier d e n o t e s a n absolute variable. • T h e identifier d e n o t e s a n inline p r o c e d u r e o r function.
Compiler error 53: Too many EXTRN definitions T u r b o Pascal f o r W i n d o w s d o e s n ' t allow .OBJ files w i t h m o r e t h a n 256 EXTRN definitions.
Compiler error 54: OF expected Y o u h a v e n ' t u s e d t h e r e s e r v e d w o r d of c o r r e c t l y . of is u s e d i n array, set, a n d file t y p e d e c l a r a t i o n s , a n d i n case s t a t e m e n t s . F o r example: { array declaration } type InList = array[1..650] of Integer; CharData = array[ A'.. Z'] of Byte; Matrix = array[0..5, 0..5] of real; 1
1
{ Set types } type Day = (Sun, Mon, Tue, Wed, Thu, Fri, Sat); CharSet = set of Char; Digits = set of 0..9; Days = set of Day; { File type declarations } type Person = record FirstName: string[15]; LastName : string[25]; Address : string[35]; end;
607
608
Part I I I — R e f e r e n c e s
PersonFile = file of Person; NumberFile = file of Integer; SwapFile = file; {case statement } case Ch of 'A'-.'Z', ' a ' - . ' z ' : WriteLn('Letter'); '0'..'9': WriteLn('Digit'); ' + ', '-', '*', '/': WriteLn('Operator'); else WriteLn('Special character'); end;
Compiler error 55: INTERFACE expected Y o u h a v e n ' t u s e d t h e r e s e r v e d w o r d interface c o r r e c t l y . T h e i n t e r f a c e s e c t i o n o f a u n i t is t h e p u b l i c part. It d e t e r m i n e s w h i c h c o m p o n e n t s are v i s i b l e a n d a c c e s s i b l e t o a n y p r o g r a m (or o t h e r u n i t ) u s i n g that unit. T h e i n t e r f a c e s e c t i o n b e g i n s w i t h t h e r e s e r v e d w o r d interface, w h i c h a p p e a r s after t h e unit h e a d e r , a n d e n d s with t h e reserved w o r d implementation. In the unit interface, y o u declare constants, data types, variables, procedures, and functions. T h e "bodies" o f t h e public p r o c e d u r e s a n d functions are in the i m p l e m entation section. A uses c l a u s e c a n a p p e a r i n t h e i n t e r f a c e s e c t i o n . (If a uses c l a u s e is p r e s e n t , uses m u s t i m m e d i a t e l y f o l l o w t h e r e s e r v e d w o r d interface).
Compiler error 56: Invalid relocatable reference T h i s e r r o r c a n o c c u r if: • T h e O B J file c o n t a i n s d a t a a n d r e l o c a t a b l e r e f e r e n c e s i n s e g m e n t s o t h e r t h a n C O D E . F o r e x a m p l e , y o u m i g h t b e trying t o d e c l a r e initialized v a r i a b l e s i n t h e D A T A s e g m e n t . • T h e O B J file c o n t a i n s b y t e - s i z e d r e f e r e n c e s t o r e l o c a t a b l e s y m b o l s . T h i s e r r o r c a n o c c u r if y o u u s e t h e HIGH a n d LOW o p e r a t o r s w i t h r e l o c a t a b l e s y m b o l s , o r if y o u refer t o r e l o c a t a b l e s y m b o l s i n DB d i r e c t i v e s . • A n o p e r a n d refers t o a r e l o c a t a b l e s y m b o l that y o u d i d n ' t d e f i n e i n t h e CODE o r DATA s e g m e n t s . • A n o p e r a n d refers t o a n EXTRN p r o c e d u r e o r f u n c t i o n w i t h a n offset.
K — T u r b o Pascal for Windows
Error Messages
Compiler error 57: THEN expected Y o u haven't u s e d the reserved w o r d t h e n correctly. F o r example: { if
'if-then'
statements
}
( I < Min) o r ( I > Max) t h e n I
: = 0;
i f ParamCount <> 2 t h e n begin W r i t e L n ( Bad command l i n e ' ) ; Halt(1); end else begin ReadFile(ParamStr(1)); WriteFile(ParamStr(2)); 1
end;
Compiler error 58: TO or DOWNTO expected Y o u haven't u s e d the reserved w o r d t o or downto correctly. F o r example: { for
...
to, for
...
downto }
f o r I : = 1 t o ParamCount do WriteLn(ParamStr(I); f o r I : = 1 t o 21 do f o r J : = 1 t o 21 do begin X : = 0; f o r K : = 1 t o 21 do X : = X + M a t 1 [ I , K] * Mat2[K, J ] ; M a t [ I , J ] := X; end;
Compiler error 59: Undefined forward This error might o c c u r if: • Y o u declared the procedure or function in the interface part o f a unit, but didn't define it in the implementation part. • Y o u declared the procedure or function forward but didn't define it.
609
610
Part I I I — R e f e r e n c e s
Compiler error 61: Invalid typecast T h i s e r r o r m i g h t o c c u r if: • I n a v a r i a b l e t y p e c a s t , t h e sizes o f t h e v a r i a b l e r e f e r e n c e a n d t h e d e s t i n a t i o n t y p e differ. • Y o u ' r e attempting to typecast a n expression w h e r e only a variable r e f e r e n c e is a l l o w e d .
Compiler error 62: Division by zero T h e preceding o p e r a n d attempts to divide by zero.
Compiler error 63: Invalidfiletype T h e f i l e - h a n d l i n g p r o c e d u r e d o e s n ' t s u p p o r t t h e g i v e n file's t y p e . F o r e x a m p l e , y o u m i g h t h a v e m a d e a call t o Readln w i t h a t y p e d file o r t o Seek w i t h a text file.
Compiler error 64: Cannot read or write variables of this type Read a n d Readln c a n i n p u t t h e f o l l o w i n g v a r i a b l e t y p e s :
Char Integer real string Write a n d Writeln c a n o u t p u t t h e f o l l o w i n g v a r i a b l e t y p e s :
Char Integer real string Boolean
Compiler error 65: Pointer variable expected This variable must b e o f a pointer type. A p o i n t e r type variable contains the m e m o r y address o f a d y n a m i c variable of a specified base type.
K — T u r b o Pascal for W i n d o w s Error M e s s a g e s
Compiler error 66: String variable expected T h i s v a r i a b l e m u s t b e o f a string t y p e .
Compiler error 67: String expression expected T h i s e x p r e s s i o n m u s t b e o f a string t y p e .
Compiler error 68: Circular unit reference T w o u n i t s c a n n o t use e a c h o t h e r i n t h e i r i n t e r f a c e p a r t s .
Compiler error 69: Unit name mismatch T h e n a m e o f t h e u n i t f o u n d i n t h e T P U file d o e s n ' t m a t c h t h e n a m e s p e c i f i e d i n t h e uses c l a u s e . O r , t h e n a m e o f t h e u n i t file n a m e d o e s n ' t m a t c h t h e n a m e o f t h e u n i t i n t h e u n i t h e a d e r w i t h i n t h e file.
Compiler error 70: Unit version mismatch O n e o r m o r e o f t h e u n i t s u s e d b y this u n i t h a v e b e e n c h a n g e d s i n c e this u n i t w a s compiled. Use Compile/Make or Compile/Build to automatically recompile the u n i t s that h a v e c h a n g e d . T h e C o m p i l e / M a k e c o m m a n d c r e a t e s a n E X E file a c c o r d i n g t o t h e f o l l o w ing rules: • If a p r i m a r y file h a s b e e n n a m e d i n t h e P r i m a r y F i l e d i a l o g b o x , that file is c o m p i l e d . O t h e r w i s e , t h e file i n t h e active edit w i n d o w is c o m p i l e d . T u r b o Pascal c h e c k s all files that t h e file b e i n g c o m p i l e d d e p e n d s o n t o s e e w h e t h e r t h e y exist a n d that t h e y are c u r r e n t . • If t h e s o u r c e file f o r a g i v e n u n i t h a s b e e n m o d i f i e d s i n c e t h e T ^ U ( o b j e c t c o d e ) file w a s c r e a t e d , that u n i t is r e c o m p i l e d . • If t h e i n t e r f a c e f o r a g i v e n u n i t h a s b e e n c h a n g e d , all o t h e r u n i t s that d e p e n d o n it are r e c o m p i l e d . • If a u n i t l i n k s i n a n O B J file ( e x t e r n a l r o u t i n e s ) , a n d t h e O B J file is n e w e r t h a n t h e u n i t ' s T P U file, t h e u n i t is r e c o m p i l e d . • If a u n i t c o n t a i n s a n I n c l u d e file a n d t h e I n c l u d e file is n e w e r t h a n that u n i t ' s T P U file, t h e u n i t is r e c o m p i l e d . • If t h e s o u r c e t o a u n i t ( T P U file) c a n n o t b e l o c a t e d , that u n i t is n o t c o m p i l e d , b u t u s e d as is.
611
612
Part I I I — R e f e r e n c e s
T h i s o p t i o n is i d e n t i c a l t o C o m p i l e / B u i l d e x c e p t that it's c o n d i t i o n a l . ( B u i l d r e b u i l d s all files r e g a r d l e s s o f w h e t h e r t h e y ' r e o u t o f d a t e . ) T h e C o m p i l e / B u i l d c o m m a n d r e b u i l d s all t h e c o m p o n e n t s o f y o u r p r o g r a m regardless o f w h e t h e r they're current. T h i s o p t i o n is i d e n t i c a l t o C o m p i l e / M a k e e x c e p t that it is u n c o n d i t i o n a l . ( M a k e r e b u i l d s o n l y t h o s e files that a r e n ' t c u r r e n t . ) T h e C o m p i l e / B u i l d c o m m a n d r e c o m p i l e s all t h e files i n c l u d e d i n t h e p r i m a r y file. If y o u a b o r t a B u i l d c o m m a n d b y p r e s s i n g C t r l - B r e a k o r g e t e r r o r s that s t o p t h e b u i l d , y o u c a n p i c k u p w h e r e it left o f f b y c h o o s i n g C o m p i l e / M a k e .
Compiler error 72: Unitfileformat error T h e T P U file is i n v a l i d . C h e c k t o e n s u r e that it's a T P U file.
Compiler error 73: IMPLEMENTATION expected E i t h e r t h e r e s e r v e d w o r d implementation d o e s n ' t a p p e a r c o r r e c t l y o r y o u ' v e u s e d it i m p r o p e r l y . T h e implementation part o f t h e u n i t is w h e r e y o u find t h e b o d i e s o f t h e p r o c e d u r e s a n d f u n c t i o n s d e c l a r e d i n t h e i n t e r f a c e part o f t h e u n i t .
Compiler error 74: Constant and case types don't match T h e t y p e o f t h e case c o n s t a n t is i n c o m p a t i b l e w i t h t h e case s t a t e m e n t ' s selector expression.
Compiler error 75: Record variable expected This variable must b e o f a record type. A r e c o r d c o n t a i n s a n u m b e r o f c o m p o n e n t s , o r fields, that c a n b e o f different types. F o r e x a m p l e :
{ Record Type Definitions } type Class = (Num, Dat, Str); Date = record D, M, Y: Integer; end; Facts = record Name: string[10];
K — T u r b o Pascal f o r W i n d o w s Error M e s s a g e s
case Kind: Num: (N: Dat: (D: Str: (S:
Class of real); Date); string);
end;
Compiler error 76: Constant out of range Y o u ' r e p r o b a b l y trying t o d o o n e o f t h e f o l l o w i n g : • I n d e x a n array w i t h a n o u t - o f - r a n g e c o n s t a n t . • Assign a n out-of-range constant to a variable. • Pass a n o u t - o f - r a n g e c o n s t a n t as a p a r a m e t e r t o a p r o c e d u r e or function.
Compiler error 77: File variable expected T h i s v a r i a b l e m u s t b e o f a file t y p e . A file t y p e c o n s i s t s o f a l i n e a r s e q u e n c e o f c o m p o n e n t s o f t h e c o m p o n e n t t y p e , w h i c h c a n b e a n y t y p e e x c e p t a file t y p e . If t h e w o r d o f a n d t h e c o m p o n e n t t y p e a r e o m i t t e d , t h e t y p e d e n o t e s a n u n t y p e d file. T h e p r e d e f i n e d file t y p e T e x t signifies a file c o n t a i n i n g c h a r a c t e r s o r g a n i z e d i n t o l i n e s . F o r e x a m p l e : { File
type declarations
}
type Person = record FirstName: string[15]; LastName : string[25]; Address : string[35]; end; PersonFile = file of Person; NumberFile = file of Integer; SwapFile = file;
613
614
Part I I I — R e f e r e n c e s
Compiler error 78: Pointer expression expected This expression must b e o f a pointer type. A pointer type variable contains t h e m e m o r y address o f a d y n a m i c variable o f a specified base type.
Compiler error 79: Integer or real expression expected T h i s e x p r e s s i o n m u s t b e o f e i t h e r a n Integer o r Real t y p e .
Compiler error 80: Label not within current block A goto s t a t e m e n t c a n n o t r e f e r e n c e a l a b e l o u t s i d e t h e c u r r e n t b l o c k .
Compiler error 81: Label already defined T h e label already marks a statement.
Compiler error 82: Undefined label in preceding statement part Y o u d e c l a r e d a n d r e f e r e n c e d t h e l a b e l i n a s t a t e m e n t part, b u t y o u n e v e r d e f i n e d it.
Compiler error 83: Invalid @ argument Valid a r g u m e n t s are variable references a n d p r o c e d u r e o r function identifiers.
Compiler error 84: UNIT expected T h e r e s e r v e d w o r d unit d o e s n ' t a p p e a r w h e r e it s h o u l d . U n i t s a r e t h e basis o f m o d u l a r p r o g r a m m i n g in T u r b o Pascal for W i n d o w s . Y o u u s e units t o create libraries a n d t o d i v i d e l a r g e p r o g r a m s i n t o l o g i c a l l y r e l a t e d m o d u l e s .
Compiler error 85:";" expected A semicolon was expected.
K — T u r b o Pascal f o r Windows
Compiler error 86:":" expected A colon was expected.
Compiler error 87:"," expected A c o m m a was expected.
Compiler error 88:"(" expected A n o p e n i n g parenthesis was expected.
Compiler error 89:")" expected A closing parenthesis was expected.
Compiler error 90: "=" expected A n equal sign was expected.
Compiler error 91: ":=" expected A n assignment operator was expected.
Compiler error 92:"[" or"(." expected A left b r a c k e t w a s e x p e c t e d .
Compiler error 93:"]" or".)" expected A right b r a c k e t w a s e x p e c t e d .
Compiler error 94:"." expected A period was expected.
Error M e s s a g e s
615
616
Part I I I — R e f e r e n c e s
Compiler error 95:expected A subrange was expected. A s u b r a n g e t y p e is a r a n g e o f v a l u e s f r o m a n o r d i n a l t y p e c a l l e d t h e h o s t t y p e . T h e d e f i n i t i o n o f a s u b r a n g e t y p e s p e c i f i e s t h e least a n d t h e largest v a l u e i n t h e s u b r a n g e . B o t h c o n s t a n t s m u s t b e o f t h e s a m e o r d i n a l t y p e , a n d t h e first c o n s t a n t m u s t b e less t h a n o r e q u a l t o t h e s e c o n d c o n s t a n t . F o r e x a m p l e : 0..99 -128..127
Compiler error 96: Too many variables Global T h e total size o f t h e g l o b a l v a r i a b l e s d e c l a r e d w i t h i n a p r o g r a m o r u n i t c a n n o t exceed 64K. Local T h e t o t a l size o f t h e l o c a l v a r i a b l e s d e c l a r e d w i t h i n a p r o c e d u r e o r f u n c t i o n cannot exceed 64K.
Compiler error 97: Invalid FOR control variable T h e for s t a t e m e n t c o n t r o l v a r i a b l e m u s t b e a s i m p l e v a r i a b l e d e f i n e d i n t h e d e c l a r a t i o n part of t h e c u r r e n t s u b p r o g r a m . F o r e x a m p l e :
{for ... to, for ... downto } for I := 1 to ParamCount do Writel_n(ParamStr(I); for I := 1 to 10 do for J := 1 to 10 do begin X := 0; for K := 1 to 10 do X := X + Mat1[I, K] * Mat2[K, J ] ; Mat[I, J] := X; end;
Compiler error 98: Integer variable expected T h i s v a r i a b l e m u s t b e of a n Integer t y p e .
K — T u r b o Pascal for W i n d o w s Error M e s s a g e s
Compiler error 99: File and procedure types are not allowed here A typed constant cannot b e o f a fde type.
Compiler error 100: String length mismatch T h e length o f the string constant d o e s n ' t m a t c h the n u m b e r o f c o m p o n e n t s in t h e c h a r a c t e r array.
Compiler error 101: Invalid ordering of fields T h e fields o f a record-type constant m u s t b e written in the o r d e r o f declaration.
Compiler error 102: String constant expected A string c o n s t a n t d o e s n ' t a p p e a r w h e r e it s h o u l d . I n i n l i n e a s s e m b l e r s t a t e m e n t s , string c o n s t a n t s m u s t b e e n c l o s e d i n single or d o u b l e quotes. T w o c o n s e c u t i v e q u o t e s o f t h e s a m e t y p e as t h e e n c l o s i n g q u o t e s c o u n t as o n l y o n e c h a r a c t e r . S t r i n g c o n s t a n t s o f a n y l e n g t h are a l l o w e d i n DB d i r e c t i v e s , a n d c a u s e allocation o f a s e q u e n c e of bytes containing the A S C I I values o f the characters i n t h e string. W h e n n o t i n a DB d i r e c t i v e , a string c o n s t a n t c a n b e n o l o n g e r t h a n f o u r c h a r a c t e r s , a n d d e n o t e s a n u m e r i c v a l u e that c a n p a r t i c i p a t e i n a n e x p r e s s i o n . T h e n u m e r i c v a l u e o f a string c o n s t a n t is c a l c u l a t e d as:
+ 0rd(Ch1) + 0rd(Ch2) shl 8 + 0rd(Ch3) shl 16 + 0rd(Ch4) shl 24 where • Ch1 is t h e r i g h t m o s t (last) c h a r a c t e r • Ch4 is t h e l e f t m o s t (first) c h a r a c t e r If t h e string is s h o r t e r t h a n f o u r c h a r a c t e r s , t h e l e f t m o s t (first) c h a r a c t e r o r c h a r a c t e r s are a s s u m e d t o b e 0 ( z e r o ) . H e r e are s o m e e x a m p l e s o f string c o n s t a n t s a n d t h e i r c o r r e s p o n d i n g numeric values:
617
618
Part I I I — R e f e r e n c e s
String
Constant
Numeric
a'
00000061H
ba'
00006261H
cba
636261H
1
'dcba'
64636261H
'a'
00006120H
a'
20202061H
'a'*2 1
000000E2H
a - A' 1
Not
Value
1
00000020H
'a'
FFFFFF9EH
Compiler error 103: Integer or real variable expected T h i s v a r i a b l e m u s t b e o f a n Integer o r Real t y p e .
Compiler error 104: Ordinal variable expected This variable must b e o f a n ordinal type. T u r b o P a s c a l h a s n i n e p r e d e f i n e d o r d i n a l t y p e s . Five o f t h e s e i n t e g e r t y p e s d e n o t e a s p e c i f i c s u b s e t o f t h e w h o l e n u m b e r s , as s h o w n i n t h e f o l l o w i n g : Type
Range
Size
Shortint
1 2 8 . . 127
8-bit
Integer
-32768.-32767
16-bit
Longint
-2147483648. .2147483647
32-bit
Byte
0.255
8-bit
Word
0.65535
16-bit
T h e o t h e r f o u r p r e d e f i n e d o r d i n a l t y p e s a r e t h e b o o l e a n s (Boolean,
WordBool, LongBool), a n d Char. T w o o t h e r classes o f u s e r - d e f i n e d o r d i n a l t y p e s a r e e n u m e r a t e d t y p e s a n d subrange types.
K — T u r b o Pascal for W i n d o w s Error M e s s a g e s
Compiler error 105: INLINE error T h e < o p e r a t o r isn't p e r m i t t e d i n c o n j u n c t i o n w i t h r e l o c a t a b l e r e f e r e n c e s t o variables. T h e s e r e f e r e n c e s a r e always w o r d - s i z e d .
Compiler error 106: Character expression expected T h i s e x p r e s s i o n m u s t b e o f a Char t y p e .
Compiler error 112: CASE constant out of range F o r Integer t y p e case s t a t e m e n t s , t h e c o n s t a n t s m u s t b e w i t h i n t h e r a n g e -32768..32767.
Compiler error 113: Error in statement T h i s s y m b o l c a n n o t start a s t a t e m e n t .
Compiler error 114: Cannot call an interrupt procedure Y o u c a n n o t d i r e c t l y call a n i n t e r r u p t p r o c e d u r e . T h e i n t e r r u p t d i r e c t i v e a l l o w s y o u t o d e c l a r e interrupt p r o c e d u r e s . A n interrupt p r o c e d u r e l o o k s like this: procedure IntProc(Flags, CS, IP, AX, BX, CX, DX, SI, DI, DS, ES, BP: Word); interrupt; T h e registers a r e p a s s e d as p s e u d o - p a r a m e t e r s s o that y o u c a n u s e a n d m o d i f y t h e m in the c o d e o f the interrupt p r o c e d u r e .
Compiler error 116: Must be in 80x87 mode to compile T h i s c o n s t r u c t c a n b e c o m p i l e d o n l y i n t h e { $ N + } state. O p e r a t i o n s o n t h e 8 0 x 8 7 Real t y p e s (Single, Double, Extended, a n d Comp) a r e n o t a l l o w e d i n t h e { $ N - } state.
619
620
Part I I I — R e f e r e n c e s
Compiler error 117: Target address not found T h e S e a r c h / F i n d E r r o r c o m m a n d c o u l d n ' t l o c a t e a s t a t e m e n t that c o r r e s p o n d s to the specified address.
Compiler error 118: Includefilesare not allowed here E v e r y s t a t e m e n t part m u s t b e c o n t a i n e d e n t i r e l y i n o n e file.
Compiler error 120: NIL expected T y p e d c o n s t a n t s o f p o i n t e r t y p e s c a n b e initialized o n l y t o t h e v a l u e n i l .
Compiler error 121: Invalid qualifier Y o u ' r e p r o b a b y trying t o d o o n e o f t h e f o l l o w i n g : • I n d e x a v a r i a b l e that is n o t a n array. • S p e c i f y fields i n a v a r i a b l e that is n o t a r e c o r d . • D e r e f e r e n c e a v a r i a b l e that is n o t a p o i n t e r .
Compiler error 122: Invalid variable reference T h i s c o n s t r u c t f o l l o w s t h e s y n t a x o f a v a r i a b l e r e f e r e n c e , b u t it d o e s n ' t d e n o t e a memory location. Y o u ' r e probably calling a pointer function, but forgetting to dereference t h e result.
Compiler error 123: Too many symbols T h e program or unit declares m o r e than 64K of symbols. I f y o u ' r e c o m p i l i n g w i t h { $ D + } , try t u r n i n g it off. {Note: T h i s s t e p p r e v e n t s y o u f r o m finding r u n - t i m e e r r o r s i n that m o d u l e . ) Y o u c a n a l s o try m o v i n g s o m e d e c l a r a t i o n s i n t o a s e p a r a t e u n i t .
Compiler error 124: Statement part too large T u r b o Pascal limits t h e size o f a s t a t e m e n t part t o a b o u t 2 4 K . If y o u e n c o u n t e r this e r r o r , m o v e s e c t i o n s o f t h e s t a t e m e n t part i n t o o n e or more procedures.
K — T u r b o Pascal for W i n d o w s Error M e s s a g e s
Compiler error 126: Files must be var parameters Y o u ' r e p r o b a b l y trying t o d e c l a r e a file-type v a l u e p a r a m e t e r . File-type p a r a m e t e r s m u s t b e v a r p a r a m e t e r s .
Compiler error 127: Too many conditional symbols T h e r e isn't e n o u g h r o o m t o d e f i n e f u r t h e r c o n d i t i o n a l s y m b o l s . Try to eliminate s o m e symbols, o r shorten s o m e o f the symbolic n a m e s .
Compiler error 128: Misplaced conditional directive T h e c o m p i l e r e n c o u n t e r e d a n {$ELSE} o r {$ENDIF} d i r e c t i v e w i t h o u t a m a t c h i n g {$IFDEF}, {$IFNDEF}, o r {$IF0PT} d i r e c t i v e .
Compiler error 129: ENDEF directive missing T h e s o u r c e file e n d e d w i t h i n a c o n d i t i o n a l c o m p i l a t i o n c o n s t r u c t . T u r b o Pascal requires a n e q u a l n u m b e r o f { $ I F x x x } s a n d {$ENDIF}sin a s o u r c e file.
Compiler error 130: Error in initial conditional defines T h e initial c o n d i t i o n a l s y m b o l s s p e c i f i e d i n O p t i o n s / C o m p i l e r / C o n d i t i o n a l D e f i n e s ( o r i n a /D directive) a r e i n v a l i d . T u r b o P a s c a l f o r W i n d o w s e x p e c t s z e r o o r m o r e identifiers s e p a r a t e d b y blanks, commas, or semicolons.
Compiler error 131: Header does not match previous definition T h e p r o c e d u r e o r f u n c t i o n h e a d e r s p e c i f i e d i n a n i n t e r f a c e part o r FORWARD d e c l a r a t i o n d o e s n ' t m a t c h this h e a d e r .
Compiler error 132: Critical disk error A critical e r r o r o c c u r r e d d u r i n g c o m p i l a t i o n (for e x a m p l e , a D r i v e N o t R e a d y error).
621
622
Part I I I — R e f e r e n c e s
Compiler error 133: Cannot evaluate this expression Y o u m i g h t b e trying t o u s e a n o n s u p p o r t e d f e a t u r e i n a c o n s t a n t e x p r e s s i o n o r in a d e b u g expression. F o r e x a m p l e , y o u m i g h t b e a t t e m p t i n g t o u s e t h e Sin f u n c t i o n i n a const d e c l a r a t i o n , o r a t t e m p t i n g t o call a u s e r - d e f i n e d f u n c t i o n i n a d e b u g e x p r e s s i o n .
Compiler error 136: Invalid indirect reference T h e statement attempts to m a k e an invalid indirect reference. For e x a m p l e , y o u might b e using an absolute variable w h o s e base variable is n o t k n o w n i n t h e c u r r e n t m o d u l e , o r u s i n g a n i n l i n e r o u t i n e that r e f e r e n c e s a variable not k n o w n in the current m o d u l e .
Compiler error 137: Structured variables are not allowed here Y o u m i g h t b e trying t o p e r f o r m a n o n s u p p o r t e d o p e r a t i o n o n a s t r u c t u r e d variable. F o r e x a m p l e , y o u m i g h t b e trying t o m u l t i p l y t w o r e c o r d s .
Compiler error 140: Invalidfloating-pointoperation A n o p e r a t i o n o n t w o real t y p e v a l u e s p r o d u c e d a n o v e r f l o w o r a d i v i s i o n by zero.
Compiler error 142: Procedure or function variable expected I n this c o n t e x t , t h e a d d r e s s o p e r a t o r ( @ ) c a n b e u s e d o n l y w i t h a p r o c e d u r e o r function variable.
Compiler error 143: Invalid procedure or function reference Y o u ' r e p r o b a b l y trying t o call a p r o c e d u r e i n a n e x p r e s s i o n . A p r o c e d u r e o r a f u n c t i o n m u s t b e c o m p i l e d i n t h e { $ F + } state, a n d c a n n o t b e d e c l a r e d w i t h i n l i n e o r i n t e r r u p t if it is t o b e a s s i g n e d t o a p r o c e d u r e variable.
K — T u r b o Pascal for W i n d o w s Error M e s s a g e s
Compiler error 146: File access denied T h e file c o u l d n ' t b e o p e n e d o r c r e a t e d . T h e p r o g r a m m i g h t b e trying t o w r i t e t o a r e a d - o n l y file.
Compiler error 147: Object type expected T h e identifier doesn't d e n o t e a n object type.
Compiler error 148: Local object types are not allowed O b j e c t t y p e s can b e d e f i n e d only in t h e o u t e r m o s t s c o p e o f a p r o g r a m o r u n i t . O b j e c t type definitions within p r o c e d u r e s a n d functions are n o t allowed.
Compiler error 149: \TKTUAL expected T h e k e y w o r d virtual is m i s s i n g . virtual is a p r o c e d u r e d i r e c t i v e . A virtual m e t h o d is a m e t h o d w h o s e call is l i n k e d t o its c o d e at r u n - t i m e , by a p r o c e s s c a l l e d late b i n d i n g . F o r example:
procedure Method(<parameter list>); virtual; D e c l a r i n g a m e t h o d as virtual m a k e s it p o s s i b l e for m e t h o d s w i t h t h e s a m e n a m e t o b e i m p l e m e n t e d in d i f f e r e n t w a y s u p a n d d o w n a h i e r a r c h y of object types.
Compiler error 150: Method identifier expected T h e identifier doesn't d e n o t e a m e t h o d .
Compiler error 151: Virtual constructors are not allowed A c o n s t r u c t o r m e t h o d m u s t b e static.
Compiler error 152: Constructor identifier expected T h e identifier doesn't d e n o t e a constructor.
Compiler error 153: Destructor identifier expected T h e identifier doesn't d e n o t e a destructor.
623
624
Part I I I — R e f e r e n c e s
Compiler error 154: Fail only allowed within constructors T h e F a i l standard procedure can be used only within constructors.
Compiler error 155: Invalid combination of opcode and operands T h e a s s e m b l e r o p c o d e d o e s n ' t a c c e p t this c o m b i n a t i o n o f o p e r a n d s . P o s s i b l e c a u s e s are • T o o m a n y o r t o o f e w o p e r a n d s for this a s s e m b l e r o p c o d e ; for e x a m p l e , I N C A X , B X o r M O V AX. • T h e n u m b e r o f o p e r a n d s is c o r r e c t , b u t t h e i r t y p e s o r o r d e r d o n ' t m a t c h t h e o p c o d e ; for e x a m p l e , DEC 1, MOV AX,CL o r MOV 1 , AX.
Compiler error 156: Memory reference expected T h e a s s e m b l e r o p e r a n d isn't a m e m o r y r e f e r e n c e , w h i c h is r e q u i r e d h e r e . M o s t likely, y o u ' v e o m i t t e d t h e s q u a r e b r a c k e t s a r o u n d a n i n d e x r e g i s t e r o p e r a n d ; for e x a m p l e , MOV A X , B X + S I r a t h e r t h a n MOV A X , [ B X + S I ] .
Compiler error 157: Cannot add or subtract relocatable symbols T h e o n l y a r i t h m e t i c o p e r a t i o n that c a n b e p e r f o r m e d o n a r e l o c a t a b l e s y m b o l i n a n a s s e m b l e r o p e r a n d is a d d i t i o n o r s u b t r a c t i o n o f a c o n s t a n t . V a r i a b l e s , p r o c e d u r e s , f u n c t i o n s , a n d l a b e l s are r e l o c a t a b l e s y m b o l s . A s s u m i n g that Var is v a r i a b l e a n d Const is a c o n s t a n t , t h e n t h e i n s t r u c t i o n s MOV
A X , Const+Const a n d MOV A X , Var+Const are v a l i d , b u t MOV A X , Var+Var is n o t .
Compiler error 158: Invalid register combination V a l i d index-register c o m b i n a t i o n s are [ BX ] , [ BP ] , [ S I ] , [ DI ] , [ B X + S I ] , [ BX+DI ] , [ B P + S I ] , a n d [ B P + D I ] . O t h e r i n d e x - r e g i s t e r c o m b i n a t i o n s , s u c h as [ A X ] , [ B P + B X ] , a n d [ S I + D X ] , are n o t a l l o w e d . L o c a l v a r i a b l e s are always a l l o c a t e d o n t h e stack a n d a c c e s s e d b y w a y o f t h e B P register. T h e a s s e m b l e r a u t o m a t i c a l l y a d d s [ BP ] i n r e f e r e n c e s t o s u c h v a r i a b l e s ; t h e r e f o r e , a c o n s t r u c t like L o c a l [ B X ] ( w h e r e L o c a l is a l o c a l v a r i a b l e ) a p p e a r s v a l i d , b u t it's n o t , b e c a u s e t h e final o p e r a n d w o u l d b e c o m e Local[BP+BX].
K — T u r b o Pascal for W i n d o w s Error M e s s a g e s 62
Compiler error 159:286/287 instructions are not enabled U s e a { $ G + } c o m p i l e r d i r e c t i v e t o e n a b l e 286/287 o p c o d e s , b u t n o t i c e that t h e resulting c o d e cannot b e r u n o n 8086- a n d 8088-based machines.
Compiler error 160: Invalid symbol reference This symbol cannot b e accessed in a n assembler o p e r a n d . Possible causes are • Y o u ' r e trying t o a c c e s s a s t a n d a r d p r o c e d u r e , a s t a n d a r d f u n c t i o n , o r t h e Mem, MemW, MemL, Port, o r PortW s p e c i a l arrays i n a n a s s e m b l e r operand. • Y o u ' r e trying t o a c c e s s a string, f l o a t i n g - p o i n t , o r set c o n s t a n t i n a n assembler operand. • Y o u ' r e trying t o a c c e s s a n i n l i n e p r o c e d u r e o r f u n c t i o n i n a n a s s e m b l e r operand. • Y o u ' r e trying t o a c c e s s t h e ^Result s p e c i a l s y m b o l o u t s i d e a f u n c t i o n . • Y o u ' r e trying t o g e n e r a t e a s h o r t J M P i n s t r u c t i o n that j u m p s t o s o m e thing other than a label.
Compiler error 161: Code generation error T h e p r e c e d i n g s t a t e m e n t part c o n t a i n s a L O O P N E , L O O P E , L O O P , o r J C X Z i n s t r u c t i o n that c a n n o t r e a c h its target l a b e l .
Compiler error 162: ASM expected T h e c o m p i l e r e x p e c t s a n asm r e s e r v e d w o r d at this l o c a t i o n .
Compiler error 163: Duplicate dynamic method index This dynamic m e t h o d index has b e e n u s e d already by another m e t h o d .
Compiler error 164: Duplicate resource identifier T h i s r e s o u r c e file c o n t a i n s a r e s o u r c e w i t h a n a m e o r I D that h a s b e e n u s e d already by another resource.
5
626
Part I I I — R e f e r e n c e s
Compiler error 165: Duplicate or invalid export index T h e o r d i n a l n u m b e r s p e c i f i e d i n t h e i n d e x c a u s e is n o t w i t h i n t h e r a n g e 1..32767, or has b e e n u s e d already by another e x p o r t e d routine.
Compiler error 166: Procedure or function identifier expected T h e exports clause allows only procedures a n d functions to be exported.
Compiler error 167: Cannot export this symbol A p r o c e d u r e o r f u n c t i o n c a n n o t b e e x p o r t e d u n l e s s it w a s d e c l a r e d w i t h t h e export function.
Compiler error 168: Duplicate export name T h e n a m e specified in the n a m e clause has b e e n u s e d already by another exported routine.
Run-time Error Messages Error
Number
Error
Message
1
Invalid function n u m b e r
2
File n o t f o u n d
3
Path not f o u n d
4
T o o m a n y o p e n files
5
File a c c e s s d e n i e d
6
I n v a l i d file h a n d l e
12
I n v a l i d file a c c e s s c o d e
15
I n v a l i d drive n u m b e r
16
C a n n o t remove current directory
17
C a n n o t r e n a m e a c r o s s drives
100
Disk read error
K — T u r b o Pascal for W i n d o w s Error M e s s a g e s 62
Error
Number
Error
Message
101
Disk write error
102
File n o t a s s i g n e d
103
File n o t o p e n
104
File n o t o p e n for i n p u t
105
File n o t o p e n for o u t p u t
106
Invalid numeric format
200
Division by zero
201
Range check error
202
Stack overflow error
203
H e a p overflow error
204
Invalid pointer operation
205
Floating point overflow
206
Floating point underflow
207
I n v a l i d floating p o i n t o p e r a t i o n
210
O b j e c t n o t initialized
211
C a l l t o abstract m e t h o d
212
Stream registration error
213
Collection index out of range
214
C o l l e c t i o n overflow error
Run-time error 1: Invalid function number Y o u t r i e d t o call a n o n e x i s t e n t D O S f u n c t i o n .
Run-time error 2: File not found T h e r o u t i n e s Reset, Append, Rename, a n d Erase r e p o r t this e r r o r if t h e n a m e a s s i g n e d t o t h e file v a r i a b l e d o e s n ' t s p e c i f y a n e x i s t i n g file.
7
628
Part I I I — R e f e r e n c e s
Run-time error 3: Path not found T h e r o u t i n e s R e s e t , A p p e n d , R e w r i t e , Rename, a n d E r a s e r e p o r t this e r r o r if t h e n a m e a s s i g n e d t o t h e file v a r i a b l e is i n v a l i d o r s p e c i f i e s a n o n - e x i s t e n t subdirectory. T h e r o u t i n e s C h D i r , M k D i r , a n d RmDir r e p o r t this e r r o r if t h e p a t h is i n v a l i d o r if it s p e c i f i e s a n o n - e x i s t e n t s u b d i r e c t o r y .
Run-time error 4: Too many open files T h e r o u t i n e s R e s e t , R e w r i t e , a n d A p p e n d r e p o r t this e r r o r if t h e p r o g r a m h a s t o o m a n y o p e n files. D O S n e v e r a l l o w s m o r e t h a n 15 o p e n files p e r p r o c e s s . If y o u g e t this e r r o r w i t h less t h a n 15 o p e n files, t h e C O N F I G . S Y S file m i g h t n o t i n c l u d e a F I L E S = x x e n t r y (or x x m i g h t s p e c i f y t o o f e w files). Increase the n u m b e r xx to s o m e suitable value, b e t w e e n 20 a n d 30.
Run-time error 5: File access denied Reported
By
When
Problem
Occurs
Reset
F i l e M o d e a l l o w s writing, a n d t h e n a m e a s s i g n e d t o t h e file variable specifies a directory o r a reado n l y file.
Append
F i l e M o d e a l l o w s writing, a n d t h e n a m e a s s i g n e d t o t h e file variable specifies a directory o r a reado n l y file.
Rewrite
T h e directory is full, o r t h e n a m e a s s i g n e d t o t h e file variable specifies a directory o r a n e x i s t i n g read-only file.
Rename
T h e n a m e a s s i g n e d t o t h e file variable specifies a directory, o r t h e n e w n a m e s p e c i f i e s a n e x i s t i n g file.
Erase
T h e n a m e a s s i g n e d t o t h e file variable s p e c i f i e s a directory o r a read-only file.
MkDir
A file w i t h t h e s a m e n a m e exists in t h e p a r e n t directory, o r there is n o room in t h e p a r e n t directory, o r t h e p a t h s p e c i f i e s a d e v i c e .
RmDir
T h e directory isn't e m p t y , o r t h e p a t h d o e s n ' t specify a directory, o r t h e p a t h specifies t h e root directory.
K — T u r b o Pascal f o r W i n d o w s Error M e s s a g e s
Reported
By
When
Problem
Occurs
Read
( O n a t y p e d o r u n t y p e d file): T h e file is n o t o p e n for reading.
BlockRead
( O n a t y p e d o r u n t y p e d f i l e ) : T h e file is n o t o p e n for reading.
Write
( O n a t y p e d o r u n t y p e d f i l e ) : T h e file is n o t o p e n for writing.
BlockWrite
( O n a t y p e d o r u n t y p e d f i l e ) : T h e file is n o t o p e n for writing.
Run-time error 6: Invalidfilehandle T h i s e r r o r is r e p o r t e d if a n i n v a l i d file h a n d l e is p a s s e d t o a D O S s y s t e m c a l l . T h i s e r r o r s h o u l d n e v e r o c c u r ; if it d o e s , y o u k n o w that t h e file v a r i a b l e is s o m e h o w t r a s h e d .
Run-time error 12: Invalidfileaccess code Reset a n d Append r e p o r t this e r r o r ( o n a t y p e d o r u n t y p e d file) if t h e v a l u e o f F i l e M o d e is i n v a l i d .
Run-time error 15: Invalid drive number GetDir a n d ChDir r e p o r t this e r r o r if t h e d r i v e n u m b e r is i n v a l i d .
Run-time error 16: Cannot remove current directory RmDir r e p o r t s this e r r o r if t h e p a t h s p e c i f i e s t h e c u r r e n t d i r e c t o r y .
Run-time error 17: Cannot rename across drives Rename r e p o r t s this e r r o r if b o t h n a m e s a r e n o t o n t h e s a m e d r i v e .
Run-time error 100: Disk read error R e a d r e p o r t s this e r r o r o n a t y p e d file if y o u a t t e m p t t o r e a d p a s t t h e e n d o f t h e file.
629
630
Part I I I — R e f e r e n c e s
Run-time error 101: Disk write error Close, Write, Writeln, a n d Flush r e p o r t this e r r o r if t h e d i s k b e c o m e s f u l l .
Run-time error 102: File not assigned Reset,Rewrite,Append,Rename, a n d Erase r e p o r t this e r r o r if t h e file v a r i a b l e h a s n o t b e e n a s s i g n e d a n a m e t h r o u g h a call t o Assign.
Run-time error 103: File not open T h e f o l l o w i n g p r o c e d u r e s ( o r f u n c t i o n s ) r e p o r t this e r r o r if t h e file isn't o p e n : BlockRead BlockWrite Close Eof FilePos FileSize Flush Read Seek Write
Run-time error 104: File not open for input T h e f o l l o w i n g p r o c e d u r e s (or f u n c t i o n s ) r e p o r t this e r r o r o n a text file if t h e file isn't o p e n f o r i n p u t : Eof Eoln Read ReadLn SeekEof SeekEoln
Run-time error 105: File not open for output T h i s e r r o r o c c u r s if y o u try t o u s e s t a n d a r d i n p u t a n d o u t p u t f u n c t i o n s s u c h as Readln a n d Writeln w i t h o u t t h e Uses WinCRT; s t a t e m e n t . T o c o r r e c t this e r r o r , just a d d Uses WinCRT; t o y o u r p r o g r a m .
K — T u r b o Pascal f o r W i n d o w s Error M e s s a g e s
Run-time error 106: Invalid numeric format Read a n d Read I n r e p o r t this e r r o r if a n u m e r i c v a l u e r e a d f r o m a text file d o e s n ' t c o n f o r m to the proper numeric format.
Run-time error 200: Division by zero T h e p r o g r a m a t t e m p t e d t o d i v i d e a n u m b e r b y 0 d u r i n g a /, mod, o r d i v operation.
Run-time error 201: Range check error T h i s e r r o r is r e p o r t e d b y s t a t e m e n t s c o m p i l e d i n t h e { $ R + } state, w h e n o n e o f t h e f o l l o w i n g s i t u a t i o n s arises: • T h e i n d e x o f a n array w a s o u t o f r a n g e . • T h e p r o g r a m attempted to assign a n out-of-range value to a variable. • T h e p r o g r a m a t t e m p t e d t o p a s s a n o u t - o f - r a n g e v a l u e as a p a r a m e t e r t o a procedure or function.
Run-time error 202: Stack overflow error A n a p p l i c a t i o n r e p o r t s this e r r o r o n e n t r y t o a p r o c e d u r e o r f u n c t i o n c o m p i l e d i n t h e { $ S + } state w h e n t h e r e isn't e n o u g h stack s p a c e t o a l l o c a t e t h e subprogram's local variables. I n c r e a s e t h e size o f t h e stack w i t h t h e $M c o m p i l e r d i r e c t i v e . T h e S t a c k O v e r f l o w e r r o r c a n a l s o b e c a u s e d b y infinite r e c u r s i o n , o r b y a n a s s e m b l y l a n g u a g e p r o c e d u r e that d o e s n ' t m a i n t a i n t h e stack p r o p e r l y .
Run-time error 203: Heap overflow error New a n d GetMem r e p o r t this e r r o r w h e n t h e r e isn't e n o u g h free s p a c e i n t h e h e a p t o a l l o c a t e a b l o c k o f t h e r e q u e s t e d size.
Run-time error 204: Invalid pointer operation Dispose a n d FreeMem r e p o r t this e r r o r if t h e p o i n t e r is n i l o r if it p o i n t s t o a location outside the heap.
631
632
Part I I I — R e f e r e n c e s
Run-time error 205: Floating point overflow A floating-point o p e r a t i o n p r o d u c e d a n u m b e r t o o l a r g e f o r T u r b o Pascal (or t h e n u m e r i c c o p r o c e s s o r , if t h e r e is o n e ) t o h a n d l e .
Run-time error 206: Floating point underflow A
floating-point o p e r a t i o n p r o d u c e d a n u n d e r f l o w . T h i s e r r o r is r e p o r t e d o n l y if y o u a r e u s i n g a n u m e r i c c o p r o c e s s o r w i t h a c o n t r o l w o r d that u n m a s k s u n d e r f l o w e x c e p t i o n s . B y d e f a u l t , a n u n d e r f l o w c a u s e s a result o f z e r o t o b e r e t u r n e d .
Run-time error 207: Invalidfloatingpoint operation O n e o f the following
floating-point
errors o c c u r r e d :
• T h e real v a l u e p a s s e d toTruncorRound c o u l d n o t b e c o n v e r t e d t o a n i n t e g e r w i t h i n t h e Longint r a n g e ( - 2 1 4 7 4 8 3 6 4 8 t o 2 1 4 7 4 8 3 6 4 7 ) . • T h e a r g u m e n t p a s s e d t o t h e Sqrt f u n c t i o n w a s n e g a t i v e . • T h e a r g u m e n t p a s s e d t o t h e Ln f u n c t i o n w a s 0 o r n e g a t i v e . • A n 8 0 x 8 7 stack o v e r f l o w o c c u r r e d .
Run-time error 210: Object not initialized W i t h r a n g e - c h e c k i n g o n , y o u m a d e a call t o a n o b j e c t ' s virtual m e t h o d , b e f o r e t h e o b j e c t h a d b e e n initialized b y w a y o f a c o n s t r u c t o r c a l l .
Run-time error 211: Call to abstract method T h i s e r r o r is g e n e r a t e d b y t h e Abstract p r o c e d u r e i n t h e W O b j ects u n i t . It i n d i c a t e s that y o u r p r o g r a m t r i e d t o e x e c u t e a n abstract virtual method.
Run-time error 212: Stream registration error T h i s e r r o r is g e n e r a t e d b y t h e RegisterType p r o c e d u r e i n t h e WOb j ects u n i t . It i n d i c a t e s that o n e o f t h e f o l l o w i n g errors h a s o c c u r r e d : • T h e stream registration record d o e s n o t reside in the data segment. • T h e Ob j Type field o f t h e s t r e a m r e g i s t r a t i o n r e c o r d is 0 .
K — T u r b o Pascal f o r W i n d o w s Error M e s s a g e s
• T h e type has already b e e n registered. • A n o t h e r t y p e w i t h t h e s a m e Ob j T y p e v a l u e a l r e a d y e x i s t s .
Run-time error 213: Collection index out of range T h e i n d e x p a s s e d t o a T C o l l e c t i o n m e t h o d is o u t o f r a n g e .
Run-time error 214: Collection overflow error T h i s e r r o r is r e p o r t e d b y a T C o l l e c t i o n if a n a t t e m p t is m a d e t o a d d a n e l e m e n t w h e n the collection cannot be expanded.
633
L REFERENCE
WINDOW MANAGER INTERFACE PROCEDURES AND FUNCTIONS A l p h a b e t i c a l listing o f W i n d o w s M a n a g e r I n t e r f a c e p r o c e d u r e s a n d f u n c t i o n s :
Caret Clipboard Cursor Dialog-Box Display and Movement Error Hardware Hook Information
Input Menu Message Painting Property Scrolling System Window-Creation
Caret Procedures and Functions CreateCaret DestroyCaret GetCaretBlinkTime GetCaretPos
HideCaret SetCaretBlinkTime SetCaretPos ShowCaret
636
Part I I I — R e f e r e n c e s
CreateCaret procedure CreateCaret(Wnd: HWnd; ABitmap: HBitmap; Width, Height: Integer); C r e a t e s a n e w s h a p e f o r t h e s y s t e m caret. Parameters
Description
Wnd
O w n i n g w i n d o w o f t h e n e w caret
ABitmap
B i t m a p that d e f i n e s t h e caret; if 0 caret is b l a c k ; if 1 caret is g r a y
Width
Caret w i d t h (in logical units)
Height
Caret height (in logical units)
DestroyCaret procedure DestroyCaret; D e s t r o y s t h e c u r r e n t caret, frees it f r o m t h e o w n i n g w i n d o w , a n d r e m o v e s it f r o m t h e s c r e e n (if it is c u r r e n t l y v i s i b l e ) .
GetCaretBlinkrime function GetCaretBlinkTime: Word; G e t s caret b l i n k ( t i m e b e t w e e n flashes o f t h e c a r e t ) . Return Value: B l i n k rate (in m i l l i s e c o n d s ) .
GetCaretPos procedure GetCaretPos(var Point: TPoint); G e t s t h e c u r r e n t caret p o s i t i o n (in c l i e n t c o o r d i n a t e s ) . Parameter Point
Description R e c e i v i n g TPoint s t r u c t u r e
L — W i n d o w M a n a g e r Interface P r o c e d u r e s a n d F u n c t i o n s
HideCaret procedure HideCaret(Wnd: HWnd); N o n d e s t r u c t i v e l y r e m o v e s t h e caret f r o m t h e d i s p l a y s c r e e n . Parameter Wnd
Description O w n i n g w i n d o w o f caret o r 0 if o w n i n g w i n d o w is i n c u r r e n t task
SetCaretBlinkTime procedure SetCaretBlinkTime(MSeconds: Word); S e t s t h e e l a p s e d t i m e b e t w e e n caret Parameter MSeconds
flashes.
Description B l i n k rate ( i n m i l l i s e c o n d s )
SetCaretPos procedure SetCaretPos(X, Y :
Integer);
M o v e s t h e caret t o t h e s p e c i f i e d (X, Y) p o s i t i o n . Parameter X, Y
Description N e w position (in logical coordinates)
ShowCaret procedure ShowCaret(Wnd: HWnd); S h o w s a caret that is o w n e d b y Wnd o n t h e d i s p l a y . Parameter Wnd
Description W i n d o w i d e n t i f i e r o r 0 f o r a w i n d o w i n t h e c u r r e n t task.
637
638
Part I I I — R e f e r e n c e s
Clipboard Procedures and Functions ChangeClipboardChain CloseClipboard EmptyClipboard EnumClipboardFormats GetClipboardData GetClipboardFormatName GetClipboardOwner GetClipboardViewer GetPriorityClipboardFormat IsClipboardFormatAvailable OpenClipboard RegisterClipboardFormat SetClipboardData SetClipboardViewer
ChangeClipboardChain function ChangeClipboardChain(Wnd, WndNext: HWnd): Bool; R e m o v e s Wnd f r o m t h e c h a i n o f c l i p b o a r d v i e w e r s a n d r e p l a c e s it w i t h WndNext. Parameters
Description
Wnd
W i n d o w to be removed from chain
WndNext
W i n d o w that f o l l o w s Wnd i n t h e c l i p b o a r d - v i e w e r c h a i n .
Return Value: N o n z e r o if t h e w i n d o w is f o u n d a n d r e m o v e d .
CloseClipboard function CloseClipboard: Bool; Closes the clipboard to allow the clipboard to be accessed by other applications. Return
Value:
N o n z e r o if c l i p b o a r d is c l o s e d ; e l s e 0.
EmptyClipboard function EmptyClipboard: Bool;
L — W i n d o w M a n a g e r Interface P r o c e d u r e s a n d F u n c t i o n s
E m p t i e s t h e c l i p b o a r d a n d frees handles t o d a t a i n t h e c l i p b o a r d . O w n e r s h i p is a s s i g n e d t o t h e w i n d o w that has t h e c l i p b o a r d o p e n . Return Value: N o n z e r o if t h e c l i p b o a r d is e m p t i e d ; 0 if error.
EnumClipboardFofmats function EnumClipboardFormats(Format: Word): Word; E n u m e r a t e s list of available c l i p b o a r d formats. Parameter Format
Description K n o w n format or 0 for first format in list; t h e formats are s p e c i f i e d b y t h e cf _Clipboard formats.
Return Value: N e x t k n o w n c l i p b o a r d f o r m a t ; 0 if e n d o f f o r m a t list o r if c l i p b o a r d c l o s e d .
GetClipboardData function GetClipboardData(Format: Word): "["Handle; Gets clipboard data in a specified format. T h e clipboard controls the memory block. Parameter Format
returned
Description C l i p b o a r d d a t a format; one of t h e cf _ Clipboard formats' c o n s t a n t s
Return Value: M e m o r y b l o c k c o n t a i n i n g c l i p b o a r d d a t a ; 0 if error.
GetClipboardFormatName function GetClipboardFormatName(Format: Word; FormatName: PChar; MaxCount: Integer): Integer; G e t s a registered Parameters
f o r m a t n a m e from t h e c l i p b o a r d . Description
Format
C l i p b o a r d format; one of t h e cf _ Clipboard formats' constants
FormatName
Receiving buffer
MaxCount
Size o f buffer
639
640
Part I I I — R e f e r e n c e s
Return Value: A c t u a l l e n g t h o f c o p i e d string; 0 if i n v a l i d f o r m a t r e q u e s t e d .
GetClipboardOwner function GetClipboardOwner: HWnd; G e t s t h e w i n d o w that c u r r e n t l y o w n s t h e c l i p b o a r d . Return Value: O w n i n g w i n d o w ; 0 if n o o w n e r .
GetClipboardViewer function GetClipboardViewer: HWnd; G e t s t h e first w i n d o w i n t h e c l i p b o a r d - v i e w e r c h a i n . Return Value: W i n d o w c u r r e n t l y r e s p o n s i b l e f o r d i s p l a y i n g t h e c l i p b o a r d ; 0 if n o v i e w e r .
GetPriorityClipboardFormat function GetPriorityClipboardFormat(var Count: Integer): Integer;
PriorityList;
G e t s t h e first c l i p b o a r d f o r m a t i n PriorityList f o r which d a t a e x i s t s . Parameters
Description
PriorityList
I n t e g e r array c o n t a i n i n g c l i p b o a r d f o r m a t s i n p r i o r i t y o r d e r ; t h e f o r m a t s a r e c f _ Clipboard f o r m a t s
Count
S i z e o f PriorityList
Return Value: H i g h e s t p r i o r i t y f o r m a t i n list: - 1 if n o m a t c h ; 0 if t h e r e ' s n o d a t a i n t h e clipboard.
IsClipboardFormatAvailable function IsClipboardFormatAvailable(Format: Word): Bool; D e t e r m i n e s w h e t h e r d a t a i n t h e s p e c i f i e d f o r m a t is i n t h e c l i p b o a r d . Parameter Format
Description Registered clipboard format; o n e o f the c f formats' constants
Clipboard
L — W i n d o w M a n a g e r Interface P r o c e d u r e s a n d F u n c t i o n s
Return Value: N o n z e r o if d a t a available i n F o r m a t ; e l s e 0.
OpenClipboard function OpenClipboard(Wnd: HWnd): Bool; Opens the clipboard for exclusive use by an application. Parameter Wnd
Description Window identifier
Return Value: Nonzero if successful; 0 if Clipboard already opened by another application.
RegisterClipboardFormat function RegisterClipboardFormat(FormatName: PChar): Word; Registers a c l i p b o a r d f o r m a t , incrementing b e e n previously registered. Parameter FormatName
t h e f o r m a t ' s reference
c o u n t if it had
Description Format n a m e (null-terminated)
Return Value: R e g i s t e r e d f o r m a t identifier
($C000 t o $ F F F F ) if s u c c e s s f u l ; e l s e 0.
SetClipboardData function SetClipboardData(Format: Word; Mem: THandle): THandle; S e t s a d a t a handle to the clipboard in Format. U s u a l l y the d a t a handle before the f u n c t i o n returns. Parameters
Description
Format
O n e of the cf _ Clipboard formats' constants
Mem
H a n d l e to g l o b a l m e m o r y b l o c k c o n t a i n i n g d a t a in format or 0 for wm_RenderFormat m e s s a g e
Return Value: D a t a identifier assigned b y Clipboard.
is freed
641
642
Part I I I — R e f e r e n c e s
SetClipboardViewer function SetClipboardViewer(Wnd: HWnd): HWnd; A d d s a w i n d o w t o t h e c h a i n o f w i n d o w s t o b e n o t i f i e d b y a wm_DrawClipboard message whenever the clipboard changes. Parameter Wnd
Description W i n d o w identifier
Return Value: Next w i n d o w in clipboard-viewer chain.
Cursor Procedures and Functions ClipCursor CreateCursor DestroyCursor GetCursorPos LoadCursor SetCursor SetCursorPos ShowCursor
ClipCursor procedure ClipCursor(Rect: LPRect); K e e p s c u r s o r w i t h i n Rect. I f Rect is n i l t h e c u r s o r is u n b o u n d e d . Parameter Rect
Description B o u n d i n g TRect i n s c r e e n c o o r d i n a t e s
CreateCursor function CreateCursor(Instance: THandle; Xhotspot, Yhotspot, Width, Height: Integer; ANDBitPlane, XORBitPlane: Pointer): HCursor; Creates a cursor.
L — W i n d o w M a n a g e r Interface P r o c e d u r e s a n d F u n c t i o n s
Parameters
643
Description
Instance
M o d u l e instance creating the cursor
Xhotspot, Yhotspot
Position o f cursor hotspot
Width
C u r s o r width (in pixels)
Height
C u r s o r h e i g h t (in p i x e l s )
ANDBitPlane
Array o f b y t e s c o n t a i n i n g AND m a s k
XORBitPlane
Array o f b y t e s c o n t a i n i n g XOR m a s k
Return Value: C u r s o r i d e n t i f i e r if s u c c e s s f u l ; e l s e 0.
DestroyCursor function D e s t r o y C u r s o r ( C u r s o r :
HCursor): Bool;
D e s t r o y s c u r s o r a n d frees a s s o c i a t e d m e m o r y . Parameter Cursor
Description C u r s o r identifier
Return Value: N o n z e r o if s u c c e s s f u l ; e l s e 0.
GetCursorPos procedure G e t C u r s o r P o s ( v a r
Point: TPoint);
Gets the screen coordinates o f the cursor's current position. Parameter Point
Description R e c e i v i n g TPoint s t r u c t u r e
LoadCursor function LoadCursor(Instance: THandle; CursorName: PChar): HCursor; Loads the n a m e d cursor resource.
644
Part I I I — R e f e r e n c e s
Parameters
Description
Instance
M o d u l e i n s t a n c e w h o s e e x e c u t a b l e file c o n t a i n s t h e cursor or 0 for predefined cursor
CursorName
String (null-terminated) o r integer I D n a m e o r a pred e f i n e d c u r s o r , s p e c i f i e d w i t h o n e o f t h e idc_ Standard c u r s o r I D s ' c o n s t a n t s .
Return Value: C u r s o r i d e n t i f i e r if s u c c e s s f u l ; 0 if c u r s o r is n o t f o u n d ; u n d e f i n e d if n o t a c u r s o r resource.
SetCursor function SetCursor(Cursor: HCursor): HCursor; Sets the cursor shape t o the specified cursor resource. Parameter Cursor
Description C u r s o r resource identifier (previously returned by LoadCursor)
Return Value: P r e v i o u s c u r s o r s h a p e ; 0 if n o p r e v i o u s c u r s o r .
SetCursorPos procedure SetCursorPos(X, Y: Integer); M o v e s t h e c u r s o r t o t h e s p e c i f i e d s c r e e n c o o r d i n a t e s . T h e p o s i t i o n is a d j u s t e d if it lies o u t s i d e t h e ClipCursor r e c t a n g l e . Parameter X, Y
Description N e w p o s i t i o n (in s c r e e n c o o r d i n a t e s ) o f t h e c u r s o r
ShowCursor function ShowCursor(Show: Bool): Integer; S h o w s t h e c u r s o r if its d i s p l a y c o u n t (initially set t o 0 ) is g r e a t e r t h a n o r e q u a l t o 0 . O t h e r w i s e t h e c u r s o r is h i d d e n .
L — W i n d o w M a n a g e r Interface P r o c e d u r e s a n d F u n c t i o n s
Parameter Show
Description N o n z e r o to increment display c o u n t or 0 to decrement display c o u n t
Return Value: N e w display count.
Dialog-Box Procedures and Functions CheckDlgButton CheckRadioButton CreateDialog CreateDialogIndirect CreateDialoglndirectParam CreateDialogParam DefDlgProc DialogBox DialogBoxIndirect DialogBoxIndirectParam DialogBoxParam DlgDirList DlgDirListComboBox DlgDirSelect DlgDirSelectComboBox EndDialog GetDialogBaseUnits GetDlgCtrllD GetDlgltem GetDlgltemlnt GetDlgltemText GetNextDlgGroupItem GetNextDlgTabltem IsDialogMessage IsDlgButtonChecked MapDialogRect SendDlgltemMessage SetDlgltemlnt SetDlgltemText
645
6 4 6 Part III—References
CheckDlgButton procedure CheckDlgButton(Dig: HWnd; IDButton: Integer; Check: Word); Places or removes a check mark from a button control or changes the state of a 3-button control. Parameters
Description
Dig
Dialog box that contains the button
IDButton
Button control to be modified
Check
R e m o v e d (0), checked (1), grayed (2)
CheckRadioButton procedure CheckRadioButton(Dlg: HWnd; IDFirstButton, IDLastButton, IDCheckButton: Integer); Checks IDCheckButton and removes the check mark from the group of radio buttons specified by IDFirstButton and IDLastButton. Parameters
Description
Dig
Dialog box
IDFirstButton
ID offirstradio button in group
IDLastButton
ID of last radio button in group
IDCheckButton
ID of radio button to check
CreateDialog function (Instance: THandle; TemplateName: PChar; WndParent: HWnd DialogFunc: TFarProc): HWnd; Creates a modeless dialog box defined by TemplateName dialog box resource. Parameters
Description
Instance
Module instance whose executablefilecontains the dialog box resource
TemplateName
Dialog box resource n a m e (null-terminated)
WndParent
Parent w i n d o w of the dialog box
DialogFunc
Dialog function procedure-instance address or nil if class defined
L — W i n d o w M a n a g e r Interface P r o c e d u r e s a n d F u n c t i o n s
647
Return Value: D i a l o g b o x w i n d o w h a n d l e if s u c c e s s f u l ; e l s e 0.
CreateDialoglndirect function CreateDialoglndirect(Instance: THandle; DialogTemplate: PChar; Parent: HWnd; DialogFunc: TFarProc): HWnd; Creates a modeless dialog b o x defined by dialog template. Parameters
Description
Instance
M o d u l e instance
DialogTemplate
Structure containing dialog b o x template
WndParent
O w n i n g w i n d o w o f the dialog b o x
DialogFunc
Dialog callback function procedure-instance address
Return Value: D i a l o g b o x w i n d o w h a n d l e if s u c c e s s f u l ; e l s e 0.
CreateDMoglndirectParam function CreateDialogIndirectParam(Instance: THandle; v a r DialogTemplate; WndParent: HWnd; DialogFunc: TFarProc; InitParam: Longint): HWnd; C r e a t e s t h e m o d e l e s s d i a l o g b o x d e f i n e d b y d i a l o g t e m p l a t e . It differs f r o m CreateDialoglndirect b e c a u s e it a l l o w s y o u t o p a s s a p a r a m e t e r , InitParam, t o t h e callback f u n c t i o n . Parameters
Description
Instance
M o d u l e instance
DialogTemplate
Structure containing dialog b o x template
WndParent
O w n i n g w i n d o w of the dialog b o x
DialogFunc
D i a l o g f u n c t i o n p r o c e d u r e - i n s t a n c e a d d r e s s , o r n i l if class d e f i n e d
InitParam
V a l u e p a s s e d t o d i a l o g f u n c t i o n (lParam o f wm_I nit Dialog m e s s a g e ) w h e n t h e d i a l o g b o x is created
Return Value: D i a l o g b o x w i n d o w h a n d l e if s u c c e s s f u l ; e l s e 0.
648
Part III—References
CreateDialogParam f u n c t i o n C r e a t e D i a l o g P a r a m ( I n s t a n c e : THandle; TemplateName: W n d P a r e n t : HWnd; D i a l o g F u n c : T F a r P r o c ; I n i t P a r a m : L o n g i n t ) : HWnd; Creates a modeless dialog b o x defined by TemplateName.
Parameter
Description
Instance
M o d u l e instance w h o s e executable file contains the dialog b o x template
TemplateName
Dialog b o x template n a m e (null-terminated)
Parent
O w n i n g w i n d o w o f the dialog b o x
DialogFunc
D i a l o g function procedure-instance address, o r nil if class defined
InitParam
Value passed to dialog function (lParam o f w m l n i t D i a l o g message) w h e n the dialog b o x is created
Return Value: Dialog b o x w i n d o w handle if successful; else 0.
DefDlgProc function lParam:
DefDlgProc(Dig: Longint):
HWnd; M s g , wParam: Word;
Longint;
Supplies default processing for dialogs with a private w i n d o w class.
Parameters
Description
Dig
Dialog b o x identifier
Msg
Message n u m b e r
wParam
M e s s a g e - d e p e n d e n t information
lParam
Message-dependent information
Return Value: Result o f the message processing.
PChar
L — W i n d o w M a n a g e r Interface P r o c e d u r e s a n d F u n c t i o n s
DialogBox function DialogBox(Instance: THandle; TemplateName: PChar; WndParent: HWnd; DialogFunc: TFarProc): Integer; C r e a t e s a m o d a l d i a l o g b o x d e f i n e d b y TemplateName a n d s e n d s wm_I nit Dialog before displaying the dialog. Parameters
Description
Instance
M o d u l e i n s t a n c e w h o s e e x e c u t a b l e file c o n t a i n s t h e dialog b o x template
TemplateName
Dialog b o x template n a m e (null-terminated)
WndParent
Owning window
DialogFunc
Dialog callback function procedure-instance address
Return Value: EndDialog nResult p a r a m e t e r ; - 1 if d i a l o g c o u l d n o t b e c r e a t e d .
DialogBoxIndirect function DialogBoxIndirect(Instance,
DialogTemplate:THandle;
WndParent: HWnd; DialogFunc: TFarProc): Integer; Creates the modal dialog b o x defined by dialog template, and sends wmlnitDialog before displaying the dialog. Parameters
Description
Instance
M o d u l e i n s t a n c e w h o s e e x e c u t a b l e file c o n t a i n s t h e dialog b o x template
DialogTemplate
Global memory block containing dialog template structure
WndParent
Owning window
DialogFunc
Dialog callback function procedure-instance address
Return Value: EndDialog nResult p a r a m e t e r ; - 1 if d i a l o g c o u l d n o t b e c r e a t e d .
continues
649
650
Part III—References
DialogBoxIndirectParam function
DialogBoxIndirectParam(Instance,
WndParent:
HWnd; D i a l o g F u n c :
TFarProc;
DialogTemplate: InitParam:
THandle;
Longint):
Integer
Creates the modal dialog b o x defined by dialog template and sends w m _ I n i t D i a l o g before displaying the dialog. Also, D i a l o g B o x I n d i r e c t P A r a m a l l o w s y o u t o s e n d a n initial p a r a m e t e r t o t h e c a l l b a c k f u n c t i o n . Parameters
Description
Instance
M o d u l e instance
w h o s e e x e c u t a b l e file c o n t a i n s t h e
dialog b o x template DialogTemplate
Global memory block containing dialog template structure
WndParent
Owning window
DialogFunc
Dialog function procedure-instance address
InitParam
P a s s e d in l P a r a m o f w m _ I n i t D i a l o g m e s s a g e
Return Value: E n d D i a l o g n R e s u l t parameter; - 1 if d i a l o g c o u l d n o t b e c r e a t e d .
DialogBoxParam function
DialogBoxParam(Instance:
Parent:
HWnd; D i a l o g F u n c :
THandle;
TFarProc;
TemplateName:
InitParam:
PChar;
Longint):
Integer;
Creates the m o d a l dialog b o x defined by T e m p l a t e N a m e and sends wm_I n i t D i a l o g b e f o r e d i s p l a y i n g t h e d i a l o g . A l s o a l l o w s y o u t o s e n d a n initial parameter to the callback function. Parameters
Description
Instance
M o d u l e instance w h o s e e x e c u t a b l e file c o n t a i n s t h e dialog b o x template
TemplateName
Dialog b o x template n a m e (null-terminated)
Parent
Owning window
DialogFunc
Dialog function procedure-instance address
InitParam
P a s s e d in l P a r a m o f w m _ I n i t D i a l o g m e s s a g e
Return Value: E n d D i a l o g n R e s u l t parameter; - 1 if d i a l o g c o u l d n o t b e c r e a t e d .
L—Window Manager Interface Procedures and Functions
DlgDMist function DlgDirList(Dig: HWnd; PathSpec: PChar; IDListBox, IDStaticPath: Integer; Filetype: Word): Integer; Fills IDListBox with a file or directory listing that matches the path name specified by PathSpec. Parameter
Description
Dig
Dialog box containing IDListBox
PathSpec
Path name string (null-terminated)
IDListBox
List-box control ID
IDStaticPath
Static-text control ID to display current drive and directory
Filetype
$0000 (read/write), $0001 (read-only), $0002 (hidden), $0004 (system), $0010 (subdirectories), $0020 (archives), $2000 (lb_Dir), $4000(drives), $8000 (exclusive)
Return
Value:
Nonzero if listing made; 0 if invalid search path.
DlgDirListComboBox function DlgDirListComboBox(Dig: HWnd; PathSpec: PChar; IDComboBox, IDStaticPath: Integer; Filetype: Word): Integer; Fills IDComboBox with afileor directory listing that matches the path name specified by PathSpec. Parameters
Description
Dig
Dialog box containing IDComboBox
PathSpec
Path name string (null-terminated)
IDComboBox
Combo box control ID
IDStaticPath
Static-text control ID to display current drive and directory
Filetype
$0000 (read/write), $0001 (read-only), $0002 (hidden), $0004 (system), $0010 (subdirectories), $0020 (archives), $2000 (lb_Dir), $4000(drives), $8000 (exclusive)
Return
Value:
Nonzero if listing made; 0 if invalid search path.
651
652
Part I I I — R e f e r e n c e s
DlgDirSelect function DlgDirSelect(Dig: HWnd; Str: PChar; IDListBox: Integer): Bool; G e t s c u r r e n t list-box s e l e c t i o n a n d fills Str. Parameter
Description
Dig
D i a l o g b o x c o n t a i n i n g IDListBox
Str
Path n a m e buffer
IDListBox
List-box control I D
Return Value: N o n z e r o if c u r r e n t s e l e c t i o n is a d i r e c t o r y ; e l s e 0.
DlgDirSelectComboBox function DlgDirSelectComboBox(Dig: IDComboBox: Integer): Bool;
HWnd; Str: PChar;
G e t s c u r r e n t c o m b o b o x s e l e c t i o n , f r o m a s i m p l e c o m b o b o x (cbs_Simple) o n l y , a n d fills Str. Parameters
Description
Dig
D i a l o g b o x c o n t a i n i n g IDComboBox
Str
Path n a m e buffer
IDComboBox
C o m b o b o x control I D
Return Value: N o n z e r o if c u r r e n t s e l e c t i o n is a d i r e c t o r y ; e l s e 0.
DlgDirSelect function DlgDirSelect(Dig: HWnd; Str: PChar; IDListBox: Integer): Bool; G e t s c u r r e n t list-box s e l e c t i o n a n d fills Str. Parameters
Description
Dig
D i a l o g b o x c o n t a i n i n g IDListBox
Str
Path n a m e buffer
IDListBox
List-box control I D
Return
Value:
N o n z e r o if c u r r e n t s e l e c t i o n is a d i r e c t o r y ; e l s e 0.
L — W i n d o w M a n a g e r Interface P r o c e d u r e s a n d F u n c t i o n s
DlgDirSelectComboBox function DlgDirSelectComboBox(Dig: IDComboBox: Integer): Bool;
HWnd; Str: PChar;
G e t s c u r r e n t c o m b o b o x s e l e c t i o n , f r o m a s i m p l e c o m b o b o x (cbs_Simple) o n l y , a n d fills Str. Parameters
Description
Dig
D i a l o g b o x c o n t a i n i n g IDComboBox
Str
Path n a m e buffer
IDComboBox
C o m b o b o x control I D
Return Value: N o n z e r o if c u r r e n t s e l e c t i o n is a d i r e c t o r y ; e l s e 0.
EndDialog procedure EndDialog(Dig: HWnd; Result: Integer); T e r m i n a t e s a m o d a l d i a l o g b o x . T h e v a l u e s p e c i f i e d b y R e s u 11 is r e t u r n e d t o t h e c r e a t i n g DialogBox f u n c t i o n . Parameters
Description
Dig
Dialog to b e destroyed
Result
Return value
GetDialogBaseUnits function GetDialogBaseUnits: Longint; Gets dialog base units. T h e base width represents the average system font w i d t h . T h e d i a l o g u n i t is U a n d V s t h e r e t u r n e d b a s e w i d t h a n d h e i g h t u n i t , respectively. 1
Return Value: H e i g h t (in p i x e l s ) , b a s e u n i t i n h i g h w o r d ; w i d t h ( i n p i x e l s ) , b a s e u n i t i n l o w word.
653
654
Part III—References
GetDlgCtrllD function
GetDlgCtrlID(Wnd:
HWnd):
Integer;
G e t s a control w i n d o w ' s I D value. Parameter
Description
Wnd
Control
Return Value: C o n t r o l ' s numeric identifier;
identifier
0 if error.
GetDlgltem function
GetDlgItem(Dlg:
G e t s a control handle Parameters
HWnd; I D D l g l t e m :
Integer):
HWnd;
contained in t h e specified dialog b o x . Description
Dig
D i a l o g b o x containing t h e control
IDDlgltem
Control ID
Return Value: C o n t r o l identifier;
0 if the specified control doesn't exist.
GetDlgltemlnt function
GetDlgltemlnt(Dig:
Translate:
LPBool;
Signed:
HWnd; I D D l g l t e m : Bool):
Integer;
Word;
Translates a control's text, in a dialog b o x , into an integer
value. Preceding
spaces are stripped. Parameter
Description
Dig
Dialog box
IDDlgltem
Item I D
Translate
Returned B o o l e a n value; 0 if translation error
Return Value: Translated value.
identifier
L — W i n d o w M a n a g e r Interface P r o c e d u r e s a n d F u n c t i o n s
655
GetDlgltemText f u n c t i o n G e t D l g l t e m T e x t ( D i g : HWnd; I D D l g l t e m : S t r : PChar; MaxCount: I n t e g e r ) : I n t e g e r ;
Integer;
G e t s a control's text. Parameters
Description
Dig
D i a l o g b o x identifier
IDDlgltem
Item I D
Str
Buffer to receive
MaxCount
Size o f buffer
text
Return Value: N u m b e r o f characters c o p i e d .
GetNextDlgGroupItem function GetNextDlgGroupItem(Dlg: P r e v i o u s : B o o l ) : HWnd;
HWnd; C t r l :
HWnd;
G e t s the next o r previous w s G r o u p style control from C t r l . T h e search is cyclical. Parameters
Description
Dig
D i a l o g b o x identifier
Ctrl
Search start control identifier
Previous
Z e r o to search for previous control o r n o n z e r o to search for next
Return
Value:
C o n t r o l identifier.
GetNextDlgTabltem function
GetNextDlgTabItem(Dlg:
HWnd; C t r l :
HWnd; P r e v i o u s :
Bool):
G e t s the next o r previous w s _ T a b S t o p style control f r o m C t r l . T h e search is cyclical.
HWnd;
656
Part I I I — R e f e r e n c e s
Parameters
Description
Dig
D i a l o g b o x identifier
Ctrl
S e a r c h start c o n t r o l i d e n t i f i e r
Previous
Z e r o to search for previous control o r n o n z e r o to search for n e x t
Return Value: C o n t r o l identifier.
IsDialogMessage function IsDialogMessage(Dig: HWnd; var Msg: TMsg): Bool; D e t e r m i n e s a n d p r o c e s s e s m e s s a g e s for m o d e l e s s d i a l o g b o x e s , c o n v e r t i n g keyboard messages into c o m m a n d messages. Parameters
Description
Digs
D i a l o g b o x identifier
Msg
TMsg s t r u c t u r e
Return Value: N o n z e r o if Msg p r o c e s s e d (TranslateMessage s h o u l d n ' t b e s e n t m e s s a g e s ) ; e l s e 0.
a n d DispatchMessage
IsDlgButtonChecked function IsDlgButtonChecked(Dlg: HWnd; IDButton: Integer): Word; D e t e r m i n e s w h e t h e r b u t t o n c o n t r o l is c h e c k e d . Parameters
Description
Dig
D i a l o g b o x identifier
IDButton
Button control I D
Return
Value:
N o n z e r o if c h e c k e d ; e l s e 0. F o r 3-state b u t t o n : g r a y e d (2), c h e c k e d (1), o r 0.
L — W i n d o w M a n a g e r Interface P r o c e d u r e s a n d F u n c t i o n s
MapDialogRect procedure MapDialogRect(Dig: HWnd; var Rect: TRect); C o n v e r t s d i a l o g b o x u n i t s i n Rect t o s c r e e n u n i t s . Parameters
Description
Dig
D i a l o g b o x identifier
Rect
TRect structure
SendDlgltemMessage function SendDlgItemMessage(Dlg: Msg,
HWnd; IDDlgltem:
Integer;
wParam: Word; lParam: Longint): Longint;
S e n d s a m e s s a g e t o a d i a l o g b o x c o n t r o l s p e c i f i e d b y IDDlgltem. T h e f u n c t i o n r e t u r n s after t h e m e s s a g e is p r o c e s s e d . Parameters
Description
Dig
D i a l o g b o x identifier
IDDlgltem
Integer I D o f destination dialog item
Msg
Message type
wParam
Additional message information
lParam
Additional message information
Return Value: V a l u e r e t u r n e d b y c o n t r o l ' s w i n d o w f u n c t i o n ; 0 if i n v a l i d IDDlgltem.
SetDlgltemlnt procedure SetDlgltemlnt(Dig: HWnd; IDDlgltem: Value: Word; Signed: Bool);
Integer;
S e t s t h e text o f a d i a l o g b o x c o n t r o l t o t h e c o n v e r t e d string v a l u e s p e c i f i e d b y Value.
657
658
Part I I I — R e f e r e n c e s
Parameters
Description
Dig
D i a l o g b o x identifier
IDDlgltem
Control's integer I D
Value
Set value
Signed
N o n z e r o if V a l u e is s i g n e d
SetDlgltemText procedure SetDlgltemText(Dig: HWnd; IDDlgltem: Integer; Str: PChar); S e t s t h e c a p t i o n o r text of a d i a l o g b o x c o n t r o l t o t h e v a l u e s p e c i f i e d b y Str. Parameters
Description
Dig
D i a l o g b o x identifier
IDDlgltem
Control's integer I D
Str
String (null-terminated)
Display and Movement Procedures and Functions ArrangeIconicWindows BeginDeferWindowPos BringWindowToTop CloseWindow DeferWindowPos EndDeferWindowPos GetClientRect GetWindowRect GetWindowText GetWindowTextLength Islconic IsWindowVisible IsZoomed MoveWindow Openlcon SetWindowPos SetWindowText ShowOwnedPopups ShowWindow
L — W i n d o w M a n a g e r Interface P r o c e d u r e s a n d F u n c t i o n s
ArrangelconicWindows function ArrangeIconicWindows(Wnd: HWnd): Word; A r r a n g e s icons
in a n MDI c l i e n t w i n d o w o r icons o n t h e d e s k t o p w i n d o w .
Parameters Wnd
Description Parent w i n d o w
Return Value: H e i g h t o f o n e row o f icons;
0 if n o
identifier
icons.
BeginDefer^lndowPos function BeginDeferWindowPos(NumWindows:
Integer): THandle;
Allocates m e m o r y for multiple window-position data structure. Parameters NumWindows
Description Initial n u m b e r o f w i n d o w s w i t h p o s i t i o n information
that
needs to b e stored. Return Value: Window-position
structure
identifier.
BrmgWmdowToTop procedure BringWindowToTop(Wnd:
HWnd);
Activates a n d b r i n g s Wnd t o t o p o f a stack o f o v e r l a p p i n g w i n d o w s . Parameters Wnd
Description P o p - u p or child w i n d o w
CloseWindow procedure CloseWindow(Wnd: HWnd); M i n i m i z e s Wnd. I c o n s f o r o v e r l a p p e d w i n d o w s are m o v e d into t h e icon area o f the screen. Parameters Wnd
Description Window
to be minimized
659
660
Part I I I — R e f e r e n c e s
DeferWindowPos function DeferWindowPos(WinPosInfo: THandle; Wnd, WndlnsertAfter: HWnd; X, Y, cX, cY: Integer; Flags: Word): THandle; U p d a t e s WinPosInf o f o r t h e w i n d o w i d e n t i f i e d b y Wnd. Parameters
Description
WinPosInfo
Multiple w i n d o w - p o s i t i o n data structure identifier
Wnd
U p d a t e i n f o r m a t i o n is s t o r e d r e g a r d i n g this w i n d o w
WndlnsertAfter
Wnd is i n s e r t e d after this w i n d o w
X, Y
W i n d o w s upper-left corner position
cX
Window's n e w width
cY
Window's n e w height
Flags
O n e o f t h e swp_ Set w i n d o w p o s i t i o n
Return
flags
Value:
U p d a t e d multiple window-position data structure.
EndDeferWindowPos procedure EndDeferWindowPos(WinPosInfo:
THandle);
I n a s i n g l e s c r e e n - r e f r e s h c y c l e , EndDef erWindowPos u p d t a e s t h e size a n d position of o n e or more windows. Parameters WinPosInfo
Description Multiple w i n d o w data structure containing u p d a t e information for multiple windows
GetClientRect procedure GetClientRect(Wnd: HWnd; var Rect: TRect); G e t s a w i n d o w ' s client coordinates. Parameters
Description
Wnd
W i n d o w identifier
Rect
TRect t o r e c e i v e c l i e n t c o o r d i n a t e s
L — W i n d o w M a n a g e r Interface P r o c e d u r e s a n d F u n c t i o n s
GetWindowRect procedure GetWindowRect(Wnd: HWnd; var Rect: TRect); G e t s t h e d i m e n s i o n s o f a w i n d o w ' s b o u n d i n g r e c t a n g l e i n t o Rect ( i n s c r e e n coordinates). Parameters
Description
Wnd
W i n d o w identifier
Rect
R e c e i v i n g TRect s t r u c t u r e
GetWindowText function GetWindowText(Wnd: HWnd; Str: PChar; MaxCount: Integer): Integer; C o p i e s w i n d o w ' s c a p t i o n o r a c o n t r o l ' s text i n t o Str. Parameters
Description
Wnd
W i n d o w o r control identifier
Str
R e c e i v i n g string b u f f e r
MaxCount
Size o f Str
Return Value: N u m b e r o f b y t e s c o p i e d ; 0 if n o text.
GetWIndowTextLength function GetWindowTextLength(Wnd: HWnd): Integer; G e t s a w i n d o w ' s c a p t i o n o r a c o n t r o l ' s text l e n g t h . Parameters Wnd
Description W i n d o w o r control identifier
Return Value: Text length.
Islconic function IsIconic(Wnd: HWnd): Bool; D e t e r m i n e s w h e t h e r a w i n d o w is i c o n i c ( m i n i m i z e d ) .
661
662
Part I I I — R e f e r e n c e s
Parameters Wnd
Description W i n d o w identifier
Return Value: N o n z e r o if m i n i m i z e d ; e l s e 0.
IsWindowVisible function IsWindowVisible(Wnd: HWnd): Bool; D e t e r m i n e s w h e t h e r ShowWindow h a s m a d e a w i n d o w v i s i b l e . Parameters Wnd Return
Description W i n d o w identifier
Value:
N o n z e r o if w i n d o w exists o n - s c r e e n ( e v e n if it is c o v e r e d ) ; e l s e 0.
IsZoomed function IsZoomed(Wnd: HWnd): Bool; D e t e r m i n e s w h e t h e r a w i n d o w is m a x i m i z e d . Parameters Wnd
Description W i n d o w identifier
Return Value: N o n z e r o if m a x i m i z e d ; e l s e 0.
MoveWindow procedure MoveWindow(Wnd: HWnd; X, Y, Width, Height: Integer; Repaint: Bool); S e n d s a wm_Size m e s s a g e t o a w i n d o w . Width a n d Height v a l u e s p a s s e d w i t h wm_Size a r e t h o s e o f t h e c l i e n t a r e a . Parameters
Description
Wnd
P o p - u p o r child w i n d o w identifier
X, Y
N e w upper-left corner o f w i n d o w
Width
N e w window width
Height
N e w w i n d o w height
Repaint
N o n z e r o t o r e p a i n t w i n d o w after m o v i n g
L — W i n d o w M a n a g e r Interface P r o c e d u r e s a n d F u n c t i o n s
Openlcon function Openlcon(Wnd: HWnd): Bool; R e s t o r e s a m i n i m i z e d w i n d o w t o its o r i g i n a l size a n d p o s i t i o n . Parameters Wnd Return
Description W i n d o w identifier
Value:
N o n z e r o if s u c c e s s f u l ; e l s e 0.
SetWindowPos procedure SetWindowPos(Wnd, WndlnsertAfter: HWnd; X , Y , c x , c y : Integer; Flags: Word); C h a n g e s t h e size, position, a n d ordering o f a w i n d o w . Parameters
Description
Wnd
W i n d o w identifier
WndlnsertAfter
P r e c e d i n g w i n d o w i n w i n d o w m a n a g e r ' s list
X, Y
Upper-left corner
cx
N e w window width
cy
N e w w i n d o w height
Flags
O n e o f t h e swp_ Set w i n d o w - p o s i t i o n
flags
SetWindowText procedure SetWindowText(Wnd: HWnd; Str: PChar); S e t s t h e c a p t i o n title f o r a w i n d o w o r text o f a c o n t r o l w i t h Str. Parameters
Description
Wnd
W i n d o w o r control identifier
Str
String (null-terminated)
ShowOwnedPopups procedure ShowOwnedPopups(Wnd: HWnd; Show: Bool); S h o w s o r h i d e s , as s p e c i f i e d b y Show, all p o p - u p w i n d o w s a s s o c i a t e d w i t h t h e specified w i n d o w .
663
664
Part I I I — R e f e r e n c e s
Parameters
Description
Wnd
W i n d o w identifier
Show
N o n z e r o t o s h o w all h i d d e n p o p u p s o r 0 t o h i d e all visible p o p - u p s
ShowWindow function ShowWindow(Wnd: HWnd; CmdShow: Integer): Bool; S h o w s o r h i d e s a w i n d o w s p e c i f i e d b y CmdShow. Parameters
Description
Wnd
W i n d o w identifier
CmdShow
O n e of t h e sw_ Show w i n d o w c o n s t a n t s
Return Value: N o n z e r o if w i n d o w w a s p r e v i o u s l y v i s i b l e ; 0 if w i n d o w w a s p r e v i o u s l y h i d d e n .
Error Procedures and Functions FlashWindow MessageBeep MessageBox
FlashWindow function FlashWindow(Wnd: HWnd; Invert: Bool): Bool; F l a s h e s a w i n d o w o r i c o n a n d inverts a n o p e n w i n d o w ' s active s t a t u s . Parameters
Description
Wnd
W i n d o w to b e flashed
Invert
N o n z e r o t o flash o r 0 t o r e t u r n t o o r i g i n a l state ( i g n o r e d for icons)
Return
Value:
N o n z e r o if w i n d o w w a s active p r e v i o u s t o call; e l s e 0.
L — W i n d o w M a n a g e r Interface P r o c e d u r e s a n d F u n c t i o n s
MessageBeep procedure MessageBeep(BeepType: Word); B e e p s t h e system speaker. Parameters BeepType
Description Set to 0
MessageBox function MessageBox(Parent: HWnd; Txt, Caption: PChar; TextType: Word):
Integer;
Creates a n d displays a dialog b o x containing t h e specified message a n d caption a n d a n y p r e d e f i n e d i c o n s a n d p u s h - b u t t o n as s p e c i f i e d b y TextType. Parameters
Description
Parent
O w n i n g window of message b o x
Txt
Message t o display (null-terminated)
Caption
D i a l o g - b o x c a p t i o n ( n u l l - t e r m i n a t e d ) o r n i l f o r "Error"
TextType
O n e o r a c o m b i n a t i o n o f t h e m b _ M e s s a g e b o x flags' constants
Return Value: O n e o f t h e I D d i a l o g - b o x c o m m a n d I D s if s u c c e s s f u l ; 0 if t h e r e ' s n o t e n o u g h m e m o r y t o create a n d display message b o x .
Hardware Procedures and Functions EnableHardwarelnput GetAsyncKeyState GetlnputState GetKeyboardState GetKeyNameText GetKeyState GetKBCodePage OemKeyScan SetKeyboardState MapVirtualKey VkKeyScan
665
666
Part I I I — R e f e r e n c e s
EnableHardwarelnput function EnableHardwarelnput(Enablelnput:
Bool): Bool;
D i s a b l e s m o u s e a n d k e y b o a r d i n p u t , s a v i n g o r d i s c a r d i n g i n p u t as s p e c i f i e d b y Enablelnput. Parameters Enablelnput
Description N o n z e r o t o save i n p u t ; 0 t o d i s c a r d i n p u t
Return Value: N o n z e r o ( t h e d e f a u l t ) if i n p u t w a s p r e v i o u s l y e n a b l e d ; e l s e 0.
GetAsyncKeyState function GetAsyncKeyState(Key:
Integer): Integer;
D e t e r m i n e s t h e state o f a virtual k e y . Parameters Key
Description Virtual-key c o d e
Return Value: Key is d o w n if h i g h - o r d e r bit is 1.
GetlnputState function GetlnputState: Bool; Determines whether the system q u e u e currently contains m o u s e , keyboard, or timer events. Return Value: N o n z e r o if i n p u t d e t e c t e d ; e l s e 0 .
GetKeyboardState procedure GetKeyboardState(var
KeyState: Byte);
C o p i e s t h e virtual k e y b o a r d key-set status i n t o KeyState. I f h i g h bit o f b y t e is 1, k e y is d o w n . I f l o w bit is 1, k e y w a s p r e s s e d o d d n u m b e r o f t i m e s s i n c e system start-up. Parameters KeyState
Description 256-byte c h a r a c t e r array
L — W i n d o w M a n a g e r Interface P r o c e d u r e s a n d F u n c t i o n s
GetKeyNameText function GetKeyNameText(lParam:
Longint; Buffer: PChar;
Size: Integer): Integer; G e t s k e y n a m e string f o r k e y s l o n g e r t h a n a s i n g l e c h a r a c t e r . Parameters
Description
lParam
Long parameter to wmKeyDown message
Buffer
Receiving buffer
Size
Size o f buffer
Return Value: N u m b e r o f bytes c o p i e d .
GetKeyState function GetKeyState(VirtKey:
Integer): Integer;
D e t e r m i n e s w h e t h e r t h e state of a virtual k e y is u p , d o w n , o r t o g g l e d . Parameters VirtKey
Description Virtual key
Return Value: K e y is d o w n if h i g h - o r d e r bit is 1; K e y is t o g g l e d if l o w - o r d e r bit is 1.
GetKBCodePage function GetKBCodePage:
Integer;
G e t s the currently loaded O E M o r A N S I table. Return Value: C u r r e n t c o d e p a g e : (437) (850) (860) (861) (863) (865)
USA International Portugal Iceland French Canadian Norway/Denmark
667
668
Part I I I — R e f e r e n c e s
OemKeyScan function OemKeyScan(OemChar: Word): Longint; M a p s OemCh a r i n t o O E M ( I B M c h a r a c t e r set) s c a n c o d e s . T h e O E M c h a r a c t e r set is t h e I B M c h a r a c t e r set. Parameters OemChar Return
Description O E M A S C I I c h a r a c t e r c o d e (0 t o $ 0 F F )
Value.
S c a n c o d e a n d shift state (bit 2 C t r l k e y , bit 1 Shift k e y p r e s s e d ) i n l o w - a n d h i g h o r d e r w o r d , r e s p e c t i v e l y , if s u c c e s s f u l ; else - 1 i n l o w - a n d h i g h - o r d e r w o r d .
SetKeyboardState procedure SetKeyboardState(var
KeyState: Byte);
C o p i e s KeyState i n t o W i n d o w s k e y b o a r d - s t a t e t a b l e . Parameters KeyState
Description A r r a y o f 2 5 5 b y t e s c o n t a i n i n g k e y states
MapVirtualKey function MapVirtualKey(Code, MapType: Word): Word; M a p s a virtual-key o r s c a n c o d e f o r a k e y t o its c o r r e s p o n d i n g s c a n c o d e , virtualk e y c o d e , o r A S C I I v a l u e as s p e c i f i e d b y MapType. Parameters
Description
Code
Virtual-key o r scan c o d e for a key d e t e r m i n e d by MapType v a l u e
MapType
(0) virtual-key c o d e , (1) s c a n c o d e , (2) virtual-key c o d e
Return
Value:
MapType v a l u e s : 0 r e t u r n s s c a n c o d e ; 1 r e t u r n s virtual-key c o d e ; 2 r e t u r n s unshifted ASCII value.
VkKeyScan function VkKeyScan(AChar: Word): Word; T r a n s l a t e s AChar i n t o its c o r r e s p o n d i n g virtual-key c o d e a n d shift state.
L — W i n d o w M a n a g e r Interface P r o c e d u r e s a n d F u n c t i o n s
Parameters AChar Return
669
Description A N S I c h a r a c t e r t o find c o r r e s p o n d i n g virtual-key c o d e
Value:
V i r t u a l - k e y c o d e i n t h e l o w - o r d e r b y t e ; t h e f o l l o w i n g shift states i n t h e h i g h order byte: (0) N o shift (1) S h i f t e d (2) C o n t r o l c h a r (6) C o n t r o l + A l t (7) S h i f t + C o n t r o l - A l t or ( 3 ) , ( 4 ) , or ( 5 ) , w h i c h a r e n ' t u s e d for c h a r a c t e r s If t h e r e ' s a n e r r o r , b o t h b y t e s a r e - 1 .
Hook Procedures and Functions CallMsgFilter DefHookProc SetWindowsHook UnhookWindowsHook
CallMsgFilter function CallMsgFilter(var Msg: TMsg; Code: Integer): Bool; S e n d s Msg t o t h e c u r r e n t m e s s a g e filter f u n c t i o n . Parameters
Description
Msg
TMsg c o n t a i n i n g m e s s a g e t o b e
Code
Filter f u n c t i o n c o d e
filtered
Return Value: 0 if m e s s a g e s h o u l d b e p r o c e s s e d ; e l s e n o n z e r o .
DefHookProc function DefHookProc(Code: Integer; wParam: Word; lParam: Longint; NextHook: TFarProc): Longint; C a l l s n e x t f u n c t i o n i n c h a i n o f h o o k ( m e s s a g e filter) f u n c t i o n s .
670
Part I I I — R e f e r e n c e s
Parameters
Description
Code
D e t e r m i n e s how m e s s a g e is p r o c e s s e d
wParam
Message word parameter
lParams
Message long parameter
NextHook
T F a r P r o c t o n e x t hook
Return
function
Value:
A value depending o n code.
SetWindowsHook function
SetWindowsHook(FilterType:
FilterFunc:
TFarProc):
Integer;
TFarProc;
Installs a filter f u n c t i o n i n t h e c h a i n o f filter f u n c t i o n s s p e c i f i e d b y F i l t e r T y p e . T h e filter f u n c t i o n is p a s s e d a C o d e , wParam, a n d l P a r a m , w h i c h h a v e v a l u e s that are f i l t e r - t y p e - d e p e n d e n t . Parameters
Description
FilterType
O n e of the wh_ Windows h o o k codes
FilterFunc
Filter f u n c t i o n ' s p r o c e d u r e - i n s t a n c e a d d r e s s
Return
Value:
P r o c e d u r e - i n s t a n c e a d d r e s s o f p r e v i o u s l y i n s t a l l e d filter f u n c t i o n ; nil if n o p r e v i o u s filter.
UnhookWindowsHook function
UnhookWindowsHook(Hook:
R e m o v e s a hook Parameters
Integer;
f u n c t i o n f r o m t h e c h a i n o f hook
HookFunc:
f u n c t i o n s s p e c i f i e d b y Hook.
Description
Hook
O n e o f w h _ Windows hook
HookFunc
Hook f u n c t i o n ' s p r o c e d u r e - i n s t a n c e a d d r e s s
Return Value: N o n z e r o if s u c c e s s f u l ; e l s e 0.
TFarProc):
codes
Bool
L — W i n d o w M a n a g e r Interface P r o c e d u r e s a n d F u n c t i o n s
671
Information Procedures and Functions AnyPopup ChildWindowFromPoint EnumChildWindows EnumTaskWindows EnumWindows FindWindow GetNextWindow GetParent GetTopWindow GetWindow GetWindowTask IsChild IsWindow SetParent WindowFromPoint
AnyPopup function AnyPopup: Bool; D e c i d e s w h e t h e r a p o p - u p w i n d o w is o n t h e s c r e e n . Return Value: N o n z e r o if p o p - u p w i n d o w e x i s t s ; e l s e 0.
ChildWindowFromPoint function ChildWindowFromPoint(WndParent: HWnd; APoint: TPoint): HWnd; D e t e r m i n e s w h i c h c h i l d w i n d o w o w n e d b y WndParent c o n t a i n s APoint. Parameters
Description
WndParent
Parent w i n d o w
APoint
TPoint s t r u c t u r e of c l i e n t c o o r d i n a t e s t o b e t e s t e d
Return
Value:
C h i l d w i n d o w that c o n t a i n s t h e p o i n t ; 0 if p o i n t lies o u t s i d e t h e p a r e n t w i n d o w ; WndParent if t h e p o i n t is n o t c o n t a i n e d i n a n y c h i l d w i n d o w .
672
Part I I I — R e f e r e n c e s
EnumChildWindows function EnumChildWindows(WndParent: HWnd; EnumFunc: TFarProc; lParam: Longint): Bool; Enumerates child w i n d o w s o f given parent, passing the child handle a n d lParam t o t h e c a l l b a c k . E n u m e r a t i o n e n d s if t h e callback r e t u r n s 0 o r t h e last c h i l d is e n u m e r a t e d . Parameters
Description
WndParent
Parent w i n d o w o f child w i n d o w s t o e n u m e r a t e
EnumFunc
Callback f u n c t i o n ' s p r o c e d u r e - i n s t a n c e a d d r e s s
lParam
V a l u e p a s s e d t o callback f u n c t i o n
Return Value: N o n z e r o if all c h i l d w i n d o w s h a v e b e e n e n u m e r a t e d ; e l s e 0.
EnumTaskWindows function EnumTaskWindows(Task: THandle; EnumFunc: TFarProc; lParam: Longint): Bool; E n u m e r a t e s all w i n d o w s i n a task, p a s s i n g t h e w i n d o w h a n d l e a n d lParam t o t h e callback. E n u m e r a t i o n e n d s if t h e callback r e t u r n s 0 o r all w i n d o w s a r e enumerated. Parameters
Description
Task
Task identifier
EnumFunc
Callback f u n c t i o n ' s p r o c e d u r e - i n s t a n c e a d d r e s s
lParam
V a l u e p a s s e d t o callback
Return Value: N o n z e r o if all w i n d o w s a r e e n u m e r a t e d ; e l s e 0.
EnumWindows function EnumWindows(EnumFunc: TFarProc; lParam: Longint): Bool; E n u m e r a t e s all p a r e n t w i n d o w s o n t h e s c r e e n p a s s i n g t h e w i n d o w h a n d l e a n d lParam t o t h e callback. E n u m e r a t i o n e n d s if t h e callback r e t u r n s 0 o r all w i n d o w s are e n u m e r a t e d .
L — W i n d o w M a n a g e r Interface P r o c e d u r e s a n d F u n c t i o n s
Parameters
Description
EnumFunc
Callback f u n c t i o n ' s p r o c e d u r e - i n s t a n c e a d d r e s s
lParam
V a l u e p a s s e d t o callback
Return
Value:
N o n z e r o if all w i n d o w s a r e e n u m e r a t e d ; e l s e 0.
FindWindow function FindWindow(ClassName, WindowName: PChar): HWnd; F i n d s a t o p - l e v e l p a r e n t w i n d o w w i t h m a t c h i n g ClassName a n d WindowName d o e s not search child w i n d o w s . Parameters
Description
ClassName
W i n d o w ' s class n a m e ( n u l l - t e r m i n a t e d o r n i l f o r all)
WindowName
W i n d o w ' s text c a p t i o n o r 0 f o r all
Return Value: W i n d o w h a n d l e ; 0 if n o w i n d o w .
GetNextWindow function GetNextWindow(Wnd: HWnd; Flag: Word): HWnd; G e t s n e x t o r p r e v i o u s w i n d o w f r o m Wnd, if t o p - l e v e l w i n d o w s e a r c h e s f o r n e x t t o p - l e v e l w i n d o w o r if c h i l d w i n d o w s e a r c h e s f o r n e x t c h i l d w i n d o w . Parameters
Description
Wnd
W i n d o w identifier
Flag
O n e o f t h e gw_ Get w i n d o w c o n s t a n t s : gw_HWndNext o r gwJHWndPrev
Return Value: W i n d o w identifier.
GetParent function GetParent(Wnd: HWnd): HWnd; Gets a window's parent w i n d o w handle.
673
674
Part I I I — R e f e r e n c e s
Parameters Wnd
Description W i n d o w identifier
Return Value: P a r e n t w i n d o w i d e n t i f i e r ; 0 if n o p a r e n t w i n d o w .
GetTopWindow function GetTopWindow(Wnd: HWnd): HWnd; G e t s a w i n d o w ' s top-level child w i n d o w . Parameters Wnd
Description Parent w i n d o w identifier
Return Value: C h i l d w i n d o w i d e n t i f i e r ; 0 if n o c h i l d w i n d o w .
GetWindow function GetWindow(Wnd: HWnd; Cmd: Word): HWnd; G e t s t h e w i n d o w w i t h t h e r e l a t i o n s h i p s p e c i f i e d i n Cmd t o t h e w i n d o w s p e c i f i e d i n Wnd. Parameters
Description
Wnd
Original w i n d o w
Cmd
O n e of t h e gw_ Get w i n d o w c o n s t a n t s
Return
Value:
W i n d o w i d e n t i f i e r ; 0 if w i n d o w is n o t f o u n d o r if i n v a l i d Cmd.
GetWindowTask function GetWindowTask(Wnd: HWnd): THandle; G e t s a w i n d o w ' s a p p l i c a t i o n task i d e n t i f i e r . Parameters Wnd Return Value: Task identifier.
Description W i n d o w identifier
L — W i n d o w M a n a g e r Interface P r o c e d u r e s a n d F u n c t i o n s
IsChild function
IsChild(Parent,
Wnd: HWnd):
Bool;
D e t e r m i n e s w h e t h e r Wnd is a c h i l d w i n d o w o f P a r e n t . Parameters
Description
Parent
W i n d o w identifier
Wnd
Test w i n d o w
Return Value: N o n z e r o if c h i l d w i n d o w ; e l s e 0.
IsWindow function
IsWindow(Wnd:
HWnd):
Bool;
D e t e r m i n e s w h e t h e r Wnd is a v a l i d w i n d o w . Parameters Wnd Return
Description W i n d o w identifier
Value:
N o n z e r o if v a l i d ; e l s e 0.
SetParent function
SetParent(WndChild,
WndNewParent:
HWnd): HWnd;
C h a n g e s the parent o f a child w i n d o w to WndNewParent. Parameters
Description
WndChild
C h i l d w i n d o w identifier
WndNewParent
Parent w i n d o w identifier
Return Value: Previous parent w i n d o w .
WindowFromPoint function
WindowFromPoint(Point:
TPoint):
HWnd;
Decides which w i n d o w contains the specified point.
675
676
Part I I I — R e f e r e n c e s
Parameters Point
Description TPoint t o b e c h e c k e d (in s c r e e n c o o r d i n a t e s )
Return Value: W i n d o w i d e n t i f i e r ; 0 if t h e r e ' s n o w i n d o w at s p e c i f i e d p o i n t .
Input Procedures and Functions EnableWindow GetActiveWindow GetCapture GetCurrentTime GetDoubleClickTime GetFocus GetTickCount IsWindowEnabled KillTimer ReleaseCapture SetActiveWindow SetCapture SetDoubleClickTime SetFocus SetSysModalWindow SetTimer SwapMouseButton
EnableWindow function EnableWindow(Wnd: HWnd; Enable: Bool): Bool; Enables or disables m o u s e a n d keyboard input to a w i n d o w or control. Parameters
Description
Wnd
W i n d o w to be enabled or disabled
Enable
N o n z e r o to enable; 0 to disable
Return Value: N o n z e r o if s u c c e s s f u l ; e l s e 0.
L — W i n d o w M a n a g e r Interface P r o c e d u r e s a n d F u n c t i o n s
GetActiveWindow function GetActiveWindow: HWnd; G e t s t h e h a n d l e o f t h e w i n d o w that h a s t h e c u r r e n t i n p u t f o c u s . Return Value: Active w i n d o w identifier.
GetCapture function GetCapture: HWnd; G e t s t h e w i n d o w that is c u r r e n t l y r e c e i v i n g all m o u s e i n p u t . Return Value: W i n d o w t h a t h a s t h e m o u s e c a p t u r e ; 0 if n o w i n d o w .
GetCurrentTlme function GetCurrentTime: Longint; G e t s the elapsed time since the system w a s rebooted. Return Value: C u r r e n t t i m e (in m i l l i s e c o n d s ) .
GetDoubleCHckTime function GetDoubleClickTime: Word; G e t s t h e m a x i m u m t i m e b e t w e e n a series o f t w o m o u s e clicks (that is, a double-click). Return Value: C u r r e n t double-click time (in milliseconds)
GetFocus function GetFocus: HWnd; G e t s t h e w i n d o w that c u r r e n t l y h a s t h e i n p u t f o c u s . Return Value: W i n d o w i d e n t i f i e r if s u c c e s s f u l ; e l s e 0.
677
678
Part I I I — R e f e r e n c e s
GetTickCount function GetTickCount: Longint; G e t s t h e elapsed time since t h e system started. Return
Value:
E l a p s e d time (in milliseconds).
IsWindowEnabled function IsWindowEnabled(Wnd: HWnd): Bool; D e t e r m i n e s w h e t h e r a w i n d o w is e n a b l e d for m o u s e a n d k e y b o a r d i n p u t . Parameters
Description
Wnd Return
W i n d o w identifier Value:
N o n z e r o if e n a b l e d ; e l s e 0.
KillTimer function KillTimer(Wnd: HWnd; IDEvent: Integer): Bool; Kills a t i m e r e v e n t ; r e m o v e s a n y a s s o c i a t e d wm_Timer m e s s a g e s f r o m t h e message queue. Parameters
Description
Wnd
W i n d o w identifier
IDEvent
Timer event I D
Return Value: N o n z e r o if s u c c e s s f u l ; 0 if i n v a l i d IDEvent.
ReleaseCapture procedure
ReleaseCapture;
Releases m o u s e capture; restores n o r m a l input processing.
L — W i n d o w M a n a g e r Interface P r o c e d u r e s a n d F u n c t i o n s
SetActiveWindow function
SetActiveWindow(Wnd:
HWnd): HWnd;
Activates a t o p - l e v e l w i n d o w . Parameters
Description
Wnd
W i n d o w identifier
Return Value: P r e v i o u s l y active w i n d o w .
SetCapture function
SetCapture(Wnd:
HWnd): HWnd;
C a u s e s all c u r s o r i n p u t t o b e s e n t t o Wn d r e g a r d l e s s o f t h e p o s i t i o n o f t h e m o u s e . Parameters
Description
Wnd Return
W i n d o w identifier Value:
P r e v i o u s w i n d o w that r e c e i v e d all m o u s e i n p u t ; 0 if t h e r e ' s n o c o r r e s p o n d i n g window.
SetDoubleClickTime procedure
SetDoubleClickTime(Count:
Word);
S e t s m a x i m u m e l a p s e d t i m e a l l o w e d b e t w e e n t h e first a n d s e c o n d clicks o f a m o u s e d o u b l e click. Parameters Count
Description Milliseconds b e t w e e n d o u b l e clicks, or 0 to use default (500) v a l u e .
SetFocus function
SetFocus(Wnd:
HWnd): HWnd;
A s s i g n s i n p u t f o c u s t o a w i n d o w a n d d i r e c t s all k e y b o a r d i n p u t t o t h e w i n d o w .
679
680
Part III—References
Parameters Wnd
Description Window
Return Value: P r e v i o u s w i n d o w having
identifier or 0 to ignore keystrokes
i n p u t f o c u s ; 0 if t h e r e ' s n o c o r r e s p o n d i n g w i n d o w .
SetSysModalWindow function SetSysModalWindow(Wnd: HWnd): HWnd; Makes a Wnd a system-modal window. The system-modal state is terminated w h e n the w i n d o w is destroyed. Parameters
Wnd Return
Description
W i n d o w identifier Value:
Previous system-modal window.
SetTimer function SetTimer(Wnd: HWnd; IDEvent: Integer; Elapse: Word; TimerFunc: TFarProc): Word; Creates a system timer, causing a wm_Time r message to be sent to an application at the interval specified by Elapse. Parameters
Description
Wnd
W i n d o w identifier or 0 if there's no associated w i n d o w
IDEvent
Nonzero timer-event identifier or ignored if Wnd is 0
Elapse
N u m b e r of milliseconds between timer events
TimerFunc
Callback function's procedure-instance address or nil to place wm_Timer messages in application queue
Return
Value:
IDEvent if Wnd is not 0, indicating a n e w timer event; 0 if error.
SwapMouseButton function SwapMouseButton(Swap: Bool): Bool; Reverses or restores the meaning of the left and right m o u s e button specified by Swap.
L — W i n d o w M a n a g e r Interface P r o c e d u r e s a n d F u n c t i o n s
Parameters Swap
Description N o n z e r o to swap b u t t o n m e a n i n g s or 0 to restore original meanings
Return Value: N o n z e r o if m e a n i n g s r e v e r s e d ; e l s e 0.
Menu Procedures and Functions AppendMenu CheckMenuItem CreateMenu CreatePopupMenu DeleteMenu DestroyMenu DrawMenuBar EnableMenuItem GetMenu GetMenuCheckMarkDimensions GetMenuItemCount GetMenuItemID GetMenuState GetMenuString GetSubMenu GetSystemMenu HiliteMenuItem InsertMenu LoadMenuIndirect ModifyMenu RemoveMenu SetMenu SetMenuItemBitmaps TrackPopupMenu
AppendMenu function AppendMenu(Menu: HMenu; Flags, IDNewItem: Word; Newltem: PChar): Bool; A p p e n d s a n e w i t e m (with a state s p e c i f i e d b y Flags) t o t h e e n d o f a m e n u .
681
682
Part I I I — R e f e r e n c e s
Parameters
Description
Menu
M e n u to be changed
Flags
O n e o r a c o m b i n a t i o n o f t h e f o l l o w i n g mf _ constants:
Menu
flags'
mf_Bitmap mf_Checked mf_Disabled mf_Enabled mf_Grayed mf_MenuBarBreak mf_MenuBreak mf_OwnerDraw mf_Popup mf_Separator mf_String mf_Unchecked IDNewItem
C o m m a n d I D o r m e n u h a n d l e if p o p - u p m e n u .
Newltem
N e w m e n u string, o r w h e n u s i n g a bit m a p as a n i t e m , t h e l o w - o r d e r w o r d h o l d s a h a n d l e t o t h e bit m a p .
Return
Value:
N o n z e r o if s u c c e s s f u l ; e l s e 0.
CheckMenuItem function
CheckMenuItem(Menu:
P l a c e s o r removes Parameters
HMenu;
IDCheckltem,
Check:
Word):
a check mark from m e n u items in a p o p - u p m e n u . Description
Menu
Pop-up menu
IDCheckltem
M e n u item to be checked
Check
H o w i t e m s h o u l d b e c h e c k e d a n d h o w its p o s i t i o n is specified; any combination of the following m f _ Menu
flags:
mf_ByCommand mf_ByPosition mf_Checked mf_Unchecked
Bool
L — W i n d o w M a n a g e r Interface P r o c e d u r e s a n d F u n c t i o n s
Return Value: P r e v i o u s state o f Item; - 1 if t h e m e n u i t e m d o e s n o t exist.
CreateMenu function CreateMenu: HMenu; Creates an empty m e n u . Return Value: M e n u i d e n t i f i e r if s u c c e s s f u l ; e l s e 0.
CreatePopupMenu function CreatePopupMenu: HMenu; Creates an empty pop-up m e n u . Return Value: M e n u i d e n t i f i e r if s u c c e s s f u l ; e l s e 0.
DeleteMenu function DeleteMenu(Menu: HMenu; Position, Flags: Word): Bool; D e l e t e s a n i t e m f r o m Menu. If t h e i t e m is a p o p - u p , its h a n d l e is d e s t r o y e d , a n d t h e m e m o r y it u s e d is f r e e d . Parameters
Description
Menu
M e n u identifier
Position
Position or c o m m a n d I D
Flags
O n e o f t h e mf _ Menu flags' c o n s t a n t s : mf_ByPosition mf_ByCommand
Return Value: N o n z e r o if s u c c e s s f u l ; e l s e 0.
DestroyMenu function DestroyMenu(Menu: HMenu): Bool; D e s t r o y s Menu a n d frees a s s o c i a t e d m e m o r y .
683
684
Part I I I — R e f e r e n c e s
Parameters Menu
Description M e n u identifier
Return Value: N o n z e r o if s u c c e s s f u l ; e l s e 0.
DrawMenuBar procedure DrawMenuBar(Wnd: HWnd); R e d r a w s a w i n d o w ' s m e n u b a r . U s e d if t h e m e n u b a r c h a n g e s after t h e w i n d o w is c r e a t e d . Parameters Wnd
Description W i n d o w identifier
EnableMenuItem function EnableMenuItem(Menu: HMenu; IDEnableltem, Enable: Word): Bool; E n a b l e s , d i s a b l e s , o r grays a m e n u i t e m s p e c i f i e d b y Enable. Parameters
Description
Menu
M e n u identifier
IDEnableltem
I D or position of m e n u item or p o p - u p to be checked
Enable
A c o m b i n a t i o n o f t h e mf _ Menu flags' c o n s t a n t s : mf_Command o r mf_ByPosition w i t h mf_Disabled, mf_Enabled, o r mf_Grayed
Return Value: P r e v i o u s state o f m e n u i t e m ; - 1 if m e n u i t e m d o e s n ' t exist.
GetMenu function GetMenu(Wnd: HWnd): HMenu; Gets a window's menu handle. Parameters Wnd
Description Owning window of menu
Return Value: M e n u i d e n t i f i e r ; 0 if t h e r e ' s n o m e n u ; u n d e f i n e d if Wnd is a c h i l d w i n d o w .
L — W i n d o w M a n a g e r Interface P r o c e d u r e s a n d F u n c t i o n s
GetMenuCheckMarld)imensions function GetMenuCheckMarkDimensions:
Longint;
G e t s the dimensions o f the default check mark bitmap displayed next t o checked m e n u items. Return Value: H e i g h t (in p i x e l s ) i n t h e h i g h - o r d e r w o r d ; w i d t h ( i n p i x e l s ) i n t h e l o w - o r d e r word.
GetMenuItemCount function GetMenuItemCount(Menu: HMenu): Word; G e t s the n u m b e r o f top-level m e n u s a n d the m e n u items in a specified m e n u . Parameters Menu
Description T h e m e n u identifier
Return Value: T h e n u m b e r o f m e n u i t e m s , if s u c c e s s f u l ; -1 if u n s u c c e s s f u l .
GetMenuItemlD function GetMenuItemID(Menu: HMenu; Pos: Integer): Word; G e t s t h e m e n u i t e m ' s n u m e r i c I D l o c a t e d at t h e s p e c i f i e d p o s i t i o n i n t h e m e n u . Parameters
Description
Menu
P o p - u p m e n u identifier
Pos
Item p o s i t i o n , starting at 0 , i n m e n u
Return Value: Item I D if s u c c e s s f u l ; 0 if i t e m is a p o p - u p ; - 1 if e r r o r .
GetMenuState function GetMenuState(Menu: HMenu; ID, Flags: Word): Word; G e t s state i n f o r m a t i o n f o r a s p e c i f i e d m e n u i t e m .
685
686
Part I I I — R e f e r e n c e s
Parameters
Description
Menu
M e n u o r p o p - u p m e n u identifier
ID
M e n u item I D
Flags
O n e of t h e mf _ Menu flags' c o n s t a n t s : mf_ByPosition mf_ByCommand
Return Value: F l a g s m a s k of t h e f o l l o w i n g mf _ Menu flags v a l u e s : mf_Checked mf_Disabled mf_Enabled mf_MenuBarBreak mf_MenuBreak mf_Separator mfJJnchecked If p o p - u p , t h e h i g h - o r d e r b y t e c o n t a i n s t h e n u m b e r o f i t e m s ; - 1 if ID is i n v a l i d .
GetMenuString function GetMenuString(Menu: HMenu; IDItem: Word; Str: PChar; MaxCount: Integer; Flag: Word): Integer; C o p i e s a m e n u i t e m ' s l a b e l i n t o Str. T h e c o p i e d l a b e l is n u l l - t e r m i n a t e d . Parameters
Description
Menu
M e n u identifier
IDItem
M e n u item I D
Str
Receiving buffer
MaxCount
Size o f the buffer
Flag
O n e of t h e mf _ Menu flags' c o n s t a n t s : mf_ByPosition mf_ByCommand
Return Value: N u m b e r o f bytes c o p i e d .
L — W i n d o w M a n a g e r Interface P r o c e d u r e s a n d F u n c t i o n s
GetSubMenu function GetSubMenu(Menu: HMenu; Pos: Integer): HMenu; Gets a pop-up menu's handle. Parameters
Description
Menu
M e n u identifier
Pos
P o s i t i o n o f p o p - u p m e n u i n Menu
Return Value: P o p - u p m e n u identifier; 0, if n o p o p - u p m e n u exists at Pos.
GetSystemMenu function GetSystemMenu(Wnd: HWnd; Revert: Bool): HMenu; G e t s a w i n d o w ' s system m e n u for copying a n d changing. Parameters Wnd
Description W i n d o w identifier
Revert 0 t o r e t u r n h a n d l e t o a copy o f t h e s y s t e m m e n u o r n o n z e r o t o r e t u r n handle to original system m e n u . Return Value: S y s t e m m e n u i d e n t i f i e r ; 0 if Revert is n o n z e r o a n d t h e s y s t e m m e n u h a s n o t been changed.
HiliteMenuItem function HiliteMenuItem(Wnd: HWnd; Menu: HMenu; IDHilite, Hilite: Word): Bool; Highlights o r removes highlighting from a top-level m e n u item. Parameters
Description
Wnd
W i n d o w identifier
Menu
Top-level m e n u identifier
IDHilite
Integer I D or position of m e n u item
Hilite
A c o m b i n a t i o n of t h e mf _ Menu flags, mf _ByCommand or mf_ByPosition w i t h mfJHilite or mf JJnhilite
Return Value: N o n z e r o if s u c c e s s f u l ; e l s e 0.
687
688
Part III—References
InsertMenu function InsertMenu(Menu:HMenu; Position, Flags, IDNewItem: Word Newltem: PChar): Bool; Inserts n e w m e n u item with a state specified by Flags. Parameters
Description
Menu
M e n u identifier
Position
C o m m a n d ID or position of m e n u item to insert n e w m e n u item after or - 1 to append to end
Flags
O n e of the mf _ Menuflags,mf _ByCommand or mf _ByPosition combined with any of the following: mf_Bitmap mf_String mf_OwnerDraw mf_Separator mf_Popup mf_MenuBarBreak mf_MenuBreak mf_Checked mfJJnchecked
IDNewItem
N e w m e n u item c o m m a n d ID or m e n u handle if pop-up
Newltem
N e w m e n u item contents
Return
Value:
Nonzero if successful; else 0.
LoadMenuIndirect function LoadMenuIndirect(var MenuTemplate): HMenu; Loads the m e n u defined by MenuTemplate. Parameters
Description
MenuTemplate Array of TMenuItemTemplate structures Return
Value:
Menu identifier if successful.
L — W i n d o w M a n a g e r Interface P r o c e d u r e s a n d F u n c t i o n s
689
ModifyMenu function ModifyMenu(Menu: HMenu; Position, Flags, IDNewItem: Word; Newltem: PChar): Bool; C h a n g e s a n e x i s t i n g m e n u i t e m that h a s a n e w state that is s p e c i f i e d b y Flags. Parameters
Description
Menu
M e n u identifier
Position
C o m m a n d I D or position of m e n u item
Flags
C o m b i n a t i o n o f mf_ByCommand or mf_ByPosition w i t h o n e o f t h e f o l l o w i n g mf _ Menu flags' c o n s t a n t s :
mf_Disabled mf_Enabled mf_Grayed mf_Bitmap mf_String mfJDwnerDraw mf_Separator mf_Popup mf_MenuBarBreak mf_MenuBreak mf_Checked mfJJnchecked IDNewItem
Newltem
C o m m a n d I D or m e n u h a n d l e , if flags set t o mf Popup, o f modified m e n u item
String (mf_String), HBitmap (mf_Bitmap), or a p p l i c a t i o n s u p p l i e d d a t a (mf_OwnerDraw)
Return Value: N o n z e r o if s u c c e s s f u l ; e l s e 0.
RemoveMenu function RemoveMenu(Menu: HMenu; Position, Flags: Word): Bool; Nondestructively removes a m e n u item a n d a n associated p o p - u p from the specified m e n u . Y o u c a n u s e the p o p - u p in ensuing operations.
690
Part I I I — R e f e r e n c e s
Parameters
Description
Menu
M e n u identifier
Position
C o m m a n d I D or position of m e n u item
Flags
O n e o f t h e mf _
Menu flags, mf _ByCommand o r
m f _ B y P o s i t i o n specifying the nature of the P o s i t i o n argument. Return Value: N o n z e r o if s u c c e s s f u l ; e l s e 0.
SetMenu function
SetMenu(Wnd:
HWnd; M e n u :
HMenu):
Bool;
S e t s a n d r e d r a w s a w i n d o w ' s m e n u t o t h e m e n u s p e c i f i e d b y Menu. T h e p r e v i o u s m e n u is n o t d e s t r o y e d . Parameters
Description
Wnd
W i n d o w identifier
Menu
N e w m e n u or 0 to remove current m e n u
Return Value: N o n z e r o if s u c c e s s f u l ; e l s e 0.
SetMenuItemBitmaps f u n c t i o n SetMenuItemBitmaps(Menu: BitmapUnchecked, BitmapChecked:
HMenu; P o s i t i o n , HBitmap): Bool;
Flags:
Word;
A s s o c i a t e s t w o b i t m a p s w i t h a m e n u i t e m . O n e is d i s p l a y e d w h e n t h e i t e m is c h e c k e d a n d t h e o t h e r w h e n t h e i t e m is u n c h e c k e d . Parameters
Description
Menu
Menu
identifier
Position
C o m m a n d I D or position of m e n u
Flags
O n e o f t h e mf _ Menu flags' c o n s t a n t s , mf_ByCommand o r m f _ B y P o s i t i o n
BitmapUnchecked
H B i t m a p t o b e d i s p l a y e d w h e n item n o t c h e c k e d or 0 to display nothing
item
L — W i n d o w M a n a g e r Interface P r o c e d u r e s a n d F u n c t i o n s
Parameters
691
Description
BitmapChecked
HBitmap t o b e d i s p l a y e d w h e n i t e m c h e c k e d o r 0 t o d i s p l a y n o t h i n g ; if BitmapUnchecked a n d BitmapChecked a r e 0, W i n d o w s u s e s d e f a u l t check mark
Return Value: N o n z e r o if s u c c e s s f u l ; e l s e 0.
ThckPopupMenu function TrackPopupMenu(Menu: HMenu; Flags: Word; x, y, cx: Integer; Wnd: HWnd; var Rect: TRect): Bool; D i s p l a y s a f l o a t i n g p o p - u p m e n u a n d tracks i t e m s e l e c t i o n . Floating p o p - u p m e n u s can appear anywhere o n the screen. Parameters
Description
Menu
P o p - u p m e n u identifier
Flags
S e t t o 0, n o t u s e d
x, y
Upper-left position (in screen coordinates) o f m e n u
cx
M e n u w i d t h (in s c r e e n u n i t s ) o r 0 f o r d e f a u l t
Wnd
O w n i n g w i n d o w o f the p o p - u p m e n u , to receive wm_Command m e s s a g e s
Rect
TRect d e f i n i n g m o u s e a r e a w h e r e m e n u r e m a i n s visible if t h e u s e r r e l e a s e s t h e m o u s e b u t t o n
Return Value: N o n z e r o if s u c c e s s f u l ; e l s e 0.
Message Procedures and Functions CallWindowProc DispatchMessage GetMessage GetMessagePos GetMessageTime InSendMessage PeekMessage PostAppMessage
692
Part I I I — R e f e r e n c e s
PostMessage PostQuitMessage ReplyMessage SendMessage SetMessageQueue TranslateAccelerator TranslateMDISysAccel TranslateMessage WaitMessage
CallVMowProc function CallWindowProc(PrevWndProc: TFarProc; Wnd: HWnd; Msg, wParam: Word; lParam: Longint): Longint; S e n d s a m e s s a g e t o PrevWndProc. E n a b l e s w i n d o w s u b c l a s s i n g b y a l l o w i n g messages t o b e intercepted before they are sent t o t h e w i n d o w f u n c t i o n o f the class. Parameters
Description
PrevWndProc
Procedure-instance address o f the previous w i n d o w function
Wnd
W i n d o w that r e c e i v e s t h e m e s s a g e
Msg
Message identifier
wParam
Additional message-dependent information
lParam
Additional message-dependent information
Return Value: V a l u e f r o m call t o PrevWndProc.
DispatchMessage function DispatchMessage(var Msg: TMsg): Longint; Passes t h e m e s s a g e i n Msg t o t h e w i n d o w ' s w i n d o w f u n c t i o n . Parameters Msg
Description TMsg s t r u c t u r e
Return Value: A value returned from the w i n d o w function.
L — W i n d o w M a n a g e r Interface P r o c e d u r e s a n d F u n c t i o n s
GetMessage function GetMessage(var Msg: TMsg; Wnd: HWnd; MsgFilterMin, MsgFilterMax: Word): Bool; G e t s a m e s s a g e ( w i t h i n t h e filter r a n g e ) f r o m t h e a p p l i c a t i o n ' s m e s s a g e q u e u e . Y i e l d s c o n t r o l t o o t h e r a p p l i c a t i o n s if t h e r e a r e n o m e s s a g e s p e n d i n g , o r wm_Paint, o r wm_Timer is t h e n e x t m e s s a g e . Parameters
Description
Msg
R e c e i v i n g TMsg s t r u c t u r e
Wnd
M e s s a g e d e s t i n a t i o n w i n d o w o r 0 f o r all w i n d o w s i n applications
MsgFilterMin
0 for n o filtering o r wm_KeyFirst for k e y b o a r d o n l y o r wm_MouseFirst for m o u s e o n l y
MsgFilterMax
0 for n o filtering o r w m K e y L a s t for k e y b o a r d o n l y o r w m M o u s e L a s t for m o u s e o n l y
Return Value: N o n z e r o if n o t a w m Q u i t m e s s a g e ; e l s e 0.
GetMessagePos function GetMessagePos: Longint; G e t s t h e c u r s o r p o s i t i o n for t h e p r e v i o u s m e s s a g e o b t a i n e d f r o m GetMessage. Return
Value: X-coordinates in l o w word; Y-coordinates in high word.
GetMessagelime function GetMessageTime: Longint; G e t s t h e t i m e that h a s e l a p s e d s i n c e a s y s t e m r e b o o t for t h e last m e s s a g e o b t a i n e d f r o m GetMessage. Return Value: M e s s a g e t i m e (in m i l l i s e c o n d s ) .
693
694
Part I I I — R e f e r e n c e s
InSendMessage function InSendMessage: Bool; Decides whether the message being processed by the current w i n d o w function w a s s e n t t h r o u g h SendMessage. Return Value: N o n z e r o if t h e m e s s a g e w a s s e n t b y SendMessage; e l s e 0.
PeekMessage function PeekMessage(var Msg: TMsg; Wnd: HWnd; MsgFilterMin, MsgFilterMax, RemoveMsg: Word): Bool; C h e c k s t h e a p p l i c a t i o n q u e u e f o r a m e s s a g e a n d c o p i e s it t o Msg. If t h e r e a r e n o messages, the function returns immediately, giving control to W i n d o w s . Parameters
Description
Msg
R e c e i v i n g TMsg s t r u c t u r e
Wnd
Messages destination w i n d o w or 0 for any w i n d o w in application or - 1 for messages posted by PostAppMessage f u n c t i o n .
MsgFilterMin
L o w e s t m e s s a g e I D t o e x a m i n e , o r 0 f o r n o limit
MsgFilterMax
H i g h e s t m e s s a g e I D t o e x a m i n e , o r 0 f o r n o limit
RemoveMsg
O n e o r m o r e o f t h e pm_ Peek m e s s a g e o p t i o n s
Return
Value:
N o n z e r o if m e s s a g e a v a i l a b l e ; e l s e 0.
PostAppMessage function PostAppMessage(Task: THandle; Msg, wParam: Word; lParam: Longint): Bool; Posts a m e s s a g e t o a n a p p l i c a t i o n . T h e Wnd of t h e m e s s a g e is set t o 0. Parameters
Description
Task
Application to receive message
Msg
Message type
wParam
Additional message information
lParam
Additional message information
L — W i n d o w M a n a g e r Interface P r o c e d u r e s a n d F u n c t i o n s
Return Value: N o n z e r o if s u c c e s s f u l ; e l s e 0.
PostMessage function PostMessage(Wnd: HWnd; Msg, wParam: Word; lParam: Longint): Bool; Posts a m e s s a g e t o a n application w i n d o w . Parameters Wnd
Description W i n d o w t o r e c e i v e m e s s a g e o r $ F F F F f o r all o v e r l a p p e d or pop-up windows
Msg
Message type
wParam
Additional message information
lParam
Additional message information
Return Value: N o n z e r o if s u c c e s s f u l ; e l s e 0.
PostQuitMessage procedure PostQuitMessage(ExitCode:
Integer);
P o s t s a wm_Quit m e s s a g e u s u a l l y i n r e s p o n s e t o a w m D e s t r o y m e s s a g e . Parameters ExitCode
Description A p p l i c a t i o n exit c o d e (wParam o f wm_Quit m e s s a g e )
ReplyMessage procedure ReplyMessage(Reply: Longint); R e p l i e s t o a m e s s a g e s e n t byaSendMessagecall, a l l o w i n g b o t h t h e r e q u e s t e r o f t h e SendMessage a n d ReplyMessage t o c o n t i n u e p r o c e s s i n g . Parameters Reply
Description M e s s a g e - d e p e n d e n t r e t u r n result
695
696
Part I I I — R e f e r e n c e s
SendMessage function SendMessage(Wnd: HWnd; Msg, wParam: Word; lParam: Longint): Longint; Sends a message to the w i n d o w function o f a specified w i n d o w . T h e function d o e s n ' t r e t u r n u n t i l t h e m e s s a g e is p r o c e s s e d . Parameters
Description
Wnd
W i n d o w t o r e c e i v e m e s s a g e o r $ F F F F t o s e n d t o all p o p u p w i n d o w s in system
Msg
Message type
wParam
Additional message information
lParam
Additional message information
Return Value: Value returned by the receiving w i n d o w function.
SetMessageQueue function SetMessageQueue(Msg:
Integer): Bool;
C r e a t e s a n e w a p p l i c a t i o n m e s s a g e q u e u e o f a s p e c i f i e d s i z e . T h e o l d q u e u e is deleted. Parameters Msg Return
Description Size o f q u e u e
Value:
N o n z e r o if s u c c e s s f u l ; e l s e 0.
ThmslateAccelerator function TranslateAccelerator(Wnd: HWnd; AccTable: THandle; var Msg: TMsg): Integer; T r a n s l a t e s a n y k e y b o a r d a c c e l e r a t o r s (wm_KeyUp a n d wm_KeyDown) i n t o m e n u c o m m a n d m e s s a g e s , w m C o m m a n d a n d wmSysCommand, which t h e n a r e s e n t directly t o t h e w i n d o w .
L — W i n d o w Manager Interface Procedures and Functions
Parameters
Description
Wnd
Window identifier
AccTable
Accelerator table identifier (returned by LoadAccelerators)
Msg
TMsg information retrieved from GetMessage or PeekMessage
Return Value: Nonzero if translation occurred; else 0.
TranslateMDISysAccel function TranslateMDISysAccel(Wnd: HWnd; var Msg: TMsg): Bool; Translates any keyboard accelerators for M D I child w i n d o w system-menu wm_SysCommand messages. These messages then are sent directly to the window. Parameters
Description
Wnd
MDI client parent w i n d o w
Msg
TMsg information retrieved from GetMessage or PeekMessage
Return Value: Nonzero if translation occurred; else 0.
IfonslateMessage function TranslateMessage(var Msg: TMsg): Bool; Translates wm_KeyDown/wm_KeyUp combinations to wm_Charor wm_DeadChar, and wm_SysKeyDown/wm_SysKeyllp combinations to w m _ S y s C h a r or wmSysDeadChar. Also posts the character message to the application queue. Parameters Msg
Description TMsg information retrieved from GetMessage or PeekMessage
Return Value: Nonzero if translation occurred; else 0.
697
698
Part I I I — R e f e r e n c e s
WaitMessage procedure WaitMessage; Yields control to other applications and does not return until a message appears in the application q u e u e .
Painting Procedures and Functions BeginPaint DrawFocusRect Drawlcon DrawText EndPaint ExcludeUpdateRgn FillRect FrameRect GetDC GetUpdateRect GetUpdateRgn GetWindowDC GrayString InvalidateRect InvalidateRgn InvertRect ReleaseDC UpdateWindow ValidateRect ValidateRgn
BeginPaint function BeginPaint(Wnd: HWnd; var Paint: TPaintStruct): HDC; P r e p a r e s a w i n d o w f o r p a i n t i n g i n r e s p o n s e t o a wm_Paint m e s s a g e . Fills Paint with the required information in order to paint. Parameters
Description
Wnd
W i n d o w to be repainted
Paint
TPaintStruct t o r e c e i v e p a i n t i n g i n f o r m a t i o n
Return Value. Device context identifier.
L — W i n d o w M a n a g e r Interface Procedures a n d F u n c t i o n s
DrawFocusRect procedure DrawFocusRect(DC: HDC; var Rect: TRect); Does XOR to d r a w a focus style rectangle. Parameters
Description
DC
Device context identifier
Rect
TRect to be d r a w n
Drawlcon function DrawIcon(DC: HDC; X, Y: Integer; Icon: HIcon): Bool; D r a w s an icon. Parameters
Description
DC
Device context identifier
X, Y
Upper-left corner of the icon
Icon
Icon to be d r a w n
Return Value: Nonzero if successful; else 0.
DrawText function DrawText(DC: HDC; Str: PChar; Count: Integer; var Rect: TRect; Format: Word): Integer; D r a w s formatted text w h o s e formatting is specified by Format. T h e text is clipped to the bounding rectangle, unless specified by dtNoClip. Parameters
Description
DC
Device-context identifier
Str
String to be drawn; if Count is - 1 , must be nullterminated
Count
N u m b e r of bytes in string
Rect
Bounding TRect of the text
Format
O n e or m o r e of the dt_ Text drawing formatting flags
Return Value: Text height.
699
700
Part I I I — R e f e r e n c e s
EndPaint procedure EndPaint(Wnd: HWnd; var Paint: TPaintStruct); D e n o t e s e n d of painting in Wnd. Parameters
Description
Wnd
Repainted window
Paint
TPaintStruct retrieved from BeginPaint function
ExcludeUpdateRgn function ExcludeUpdateRgn(DC: HDC; Wnd: HWnd): Integer; E x c l u d e s a w i n d o w ' s u p d a t e d region from a clipping region, drawing o u t s i d e the valid areas of the w i n d o w . Parameters
thus preventing
Description
DC
Device c o n t e x t
Wnd
Window
identifier
being u p d a t e d
Return Value: O n e of the Region flags' c o n s t a n t s .
FillRect function FillRect(DC: HDC; var Rect: TRect; Brush: HBrush): Integer; Fills a rectangle, Parameters
u s i n g Brush u p to the right a n d bottom borders. Description
DC
Device c o n t e x t identifier
Rect
TRect to be
Brush
Fill b r u s h
Return Value: Not used.
filled
L — W i n d o w M a n a g e r Interface P r o c e d u r e s a n d F u n c t i o n s
701
FrameRect procedure
FrameRect(DC:
HDC; var Rect: TRect; Brush: HBrush):
Draws a border o n e logical unit wide a r o u n d a rectangle. Parameters
Description
DC
D e v i c e context identifier
Rect
TRect d e f i n i n g c o r n e r s o f t h e r e c t a n g l e
Brush
Framing brush
GetDC function GetDC(Wnd: HWnd): HDC; G e t s a display context for u s e by G D I functions in a w i n d o w ' s client area. Parameters Wnd
Description W i n d o w identifier
Return Value: D i s p l a y c o n t e x t i d e n t i f i e r ; 0 if e r r o r .
GetUpdateRect function GetUpdateRect(Wnd:
HWnd; var Rect: TRect;
Erase: Bool): Bool; G e t s the smallest enclosing rectangle o f a w i n d o w ' s u p d a t e region. Parameters
Description
Wnd
W i n d o w identifier
Rect
R e c e i v i n g TRect s t r u c t u r e
Erase
N o n z e r o to erase u p d a t e region b a c k g r o u n d
Return Value: N o n z e r o if n o n - e m p t y u p d a t e r e g i o n ; e l s e 0.
Integer;
702
Part I I I — R e f e r e n c e s
GetUpdateRgn function GetUpdateRgn(Wnd: HWnd; Rgn: HRgn; Erase: Bool): Integer; C o p i e s i n t o Rgn a w i n d o w ' s u p d a t e r e g i o n . Parameters
Description
Wnd
W i n d o w identifier
Rgn
Receiving update region
Erase
N o n z e r o if b a c k g r o u n d s h o u l d b e e r a s e d a n d c h i l d windows redrawn
Return Value: O n e o f t h e Region flags' c o n s t a n t s .
GetWindowDC function GetWindowDC(Wnd: HWnd): HDC; G e t s a d i s p l a y c o n t e x t u s u a l l y u s e d f o r p a i n t i n g n o n c l i e n t areas o f a w i n d o w . Parameters Wnd
Description W i n d o w identifier
Return Value: D i s p l a y c o n t e x t i d e n t i f i e r ; 0 if t h e r e ' s a n e r r o r .
GrayString function GrayString(DC: HDC; Brush: HBrush; OutputFunc: TFarProc; Data: Longint; Count, X, Y, Width, Height: Integer): Bool; D r a w s g r a y text ( u s i n g t h e c u r r e n t l y s e l e c t e d f o n t ) b y s e n d i n g a m e s s a g e t o OutputFunc that c o n t a i n s DC (with a bit m a p o f Height a n d Width s i z e ) , Data, a n d Count. Parameters
Description
DC
Device context identifier
Brush
HBrush u s e d f o r g r a y i n g
OutputFunc
D r a w f u n c t i o n p r o c e d u r e - i n s t a n c e a d d r e s s or n i l t o u s e TextOut
Data
D a t a t o p a s s t o OutputFunc or string if OutputFunc is 0
L — W i n d o w M a n a g e r Interface P r o c e d u r e s a n d F u n c t i o n s
Parameters
Description
Count
S i z e o f D a t a o r 0 a n d D a t a is a string t o c a l c u l a t e l e n g t h , o r - 1 a n d O u t p u t F u n c r e t u r n s 0 a n d i m a g e is d i s p l a y e d but not shown
X,Y
Starting logical position o f enclosing rectangle
Width
W i d t h (in l o g i c a l u n i t s ) o f e n c l o s i n g r e c t a n g l e , o r 0 a n d D a t a is a string t o c a l c u l a t e w i d t h
Height
H e i g h t (in l o g i c a l u n i t s ) o f e n c l o s i n g r e c t a n g l e , o r 0 a n d D a t a is a string t o c a l c u l a t e h e i g h t
Return Value: N o n z e r o if s u c c e s s f u l ; 0 if t h e o u t p u t f u n c t i o n r e t u r n e d 0 o r if i n s u f f i c i e n t m e m o r y t o c r e a t e t h e bit m a p .
InvalidateRect procedure
InvalidateRect(Wnd:
HWnd; R e c t :
LPRect;
Erase:
Bool);
Invalidates a w i n d o w ' s client area by a d d i n g R e c t to the w i n d o w ' s u p d a t e region. Parameters
Description
Wnd
W i n d o w identifier
Rect
T R e c t to b e a d d e d to u p d a t e region o r nil for the entire client area
Erase
N o n z e r o for B e g i n P a i n t to erase b a c k g r o u n d
InvalidateRgn procedure
InvalidateRgn(Wnd:
HWnd; R g n :
HRgn;
Erase:
Bool);
I n v a l i d a t e s a w i n d o w ' s c l i e n t a r e a b y a d d i n g Rg n t o t h e w i n d o w ' s u p d a t e r e g i o n . Parameters
Description
Wnd
W i n d o w identifier
Rgn
R e g i o n i d e n t i f i e r (in c l i e n t c o o r d i n a t e s )
Erase
N o n z e r o for B e g i n P a i n t t o e r a s e b a c k g r o u n d
703
704
Part I I I — R e f e r e n c e s
InvertRect procedure InvertRect(DC: HDC; var Rect: TRect); Inverts t h e c o l o r s o f t h e r e c t a n g l e s p e c i f i e d b y Rect. Parameters
Description
DC
Device context identifier
Rect
TRect s t r u c t u r e ( i n l o g i c a l c o o r d i n a t e s )
ReleaseDC function ReleaseDC(Wnd: HWnd; DC: HDC): Integer; R e l e a s e s a c o m m o n o r w i n d o w d e v i c e c o n t e x t , t h u s m a k i n g it available t o o t h e r applications. Parameters
Description
Wnd
W i n d o w identifier
DC
Device context identifier
Return Value: 1 if d e v i c e c o n t e x t r e l e a s e d ; e l s e 0.
UpdateWindow procedure UpdateWindow(Wnd: HWnd); S e n d s a w m P a i n t m e s s a g e d i r e c t l y t o a w i n d o w ' s window f u n c t i o n if t h e u p d a t e r e g i o n o f t h e w i n d o w is n o t e m p t y . Parameters Wnd
Description W i n d o w identifier
ValidateRect procedure ValidateRect(Wnd: HWnd; Rect: LPRect); V a l i d a t e s t h e c l i e n t a r e a b y r e m o v i n g Rect f r o m t h e w i n d o w ' s u p d a t e r e g i o n . Parameters
Description
Wnd
W i n d o w identifier
Rect
TRect ( i n c l i e n t c o o r d i n a t e s ) t o b e r e m o v e d f r o m u p d a t e region o r nil for entire client area
L — W i n d o w M a n a g e r Interface P r o c e d u r e s a n d F u n c t i o n s
ValidateRgn procedure ValidateRgn(Wnd: HWnd; Rgn: HRgn); V a l i d a t e s t h e c l i e n t a r e a b y r e m o v i n g t h e r e g i o n s p e c i f i e d b y Rgn f r o m t h e window's update region. Parameters
Description
Wnd
W i n d o w identifier
Rgn
R e g i o n i d e n t i f i e r (in c l i e n t c o o r d i n a t e s )
Property Procedures and Functions EnumProps GetProp RemoveProp SetProp
EnumProps function EnumProps(Wnd: HWnd; EnumFunc: TFarProc): Integer; E n u m e r a t e s a w i n d o w ' s p r o p e r t y list s e n d i n g Wnd, nDummy, PSTR, a n d hData t o t h e callback. E n u m e r a t i o n e n d s if t h e callback r e t u r n s 0 o r if all p r o p e r t i e s are e n u m e r a t e d . Parameters
Description
Wnd
W i n d o w identifier
EnumFunc
Callback f u n c t i o n ' s p r o c e d u r e - i n s t a n c e a d d r e s s
Return Value: P r e v i o u s v a l u e r e t u r n e d b y callback; - 1 if w i n d o w h a s n o p r o p e r t i e s .
GetProp function GetProp(Wnd: HWnd; Str: PChar): THandle; G e t s t h e a s s o c i a t e d d a t a h a n d l e f r o m a w i n d o w ' s p r o p e r t y list.
705
706
Part I I I — R e f e r e n c e s
Parameters
Description
Wnd
W i n d o w identifier
Str
String (null-terminated) o r a t o m
Return Value: D a t a h a n d l e if p r o p e r t y list c o n t a i n s Str; e l s e 0.
RemoveProp function RemoveProp(Wnd: HWnd; Str: PChar): THandle; R e m o v e s a n e n t r y ( s p e c i f i e d b y Str) f r o m a w i n d o w ' s p r o p e r t y list. A n a p p l i c a t i o n is r e s p o n s i b l e f o r f r e e i n g t h e r e t u r n e d d a t a h a n d l e . Parameters
Description
Wnd
W i n d o w identifier
Str
String (null-terminated) o r an a t o m
Return Value: D a t a h a n d l e t o string; 0 if t h e string is n o t f o u n d .
SetProp function SetProp(Wnd: HWnd; Str: PChar; Data: THandle): Bool; A d d s o r c h a n g e s a n e n t r y ( s p e c i f i e d b y Str) t o a w i n d o w ' s p r o p e r t y list. Parameters
Description
Wnd
W i n d o w identifier
Str
String (null-terminated) o r a t o m value created by calling AddAtom
Data
Associated property data handle
Return Value: N o n z e r o if a d d e d ; e l s e 0.
Scrolling Procedures and Functions GetScrollPos GetScrollRange ScrollDC ScrollWindow
L — W i n d o w M a n a g e r Interface P r o c e d u r e s a n d F u n c t i o n s
707
SetScrollPos SetScrollRange ShowScrollBar
GetScrollPos function
GetScrollPos(Wnd:
HWnd; B a r :
Integer):
Integer;
G e t s t h e c u r r e n t p o s i t i o n o f a scroll-bar t h u m b relative t o t h e c u r r e n t s c r o l l i n g range. Parameters
Description
Wnd
W i n d o w containing scroll bar
Bar
O n e of the s b _ S c r o l l bar constants
Return Value: C u r r e n t scroll-bar t h u m b p o s i t i o n .
GetScrollRange p r o c e d u r e G e t S c r o l l R a n g e ( W n d : HWnd; B a r : var MinPos, MaxPos: I n t e g e r ) ;
Integer;
G e t s a scroll bar's m i n i m u m a n d m a x i m u m positions. Parameters
Description
Wnd
W i n d o w containing scroll bar
Bar
O n e of the s b _ S c r o l l bar constants
MinPos
Integer to receive m i n i m u m position
MaxPos
Integer to receive m a x i m u m position
ScrollDC f u n c t i o n S c r o l l D C ( D C : HDC; d x , U p d a t e R g n : HRgn; U p d a t e R e c t :
dy: I n t e g e r ; var S c r o l l , LPRect): Bool;
S c r o l l s a r e c t a n g l e o f bits b y dx a n d dy u n i t s .
Clip:
TRect;
708
Part I I I — R e f e r e n c e s
Parameters
Description
DC
Device context identifier
dx
Horizontal scroll units
dy
Vertical scroll units
Scroll
T R e c t c o n t a i n i n g s c r o l l i n g rectangle containing clipping rectangle
UpdateRgn
S c r o l l D C region u n c o v e r e d b y t h e s c r o l l i n g p r o c e s s ; if n i l , u p d a t e region is n o t c o m p u t e d
UpdateRect
R e c e i v i n g T R e c t c o n t a i n i n g t h e b o u n d i n g rectangle of t h e s c r o l l u p d a t e region; if n i l , u p d a t e rectangle is n o t computed
Clip
TRect
Return Value: N o n z e r o if s u c c e s s f u l ; e l s e 0.
SaollWmdow procedure ScrollWindow(Wnd: Rect,
ClipRect:
HWnd; X A m o u n t ,
YAmount:
Integer;
LPRect);
S c r o l l s a w i n d o w ' s c l i e n t a r e a b y XAmount a n d YAmount. T h e u n c o v e r e d a r e a is c o m b i n e d with the window's update regions Parameters
Description
Wnd
W i n d o w identifier
XAmount
Device units to scroll in x-direction
YAmount
Device units to scroll in y-direction
Rect
Client area T R e c t to b e scrolled or nil for the entire client area
ClipRect
C l i p p i n g T R e c t to b e scrolled or nil for the entire window
SetScrollPos function SetScrollPos(Wnd: Bool): Integer; Sets a scroll bar's t h u m b to P o s .
HWnd; B a r ,
Pos:
Integer;
Redraw:
L — W i n d o w M a n a g e r Interface P r o c e d u r e s a n d F u n c t i o n s
N o t e : T h e s c r o l l b a r ' s " t h u m b " is t h e " S c r o l l B o x " i n a s c r o l l b a r that i n d i c a t e s y o u r p o s i t i o n i n a file. T h u s , y o u c a n set t h e " t h u m b " to any position.
Parameters
Description
Wnd
W i n d o w i d e n t i f i e r o r scroll-bar c o n t r o l i d e n t i f i e r if B a r is set t o s b _ C t l
Bar
O n e of the s b _ S c r o l l bar constants
Pos
N e w position
Redraw
N o n z e r o to redraw scroll bar
Return
Value:
Previous position o f scroll bar t h u m b .
SetScrollRange procedure Redraw:
SetScrollRange(Wnd: Bool);
HWnd; B a r ,
MinPos,
MaxPos:
Integer;
Sets a scroll bar's m i n i m u m a n d m a x i m u m position values. Parameters
Description
Wnd
W i n d o w i d e n t i f i e r o r s c r o l l b a r c o n t r o l i d e n t i f i e r if B a r is set t o s b _ C t l
Bar
O n e of the s b _ S c r o l l bar constants
MinPos
M i n i m u m scrolling position
MaxPos
M a x i m u m s c r o l l i n g p o s i t i o n o r 0 a n d M i n P o s set t o 0 t o h i d e the scroll bar
Redraw
N o n z e r o to redraw the scroll bar
ShowScrollBar procedure
ShowScrollBar(Wnd:
HWnd; B a r :
S h o w s o r h i d e s a s c r o l l b a r as s p e c i f i e d b y Show.
Word; Show:
Bool);
709
710
Part I I I — R e f e r e n c e s
Parameters
Description
Wnd
W i n d o w i d e n t i f i e r o r s c r o l l b a r c o n t r o l if B a r is set t o sb_Ctl
Bar
O n e o f t h e sb_ Scroll b a r c o n s t a n t s
Show
N o n z e r o t o s h o w t h e s c r o l l b a r o r 0 t o h i d e it
System Procedures and Functions GetCurrentTime GetSysColor GetSystemMetrics SetSysColors
GetCurrentTime function GetCurrentTime: Longint; G e t s the elapsed time since the system w a s rebooted. Return
Value:
C u r r e n t t i m e (in m i l l i s e c o n d s ) .
GetSysColor function GetSysColor(Index:
Integer): Longint;
Gets a W i n d o w s display element's current color. Parameters Index
Description Display element
Return Value: R G B color value.
GetSystemMetrics function GetSystemMetrics(Index:
Integer): Integer;
G e t s t h e s y s t e m m e t r i c s , s u c h as m o u s e s t a t u s , p i x e l w i d t h , a n d h e i g h t o f v a r i o u s display elements, a n d W i n d o w s d e b u g version.
L — W i n d o w M a n a g e r Interface P r o c e d u r e s a n d F u n c t i o n s
Parameters Index
Description O n e o f t h e sm_ S y s t e m m e t r i c s c o d e s ' c o n s t a n t s
Return Value: T h e requested system metric value.
SetSysColors procedure SetSysColors(Changes: Integer; var SysColor; var ColorValues); S e t s t h e s y s t e m c o l o r s f o r t h e d i s p l a y e l e m e n t s s p e c i f i e d i n SysColor. Parameters Change
SysColor
Description N u m b e r o f system colors to c h a n g e
I n t e g e r array w h o s e i n d e x e s a r e color_ System color codes
ColorValues
Longint array c o n t a i n i n g c o r r e s p o n d i n g R G B color v a l u e
f o r e a c h color i n d e x i n SysColor
Window-Creation Procedures and Functions Adj ustWindowRect Ad j ustWindowRectEx CreateWindow CreateWindowEx DefDlgProc DefFrameProc DefMDIChildProc DefWindowProc DestroyWindow GetClassInfo GetClassLong GetClassName GetClassWord GetLastActivePopup GetWindowLong GetWindowWord RegisterClass SetClassLong SetClassWord
711
712
Part I I I — R e f e r e n c e s
SetWindowLong SetWindowWord UnregisterClass
AdjustWindowRect procedure AdjustWindowRect(var
Rect: TRect; Style: Longint;
Menu: Bool); C o m p u t e s t h e size a w i n d o w r e c t a n g l e r e q u i r e s b a s e d o n Rect s i z e . Parameters
Description
Rect
TRect c o n t a i n i n g c l i e n t r e c t a n g l e c o o r d i n a t e s t o b e converted
Style
W i n d o w styles o f t h e w i n d o w w i t h a c l i e n t r e c t a n g l e that is t o b e c o n v e r t e d
Menu
N o n z e r o if w i n d o w h a s a m e n u
AdjustWindowRectEx procedure AdjustWindowRectEx(var Rect: TRect; Style: Longint; Menu: Bool; ExStyle: Longint); C o m p u t e s t h e size o f a w i n d o w r e c t a n g l e w i t h e x t e n d e d style b a s e d o n Rect size. A s s u m e s a s i n g l e r o w m e n u , if t h e r e ' s a m e n u . Parameters
Description
Rect
T R e c t structure containing client rectangle coordinates to be converted
Style
W i n d o w styles o f t h e w i n d o w w h o s e c l i e n t r e c t a n g l e w i l l be converted
Menu
N o n z e r o if t h e w i n d o w h a s a m e n u
ExStyle
E x t e n d e d style o f t h e w i n d o w b e i n g c r e a t e d
CreateWindow function CreateWindow(ClassName, WindowName: PChar; Style: Longint; X, Y, Width, Height: Integer; WndParent: HWnd; Menu: HMenu; Instance: THandle; Param: Pointer): HWnd; Creates a pop-up, overlapped, or child window.
L — W i n d o w M a n a g e r Interface P r o c e d u r e s a n d F u n c t i o n s
Parameters
713
Description
ClassName
W i n d o w class n a m e ( n u l l - t e r m i n a t e d ) o r a p r e d e f i n e d control-class n a m e
WindowName
W i n d o w caption or n a m e (null-terminated)
Style
O n e o r a c o m b i n a t i o n o f w i n d o w o r c o n t r o l style c o n stants: bs_ Button styles cbs_ Combo b o x styles ds_ Dialog styles es_ Edit c o n t r o l styles lbs_ List b o x styles sbs_ Scroll b a r styles ss_ Static c o n t r o l styles ws_ Window styles
X, Y
S t a r t i n g w i n d o w p o s i t i o n o r cwJJseDefault
Width
Starting w i n d o w w i d t h (in device units)
Height
Starting w i n d o w height (in device units)
WndParent
Owner window
Menu
M e n u o r c h i l d - w i n d o w identifier
Instance
Associated m o d u l e instance
Param
V a l u e p a s s e d i n TCreateStruct i n lParam o f t h e w m C r e a t e m e s s a g e ; this m u s t b e a p o i n t e r t o a TClientCreateStruct f o r MDI c l i e n t w i n d o w c r e a t i o n
Return Value: W i n d o w i d e n t i f i e r if s u c c e s s f u l ; e l s e 0 .
CreateWindowEx function CreateWindowEx(ExStyle: Longint; ClassName, WindowName: PChar; Style: Longint; X, Y, Width, Height: Integer; WndParent: HWnd; Menu: HMenu; Instance: THandle; Param: Pointer): HWnd; C r e a t e s a p o p - u p , o v e r l a p p e d , o r c h i l d w i n d o w w i t h a n e x t e n d e d style.
714
Part I I I — R e f e r e n c e s
Parameters
Description
ExStyle
O n e of t h e ws_ex_ Extended w i n d o w styles' c o n s t a n t s
ClassName
W i n d o w class n a m e ( n u l l - t e r m i n a t e d ) o r a p r e d e f i n e d control-class n a m e
WindowName
W i n d o w caption o r n a m e (null-terminated)
Style
O n e o r a c o m b i n a t i o n o f w i n d o w o r c o n t r o l style c o n stants: bs_ Button styles cbs_ Combo b o x styles ds_ Dialog styles es_ Edit c o n t r o l styles lbs_ List b o x styles sbs_ Scroll b a r styles ss_ Static c o n t r o l styles ws_ Window styles
X, Y
S t a r t i n g w i n d o w p o s i t i o n o r cw_UseDef ault
Width
S t a r t i n g w i n d o w w i d t h (in d e v i c e u n i t s )
Height
S t a r t i n g w i n d o w h e i g h t (in d e v i c e u n i t s )
WndParent
Owner window
Menu
M e n u o r child-window identifier
Instance
Associated m o d u l e instance
Param
V a l u e p a s s e d i n TCreateStruct i n lParam o f t h e wmCreate message, must be a pointer to a TClientCreateStruct f o r MDI c l i e n t w i n d o w c r e a t i o n
Return Value: W i n d o w identifier if s u c c e s s f u l ; e l s e 0.
DefDlgProc function DefDlgProc(Dig: HWnd; Msg, wParam: Word; lParam: Longint): Longint; H a n d l e s d e f a u l t p r o c e s s i n g f o r d i a l o g s w i t h a private w i n d o w class. Parameters
Description
Dig
D i a l o g b o x identifier
Msg
Message number
L — W i n d o w M a n a g e r Interface P r o c e d u r e s a n d F u n c t i o n s
Parameters
Description
wParam
Message-dependent information
lParam
Message-dependent information
Return Value: Result o f the message processing.
DefframeProc function DefFrameProc(Wnd, MDIClient: HWnd; Msg, wParam: Word; lParam: Longint): Longint; H a n d l e s d e f a u l t m e s s a g e p r o c e s s i n g f o r MDI f r a m e w i n d o w s . Parameters
Description
Wnd
MDI f r a m e w i n d o w
MDIClient
MDI c l i e n t w i n d o w
Msg
Message number
wParam
Message-dependent information
lParam
Message-dependent information
Return Value: Result o f message processing.
DeM)IChildProc function DefMDIChildProc(Wnd: HWnd; Msg, wParam: Word; lParam: Longint): Longint; H a n d l e s d e f a u l t m e s s a g e p r o c e s s i n g f o r MDI c h i l d w i n d o w s . Parameters
Description
Wnd
MDI c h i l d w i n d o w
Msg
Message number
wParam
Message-dependent information
lParam
Message-dependent information
Return Value: Result o f the message processing.
715
716
Part H I — R e f e r e n c e s
DefVTindowProc function DefWindowProc(Wnd: HWnd; Msg, wParam: Word; lParam: Longint): Longint; H a n d l e s default message processing for any messages n o t explicitly h a n d l e d b y an application. Parameters
Description
Wnd
W i n d o w identifier
Msg
Message number
wParam
Message-dependent information
lParam
Message-dependent information
Return Value: R e s u l t of t h e m e s s a g e p r o c e s s i n g .
Destroy^ndow function DestroyWindow(Wnd: HWnd): Bool; D e s t r o y s a w i n d o w or a m o d e l e s s d i a l o g box a n d a n y of its a s s o c i a t e d child windows. Parameters Wnd
Description Window
identifier
Return Value: N o n z e r o if s u c c e s s f u l ; e l s e 0.
GetClassInfo function GetClassInfo(Instance: THandle; Classlnfo: PChar; var WndClass: TWndClass): Bool; G e t s class information for t h e s p e c i f i e d class .TWndClass fields .IpszClassName, IpszMenuName, a n d hlnstance are n o t returned. Parameters
Description
Instance
A p p l i c a t i o n i n s t a n c e that created t h e class or 0 for a p r e d e f i n e d Windows class ClassName C l a s s n a m e ( n u l l - t e r m i n a t e d ) or I D
WndClass
TWndClass to receive class information
L — W i n d o w M a n a g e r Interface P r o c e d u r e s a n d F u n c t i o n s
Return Value: N o n z e r o if s u c c e s s f u l ; 0 if m a t c h i n g class is n o t f o u n d .
GetClassLong function GetClassLong(Wnd: HWnd; Index: Integer): Longint; G e t s t h e l o n g v a l u e at I n d e x f r o m a w i n d o w ' s TWndClass s t r u c t u r e . Positive b y t e offsets ( f r o m 0) t o a c c e s s e x t r a class b y t e s . Parameters
Description
Wnd
W i n d o w identifier
Index
B y t e offset o r t h e c o n s t a n t gcl_WndProc
Return Value: Value retrieved.
GetClassName function GetClassName(Wnd: HWnd; ClassName: PChar; MaxCount: Integer): Integer; G e t s a w i n d o w ' s class n a m e . Parameters
Description
Wnd
W i n d o w identifier
ClassName
B u f f e r t o r e c e i v e class n a m e
MaxCount
Size o f buffer
Return Value: N u m b e r o f c h a r a c t e r s c o p i e d ; 0 if t h e r e ' s a n e r r o r .
GetClassWord function GetClassWord(Wnd: HWnd, Index: Integer): Word; G e t s t h e w o r d v a l u e at Index f r o m a w i n d o w ' s TWndClass s t r u c t u r e . Positive b y t e offsets ( f r o m 0) t o a c c e s s e x t r a class b y t e s .
717
718
Part I I I — R e f e r e n c e s
Parameters
Description
Wnd
W i n d o w identifier
Index
B y t e offset o r o n e o f t h e gcw_ Class field offsets' constants
Return Value: Value retrieved.
GetLastActivePopup function GetLastActivePopup(WndOwner: HWnd): HWnd; G e t s t h e m o s t r e c e n t l y active p o p - u p w i n d o w . Parameters WndOwner
Description O w n i n g parent w i n d o w o f pop-up.
Return Value: P o p - u p w i n d o w identifier; WndOwner.
GetWindowLong function GetWindowLong(Wnd: HWnd; Index: Integer): Longint; G e t s i n f o r m a t i o n about a w i n d o w o r a w i n d o w ' s e x t r a b y t e v a l u e s . Parameters
Description
Wnd
W i n d o w identifier
Index
B y t e oTbf f set o r o n e o f t h e gwl_ Window field offsets
Return Value: Specified w i n d o w information.
GetWindowWord function GetWindowWord(Wnd: HWnd; Index: Integer): Word; G e t s i n f o r m a t i o n a b o u t a w i n d o w o r window-class e x t r a b y t e v a l u e s .
L — W i n d o w M a n a g e r Interface P r o c e d u r e s a n d F u n c t i o n s
Parameters
Description
Wnd
W i n d o w identifier
Index
Positive b y t e offset o r o n e o f t h e gww_ Window offsets' c o n s t a n t s
field
Return Value: W o r d value.
RegisterClass function RegisterClass(var WndClass: TWndClass): Bool; Registers a w i n d o w class w h o s e attributes a r e s p e c i f i e d b y WndClass. Parameters WndClass
Description TWndClass s t r u c t u r e
Return Value: N o n z e r o if class r e g i s t e r e d ; e l s e 0.
SetClassLong function SetClassLong(Wnd: HWnd; Index: NewLong: Longint): Longint;
Integer;
Replaces the l o n g value specified by I n d e x in the w i n d o w ' s structure. Parameters
TWndClass
Description
Wnd
W i n d o w identifier
Index
O n e o f t h e gcl_ Class field offsets o r p o s i t i v e b y t e offset t o set e x t r a 4-byte v a l u e s
NewLong
Replacement value
Return Value: Previous value.
719
720
Part I I I — R e f e r e n c e s
SetClassWord function SetClassWord(Wnd: HWnd; Index: Integer; NewWord: Word): Word; R e p l a c e s t h e w o r d v a l u e s p e c i f i e d b y Index i n t h e w i n d o w ' s TWndClass structure. Parameters
Description
Wnd
W i n d o w identifier
Index
O n e of t h e gcw_ Class field o f f s e t s o r p o s i t i v e b y t e offset t o set e x t r a 2-byte v a l u e
NewWord
Replacement value
Return Value: Previous value.
SetWindowLong function SetWindowLong(Wnd: HWnd; Index: Integer; NewLong: Longint): Longint; R e p l a c e s a n attribute o f a w i n d o w ' s w i n d o w - c l a s s s t r u c t u r e w i t h a n e w v a l u e . Parameters
Description
Wnd
W i n d o w identifier
Index
O n e of t h e gwl_ Window f i e l d offsets o r p o s i t i v e b y t e offset t o a c c e s s e x t r a 4-byte v a l u e s
NewLong
Replacement value
Return Value: Previous value.
SetWindowWord function SetWindowWord(Wnd: HWnd; Index: Integer; NewWord: Word): Word; C h a n g e s t h e v a l u e of a n attribute ( s p e c i f i e d b y Index) i n a w i n d o w ' s w i n d o w class s t r u c t u r e .
L — W i n d o w M a n a g e r Interface P r o c e d u r e s a n d F u n c t i o n s
Parameters
721
Description
Wnd
W i n d o w identifier
Index
O n e of t h e gww_ Window f i e l d offsets o r p o s i t i v e b y t e offset t o a c c e s s e x t r a 2-byte v a l u e s
NewWord
Replacement value
Return Value: Previous value.
UnregisterClass function UnregisterClass(ClassName: PChar; Instance: THandle): Bool; D e l e t e s a w i n d o w class f r o m t h e w i n d o w - c l a s s t a b l e a n d frees a n y a s s o c i a t e d memory. Parameters
Description
ClassName
Class n a m e (null-terminated) o f a previously registered class
Instance
M o d u l e i n s t a n c e that c r e a t e d t h e class
Return Value: N o n z e r o if s u c c e s s f u l ; 0 if i n v a l i d ClassName.
M REFERENCE
SYSTEM SERVICES INTERFACE P R O C E D U R E S A N D FUNCTIONS
A l p h a b e t i c a l listing o f S y s t e m Services I n t e r f a c e p r o c e d u r e s a n d f u n c t i o n s :
Application-Execution Atom-Management Communication File I/O Initialization-File Memory-Management Module-Management
Operating-System Interrupt Resource-Management Segment Sound String-Manipulation Task Utility Macros
Application-Execution Functions LoadModule WinExec WinHelp
724
Part I I I — R e f e r e n c e s
LoadModule function
LoadModule(ModuleName:
PChar;
ParameterBlock:
Pointer):
Loads and runs a Windows application. Parameters
Description
ModuleName
A p p l i c a t i o n file n a m e ( n u l l - t e r m i n a t e d )
ParameterBlock
F o u r field s t r u c t u r e
EnvSeg
Word, e n v i r o n m e n t s e g m e n t a d d r e s s o r 0 f o r Windows environment
CmdLine
L o n g i n t , c o m m a n d line
CmdShow
L o n g i n t , t w o W o r d - l e n g t h s t r u c t u r e , first w o r d set t o 2 , s e c o n d set t o CmdShow o f ShowWindow
Reserved
L o n g i n t , must be 0
Return Value: Library m o d u l e i n s t a n c e i d e n t i f i e r (value g r e a t e r t h a n 32) if s u c c e s s f u l . If n o t , its v a l u e is less t h a n 3 2 , a n d o n e o f t h e f o l l o w i n g : (0) n o m e m o r y (5) a t t e m p t t o l i n k task (6) m u l t i p l e d a t a s e g m e n t s (10) i n v a l i d W i n d o w s v e r s i o n (11) i n v a l i d E X E file (12) O S / 2 a p p (13) D O S 4 . 0 a p p (14) i n v a l i d E X E t y p e (15) n o t p r o t e c t m o d e
WinExec function WinExec(CmdLine: PChar; CmdShow: Word): Word; E x e c u t e s a n a p p l i c a t i o n s p e c i f i e d b y CmdLine. Parameters CmdLine
Description C o m m a n d line to execute the application (null-terminated)
CmdShow
S p e c i f i e s how a n a p p l i c a t i o n w i n d o w is initially
displayed
THandle;
M — S y s t e m Services Interface P r o c e d u r e s a n d F u n c t i o n s
Return
Value:
V a l u e g r e a t e r t h a n 3 2 if s u c c e s s f u l ; o t h e r w i s e it r e t u r n s o n e o f t h e f o l l o w i n g : (0) n o m e m o r y (5) a t t e m p t e d t o d y n a m i c a l l y l i n k t o a task (6) library h a s m u l t i p l e d a t a s e g m e n t s (10) W i n d o w s v e r s i o n i n c o r r e c t (11) invalid E X E file (12) O S / 2 a p p l i c a t i o n (13) D O S 4 . 0 a p p l i c a t i o n (14) u n k n o w n E X E t y p e (15) n o t a p r o t e c t e d - m o d e a p p l i c a t i o n
WinHdp function WinHelp(Wnd: HWnd; HelpFile: PChar; Command: Word; Data: Longint): Bool; Invokes Windows
help engine w i t h a c o m m a n d specified by Command.
Parameters
Description
Wnd
Window
identifier
HelpFile
N a m e ( n u l l - t e r m i n a t e d ) o f help p a t h , if n e e d e d
Command
O n e of the help_ H e l p c o m m a n d s
Data
Context identifier n u m b e r if Command set to help_Context or help topic keyword ( n u l l t e r m i n a t e d ) if Command set to help_Key
Return Value: N o n z e r o if s u c c e s s f u l ; e l s e 0
Atom-Management Procedures and Functions AddAtom DeleteAtom FindAtom
file
including
725
726
Part I I I — R e f e r e n c e s
GetAtomHandle GetAtomName GlobalAddAtom GlobalDeleteAtom GlobalFindAtom GlobalGetAtomName InitAtomTable MakelntAtom
AddAtom function AddAtom(Str: PChar): Atom; A d d s Str to t h e a t o m t a b l e . A reference count is m a i n t a i n e d for e a c h unique string i n s t a n c e . Parameters Str
Description Null-terminated character string
Return Value: U n i q u e a t o m i d e n t i f i e r if s u c c e s s f u l ; e l s e - 1 .
DeleteAtom function DeleteAtom(AnAtom: Atom): Atom; D e l e t e s an a t o m . If the Atom's reference count is zero, the a s s o c i a t e d string is removed from the a t o m t a b l e . Parameters AnAtom
Description A t o m identifier
Return Value: Zero if successful; else Atom.
FindAtom function FindAtom(Str: PChar): Atom; S e a r c h e s t h e atom t a b l e for t h e atom a s s o c i a t e d with Str. Parameters
Str
Description
Search string (null-terminated)
M — S y s t e m Services Interface Procedures and Functions
727
Return Value: A t o m associated w i t h S t r ; 0 if a t o m isn't f o u n d in table.
GetAtomHandle function
GetAtomHandle(AnAtom:
Atom):
THandle;
G e t s t h e string that c o r r e s p o n d s to a specified atom. Parameters AnAtom Return Value: Local m e m o r y handle
Description A t o m identifier
to atom string; 0 if t h e atom d o e s not exist.
GetAtomName function
GetAtomName(AnAtom:
Atom;
Buffer:
PChar;
Size:
Integer):
C o p i e s t h e associated a t o m string into B u f f e r . Parameters
Description
AnAtom
A t o m identifier
Buffer
Buffer to receive atom string
Size
Buffer size (in bytes)
Return Value: N u m b e r o f bytes c o p i e d into B u f f e r ; 0 if an invalid atom was specified.
GlobalAddAtom function
GlobalAddAtom(Str:
PChar):
Atom;
A d d s S t r to t h e atom table, t h u s creating a n e w global atom. Parameters Str
Description String (null-terminated)
Return Value: N e w l y created a t o m ; 0 if error.
Word;
728
Part III—References
GlobalDeleteAtom function GlobalDeleteAtom(AnAtom: Atom): Atom; Decreases a global atom's reference count by one, deleting the atom and its associated string from the atom table if the reference count becomes 0. Parameters
AnAtom Return
Description
A t o m identifier
Value:
Zero if successful; else AnAtom.
GlobalFindAtom function GlobalFindAtom(Str: PChar): Atom; Gets the global atom associated with Str. Parameters
Str Return
Description
Search string (null-terminated) Value:
Global atom; 0 if Str is not in the table.
GlobalGetAtomName function GlobalGetAtomName(AnAtom: Atom; Buffer: PChar; Size: Integer): Word; Copies the string associated with AnAtom into Buffer. Parameters
Description
AnAtom
A t o m identifier
Buffer
Receive buffer
Size
Size of Buffer
Return
Value:
N u m b e r of bytes copied; 0 if AnAtom is not valid.
M — S y s t e m Services Interface P r o c e d u r e s a n d F u n c t i o n s
InitAtomTable function InitAtomTable(Size: Integer): Bool; Initializes t h e a t o m h a s h t a b l e a n d sets its size. D e f a u l t is 3 7 . Parameters Size
Description N u m b e r o f table entries in a t o m hash table (should be a prime)
Return Value: N o n z e r o if s u c c e s s f u l ; e l s e 0 .
MakelntAtom (type) MakelntAtom = PStr; U s e MakelntAtom f o r t y p e c a s t i n g i n t e g e r n u m b e r s i n t o a t o m s . T h i s is e q u i v a l e n t t o t y p e c a s t i n g i n t o t h e T u r b o Pascal t y p e PChar.
Communication Procedures and Functions BuildCommDCB ClearCommBreak CloseComm EscapeCommFunction FlushComm GetCommError GetCommEventMask GetCommState OpenComm ReadComm SetCommBreak SetCommEventMask SetCommState TransmitCommChar UngetCommChar WriteComm
729
730
Part I I I — R e f e r e n c e s
BuildCommDCB function BuildCommDCB(Def: PChar; var DCB: TDCB): Integer; T r a n s l a t e s Def i n t o a p p r o p r i a t e d e v i c e - c o n t r o l b l o c k c o d e s that are c o p i e d i n t o DCB. Parameters
Description
Def
D O S M O D E c o m m a n d line (null-terminated) of device-control information
DCB
R e c e i v i n g TDCB s t r u c t u r e
Return Value: Z e r o if Def is t r a n s l a t e d ; e l s e n e g a t i v e .
ClearCommBreak function ClearCommBreak(Cid:
Integer): Integer;
R e s t o r e s c h a r a c t e r t r a n s m i s s i o n a n d p l a c e s t h e l i n e i n a n o n - b r e a k state. Parameters Cid
Description C o m m u n i c a t i o n device to b e restored
Return Value: Z e r o , if s u c c e s s f u l ; n e g a t i v e if Cid is n o t a v a l i d d e v i c e .
CloseComm function CloseComm(Cid: Integer): Integer; C l o s e s Cid, f l u s h i n g t h e o u t p u t q u e u e . F r e e s a n y m e m o r y u s e d f o r t r a n s m i t a n d receive q u e u e s . Parameters Cid
Description C o m m u n i c a t i o n s device
Return Value: Z e r o if d e v i c e is c l o s e d ; n e g a t i v e if e r r o r .
M — S y s t e m Services Interface P r o c e d u r e s a n d F u n c t i o n s
EscapeCommFunction function EscapeCommFunction(Cid, Func: Integer): Integer; E x e c u t e s t h e e x t e n d e d f u n c t i o n s p e c i f i e d b y Func o n a c o m m u n i c a t i o n s d e v i c e . Parameters
Description
Cid
C o m m u n i c a t i o n s device
Func
O n e o f t h e EscapeComm c o n s t a n t s
Return Value: Z e r o if s u c c e s s f u l ; n e g a t i v e if ab i n v a l i d f u n c t i o n c o d e w a s s p e c i f i e d .
FlushComm function FlushComm(Cid, Queue: Integer): Integer; Flushes a c o m m u n i c a t i o n device's transmit o r receive q u e u e . Parameters Cid Queue
Description C o m m u n i c a t i o n s device to b e
flushed
Z e r o t o flush t r a n s m i t q u e u e o r 1 t o flush receive q u e u e
Return Value: N o n z e r o if s u c c e s s f u l ; e l s e 0 .
GetCommError function GetCommError(Cid: Integer; var Stat: TComStat): Integer; Clears a device c o m m u n i c a t i o n s error. Parameters
Description
Cid
Communications device
Stat
TComStat t o r e c e i v e d e v i c e status i n f o r m a t i o n or nil
Return Value: O n e o f t h e ce_ Comm e r r o r flags' c o n s t a n t s .
731
732
Part III—References
GetCommEventMask function
GetCommEventMask(Cid,
EvtMask:
Integer):
Word;
G e t s a d e v i c e ' s c u r r e n t e v e n t m a s k , t h e n clears it. Parameters
Description
Cid
C o m m u n i c a t i o n s device
EvtMask
Events to be enabled
Return Value: Current event mask value.
GetCommState function
GetCommState(Cid:
Integer;
v a r DCB: T D C B ) :
Integer;
Gets a device's device control block. Parameters
Description
Cid
Communications device
DCB
TDCB t o r e c e i v e t h e c u r r e n t d e v i c e c o n t r o l block
Return Value: Z e r o if s u c c e s s f u l ; e l s e n e g a t i v e .
OpenComm function
OpenComm(ComName:
PChar;
InQueue,
OutQueue: Word):
Integer
O p e n s a c o m m u n i c a t i o n s d e v i c e . T h e d e v i c e is initialized t o a d e f a u l t c o n f i g u r a t i o n . T r a n s m i t a n d r e c e i v e q u e u e s are a l l o c a t e d . Parameters ComName
Description S t r i n g c o n t a i n i n g C O M n o r L P T n , w h e r e n is an integer
InQueue
R e c e i v e q u e u e size o r i g n o r e d f o r L P T p o r t s
OutQueue
T r a n s m i t q u e u e size o r i g n o r e d f o r L P T p o r t s
M — S y s t e m Services Interface P r o c e d u r e s a n d F u n c t i o n s
Return Value: Cid h a n d l e if s u c c e s s f u l ; e l s e n e g a t i v e e r r o r v a l u e ( o n e o f t h e ie_ c o m m u n i c a t i o n e r r o r flags).
733
Open
ReadComm function ReadComm(Cid: Integer; Buf: PChar, Size: Integer): Integer; R e a d s Cid a n d c o p i e s u p t o Size c h a r a c t e r s i n t o Buf. Parameters
Description
Cid
C o m m u n i c a t i o n s device
Buf
Receiving buffer
Size
Size o f Buffer
Return
Value:
N u m b e r o f c h a r a c t e r s r e a d ; 0 if n o c h a r a c t e r s a r e i n t h e r e c e i v e q u e u e ; n e g a t i v e if e r r o r .
SetCommBreak function SetCommBreak(Cid: Integer): Integer; Suspends character transmission a n d places the device's transmission line in a b r e a k state. Parameters Cid
Description C o m m u n i c a t i o n s device
Return Value: Z e r o if s u c c e s s f u l ; n e g a t i v e if i n v a l i d Cid.
SetCommEventMask function SetCommEventMask(Cid:
Integer; EvtMask: Word): PWord;
Activates a n d g e t s t h e c u r r e n t state o f a d e v i c e ' s e v e n t m a s k . Parameters Cid EvtMask
Description C o m m u n i c a t i o n s device A n y c o m b i n a t i o n of ev_ Comm e v e n t c o n s t a n t s
734
Part I I I — R e f e r e n c e s
Return
Value:
P o i n t e r t o a n e v e n t m a s k ; e a c h set bit i n d i c a t e s a n o c c u r r e n c e o f t h e e v e n t .
SetCommState function SetCommState(var DCB: TDCB): Integer; Reinitializes a c o m m u n i c a t i o n s d e v i c e s p e c i f i e d b y t h e Id field o f DCB t o t h e state s p e c i f i e d b y DCB. T r a n s m i t a n d r e c e i v e q u e u e s a r e n o t a f f e c t e d . Parameters DCB Return
Description TDCB s t r u c t u r e
Value:
Z e r o if s u c c e s s f u l ; e l s e n e g a t i v e .
TfonsmitCommChar function TransmitCommChar(Cid:
Integer; AChar: Char): Integer;
P u t s AChar at t h e h e a d o f t h e c o m m u n i c a t i o n d e v i c e ' s t r a n s m i t q u e u e f o r immediate transmission. Parameters
Description
Cid
C o m m u n i c a t i o n s device
AChar
Character t o transmit
Return
Value:
Z e r o if s u c c e s s f u l ; n e g a t i v e if t r a n s m i s s i o n is n o t p o s s i b l e b e c a u s e t h e p r e v i o u s character has n o t b e e n sent.
UngetCommChar function UngetCommChar(Cid: Integer; AChar: Char): Integer; P u t s AChar b a c k i n t o c o m m u n i c a t i o n d e v i c e ' s r e c e i v i n g q u e u e . Parameters
Description
Cid
C o m m u n i c a t i o n s device
AChar
Character to Un g et
Return Value: Z e r o if s u c c e s s f u l ; e l s e n e g a t i v e .
M — S y s t e m Services Interface P r o c e d u r e s a n d F u n c t i o n s
735
WriteComm f u n c t i o n WriteComm(Cid:
Integer;
Buf: PChar;
Size:
Integer):
Integer;
O u t p u t s the buffer specified by Buf to a c o m m u n i c a t i o n s device. Parameters
Description
Cid
C o m m u n i c a t i o n s device
Buf
Buffer containing characters t o b e written
Size
N u m b e r o f characters t o o u t p u t
Return Value: N u m b e r of characters written; negative if error has an absolute value that equals the n u m b e r of characters written before the error occurred.
File I/O Procedures and Functions GetDriveType GetSystemDirectory GetTempDrive GetTempFileName GetWindowsDirectory _lclose _lcreat _llseek _lopen _lread _lwrite OpenFile SetHandleCount
GetDriveType function GetDriveType(Drive: Integer): Word; Decides whether Drive is removeable, fixed, or remote. Parameters Drive
Description Drive to check (A is 0, B is 1, and so on.)
736
Part I I I — R e f e r e n c e s
Return
Value:
O n e of t h e drive_ Drive t y p e s c o n s t a n t s ; 0 if drive c a n n o t b e d e t e r m i n e d ; 1 if drive d o e s n o t exist.
GetSystemDirectory procedure GetSystemDirectory(Buffer:
PChar; Size: Word);
Gets the W i n d o w s system subdirectory path n a m e . Parameters
Description
Buffer
Receiving buffer
Size
S i z e o f B u f f e r (at least 144 c h a r a c t e r s )
GetTempDrive function GetTempDrive(DriveLetter: Char): Char; G e t s t h e d i s k d r i v e that h a s t h e o p t i m a l a c c e s s t i m e f o r t e m p o r a r y file operations. Parameters DriveLetter
Description D i s k drive letter o r 0 t o r e t u r n c u r r e n t drive
Return Value: D i s k drive letter.
GetTempFileName function GetTempFileName(DriveLetter:
Char; PrefixString: PChar;
Unique: Word; TempFileName: PChar): Integer; D e r i v e s a u n i q u e t e m p o r a r y file n a m e w i t h a p a t h n a m e of e i t h e r t h e r o o t d i r e c t o r y o r t h e d i r e c t o r y s p e c i f i e d b y t h e TEMP e n v i r o n m e n t v a r i a b l e . Parameters
Description
DriveLetter
S u g g e s t e d drive o r t f F o r c e D r i v e b i t - o r - e d with suggested drive o r 0 for default drive
PrefixString
File name t h r e e c h a r a c t e r p r e f i x ( n u l l terminated)
M — S y s t e m Services Interface P r o c e d u r e s a n d F u n c t i o n s
Parameters Unique
Description Base file-name n u m e r i c value, o r 0 for systemderived value
TempFileName
R e c e i v i n g p a t h - n a m e b u f f e r (at least 144 b y t e s long)
Return Value: File n a m e ' s n u m e r i c v a l u e .
Get^dowsDirectory function GetWindowsDirectory(Buffer:
PChar; Size: Word): Word;
G e t s the W i n d o w s directory path n a m e . Parameters
Description
Buffer
Receiving path n a m e buffer
Size
S i z e o f B u f f e r ( s h o u l d b e at least 144 b y t e s long)
Return Value: L e n g t h of t h e string c o p i e d i n t o Buffer.
Jclose function _lclose(FileHandle:
Integer): Integer;
C l o s e s a s p e c i f i e d file. Parameters FileHandle
Description D O S file h a n d l e
Return Value: Z e r o if s u c c e s s f u l ; e l s e - 1 .
lcreat function _lcreat(PathName: PChar; Attribute: O p e n s t h e s p e c i f i e d file.
Integer):Integer;
737
738
Part I I I — R e f e r e n c e s
Parameters
Description
Path n a m e
T h e D O S p a t h n a m e o f t h e file t o b e o p e n e d
Attribute
O n e of: (0) r e a d o r w r i t e , (1) r e a d o n l y , (2) h i d d e n , o r (3) s y s t e m file
Return
Value:
D O S file h a n d l e if s u c c e s s f u l ; e l s e - 1 .
Jlseek function _llseek(FileHandle: Integer; Offset: Longint; Origin: Integer): Longint; P o s i t i o n s t h e p o i n t e r i n a n o p e n file. Parameters
Description
FileHandle
D O S file h a n d l e
Offset
N u m b e r o f bytes t o m o v e the pointer
Origin
S p e c i f i e s t h e starting p o i n t a n d d i r e c t i o n o f t h e m o v e : (0) f o r w a r d f r o m t h e b e g i n n i n g , (1) f r o m t h e c u r r e n t p o s i t i o n , o r (2) b a c k f r o m t h e e n d o f t h e file
Return Value: T h e n e w offset o f t h e p o i n t e r ; - 1 if u n s u c c e s s f u l .
Jopen function _lopen(PathName: PChar; ReadWrite: Integer): Integer; O p e n s a file. Parameters
Description
Path n a m e
S t r i n g s p e c i f y i n g t h e p a t h a n d file n a m e
ReadWrite
Specifies the read a n d write access; o n e o f the f o l l o w i n g of _ Open file c o n s t a n t s : of_Read of_ReadWrite of Write
Return Value: T h e D O S file h a n d l e if s u c c e s s f u l ; e l s e - 1 .
M — S y s t e m Services Interface P r o c e d u r e s a n d F u n c t i o n s
Jread function _lread(FileHandle: Bytes: Integer): Word;
Integer; Buffer: PChar;
R e a d bytes f r o m a n o p e n file. Parameters
Description
FileHandle
T h e D O S file h a n d l e
Buffer
Receiving buffer
Bytes
T h e n u m b e r o f bytes t o read
Return Value: T h e n u m b e r o f b y t e s r e a d , if s u c c e s s f u l ; - 1 if n o t ; 0 if at t h e e n d o f file.
Jwrite function _lwrite(FileHandle: Bytes: Integer): Word;
Integer; Buffer: PChar;
W r i t e s d a t a f r o m Buffer i n t o t h e s p e c i f i e d file. Parameters
Description
FileHandle
D O S file h a n d l e
Buffer
H o l d s the data to b e written
Bytes
T h e n u m b e r o f bytes t o b e written
Return Value: T h e n u m b e r o f b y t e s w r i t t e n t o t h e file, if s u c c e s s f u l ; e l s e - 1 .
OpenFile function OpenFile(FileName: PChar; var ReOpenBuff: TOFStruct; Style: Word):
Integer;
C r e a t e s , o p e n s , r e o p e n s , o r d e l e t e s a file. Parameters
Description
File N a m e
T h e s p e c i f i e d file n a m e
ReOpenBuff
R e c e i v e s i n f o r m a t i o n a b o u t file w h e n o p e n e d
Style
S p e c i f i e s t h e a c t i o n ; o n e o f t h e of constants
Open file
739
740
Part I I I — R e f e r e n c e s
Return
Value:
D O S file h a n d l e if s u c c e s s f u l ; e l s e - 1 .
SetHandleCount function SetHandleCount(Number: Word): Word; C h a n g e s t h e n u m b e r o f file h a n d l e s available t o a task t o t h e v a l u e s p e c i f i e d b y Number. Parameters Number
Description N u m b e r o f r e q u i r e d file h a n d l e s ( m a x i m u m o f 255)
Return Value: N u m b e r o f file h a n d l e s a v a i l a b l e .
Initialization-File Procedures and Functions GetPrivateProfilelnt GetPrivateProfileString GetProfilelnt GetProfileString WritePrivateProfileString WriteProfileString
GetPrivateProfilelnt function GetPrivateProfilelnt(ApplicationName, Default: Integer; FileName: PChar): Word;
KeyName: PChar;
G e t s a n i n t e g e r k e y v a l u e f r o m a s p e c i f i e d i n i t i a l i z a t i o n file. Parameters
Description
ApplicationName
A p p l i c a t i o n h e a d i n g n a m e i n FileName
KeyName
Key n a m e i n FileName
Default
D e f a u l t v a l u e if KeyName n o t f o u n d
File N a m e
I n i t i a l i z a t i o n file n a m e i n W i n d o w s d i r e c t o r y
Return Value: Key v a l u e ; 0 if n e g a t i v e o r if Key v a l u e isn't a n i n t e g e r .
M — S y s t e m Services Interface P r o c e d u r e s a n d F u n c t i o n s
741
GetPrivateProfileString function GetPrivateProfileString(ApplicationName, KeyName, Default, ReturnedString: PChar; Size: Integer; FileName: PChar): Integer; G e t s a string k e y v a l u e f r o m a s p e c i f i e d i n i t i a l i z a t i o n file. Parameters
Description
ApplicationName
A p p l i c a t i o n h e a d i n g n a m e i n FileName
KeyName
Key n a m e i n FileName o r n i l t o o b t a i n list o f key names
Default
D e f a u l t v a l u e if KeyName n o t f o u n d
ReturnedString
Receiving buffer
Size
Size o f Buffer
File N a m e
I n i t i a l i z a t i o n file n a m e i n W i n d o w s d i r e c t o r y
Return
Value:
N u m b e r o f characters c o p i e d .
GetProfilelnt function GetProfilelnt(AppName,
KeyName: PChar; Default: Integer): Word;
G e t s a n i n t e g e r k e y v a l u e f r o m W i n d o w s W I N . I N I file. Parameters
Description
AppName
Application heading name
KeyName
Search key name
Default
D e f a u l t v a l u e if KeyName is n o t f o u n d
Return Value: K e y v a l u e ; 0 if n e g a t i v e o r if k e y v a l u e isn't a n i n t e g e r .
GetProfileString function GetProfileString(AppName, KeyName, Default, ReturnedString: PChar; Size: Integer): Integer;
742
Part I I I — R e f e r e n c e s
G e t s a string k e y v a l u e f r o m W i n d o w s W I N . I N I file Parameters AppName KeyName
Description Application heading name S e a r c h k e y n a m e o r n i l t o o b t a i n all k e y n a m e s a s s o c i a t e d w i t h AppName
Default
D e f a u l t v a l u e if KeyName n o t f o u n d
ReturnedString
Receiving buffer
Size
Size o f Buffer
Return Value: N u m b e r o f characters c o p i e d .
WritePrivateProfileString function WritePrivateProfileString(ApplicationName, KeyName, Str, FileName: PChar): Bool; S e a r c h e s FileName f o r a s p e c i f i e d a p p l i c a t i o n h e a d i n g a n d k e y n a m e ; t h e n r e p l a c e s t h e Key n a m e w i t h Str. Parameters
Description
ApplicationName
Application heading name
KeyName
Key n a m e appearing under the application heading n a m e o r nil to delete entire section
Str
N e w k e y n a m e string o r n i l t o d e l e t e k e y n a m e
File n a m e
I n i t i a l i z a t i o n file n a m e ( n u l l - t e r m i n a t e d )
Return Value: N o n z e r o if s u c c e s s f u l ; e l s e 0.
WritePfoffleString function WriteProfileString(ApplicationName,
KeyName, Str: PChar): Bool;
Searches W I N . I N I for the specified application heading a n d key n a m e ; then r e p l a c e s t h e k e y n a m e w i t h St r.
M — S y s t e m Services Interface P r o c e d u r e s a n d F u n c t i o n s
Parameters
Description
ApplicationName
Application heading
KeyName
Key n a m e appearing u n d e r the application h e a d i n g n a m e , or nil to delete entire application section
Str
N e w key n a m e value or nil to delete key n a m e
Return Value: N o n z e r o if s u c c e s s f u l ; e l s e 0.
Memory-Management Procedures and Functions DefineHandleTable GetFreeSpace GetWinFlags GlobalAlloc GlobalCompact GlobalDiscard GlobalDosAlloc GlobalDosFree GlobalFlags GlobalFree GlobalHandle GlobalLock GlobalLRUNewest GlobalLRUOldest GlobalNotify GlobalReAlloc GlobalSize GlobalUnlock GlobalUnwire GlobalWire LimitEMSPages LocalAlloc LocalCompact LocalDiscard LocalFlags LocalFree LocalHandle
743
744
Part I I I — R e f e r e n c e s
Locallnit LocalLock LocalReAlloc LocalShrink LocalSize LocalUnlock LockData LockSegment SetSwapAreaSize SwitchStackBack SwitchStackTo UnlockData UnLockSegment
DefineHandleTable function
DefineHandleTable(Offset:
Word):
Bool;
C r e a t e s a private h a n d l e t a b l e i n t h e d e f a u l t d a t a s e g m e n t . T h e t a b l e h o l d s t h e a d d r e s s e s o f l o c k e d g l o b a l m e m o r y o b j e c t s , r e t u r n e d b y G l o b a l L o c k . If t h e s e m e m o r y o b j e c t s are m o v e d , W i n d o w s u p d a t e s t h e i r a d d r e s s e s w h e n r u n n i n g i n r e a l m o d e . A d d r e s s e s a r e n ' t u p d a t e d i n p r o t e c t e d m o d e s ( S t a n d a r d a n d 386Enhanced). T h e h a n d l e t a b l e c o n s i s t s o f t w o W o r d - t y p e v a l u e s f o l l o w e d b y a n array o f addresses. • T h e first w o r d is t h e n u m b e r o f e n t r i e s i n t h e t a b l e , w h i c h m u s t b e initialized b e f o r e t h e call t o D e f i n e H a n d l e T a b l e . • T h e s e c o n d is t h e n u m b e r o f e n t r i e s t o set t o 0 w h e n W i n d o w s u p d a t e s its list o f least r e c e n t l y u s e d m e m o r y . E i t h e r w o r d c a n b e c h a n g e d at a n y t i m e . T h e a d d r e s s e s i n t h e rest o f t h e t a b l e are r e t u r n e d b y G l o b a l L o c k . Parameters Offset
Description T h e offset o f t h e t a b l e f r o m t h e b e g i n n i n g o f t h e d a t a s e g m e n t . A v a l u e o f 0 i n d i c a t e s that W i n d o w s s h o u l d n o l o n g e r u p d a t e the table
Return
Value:
Z e r o if s u c c e s s f u l ; e l s e n o n z e r o .
M — S y s t e m Services Interface P r o c e d u r e s a n d F u n c t i o n s
GetFreeSpace function
GetFreeSpace(Flag:
Word):
Longint;
G e t s t h e a m o u n t o f free m e m o r y in t h e g l o b a l Parameters
Description
Flag
Return
heap.
T h e constant gmem_Not_Banked to scan below b a n k l i n e o r 0 t o s c a n a b o v e ; ignored f o r n o n E M S systems Value:
M e m o r y available (in b y t e s ) .
GetWinFlags function
GetWinFlags:
Longint;
G e t s t h e m e m o r y - c o n f i g u r a t i o n flags i n effect d u r i n g t h e c u r r e n t W i n d o w s session. Return Value: Flag mask specifying the current m e m o r y configuration; can include o n e of t h e f o l l o w i n g wf _ W i n d o w s m e m o r y c o n f i g u r a t i o n flags: wf_CPU286 wf_CPU386 wf_PMode wf_SmallFrame wf_Win286 wf
Win386
GlobalAlloc function
GlobalAlloc(Flags:
A l l o c a t e s requested Parameters Flags
Word;
Bytes:
Longint):
a m o u n t o f m e m o r y , at m i n i m u m , f r o m t h e g l o b a l Description F l a g m a s k ; o n e o r m o r e o f t h e gmem_ G l o b a l m e m o r y flags c o n s t a n t s
Bytes Return
THandle;
N u m b e r o f bytes to allocate Value:
A l l o c a t e d g l o b a l m e m o r y identifier;
0 if error.
heap.
745
746
Part I I I — R e f e r e n c e s
GlobalCompact function GlobalCompact(MinFree:
Longint): Longint;
C o m p a c t s global m e m o r y a n d , w h e n necessary a n d possible, d i s c a r d a b l e s e g m e n t s t o c r e a t e a MinFree size b l o c k . Parameters MinFree
Return
removes
Description D e s i r e d free b y t e s o r 0 t o r e t u r n largest free s e g m e n t , if all d i s c a r d a b l e s e g m e n t s a r e removed
Value:
S i z e o f largest free b l o c k .
GlobalDLscard function GlobalDiscard(Mem: THandle): THandle; D i s c a r d s t h e s p e c i f i e d g l o b a l m e m o r y b l o c k if t h e b l o c k is d i s c a r d a b l e a n d unlocked. Parameters Mem
Description T h e handle of the global memory block to discard
Return Value: H a n d l e o f t h e b l o c k if s u c c e s s f u l l y d i s c a r d e d ; e l s e 0.
GlobalDosAlloc function GlobalDosAlloc(Bytes: Longint): Longint; A l l o c a t e s g l o b a l m e m o r y i n t h e first m e g a b y t e o f l i n e a r a d d r e s s s p a c e that c a n be accessed by D O S . A v o i d u s i n g this f u n c t i o n , if p o s s i b l e , b e c a u s e l o w m e m o r y is a s c a r c e system resource. Parameters Bytes Return
Description T h e n u m b e r o f bytes t o allocate
Value:
Z e r o if m e m o r y c o u l d n o t b e a l l o c a t e d ; e l s e , t h e v a l u e is a p a r a g r a p h - s e g m e n t value in the high-order word a n d a selector in the low-order word.
M — S y s t e m Services Interface P r o c e d u r e s a n d F u n c t i o n s
In Real m o d e , the paragraph-segment value c a n b e u s e d to access the allocated memory. I n protected m o d e , the selector should not b e used.
GlobalDosFree function GlobalDosFree(Selector: Word): Word; F r e e s a b l o c k o f m e m o r y a l l o c a t e d b y GlobalDosAlloc. Parameters Selector
Description T h e s e l e c t o r o f t h e m e m o r y t o free
Return Value: Z e r o if s u c c e s s f u l ; e l s e Selector.
GlobalFlags function GlobalFlags(Mem: THandle): Word; G e t s i n f o r m a t i o n a b o u t Mem. Parameters Mem Return
Description G l o b a l m e m o r y b l o c k identifier
Value:
I n h i g h b y t e : em_Ddeshare, gmem_Discardable, gmem_Discarded, o r gmem_Not_Banked. I n l o w b y t e : lock r e f e r e n c e - c o u n t .
GlobalFree function GlobalFree(Mem: THandle): THandle; F r e e s a n u n l o c k e d g l o b a l m e m o r y b l o c k a n d i n v a l i d a t e s its h a n d l e . Parameters Mem
Description G l o b a l m e m o r y b l o c k identifier
Return Value: Z e r o if s u c c e s s f u l ; e l s e Mem.
747
748
Part I I I — R e f e r e n c e s
GlobalHandle function GlobalHandle(Mem: Word): Longint; Gets the handle o f a global m e m o r y object with the specified segment address. Parameters Mem Return
Description Segment address
Value:
H a n d l e a n d s e g m e n t a d d r e s s i n l o w - a n d h i g h - w o r d , r e s p e c t i v e l y ; 0 if Handle d o e s n ' t exist.
GlobalLock function GlobalLock(Mem: THandle): Pointer; Increments the reference count o f a global m e m o r y block a n d returns a p o i n t e r t o it. Parameters Mem
Description G l o b a l m e m o r y b l o c k identifier
Return Value: M e m o r y b l o c k a d d r e s s if s u c c e s s f u l ; e l s e n i l .
GlobalLRUNewest function GlobalLRUNewest(Mem: THandle): THandle; R e d u c e s t h e c h a n c e a g l o b a l m e m o r y o b j e c t w i l l b e d i s c a r d e d b y m o v i n g it i n t o t h e n e w e s t , least r e c e n t l y u s e d m e m o r y p o s i t i o n . Parameters Mem Return Value: Z e r o if i n v a l i d Mem.
Description G l o b a l m e m o r y object identifier
M — S y s t e m Services Interface P r o c e d u r e s a n d F u n c t i o n s
GlobalLRUOldest function GlobalLRUOldest(Mem: THandle): THandle; I n c r e a s e s t h e c h a n c e a g l o b a l m e m o r y o b j e c t w i l l b e d i s c a r d e d b y m o v i n g it i n t o t h e o l d e s t , least recently u s e d m e m o r y p o s i t i o n . Parameters Mem
Description G l o b a l m e m o r y object identifier
Return Value: Z e r o if i n v a l i d Mem.
GlobalNotify procedure GlobalNotify(NotifyProc: TFarProc); C a l l s NotifyProc p a s s i n g t h e h a n d l e o f t h e g l o b a l m e m o r y b l o c k t o b e d i s c a r d e d . I f NotifyProc returns Parameters NotifyProc
n o n z e r o , t h e b l o c k is d i s c a r d e d .
Description Notification callback procedure's instanceaddress
GlobalReAlloc function GlobalReAlloc(Mem: THandle; Bytes: Longint; Flags: Word): THandle; R e a l l o c a t e s a g l o b a l m e m o r y b l o c k t o Bytes s i z e . Parameters
Description
Mem
G l o b a l m e m o r y b l o c k identifier
Bytes
N e w size o f Mem
Flags
O n e o r m o r e o f t h e f o l l o w i n g gmem_ G l o b a l m e m o r y flags: gmem_Discardable gmem_Notify gmem_Moveable gmem_NoCompact gmem_NoDiscard gmem Zerolnit
749
750
Part I I I — R e f e r e n c e s
Return
Value:
R e a l l o c a t e d g l o b a l m e m o r y b l o c k identifier; 0 if e r r o r .
Globalize function GlobalSize(Mem: THandle): Longint; G e t s t h e c u r r e n t size o f a g l o b a l m e m o r y b l o c k . Parameters Mem
Description G l o b a l m e m o r y b l o c k identifier
Return Value: S i z e (in b y t e s ) ; 0 if Mem is i n v a l i d o r d i s c a r d e d .
GlobalUnlock function GlobalUnlock(Mem: THandle): Bool; U n l o c k s a g l o b a l m e m o r y b l o c k l o c k e d b y GlobalLock. I f t h e b l o c k ' s l o c k r e f e r e n c e - c o u n t r e a c h e s 0, t h e b l o c k is s u b j e c t t o m o v i n g o r d i s c a r d i n g . Parameters Mem Return
Description G l o b a l m e m o r y b l o c k identifier
Value:
Z e r o if l o c k r e f e r e n c e - c o u n t d e c r e m e n t s t o 0; e l s e n o n z e r o .
GlobalUnWire function GlobalUnWire(Mem: THandle): Bool; U n l o c k s a m e m o r y s e g m e n t p r e v i o u s l y l o c k e d b y GlobalWire. Parameters Mem
Description S e g m e n t identifier
Return Value: N o n z e r o if s e g m e n t u n l o c k e d ; e l s e 0.
M — S y s t e m Services Interface P r o c e d u r e s a n d F u n c t i o n s
GlobalWire function GlobalWire(Mem: THandle): PChar; M o v e s a s e g m e n t , w h i c h m u s t b e l o c k e d for a l o n g p e r i o d , i n t o l o w m e m o r y a n d l o c k s it. Parameters Mem
Description S e g m e n t identifier
Return Value: N e w s e g m e n t l o c a t i o n if s u c c e s s f u l ; e l s e n i l .
IimitEmsPages procedure LimitEmsPages(Kbytes: Longint); L i m i t s a m o u n t of e x p a n d e d m e m o r y (in K ) that Windows a s s i g n s to a n a p p l i c a t i o n w h e n running u n d e r e x p a n d e d m e m o r y c o n f i g u r a t i o n . Parameters Kbytes
Description N u m b e r o f kilobytes o f e x p a n d e d m e m o r y assigned
LocalAlloc function LocalAlloc(Flags, Bytes: Word): THandle; A l l o c a t e s a l o c a l m e m o r y b l o c k from the l o c a l heap. T h e true size m i g h t b e larger than t h e s p e c i f i e d size. Parameters
Description
Flags
O n e or m o r e of the following lmem_ L o c a l m e m o r y flags c o n s t a n t s : lmem_Discardable lmem_Fixed lmem_Modify lmem_Moveable lmem_Nocompact lmem_Nodiscard lmem_Zeroinit
Bytes
S i z e (in bytes) o f b l o c k t o a l l o c a t e
751
752
Part I I I — R e f e r e n c e s
Return Value: L o c a l m e m o r y b l o c k i d e n t i f i e r if s u c c e s s f u l ; e l s e 0.
LocalCompact function LocalCompact(MinFree: Word): Word; G e n e r a t e s a free b l o c k o f at least MinFree size. If n e c e s s a r y , t h e f u n c t i o n m o v e s or discards u n l o c k e d blocks. Parameters
Description
MinFree
N u m b e r o f desired free bytes, o r 0 t o return largest c o n t i g u o u s b l o c k
Return Value: S i z e ( i n b y t e s ) o f largest b l o c k .
LocalDiscard function LocalDiscard(Mem: THandle): THandle; D i s c a r d s t h e s p e c i f i e d l o c a l m e m o r y b l o c k , l e a v i n g its h a n d l e v a l i d , m e a n i n g t h e h a n d l e c a n b e r e u s e d b y c a l l i n g LocalReAlloc. Parameters Mem Return
Description T h e handle of the local m e m o r y block
Value:
Z e r o if s u c c e s s f u l ; e l s e Mem.
LocalFlags function LocalFlags(Mem: THandle): Word; Gets information about a memory block. Parameters Mem Return
Description Local m e m o r y b l o c k identifier
Value:
In high byte: In l o w byte:
lmem_Discardable o r lmem_Discarded lock count
M — S y s t e m Services Interface P r o c e d u r e s a n d F u n c t i o n s
LocalFree function LocalFree(Mem: THandle): THandle; F r e e s a l o c a l m e m o r y b l o c k a n d i n v a l i d a t e s its h a n d l e . Parameters Mem
Description Local m e m o r y b l o c k identifier
Return Value: Z e r o if s u c c e s s f u l ; e l s e Mem.
LocalHandle function LocalHandle(Mem: Word): THandle; G e t s t h e h a n d l e o f a l o c a l m e m o r y o b j e c t at a s p e c i f i e d a d d r e s s . Parameters Mem
Description Local m e m o r y object address
Return Value: Local m e m o r y object identifier.
Locallnit function LocalIni(Segment, Start, End: Word): Bool; Initializes a l o c a l h e a p a n d calls GlobalLock t o l o c k t h e s e g m e n t . Parameters
Description
Segment
Segment address o f local h e a p
Start
O f f s e t a d d r e s s t o start o f l o c a l h e a p
End
Offset address to e n d o f local h e a p
Return Value: N o n z e r o if i n i t i a l i z e d ; e l s e 0.
LocalLock function LocalLock(Mem: THandle): Pointer; L o c k s Mem a n d i n c r e m e n t s its l o c k c o u n t . T h e b l o c k c a n n o t b e m o v e d o r discarded.
753
754
Part I I I — R e f e r e n c e s
Parameters Mem
Description Local m e m o r y b l o c k identifier
Return Value: P o i n t e r t o b l o c k if s u c c e s s f u l ; e l s e n i l .
LocalReAlloc function
LocalReAlloc(Mem:
THandle;
Bytes,
Flags:
Word):
THandle
C h a n g e s t h e size o r a t t r i b u t e s , as s p e c i f i e d b y F l a g s , o f a l o c a l m e m o r y b l o c k . Parameters
Description
Mem
Local m e m o r y b l o c k identifier
Bytes
N e w size (in b y t e s ) o f b l o c k
Flags
O n e o r m o r e o f t h e l m e m _ L o c a l m e m o r y flags: lmem_Discardable lmem_Modify lmem_Moveable lmem_NoCompact lmem_NoDiscard lmem_ZeroInit
Return Value: L o c a l m e m o r y b l o c k i d e n t i f i e r if s u c c e s s f u l ; e l s e 0.
LocalShrink function
LocalShrink(Seg:
THandle;
Size:
Word):
Word;
R e d u c e s t h e l o c a l h e a p t o t h e s p e c i f i e d size w h o s e v a l u e m u s t b e g r e a t e r t h a n t h e m i n i m u m size s p e c i f i e d i n t h e a p p l i c a t i o n ' s m o d u l e - d e f i n i t i o n Parameters
Description
Seg
Segment containing local h e a p , or 0 for current data segment
Size
D e s i r e d size (in b y t e s ) ,
Return Value: S i z e after s h r i n k a g e .
file.
M — S y s t e m Services Interface P r o c e d u r e s a n d F u n c t i o n s
LocalSize function
LocalSize(Mem: THandle):
Word;
G e t s t h e size o f a l o c a l m e m o r y b l o c k . Parameters Mem
Description Local m e m o r y b l o c k identifier
Return Value: S i z e (in bytes) o f b l o c k ; 0 if i n v a l i d Mem.
LocalUnlock function
LocalUnlock(Mem: THandle):
Bool;
U n l o c k s a l o c a l m e m o r y b l o c k b y d e c r e m e n t i n g its l o c k c o u n t . Parameters Mem Return
Description L o c a l m e m o r y b l o c k identifier
Value:
Z e r o if l o c k c o u n t d e c r e m e n t e d t o 0 ( m a k i n g t h e b l o c k s u b j e c t t o m o v i n g o r discarding); else n o n z e r o .
LockData function
LockData(Dummy:
Integer):
THandle;
Locks the current moveable data segment in m e m o r y . Parameters Dummy
Description N o t u s e d ; set t o 0
Return Value: I d e n t i f i e r f o r t h e l o c k e d d a t a s e g m e n t if s u c c e s s f u l ; e l s e 0.
LockSegment function
LockSegment(Segment:
Word):
THandle;
Locks a segment (except protected-mode, non-discardable segments) and i n c r e m e n t s its l o c k r e f e r e n c e - c o u n t .
755
756
Part I I I — R e f e r e n c e s
Parameters
Description
Segment Return
Segment address o r - 1 for current segment
Value:
P o i n t e r t o s e g m e n t ; n i l if e r r o r o r d i s c a r d e d .
SetSwapAreaSize function SetSwapAreaSize(Size: Word): Longint; I n c r e a s e s t h e a m o u n t o f m e m o r y ( u p t o o n e - h a l f o f r e m a i n i n g s p a c e after W i n d o w s is l o a d e d ) a n a p p l i c a t i o n c a n u s e f o r its c o d e s e g m e n t s . Parameters
Description
Size Return
N u m b e r o f 16-byte p a r a g r a p h s Value:
N u m b e r o f p a r a g r a p h s o b t a i n e d i n l o w - o r d e r w o r d ; m a x i m u m size available i n high-order word.
SwitchStackBack procedure
SwitchStackBack;
R e s t o r e s t h e c u r r e n t task's stack t o its d a t a s e g m e n t p r e s e r v i n g t h e c o n t e n t s o f AX: DX r e g i s t e r s .
UnlockData function UnlockData(Dummy:
Integer): THandle;
Unlocks the current, moveable data segment. Parameters Dummy
Description N o t u s e d ; set t o 0
Return Value: I d e n t i f i e r f o r t h e u n l o c k e d s e g m e n t ; e l s e 0.
M — S y s t e m Services Interface P r o c e d u r e s a n d F u n c t i o n s
UnlockSegment function UnlockSegment(Segment: Word): THandle; U n l o c k s a s e g m e n t s p e c i f i e d b y Segment. Parameters
Description
Segment
Return Value: Z e r o if reference
Segment address or - 1 to u n l o c k current data segment
c o u n t w a s d e c r e m e n t e d t o 0; e l s e n o n z e r o .
Module-Management Procedures and Functions FreeLibrary FreeModule FreeProcInstance GetCodeHandle GetlnstanceData GetModuleFileName GetModuleHandle GetModuleUsage GetProcAddress GetVersion LoadLibrary MakeProcInstance
Freelibrary procedure Freel_ibrary(LibModule: THandle); I n v a l i d a t e s LibModule a n d frees a n y a s s o c i a t e d m e m o r y if t h e m o d u l e is n o longer referenced. Parameters LibModule
Description L o a d e d library m o d u l e
757
758
Part I I I — R e f e r e n c e s
FreeModule function FreeModule(Module: THandle): Bool; I n v a l i d a t e s Module a n d frees a n y a s s o c i a t e d m e m o r y if t h e m o d u l e is n o l o n g e r referenced. Parameters Module
Description L o a d e d m o d u l e identifier
Return Value: Not used.
FreeProcInstance procedure FreeProcInstance(Proc: TFarProc); Frees a function's procedure-instance address. Parameters Proc
Description Function's procedure-instance address (to b e freed)
GetCodeHandle function GetCodeHandle(Proc: TFarProc): THandle; G e t s t h e c o d e s e g m e n t that c o n t a i n s t h e s p e c i f i e d f u n c t i o n a n d l o a d s t h e s e g m e n t , if n e c e s s a r y . Parameters Proc
Description Function's procedure-instance address
Return Value: C o d e s e g m e n t that c o n t a i n s t h e f u n c t i o n .
GetlnstanceData function GetInstanceData(Instance: THandle; Data, Count: Word): C o p i e s a p r e v i o u s i n s t a n c e d a t a i n t o Data.
Integer;
M — S y s t e m Services Interface P r o c e d u r e s a n d F u n c t i o n s
Parameters
Description
Instance
Previous application's instance identifier
Data
Receiving buffer
Count
Size o f Buffer
Return Value: N u m b e r o f bytes c o p i e d .
GetModuleFileName function GetModuleFileName(Module: THandle; FileName: PChar; Size: Integer): Integer; G e t s t h e f u l l p a t h n a m e ( n u l l - t e r m i n a t e d ) o f t h e e x e c u t a b l e file f o r t h e s p e c i f i e d module. Parameters
Description
Module
M o d u l e identifier
File n a m e
Receiving buffer
Size
Size o f Buffer
Return Value: N u m b e r o f bytes c o p i e d .
GetModuleHandle function GetModuleHandle(ModuleName:
PChar): THandle;
Gets a module's handle. Parameters ModuleName
Description M o d u l e n a m e (null-terminated)
Return Value: M o d u l e i d e n t i f i e r if s u c c e s s f u l ; e l s e 0.
GetModuleUsage function GetModuleUsage(Module: THandle): Integer; Gets a module's reference count.
759
760
Part III—References
Parameters
Module Return
Description
Module identifier
Value:
Reference count.
GetProcAddress function GetProcAddress(Module: THandle; ProcName: PChar): TFarProc Gets the address of an exported library function. Parameters
Description
Module
Library module
ProcName
Function n a m e (null-terminated) or ordinal name
Return
Value:
Function's entry point if successful; else 0.
GetVersion function GetVersion: Word; Gets Window's current version number. Return
Value:
Minor version n u m b e r in high-order byte; Major version n u m b e r in low-order byte.
Loadlibrary function LoadLibrary(LibFileName: PChar): THandle; Loads the library module. Parameters
LibFileName Return
Description
Libraryfilen a m e (null-terminated).
Value:
Library module instance identifier (value greater than 32) if successful. If not, its value is less than 32 and one of the following:
M — S y s t e m Services Interface P r o c e d u r e s a n d F u n c t i o n s
761
(0) n o m e m o r y (5) a t t e m p t t o l i n k task (6) m u l t i p l e d a t a s e g m e n t s (10) i n v a l i d W i n d o w s v e r s i o n (11) i n v a l i d E X E file (12) OS/2 a p p (13) D O S 4.0 a p p (14) I n v a l i d E X E t y p e (15) n o t p r o t e c t m o d e
MakeProcInstance function MakeProcInstance(Proc: TFarProc; Instance: THandle): TFarProc; Creates a procedure-instance address for the specified exported function. Parameters
Description
Proc
E x p o r t e d f u n c t i o n TFarProc a d d r e s s
Instance
M o d u l e instance identifier
Return Value: F u n c t i o n p r o c e d u r e - i n s t a n c e a d d r e s s if s u c c e s s f u l ; e l s e 0.
Operating-System Interrupt Procedures and Functions D0S3Call NetBIOSCall
D0S3Call procedure D0S3Call; C a l l s t h e D O S i n t e r r u p t f u n c t i o n 21 h. D0S3Call s h o u l d b e u s e d o n l y i n a s s e m b l y l a n g u a g e r o u t i n e s , as t h e registers for t h e INT 21 h call m u s t b e set. U n d e r W i n d o w s , D0S3Call w o r k s s o m e w h a t faster t h a n a d i r e c t call t o t h e s o f t w a r e i n t e r r u p t .
762
Part I I I — R e f e r e n c e s
NetBIOSCall procedure NetBIOSCall; C a l l s t h e N E T B I O S i n t e r r u p t 5Ch. U s e this call i n s t e a d o f a d i r e c t call t o t h e 5Ch software interrupt for future compatibility. Y o u s h o u l d call NetBIOSCall o n l y i n a s s e m b l y l a n g u a g e r o u t i n e s b e c a u s e t h e C P U registers m u s t b e set f o r t h e i n t e r r u p t c a l l .
Resource-Management Procedures and Functions AccessResource AllocResource FindResource FreeResource LoadAccelerators LoadBitmap LoadCursor Loadlcon LoadMenu LoadResource LoadString LockResource SetResourceHandler SizeofResource UnlockResource
AccessResource function AccessResource(Instance, Reslnfo: THandle): Integer; O p e n s a n d p o s i t i o n s t h e r e s o u r c e file t o t h e b e g i n n i n g o f a r e s o u r c e . B e s u r e t o c l o s e t h e file after r e a d i n g t h e r e s o u r c e . Parameters
Description
Instance
I n s t a n c e m o d u l e w h o s e e x e c u t a b l e file contains the resource
Reslnfo
Desired resource, created by calling the
FindResource f u n c t i o n
M — S y s t e m Services Interface P r o c e d u r e s a n d F u n c t i o n s
763
Return Value: D O S file h a n d l e : - 1 if t h e r e s o u r c e is n o t f o u n d .
AllocResource f
function AllocResource(Instance, Reslnfo: THandle; Size: Longint): THandle; A l l o c a t e s u n i n i t i a l i z e d m e m o r y f o r Reslnfo. Parameters
Description
Instance
M o d u l e i n s t a n c e o f e x e c u t a b l e file c o n t a i n i n g the resource
Reslnfo
Desired resource
Size
Size in bytes t o allocate for the resource; i g n o r e d if 0
Return Value: Allocated global memory block.
FindResource function FindResource(Instance: THandle; Name, ResType: PChar): THandle; L o c a t e s a r e s o u r c e i n a r e s o u r c e file. Parameters
Description
Instance
M o d u l e i n s t a n c e w h o s e e x e c u t a b l e file c o n tains t h e r e s o u r c e
Name
R e s o u r c e n a m e e i t h e r a n u l l - t e r m i n a t e d string o r a n i n t e g e r ID
ResType
O n e o f t h e rt_ Resource t y p e s c o n s t a n t s , a n u l l - t e r m i n a t e d string, o r a n i n t e g e r ID
Return
Value:
R e s o u r c e i d e n t i f i e r ; 0 if t h e r e s o u r c e isn't f o u n d .
FreeResource function FreeResource(ResData: THandle): Bool; I n v a l i d a t e s ResData a n d frees a s s o c i a t e d m e m o r y if t h e r e s o u r c e is n o l o n g e r referenced.
764
Part I I I — R e f e r e n c e s
Parameters ResData
Description R e s o u r c e data identifier
Return Value: Z e r o if s u c c e s s f u l ; e l s e n o n z e r o .
LoadAccelerators function
LoadAccelerators(Instance:
THandle;
Loads a n accelerator table from an executable Parameters
TableName:
PChar):
THandle
file.
Description
Instance
M o d u l e i n s t a n c e w h o s e e x e c u t a b l e file c o n tains t h e a c c e l e r a t o r t a b l e
TableName
Accelerator table n a m e (null-terminated) or integer ID
Return Value: A c c e l e r a t o r t a b l e i d e n t i f i e r if s u c c e s s f u l ; e l s e 0.
LoadBitmap function
LoadBitmap(Instance:
THandle;
BitmapName:
PChar):
L o a d s a bit m a p r e s o u r c e . Parameters Instance
BitmapName
Description M o d u l e i n s t a n c e w h o s e e x e c u t a b l e file c o n tains t h e bit m a p , o r 0 f o r p r e d e f i n e d bit m a p S t r i n g ( n u l l - t e r m i n a t e d ) o r i n t e g e r I D specifyi n g t h e bit m a p , o r a p r e d e f i n e d bit m a p , s p e c i f i e d b y a n o b m _ P r e d e f i n e d bit m a p s constant
Return Value: Bit m a p i d e n t i f i e r if s u c c e s s f u l ; e l s e 0.
HBitmap;
M — S y s t e m Services Interface P r o c e d u r e s a n d F u n c t i o n s
765
LoadCursor function LoadCursor(Instance: THandle; CursorName: PChar): HCursor; Loads a cursor resource. Parameters Instance
CursorName
Description M o d u l e i n s t a n c e w h o s e e x e c u t a b l e file c o n tains t h e c u r s o r , o r 0 f o r p r e d e f i n e d c u r s o r S t r i n g ( n u l l - t e r m i n a t e d ) o r i n t e g e r ID n a m e o r a predefined cursor, specified with o n e o f the idc_ Standard c u r s o r I D s c o n s t a n t s
Return Value: C u r s o r i d e n t i f i e r if s u c c e s s f u l ; 0 if c u r s o r isn't f o u n d ; u n d e f i n e d if n o t a c u r s o r resource.
Loadlcon function LoadIcon(Instance: THandle; IconName: PChar): Hlcon; Loads an icon resource. Parameters Instance
IconName
Description M o d u l e i n s t a n c e w h o s e e x e c u t a b l e file c o n tains t h e i c o n , o r 0 f o r p r e d e f i n e d i c o n S t r i n g o r i n t e g e r ID n a m e o r p r e d e f i n e d i c o n , s p e c i f i e d w i t h o n e o f t h e idi_ Standard i c o n IDs
Return Value: I c o n i d e n t i f i e r if s u c c e s s f u l ; e l s e 0.
LoadMenu function LoadMenu(Instance: THandle; MenuName: PChar): HMenu; Loads a m e n u resource.
766
Part I I I — R e f e r e n c e s
Parameters
Description
Instance
M o d u l e i n s t a n c e w h o s e e x e c u t a b l e file c o n tains t h e m e n u
MenuName
S t r i n g ( n u l l - t e r m i n a t e d ) o r i n t e g e r ID n a m e o f menu
Return
Value:
M e n u i d e n t i f i e r if s u c c e s s f u l ; e l s e 0.
LoadResource function LoadResource(Instance, Allocates m e m o r y for a n d loads a Parameters
Reslnfo: THandle): THandle;
resource.
Description
Instance
M o d u l e i n s t a n c e w h o s e e x e c u t a b l e file c o n tains t h e resource
Reslnfo
R e s o u r c e i d e n t i f i e r (returned FindResource)
by
Return Value: R e s o u r c e i d e n t i f i e r if s u c c e s s f u l ; e l s e 0.
LoadString function LoadString(Instance: THandle; ID: Word; Buffer: PChar; BufferMax: Integer): Integer; L o a d s a s t r i n g resource Parameters
a n d c o p i e s it i n t o Buffer a p p e n d i n g a n u l l - c h a r a c t e r . Description
Instance
M o d u l e i n s t a n c e w h o s e e x e c u t a b l e file c o n tains t h e string
ID
Integer ID o f string
Buffer
Receiving buffer
BufferMax
Size o f Buffer
Return Value: N u m b e r o f b y t e s c o p i e d ; 0 if t h e s t r i n g d o e s n o t exist.
M — S y s t e m Services Interface P r o c e d u r e s a n d F u n c t i o n s
LockResource function LockResource(ResData: THandle): Pointer; G e t s t h e a d d r e s s o f a l o a d e d r e s o u r c e a n d i n c r e m e n t s its r e f e r e n c e - c o u n t . T h e resource can n o longer b e moved or discarded. Parameters ResData
Description Resource identifier returned f r o m LoadResource
Return Value: Pointer t o l o a d e d resource; else nil.
SetResourceHandler function SetResourceHandler(Instance: THandle; ResType: Pointer; LoadFunc: TFarProc): TFarProc; Sets u p a c a l l b a c k , w h i c h is c a l l e d b y W i n d o w s w h e n a r e s o u r c e is b e i n g l o c k e d (that i s , LockResource). T h e c a l l b a c k is p a s s e d a Mem t o t h e s t o r e d r e s o u r c e , Instance, a n d Reslnfo ( f r o m FindResource). Parameters Instance
ResType
Description M o d u l e i n s t a n c e w h o s e e x e c u t a b l e file c o n tains t h e resource Pointer t o short integer specifying a resource type
LoadFunc
Callback f u n c t i o n ' s p r o c e d u r e - i n s t a n c e address
Return Value: Pointer to callback function.
SizeofResource function SizeofResource(Instance, G e t s t h e size o f a r e s o u r c e .
Reslnfo: THandle): Word;
767
768
Part I I I — R e f e r e n c e s
Parameters
Description
Instance
M o d u l e i n s t a n c e w h o s e e x e c u t a b l e file c o n tains t h e resource.
Reslnfo
S e l e c t e d r e s o u r c e , r e t u r n e d b y FindResource.
Return
Value:
S i z e (in b y t e s ) o f r e s o u r c e ; 0 if t h e r e s o u r c e isn't f o u n d .
UnlockResource function UnlockResource(RezData: THandle): Bool; U n l o c k s t h e RezData r e s o u r c e a n d d e c r e m e n t s its r e f e r e n c e c o u n t e r . Parameters RezData Return
Description G l o b a l m e m o r y b l o c k Identifier.
Value:
Z e r o if t h e r e f e r e n c e c o u n t e r is 0 ; e l s e n o n z e r o .
Segment Procedures and Functions AllocDStoCSAlias AllocSelector ChangeSelector DefineHandleTable FreeSelector GetCodelnfo GlobalFix GlobalPageLock GlobalPageUnlock GlobalUnfix LockSegment UnlockSegment
AllocDStoCSAlias function AllocDStoCSAlias(Selector: Word): Word; M a p s Selector t o a c o d e - s e g m e n t s e l e c t o r .
M — S y s t e m Services Interface P r o c e d u r e s a n d F u n c t i o n s
Parameters Selector
769
Description Data-segment selector
Return Value: C o r r e s p o n d i n g c o d e - s e g m e n t s e l e c t o r if s u c c e s s f u l ; e l s e 0.
AllocSelector function AllocSelector(Selector: Word): Word; A l l o c a t e s a n e w s e l e c t o r , w h i c h is a n e x a c t c o p y o f Selector. If Selector is n i l , AllocSelector allocates a n e w , u n i n i t i a l i z e d s e l e c t o r . AllocSelector a n d r e l a t e d f u n c t i o n s a r e n o t a f t e n u s e d ; a v o i d u s i n g t h e s e f u n c t i o n s , if possible. Parameters Selector
Description Selector to b e copied
Return Value: A s e l e c t o r if s u c c e s s f u l ; e l s e 0.
ChangeSelector function ChangeSelector(DestSelector,
SourceSelector: Word): Word;
C h a n g e s t h e attributes o f a s e l e c t o r f r o m c o d e t o d a t a o r v i c e versa. T h e v a l u e o f t h e s e l e c t o r is n o t a f f e c t e d . U s u a l l y , y o u s h o u l d c h a n g e t h e s e l e c t o r o n l y if a b s o l u t e l y n e c e s s a r y . T h e converted selector s h o u l d b e u s e d immediately, because there's n o way to k e e p the source a n d destination selectors synchronized. Parameters
Description
DestSelector
T h e s e l e c t o r that r e c e i v e s t h e c o n v e r t e d s e l e c t o r m u s t h a v e b e e n p r e v i o u s l y allocated w i t h AllocSelector
SourceSelector
T h e selector to b e converted
Return Value: C o n v e r t e d selector; else 0 (indicating failure).
770
Part I I I — R e f e r e n c e s
DefineHandleTable function DefineHandleTable(Offset: Word): Bool; C r e a t e s a private h a n d l e t a b l e i n t h e d e f a u l t d a t a s e g m e n t . T h e t a b l e h o l d s t h e a d d r e s s e s o f l o c k e d g l o b a l m e m o r y o b j e c t s , as r e t u r n e d b y GlobalLock. If t h e m e m o r y objects are m o v e d , W i n d o w s updates these addresses w h e n r u n n i n g i n r e a l m o d e . A d d r e s s e s a r e n ' t u p d a t e d i n p r o t e c t e d m o d e s ( S t a n d a r d a n d 386 Enhanced). T h e h a n d l e t a b l e c o n s i s t s o f t w o Word-type v a l u e s f o l l o w e d b y a n array o f addresses. • T h e first w o r d is t h e n u m b e r o f e n t r i e s i n t h e t a b l e , w h i c h m u s t b e initialized b e f o r e t h e call t o DefineHandleTable. • T h e s e c o n d is t h e n u m b e r o f e n t r i e s t o set t o z e r o w h e n W i n d o w s u p d a t e s its list o f least r e c e n t l y u s e d m e m o r y . E i t h e r w o r d c a n b e c h a n g e d at a n y t i m e . T h e a d d r e s s e s i n t h e rest o f t h e t a b l e a r e r e t u r n e d b y GlobalLock. Parameters Offset
Description T h e offset o f t h e t a b l e f r o m t h e b e g i n n i n g o f t h e d a t a s e g m e n t . A v a l u e o f 0 i n d i c a t e s that W i n d o w s s h o u l d n o l o n g e r u p d a t e the table
Return Value.s N o n z e r o if s u c c e s s f u l ; 0 if s u c c e s s f u l .
FreeSelector function FreeSelector(Selector: Word): Word; Frees and invalidates AllocDStoCSAlias. Parameters Selector
a selector
allocated
Description T h e s e l e c t o r t o free
Return Value: Z e r o if s u c c e s s f u l ; e l s e Selector.
by AllocSelector
or
M — S y s t e m Services Interface P r o c e d u r e s a n d F u n c t i o n s
GetCodelnfo procedure GetCodeInfo(Proc: TFarProc; Seglnfo Pointer); G e t s i n f o r m a t i o n a b o u t t h e c o d e s e g m e n t that c o n t a i n s Proc. Parameters
Description
Proc
Function address or m o d u l e handle a n d segment number.
Seglnfo
A n y array o f f o u r 32-bit v a l u e s .
GlobalFix procedure GlobalFix(Mem: THandle); F i x e s a g l o b a l m e m o r y b l o c k i n m e m o r y a n d i n c r e a s e s its l o c k r e f e r e n c e c o u n t by o n e . Parameters Mem
Description G l o b a l m e m o r y b l o c k identifier
GlobalPageLock function GlobalPageLock(Selector: THandle): Word; I n c r e m e n t s a m e m o r y b l o c k ' s page-lock c o u n t . Parameters
Description
Selector
M e m o r y selector
Return Value: I n c r e m e n t e d p a g e - l o c k c o u n t if s u c c e s s f u l ; e l s e 0.
GlobalPageUnlock function GlobalPageUnlock(Selector: THandle): Word; D e c r e m e n t s a m e m o r y b l o c k ' s p a g e - l o c k c o u n t . If c o u n t r e a c h e s 0, t h e p a g e c a n b e m o v e d o r s w a p p e d t o disk.
771
772
Part I I I — R e f e r e n c e s
Parameters
Description
Selector
M e m o r y selector
Return Value: D e c r e m e n t e d p a g e - l o c k c o u n t if s u c c e s s f u l ; e l s e 0.
GlobalUnfix function GlobalUnfix(Mem: THandle): Bool; U n l o c k s a g l o b a l m e m o r y b l o c k l o c k e d b y GlobalFix. If t h e b l o c k ' s l o c k r e f e r e n c e - c o u n t r e a c h e s 0, t h e b l o c k c a n b e m o v e d o r d i s c a r d e d . Parameters Mem
Description G l o b a l m e m o r y b l o c k identifier
Return Value: Z e r o if l o c k r e f e r e n c e - c o u n t d e c r e m e n t s t o 0; e l s e n o n z e r o .
LockSegment function LockSegment(Segment: Word): THandle; Locks a segment (except protected-mode, non-discardable segments) a n d i n c r e m e n t s its l o c k r e f e r e n c e - c o u n t . Parameters Segment
Description Segment address or - 1 for current segment
Return Value: P o i n t e r t o Segment; n i l if e r r o r o r if s e g m e n t is d i s c a r d e d .
UnlockSegment function UnlockSegment(Segment: Word): THandle; U n l o c k s a s e g m e n t s p e c i f i e d b y Segment. Parameters Segment
Return
Description Segment address, or - 1 to u n l o c k current data segment
Value:
Z e r o if r e f e r e n c e c o u n t w a s d e c r e m e n t e d t o 0; e l s e n o n z e r o .
M — S y s t e m Services Interface P r o c e d u r e s a n d F u n c t i o n s
Sound Procedures and Functions CloseSound CountVoiceNotes GetThresholdEvent GetThresholdStatus OpenSound SetSoundNoise SetVoiceAccent SetVoiceEnvelope SetVoiceNote SetVoiceQueueSize SetVoiceSound SetVoiceThreshold StartSound StopSound SyncAllVoices WaitSoundState
CloseSound procedure CloseSound; F l u s h e s all v o i c e q u e u e s , frees a n y a l l o c a t e d b u f f e r s , a n d c l o s e s t h e p l a y d e v i c e .
CountVoiceNotes function CountVoiceNotes(Voice: Integer): Integer; C o u n t s t h e n u m b e r of n o t e s i n Voice. Parameters Voice Return
Description Voice queue
Value:
N u m b e r of notes.
GetThresholdEvent function GetThresholdEvent: LPInteger; Gets a recent threshold event.
773
774
Part I I I — R e f e r e n c e s
Return Value: Pointer t o threshold event.
GetThresholdStatiis function GetThresholdStatus: Integer; G e t s a threshold e v e n t status where e a c h set bit represents that is currently b e l o w t h r e s h o l d . Return Value: C u r r e n t t h r e s h o l d e v e n t status
a voice-queue level
flags.
OpenSound function OpenSound: Integer; O p e n s the p l a y device for e x c l u s i v e u s e b y t h e application. Return
Value:
N u m b e r of available s_Sound voices; insufficient m e m o r y .
s_SerDVNA if in u s e ;
s_SerOFM if
SetSoundNoise function SetSoundNoise(Source, Duration: Integer): Integer; S e t s a n o i s e source a n d duration v a l u e s for t h e p l a y device. Parameters
Description
Source
A n y o n e of t h e SetSoundNoise c o n s t a n t s
Duration
N o i s e d u r a t i o n (in clock ticks)
Return Value: Zero if s u c c e s s f u l ; s_SerDSR if an invalid Source.
SetVoiceAccent function SetVoiceAccent(Voice, Tempo, Volume, Mode, Pitch: Integer): Integer; R e p l a c e s the e n v e l o p e in a v o i c e q u e u e .
M — S y s t e m Services Interface P r o c e d u r e s a n d F u n c t i o n s
Parameters
Description
Voice
A v o i c e q u e u e (starting f r o m o n e )
Tempo
Q u a r t e r n o t e s p l a y e d p e r m i n u t e (default, 120)
Volume
V o l u m e l e v e l (0 t o 2 5 5 )
Mode
O n e o f the S e t V o i c e A c c e n t s o u n d constants
Pitch
P i t c h o f p l a y e d n o t e s (0 t o 8 3 )
Return
775
Value:
Z e r o if s u c c e s s f u l ; e l s e o n e o f t h e s e n e g a t i v e c o n s t a n t s : s_SerDMD s_SerDTP s_SerDVL s_SerQFUL
SetVoiceEnvelope function SetVoiceEnvelope(Voice, Shape, RepeatCount: Integer): Integer; Places a voice e n v e l o p e in the voice q u e u e a n d replaces t h e existing voice envelope. Parameters
Description
Voice
A voice queue
Shape
O E M wave-shape table i n d e x
RepeatCount
N u m b e r o f repetitions o f wave-shape p e r note
Return Value: Z e r o if s u c c e s s f u l ; e l s e o n e o f t h e s e n e g a t i v e c o n s t a n t s : s_SerQFUL s_SerDSH
SetVoiceNote function SetVoiceNote(Voice, Value, Length, Cdots: Integer): Integer; Places a n o t e o n a voice q u e u e with the specified qualities.
776
Part I I I — R e f e r e n c e s
Parameters
Description
Voice
A voice queue
Value
A n o t e ( o n e o f 8 4 ) o r 0 f o r rest
Length
Reciprocal o f note duration
Cdots
N o t e d u r a t i o n i n d o t s : (Length *(Cdots
Return
*3/2))
Value:
Z e r o if s u c c e s s f u l ; e l s e o n e o f t h e s e n e g a t i v e c o n s t a n t s : s_SerDCC s_SerDLN s_SerBDNT s_SerQFUL
SetVoiceQueueSize function SetVoiceQueueSize(Voice,
Bytes: Integer): Integer;
S e t s t h e size o f n o n - p l a y i n g v o i c e q u e u e . T h e d e f a u l t is 192 b y t e s o r a p p r o x i mately 32 notes. Parameters
Description
Voice
A voice queue
Bytes
S i z e (in b y t e s ) o f v o i c e q u e u e
Return
Value:
Z e r o if s u c c e s s f u l ; e l s e o n e o f t h e f o l l o w i n g n e g a t i v e c o n s t a n t s : s_SerMACT s_SerOFM
SetVoiceSound function SetVoiceSound(Voice: Longint; Frequency: Longint; Duration: Integer): Integer; Places the s o u n d frequency a n d duration o n a voice q u e u e . Parameters
Description
Voice
A voice queue
Frequency
Hertz a n d fractional frequency in high- a n d low-order words
Duration
S o u n d d u r a t i o n ( i n c l o c k ticks)
M — S y s t e m Services Interface P r o c e d u r e s a n d F u n c t i o n s
Return
Value:
Z e r o if s u c c e s s f u l ; e l s e o n e o f t h e f o l l o w i n g n e g a t i v e c o n s t a n t s : s_SerDDR s_SerDFQ s_SerDVL s_SerQFUL
SetVoiceThreshold function SetVoiceThreshold(Voice,
Notes: Integer): Integer;
S e t s t h e t h r e s h o l d l e v e l f o r a v o i c e q u e u e . If t h e n u m b e r o f n o t e s i n q u e u e d r o p b e l o w t h e t h r e s h o l d , t h e t h r e s h o l d flag is set. Parameters
Description
Voice
A voice q u e u e
Notes
N u m b e r o f notes specifying the threshold level
Return
Value:
Z e r o if s u c c e s s f u l ; 1 if N o t e is o u t o f r a n g e .
StartSound function StartSound: Integer; Non-destructively plays the voice q u e u e . Return Value: Not used.
StopSound function StopSound: Integer; S t o p s p l a y i n g all v o i c e q u e u e s , f l u s h e s q u e u e c o n t e n t s , a n d t u r n s o f f v o i c e s o u n d drivers. Return Value: Not used.
777
778
Part I I I — R e f e r e n c e s
SyncAllVoices function SyncAllVoices: Integer; P l a c e s a s y n c m a r k i n all v o i c e q u e u e s . Return
Value:
Z e r o if s u c c e s s f u l ; s_SerQFUL if t h e v o i c e q u e u e is f u l l .
WaitSoundState function WaitSoundState(State: Integer): Integer; W a i t s f o r t h e p l a y driver t o e n t e r t h e state s p e c i f i e d by State. Parameters State Return
Description O n e o f t h e WaitSoundState c o n s t a n t s
Value:
Z e r o if s u c c e s s f u l ; s S e r D S T if a n i n v a l i d State.
String-Manipulation Procedures and Functions AnsiLower AnsiLowerBuff AnsiNext AnsiPrev AnsiToOem AnsiToOemBuff AnsiUpper AnsiUpperBuff IsCharAlpha IsCharAlphaNumeric IsCharLower IsCharUpper lstrcat lstrcmp lstrcmpi lstrcpy lstrlen
M — S y s t e m Services Interface P r o c e d u r e s a n d F u n c t i o n s
OemToAnsi OemToAnsiBuff ToAscii wvsprintf
AnsiLower function AnsiLower(Str: PChar): PChar; U s e s t h e l a n g u a g e d r i v e r t o c o n v e r t Str t o l o w e r c a s e . Parameters Str
Description N u l l - t e r m i n a t e d string o r a s i n g l e c h a r a c t e r ( i n low-order byte)
Return Value: C o n v e r t e d string o r c h a r a c t e r .
AnsiLowerBuff function AnsiLowerBuff(Str: PChar; Length: Word): Word; U s e s t h e l a n g u a g e driver t o c o n v e r t Str t o l o w e r c a s e . Parameters
Description
Str
Buffer o f characters
Length
N u m b e r o f c h a r a c t e r s i n b u f f e r ; if 0 , l e n g t h is 6 4 K (65,536)
Return Value: L e n g t h o f t h e c o n v e r t e d string.
AnsiNext function AnsiNext(CurrentChar:
PChar): PChar;
Iterates t h r o u g h strings w h o s e c h a r a c t e r s a r e t w o o r m o r e b y t e s l o n g . Parameters CurrentChar
Description N u l l - t e r m i n a t e d string
Return Value: P o i n t e r t o n e x t c h a r a c t e r i n string.
779
780
Part I I I — R e f e r e n c e s
AnsiPrev function AnsiPrev(Start, CurrentChar: PChar): PChar; Iterates b a c k w a r d t h r o u g h strings w h o s e c h a r a c t e r s a r e t w o o r m o r e b y t e s l o n g . Parameters
Description
Start
B e g i n n i n g o f string ( n u l l - t e r m i n a t e d )
CurrentChar
P o i n t s t o a c h a r a c t e r i n t h e string
Return Value: P o i n t e r t o p r e v i o u s c h a r a c t e r i n t h e string.
AnsiToOem function AnsiToOem(AnsiStr, OemStr: PChar): Integer; T r a n s l a t e s AnsiStr t o O E M - d e f i n e d c h a r a c t e r set. L e n g t h c a n b e g r e a t e r t h a n 64K. Parameters
Description
AnsiStr
String (null-terminated) o f A N S I characters
OemStr
L o c a t i o n w h e r e t r a n s l a t e d string is t o b e c o p i e d , c a n b e s a m e as AnsiStr
Return Value: Always - 1 .
AnsiToOemBuff procedure AnsiToOemBuff(AnsiStr, OemStr: PChar; Length: Integer); T r a n s l a t e s AnsiStr t o O E M - d e f i n e d c h a r a c t e r set. Parameters
Description
AnsiStr
Buffer o f A N S I characters
OemStr
L o c a t i o n w h e r e t r a n s l a t e d string is t o b e c o p i e d , c a n b e s a m e as AnsiStr
Length
S i z e o f AnsiStr, if 0 , t h e l e n g t h is 6 4 K
M — S y s t e m Services Interface P r o c e d u r e s a n d F u n c t i o n s
AnsiUpper function AnsiUpper(Str: PChar): PChar; U s e s t h e l a n g u a g e driver t o c o n v e r t Str t o u p p e r c a s e . Parameters Str
Description String (null-terminated) o r a single character (in l o w - o r d e r b y t e )
Return Value: C o n v e r t e d string o r c h a r a c t e r .
AnsiUpperBuff function AnsiUpperBuff(Str: PChar; Length: Word): Word; U s e s t h e l a n g u a g e d r i v e r t o c o n v e r t Str t o u p p e r c a s e . Parameters
Description
Str
Buffer o f characters
Length
S i z e o f S t r ; if 0 , l e n g t h is 6 4 K
Return
Value:
L e n g t h o f t h e c o n v e r t e d string.
IsCharAlpha function IsCharAlpha(AChar: Char): Bool; U s e s t h e l a n g u a g e driver a n d t h e c u r r e n t l a n g u a g e t o d e t e r m i n e if AChar is alphabetical. Parameters AChar
Description Test character
Return Value: N o n z e r o if a l p h a b e t i c a l ; e l s e 0.
781
782
Part I I I — R e f e r e n c e s
IsCharAlphaNumeric function IsCharAlphaNumeric(AChar: Char): Bool; U s e s t h e l a n g u a g e d r i v e r a n d t h e c u r r e n t l a n g u a g e t o d e t e r m i n e if AChar is alphanumeric. Parameters AChar
Description Test character
Return Value: N o n z e r o if a l p h a n u m e r i c ; e l s e 0.
IsCharLower function IsCharLower(AChar: Char): Bool; U s e s t h e l a n g u a g e driver a n d t h e c u r r e n t l a n g u a g e t o d e t e r m i n e if AChar is lowercase. Parameters AChar
Description Test character
Return Value: N o n z e r o if l o w e r c a s e ; e l s e 0.
IsCharUpper function IsCharUpper(AChar: Char): Bool; U s e s t h e l a n g u a g e driver a n d t h e c u r r e n t l a n g u a g e t o d e t e r m i n e if AChar is uppercase. Parameters AChar Return
Description Test character
Value:
N o n z e r o if u p p e r c a s e ; e l s e 0.
lstrcat function lstrcat(Str1, Str2: PChar): PChar; C o n c a t e n a t e s Str2 t o Str1.
M — S y s t e m Services Interface P r o c e d u r e s a n d F u n c t i o n s
Parameters
Description
Strl
First string ( n u l l - t e r m i n a t e d )
Str2
S e c o n d string ( n u l l - t e r m i n a t e d )
Return Value: Str1 if s u c c e s s f u l ; e l s e 0.
lstrcmp function lstrcmp(Str1, Str2: PChar): Integer; D o e s c a s e - s e n s i t i v e , l e x i c o g r a p h i c a l c o m p a r i s o n o f t w o strings b a s e d o n t h e currently selected language. U p p e r c a s e characters evaluate lower than lowercase characters. Parameters
Description
Strl
First string ( n u l l - t e r m i n a t e d )
Str2
S e c o n d string ( n u l l - t e r m i n a t e d )
Return
Value:
Less t h a n 0 if Str 1 < Str2; 0 if Str 1 = Str2; G r e a t e r t h a n 0 if Str 1 > Str2.
lstrcmpi function lstrcmpi(Str1, Str2: PChar): Integer; D o e s c a s e - i n s e n s i t i v e , l e x i c o g r a p h i c a l c o m p a r i s o n of t w o strings b a s e d o n t h e currently selected language. Parameters
Description
Strl
First string ( n u l l - t e r m i n a t e d )
Str2
S e c o n d string ( n u l l - t e r m i n a t e d )
Return Value: Less t h a n 0 if Strl < Str2; 0 if Strl = Str2; G r e a t e r t h a n 0 if Strl > Str2.
lstrcpy function lstrcpy(Strl, Str2: PChar): PChar; C o p i e s Str2 t o Str 1 (including n u l l ) .
783
784
Part III—References
Parameters
Description
Strl
First string (null-terminated)
Str2
Second string (null-terminated)
Return
Value:
Pointer to Str 1 if successful; else 0.
lstrien function lstrlen(Str: PChar): Integer; Calculates length (not including null) of Str. Parameters
Str Return
Description
String (null-terminated) Value:
Length (in bytes) of Str.
OemToAnsi function OemToAnsi(OemStr, AnsiStr: PChar): Bool; Translates OemStr to ANSI character set. Parameters
Description
OemStr
String of O E M characters (null-terminated)
AnsiStr
Receive buffer or OemStr to translate in place
Return
Value:
Always - 1 (False).
OemToAnsiBuff procedure OemToAnsiBuff(OemStr, AnsiStr: PChar; Length: Integer) Translates OemSt r to ANSI character set.
M — S y s t e m Services Interface P r o c e d u r e s a n d F u n c t i o n s
Parameters
Description
OemStr
Buffer o f O E M characters
AnsiStr
R e c e i v e b u f f e r o r OemStr t o translate i n p l a c e
Length
Size o f O e m S t r
ToAscii function ToAscii(VirtKey, ScanCode: Word; KeyState: PChar; CharBuff: Pointer; Flags: Word): Integer; T r a n s l a t e s VirtKey a n d t h e c u r r e n t k e y b o a r d state i n t o c o r r e s p o n d i n g A N S I characters. Parameters
Description
VirtKey
Virtual-key c o d e
ScanCode
R a w k e y s c a n c o d e , h i g h bit set if k e y u p
KeyState
Array o f 256 B y t e s c o n t a i n i n g t h e state o f e a c h k e y , h i g h bit set if k e y u p
CharBuff
P o i n t e r t o a 32-bit r e c e i v i n g b u f f e r
Flags
Not used
Return
Value:
(2) a c c e n t a n d d e a d k e y c o p i e d t o CharBuff, (1) o n e A N S I c h a r a c t e r c o p i e d t o CharBuff, (0) t r a n s l a t i o n is n o t p o s s i b l e w i t h c u r r e n t k e y b o a r d state.
wvsprintf function wvsprintf(Output, Format, ArgList: PChar): Integer; F o r m a t s a n d s t o r e s a series o f c h a r a c t e r s i n a b u f f e r . Parameters
Description
Output
Buffer t o receive formatted characters
Format
F o r m a t c o n t r o l string
ArgList
A n array o f a r g u m e n t s t o t h e f o r m a t c o n t r o l string
785
786
Part I I I — R e f e r e n c e s
Return Value: If s u c c e s s f u l , t h e n u m b e r of characters in Output, ( n o t c o u n t i n g 0). If n o t s u c c e s s f u l , t h e n u m b e r of characters returned is less t h a n t h e l e n g t h of Format.
Task Procedures and Functions Catch ExitWindows GetCurrentPDB GetCurrentTask GetDOSEnvironment GetNumTasks SetErrorMode Throw Yield
Catch function Catch(var CatchBuf: TCatchBuf): Integer; C o p i e s t h e state of all s y s t e m s registers CatchBuf. Parameters CatchBuf
a n d t h e instruction
pointer
into
Description TCatchBuf to copy e x e c u t i o n e n v i r o n m e n t state
Return Value: Z e r o if t h e e n v i r o n m e n t is c o p i e d .
ExitWindows function ExitWindows(Reserved: DWord; ReturnCode: Word): Bool; Initiates s t a n d a r d Windows s h u t d o w n p r o c e d u r e . A l l a p p l i c a t i o n s m u s t a g r e e to t e r m i n a t e for Windows to exit. C a l l s D O S Integer 21H function 4CH. Parameters
Description
Reserved
Set to 0
ReturnCode
V a l u e p a s s e d t o D O S (AL)
M — S y s t e m Services Interface P r o c e d u r e s a n d F u n c t i o n s
Return
Value:
Z e r o if o n e o r m o r e a p p l i c a t i o n s r e f u s e t o t e r m i n a t e .
GetCurrentPDB function GetCurrentPDB: Word; G e t s t h e current D O S Program D a t a Base ( P D B — a n d also k n o w n as t h e Program S e g m e n t Prefix). Return Value: Current P D B paragraph address o r selector.
GetCurrentTask function GetCurrentTask
.-THandle;
G e t s t h e h a n d l e o f t h e c u r r e n t l y e x e c u t i n g task. Return Value: T a s k i d e n t i f i e r if s u c c e s s f u l ; e l s e 0.
GetDOSEnvironment function GetDOSEnvironment: PChar; G e t s t h e c u r r e n t task's D O S e n v i r o n m e n t string. Return Value: T a s k ' s e n v i r o n m e n t string.
GetNumTasks function GetNumTasks: Word; G e t s t h e n u m b e r o f tasks that a r e c u r r e n t l y e x e c u t i n g i n t h e s y s t e m . Return Value: N u m b e r o f c u r r e n t l y e x e c u t i n g tasks.
787
788
Part I I I — R e f e r e n c e s
SetErrorMode function SetErrorMode(Mode: Word): Bool; S p e c i f i e s w h e t h e r W i n d o w s d i s p l a y s a n e r r o r b o x o n D O S I NT 24H e r r o r s . If n o t , W i n d o w s fails t h e o r i g i n a l INT 21H c a l l , a l l o w i n g t h e a p p l i c a t i o n t o h a n d l e t h e error. Parameters
Description
Mode
(0) W i n d o w s d i s p l a y s e r r o r b o x , (1) W i n d o w s fails t o t h e a p p l i c a t i o n
Return Value: N o n z e r o if set; e l s e 0.
Throw procedure Throw(var
CatchBuf:
TCatchBuf;
ThrowBack:
Integer);
R e s t o r e s a n a p p l i c a t i o n ' s e x e c u t i o n e n v i r o n m e n t . E x e c u t i o n c o n t i n u e s at t h e C a t c h f u n c t i o n that o r i g i n a l l y s a v e d t h e e n v i r o n m e n t t o C a t c h B u f . Parameters CatchBuf
Description T C a t c h B u f containing the execution environment
ThrowBack
Value returned to C a t c h function
Yield function Yield: Bool; H a l t s t h e c u r r e n t task a n d starts a w a i t i n g task. Return Value: Not used.
Utility Macros and Functions GetNearestPaletteIndex HiByte HiWord
M — S y s t e m Services Interface P r o c e d u r e s a n d F u n c t i o n s
LoByte LoWord MakelntAtom MakelntResource MakeLong MakePoint MulDiv PaletteRGB RGB
GetNearestPalettelndex function Color:
GetNearestPalettelndex(Palette: T C o l o r R e f ) : Word;
HPalette;
G e t s the closest matching color in a logical-palette to C o l o r . Parameters
Description
Palette
Logical palette identifier
Color
T C o l o r R e f to be matched
Return Value: Logical-palette entry index.
HiByte function
HiByte(A:
inline( $5A/ $8A/$C4/ $32/$E4);
Word):
Byte;
{ POP AX { MOV A L , A H
} }
{ XOR A H , A H
}
Extracts t h e h i g h - o r d e r b y t e f r o m a 16-bit i n t e g e r v a l u e . Parameters A Return Value: T h e high-order byte.
Description T h e 16-bit i n t e g e r
789
790
Part I I I — R e f e r e n c e s
HiWord function HiWord(Anlnteger: Longint): Word; E x t r a c t s t h e h i g h - o r d e r w o r d f r o m a 32-bit i n t e g e r v a l u e . Parameters
Description
Anlnteger
T h e 32-bit i n t e g e r
Return Value: T h e high-order word.
LoByte function LoByte(A: Word): Byte; inline( $5A/ $32/$E4);
{ POP AX } { XOR AH,AH }
E x t r a c t s t h e l o w - o r d e r b y t e f r o m a 16-bit i n t e g e r v a l u e . Parameters A
Description T h e 16-bit i n t e g e r
Return Value: T h e low-order byte.
LoWord function LoWord(Anlnteger: Longint): Word; E x t r a c t s t h e l o w - o r d e r w o r d f r o m a 32-bit i n t e g e r v a l u e . Parameters Anlnteger Return Value: The low-order word.
Description T h e 32-bit i n t e g e r
M — S y s t e m Services Interface Procedures and Functions
791
MakelntAtom (type) MakelntAtom = PStr; Use MakelntAtom for typecasting integer numbers into atoms. It's equivalent to typecasting into the Turbo Pascal type PChar.
MakelntResource (type) MakelntResource = PStr; Use MakelntResource for typecasting integer numbers into resource names. It's equivalent to typecasting into the Turbo Pascal type PChar.
MakeLong function MakeLong(Low, High: Word): Longint; Concatenates two w o r d values into one unsigned long value. Parameters
Description
Low
The low-order w o r d of the n e w unsigned long
High
The high-order w o r d of the n e w unsigned long
Return
Value:
The resulting unsigned Longint.
MakePoint (type) MakePoint = TPoint; Use MakePoint for typecasting long integer numbers into TPoint records.
MulDiv function MulDiv(Number, Numerator, Denominator: Integer): Integer; Multiplies Numerator by Number and divides the result by Denominator, rounding to the nearest integer.
792
Part I I I — R e f e r e n c e s
Parameters
Description
Number
A number
Numerator
Another number
Denominator
Another number
Return Value: R e s u l t v a l u e ; 3 2 , 7 6 7 , o r - 3 2 , 7 6 7 if o v e r f l o w o r if D e n o m i n a t o r is 0.
PaletteRGB function PaletteRGB(Red, Green, Blue: Byte): Longint; P r o d u c e s a palette-relative R G B c o l o r v a l u e from t h r e e p r i m a r y c o l o r v a l u e s ranging
f r o m 0 t o 2 5 5 . T h e return v a l u e h a s t w o i n t h e h i g h - o r d e r b y t e .
Parameters
Description
Red
T h e red i n t e n s i t y v a l u e
Green
T h e g r e e n intensity value
Blue
T h e b l u e intensity value
Return Value: T h e resulting R G B c o l o r .
RGB function RGB(Red, Green, Blue: Byte): Longint; P r o d u c e s a n R G B c o l o r v a l u e f r o m t h r e e p r i m a r y c o l o r v a l u e s ranging to 255. Parameters
Description
Red
T h e red i n t e n s i t y v a l u e
Green
T h e g r e e n intensity value
Blue
T h e b l u e intensity value
Return Value: T h e resulting R G B c o l o r .
from 0
N
REFERENCE
GDI (GRAPHICS DEVICE INTERFACE) PROCEDURES AND FUNCTIONS T h e G r a p h i c s Device Interface ( G D I ) built into W i n d o w s gives W i n d o w s a p p l i c a t i o n s a full r a n g e o f f u n c t i o n s for d i s p l a y i n g a n d m a n i p u l a t i n g g r a p h i c s . T h e G D I u s e s d e v i c e drivers t o translate f u n c t i o n calls i n t o c o m m a n d s that can be u s e d by o u t p u t devices. In particular, G D I functions give y o u r applicat i o n d r a w i n g c a p a b i l i t i e s that are i n d e p e n d e n t o f t h e d i s p l a y d e v i c e u s e d :
Bitmap Clipping Color palette Coordinate translation Device context Device-independent bitmap Drawing-attribute Drawing-tool Environment Escape
Font Line-drawing Mapping Metafile Printer-control Rectangle Region Shape-drawing Text-drawing
794
Part I I I — R e f e r e n c e s
Bitmap Procedures and Functions A b i t m a p is t h e s u r f a c e o f a d i s p l a y c o n t e x t . B e c a u s e a b i t m a p r e p r e s e n t s t h e m e m o r y c o n f i g u r a t i o n o f a d e v i c e , it is d e p e n d e n t o n t h e d e v i c e b e i n g addressed. G D I supplies techniques for addressing the device-dependence problem, including device-independent bitmaps: BitBlt CreateBitmap CreateBitmapIndirect CreateCompatibleBitmap CreateDiscardableBitmap ExtFloodFill FloodFill GetBitmapBits GetBitmapDimension GetPixel LoadBitmap PatBlt SetBitmapBits SetBitmapDimension SetPixel StretchBlt
BitBlt C o p i e s a b i t m a p f r o m SrcDC t o DestDC, a n d h a n d l e s t h e s p e c i f i e d raster operation. function BitBlt(DestDC: HDC; X, Y, Width, Height: Integer; SrcDC: HDC; XSrc, YSrc: Integer; Rop: Longint): Bool; Parameter DestDC X, Y Width Height SSrcDC XSrc, YSrc
Description Device context to receive the bitmap Upper-left corner o f the destination rectangle Width o f the destination rectangle a n d source bitmap Height o f the destination rectangle a n d source bitmap D e v i c e c o n t e x t t o c o p y b i t m a p f r o m , o r 0 f o r raster o p e r a t i o n o n DestDC o n l y U p p e r - l e f t c o r n e r o f SrcDC
N — G D I Procedures and Functions
Parameter
Rop Return
795
Description
O n e of the Ternary raster operations' constants for copying from source to destination Value:
Nonzero if bitmap is drawn; else 0.
CreateBitmap Creates a device-dependent m e m o r y bitmap. function CreateBitmap(Width, Bits: Pointer): HBitmap; Parameter Width Height Planes BitCount Bits
Height: Integer; Planes,BitCount:
Byte;
Description Width (in p i x e l s ) o f t h e b i t m a p H e i g h t (in p i x e l s ) o f t h e b i t m a p N u m b e r of color planes in t h e bitmap N u m b e r o f c o l o r bits p e r d i s p l a y p i x e l S h o r t - i n t e g e r array c o n t a i n i n g initial b i t m a p v a l u e s ; if nil t h e n e w b i t m a p is left u n i n i t i a l i z e d
Return Value: B i t m a p i d e n t i f i e r if s u c c e s s f u l ; e l s e 0.
CreateBitmapIndirect C r e a t e s Bitmap.
function CreateBitmapIndirect(var Parameter
Bitmap
Bitmap: TBitmap):
HBitmap;
Description
TBitmap structure
Return Value: B i t m a p i d e n t i f i e r if s u c c e s s f u l ; e l s e 0
CreateCompatibleBitmap Creates a bitmap compatible with D C .
function CreateCompatibleBitmap(DC:
HDC; Width, Height: Integer):
HBitmap;
796
Part I I I — R e f e r e n c e s
Parameter DC Width Height Return
Description Device context B i t m a p w i d t h (in bits) B i t m a p height (in bits)
Value:
B i t m a p identifier
if s u c c e s s f u l ; e l s e 0.
CreateDiscardableBitmap C r e a t e s a d i s c a r d a b l e b i t m a p c o m p a t i b l e w i t h DC. function CreateDiscardableBitmap(DC: HDC; Width, Height: Integer): HBitmap; Parameter DC Width Height Return Value: B i t m a p identifier
Description Device context B i t m a p w i d t h (in bits) B i t m a p height (in bits)
if s u c c e s s f u l ; e l s e 0.
ExtFloodFill Fills a n area o f a raster d i s p l a y surface in t h e m a n n e r s p e c i f i e d b y FillType. U s e s t h e current b r u s h . function ExtFloodFill(DC: HDC; X, Y: Integer; Color: TColorRef; FillType: Word): Bool; Parameter DC X, Y Color FillType
Description D e v i c e c o n t e x t identifier Fill b e g i n p o i n t TColorRef o f b o u n d a r y o r area t o b e filled O n e o f t h e F l o o d fill style flags' c o n s t a n t s
Return Value: N o n z e r o if s u c c e s s f u l ; e l s e 0.
FloodFffl Fills t h e d i s p l a y area w i t h t h e current b r u s h b o u n d e d b y Color. function FloodFill(DC: HDC; X, Y: Integer; Color: TColorRef): Bool;
N — G D I Procedures a n d Functions
Parameter
Description
DC X, Y Color Return
Device context identifier P o s i t i o n t o b e g i n filling B o u n d a r y color, a TColorRef Value:
N o n z e r o if s u c c e s s f u l ; e l s e 0.
GetBitmapBits C o p i e s t h e bits o f a b i t m a p into Bits. function GetBitmapBits(Bitmap: HBitmap; Count: Longint; Bits: Pointer): Longint; Parameter Bitmap Count Bits
Description Bitmap identifier N u m b e r o f bytes t o c o p y B y t e array c o n f o r m i n g t o a structure in w h i c h horizontal
s c a n l i n e s are m u l t i p l e s o f 16 bits
Return Value: N u m b e r o f b y t e s in t h e b i t m a p ; 0 if error.
GetBitmapDimension G e t s t h e height
and width o f a bitmap.
function GetBitmapDimension(Bitmap: Parameter Bitmap Return
HBitmap): Longint;
Description Bitmap
identifier
Value:
H e i g h t (in t e n t h s o f m i l l i m e t e r s ) in high w o r d ; w i d t h (in t e n t h s o f m i l l i m e t e r s ) in l o w w o r d ; 0 if t h e d i m e n s i o n s haven't b e e n u s e d .
GetPixel G e t s t h e R G B c o l o r at t h e s p e c i f i e d p o i n t . function GetPixel(DC: HDC; X, Y; Integer): Longint;
797
798
Part I I I — R e f e r e n c e s
Parameter DC X, Y
Description D e v i c e context identifier Point to b e e x a m i n e d
Return Value: R G B c o l o r v a l u e ; - 1 if p o i n t is n o t i n c l i p p i n g r e g i o n .
LoadBitmap Loads the bitmap resource. function LoadBitmap(Instance: THandle; BitmapName: PChar): HBitmap; Parameter Instance BitmapName
Description M o d u l e i n s t a n c e w h o s e e x e c u t a b l e file c o n t a i n s t h e bitmap or 0 for predefined bitmap S t r i n g ( n u l l - t e r m i n a t e d ) o r i n t e g e r ID s p e c i f y i n g t h e bitmap, o r a predefined bitmap, specified by a n obm_ Predefined b i t m a p s c o n s t a n t
Return Value: B i t m a p i d e n t i f i e r if s u c c e s s f u l ; e l s e 0.
PatBlt C r e a t e s a bit p a t t e r n , u s i n g Rop, t h e s e l e c t e d b r u s h , a n d t h e p a t t e r n a l r e a d y o n the device. function PatBlt(DC: HDC; X, Y, Width, Height: Integer; Rop: Longint): Bool; Parameter DC X, Y Width Height Rop
Description Device context identifier Upper-left corner o f rectangle W i d t h (in logical units) o f rectangle H e i g h t (in l o g i c a l u n i t s ) o f r e c t a n g l e O n e o f t h e f o l l o w i n g Ternary raster o p e r a t i o n s : PatCopy Patlnvert DSTInvert Blackness Whiteness
Return Value: N o n z e r o if t h e bit p a t t e r n is d r a w n ; else 0.
N — G D I Procedures and Functions
799
SetBitmapBits S e t s t h e bits o f B i t m a p t o t h e bit v a l u e s i n B i t s . function SetBitmapBits(Bitmap: B i t s : Pointer): Longint; Parameter Bitmap Count Bits Return
HBitmap;
Count:
Longint;
Description H B i t m a p t o set S i z e (in bytes) o f B i t s B y t e array o f b i t m a p bits
Value:
N u m b e r o f b y t e s u s e d t o set b i t m a p b i t s ; 0 if e r r o r .
SetBitmapDimension Sets a bitmap's height a n d w i d t h in 0.1-millimeter units.
function SetBitmapDimension(ABitmap: HBitmap; X, Y: Integer): Longint; Parameter
Description
Bitmap X
B i t m a p identifier B i t m a p w i d t h (in 0 . 1 - m i l l i m e t e r u n i t s )
Y
B i t m a p h e i g h t (in 0 . 1 - m i l l i m e t e r u n i t s )
Return Value: Height of previous dimensions in high-order w o r d ; width of previous dimensions in low-order w o r d .
SetPixel Paints t h e p i x e l at t h e s p e c i f i e d p o i n t .
function SetPixel(DC: HDC; X, Y: Integer; Color: TColorRef): Longint; Parameter DC X, Y Color
Description Device context Logical coordinates of point T C o l o r R e f specifying the color to paint the point
Return Value: T C o l o r R e f u s e d t o p a i n t ; - 1 if t h e p o i n t is o u t s i d e t h e clipping
region.
800
Part I I I — R e f e r e n c e s
StretchBlt M o v e s a b i t m a p ( s t r e t c h i n g o r c o m p r e s s i n g it if r e q u i r e d ) f r o m a s o u r c e r e c t a n g l e t o a d e s t i n a t i o n r e c t a n g l e . T h e s o u r c e a n d d e s t i n a t i o n are c o m b i n e d as s p e c i f i e d b y R o p . function SrcDC:
StretchBlt(DestDC: HDC; X S r c ,
YSrc,
Parameter DestDC X, Y Width Height SrcDC XSrc, YSrc SrcWidth SrcHeight Rop Return
HDC; X ,
SrcWidth,
Y,
Width,
SrcHeight:
Height:
Integer;
Integer;
Rop:
Longint):
Bool;
Description Receiving device context Upper-left corner of destination rectangle D e s t i n a t i o n rectangle w i d t h (in l o g i c a l u n i t s ) D e s t i n a t i o n rectangle height (in l o g i c a l u n i t s ) Source bitmap device context Upper-left corner of source rectangle S o u r c e rectangle w i d t h (in l o g i c a l u n i t s ) S o u r c e rectangle height (in l o g i c a l u n i t s ) T e r n a r y raster o p e r a t i o n s t o b e p e r f o r m e d
Value:
N o n z e r o if b i t m a p is d r a w n ; e l s e 0.
Clipping Procedures and Functions Every display context has a clipping r e g i o n attribute to prevent drawing outside a n i n t e n d e d a r e a . T h e d e f a u l t c l i p p i n g r e g i o n (the w i n d o w ' s c l i e n t area) is g o o d e n o u g h f o r m o s t a p p l i c a t i o n s . A p p l i c a t i o n s that c r e a t e s p e c i a l v i s u a l effects might n e e d to change the clipping region.
ExcludeClipRect GetClipBox IntersectClipRect OffsetClipRgn PtVisible RectVisible SelectClipRgn
ExcludeClipRect C r e a t e s a n e w c l i p p i n g r e g i o n that c o n s i s t s o f t h e r e g i o n m i n u s t h e s p e c i f i e d rectangle.
function ExcludeClipRect(DC: HDC; X1, Y1, X2, Y2: Integer): Integer;
N — G D I Procedures a n d Functions
Parameter DC XI, Yl X2, Y2 Return
801
Description Device context Upper-left corner o f the rectangle Lower-right corner o f the rectangle
Value:
O n e o f t h e R e g i o n flags' c o n s t a n t s .
GetClipBox G e t s t h e tightest b o u n d i n g r e c t a n g l e a r o u n d t h e c u r r e n t c l i p p i n g b o u n d a r y , function GetClipBox(DC: HDC; v a r Rect: TRect): Integer; Parameter
Description
DC
Device context
Rect
Receiving T R e c t structure
Return
Value:
O n e of t h e Region flags' c o n s t a n t s .
IntersectCIipRect Creates a n e w clipping region from the intersection o f the region a n d the specified rectangle. function IntersectCIipRect(DC: HDC; X1, Y1, X2, Y2: Integer): Integer; Parameter
Description
DC
Device context
XI, Yl X2, Y2
Upper-left corner o f rectangle Lower-right corner o f rectangle
Return Value: O n e of t h e Region
flags.
OffsetClipRgn M o v e s t h e d e v i c e ' s c l i p p i n g r e g i o n a c c o r d i n g t o t h e s p e c i f i e d X a n d Y offsets, function OffsetClipRgn(DC: HDC; X , Y :
Integer): Integer;
802
Part I I I — R e f e r e n c e s
Parameter DC X Y
Description Device context L o g i c a l u n i t s t o m o v e left o r right Logical units to move u p or d o w n
Return Value: O n e of t h e Region flags' c o n s t a n t s .
Pt Visible D e t e r m i n e s w h e t h e r a p o i n t lies w i t h i n t h e s p e c i f i e d d e v i c e ' s c l i p p i n g r e g i o n , function PtVisible(DC: HDC; X, Y: Integer): Bool; Parameter DC X,Y
Description Device context A point
Return Value: If t h e p o i n t lies w i t h i n t h e c l i p p i n g r e g i o n of DC, n o n z e r o ; e l s e 0 .
RectVisible D e c i d e s w h e t h e r a n y part of Rect lies w i t h i n t h e s p e c i f i e d d e v i c e - c o n t e x t clipping region. function RectVisible(DC: HDC; var Rect: TRect): Bool; Parameter
Description
DC
Device context
Rect
TRect s t r u c t u r e
Return Value: N o n z e r o if i n t h e c l i p p i n g r e g i o n ; e l s e 0.
SelectClipRgn U s e s a c o p y of Rgn as t h e c u r r e n t c l i p p i n g r e g i o n f o r t h e d e v i c e c o n t e x t , function SelectClipRgn(DC: HDC; Rgn: HRgn): Integer; Parameter DC Rgn
Description Device context Selected region
Return Value: O n e of t h e Region flags' c o n s t a n t s .
N — G D I Procedures a n d Functions
Color Palette Procedures and Functions A l t h o u g h s o m e display devices c a n s h o w m a n y colors, they can s h o w only a f e w at o n e t i m e . T h e s y s t e m p a l e t t e is a g r o u p o f c o l o r s c u r r e n t l y available o n t h e device for s i m u l t a n e o u s display. W i n d o w s gives y o u r application s o m e control over t h e colors in t h e device's system palette. If y o u r applications u s e o n l y simple colors, y o u d o n ' t n e e d t o u s e a p a l e t t e directly. AnimatePalette CreatePalette GetNearestPalettelndex GetPaletteEntries GetSystemPaletteEntries GetSystemPaletteUse RealizePalette SelectPalette SetPaletteEntries SetSystemPaletteUse UpdateColors M o d i f y i n g t h e s y s t e m p a l e t t e affects e v e r y t h i n g d r a w n o n t h e s c r e e n , including the colors of other applications. In other words, o n e application can c a u s e all t h e o t h e r a p p l i c a t i o n s t o a p p e a r w i t h i n c o r r e c t c o l o r s . T h e W i n d o w s p a l e t t e m a n a g e r s o l v e s this p r o b l e m b y m e d i a t i n g a m o n g a p p l i c a t i o n s that c h a n g e t h e s y s t e m p a l e t t e . W i n d o w s s u p p l i e s e a c h a p p l i c a t i o n w i t h a l o g i c a l p a l e t t e (a g r o u p o f c o l o r s f o r a s p e c i f i c a p p l i c a t i o n ) . T h e p a l e t t e m a n a g e r m a p s t h e r e q u e s t e d c o l o r s from t h e l o g i c a l p a l e t t e t o t h e c o l o r s available i n t h e s y s t e m p a l e t t e . • I f t h e r e q u e s t e d c o l o r isn't listed i n t h e s y s t e m p a l e t t e , t h e p a l e t t e manager c a n a d d the color to the system palette. • If t h e l o g i c a l p a l e t t e s p e c i f i e s m o r e c o l o r s t h a n t h e s y s t e m p a l e t t e c a n h a n d l e , t h e a d d i t i o n a l c o l o r s a r e m a t c h e d t o t h e c l o s e s t available c o l o r in the system palette. W i n d o w s reserves 2 0 p e r m a n e n t c o l o r s i n t h e s y s t e m p a l e t t e t o g e n e r a l l y p r e s e r v e t h e c o l o r s c h e m e o f W i n d o w s a n d all W i n d o w s a p p l i c a t i o n s .
AnimatePalette R e p l a c e s e n t r i e s i n Palette b e t w e e n Startlndex a n d NumEntries w i t h PaletteColors. procedure AnimatePalette(Palette: HPalette; Startlndex: Word; NumEntries: Word; var PaletteColors);
803
804
Part I I I — R e f e r e n c e s
Parameter Palette Startlndex NumEntries PaletteColors
Description T h e logical palette T h e first e n t r y i n p a l e t t e t o b e a n i m a t e d T h e n u m b e r o f entries in palette to b e animated A n array o f T P a l e t t e E n t r y s t r u c t u r e s
CreatePalette Creates a logical color palette. function
CreatePalette(var
Parameter LogPalette
LogPalette:
TLogPalette):
HPalette;
Description T L o g P a l e t t e containing color information about the logical palette
Return Value: L o g i c a l p a l e t t e i d e n t i f i e r if s u c c e s s f u l ; e l s e 0.
GetNearestPalettelndex G e t s the closest matching color in a logical palette to C o l o r . function
GetNearestPaletteIndex(Palette:
Parameter Palette Color
HPalette;
Color:
TColorRef):
Description Logical palette identifier T C o l o r R e f to be matched
Return Value: Logical-palette entry index.
GetPaletteEntries G e t s the specified range o f palette entries a n d copies the palette range to PaletteEntries. function GetPaletteEntries(Palette: HPalette; Startlndex, N u m E n t r i e s : Word; v a r P a l e t t e E n t r i e s ) : Word;
Word;
N — G D I Procedures and Functions
Parameter
805
Description
Palette Startlndex NumEntries
Logical palette identifier First e n t r y N u m b e r o f entries
PaletteEntries
TPaletteEntry array t o r e c e i v e t h e p a l e t t e e n t r i e s
Return Value: N u m b e r o f e n t r i e s r e t r i e v e d ; 0 if e r r o r .
GetSystemPaletteEntries G e t s a range o f palette entries from the system palette. function GetSystemPaletteEntries(DC: HDC; Startlndex, NumEntries: Word; var PaletteEntries: TPaletteEntry): Word; Parameter
Description
DC Startlndex
Device context First e n t r y t o retrieve
NumEntries PaletteEntries
N u m b e r of e n t r i e s t o retrieve R e c e i v i n g TPaletteEntry array
Return
Value:
N u m b e r o f e n t r i e s r e t r i e v e d ; 0 if e r r o r .
GetSystemPaletteUse D e c i d e s w h e t h e r a n a p p l i c a t i o n h a s full a c c e s s t o t h e s y s t e m p a l e t t e , function GetSystemPaletteUse(DC: HDC): Word; Parameter DC
Description Device context
Return Value: O n e of t h e syspal_ s y s t e m p a l e t t e flags.
RealizePalette M a p s the selected logical palette t o entries in the system palette, function RealizePalette(DC: HDC): Word;
806
Part I I I — R e f e r e n c e s
Parameter
Description
DC Return
Device context Value:
N u m b e r o f entries in logical palette m a p p e d to different system palettes since last R e a l i z e P a l e t t e .
SelectPalette S e l e c t s P a l e t t e as t h e d e v i c e c o n t e x t ' s s e l e c t e d p a l e t t e o b j e c t , w h i c h t h e n is used by G D I to control displayed colors. f u n c t i o n S e l e c t P a l e t t e ( D C : HDC; P a l e t t e : ForceBackground: Bool): HPalette; Parameter
Description
DC Palette ForceBackground
Return
HPalette;
Device context Logical palette to select If n o n z e r o t h e n b a c k g r o u n d p a l e t t e ; o r if 0, foreground palette w h e n w i n d o w has the input focus
Value:
R e p l a c e d l o g i c a l p a l e t t e if s u c c e s s f u l ; e l s e 0.
SetPaletteEntries Sets l o g i c a l p a l e t t e entries i n t h e s p e c i f i e d r a n g e t o t h e v a l u e s i n P a l e t t e E n t r i e s . function SetPaletteEntries(Palette: HPalette; Startlndex, N u m E n t r i e s : Word; v a r P a l e t t e E n t r i e s ) : Word; Parameter
Description
Palette Startlndex
Logical palette identifier First e n t r y t o set
NumEntries
N u m b e r o f e n t r i e s t o set
PaletteEntries
Array o f T P a l e t t e E n t r y s t r u c t u r e
Return Value: N u m b e r o f e n t r i e s set; 0 if e r r o r .
SetSystemPaletteUse A l l o w s a n a p p l i c a t i o n t o u s e t h e full s y s t e m p a l e t t e .
N — G D I Procedures a n d Functions
807
function SetSystemPaletteUse(DC: HDC; Usage: Word): Word; Parameter
Description
DC
Device context
Usage
O n e o f t h e syspal_ s y s t e m p a l e t t e flags
Return Value: Previous system palette usage.
UpdateColors U p d a t e s t h e client area b y m a t c h i n g the current colors o f the client area pixelby-pixel with the system palette. function UpdateColors(DC: HDC): Integer; Parameter DC
Description Device context
Return Value: Not used.
Coordinate-Translation Procedures and Functions S o m e t i m e s y o u m i g h t w a n t t o translate b e t w e e n t h e l o g i c a l c o o r d i n a t e s ( y o u d r a w w i t h t h e m ) a n d p h y s i c a l b i t m a p c o o r d i n a t e s (to w h i c h t h e c u r r e n t m a p p i n g m o d e translates l o g i c a l c o o r d i n a t e s ) . G D I s u p p l i e s t h e f o l l o w i n g functions to h a n d l e coordinate translations: ChildWindowFromPoint ClientToScreen DPtoLP LPtoDP ScreenToClient WindowFromPoint
ChildWindowFromPoint D e c i d e s w h i c h c h i l d w i n d o w o w n e d b y WndParent c o n t a i n s APoint. function ChildWindowFromPoint(WndParent:
HWnd; APoint: TPoint): HWnd;
808
Part III—References
Parameter
Description
WndParent
Parent w i n d o w
APoint
TPoint structure of client coordinates to be tested
Return
Value:
Child w i n d o w that contains the point; 0 if point lies outside the parent window; WndParent if point isn't contained within any child window.
ClientToScreen Converts client coordinates in APoint to screen coordinates, procedure ClientToScreen(Wnd: HWnd; var Point: TPoint); Parameter
Wnd APoint
Description
W i n d o w containing client area TPoint containing client coordinates
DPtoLP Converts device points to logical points. function DPtoLP(DC: HDC; var Points; Count: Integer): Bool; Parameter
DC Points Count Return
Description
Device context Array of TPoint structures N u m b e r of points in Points Value:
Nonzero if all points are converted; else 0.
LPtoDP Converts logical points in Points, in the current mapping m o d e , to device points. function LPtoDP(DC: HDC; var Points; Count: Integer): Bool; Parameter
DC Points Count Return
Description
Device context Array of T P o i n t structures Size of Points
Value:
Nonzero if all points converted; else 0.
N — G D I Procedures and Functions
ScreenToClient C o n v e r t s a n d r e p l a c e s t h e s c r e e n - c o o r d i n a t e v a l u e s i n Point with t h e c l i e n t coordinates o f the specified w i n d o w . procedure ScreenToClient(Wnd: HWnd; var Point); Parameter
Description
Wnd
W i n d o w identifier
Point
TPoint s t r u c t u r e
WindowFromPoint D e c i d e s which w i n d o w c o n t a i n s t h e s p e c i f i e d p o i n t , function WindowFromPoint(Point: TPoint): HWnd; Parameter Point
Description TPoint t o b e c h e c k e d (in s c r e e n c o o r d i n a t e s )
Return Value: W i n d o w identifier; 0 if n o w i n d o w is at t h e s p e c i f i e d p o i n t .
Device-Context Procedures and Functions A d e v i c e c o n t e x t r e p r e s e n t s t h e d e v i c e driver, o u t p u t d e v i c e , a n d ( s o m e t i m e s ) t h e c o m m u n i c a t i o n s p o r t . Y o u r a p p l i c a t i o n ' s g r a p h i c f u n c t i o n s relate t o a specific device. CreateCompatibleDC CreateDC CreateIC DeleteDC GetDCOrg RestoreDC SaveDC
CreateCompatibleDC C r e a t e s a m e m o r y d e v i c e c o n t e x t c o m p a t i b l e with DC. function CreateCompatibleDC(DC: HDC): HDC;
809
810
Part I I I — R e f e r e n c e s
Parameter DC
Description D e v i c e c o n t e x t ; if 0, a m e m o r y d e v i c e c o n t e x t is created
Return Value: N e w m e m o r y d e v i c e c o n t e x t if s u c c e s s f u l ; e l s e 0.
CreateDC C r e a t e s a d e v i c e c o n t e x t f o r DriverName d e v i c e .
function CreateDC(DriverName, DeviceName, Output: PChar; InitData: Pointer): HDC; Parameter
Description
DriverName
D O S file n a m e ( w i t h o u t e x t e n s i o n a n d n u l l t e r m i n a t e d ) o f t h e d e v i c e driver
DeviceName
N a m e o f specific device to b e s u p p o r t e d (nullterminated)
Output InitData
O u t p u t D O S file o r d e v i c e n a m e ( n u l l - t e r m i n a t e d ) D E V M O D E structure containing device-specific initialization data
Return Value: D e v i c e c o n t e x t i d e n t i f i e r if s u c c e s s f u l ; e l s e 0.
CreateIC Creates an information context for the device.
function CreateIC(DriverName, DeviceName, Output, InitData: PChar): HDC; Parameter DriverName DeviceName Output InitData
Return
Description D e v i c e - d r i v e r D O S file n a m e ( n o e x t e n s i o n a n d null-terminated) Specific device n a m e (null-terminated) O u t p u t D O S file o r d e v i c e n a m e ( n u l l - t e r m i n a t e d ) Device-specific initialization data; nil for default initialization
Value:
I n f o r m a t i o n c o n t e x t i d e n t i f i e r if s u c c e s s f u l ; e l s e 0.
N — G D I Procedures a n d Functions
DeleteDC Deletes the device context. Notifies the device and releases all storage and systems resources if DC is the last device context for the device. function DeleteDC(DC: HDC): Bool; Parameter DC
Description Device context
Return Value: Nonzero if successful; else 0.
GetDCOrg Gets a device's final translation origin (in screen coordinates), w h i c h is the offset used by Windows to translate device coordinates to client coordinates. function GetDC0rg(DC: HDC): Longint; Parameter DC
Description Device context
Return Value: X-coordinate in the low w o r d ; Y-coordinate in the high word.
RestoreDC Restores a device context to the state specified by Save DC (a previous state) from the context stack. State information is deleted if SaveDC isn't at the top of the stack. function RestoreDC(DC: HDC; SaveDC: Integer): Bool; Parameter
Description
DC
Device context
SaveDC
Returns value of a previous SaveDC call or - 1 for most recently saved device context
Return Value: Nonzero if restored; else 0.
811
812
Part I I I — R e f e r e n c e s
SaveDC S a v e s t h e c u r r e n t state o f DC o n t h e c o n t e x t stack, function SaveDC(DC: HDC): Integer; Parameter DC Return
Description D e v i c e context identifier
Value:
S a v e d d e v i c e c o n t e x t if s u c c e s s f u l ; e l s e 0.
Device-Independent Bitmap Procedures and Functions B e c a u s e bitmaps represent the m e m o r y configuration o f a specific device, t h e y ' r e d e p e n d e n t o n t h e d e v i c e that's a d d r e s s e d . T h u s , b i t m a p s s a v e d f r o m o n e device might b e incompatible with another device. G D I supplies devicei n d e p e n d e n t (DI) b i t m a p s t o h e l p y o u t h r o u g h this p r o b l e m . U s e t h e f o l l o w i n g r o u t i n e s f o r DI b i t m a p s : CreateDIBitmap GetDIBits SetDIBits SetDIBitsToDevice StretchDIBits
CreateDIBitmap Creates a device-specific m e m o r y bitmap f r o m a device-independent b i t m a p d e s c r i b e d b y Inf oHeader a n d Initlnf o. function CreateDIBitmap(DC: HDC; var InfoHeader:
TBitmapInfoHeader;
Usage: Longint; InitBits: PChar; var Initlnfo: TBitmapInfo; Usage: Word): HBitmap; Parameter
Description
DC InfoHeader
Device context TBitmapInf oHeader that d e s c r i b e s b i t m a p size a n d
Usage
format I f cbm_Init t h e b i t m a p is initialized a c c o r d i n g t o InitBits a n d Initlnfo
N — G D I Procedures and Functions
Parameter
813
Description
InitBits
B y t e array c o n t a i n i n g initial b i t m a p v a l u e s , f o r m a t d e p e n d e n t o n biBitCount field o f Initlnf o
Initlnfo
T B i t m a p I n f o s t r u c t u r e that d e s c r i b e s d i m e n s i o n s and color format
Usage
O n e o f t h e D I B _ Color t a b l e i d e n t i f i e r s ' c o n s t a n t s
Return Value: B i t m a p i d e n t i f i e r if s u c c e s s f u l ; e l s e 0.
GetDIBits C o p i e s a bitmap, i n d e v i c e i n d e p e n d e n t format, t o Bits. function GetDIBits(DC: HDC; Bitmap: THandle; StartScan, NumScans: Word; Bits: Pointer; var Bitlnfo: TBitmapInfo; Usage: Word): Integer; Parameter DC Bitmap StartScan NumScans Bits Bitlnfo Usage
Description Device context Source bitmap First s c a n l i n e N u m b e r o f lines to copy B u f f e r t o r e c e i v e b i t m a p o r n i l t o fill Bitslnf o TBitmapInfo c o n t a i n i n g c o l o r f o r m a t a n d dimension of bitmap Indicates the source o f colors; o n e o f the Dib_ Color t a b l e i d e n t i f i e r s ' c o n s t a n t s
Return Value: N u m b e r o f s c a n l i n e s c o p i e d ; 0 if e r r o r .
SetDIBits S e t s a b i t m a p ' s bits t o t h e v a l u e s of a d e v i c e - i n d e p e n d e n t b i t m a p (DIB) specification. function SetDIBits(DC: HDC; Bitmap: THandle; StartScan, NumScans: Word; Bits: Pointer; var Bitslnfo: TBitmapInfo; Usage: Word): Integer;
814
Part I I I — R e f e r e n c e s
Parameter DC Bitmap StartScan NumScans Bits Bitslnfo Usage
Description Device context B i t m a p identifier S c a n l i n e n u m b e r c o r r e s p o n d i n g t o first s c a n l i n e i n Bits N u m b e r o f s c a n l i n e s i n Bits Array o f b y t e s c o n t a i n i n g t h e DIB bits w h o s e f o r m a t is s p e c i f i e d b y t h e biBitCount field o f Bitslnf o TBitmapInf o c o n t a i n i n g DIB i n f o r m a t i o n D e s c r i b e s c o n t e n t s o f bmiColors fields o f Bitslnf 0; e i t h e r o n e o f t h e DIB_ Color t a b l e identifiers
Return Value: N u m b e r o f s c a n l i n e s c o p i e d if s u c c e s s f u l ; e l s e 0.
SetDIBitsToDevice S e t s t h e bits o n a d e v i c e s u r f a c e d i r e c t l y f r o m a d e v i c e - i n d e p e n d e n t b i t m a p (DIB). function SetDIBitsToDevice(DC: HDC; DestX, DestY, Width, Height, SrcX, SrcY, StartScan, NumScans: Word; Bits: Pointer; var Bitslnfo:TBitmapInfo; Usage: Word): Integer; Parameter DC DestX, DestY Width Height SrcX, SrcY StartScan NumScans Bits Bitslnfo Usage
Description Device context Device destination rectangle origin DIB r e c t a n g l e x - e x t e n t DIB r e c t a n g l e y - e x t e n t DIB s o u r c e p o s i t i o n DIB s c a n l i n e n u m b e r c o r r e s p o n d i n g t o first s c a n l i n e i n Bits DIB s c a n l i n e s i n Bits Array o f b y t e s c o n t a i n i n g t h e DIB bits w h o s e f o r m a t is s p e c i f i e d b y t h e biBitCount field o f Bitslnf o TBitmapInf o c o n t a i n i n g DIB i n f o r m a t i o n D e s c r i b e s c o n t e n t s o f bmiColors fields o f Bitslnfo; e i t h e r o n e o f DIB_ Color t a b l e identifiers
Return Value: N u m b e r o f s c a n l i n e s set.
N — G D I Procedures a n d Functions
815
StretchDIBits M o v e s a d e v i c e - i n d e p e n d e n t b i t m a p ( s t r e t c h i n g or c o m p r e s s i n g t h e b i t m a p if required) from a source rectangle to a destination rectangle. T h e source a n d d e s t i n a t i o n a r e c o m b i n e d as s p e c i f i e d b y Rop. function StretchDIBits(DC: HDC; DestX, DestY, DestWidth, DestHeight, SrcX, SrcY, SrcWidth, SrcHeight: Word; Bits: Pointer; var Bitslnfo: TBitmapInfo; Usage: Word; Rop: DWord): Integer; Parameter
Description
DC
Receiving device context
DestX, DestY
Destination rectangle origin (in logical units)
DestWidth DestHeight SrcX, SrcY SrcWidth
Destination rectangle x-extent (in logical units) Destination rectangle y-extent (in logical units) S o u r c e r e c t a n g l e o r i g i n (in p i x e l s ) i n t h e DIB S o u r c e rectangle w i d t h (in pixels)
SrcHeight Bits Usage
S o u r c e rectangle height (in pixels) B y t e array c o n t a i n i n g DIB bits DIB_RGB_Colors s p e c i f i e s w h e t h e r t h e Bitslnfo. bmiColors field c o n t a i n s R G B v a l u e s o r DIB_Pal_Colors s p e c i f i e s i n d e x e s t o c u r r e n t l y realized logical palette
Return Value: N u m b e r o f scan lines c o p i e d .
Drawing-Attribute Procedures and Functions W i n d o w s a p p l i c a t i o n s w r i t e t o a l o g i c a l e n t i t y c a l l e d a d i s p l a y c o n t e x t (a virtual surface with associated attributes). T h e display context m a n a g e s t h e display o f graphics o n the screen. Y o u d o n ' t control the display context attributes. Y o u can, however, adjust certain drawing attributes, i n c l u d i n g b a c k g r o u n d c o l o r a n d m o d e , f o r e g r o u n d c o l o r f o r text, d r a w i n g ( c o l o r - c o m b i n i n g ) m o d e , b i t m a p - s t r e t c h i n g m o d e , a n d polygon-filling m o d e . Y o u c a n a l s o m o d i f y t h e d r a w i n g t o o l s y o u u s e t o c h a n g e t h e attributes o f displayed graphics. T h e attributes o f these tools dictate t h e a p p e a r a n c e o f graphics drawn with G D I functions. GetBkColor GetBkMode GetPolyFillMode GetR0P2
816
Part I I I — R e f e r e n c e s
GetStretchBltMode GetTextColor SetBkColor SetBkMode SetPolyFillMode SetR0P2 SetStretchBltMode SetTextColor
GetBkColor Gets the current device background color, function GetBkColor(DC: HDC): Longint; Parameter DC
Description Device context
Return Value: R G B color value.
GetBkMode G e t s t h e c u r r e n t d e v i c e b a c k g r o u n d m o d e , u s e d f o r text, h a t c h e d b r u s h e s , a n d n o n s o l i d l i n e - p e n styles. function GetBkMode(DC: HDC): Integer; Parameter DC
Description Device context
Return Value: O n e of t h e Background m o d e s ' c o n s t a n t s .
GetPolyFillMode G e t s t h e c u r r e n t p o l y g o n filling m o d e , function GetPolyFillMode(DC: HDC): Integer; Parameter DC
Description Device context
Return Value: P o l y g o n filling m o d e ; o n e of t h e PolyFill m o d e s ' c o n s t a n t s .
N — G D I Procedures a n d Functions
GetR0P2 Gets the current drawing m o d e , function GetR0P2(DC: HDC): Integer; Parameter DC
Description Raster d e v i c e c o n t e x t
Return Value: D r a w i n g m o d e ; o n e o f t h e r2_ Binary raster o p e r a t i o n s ' c o n s t a n t s .
GetStretchBltMode G e t s the current stretching m o d e . function GetStretchBltMode(DC: HDC): Integer; Parameter DC
Description Device context
Return Value: O n e o f t h e StretchBlt m o d e s ' c o n s t a n t s .
GetTextColor G e t s the current f o r e g r o u n d color u s e d t o draw characters, function GetTextColor(DC: HDC): Longint; Parameter DC
Description Device context
Return Value: R G B color value.
SetBkColor S e t s t h e c u r r e n t b a c k g r o u n d t o Color o r t h e n e a r e s t p h y s i c a l c o l o r s u p p o r t e d by the device. function SetBkColor(DC: HDC; Color: TColorRef): Longint;
817
818
Part I I I — R e f e r e n c e s
Parameter DC Color Return
Description Device context N e w background TColorRef
Value:
P r e v i o u s R G B b a c k g r o u n d c o l o r if s u c c e s s f u l ; e l s e $80,000,000.
SetBkMode Sets t h e b a c k g r o u n d m o d e that s p e c i f i e s w h e t h e r t h e G D I s h o u l d remove e x i s t i n g b a c k g r o u n d c o l o r s b e f o r e d r a w i n g text, h a t c h e d b r u s h e s , o r u s i n g n o n s o l i d p e n styles. function SetBkMode(DC: HDC; BkMode: Integer): Integer; Parameter
Description
DC
Device context
BkMode
O n e o f t h e Background m o d e s ' c o n s t a n t s
Return Value: P r e v i o u s m o d e if s u c c e s s f u l ; e l s e 0.
SetPolyFillMode S e t s t h e p o l y g o n filling m o d e u s e d b y G D I f u n c t i o n s that u s e t h e p o l y g o n algorithm for c o m p u t i n g interior points. function SetPolyFillMode(DC: HDC; PolyFillMode: Integer): Integer; Parameter
Description
DC
Device context
PolyFillMode
O n e o f t h e PolyFill m o d e s ' c o n s t a n t s
Return Value: P r e v i o u s filling m o d e if s u c c e s s f u l ; e l s e 0.
SetR0P2 S e t s t h e c u r r e n t d r a w i n g m o d e t o t h e v a l u e s p e c i f i e d b y DrawMode. T h i s m o d e s p e c i f i e s h o w o b j e c t interiors a n d p e n s are c o m b i n e d w i t h c o l o r s a l r e a d y o n the display surface. function SetR0P2(DC: HDC; DrawMode: Integer): Integer;
N — G D I Procedures and Functions
Parameter DC DrawMode
819
Description Device context A n y o n e o f t h e r2_ constants
B i n a r y raster o p e r a t i o n s '
Return Value: Previous drawing m o d e .
SetStretchBltMode Sets the stretching m o d e u s e d by S t r e t c h M o d e to contract a b i t m a p . function
SetStretchBltMode(DC:
Parameter DC StretchMode
HDC;
StretchMode:
Integer):
Integer;
Description Device context O n e of the S t r e t c h B l t m o d e s ' constants
Return Value: Previous stretching m o d e .
SetTextColor S e t s t h e text c o l o r o r n e a r e s t d e v i c e - s u p p o r t e d c o l o r u s e d b y T e x t O u t a n d E x t T e x t O u t t o d r a w a c h a r a c t e r ' s f a c e . S e t T e x t C o l o r is u s e d a l s o b y t h e G D I to convert bitmaps f r o m m o n o c h r o m e to color a n d vice versa. function
SetTextColor(DC:
Parameter DC Color
HDC;
Color:
TColorRef):
Longint;
Description Device context Text T C o l o r R e f
Return Value: P r e v i o u s text R G B c o l o r v a l u e .
Drawing Tool Procedures and Functions T h e display context manages the screen display o f graphics. T o display graphics in other ways, y o u can c h a n g e the drawing tools u s e d to render the graphics: • Pens dictate the appearance o f d r a w n lines. • B r u s h e s d i c t a t e t h e a p p e a r a n c e o f filled s h a p e s .
820
Part I I I — R e f e r e n c e s
• F o n t s d i c t a t e t h e a p p e a r a n c e o f d r a w n text. T o assign the attributes o f a drawing t o o l , a W i n d o w s application selects a logical or stock tool in a display context. • Y o u r a p p l i c a t i o n c r e a t e s a l o g i c a l t o o l b y filling t h e fields o f a p a r t i c u l a r record (TLogPen, TLogBrush, or TLogFont). • A s t o c k t o o l is a n e x i s t i n g , W i n d o w s - d e f i n e d t o o l r e p r e s e n t i n g t h e m o s t c o m m o n attribute c h o i c e s . Logical Tools DeleteObject GetBrushOrg GetObject SelectObject SetBrushOrg UnrealizeObject CreateBrushIndirect CreateDIBPatternBrush CreateHatchBrush CreatePatternBrush CreateSolidBrush EnumObjects CreatePen CreatePenlndirect CreateFont CreateFontIndirect Stock Tools GetStockObject
DeleteObject D e l e t e s H a n d l e f r o m m e m o r y a n d frees all a s s o c i a t e d s y s t e m r e s o u r c e s , function
DeleteObject(Handle:
Parameter Handle
THandle):
Bool;
Description H a n d l e to a logical p e n , brush, font, bitmap, region, or palette
Return Value: N o n z e r o if d e l e t e d ; 0 if H a n d l e isn't v a l i d o r c u r r e n t l y s e l e c t e d i n a d e v i c e context.
N — G D I Procedures a n d Functions
GetBrushOrg Gets the current device brush origin, function GetBrushOrg(DC: HDC): Longint; Parameter DC
Description Device context
Return Value: X-coordinates in l o w word; Y-coordinates in high word.
GetObject Fills a b u f f e r w i t h d a t a that d e f i n e s a l o g i c a l o b j e c t a n d r e t u r n s t h e n u m b e r o f entries for logical palettes. function GetObject(hObject: THandle; Count: Integer; ObjectPtr: Pointer): Integer; Parameter hObject Count ObjectPtr
Description Object N u m b e r o f b y t e s t o c o p y t o 0b j ectPtr R e c e i v i n g b u f f e r ; TLogPen, TLogBrush, TLogFont, TBitmap, o r a n i n t e g e r
Return Value: N u m b e r o f b y t e s c o p i e d ; 0 if e r r o r .
SelectObject S e l e c t s a l o g i c a l o b j e c t f o r DC. O n l y o n e o b j e c t c a n b e s e l e c t e d at o n e t i m e , a n d it s h o u l d b e d e l e t e d w h e n it's n o l o n g e r b e i n g u s e d . function SelectObject(DC: HDC; hObject: THandle): THandle; Parameter DC hObject
Description Device context O n e o f the following: bitmap, brush, font, p e n , o r region
Return Value: O b j e c t b e i n g r e p l a c e d o r n o n z e r o if m e t a f i l e DC; 0 if e r r o r .
821
822
Part I I I — R e f e r e n c e s
SetBrushOrg Sets the origin o f the selected brush. T h e brush shouldn't b e a stock object, function SetBrushOrg(DC: HDC; X, Y: Integer): Longint; Parameter
Description
DC
Device context
X,Y
N e w o r i g i n (in d e v i c e u n i t s ) , r a n g i n g f r o m 0 t o 7
Return
Value:
P r e v i o u s o r i g i n w h e r e X - c o o r d i n a t e is i n l o w - o r d e r w o r d ; Y - c o o r d i n a t e is i n high-order word.
UnrealizeObject R e s e t s t h e o r i g i n t h e n e x t t i m e s e l e c t e d if hOb j ect is a b r u s h o r t o r e a l i z e t h e p a l e t t e if hOb j ect is a l o g i c a l p a l e t t e . function UnrealizeObject(hObject: HBrush): Bool; Parameter hObject Return
Description O b j e c t t o b e reset
Value:
N o n z e r o if s u c c e s s f u l ; e l s e 0.
CreateBrushlndirect C r e a t e s a logical b r u s h d e f i n e d b y LogBrush. function CreateBrushlndirect(var Parameter LogBrush
LogBrush: TLogBrush): HBrush;
Description TLogBrush s t r u c t u r e
Return Value: L o g i c a l b r u s h i d e n t i f i e r if s u c c e s s f u l ; e l s e 0.
CreateDIBPatternBrush C r e a t e s a logical b r u s h f r o m t h e d e v i c e - i n d e p e n d e n t b i t m a p d e f i n e d b y PackedDIB. function CreateDIBPatternBrush(PackedDIB: Usage: Word): HBitmap;
THandle;
N — G D I Procedures a n d Functions
Parameter
823
Description
PackedDIB
G l o b a l m e m o r y c o n t a i n i n g TBitmapInf o s t r u c t u r e
Usage
p l u s array o f p i x e l s O n e o f t h e DIB_ Color t a b l e i d e n t i f i e r s ' c o n s t a n t s
Return Value: L o g i c a l b r u s h i d e n t i f i e r if s u c c e s s f u l ; e l s e 0.
CreateHatchfirush C r e a t e s a l o g i c a l b r u s h w i t h a s p e c i f i e d h a t c h style. function CreateHatchBrush(Index: Parameter
Integer; Color: TColorRef): HBrush;
Description
Index
O n e o f t h e hs_ Hatch styles' c o n s t a n t s
Color
TColorRef that s p e c i f i e s t h e c o l o r o f t h e h a t c h e s
Return Value: L o g i c a l b r u s h i d e n t i f i e r if s u c c e s s f u l ; e l s e 0.
CreatePatternBmsh C r e a t e s a logical b r u s h w i t h a Bitmap p a t t e r n . function CreatePatternBrush(Bitmap: Parameter Bitmap
HBitmap): HBrush;
Description HBitmap b i t m a p
Return Value: L o g i c a l b r u s h i d e n t i f i e r if s u c c e s s f u l ; e l s e 0.
CreateSolidBrush Creates a logical brush. function CreateSolidBrush(Color: TColorRef): HBrush; Parameter Color
Description B r u s h TColorRef
Return Value: L o g i c a l b r u s h i d e n t i f i e r if s u c c e s s f u l ; e l s e 0.
824
Part III—References
EnumObjects Enumerates the object types currently available o n a device by passing TLogPen orTLogBrushand data to the callback. Enumeration ends if the callback returns 0 or all objects are enumerated. function EnumObjects(DC: HDC; ObjectType: Integer; ObjectFunc: TFarProc Data: Pointer): Integer; Parameter
DC ObjectType ObjectFunc Data Return
Description
Device context Can be one of the ob j_ G D I object type constants: obj_Brush or obj_Pen Callback function's procedure-instance address Data passed to callback
Value:
Last value returned by callback.
CreatePen Creates a logical pen. function CreatePen(PenStyle, Width: Integer; Color: TColorRef): HPen; Parameter
PenStyle Width Color Return
Description
O n e of the ps_ Pen styles' constants Pen width (in logical units) Pen TColorRef
Value:
Logical pen identifier if successful; else 0.
CreatePenlndirect Creates a logical pen defined by LogPen. function CreatePenlndirect(var LogPen: TLogPen): HPen; Parameter
LogPen Return
Description
TLogPen structure
Value:
Logical pen identifier if successful; else 0.
N — G D I Procedures a n d Functions
CreateFont Creates a logical font selected from G D I ' s p o o l o f physical fonts according to specified characteristics. function CreateFont(Height, Width, Escapement, Orientation, Weight:Integer; Italic, Underline, Strikeout, CharSet, OutputPrecision,ClipPrecision, Quality, PitchAndFamily: Byte; FaceName: PChar): HFont; Parameter Height Width Escapement Orientation Weight Italic Underline StrikeOut CharSet OutputPrecision ClipPrecision Quality PitchAndFamily Facename
Description F o n t height (in l o g i c a l u n i t s ) A v e r a g e f o n t w i d t h (in l o g i c a l u n i t s ) L i n e a n g l e (in t e n t h s o f d e g r e e s ) C h a r a c t e r b a s e l i n e a n g l e (in t e n t h s o f d e g r e e s ) F o n t w e i g h t (0 t o 1000); o r u s e a f w_ F o n t w e i g h t flag s u c h as f w _ N o r m a l o r f w _ B o l d F o n t is italic F o n t is u n d e r l i n e d F o n t is s t r u c k o u t O n e o f t h e F o n t character set flags' c o n s t a n t s O n e o f t h e o u t _ F o n t o u t p u t p r e c i s i o n flags' constants O n e o f t h e c l i p _ F o n t c l i p p i n g p r e c i s i o n flags' constants O n e o f the Font o u t p u t quality flags' constants O n e o f the F o n t pitch flags' constants c o m b i n e d w i t h o n e o f t h e f f _ F o n t f a m i l y flags Font typeface n a m e (null-terminated)
Return Value: L o g i c a l f o n t i d e n t i f i e r if s u c c e s s f u l ; e l s e 0.
CreateFontlndirect Creates a logical font selected from the GDI's pool of physical fonts according to the characteristics in ALogFont. function CreateFontlndirect(var Parameter ALogFont
LogFont: TLogFont): HFont;
Description TLogFont structure
Return Value: L o g i c a l f o n t i d e n t i f i e r if s u c c e s s f u l ; e l s e 0.
825
826
Part I I I — R e f e r e n c e s
GetStockObject G e t s a handle to a predefined stock p e n , brush, o r font, function GetStockObject(Index: Parameter Index Return
Integer): THandle;
Description O n e o f t h e Stock logical o b j e c t s ' c o n s t a n t s
Value:
S e l e c t e d l o g i c a l o b j e c t i d e n t i f i e r if s u c c e s s f u l ; e l s e 0 .
Environment Procedures and Functions GetEnvironment SetEnvironment Escape
GetEnvironment G e t s the current environment for the device attached to the system port. function GetEnvironment(PortName, MaxCount: Word): Integer; Parameter
Environ: PChar;
Description
PortName
Port n a m e ( n u l l - t e r m i n a t e d )
Environ
B u f f e r t o r e c e i v e e n v i r o n m e n t (first field m u s t c o n t a i n d e v i c e n a m e ) o r n i l t o r e t u r n r e q u i r e d size Size o f buffer
MaxCount Return
Value:
N u m b e r o f b y t e s c o p i e d ; 0 if e n v i r o n m e n t c a n n o t b e f o u n d .
SetEnvironment Creates or replaces a device's environment. function SetEnvironment(PortName,
Environ: PChar; Count: Word):
Integer;
N — G D I Procedures a n d Functions
Parameter PortName Environ Count
Description System port n a m e (null-terminated) Buffer containing n e w environment N u m b e r o f bytes in E n v i r o n t o c o p y o r 0 t o delete current environment
Return Value: N u m b e r o f b y t e s c o p i e d ; 0 if e r r o r ; - 1 if e n v i r o n m e n t is d e l e t e d .
Escape A l l o w s a c c e s s t o d e v i c e - s p e c i f i c facilities n o t s u p p o r t e d b y t h e G D I . function Escape(DC: HDC; Escape, Count: Integer; InData, OutData: Pointer): Integer; Parameter DC Count InData OutData
Description Device context B y t e s o f d a t a i n InData T h e input data structure S t r u c t u r e t o r e c e i v e Escape o u t p u t d a t a o r n i l f o r n o output data
Return Value: A p o s i t i v e n u m b e r if s u c c e s s f u l ; 0 if e s c a p e isn't i m p l e m e n t e d ; n e g a t i v e if e r r o r ; if e r r o r , m a y b e o n e o f t h e sp_ Spooler e r r o r c o d e s .
Font Procedures and Functions A f o n t is a s u b s e t o f a p a r t i c u l a r t y p e f a c e . F o n t p r o c e d u r e s a n d f u n c t i o n s c r e a t e , r e m o v e , select, a n d g e t i n f o r m a t i o n a b o u t f o n t s . AddFontResource CreateFont CreateFontIndirect EnumFonts GetCharWidth RemoveFontResource SetMapperFlags
827
828
Part I I I — R e f e r e n c e s
AddFontResource A d d s f o n t resource
f r o m FileName f o n t - r e s o u r c e file t o t h e s y s t e m f o n t t a b l e ,
function AddFontResource(FileName: Parameter FileName
PChar): Integer;
Description H a n d l e t o l o a d e d m o d u l e o r n u l l - t e r m i n a t e d string
Return Value: N u m b e r o f f o n t s a d d e d ; 0 if n o f o n t s w e r e a d d e d .
CreateFont Creates a logical font selected from G D I ' s p o o l of physical fonts according to the specified characteristics. function CreateFont(Height, Width, Escapement, Orientation, Weight: Integer; Italic, Underline, Strikeout, CharSet, OutputPrecision, ClipPrecision, Quality, PitchAndFamily: Byte; FaceName: PChar): HFont; Parameter
Description
Height Width
F o n t height (in l o g i c a l u n i t s ) A v e r a g e f o n t w i d t h (in l o g i c a l u n i t s )
Escapement Orientation Weight
L i n e a n g l e (in t e n t h s o f d e g r e e s ) C h a r a c t e r b a s e l i n e a n g l e (in t e n t h s o f d e g r e e s ) F o n t w e i g h t (0 t o 1 0 0 0 ) ; o r u s e a f w_ f o n t w e i g h t flag s u c h as f w _ N o r m a l o r f w _ B o l d F o n t is italic
Italic Underline StrikeOut CharSet OutputPrecision
F o n t is u n d e r l i n e d F o n t is s t r u c k o u t O n e o f t h e f o n t character set flags' c o n s t a n t s O n e o f t h e o u t _ f o n t o u t p u t p r e c i s i o n flags' constants
ClipPrecision
O n e of the c l i p _ font clipping precision constants
Quality PitchAndFamily
O n e o f t h e f o n t o u t p u t q u a l i t y flags' c o n s t a n t s O n e o f t h e f o n t p i t c h flags' c o n s t a n t s c o m b i n e d w i t h o n e o f t h e f f _ f o n t family flags font typeface n a m e (null-terminated)
Facename
Return Value: L o g i c a l f o n t i d e n t i f i e r if s u c c e s s f u l ; e l s e 0.
flags'
N — G D I Procedures and Functions
CreateFontlndirect Creates a logical font selected from G D I ' s p o o l of physical fonts according to the characteristics i n A L o g F o n t . function
CreateFontlndirect(var
Parameter ALogFont
LogFont:
TLogFont):
HFont;
Description T L o g F o n t structure
Return Value: L o g i c a l f o n t i d e n t i f i e r if s u c c e s s f u l ; e l s e 0.
EnumFonts E n u m e r a t e s available f o n t s h a v i n g t h e s p e c i f i e d t y p e f a c e o n a d e v i c e . T h e c a l l b a c k is p a s s e d T L o g F o n t , T T e x t M e t r i c , F o n t T y p e , a n d D a t a . E n u m e r a t i o n e n d s if t h e c a l l b a c k r e t u r n s 0 o r w h e n all f o n t s are e n u m e r a t e d . f u n c t i o n E n u m F o n t s ( D C : HDC; F a c e N a m e : TFarProc; Data: Pointer): Integer; Parameter DC FaceName FontFunc Data
PChar;
FontFunc:
Description Device context Typeface n a m e (null-terminated) o r nil to r a n d o m l y s e l e c t o n e f o n t f o r e a c h available t y p e f a c e C a l l b a c k function's procedure-instance address Data passed to the c a l l b a c k function
Return Value: Last v a l u e r e t u r n e d b y t h e c a l l b a c k .
GetCharWidth G e t s individual character widths for a g r o u p of consecutive characters. function GetCharWidth(DC: var B u f f e r ) : Bool; Parameter DC FirstChar LastChar Buffer
HDC; F i r s t C h a r ,
LastChar:
Word;
Description Device context First c h a r a c t e r i n c o n s e c u t i v e c h a r a c t e r g r o u p Last c h a r a c t e r i n c o n s e c u t i v e c h a r a c t e r g r o u p R e c e i v i n g i n t e g e r array f o r w i d t h v a l u e s
Return Value: N o n z e r o if s u c c e s s f u l ; e l s e 0.
829
830
Part I I I — R e f e r e n c e s
RemoveFontResource R e m o v e s a f o n t f r o m W i n d o w s ' f o n t t a b l e . T h e f o n t isn't r e m o v e d u n t i l all o u t s t a n d i n g references t o t h e resource are deleted. function RemoveFontResourc(FileName: Parameter FileName
Return
PChar): Bool;
Description F o n t - r e s o u r c e file n a m e ( n u l l - t e r m i n a t e d ) o r module-instance handle
Value:
N o n z e r o if s u c c e s s f u l ; e l s e 0.
SetMapperFlags C h a n g e s t h e f o n t - m a p p e r a l g o r i t h m as s p e c i f i e d b y Flag. function SetMapperFlags(DC: HDC; Flag: Longint): Longint; Parameter DC Flag
Description Device context I f first bit set t o 1, o n l y f o n t s w h o s e X - a n d Y - a s p e c t s exactly m a t c h the device are selected
Return Value: P r e v i o u s f o n t - m a p p e r flag.
line-Drawing Procedures and Functions Line-drawing procedures a n d functions u s e the specified display context's current p e n for drawing. Arc LineDDA LineTo MoveTo Polyline
Arc D r a w s a n elliptical arc c e n t e r e d i n t h e b o u n d i n g r e c t a n g l e . function Arc(DC: HDC; X1, Y1, X2, Y2, X3, Y3, X4, Y4: Integer): Bool;
N — G D I Procedures a n d Functions
Parameter DC XI, X2, X3, X4,
Yl Y2 Y3 Y4
Return
Description Device context Upper-left corner o f b o u n d i n g rectangle Lower-right corner o f b o u n d i n g rectangle A r c ' s starting p o i n t Arc's e n d point
Value:
N o n z e r o if t h e arc is d r a w n ; e l s e 0. T h e b o u n d i n g r e c t a n g l e c a n n o t b e taller o r w i d e r t h a n 32,767 u n i t s (that i s , a n i n t e g e r v a l u e ) .
IineDDA C o m p u t e s all s u c c e s s i v e p o i n t s i n a l i n e a n d calls LineFunc p a s s i n g X a n d Y o f t h e p o i n t a n d Data. procedure LineDDA(X1, Y1, X2, Y2: Integer; LineFunc: TFarProc; Data: Pointer); Parameter XI, Yl X2, Y2 LineFunc Data
Description First p o i n t i n l i n e Last p o i n t i n l i n e C a l l b a c k function procedure-instance address D a t a p a s s e d t o LineFunc
IineTo Draws a line, using selected p e n , from the current position u p to the specified endpoint. function LineTo(DC: HDC; X , Y : Parameter DC X, Y
Integer): Bool;
Description Device context E n d p o i n t o f the line
Return Value: N o n z e r o if d r a w n ; e l s e 0.
MoveTo Moves the current position to the specified point, function MoveTo(DC: HDC; X , Y :
Integer): Longint;
831
832
Part I I I — R e f e r e n c e s
Parameter DC X, Y
Description Device context N e w position
Return Value: X-coordinates o f previous position in low-order w o r d ; Y-coordinates o f previous position in high-order word.
Polyline D r a w s a set o f l i n e s e g m e n t s u s i n g a s e l e c t e d p e n , w h e r e e a c h s u b s e q u e n t p o i n t is s p e c i f i e d b y Points. function Polyline(DC: HDC; var Points; Count: Integer): Bool; Parameter DC Points Count
Description Device context Array o f T P o i n t s t r u c t u r e s S i z e o f Points
Return Value: N o n z e r o if s u c c e s s f u l ; e l s e 0.
Mapping Procedures and Functions M a p p i n g m o d e s d e s c r i b e t h e relative s i z e , p o s i t i o n , a n d o r i e n t a t i o n o f l o g i c a l coordinates versus device coordinates: GetMapMode GetViewportExt GetViewportOrg GetWindowExt GetWindowOrg OffsetViewportOrg OffsetWindowOrg ScaleViewportExt ScaleWindowExt SetMapMode SetViewportExt SetViewportOrg SetWindowExt SetWindowOrg
N — G D I Procedures a n d Functions
GetMapMode Gets the current m a p p i n g m o d e . function GetMapMode(DC: HDC): Integer; Parameter DC
Description Device context
Return Value: A n mm_ Mapping m o d e s ' c o n s t a n t .
GetViewportExt G e t s t h e v i e w p o r t e x t e n t s of a d e v i c e c o n t e x t , function GetViewportExt(DC: HDC): Longint; Parameter DC Return
Description Device context
Value:
X-extents (in device units) in low-order w o r d ; Y-extents (in device units) in high-order word.
GetViewportOrg G e t s t h e v i e w p o r t o r i g i n of a d e v i c e c o n t e x t , function GetViewportOrg(DC: HDC): Longint; Parameter DC Return
Description Device context
Value:
X - c o o r d i n a t e (in d e v i c e u n i t s ) i n l o w - o r d e r w o r d ; Y - c o o r d i n a t e (in d e v i c e u n i t s ) in high-order w o r d .
GetWindowExt Gets a window's extents. function GetWindowExt(DC: HDC): Longint;
833
834
Part I I I — R e f e r e n c e s
Parameter DC Return
Description Device context
Value:
X - e x t e n t s (in d e v i c e u n i t s ) i n l o w - o r d e r w o r d ; Y - e x t e n t s ( i n d e v i c e u n i t s ) i n high-order word.
GetWindowOrg Gets a window's origin. function GetWindowOrg(DC: HDC): Longint; Parameter DC Return
Description Device context
Value:
X - c o o r d i n a t e s ( i n l o g i c a l c o o r d i n a t e s ) i n l o w w o r d ; Y - c o o r d i n a t e s (in l o g i c a l coordinates) in high word.
OffsetViewportOrg C h a n g e s a viewport origin by s u m m i n g the current origin with the specified X and Y values. function OffsetViewportOrg(DC: HDC; X , Y: Integer): Longint; Parameter
Description
DC
Device context
X Y
X - c o o r d i n a t e o r i g i n offset Y - c o o r d i n a t e o r i g i n offset
Return Value: Y-coordinates of previous origin in high-order word; X-coordinates of previous origin in low-order word.
OfifeetWindowOrg C h a n g e s a w i n d o w ' s origin by s u m m i n g the current origin with the specified X a n d Y values. function OffsetWindowOrg(DC: HDC; X , Y: Integer): Longint;
N — G D I Procedures and Functions
Parameter DC X Y
Description Device context X - c o o r d i n a t e (in l o g i c a l u n i t s ) o r i g i n offset Y - c o o r d i n a t e (in l o g i c a l u n i t s ) o r i g i n offset
Return Value: Y-coordinates of previous origin in high-order w o r d ; X-coordinates o f previous origin in low-order w o r d .
ScaleViewportExt C h a n g e s the current viewport extents.
function ScaleViewportExt(DC: HDC; Xnum, Xdenom, Ynum, Ydenom: Integer): Longint; Parameter
Description
DC Xnum
Device context Value to multiply current X-extent
Xdenom Ynum Ydenom
Value to divide current X-extent Value to multiply current Y-extent Value to divide current Y-extent
Return Value: Previous Y-extent in high-order w o r d ; previous X-extent in low-order w o r d .
ScaleWindowExt C h a n g e s the current w i n d o w extents.
function ScaleWindowExt(DC: HDC; Xnum, Xdenom, Ynum, Ydenom: Integer): Longint; Parameter
Description
Xnum Xdenom Ynum Ydenom
Value Value Value Value
to to to to
multiply current X-extent divide current X-extent multiply current Y-extent divide current Y-extent
Return Value: Previous Y-extent in high-order w o r d ; previous X-extent in low-order w o r d .
835
836
Part I I I — R e f e r e n c e s
SetMapMode S e t s t h e d e v i c e - c o n t e x t m a p p i n g m o d e that d e f i n e s l o g i c a l - t o - d e v i c e u n i t s ' transformations for G D I a n d X - a n d Y-axis orientation. function SetMapMode(DC: HDC; MapMode: Integer): Integer; Parameter DC MapMode Return
Description Device context O n e o f t h e mm_ Mapping m o d e s ' c o n s t a n t s
Value:
Previous m a p p i n g m o d e .
SetViewportExt Sets a viewport's X - a n d Y-extents, w h i c h defines h o w t h e G D I stretches o r c o m p r e s s e s l o g i c a l u n i t s t o fit d e v i c e u n i t s . function SetViewportExt(DC: HDC; X, Y: Integer): Longint; Parameter
Description
DC
Device context
X, Y
N e w v i e w p o r t e x t e n t s (in d e v i c e u n i t s )
Return Value: Previous X-extent in low-order words; previous Yextents in high-order words.
SetViewportOrg Sets a v i e w p o r t ' s o r i g i n t o d e f i n e h o w t h e G D I m a p s l o g i c a l c o o r d i n a t e s t o points in device coordinates. function SetViewportOrg(DC: HDC; X, Y: Integer): Longint; Parameter
Description
DC
Device context
X, Y
N e w v i e w p o r t o r i g i n (in d e v i c e u n i t s )
Return Value: X-coordinates of previous origin in low-order word; Y-coordinates of previous origin in high-order word.
N — G D I Procedures a n d Functions
SetWindowExt Sets a w i n d o w ' s X - a n d Y-extents. This, a l o n g with the viewport extents, defines h o w G D I s t r e t c h e s o r c o m p r e s s e s l o g i c a l u n i t s t o fit d e v i c e u n i t s . function SetWindowExt(DC: HDC; X, Y: Integer): Longint; Parameter
Description
DC
Device context
X, Y
W i n d o w extents
Return Value: Previous Xextents in low-order words; previous Yextents in high-order words; 0 if e r r o r .
SetWindowOrg Sets a w i n d o w ' s origin within the viewport o f the specified device context, function SetWindowOrg(DC: HDC; X, Y: Integer): Longint; Parameter DC X, Y Return
Description Device context N e w w i n d o w origin
Value:
Previous X-coordinate in low-order w o r d ; previous Y-coordinate in high-order word.
Metafile Procedures and Functions A m e t a f i l e is a set o f G D I c o m m a n d s f o r c r e a t i n g t e x t o r g r a p h i c s i m a g e s . M e t a f i l e f u n c t i o n s c r e a t e , c l o s e , c o p y , d e l e t e , p l a y , retrieve, a n d g e t i n f o r m a t i o n about metafiles. CloseMetaFile CopyMetaFile CreateMetaFile DeleteMetaFile EnumMetaFile GetMetaFile GetMetaFileBits PlayMetaFile PlayMetaFileRecord SetMetaFileBits
837
838
Part in—References
CloseMetaFile Closes D C and creates a metafile handle that can be used to play the metafile, function CloseMetaFile(DC: THandle): THandle; Parameter
DC Return
Description
Metafile device context Value:
Metafile identifier if successful; else 0.
CopyMetaFile Copies SrcMetaFileto thefileFileName. function CopyMetaFile(SrcMetaFile: THandle; FileName: PChar): THandle Parameter
Description
SrcMetaFile
Source metafile
FileName
Metafile n a m e (null-terminated) or 0 to copy to a m e m o r y metafile
Return
Value:
N e w metafile identifier.
CreateMetaFile Creates a metafile device context. function CreateMetaFile(FileName: PChar): THandle; Parameter
FileName Return
Description
Metafile n a m e (null-terminated) or nil to specify a m e m o r y metafile
Value:
Metafile device context identifier if successful; else 0.
DeleteMetaFile Invalidates a metafile handle and frees its associated system resources. The metafile isn't deleted. function DeleteMetaFile(MF: THandle): Bool;
N — G D I Procedures and Functions
Parameter
Description
MF
Metafile identifier
Return
Value:
Nonzero if successful; 0 if M F isn't a valid handle.
EnumMetaFile Enumerates G D I calls in a metafile passing the following information: •
DC
• A pointer to the metafile's object handles table • A pointer to a record in the metafile • The n u m b e r of objects with associated handles in the table • ClientData to the callback function EnumMetaFile(DC: HDC; MF: THandle; CallbackFunc: TFarProc; ClientData: LPByte): Bool; Enumeration ends if the callback returns 0 or if all G D I calls are enumerated. Parameter
DC MF CallbackFunc ClientData Return
Description
Device context associated with metafile Metafile identifier Callback function's procedure-instance address D a t a passed to callback
Value:
Nonzero if all G D I calls in metafile are enumerated; else 0.
GetMetaFile Creates a handle for the n a m e d metafile. function GetMetaFile(FileName: PChar): THandle; Parameter
Description
FileName
Metafile D O Sfilen a m e (null-terminated)
Return
Value:
Metafile identifier if successful; else 0.
839
8 4 0 Part III—References
GetMetaFileBits Gets a read-only global m e m o r y block containing the metafile as a collection of bits. Used to determine size and save as metafile. function GetMetaFileBits(MF: THandle): THandle; Parameter
MF Return
Description
M e m o r y metafile identifier, becomes invalid after call Value:
Global m e m o r y block if successful; else 0.
PlayMetaFile Plays the contents of a metafile o n the specified device, function PlayMetaFile(DC: HDC; MF: THandle): Bool; Parameter
DC MF Return
Description
Device context Metafile identifier Value:
Nonzero if successful; else 0.
PlayMetaFileRecord Executes the G D I function call contained in a metafile record. procedure PlayMetaFileRecord(DC: HDC; var HandleTable: THandleTable var MetaRecord: TMetaRecord; Handles: Word); Parameter
DC HandleTable MetaRecord Handles
Description
Device context THandleTable used for metafile playback TMetaRecord of metafile to play Size of HandleTable
SetMetaFileBits Creates a m e m o r y metafile from the data specified by Mem. function SetMetaFileBits(Mem: THandle): THandle;
N — G D I Procedures and Functions
Parameter Mem
Description G l o b a l m e m o r y block containing metafile data p r e v i o u s l y c r e a t e d b y GetMetaFileBits
Return Value: M e m o r y m e t a f i l e i d e n t i f i e r if s u c c e s s f u l ; e l s e 0.
Printer-Control Procedures and Functions Device capabilities D e v i c e c a p a b i l i t i e s ' c o n s t a n t s are a s s o c i a t e d w i t h s p e c i f i c c a p a b i l i t i e s o f a d e v i c e c o n t e x t . T h e y a r e u s e d i n t h e GetDeviceCaps f u n c t i o n : Constant AspectX AspectXY AspectY BitsPixel ClipCaps
Meaning
LogPixelsX LogPixelsY NumBrushes NumColors NumFonts NumMarkers
Relative p i x e l w i d t h Diagonal pixel length Relative p i x e l h e i g h t N u m b e r o f bits p e r p i x e l C l i p p i n g c a p a b i l i t i e s ; r e t u r n s a cp_ c l i p p i n g capabilities' constant C o l o r r e s o l u t i o n i n bits p e r p i x e l C u r v e c a p a b i l i t i e s ; r e t u r n s a cc_ c u r v e c a p a b i l i t i e s ' constant D e v i c e driver v e r s i o n ; f o r e x a m p l e , $ 1 0 0 is 1.0 Horizontal width in pixels H o r i z o n t a l size i n m i l l i m e t e r s Line capabilities; returns a l c _ line capabilities' constant N u m b e r o f pixels p e r horizontal inch N u m b e r o f p i x e l s p e r vertical i n c h N u m b e r of brushes the device has N u m b e r o f colors the device supports N u m b e r o f fonts the device has N u m b e r of markers the device has
NumPens NumReserved PDeviceSize Planes
N u m b e r o f pens the device has N u m b e r o f reserved entries in palette Size required for device descriptor N u m b e r of color planes
PolygonalCaps
P o l y g o n a l c a p a b i l i t i e s ; r e t u r n s a pc_ p o l y g o n a l capabilities' constant
ColorRes CurveCaps DriverVersion HorzRes HorzSize LineCaps
841
842
Part I I I — R e f e r e n c e s
Constant RasterCaps SizePalette Technology
Meaning Raster c a p a b i l i t i e s ; r e t u r n s a r c _ raster c a p a b i l i t i e s ' constant N u m b e r o f entries in physical palette D e v i c e classification; returns a d t _ device
TextCaps
technology constant T e x t c a p a b i l i t i e s ; r e t u r n s a t c _ text c a p a b i l i t i e s ' constant
VertRes VertSize
Vertical width in pixels V e r t i c a l size i n m i l l i m e t e r s
Rectangle Procedures and Functions A r e c t a n g l e is d e f i n e d b y t h e W i n d o w s d a t a s t r u c t u r e , TRect. R e c t a n g l e functions modify a n d get information about rectangles: CopyRect EqualRect InflateRect IntersectRect OffsetRect PtlnRect SetRectEmpty UnionRect
CopyRect C o p i e s SourceRect t o DestRect. procedure CopyRect(var DestRect, SourceRect: TRect); Parameter DestRect SourceRect
Description TRect s t r u c t u r e TRect s t r u c t u r e
EqualRect C o m p a r e s t h e u p p e r - l e f t a n d l o w e r - r i g h t c o r n e r s of t w o r e c t a n g l e s , function EqualRect(var Recti, Rect2: TRect): Bool;
N — G D I Procedures and Functions
Parameter
Recti, Rect2 Return
Description
Rectangles to be compared
Value:
Nonzero if equal; else 0.
InflateRect Changes the width and height of Rect. Adds X to left and right ends and Y to top and bottom of rectangle. procedure InflateRect(var Rect: TRect; X, Y: Integer); Parameter
Rect X Y
Description
TRect structure Positive or negative value to change rectangle width Positive or negative value to change rectangle height
IntersectRect Finds the intersection of two rectangles. function IntersectRect (var DestRect, S r d R e c t , Src2Rect: TRect): Integer; Parameter
DestRect SrclRect Src2Rect Return
Description
TRect structure representing the resulting rectangle TRect structure representing a source rectangle TRect structure representing a source rectangle
Value:
If intersection isn't empty, nonzero; 0 if intersection is empty.
OflfeetRect Adjusts a rectangle's coordinates by the specified X and Y offsets procedure OffsetRect(var Rect: TRect; X, Y: Integer); Parameter
Rect X Y
Description
TRect structure Units to m o v e left or right Units to m o v e u p or d o w n
843
844
Part I I I — R e f e r e n c e s
PtmRect D e c i d e s w h e t h e r a p o i n t lies w i t h i n , o r o n t h e left o r t o p s i d e , o f a r e c t a n g l e , function PtInRect(var Rect: TRect; Point: TPoint): B o o l ; Parameter Rect Point
Description TRect s t r u c t u r e TPoint s t r u c t u r e
Return Value: N o n z e r o if Point lies w i t h i n Rect; e l s e 0.
SetRectEmpty S e t s all Rect c o o r d i n a t e s t o 0. procedure SetRectEmpty(var Rect: TRect); Parameter Rect
Description R e c e i v i n g TRect s t r u c t u r e
UnionRect C r e a t e s a u n i o n o f t w o r e c t a n g l e s a n d s t o r e s t h e result inDestRect. function UnionRect (var DestRect, S r d R e c t , Src2Rect: LPRect): Integer; Parameter
Description
DestRect SrclRect
R e s u l t TRect s t r u c t u r e S o u r c e TRect s t r u c t u r e 1
Src2Rect
S o u r c e TRect s t r u c t u r e 2
Return
Value:
N o n z e r o if u n i o n isn't e m p t y ; 0 if e m p t y .
Region Procedures and Functions A r e g i o n is a n a r e a (a p o l y g o n o r a n e l l i p s e ) i n a w i n d o w . R e g i o n s c a n b e filled with graphical output. Region procedures a n d functions create, modify, a n d get information about regions:
N — G D I Procedures and Functions
CombineRgn CreateEllipticRgn CreateEllipticRgnIndirect CreatePolygonRgn CreatePolyPolygonRgn CreateRectRgn CreateRectRgnIndirect CreateRoundRectRgn EqualRgn FillRgn FrameRgn GetRgnBox InvertRgn OffsetRgn PaintRgn PtlnRegion RectlnRegion SetRectRgn
CombineRgn C o m b i n e s r e g i o n s SrcRgnl w i t h SrcRgn2 a n d p u t s t h e result i n DestRgn. CombineMode s p e c i f i e s t h e m e t h o d u s e d t o c o m b i n e t h e r e g i o n s .
function CombineRgn(DestRgn, SrcRgnl, SrcRgn2: HRgn; CombineMode: Integer): Integer; Parameter
Description
DestRgn SrcRgnl SrcRgn2
Region to b e replaced with n e w region A n existing region A n existing region
CombineMode
O n e of t h e rgn_ Combine r e g i o n
flags
Return Value: O n e of t h e Region flags' c o n s t a n t s .
CreateEllipticRgn C r e a t e s a n elliptical r e g i o n b o u n d e d b y t h e s p e c i f i e d r e c t a n g l e ,
function CreateEllipticRgn(X1, Y1, X2, Y2: Integer): HRgn;
845
846
Part I I I — R e f e r e n c e s
Parameter XI, Yl X2, Y2
Description Upper-left corner o f b o u n d i n g rectangle Lower-right corner o f b o u n d i n g rectangle
Return Value: N e w r e g i o n i d e n t i f i e r if s u c c e s s f u l ; e l s e 0.
CreateEllipticRgnlndirect C r e a t e s a n elliptical r e g i o n b o u n d e d b y t h e r e c t a n g l e s p e c i f i e d i n ARect. function CreateEllipticRgnlndirect(var Parameter ARect
Rect: TRect): HRgn;
Description TRect c o n t a i n i n g u p p e r - l e f t a n d l o w e r - r i g h t c o r n e r s of the b o u n d i n g rectangle
Return Value: N e w r e g i o n i d e n t i f i e r if s u c c e s s f u l ; e l s e 0.
CreatePolygonRgn Creates a polygon region. function CreatePolygonRgn(var Integer): HRgn; Parameter
Points; Count, PolyFillMode:
Description
Points Count
TPoint array c o n t a i n i n g v e r t i c e s o f t h e p o l y g o n N u m b e r o f p o i n t s i n Points
PolyFillMode
M o d e f o r filling t h e r e g i o n ; u s e o n e o f t h e PolyFill m o d e s ' c o n s t a n t s
Return Value: N e w r e g i o n i d e n t i f i e r if s u c c e s s f u l ; e l s e 0.
CreatePolyPolygonRgn C r e a t e s a r e g i o n c o n s i s t i n g o f a series o f p o s s i b l y o v e r l a p p i n g c l o s e d p o l y g o n s . function CreatePolyPolygonRgn(var
Points; var PolyCounts;
Counts, PolyFillMode: Integer): HRgn;
N — G D I Procedures a n d Functions
Parameter
847
Description
Points PolyCounts
TPoint array c o n t a i n i n g v e r t i c e s o f t h e p o l y g o n s I n t e g e r array w h e r e e a c h c o r r e s p o n d i n g e l e m e n t specifies the n u m b e r o f points for each p o l y g o n in Points
Count PolyFillMode
S i z e o f PolyCounts O n e o f t h e PolyFill m o d e s
Return Value: R e g i o n i d e n t i f i e r if s u c c e s s f u l ; e l s e 0.
CreateRectRgn Creates a rectangular region b o u n d e d by the specified rectangle, function CreateRectRgn(X1, Y1, X2, Y2: Integer): HRgn; Parameters
Description
XI, Yl
Upper-left corner o f b o u n d i n g rectangle
X2, Y2
Lower-right corner o f b o u n d i n g rectangle
Return Value: R e g i o n i d e n t i f i e r if s u c c e s s f u l ; e l s e 0.
CreateRectRgnlndirect C r e a t e s a r e c t a n g u l a r r e g i o n b o u n d e d b y ARect. function CreateRectRgnlndirect(var Parameter ARect
Rect: TRect): HRgn;
Description TRect c o n t a i n i n g u p p e r - l e f t a n d l o w e r - r i g h t c o r n e r s of the region
CreateRoundRectRgn Creates a rectangular region with r o u n d e d corners b o u n d e d by the specified region. function CreateRoundRectRgn(X1, Y1, X2, Y2, X3, Y3: Integer): HRgn;
848
Part I I I — R e f e r e n c e s
Parameter XI, Yl X2, Y2 X3 Y3
Description Upper-left corner o f region Lower-right corner o f region Ellipse width for r o u n d e d corners Ellipse height for r o u n d e d corners
Return Value: R e g i o n i d e n t i f i e r if s u c c e s s f u l ; e l s e 0.
EqualRgn Compares two regions. function EqualRgn(SrcRgn1, Parameter
SrcRgn2: HRgn): Bool;
Description
SrcRgnl, SrcRgn2
Regions to be compared
Return Value: N o n z e r o if e q u a l ; e l s e 0.
FillRgn Fills a r e g i o n u s i n g Brush. function FillRgn(DC: HDC; Rgn: HRgn; Brush: HBrush): Bool; Parameter DC Rgn Brush Return
Description Device context R e g i o n t o b e filled Fill b r u s h
Value:
N o n z e r o if s u c c e s s f u l ; e l s e 0.
FrameRgn Draws a border around a region. function FrameRgn(DC: HDC; Rgn: HRgn; Brush: HBrush; Width, Height: Integer): Bool;
N — G D I Procedures a n d Functions
Parameter
Description
DC
Device context
Rgn Brush Width
Region to be closed Framing brush B o r d e r w i d t h i n vertical b r u s h s t r o k e s ( l o g i c a l units) B o r d e r height in horizontal brush strokes (logical units)
Height
Return Value: N o n z e r o if s u c c e s s f u l ; e l s e 0.
GetRgnBox Gets a region's b o u n d i n g rectangle. function GetRgnBox(Rgn: HRgn; var Rect: TRect): Integer; Parameter
Description
Rgn
R e g i o n identifier
Rect
R e c e i v i n g TRect
Return Value: R e g i o n s t y p e , o n e o f t h e Region flags: ComplexRegion NullRegion SimpleRegion; 0 if i n v a l i d r e g i o n .
InvertRgn Inverts t h e c o l o r s o f t h e r e g i o n s p e c i f i e d b y Rgn. function InvertRgn(DC: HDC; Rgn: HRgn): Bool; Parameter DC Rgn
Description Device context R e g i o n i d e n t i f i e r (in d e v i c e u n i t s )
Return Value: N o n z e r o if s u c c e s s f u l ; e l s e 0 .
849
850
Part I I I — R e f e r e n c e s
OflfcetRgn M o v e s a r e g i o n b y t h e s p e c i f i e d X a n d Y offsets. function OffsetRgn(Rgn: HRgn; X , Y : Parameter
Integer): Integer;
Description
Rgn
R e g i o n identifier
X Y
U n i t s t o m o v e left o r right Units to move u p or d o w n
Return
Value:
O n e o f t h e Region flags' c o n s t a n t s .
PaintRgn Fills a r e g i o n w i t h t h e c u r r e n t b r u s h , function PaintRgn(DC: HDC; Rgn: HRgn): Bool; Parameter DC Rgn Return
Description Device context Fill r e g i o n
Value:
N o n z e r o if s u c c e s s f u l ; e l s e 0.
PtlnRegion D e c i d e s w h e t h e r a p o i n t lies w i t h i n a r e g i o n , function PtInRegion(Rgn: HRgn; X , Y : Parameter Rgn X, Y
Description R e g i o n identifier A point
Return Value: N o n z e r o if t h e p o i n t lies w i t h i n Rgn; e l s e 0.
Integer): Bool;
N — G D I Procedures a n d Functions
RectlnRegion D e c i d e s w h e t h e r a n y p a r t o f Rect lies w i t h i n a r e g i o n , function RectlnRegion(Region: HRgn; var Rect: TRect): Bool; Parameter
Description
Region
HRgn r e g i o n i d e n t i f i e r
Rect
TRect s t r u c t u r e
Return Value: N o n z e r o if w i t h i n r e g i o n b o u n d a r i e s ; e l s e 0.
SetRectRgn U s e s t h e s p a c e a l l o c a t e d f o r Rgn t o c r e a t e a r e c t a n g u l a r r e g i o n w i t h a s p e c i f i e d size. procedure SetRectRgn(Rgn: HRgn; X1, Y1, X2, Y2: Integer); Parameter Rgn XI, Yl X2, Y2
Description R e g i o n identifier Upper-left corner o f rectangle region Lower-left c o r n e r o f r e c t a n g l e r e g i o n
Shape-Drawing Procedures and Functions Shape-drawing functions u s e a specified display context's p e n to draw the p e r i m e t e r a n d t h e d i s p l a y c o n t e x t ' s c u r r e n t b r u s h t o fill t h e i n t e r i o r . T h e y d o n o t , h o w e v e r , affect t h e c u r r e n t p o s i t i o n . T h e s h a p e - d r a w i n g p r o c e d u r e s a n d f u n c t i o n s a r e as f o l l o w s : Chord DrawFocusRect Ellipse Pie Polygon PolyPolygon Rectangle RoundRect
851
852
Part I I I — R e f e r e n c e s
Chord Draws a c h o r d b o u n d e d by the intersection of an ellipse centered in the b o u n d i n g rectangle and a line segment.
function Chord(DC: HDC; X1, Y1, X2, Y2, X3, Y3, X4, Y4: Integer): Bool; Parameter DC XI, X2, X3, X4,
Device context Upper-left corner of b o u n d i n g rectangle Lower-right corner of b o u n d i n g rectangle O n e e n d of the line segment O n e e n d of the line segment
Yl Y2 Y3 Y4
Return
Description
Value:
N o n z e r o if t h e c h o r d is d r a w n ; e l s e 0.
DrawFocusRect P e r f o r m s XOR t o d r a w a f o c u s style r e c t a n g l e ,
procedure DrawFocusRect(DC: HDC; v a r Rect: TRect); Parameter DC Rect
Description Device context TRect t o b e d r a w n
Ellipse D r a w s a n e l l i p s e c e n t e r e d i n t h e b o u n d i n g r e c t a n g l e , w h o s e b o r d e r is d r a w n w i t h t h e c u r r e n t p e n a n d filled w i t h t h e c u r r e n t b r u s h .
function Ellipse(DC: HDC; X1, Y1, X2, Y2: Integer): Bool; Parameter DC XI, Yl X2, Y2
Description Device context Upper-left corner of the b o u n d i n g rectangle Lower-left c o r n e r o f t h e b o u n d i n g r e c t a n g l e
Return Value: N o n z e r o if t h e e l l i p s e w a s d r a w n ; e l s e 0.
N — G D I Procedures and Functions
853
We D r a w s a p i e - s h a p e d w e d g e u s i n g t h e c u r r e n t p e n a n d filled w i t h t h e c u r r e n t brush, centered in the b o u n d i n g rectangle. function
Pie(DC:
HDC; X 1 , Y 1 ,
Parameter DC XI, X2, X3, X4,
X2, Y2,
X3,
Y3,
X4,
Y4:
Integer):
Description Device context Upper-left corner of b o u n d i n g rectangle Lower-left c o r n e r o f b o u n d i n g r e c t a n g l e S t a r t i n g p o i n t o f arc E n d p o i n t o f arc
Yl Y2 Y3 Y4
Return Value: N o n z e r o if d r a w n ; e l s e 0.
Polygon D r a w s a p o l y g o n u s i n g t h e c u r r e n t p o l y g o n - f i l l i n g m o d e , w h o s e v e r t i c e s are s p e c i f i e d b y P o i n t s . If n e c e s s a r y , t h e p o l y g o n is c l o s e d . function
Polygon(DC:
Parameter
HDC; v a r P o i n t s ;
Count:
Integer):
Bool;
Description
DC
Device context
Points Count
Array o f T P o i n t s t r u c t u r e s Size of P o i n t s
Return Value: N o n z e r o if s u c c e s s f u l ; e l s e 0.
PolyPolygon D r a w s a series o f p o s s i b l y o v e r l a p p i n g p o l y g o n s u s i n g t h e c u r r e n t p o l y g o n filling m o d e , w h o s e v e r t i c e s are s p e c i f i e d b y P o i n t s . T h e p o l y g o n s are n o t closed automatically. function Count:
PolyPolygon(DC: Integer):
Bool;
HDC; v a r P o i n t s ;
var
PolyCounts;
Bool;
854
Part I I I — R e f e r e n c e s
Parameter
Description
DC Points PolyCounts
Device context Array o f T P o i n t s t r u c t u r e s Array o f i n t e g e r s i n w h i c h e a c h n u m b e r s p e c i f i e s t h e n u m b e r o f vertices for e a c h p o l y g o n in P o i n t s Size o f P o l y C o u n t s
Count Return
Value:
N o n z e r o if d r a w n ; e l s e 0.
Rectangle D r a w s a r e c t a n g l e u s i n g t h e c u r r e n t p e n a n d fills its i n t e r i o r w i t h t h e c u r r e n t brush. function
Rectangle(DC:
Parameter DC XI, Yl X2, Y2
HDC; X1, Y1, X2, Y2:
Integer):
Bool;
Description Device context Upper-left corner of rectangle Lower-right corner of rectangle
Return Value: N o n z e r o if r e c t a n g l e d r a w n ; e l s e 0.
RoimdRect D r a w s a rectangle w i t h rounded t h e current brush.
c o r n e r s u s i n g t h e c u r r e n t p e n a n d filled u s i n g
function RoundRect(DC: HDC; X1, Y1, X2, Y2, X3, Y3: Integer): Bool; Parameter DC XI, Yl X2, Y2 X3 Y3
Description Device context Upper-left corner of rectangle Lower-right corner of rectangle Ellipse width u s e d to draw r o u n d e d corners Ellipse height u s e d to draw r o u n d e d corners
Return Value: N o n z e r o if d r a w n ; e l s e 0.
N — G D I Procedures a n d Functions
855
Text-Drawing Procedures and Functions Text-drawing functions u s e the display context's current font t o draw.
ExtTextOut GetTabbedTextExtent GetTextAlign GetTextExtent GetTextFace GetTextMetrics SetTextAlign SetTextJustification TabbedTextOut TextOut
ExtTextOut W r i t e s a string ( u s i n g t h e c u r r e n t f o n t ) w i t h i n Rect.
function ExtTextOut(DC: HDC; X, Y: Integer; Options: Word; Rect: LPRect; Str: PChar; Count: Word; Dx: LPInteger): Bool; Parameter
Description
DC X, Y Options
Device context O r i g i n o f first c h a r a c t e r c e l l C a n b e a c o m b i n a t i o n ofeto_ ExtTextOut o p t i o n s
ARect
TRect o r n i l
Str Count Dx
String to write N u m b e r o f c h a r a c t e r s i n string Array o f v a l u e s s p e c i f y i n g d i s t a n c e b e t w e e n a d j a c e n t cells o r 0 for d e f a u l t s p a c i n g
Return
Value:
N o n z e r o if string is d r a w n ; e l s e 0.
GetTabbedTextExtent C o m p u t e s t h e h e i g h t a n d w i d t h (in p i x e l s ) o f Str u s i n g t h e c u r r e n t f o n t . T a b s are e x p a n d e d as s p e c i f i e d .
function GetTabbedTextExtent(DC: HDC; Str: PChar; Count, TabPositions: Integer; var TabStopPositions): Longint;
856
Part I I I — R e f e r e n c e s
Parameter
Description
DC Str Count
Device context L i n e o f text N u m b e r o f characters in S t r
TabPositions
N u m b e r of tab-stop positions in T a b S t o p P o s i t i o n s o r 0 a n d tabs are e x p a n d e d eight average character widths I n t e g e r array c o n t a i n i n g i n c r e a s i n g o r d e r o f t a b s t o p p o s i t i o n s (in p i x e l s )
TabStopPositions
Return Value: H e i g h t in high-order w o r d ; w i d t h in low-order w o r d .
GetTextAlign Gets text-alignment function
flags.
GetTextAlign(DC:
Parameter DC
HDC): Word;
Description Device context
Return Value: C o m b i n a t i o n o f t a _ text a l i g n m e n t o p t i o n s
flags
GetTextExtent Calculates the dimensions of S t r based o n the current font. function
GetTextExtent(DC:
Parameter DC Str Count
HDC; S t r :
PChar;
Count:
Integer):
Longint;
Description Device context L i n e o f text N u m b e r of characters in S t r
Return Value: H e i g h t (in l o g i c a l u n i t s ) i n h i g h w o r d ; w i d t h (in l o g i c a l u n i t s ) i n l o w w o r d .
GetTextFace C o p i e s current font's typeface n a m e to Facename. function
GetTextFace(DC:
HDC; C o u n t :
Integer;
Facename:
PChar):
Integer
N — G D I Procedures and Functions
Parameter
DC Count Facename Return
Description
Device context Size of Facename Receiving buffer
Value:
N u m b e r of bytes copied.
GetTextMetrics Gets the metrics of the current font. function GetTextMetrics(DC: HDC; var Metrics: TTextMetric): Bool; Parameter
DC Metrics Return
Description
Device context Receiving TTextMetric structure
Value:
Nonzero if successful; else 0.
SetTextAlign Sets text-alignment flags usedbyTextOut and ExtTextOut for positioning text in relationship to its bounding rectangle. function SetTextAlign(DC: HDC; Flags: Word): Word; Parameter
DC Flags Return
Description
Device or display context A combination of the ta_ Text alignment options' constants Value:
Previous horizontal alignment in low-order byte; previous vertical alignment in high-order byte.
SetTextJustification Defines justification parameters used by the G D I to justify a line of text. function SetTextJustification(DC: HDC; BreakExtra, BreakCount: Integer): Integer;
857
858
Part III—References
Parameter
DC BreakExtra BreakCount Return
Description
Device context Extra line space (in logical units) to be added N u m b e r of break characters (usually space character) in line
Value:
1 if successful; else 0.
TabbedTextOut Draws a line of text with tabs expanded as specified in TabStopPositions, using the current font. function TabbedTextOut(DC: HDC; X, Y: Integer; Str: PChar; Count, TabPositions: Integer; var TabStopPositions; TabOrigin: Integer): Longint; Parameter DC X, Y Str Count TabPositions
Description Device context S t r i n g starting p o i n t String to b e d r a w n S i z e (in c h a r a c t e r s ) o f St r N u m b e r of tab-stop positions in
TabStopPositions o r 0 if tab-stops are TabStopPositions TabOrigin
Return
e x p a n d e d eight average character widths I n t e g e r array c o n t a i n i n g a s c e n d i n g t a b - s t o p p o s i t i o n s (in p i x e l s ) S t a r t i n g p o s i t i o n (in l o g i c a l u n i t s ) f r o m w h i c h tabs are e x p a n d e d
Value:
Not used.
TextOut Draws a line of text using the current font. function Text0ut(DC: HDC; X, Y: Integer; Str: PChar; Count: Integer): Bool;
N — G D I Procedures and Functions
Parameter DC X, Y Str Count
Description Device context S t r i n g starting p o i n t String to be drawn S i z e (in c h a r a c t e r s ) o f S t r
Return Value: N o n z e r o if d r a w n ; e l s e 0.
859
O
REFERENCE
OBJECTGRAPHICS (A WHITEWATER G R O U P GRAPHICS TOOLKIT)
O b j e c t G r a p h i c s is a library o f o b j e c t t y p e s that y o u c a n u s e t o h a n d l e m o s t o f t h e d e t a i l s o f g r a p h i c s m a n i p u l a t i o n i n y o u r T u r b o Pascal f o r W i n d o w s a p p l i cations. O b j e c t G r a p h i c s is d e s i g n e d t o b e u s e d a l o n g w i t h O b j e c t W i n d o w s , w h i c h defines the object types for h a n d l i n g the details o f w i n d o w m a n a g e m e n t for T u r b o Pascal for W i n d o w s applications. O b j e c t G r a p h i c s c o n t a i n s m a n y u s e f u l g r a p h i c s o b j e c t s that y o u c a n m o r e o r less p l u g i n t o y o u r T u r b o Pascal for W i n d o w s a p p l i c a t i o n s . T h e s e g r a p h i c objects include the following: Graphics TBezier
TChooser
Object
Use D i s p l a y e d as a c u r v e a n d d e f i n e d b y a polynomial approximation U s e d t o select o t h e r g r a p h i c s o b j e c t s f r o m a p i c t u r e ; d r a w n as a r e c t a n g u l a r s h a p e
TCurve
Drawn using control points continues
862
Part I I I — R e f e r e n c e s
Graphics
Object
Use
TEllipse
A s i m p l e elliptical g r a p h i c s o b j e c t
TEllipticalArc
D r a w n as a n elliptical arc
TGBitmap
I m p l e m e n t s the platform-specific data a n d functions for creating a n d using bitmaps
TGPrinter
P r o v i d e s a n abstract p r o t o c o l f o r p r i n t i n g ObjectGraphics graphic objects
TGraphic
A f o r m a l class w h i c h d e f i n e s b e h a v i o r w h i c h c a n b e inherited
b y its d e s c e n d a n t s
TGScroller
A c u s t o m i z e d scroller
TGWindow
A customized window
TIcon
Handles platform-independent manipulation o f icons
TLabel
I m p l e m e n t s s i m p l e a t t r i b u t e d text
TLine
A simple graphics object which o w n s a p e n , but not a brush
TLogBitmap
A formal type which defines the platformindependent data a n d behaviors for bitmaps
TPicture
A collection o f graphics objects
TPie
A pie-shaped graphics object
TPolygon
A graphics object with a polygonal shape
TPolyLine
A g r a p h i c s o b j e c t d r a w n as a g r o u p o f c o n n e c t e d line segments
TPolyMark
A g r o u p o f g r a p h i c s markers u s e d t o m a r k t h e c o r n e r s o r vertices o f o t h e r g r a p h i c s
TPolyShape
A f o r m a l class w h i c h d e f i n e s b e h a v i o r w h i c h its d e s c e n d a n t s c a n inherit
TPort
Defines most of the platform-dependent b e h a v i o r u s e d in O b j e c t G r a p h i c s a p p l i c a t i o n s
TRectangle
A simple graphics object
TRegion
U s e d t o d e s c r i b e a c o m p l e x area o f t h e d i s p l a y
TRichText
A collection of T L a b e l s
TRoundRect
A rectangle
w i t h round
corners
O—ObjectGraphics
Graphics
Object
TShape
Use A formal type defining behavior w h i c h can be i n h e r i t e d b y its d e s c e n d a n t s . T S h a p e d e s c e n dants draw themselves by outlining (framing) w i t h a T P e n o b j e c t a n d t h e n filling w i t h a TBrush object
TSubPicture
A c o l l e c t i o n o f g r a p h i c s o b j e c t s . It differs f r o m a T P i c t u r e only by not assumming ownership o f its m e m b e r o b j e c t s . T h u s , it d o e s n ' t d i s p o s e its m e m b e r o b j e c t s i n its d e s t r u c t o r
TBrush
A l o g i c a l g r a p h i c s b r u s h , u s e d t o fill T S h a p e objects. B r u s h e s b u n d l e diverse attributes o f s h a p e interiors
TColor
U s e d t o specify a c o l o r a t t r i b u t e ; its p h y s i c a l representation is d e p e n d e n t u p o n t h e c o l o r m o d e l used by the platform
TPoint
Holds and manipulates X and Y-coordinates
TGraphSpace
D e t e r m i n e s how a c o n c e p t u a l w o r l d is m a p p e d to t h e p h y s i c a l d i s p l a y d e v i c e
TIndexColor
U s e d t o specify a c o l o r a t t r i b u t e , b a s e d o n a n index into a color palette
TLogPort
A formal type w h i c h defines behavior w h i c h c a n b e i n h e r i t e d b y its d e s c e n d a n t s
TMathRect
Used for mathematical manipulation of c o o r d i n a t e s d e f i n i n g a rectangular
TMemoryStream
area
A T S t ream d e s c e n d a n t w h i c h reads a n d w r i t e s t o m e m o r y , rather
than to t h e disk or to E M S
TPen
A logical drawing p e n w h i c h b u n d l e s diverse attributes o f a l i n e
TPointColl
A collection of points
TSystemColor
A c o l o r o b j e c t w h o s e c o l o r is b a s e d o n a c o l o r s p e c i f i e d b y t h e u s e r as a n e n v i r o n m e n t o p t i o n
TTextPen
A l o g i c a l text d r a w i n g t o o l
O b j e c t G r a p h i c s o b j e c t s are u s e d similarly t o O b j e c t W i n d o w s o b j e c t s . F o r e x a m p l e , the following short application uses ObjectGraphics and O b j e c t W i n d o w s to create a picture w i n d o w :
863
864
Part I I I — R e f e r e n c e s
program APicture; uses 0GL1, 0GL2, 0GL3, WObjects, WinTypes, WinProcs;
{ { { { { {
ObjectGraphics units ' ' ' ' ObjectWindows units ' ' ' ' 1
1 1
1
1
1
1 1
} } } } } }
type APictureApp = object(TApplication) procedure InitMainWindow; virtual; end; PPictureWindow = "APictureWindow; APictureWindow = object(TGWindow) { a customized window } constructor Init(AParent: PWindowsObject; ATitle: PChar); procedure BeginDrag(MousePt: PGPoint; KeyStates: Word); virtual; end; constructor APictureWindow.Init(AParent: PWindowsObject; ATitle: PChar); var Recti, Rect2, Rect3: PRectangle; BrushColor: PColor; begin AGWindow.Init(AParent, ATitle); Recti := New(PRectangle, Init(30, 30, 100, 100, tc_Tools)); BrushColor := New(PColor, Init(ps_Red)); Recti".Brush".SetColor(BrushColor); Picture".Add(Rect1); Rect2 := New(PRectangle, Init(50, 50, 120, 120, tc_Tools)); BrushColor".SetPrimary(ps_Green); Rect2".Brush".SetColor(BrushColor); Picture".Add(Rect2); Rect3 := New(PRectangle, Init(70, 70, 140, 140, tc_Tools)); BrushColor".SetPrimary(ps_Blue); Rect3".Brush".SetColor(BrushColor); Picture".Add(Rect3); Dispose(BrushColor, Done); end;
O—ObjectGraphics
865
procedure APictureWindow.BeginDrag(MousePt: PGPoint; KeyStates:Word); var SelGraphic: PGraphic; begin SelGraphic := Picture".ThatContains(MousePt); if SelGraphic <> nil then begin Picture".BringFront(SelGraphic); {SelGraphic".Invalidate(Port);} Port".Associate(@Self); SelGraphic".Draw(Port); Port".Dissociate; end; end; procedure APictureApp.InitMainWindow; begin MainWindow := New(PPictureWindow, Init(nil, Application".Name)); end; var PictureApp: APictureApp; begin PictureApp.Init('This Picture'); PictureApp.Run; PictureApp.Done; end. For m o r e information about O b j e c t G r a p h i c s , write to: The Whitewater G r o u p 1800 Ridge A v e n u e Evanston, Illinois 60201
p REFERENCE
NOTES FOR MANAGING A PROJECT T u r b o Pascal f o r W i n d o w s h a s a b u i l t - i n I D E ( i n t e g r a t e d d e v e l o p m e n t e n v i r o n m e n t ) that m a k e s it very easy t o d e v e l o p l a r g e p r o g r a m m i n g p r o j e c t s . I n p a r t i c u l a r , try t o m a k e g o o d u s e o f t h e c o n f i g u r a t i o n ( C F G ) file a n d its c o r r e s p o n d i n g d e s k t o p ( D S K ) file. T h e s e files e n a b l e y o u t o set u p a p r o j e c t ' s files a n d h a v e t h e m a u t o m a t i c a l l y c o m p i l e d (as a p r o j e c t ) a n d l o a d e d (as a p r o j e c t ) e a c h t i m e y o u start T u r b o Pascal f o r W i n d o w s . B e c a u s e T u r b o Pascal f o r W i n d o w s r e m e m b e r s w h e r e y o u are i n e a c h o f t h e s e files ( u s i n g t h e d e s k t o p file), y o u c a n w o r k o n m a n y files at o n c e w i t h o u t k e e p i n g track (yourself) o f w h e r e y o u a r e . Y o u r current environment (including compiler, linker, editor, and other p r e f e r e n c e s ) are s a v e d f o r y o u e a c h t i m e y o u c l o s e T u r b o Pascal f o r W i n d o w s . I n w r i t i n g this b o o k , I m a d e e a c h c h a p t e r a p r o j e c t a n d e a c h n e w w i n d o w development a unit, and I u s e d the Make compile o p t i o n to compile c o d e . T h e M a k e o p t i o n c a n save y o u m u c h o r g a n i z a t i o n a l t i m e b e c a u s e it a u t o m a t i c a l l y p e r f o r m s several c h e c k s o n y o u r files: 1. It c o m p a r e s t h e d a t e a n d t i m e o f t h e T P U file f o r e a c h u n i t u s e d b y t h e m a i n p r o g r a m in t h e p r o j e c t w i t h t h e u n i t ' s c o r r e s p o n d i n g P A S file. If t h e PAS file h a s c h a n g e d . M a k e r e c o m p i l e s it, c r e a t i n g a n e w ( u p d a t e d ) T P U file ( u n i t ) .
868
Part I I I — R e f e r e n c e s
2. It c h e c k s t o s e e w h e t h e r y o u ' v e c h a n g e d t h e i n t e r f a c e part o f a m o d i f i e d u n i t . If s o , M a k e r e c o m p i l e s all u n i t s u s i n g this u n i t . 3. It c h e c k s t o s e e w h e t h e r y o u ' v e c h a n g e d a n y I n c l u d e o r O B J files u s e d b y a n y u n i t s . If a T P U is o l d e r t h a n a n y o f t h e I n c l u d e o r O B J files M a k e l i n k s i n , it r e c o m p i l e s t h e u n i t .
Q REFERENCE
GLOSSARY a b s t r a c t t y p e — A s p e c i f i c k i n d o f b a s e t y p e d e s i g n e d t o b e u s e d strictly as a basis for o t h e r t y p e s . It h a s n o i n s t a n c e s , a n d t h u s c a n b e u s e d o n l y t o d e r i v e n e w t y p e s . It s p e c i f i e s a n i n t e r f a c e f o r all t y p e s d e r i v e d f r o m it. U s e a n abstract t y p e t o g r o u p c o m m o n c o d e . F o r e x a m p l e , if y o u h a v e several d i f f e r e n t c o l l e c t i o n t y p e s , t h e y c a n all i n h e r i t f r o m a s i n g l e abstract t y p e . A l s o k n o w n as formal class i n s o m e l a n g u a g e s . a c c e l e r a t o r — A n a c c e l e r a t o r is a " m i n i - m a c r o " c r e a t e d w i t h a k e y ( o r c o m b i n a t i o n o f keys) f o r m a k i n g m e n u s e l e c t i o n s . F o r e x a m p l e , y o u c a n d e f i n e a n a c c e l e r a t o r ( s u c h as S h i f t - D e l e t e ) t o r e p l a c e a m e n u s e l e c t i o n ( s u c h as EditCut). a c c e s s s p e c i f i e r — A k e y w o r d that c o n t r o l s a c c e s s t o d a t a m e m b e r s a n d m e t h o d s within user-defined types. T u r b o Pascal for W i n d o w s h a s o n e : private. S e e t h e i n d i v i d u a l d e f i n i t i o n s f o r private. a n c e s t o r — T h e t y p e that a d e s c e n d a n t t y p e i n h e r i t s f r o m . a t o m — I n t h e D D E p r o t o c o l , a w o r d v a l u e that r e p r e s e n t s a c h a r a c t e r string. A n a t o m is n o t c a s e - s e n s i t i v e . b a s e t y p e — D e f i n e s a c o m m o n i n t e r f a c e t o a g r o u p o f d e s c e n d a n t t y p e s . It g e n e r a l i z e s t h e i n t e n d e d u s e s f o r a h i e r a r c h y o f t y p e s . I n o t h e r w o r d s , it d e s c r i b e s t h e r a n g e o f m e s s a g e s that a n o b j e c t o f a t y p e c a n h a n d l e . A b a s e t y p e can also b e called an ancestor. b e h a v i o r — A n o t h e r n a m e for a m e t h o d declared within a type.
870
Part I I I — R e f e r e n c e s
b i n d i n g ( e a r l y ) — R e s o l v i n g a m e t h o d call at c o m p i l e - t i m e . S e e b i n d i n g (late). b i n d i n g ( l a t e ) — R e s o l v i n g a m e t h o d call at r u n - t i m e . W h e n y o u r e s o l v e a m e t h o d c a l l , y o u insert t h e c o d e t o d e t e r m i n e t h e a d d r e s s ( o r a n o t h e r r e f e r e n c e ) o f t h e m e t h o d d e f i n i t i o n at t h e p o i n t w h e r e t h e m e t h o d is s e n t a message. b i t m a p — A b i t m a p is a p i c t u r e , o r m o r e specifically, t h e d a t a r e p r e s e n t i n g a picture. b r o w s e r — A s o f t w a r e t o o l for i n s p e c t i n g o b j e c t h i e r a r c h i e s . b u i l t - i n t y p e — A t y p e ( s u c h as double, char, a n d s o o n ) i n c l u d e d ( o r b u i l t ) i n a l a n g u a g e . T h e c o m p i l e r a l r e a d y k n o w s h o w t o h a n d l e it, a n d d o e s n ' t h a v e t o l e a r n a b o u t it e a c h t i m e it e n c o u n t e r s a n i n s t a n c e o f o n e . c h a o s — S t o c h a s t i c (or r a n d o m ) behavior occurring in a deterministic system. c h a r a c t e r i s t i c — A n o t h e r n a m e for d a t a d e c l a r e d w i t h i n a t y p e . c l i p p i n g r e g i o n — A p o l y g o n a l o r elliptical s h a p e i n w h i c h a n y d r a w i n g o n a d i s p l a y c o n t e x t ' s virtual s u r f a c e c a n a p p e a r . T h e w i n d o w ' s c l i e n t a r e a is t h e default clipping region. c o m p o s i t i o n — I n c l u d i n g u s e r - d e f i n e d o b j e c t t y p e s as parts o f o t h e r o b j e c t types, rather than derivation (inheritance). constants — ObjectWindows defines n u m e r o u s constants to represent c o m m a n d m e s s a g e s ; b u t t o n , c h e c k b o x , a n d r a d i o b u t t o n states; e r r o r s ; c h i l d I D , n o t i f i c a t i o n , a n d s t r e a m s m e s s a g e s ; transfer flags; b i t m a p p e d fields; a n d Windows messages. T h e u s e o f c o n s t a n t s i m p r o v e s p r o g r a m r e a d a b i l i t y a n d m a k e s it e a s i e r for a p r o g r a m t o c h a n g e , if it n e e d s t o , i n r e s p o n s e t o c h a n g e s i n s u b s e q u e n t versions of Windows. See ObjectWindows constants in Reference B, " O b j e c t W i n d o w s C o n s t a n t s , " for m o r e i n f o r m a t i o n a n d a d e t a i l e d list o f constants. c o n s t r u c t o r — A s p e c i a l k i n d o f m e t h o d that initializes a t y p e . A constructor can have any legal n a m e n o t already in u s e , t h o u g h often the i d e n t i f i e r Init is u s e d :
Plant = object constructor Setup; end;
{ constructor }
I n T u r b o P a s c a l for W i n d o w s , y o u m u s t e x p l i c i t l y d e f i n e a n d call ( s e n d a message to) a constructor. A user-defined type c a n have any n u m b e r o f c o n s t r u c t o r s , b u t t h e y c a n ' t b e virtual b e c a u s e t h e v i r t u a l - m e t h o d m e c h a n i s m d e p e n d s o n t h e c o n s t r u c t o r t o set u p t h e l i n k t o t h e V M T (virtual m e t h o d t a b l e ) .
Q—Glossary
c o n t r o l s — U s e r interface devices. O b j e c t W i n d o w s supports the following controls: • Check boxes • C o m b o boxes • Edit controls • Group boxes • List b o x e s • MDI c l i e n t s • Push buttons • Radio buttons • Scroll bars • Static c o n t r o l s c u r s o r — T h e s h a p e o n t h e s c r e e n that r e p r e s e n t s t h e p o s i t i o n f o r t h e n e x t i n p u t . I n t e x t - b a s e d a p p l i c a t i o n s , a c u r s o r is e i t h e r a b l o c k o r a l i n e , o r s o m e t h i n g i n b e t w e e n . I n W i n d o w s a p p l i c a t i o n s , h o w e v e r , a c u r s o r is a 32-by-32 p i x e l b i t m a p . A W i n d o w s c u r s o r , t h e r e f o r e , c a n b e o n e o f m a n y d i f f e r e n t s h a p e s , a n d is a b i t m a p . d a t a h i d i n g — R e m o v i n g s o m e d a t a f r o m p u b l i c v i e w . A l s o k n o w n as abstraction.
data
data members—Characteristics of a type. D D E ( d y n a m i c d a t a e x c h a n g e ) — M i c r o s o f t W i n d o w s p r o t o c o l for letting applications share data. d e r i v a t i o n — A n o t h e r n a m e for inheritance. d e s c e n d a n t — A t y p e that i n h e r i t s t h e characteristics a n d b e h a v i o r s o f a n o t h e r type. d e s t r u c t o r — A s p e c i a l t y p e o f m e t h o d that p e r f o r m s c l e a n u p f o r a u s e r - d e f i n e d object type. I n T u r b o Pascal f o r W i n d o w s , a d e s t r u c t o r c a n h a v e a n y l e g a l n a m e n o t already in use:
Bridge = object constructor Create; { constructor } destructor Remove; { destructor } end; I n T u r b o P a s c a l f o r W i n d o w s , d e s t r u c t o r s c a n b e static o r v i r t u a l , a n d a t y p e c a n h a v e m o r e t h a n o n e d e s t r u c t o r . A d e s t r u c t o r c a n b e i n h e r i t e d just l i k e other methods.
871
872
Part I I I — R e f e r e n c e s
d i a l o g b o x — A n i n p u t s c r e e n (or w i n d o w ) f o r l e t t i n g a u s e r e n t e r i n f o r m a t i o n i n y o u r a p p l i c a t i o n . C a n b e b a r e - b o n e s Or c o n t a i n o t h e r W i n d o w s g r a p h i c a l e l e m e n t s (called controls). T h e resource data associated with a dialog b o x specifies the dialog b o x ' s s i z e , s c r e e n l o c a t i o n , a n d text l a b e l s . d i s p l a y c o n t e x t — T h e s u r f a c e o f t h e w i n d o w , w h i c h y o u m u s t specify i n o r d e r t o d i s p l a y text o r g r a p h i c s i n a w i n d o w . d i s p o s e — P r o c e d u r e for de-allocating objects allocated o n the h e a p :
Dispose(ShapePointer); A l t e r n a t i v e l y ( a n d p r e f e r a b l y ) , y o u s h o u l d call t h e d e s t r u c t o r i n s i d e t h e D i s p o s e call b y u s i n g t h e f o l l o w i n g e x t e n d e d s y n t a x t o c l e a n u p a n o b j e c t :
PtrSomeObject = "SomeObject; SomeObject = object constructor Init; destructor Done; end; var P : PtrSomeObject; Dispose(P, Done); { call the destructor to clean up properly } DLL ( d y n a m i c l i n k l i b r a r i e s ) — A library o f i n d e x e d f u n c t i o n s a n d p r o c e d u r e s . E x e c u t a b l e m o d u l e s o f c o d e l i n k e d i n t o a n a p p l i c a t i o n at r u n - t i m e . DLLs allow programmers to develop and maintain independent program c o m p o n e n t s . S i m i l a r t o u n i t s i n t h e i r m o d u l a r i t y , t h e y are m o r e p o w e r f u l because they can be 1. L i n k e d i n t o a n a p p l i c a t i o n at r u n - t i m e 2. S h a r e d b y m a n y c o n c u r r e n t l y e x e c u t i n g p r o g r a m s 3. W r i t t e n i n a variety o f l a n g u a g e s , r e g a r d l e s s o f t h e l a n g u a g e u s e d t o access the D L L d y n a m i c b i n d i n g — A n o t h e r n a m e for late binding.
S e e b i n d i n g (late).
d y n a m i c m e t h o d t a b l e ( D M T ) — A m e t h o d t a b l e n e w t o T u r b o P a s c a l for W i n d o w s for d i s p a t c h i n g l a t e - b o u n d m e t h o d s . W h e r e a s t h e V M T (virtual m e t h o d t a b l e ) e n c o d e s a p o i n t e r for all l a t e - b o u n d m e t h o d s i n a n o b j e c t t y p e , t h e V M T e n c o d e s o n l y t h e m e t h o d s that w e r e o v e r r i d d e n i n t h e o b j e c t t y p e . If a d e s c e n d a n t t y p e o v e r r i d e s o n l y a f e w v i r t u a l m e t h o d s , a D M T u s e s less s p a c e than a V M T . See V M T .
Q—Glossary
d y n a m i c v a r i a b l e — A variable allocated o n the h e a p a n d m a n i p u l a t e d with pointers. d y n a m i c v a r i a b l e a l l o c a t i o n — C r e a t i n g a n d d e s t r o y i n g v a r i a b l e s at r u n - t i m e r a t h e r t h a n at c o m p i l e - t i m e . S e e b i n d i n g (late). e n c a p s u l a t i o n — C o m b i n i n g d a t a (characteristics) w i t h t h e m e t h o d s (behaviors) f o r m a n i p u l a t i n g it; o r g a n i z i n g c o d e i n t o u s e r - d e f i n e d t y p e s . e v e n t — A n o c c u r r e n c e that affects a p r o g r a m f r o m t h e o u t s i d e w o r l d . S o m e e x a m p l e s are k e y s t r o k e s , m o u s e - b u t t o n c l i c k s , a c h a r a c t e r f r o m a serial p o r t , a n d o c c u r r e n c e s t r i g g e r e d b y t h e s y s t e m s o f t w a r e ( D O S , B I O S ) , s u c h as a " t i m e r tick." GDI—See Windows G D I . Global a n d local m e m o r y — Y o u r applications c a n allocate m e m o r y blocks in either o f t w o areas: the global or the local h e a p . T h e g l o b a l h e a p is all t h e m e m o r y that W i n d o w s " c l a i m s " w h e n y o u r u n it. T h e g l o b a l h e a p is s h a r e d b y W i n d o w s , W i n d o w s a p p l i c a t i o n s , a n d t h e " g l o b a l " m e m o r y b l o c k s a l l o c a t e d b y W i n d o w s a p p l i c a t i o n s . G l o b a l m e m o r y is p o w e r f u l b e c a u s e it's s y s t e m - s i z e d : m e m o r y w i t h i n a n d b e y o n d y o u r a p p l i c a t i o n s . A g l o b a l m e m o r y b l o c k c a n b e as l a r g e as 1 M i n W i n d o w s s t a n d a r d m o d e a n d 6 4 M in 386-enhanced m o d e . A global m e m o r y block can b e u s e d to access the data in other programs. T h e l o c a l h e a p is m e m o r y a c c e s s i b l e o n l y b y a s p e c i f i c i n s t a n c e o f y o u r a p p l i c a t i o n . I n o t h e r w o r d s , it's " p r i v a t e " t o y o u r a p p l i c a t i o n a n d just l i k e t h e h e a p y o u ' v e b e e n u s e d t o i n T u r b o P a s c a l ( b e f o r e W i n d o w s ) . It's l i m i t e d t o w h a t e v e r ' s left o f t h e 6 4 K d a t a s e g m e n t after y o u r a p p l i c a t i o n ' s u s e d s o m e o f it f o r a stack a n d its o w n g l o b a l v a r i a b l e s . T h e l o c a l h e a p is o n l y 8 K b y d e f a u l t , b u t y o u c a n a d j u s t its size u s i n g e i t h e r t h e $M c o m p i l e r d i r e c t i v e o r b y w a y o f t h e T u r b o Pascal f o r W i n d o w ' s I D E o p t i o n / C o m p i l e r / M e m o r y S i z e m e n u s . GUI ( g r a p h i c a l u s e r i n t e r f a c e ) — W i n d o w s is a g r a p h i c a l u s e r i n t e r f a c e ( G U I ) . E v e r y t h i n g — t e x t , d o t s , fills, a n d p i c t u r e s — i s t r e a t e d b y W i n d o w s n o t as A S C I I c h a r a c t e r s ( D O S - s t y l e ) b u t as p i x e l s t u r n e d o n a n d o f f i n a d i s p l a y c o n t e x t (the W i n d o w s n a m e for a painting surface). h a n d l e — A n a m e ; represents a pointer to a pointer to a m e m o r y block. h e a p — T h e free m e m o r y available t o a n a p p l i c a t i o n . T h e g l o b a l h e a p c o n t a i n s m e m o r y available t o all a p p l i c a t i o n s . T h e l o c a l h e a p c o n t a i n s m e m o r y available only to a specific application. h i e r a r c h y — A g r o u p o f types derived f r o m a base type. T u r b o Pascal for W i n d o w s implements single inheritance. Although an ancestor can have m a n y descendants, and a descendant can have many ancestors, a descendant can have only o n e i m m e d i a t e ancestor. See the following illustration.
873
874
Part I I I — R e f e r e n c e s
01
Base 02
Derived from 01 04
03
Derived from 02
Derived from 01
05
Derived from 01
i c o n — A n icon is t h e g r a p h i c a l s c r e e n e l e m e n t that represents y o u r a p p l i c a t i o n p r o g r a m ' s state. Y o u select a n icon f r o m t h e p r o g r a m m a n a g e r ' s w i n d o w t o run p r o g r a m s , f o r e x a m p l e . A n icon, t o o , is a b i t m a p . i m p l e m e n t a t i o n — D e s c r i b e s how a n o b j e c t t y p e b e h a v e s . Y o u c a n c o m p i l e , b u t n o t link, c o d e w i t h just t h e interface d e s c r i p t i o n . T h e r e f o r e , y o u c a n create different implementations later a n d l i n k t h e m in t h e n , w i t h o u t recompiling the rest o f t h e p r o j e c t . B y s e p a r a t i n g t h e interface f r o m t h e implementation, you isolate b u g s a n d m a k e e x p e r i m e n t a t i o n easier. i n h e r i t a n c e — O r g a n i z i n g u s e r - d e f i n e d t y p e s into hierarchies. N o t e that T u r b o P a s c a l f o r Windows implements s i n g l e inheritance. In other words, a descend a n t c a n have o n l y o n e immediate ancestor, as s h o w n in t h e f o l l o w i n g illustration. 04
Base 06
Derived from 04 08
07
Derived from 04
A new base Derived from 04
09
i n i t i a l i z a t i o n — S e t t i n g a variable o r instance
o f a t y p e t o a specific v a l u e ,
i n s t a n c e — A variable o f a t y p e . i n t e r f a c e — I n T u r b o Pascal f o r Windows,
the object definition.
T h e interface says, " H e r e ' s w h a t a t y p e l o o k s l i k e , a n d here are its b e h a v i o r s . " B u t it d o e s n ' t specify how t h e t y p e b e h a v e s . T h a t ' s left t o t h e implementation, w h i c h d e f i n e s t h e t y p e ' s specific behavior. T h e interface d e s c r i b e s w h a t a t y p e d o e s . T h e implementation d e s c r i b e s how t h e t y p e w o r k s . list b o x — A list b o x is a sort o f w i n d o w (it's d e f i n e d b y a rectangle o n t h e s c r e e n ) that s h o w s t h e u s e r a list o f information. T h i s information Can b e integers, strings, a n d s o o n . T h e u s e r c a n c l i c k o n a list item, a n d t h e s e l e c t e d item c a n b e transferred into a n o t h e r variable o r c a n trigger o t h e r m e s s a g e s a n d a c t i o n s . local m e m o r y — S e e global and local memory.
Q—Glossary
MDI ( m u l t i p l e d o c u m e n t i n t e r f a c e ) — O b j e c t W i n d o w s supports t h e W i n d o w s Multi-document interface (MDI) s t a n d a r d , w h i c h a l l o w s a n a p p l i c a t i o n o r task t o w o r k s i m u l t a n e o u s l y w i t h m a n y o p e n d o c u m e n t s . T h i n k o f t h e s e d o c u m e n t s u s u a l l y as text, d a t a b a s e , o r s p r e a d s h e e t files. Several c o m p o n e n t s (or features) are c o m m o n t o any M D I application. Every M D I a p p l i c a t i o n h a s a m a i n w i n d o w ( c a l l e d a f r a m e w i n d o w ) , a n d w i t h i n t h e f r a m e w i n d o w a n invisible w i n d o w c a l l e d t h e M D I c l i e n t w i n d o w , w h i c h h o l d s M D I c h i l d w i n d o w s . T h e c l i e n t w i n d o w m a n a g e s ( b e h i n d t h e s c e n e s ) its M D I child w i n d o w s . T M D I W i n d o w ' s m e t h o d s primarily construct a n d m a n a g e child windows a n d process m e n u selections. T h e MDI f r a m e w i n d o w is t h e Main W i n d o w o f t h e multi-document
interface (MDI). m e n u — D i s p l a y s application options a n d allows the user to make selections. T h e m e n u ' s resource identifies the order a n d n u m b e r o f these o p t i o n s . m e s s a g e — T h e n a m e of a m e t h o d passed to an instance of an object type. W h e n y o u s e n d a m e s s a g e t o a n i n s t a n c e o f a n o b j e c t , y o u call o n e o f its m e t h o d s . T o s e n d a m e s s a g e t o a n i n s t a n c e o f a n o b j e c t , y o u specify t h e o b j e c t a n d t h e m e t h o d y o u w a n t t o i n v o k e . F o r e x a m p l e , if S o m e T y p e is a n i n s t a n c e o f a n o b j ect a n d I nit is a m e t h o d , t h e n t h e f o l l o w i n g s e n d s a n I nit m e s s a g e t o t h e o b j e c t :
SomeType.Init; m e t h o d — I n T u r b o Pascal f o r W i n d o w s , a p r o c e d u r e o r f u n c t i o n d e c l a r e d within an object, u s e d to access the data within the object. m o d e l — A mathematical representation o f s o m e aspect o f the world. n e w — A p r o c e d u r e f o r a l l o c a t i n g s p a c e f o r a t y p e o n t h e h e a p a n d initializing t h e o b j e c t i n o n e o p e r a t i o n . N e w is i n v o k e d w i t h t w o p a r a m e t e r s : a p o i n t e r n a m e a n d a c o n s t r u c t o r call:
new(ArcPointer,Init(35,24,35)); o b j e c t — A n i n s t a n c e o f a n o b j e c t t y p e ; a r e c o r d that c a n i n h e r i t , c o n s i s t i n g o f data a n d m e t h o d s . o v e r r i d e — R e i m p l e m e n t , redefine. Used to describe the reimplementation o f m e t h o d s by object types. p i x e l — A d o t ; the smallest displayable e l e m e n t o f a c o m p u t e r screen. p o i n t e r — C o n t a i n s t h e a d d r e s s o f (that is, p o i n t s t o ) a v a r i a b l e . I n T u r b o Pascal for W i n d o w s , designated by ^ :
IntPointer : "Integer; p o l y m o r p h i c c o l l e c t i o n s — T h e O b j e c t W i n d o w s TCollection o b j e c t is a n abstract t y p e f o r " c o l l e c t i n g " d a t a .
875
876
Part I I I — R e f e r e n c e s
TCollection o b j e c t s c a n size t h e m s e l v e s d y n a m i c a l l y at r u n - t i m e , a n d t h e y c a n b e p o l y m o r p h i c . T h u s , a c o l l e c t i o n c a n g r o w as y o u w a n t it t o , w i t h o u t y o u r c h a n g i n g a n y c o d e . A n d b e c a u s e it's p o l y m o r p h i c , y o u c a n p u t a n y k i n d o f o b j e c t ( a n d e v e n n o n o b j e c t s ) i n it. Y o u c a n e v e n m i x t h e o b j e c t t y p e s w i t h i n a single collection! B e c a u s e a c o l l e c t i o n u s e s u n t y p e d p o i n t e r s , it d o e s n ' t n e e d t o k n o w a n y t h i n g a b o u t t h e o b j e c t s it's g i v e n t o p r o c e s s . It just s t o r e s t h e m a n d g i v e s them back. p o l y m o r p h i c t y p e — A type not k n o w n until run-time. p o l y m o r p h i s m — S i n g l e interface, m a n y i m p l e m e n t a t i o n s . Specifically, calling a virtual m e t h o d f o r a v a r i a b l e w h o s e p r e c i s e t y p e isn't k n o w n at c o m p i l e t i m e . T h e b e h a v i o r is e s t a b l i s h e d at r u n - t i m e b y w a y o f late b i n d i n g . p r i v a t e — A n y m e m b e r s f o l l o w i n g private c a n b e a c c e s s e d o n l y b y f u n c t i o n s within the same unit. r e s o u r c e — A n o t h e r n a m e f o r t h e g r a p h i c a l e l e m e n t s that c o m p o s e y o u r W i n d o w s application. B e c a u s e resources (cursor shape, m e n u s , icons, a n d s o o n ) a r e similar i n all y o u r a p p l i c a t i o n s , it m a k e s s e n s e t o s t o r e t h e m i n files outside your source c o d e a n d link t h e m with your source c o d e w h e n y o u n e e d t h e m . T h i s p r o c e s s m a k e s t h e m easy t o m o d i f y w i t h o u t a f f e c t i n g y o u r a p p l i c a tion code. Resources are data characterized by the following types: •
Accelerators
•
Bitmaps
•
Cursors
•
Icons
• Dialog boxes •
Menus
•
Strings
s c o p e — T h e l i f e t i m e a n d accessibility o f a v a r i a b l e . D e f i n e s w h i c h parts o f a p r o g r a m c a n access specific variables. F o r e x a m p l e , a variable declared within a f u n c t i o n is (by d e f a u l t ) l o c a l , a n d c a n b e a c c e s s e d o n l y b y c o d e w i t h i n t h e function. s c o p e (global)—Accessible by code within the program or application, s c o p e (local)—Accessible only by code within the function or procedure.
Q—Glossary
s t a t i c m e t h o d — A m e t h o d r e s o l v e d b y t h e c o m p i l e r at c o m p i l e - t i m e (see early binding). static i n s t a n c e — A n instance of an object type n a m e d in the v a r declaration (in T u r b o Pascal f o r W i n d o w s ) a n d a l l o c a t e d i n t h e d a t a s e g m e n t a n d o n t h e stack. s t r a n g e a t t r a c t o r — I n p h a s e s p a c e , a n attractor is a p o i n t o r limit c y c l e i n a d y n a m i c s y s t e m , w h i c h d r a w s o r attracts a s y s t e m . I n o t h e r w o r d s , as t h e s y s t e m c h a n g e s state, it c a n r e a c h e q u i l i b r i u m (settle d o w n ) t o a p o i n t o r a c y c l e . A s t r a n g e attractor is a n attractor that's " b r o k e n u p " o r f r a g m e n t e d i n p h a s e s p a c e . It r e p r e s e n t s a s y s t e m w h o s e o r d e r , w h e n p l o t t e d i n a t i m e - s e r i e s , isn't o b v i o u s , b u t s h o w s itself i n a s h a p e (an o r d e r ) i n p h a s e s p a c e . s t r e a m — A s t r e a m is a c o l l e c t i o n o f o b j e c t s o n its w a y t o s o m e d e v i c e : a file, port, E M S , and so o n . s t r i n g s — ( n u l l - t e r m i n a t e d a n d T u r b o P a s c a l ) ; t h e W i n d o w s A P I r e q u i r e s that strings b e n u l l - t e r m i n a t e d , t h e f o r m a t u s e d b y C . I n o t h e r w o r d s , a string is r e p r e s e n t e d as a s e q u e n c e o f c h a r a c t e r s t e r m i n a t e d b y a N U L L ( # 0 ) . T u r b o P a s c a l f o r W i n d o w s s t o r e s n u l l - t e r m i n a t e d strings as arrays o f c h a r a c t e r s .
type NTstring = array[0..79] of Char; A n u l l - t e r m i n a t e d string i n T u r b o Pascal f o r W i n d o w s c a n b e as l o n g as 6 5 , 5 3 5 c h a r a c t e r s (a l i m i t a t i o n i m p o s e d b y D O S a n d W i n d o w s ) . T u r b o Pascal s t o r e s its s t a n d a r d strings i n t h e string t y p e : a l e n g t h b y t e f o l l o w e d b y a s e q u e n c e o f as m a n y as 2 5 5 c h a r a c t e r s .
type TPstring = string[80]; B e c a u s e W i n d o w s d o e s n ' t r e c o g n i z e T u r b o Pascal s t r i n g s , y o u r a p p l i c a t i o n m u s t e i t h e r u s e n u l l - t e r m i n a t e d strings e x c l u s i v e l y o r c o n v e r t a n y Pascal strings t o n u l l - t e r m i n a t e d b e f o r e p a s s i n g t h e m t o W i n d o w s (to d i s p l a y , f o r example). T h e strings u n i t s u p p l i e d b y T u r b o Pascal f o r W i n d o w s p r o v i d e s t h e conversion functions and a complete manipulation package for handling nullt e r m i n a t e d s t r i n g s . S e e strings i n t h e r e f e r e n c e s e c t i o n f o r d e t a i l s . strings ( r e s o u r c e ) — T e x t displayed by application m e n u s , dialog b o x e s , error m e s s a g e s , a n d s o o n . S t r i n g s d o n ' t h a v e t o b e s p e c i f i e d as r e s o u r c e s , b u t m a i n t a i n i n g t h e m as r e s o u r c e s h e l p s k e e p y o u r s p e c i f i c a p p l i c a t i o n c o d e a n d its v i s u a l a s p e c t s s e p a r a t e .
877
878
Part I I I — R e f e r e n c e s
s t r u c t u r e d p r o g r a m m i n g — C o m b i n e s t w o ideas: 1. Structured program flow. I n o t h e r w o r d s , t h e flow o f c o n t r o l o f a p r o g r a m is d e t e r m i n e d b y t h e s y n t a x o f t h e p r o g r a m c o d e . 2. Invariants.
A s s e r t i o n s that h o l d every t i m e c o n t r o l r e a c h e s t h e m .
t y p e — T e l l s t h e r a n g e o f v a l u e s ( o r states) a v a r i a b l e c a n a s s u m e a n d t h e o p e r a t o r s that y o u c a n a p p l y t o it. E v e r y t h i n g y o u c a n k n o w a b o u t a "class o f o b j e c t s " that a v a r i a b l e o r i n s t a n c e c a n r e p r e s e n t . F o r e x a m p l e , a n i n t e g e r t y p e is a n u m b e r w i t h i n t h e r a n g e - 3 2 7 6 8 . . . 3 2 7 6 7 a n d is r e p r e s e n t e d b y a s i g n e d 16-bit f o r m a t . A b y t e is a n u m b e r w i t h i n t h e r a n g e 0 . . . 2 5 5 a n d is r e p r e s e n t e d b y a n u n g r o u p e d 8-bit f o r m a t . t y p e e x t e n s i b i l i t y — T h e ability t o a d d f u n c t i o n a l i t y t o c o d e . Y o u d e r i v e n e w t y p e s ( t h r o u g h i n h e r i t a n c e ) a n d a d d o r m o d i f y b e h a v i o r s a n d characteristics t o suit y o u r n e e d s . u n i t — I n T u r b o Pascal f o r W i n d o w s , a c o l l e c t i o n o f c o n s t a n t s , d a t a t y p e s , v a r i a b l e s , p r o c e d u r e s , a n d f u n c t i o n s that a r e s e p a r a t e l y c o m p i l e d . If d a t a m e m b e r s i n a t y p e a r e d e c l a r e d after t h e k e y w o r d , private, a n y f u n c t i o n , m e t h o d , o r p r o c e d u r e w i t h i n a u n i t c a n a c c e s s it, b u t n o f u n c t i o n s , m e t h o d s , or procedures outside the unit can. v i r t u a l m e t h o d — A m e t h o d r e s o l v e d b y t h e c o m p i l e r at r u n - t i m e . ( S e e late binding.) I n T u r b o P a s c a l f o r W i n d o w s , y o u d e c l a r e a virtual m e t h o d b y a d d i n g t h e k e y w o r d , virtual, after t h e m e t h o d :
procedure Show; virtual; u s e r - d e f i n e d t y p e — A s i n g l e s t r u c t u r e c o n t a i n i n g t h e characteristics a n d b e h a v i o r s for t h e t y p e . I n T u r b o Pascal for W i n d o w s , w e call it a n object. T h e c o m p i l e r treats this t y p e t h e w a y it treats a b u i l t - i n t y p e . VMT ( v i r t u a l m e t h o d t a b l e ) — I n T u r b o Pascal ( o b j e c t ) h a s a V M T that c o n t a i n s i n f o r m a t i o n a b o u t a n d a p o i n t e r t o t h e c o d e i m p l e m e n t i n g e a c h o f its instance o f a type sends a message to a constructor, cally e s t a b l i s h e s a l i n k t o t h e V M T .
for W i n d o w s , e a c h t y p e t h e t y p e , i n c l u d i n g its size virtual m e t h o d s . W h e n a n the constructor automati-
Each type has o n e V M T . Each instance o f a type links t o the type V M T . Important: Y o u m u s t n o t s e n d a m e s s a g e t o a virtual m e t h o d b e f o r e s e n d i n g a m e s s a g e t o its c o n s t r u c t o r ! T u r b o P a s c a l a l l o w s y o u t o u s e t h e { $ R + } s w i t c h t o c h e c k for t h e p r o p e r c o n s t r u c t i o n o f a n i n s t a n c e o f a t y p e s e n d i n g a m e s s a g e t o a n o b j e c t t y p e . If t h e i n s t a n c e h a s n ' t b e e n p r o p e r l y i n i t i a l i z e d (via a constructor), a range-check error occurs.
Q—Glossary
W i n C r t — A T u r b o P a s c a l f o r W i n d o w s u n i t that i m p l e m e n t s a t e r m i n a l - l i k e text s c r e e n i n a w i n d o w . If y o u r a p p l i c a t i o n s u s e WinCrt, t h e y d o n ' t h a v e t o c o n t a i n a n y W i n d o w s - s p e c i f i c c o d e . T h i s u n i t is u s e f u l f o r r e i m p l e m e n t i n g e x i s t i n g T u r b o Pascal t e x t - b a s e d a p p l i c a t i o n s i n W i n d o w s w i t h o u t a d d i n g a l o t o f e x t r a code. W i n d o w s G r a p h i c s D e v i c e I n t e r f a c e ( G D I ) — T h e W i n d o w s G D I allows y o u t o w r i t e a p p l i c a t i o n s that d i s p l a y a n d m a n i p u l a t e g r a p h i c s i n d e p e n d e n t o f a s p e c i f i c d i s p l a y d e v i c e . Y o u c a n , f o r e x a m p l e , w r i t e a p p l i c a t i o n s that u s e t h e same c o d e , yet c a n b e displayed in E G A , V G A , o r Hercules m o d e s . W i n d o w s a c h i e v e s d e v i c e i n d e p e n d e n c e b y u s i n g v a r i o u s d e v i c e drivers that translate G D I f u n c t i o n calls i n t o c o m m a n d s that m a k e s e n s e t o t h e s p e c i f i c o u t p u t d e v i c e b e i n g u s e d . S o , y o u w r i t e c o d e as t h o u g h t h e o u t p u t d e v i c e d o e s n ' t m a t t e r , w h i c h ( i n g e n e r a l ) is h o w it is. W i n P r o c s , W i n T y p e s — T w o o f t h e t h r e e u n i t s p a c k a g e d w i t h T u r b o Pascal f o r W i n d o w s , w h i c h establish the interface b e t w e e n y o u r applications a n d W i n d o w s . WinTypes a n d WinProcs d e f i n e t h e T u r b o P a s c a l f o r W i n d o w s function types a n d processes for s e n d i n g messages directly to the W i n d o w s A P I . If y o u r a p p l i c a t i o n s e n d s m e s s a g e s t o t h e W i n d o w s A P I o n l y t h r o u g h O b j e c t W i n d o w s , it d o e s n ' t n e e d t o i n c l u d e t h e W i n T y p e s a n d W i n P r o c s u n i t s . W O b j e c t s — O n e o f the three units p a c k a g e d with T u r b o Pascal for W i n d o w s that e s t a b l i s h t h e i n t e r f a c e b e t w e e n y o u r a p p l i c a t i o n s a n d W i n d o w s . WOb j ects is t h e O b j e c t W i n d o w s o b j e c t library. w i t h — T u r b o Pascal for W i n d o w s k e y w o r d . Y o u c a n a c c e s s a t y p e ' s d a t a m e m b e r s b y u s i n g a d o t (AType. Member) o r a with s t a t e m e n t :
with AType do begin X:= 2; Y:= 3; Z:= 4; end;
879
R REFERENCE
REFERENCES, RESOURCES, AND NOTES
H e r e are a f e w o f t h e b o o k s I t h i n k y o u s h o u l d k n o w a b o u t , if y o u w a n t m o r e i n f o r m a t i o n a b o u t o b j e c t - o r i e n t e d p r o g r a m m i n g , T u r b o Pascal, W i n d o w s , m o d e l i n g , c h a o s t h e o r y , a n d o t h e r t o p i c s I've t o u c h e d o n i n this b o o k . T h i s list is o n l y a s a m p l e o f t h e m a n y w o r k s available o n t h e s e s u b j e c t s , b u t it reflects t h e b o o k s I h a v e o n m y shelf. M o s t o f t h e s e h a v e i n s o m e w a y c o n t r i b u t e d t o m y understanding of "tough" computing topics. A b r a h a m , R a l p h ; C h r i s t o p h e r S h a w . Dynamics—4 Volumes. Santa Cruz, C a l i f o r n i a : A e r i a l Press, 1 9 8 4 - 1 9 8 9 . A g r e a t i n t r o d u c t i o n a n d s t u d y o f d y n a m i c s u s i n g p i c t u r e s . If y o u w a n t t o really " g e t a f e e l " f o r c h a o s t h e o r y , c h e c k o u t this o n e . Starts w i t h p e r i o d i c b e h a v i o r a n d w o r k s t o w a r d t h e h a r d e r stuff: c h a o t i c a n d b i f u r c a t i o n b e h a v i o r . G r e a t p e r sonalized drawings. C a s t i , J o h n L. Alternate Realities: Mathematical Models of Nature and Man. N e w Y o r k : J o h n W i l e y a n d S o n s , 1989- A t h o r o u g h m a t h e m a t i c a l discussion of m o d e l i n g . Chapters o n formal representation, cellular automata; catastrophe theory, chaos, and the relationship of m o d e l i n g t o t h e way w e v i e w t h e w o r l d .
882
Part I I I — R e f e r e n c e s
C h e n e y , W a r d ; D a v i d K i n c a i d . Numerical Mathematics and Computing. M o n t e r e y , C a l i f o r n i a : B r o o k s / C o l e P u b l i s h i n g , 1 9 8 0 , 1 9 8 5 . If y o u ' r e w r i t i n g c o d e that u s e s n u m b e r s , y o u s h o u l d h a v e at least o n e g o o d n u m e r i c a l c o m p u t i n g b o o k at h a n d . T h i s is t h e o n e I g o b a c k t o t i m e a n d a g a i n , a n d I u s e d it several t i m e s w h i l e w r i t i n g Turbo Pascal for Windows Bible. F a s c i n a t i n g i n f o r m a t i o n a b o u t t h e t r u t h ( a n d n o t - s o truth) o f numerical processing by c o m p u t e r . D o n ' t use n u m b e r s w i t h o u t it. E c k e l , B r u c e . Using C + + . B e r k e l e y , C a l i f o r n i a : O s b o r n e M c G r a w - H i l l , 1 9 8 9 . A l t h o u g h t h e s u b j e c t o f Turbo Pascal for Windows Bible is o b j e c t o r i e n t e d p r o g r a m m i n g f o r W i n d o w s , T u r b o Pascal-style, y o u c a n l e a r n a l o t a b o u t O O P f r o m C + + . T h i s o n e is m y favorite C + + p r o g r a m m i n g g u i d e s : 6 0 0 p a g e s o f c o d e , d e s c r i p t i o n s , a n d i d e a s a b o u t O O P . It p r e c e d e s t h e T u r b o C + + c o m p i l e r , s o e x a m p l e s are d e v e l o p e d a r o u n d Z o r t e c h ' s C + + c o m p i l e r . Y o u c a n easily a p p l y t h e e x a m p l e s t o a n y C + + , h o w e v e r , a n d y o u c a n u s e B r u c e ' s i d e a s if y o u ' r e p r o g r a m m i n g in T u r b o Pascal. G o e s into m a n y a d v a n c e d topics. A g o o d b o o k to e x p l o r e a n d s t u d y if y o u w a n t t o g e t t o t h e h e a r t o f o b j e c t - o r i e n t e d programming. E n t s m i n g e r , G a r y . Tao of Objects. R e d w o o d C i t y , C a l i f o r n i a : M & T B o o k s , 1 9 9 0 . M y first b o o k . A g e n t l e i n t r o d u c t i o n t o o b j e c t - o r i e n t e d p r o g r a m m i n g u s i n g T u r b o Pascal a n d C + + e x a m p l e s . P r e d a t e s T u r b o Pascal f o r W i n d o w s , b u t u s e f u l for T u r b o Pascal p r o g r a m m e r s w h o w a n t a n uncluttered introduction to O O P . G l e i c k , J a m e s . Chaos: Making a New Science. N e w Y o r k : V i k i n g Press, 1 9 8 7 . A g r e a t i n t r o d u c t i o n t o c h a o s t h e o r y . V e r y easy, f u n r e a d i n g . F o c u s e s as m u c h o n t h e p e o p l e w h o " r e d i s c o v e r e d " c h a o s as it d o e s o n t h e t h e o r y itself. A n y o n e i n t e r e s t e d i n c h a o s s h o u l d start h e r e . H o f s t a d t e r , D o u g l a s ; D a n i e l D e n n e t t . The Mind's I. N e w Y o r k : B a n t a m B o o k s , 1 9 8 1 . L i k e all o f H o f s t a d t e r ' s b o o k s , this o n e really g e t s y o u r b r a i n w o r k i n g . A c o l l e c t i o n o f stories a n d essays a b o u t self-reflection, selfc o n s c i o u s n e s s , r e c u r s i o n , m a c h i n e s w i t h s o u l s , scientific s p e c u l a t i o n s , a n d o t h e r m i n d - s t r e t c h i n g stuff. M e y e r , B e r t r a n d . Object-oriented Software Construction. E n g l e w o o d Cliffs, N e w Jersey: Prentice-Hall, 1988. A g o o d discussion about the issues a n d principles relating to software design using object-oriented techn i q u e s . O u t l i n e s t h e p a t h that l e a d s t o o b j e c t - o r i e n t e d n e s s a n d , g e n e r ally a t t e m p t s t o c o n v i n c e y o u t o p r o g r a m w i t h o b j e c t s . T h e s e c o n d h a l f o f t h e b o o k , u n f o r t u n a t e l y for T u r b o P a s c a l e r s , f o c u s e s e n t i r e l y o n M e y e r ' s l a n g u a g e , " E i f f e l , " m a k i n g it less u s e f u l t h a n it c o u l d h a v e b e e n . Worth a look, t h o u g h , because of the extensive study of design.
R—References, Resources, and Notes
O ' B r i e n , T i m . Turbo Pascal, The Complete Reference. Berkeley, California: Borland/Osborne McGraw-Hill, 1989. A g o o d reference for T u r b o Pascal. I n c l u d e s a g o o d introductory chapter o n object-oriented p r o g r a m m i n g T u r b o Pascal-style. P e t z o l d , C h a r l e s . Windows Programming, 2nd Edition. Redmond, W a s h i n g t o n : M i c r o s o f t P r e s s , 1 9 9 0 . T h i s is t h e classic w o r k o n W i n d o w s p r o g r a m m i n g . A first class " W i n d o w s B i b l e " C-style. If y o u w a n t t h e nitty-gritty details o f h o w a C p r o g r a m m e r attacks C , o r if y o u w a n t t o k n o w as m u c h as p o s s i b l e a b o u t W i n d o w s p r o g r a m m i n g , g e t this b o o k . I f o u n d it very u s e f u l i n w r i t i n g T u r b o P a s c a l f o r W i n d o w s c o d e . S e t h i , Ravi. Programming Languages: Concepts and Constructs. Reading, MA: Addison-Wesley, 1989. Excellent study o f the development, design, a n d c o n t e n t o f m o d e r n p r o g r a m m i n g l a n g u a g e s . I n p a r t i c u l a r , several fine chapters o n object-oriented p r o g r a m m i n g . G o o d discussions o f M o d u l a - 2 , C + + , a n d S m a l l t a l k . C h a p t e r s o n e n c a p s u l a t i o n , inherita n c e , f u n c t i o n a l p r o g r a m m i n g , l o g i c p r o g r a m m i n g , a n d several t o u g h , advanced chapters o n interpreters a n d l a m b d a calculus. Highly r e c o m m e n d e d for studying the d e v e l o p m e n t o f p r o g r a m m i n g languages. S h o u l d g i v e y o u a g o o d i d e a o f t h e p r o b l e m s that l a n g u a g e d e v e l o p e r s encounter. S t e w a r t , I a n . Does God Play Dice? The Mathematics of Chaos. N e w Y o r k : B a s i l Blackwell, 1989. In-depth study of the mathematics o f chaos, turbul e n c e , a n d s t r a n g e attractors. G o o d c o m b i n a t i o n o f history, m a t h e m a t ics, a n d p h i l o s o p h y . I n s p i r e d d i s c u s s i o n s o f l o g i s t i c m a p p i n g , L o r e n z & H e n o n attractors, a n d fractals. S w a n , T o m . Mastering Turbo Pascal 6. C a r m e l , I n d i a n a : H a y d e n B o o k s , 1 9 9 1 . Latest v e r s i o n o f T o m ' s f i n e series o n T u r b o P a s c a l . A g o o d r e f e r e n c e w i t h a lot o f c o d e a n d i n f o r m a t i o n a b o u t O O P . T u r b o P o w e r S o f t w a r e . S c o t t s V a l l e y , C a l i f o r n i a : Object Professional User's Manual, 1990. Three v o l u m e s of object-oriented discussion T u r b o Pascal-style. A c c o m p a n i e s t h e f i n e T u r b o P o w e r o b j e c t library f o r T u r b o Pascal 5.5 ( a n d l a t e r ) . C o m p l e t e s o u r c e c o d e f o r t h e library is i n c l u d e d , s o this p a c k a g e ( m a n u a l s a n d c o d e ) m a k e s a n e x c e l l e n t i n d e p t h resource for ideas about object-oriented p r o g r a m m i n g . Full o f g o o d c o d e a n d c o d i n g ideas for T u r b o Pascal p r o g r a m m e r s . V a s e y , P h i l , et al. Prolog+ + Programming Reference Manual. L o n d o n : Logic P r o g r a m m i n g A s s o c i a t e s L t d . , 1 9 9 0 . O n e o f t h o s e rare c r e a t u r e s : a p r o g r a m m i n g m a n u a l that really s h i n e s . I n a d d i t i o n t o s h o w i n g y o u h o w t o p r o g r a m i n P r o l o g + + , t h e o b j e c t - o r i e n t e d v e r s i o n o f P r o l o g , it c o m p a r e s object-oriented languages a n d discusses the key features of O O P . Available from Q u i n t u s C o m p u t e r Systems in M o u n t a i n View, California.
883
884
Part I I I — R e f e r e n c e s
Y o u r d o n , E . N . ; L.L. C o n s t a n t i n e . Structured Design. E n g l e w o o d Cliffs, N e w J e r s e y : P r e n t i c e - H a l l , 1 9 7 9 . A classic w o r k o n s t r u c t u r e d m e t h o d o l o g y by the gurus of the field.
Quotation Acknowledgments S A M S gratefully a c k n o w l e d g e s permission f r o m the following sources to reprint material in their control: I n t h e I n t r o d u c t i o n , I c e 9 P u b l i s h i n g f o r lyrics f r o m " B o x o f R a i n " b y R o b e r t H u n t e r . F r o m t h e a l b u m American
Beauty
by T h e Grateful D e a d . N e w York:
Warner Bros., Inc, 1970. I n C h a p t e r 1, M i c r o s o f t Press f o r l i n e s f r o m Programming
Windows,
2nd
E d i t i o n b y C h a r l e s P e t z o l d . R e d m o n d , W a s h i n g t o n : M i c r o s o f t Press, 1 9 9 0 . I n C h a p t e r 2, Q u e C o r p o r a t i o n f o r l i n e s f r o m Using
Borland
C + + by Lee
Atkinson and Mark Atkinson. Carmel, Indiana: Q u e Corporation, 1991. I n C h a p t e r 3, M & T B o o k s f o r l i n e s f r o m The Tao of Objects R e d w o o d City, California: M & T B o o k s , 1990.
by Gary Entsminger.
I n C h a p t e r 4, O s b o r n e - M c G r a w H i l l for l i n e s f r o m Windows
Programming
by
W i l l i a m H . M u r r a y , III a n d C h r i s H . P a p p a s . B e r k e l e y , C a l i f o r n i a : O s b o r n e M c G r a w Hill: 1990. I n C h a p t e r 5, M i c r o s o f t Press for l i n e s f r o m Programming Windows, Charles Petzold. R e d m o n d , W a s h i n g t o n : Microsoft Press, 1990.
2nd ed. by
I n C h a p t e r 6, P r e n t i c e - H a l l for l i n e s f r o m Object-oriented Software Construction b y B e r t r a n d M e y e r . E n g l e w o o d C l i f f s , N e w J e r s e y : P r e n t i c e - H a l l , 1 9 8 8 . I n C h a p t e r 7, V i n t a g e B o o k s ( R a n d o m H o u s e ) for l i n e s f r o m Godel, Bach:
An Eternal
Golden
Braid
Escher,
by Douglas Hofstadter. N e w York: Vintage
B o o k s , 1979. I n C h a p t e r 8, A d d i s o n - W e s l e y P u b l i s h i n g C o . for l i n e s from Raised only
to be Killed
by Research
by
Puppets
by Andrei Codrescu. Reading, Massachusetts,
Addison-Wesley, 1989. I n C h a p t e r 9 , C l a r k C i t y Press for l i n e s f r o m Just
Before
Dark
by J i m Harrison.
Livingston, M o n t a n a : Clark City Press, 1991. I n C h a p t e r 1 0 , W . H . F r e e m a n & C o . for l i n e s f r o m Aaron's
Code
by Pamela
M c C o r d u c k . N e w York: W . H . Freeman & C o . , 1991. I n C h a p t e r 1 1 , M & T B o o k s for l i n e s f r o m The Tao of Objects R e d w o o d City, California: M & T B o o k s , 1990.
by Gary Entsminger.
R—References, Resources, and Notes
I n C h a p t e r 1 2 , V i k i n g P e n g u i n for l i n e s f r o m Nature's J a m e s Gleick. N e w York: Viking Penguin, 1990.
Chaos
by Eliot Porter a n d
I n C h a p t e r 1 3 , V i n t a g e B o o k s ( R a n d o m H o u s e ) for l i n e s f r o m Godel, Bach:
An Eternal
B o o k s , 1979.
Golden
Braid
Escher,
by D o u g l a s Hofstadter. N e w York: Vintage
885
S
REFERENCE
Ascn C O D E CHARACTER SET
ASCII Dec
Value Hex
000 001 002
00 01 02
003 004
03 04
005 006 007 008
05 06 07 08
009 010 011 012 013 014 015 016 01^ 018
09 OA OB OC OD OE OF 10 11 12
ASCII
Character
ASCII Dec
Value Hex
019 020 021 022
13 14 15 16
023 024
17 18
025
19
026
1A
027
IB
028
1C
029
ID
030
IE
031
IF
032
20
033
21
034
22
035 036 037
23 24 25
ASCII
Character
888
Part III—References
ASCII Dec
Value Hex
ASCII
Character
038
26
039 040 041 042 043 044 045 046 047 048 049 050
27 28 29 2A 2B 2C 2D 2E 2F 30 31 32
&
/ 0 1 2
051 052
33 34
3 4
053 054
35 36
5 6
055 056
37 38
7 8
057 058
39 3A
9
059 060 061 062 063 064 065 066
3B 3C 3D 3E 3F 40 41 42
> ? @ A B
067 068
43 44
C D
069 070 071 072
45 46 47 48
E F G H
073 074 075 076 077 078
49 4A 4B 4C 4D 4E
I J K L M N
( ) * +
<
ASCII Dec
Value Hex
079 080 081 082
4F 50 51 52
O P Q R
083 084
53 54
S T
085 086 087 088
55 56 57 58
U V W X
089 090 091 092 093 094 095 096 097 098 099 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119
59 5A 5B 5C 5D 5E 5F 60 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F 70 71 72 73 74 75 76 77
Y Z [ \ ]
ASCII
Character
a b c d e f g h i j k 1 m n o p q r s t u v w
S — A S C I I C o d e C h a r a c t e r Set
ASCII Dec
Value Hex
ASCII
Character
ASCII Dec
Value Hex
161 162
Al A2
120
78
121
79
122
7A
123
7B
163 164
A3 A4
124
7C
165
A5
125
7D
166
A6
126
7E
167
A7
127
7F
168
A8
128
80
129 130 131 132
81 82 83 84
133 134
85 86
135 136
87 88
137 138
89 8A
169 170 171 172 173 174 175 176 177 178 179
A9 AA AB AC AD AE AF BO Bl B2 B3
139 140 141 142
8B 8C 8D 8E
143 144
8F 90
145 146
91 92
147 148
93 94
149 150
95 96
151
97
180
B4
181
B5
182
B6
183 184
B7 B8
185 186 187 188
B9 BA BB BC
189 190
BD BE
191 192
BF CO
193 194
CI C2
195 196
C3 C4
152
98
153
99
154
9A
155
9B
156
9C
197
C5
9D
198
C6
158
9E
159 160
9F AO
199 200
C7 C8
201
C9
157
ASCII
Character
889
890
Part III—References
ASCII Dec
Value Hex
202 203 204
CA CB CC
205 206 207 208
CD CE CF DO
209 210 211 212
Dl D2 D3 D4
213 214
D5 D6
215 216
D7 D8
217 218
D9 DA
219 220 221 222
DB DC DD DE
223 224 225 226
DF EO El E2
227 228
E3 E4
ASCII
Character
ASCII Dec
Value Hex
229 230
E5 E6
231 232
E7 E8
233 234 235 236 237 238 239 240 241 242
E9 EA EB EC ED EE EF FO Fl F2
243 244
F3 F4
245 246 247 248
F5 F6 F7 F8
249 250 251 252 253 254 255
F9 FA FB FC FD FE FF
ASCII
Character
Index
A abstract o b j e c t types, 156, 187, 506, 8 6 9 Abstract p r o c e d u r e s , 506 accelerators, 128, 6 9 6 , 8 6 9 access restricting, 385 specifier, 8 6 9 A c c e s s R e s o u r c e f u n c t i o n , 762 active w i n d o w , 5 A d d A t o m function, 726 AddFontResource function, 828 addresses, 581 error, 75 target, 6 2 0 A d j u s t W i n d o w R e c t p r o c e d u r e , 712 AdjustWindowRectEx procedure, 712 A l i g n m e n t palette, 2 5 7 allocating d y n a m i c variable, 8 7 3 AllocDStoCSAlias function, 768 A l l o c M u l t i S e l f u n c t i o n , 506 AllocResource function, 763 AllocSelector function, 769 Alternate edit m o d e , 12 ancestors, 8 4 , 526, 8 6 9 AnimatePalette p r o c e d u r e , 8 0 3 AnsiLower function, 779
AnsiLowerBuff function, 779 AnsiNext function, 779 AnsiPrev f u n c t i o n , 7 8 0 A N S I tables, 6 6 7 A n s i T o O e m function, 780 A n s i T o O e m B u f f procedure, 780 A n s i U p p e r f u n c t i o n , 781 A n s i U p p e r B u f f f u n c t i o n , 781 A n y P o p u p function, 671 A p p e n d M e n u f u n c t i o n , 681 A p p e n d routine, 628 a p p l i c a t i o n files, linking, 23 a p p l i c a t i o n o b j e c t s , 114-116, 214 A p p l i c a t i o n P r o g r a m m i n g Interface (API), 4 5 , 95 a p p l i c a t i o n s , 4 3 , 149-150 a p p e a r a n c e , 103 client, 354 c l o s i n g , 142 c o m p o n e n t s , 21 c o n s t r u c t i o n , 394 data sharing, 353-354 d e s i g n i n g , 383-384 e x e c u t i n g , 724 e x t e n s i o n , 394 inheriting, 112, 115 interacting w i t h w i n d o w s , 233 m e m o r y sharing, 279-280 n e w , 149
892
T u r
b o Pascal for W i n d o w s B i b l e
o b j e c t s , 114-116 object-oriented d e s i g n , 392-393 posting messages to, 694 server, 354 T a s k C o n t r o l , 271-272 task identifiers, 674 w i n d o w s , d e v e l o p i n g , 127 Arc f u n c t i o n , 8 3 0 architecture, 149 arcs, d r a w i n g , 8 3 0 a r g u m e n t s , invalid, 614 ArrangelconicWindows function, 659 arrays, 57, 61 p o i n t s , 187 A S C I I (American S t a n d a r d C o d e for I n f o r m a t i o n I n t e r c h a n g e ) character set, 887-890 c o d e s , 253 A S M reserved w o r d s , 625 A s s i g n C r t p r o c e d u r e , 516 ( : = ) a s s i g n m e n t o p e r a t o r , 64 atoms, 869 deleting, 726 strings character, 355 copying, 727 tables, 726 attaching r e s o u r c e s , 243 attractors p o i n t , 167 strange, 166-168, 171-174, 8 7 7 attributes device c o n t e x t , 312 display c o n t e x t , 313-314 file, 580-581 list b o x e s , 262 values, 720 A u t o I n d e n t e d i t o r c o m m a n d , 36 A u t o Save o p t i o n s , 26 A U T O E X E C . B A T file, 4
B b a c k g r o u n d c o l o r , 126 retrieving, 8 1 6 b a s e type o b j e c t s , 8 3 , 8 6 9 base units, 653 B a s i c A p p l i c a t i o n object, 122-124 Basiclnterface, 113, 117-121, 152,157 exiting, 143-146 o b j e c t , 114 b e e p i n g , 665 begin...end constructs, 64 BeginDeferWindowPos function, 659 BeginPaint function, 698 behavior, 8 6 9 b f _ X X X X constants, 499 binding dynamic, 90, 872 early, 9 0 , 8 7 0 late, 9 0 , 8 7 0 static, 9 0 BitBlt f u n c t i o n , 794 b i t m a p s , 128, 2 4 2 , 8 7 0 c o p y i n g , 794 creating, 795 discardable, 7 9 6 developer-generated, 253 d e v i c e - i n d e p e n d e n t , 314 editor, 2 7 6 moving, 800 resource, 798 size, 7 9 7 blocks c o p y i n g , 32 d e l e t i n g , 32 m e m o r y , 280-282 allocating, 284-286, 291 discarding, 2 8 6 fixed, 283 freeing, 291 g l o b a l , 290-293, 296
Index
l o c k i n g , 285 u n l o c k i n g , 283-285 m o v i n g , 32 r e a d i n g from disk, 33 structured, 386-388 writing t o disk, 33 B M P file, 2 7 6 B o o l e a n e x p r e s s i o n s , 7 0 , 605 B o o l e a n variable types, 52 borders d r a w i n g , 701 region, 848 boxes c h e c k , 416-419 C l o s e , 10 c o m b o , 427 d i a l o g , 128, 2 4 2 , 256-261, 434-435, 8 7 2 g r o u p , 270 list, 135, 138, 2 5 6 , 260-261, 8 7 4 attributes, 262 c o d e , 139 m e s s a g e , 141, 287-288 brackets, 64 BringWindowToTop procedure, 659 Browser C o p y c o m m a n d , 266 b r o w s e r s , 2 6 6 , 525-526, 8 7 0 brushes h a t c h e d , 323 logical, 8 2 3 stock, 322 buffers, 411 flushing, 413-414 pointer, 412 B u i l d C o m m D C B function, 730 built-in t y p e , 8 7 0 button controls, 656 check marks, 646 b u t t o n o b j e c t s , 262 buttons mouse, 680 o b j e c t s , 415 radio, 270 states, 4 9 9
bytes H i , 513 L o , 513 size allocation, 507
c calculating p o i n t s , 186 CallMsgFilter f u n c t i o n , 6 6 9 CallWindowProc function, 692 c a n c e l l i n g d i a l o g b o x e s , 263 C a n C l o s e methods, 408 c a p t i o n s , setting, 6 6 3 captures, m o u s e , 678 carets blinking, 636 destroying, 6 3 6 hiding, 637 moving, 637 position, 636 cascading w i n d o w s , 28 case statement, 65 types, 612 Catch function, 786 changes external, 389-391 internal, 389-391 ChangeClipboardChain function, 638 ChangeSelector function, 769 c h a o s t h e o r y m o d e l i n g , 171, 163-169, 8 7 0 C h a r types, 6 1 9 C h a r variable type, 53 character e x p r e s s i o n , 6 1 9 character strings, 354-355 characteristics, 8 7 0 characters A S C I I c o d e , 887-890 clearing, 517 copying b e t w e e n strings, 548 t o strings, 546
893
894
T u r b o Pascal for W i n d o w s B i b l e
illegal, 598 r e a d i n g from k e y b o a r d , 521 transmission, 7 3 0 widths, 829 c h e c k b o x e s , 416-419 E X E , 18 states, 4 9 9 storing, 4 1 8 c h e c k m a r k s , 682 button controls, 646 C h e c k D l g B u t t o n procedure, 646 C h e c k M e n u I t e m f u n c t i o n , 682 CheckRadioButton procedure, 646 child windows creating, 152, 712 e n u m e r a t i o n , 672 M D I , 226 m e n u , 216 p a r e n t , 671 ChildWindowFromPoint function, 671, 807 C h o r d function, 852 C h r f u n c t i o n , 54 circular u n i t s , 611 class i n f o r m a t i o n retrieving, 7 1 6 class n a m e s retrieving, 7 1 7 C l e a r c o m m a n d , 16 C l e a r C o m m B r e a k function, 730 clearing characters, 517 s c r e e n , 517 w i n d o w s , 197 client areas invalidating, 703 validating, 704 client c o o r d i n a t e s , 6 6 0 clients, 353 applications, 354, 370 area, 315 coordinates, 808 ClientToScreen procedure, 808
clipboard access, 3 4 6 closing, 638 data h a n d l e s , 641 d a t a i n , 345 e x c h a n g i n g data, 344-345 formats, 3 4 5 , 641 opening, 641 pasting from, 348-352 p l a c i n g text i n , 15 clipboards emptying, 639 formats, 6 3 9 ClipCursor procedure, 642 c l i p p e d d r a w i n g s , 314 c l i p p i n g r e g i o n s , 314, 8 0 0 - 8 0 1 , 8 7 0 C l o s e b o x , 10 C l o s e c o m m a n d , 8-10 CloseClipboard function, 638 C l o s e C o m m function, 730 CloseMetaFile function, 838 C l o s e S o u n d p r o c e d u r e , 773 CloseWindow procedure, 659 closing clipboards, 638 C l r E o l p r o c e d u r e , 517 C l r S c r p r o c e d u r e , 517 c m l t e r a t e m e t h o d , 156 c m X X X X c o n s t a n t s , 499-500 C M C o p y T e x t function, 347 C M F i l l e d R e c t a n g l e m e t h o d , 322 C M I t e r a t e m e t h o d , 162 C M N e w F i l e m e t h o d , 227 C M O p e n F i l e m e t h o d , 227 C M P e n S i z e m e t h o d , 303 C M P e n S t y l e m e t h o d , 303 code c o m b i n i n g w i t h data, 8 3 c o m p i l i n g , 243 list b o x e s , 139 sharing, 344 strange attractor, 172-174 c o d e segments, 46, 299 discardable, 2 9 9 m a x i m u m size, 6 0 6
Index
m o v e a b l e , 299 preloaded, 299 reloading, 299 codes A S C I I character set, 887-890 multitasking m o d e l system, 175-184 notification, 263 PAS (Pascal), 127 R E S ( R e s o u r c e ) , 127 stream h a n d l i n g , 196 c o l d links, 354 collections, 419 creating, 4 2 1 d e l e t i n g from, 4 2 2 for h a n d l i n g data, 188 index, 633 n o n t y p e d p o i n t e r s , 187 o v e r f l o w error, 6 3 3 p o l y m o r p h i c , 187, 8 7 6 size, 420-421 streams, 194 colors b a c k g r o u n d , 126, 7 1 0 , 8 1 6 inverting, 704 palettes, 8 0 4 logical, 8 0 4 R G B , 797 system, 711 text, 126 C o m b i n e R g n function, 845 c o m b o b o x e s , 4 2 7 , 652-653 c o n t r o l s , 137 C o m m a n d Set o p t i o n s , 26 commands B r o w s e r C o p y , 266 C l e a r , 16 C l o s e , 8-10 C o m p i l e / B u i l d , 21 C o m p i l e / C l e a r Primary File, 21 Compile/Compile, 20 C o m p i l e / I n f o r m a t i o n , 21 Compile/Make, 20 Compile/Primary File, 21
C o p y , 15 C u t , 15 Directories, 23 editor, 31-37 A u t o I n d e n t , 36 C o p y B l o c k , 32 C o p y Text, 32 C u t Text, 32 D e l e t e B l o c k , 32 F i n d Place M a r k e r , 3 7 M o v e , 32 O p e n File, 3 7 Paste from C l i p b o a r d , 33 R e a d B l o c k from D i s k , 33 Save File, 3 7 Set Place, 3 7 S h o w Last C o m p i l e Error, 37 Unindent, 37 Write B l o c k t o D i s k , 33 Exit, 14 F i n d , 16 G e t , 202 G o t o Line N u m b e r , 17 H e l p / T o p i c S e a r c h , 29 H e l p / U s i n g H e l p , 29-30 M a x i m i z e , 8-10 M i n i m i z e , 8-10 M o v e , 8-9 N e w , 11 N e x t , 10 O p e n , 11 O p t i o n s / C o m p i l e r , 22 Options/Linker, 23 O p t i o n s / O p e n , 26 Options/Preferences, 25 Options/Save, 26 Options/Save A s , 2 7 Paste, 15 Print, 12 Printer S e t u p , 13 Put, 2 0 0 R e d o , 15 R e p l a c e , 16 Restore, 8, 9
895
896
T
u
r
b
o
Pascal for W i n d o w s B i b l e
R u n / D e b u g g e r , 18 Run/Parameters, 19 Run/Hun, 18 Save, 12 Save All, 12 Save A s , 12 S e a r c h A g a i n , 16 Search/Find Error, 18, 620 S e a r c h / S h o w Last C o m p i l e Error, 18 Size, 8, 10 Switch T o , 9 U n d o , 14, 224 W i n d o w / A r r a n g e I c o n s , 28 W i n d o w / C a s c a d e , 28 W i n d o w / T i l e , 28 W i n d o w s / C l o s e All, 29 C o m m o n User Access (CUA),
384-385 c o m m a n d s , 26 c o m p a r i n g strings, 541-545 C o m p i l e I n f o r m a t i o n b o x , 21 C o m p i l e m e n u , 19-21 C o m p i l e - S t a t u s i n f o r m a t i o n b o x , 20 C o m p i l e / B u i l d c o m m a n d , 21 C o m p i l e / C l e a r Primary File c o m m a n d , 21 C o m p i l e / C o m p i l e c o m m a n d , 20 C o m p i l e / I n f o r m a t i o n c o m m a n d , 21 C o m p i l e / M a k e c o m m a n d , 20 Compile/Primary File c o m m a n d , 21 c o m p i l e r errors, 18, 37 c o m p i l e r directives, 30, 600 $ D + , 620 $ F + , 370
JG+,625 IL, 605 $M, 284 $ N + , 619 IR, 129, 243 c o n d i t i o n a l , 621 c o m p i l e r error m e s s a g e s , 591-626 C o m p i l e r - O p t i o n s d i a l o g b o x , 22
compilers Microsoft R e s o u r c e C o m p i l e r ,
255 o p t i o n s , 39-40 T P W C o m m a n d - l i n e , 38 c o m p i l i n g files, 21 c o n d i t i o n a l s y m b o l s , 621 c o n f i g u r a t i o n files, 27, 867 Configuration-Save-As d i a l o g b o x , 27 c o n f i g u r a t i o n s , saving, 26 c o n s t a n t s , 136, 870 b f _ X X X X , 499 c m X X X X , 499-500 c o X X X X , 501 device-capabilities, 841 e m X X X X , 501 file type, 617 flag, 503 i d _ X X X X , 502 integer, 598, 602 n f X X X X , 502 n u m e r i c , 602 return-flag, 563 stream, 195 string, 599, 617 s t X X X X , 502 S y s t e m unit, 554 t f _ X X X X , 503 types, 612 w b X X X X , 503 W i n D o s unit, 561-563 w m X X X X , 504 constructing a p p l i c a t i o n s , 394 o b j e c t s , 393 c o n s t r u c t o r s , 624, 870 identifiers, 623 static, 623 virtual, 623 c o n t e x t s , display, 872 C o n t r o l m e n u , 9-10 Control Menu box, 7 c o n t r o l o b j e c t s , 267
Index
c o n t r o l variables, 6 1 6 control w i n d o w I D v a l u e , 654 c o n t r o l s , 128, 136, 256-257, 267-268, 8 7 1 button, 646, 656 c o m b i n i n g , 274 c o m b o b o x , 137 dialog boxes, 257 text, 654-655 converting c o o r d i n a t e s , 315 strings t o l o w e r c a s e , 547 t o u p p e r c a s e , 552 c o o r d i n a t e m a p p i n g , 126 c o o r d i n a t e systems, 316 coordinates client, 6 6 0 , 8 0 8 c o n v e r t i n g , 315 r e d e f i n i n g , 188 C o p y B l o c k e d i t o r c o m m m a n d , 32 C o p y c o m m a n d , 15 C o p y T e x t e d i t o r c o m m a n d , 32 copying a t o m strings, 7 2 7 b i t m a p s , 794 r e g i o n s , 702 r e s o u r c e s , b e t w e e n files, 2 6 7 strings, 542-543 text, 15, 32 CopyMetaFile function, 838 CopyRect procedure, 842 C o p y T e x t f u n c t i o n , 347 C o u n t selections, 506 C o u n t V o i c e N o t e s function, 773 c o X X X X c o n s t a n t s , 501 Create G r o u p m o d e , 356, 367 C r e a t e B i t m a p f u n c t i o n , 795 C r e a t e B i t m a p I n d i r e c t f u n c t i o n , 795 CreateBrushlndirect function, 822 CreateCaret procedure, 636 CreateCompatibleBitmap function, 795
CreateCompatibleDC function, 314, 8 0 9 C r e a t e C u r s o r f u n c t i o n , 642 C r e a t e D C function, 810 CreateDialog function, 646 CreateDialoglndirect function, 647 CreateDialoglndirectParam function, 647 CreateDialogParam function, 648 C r e a t e D I B i t m a p f u n c t i o n , 314, 8 1 2 CreateDIBPatternBrush function, 822 C r e a t e D i r p r o c e d u r e , 572 CreateDiscardableBitmap function, 796 CreateEllipticRgn function, 845 CreateEllipticRgnlndirect function, 846 CreateFont function, 825, 828 CreateFontlndirect function, 825, 829 CreateHatchBrush function, 823 CreateIC function, 810 C r e a t e M e n u function, 683 CreateMetaFile function, 838 CreatePalette f u n c t i o n , 804 CreatePatternBrush function, 823 CreatePen function, 824 CreatePenlndirect function, 824 CreatePolygonRgn function, 846 CreatePolyPolygonRgn function, 846 CreateRectRgn function, 847 CreateRectRgnlndirect function, 847 CreateRoundRectRgn function, 847 CreateSolidBrush function, 823 C r e a t e W i n d o w f u n c t i o n , 712 C r e a t e W i n d o w E x f u n c t i o n , 713 C r e a t e W i n d o w m e s s a g e , 103 creating b i t m a p s , 795-796 c o l l e c t i o n s , 421 cursors, 642 dialog boxes, 257 file d i a l o g o b j e c t s , 198
897
898
T
u
r
b
o
Pascal for W i n d o w s B i b l e
files, 10, 224 h e l p w i n d o w s , 230-232 m e n u , 683 p e n s , 322 p o p - u p m e n u s , 683 subdirectories, 572 w i n d o w s applications, 3 C R T w i n d o w s , 519 C U A ( C o m m o n User Access), 384-385 c o m m a n d s , 26 edit m o d e , 12 cursor, 2 4 2 , 871 creating, 6 4 2 m o v e m e n t , 518-519 restoring, 14 s h a p e , 127 tabs, 36 cursors destroying, 6 4 3 input, 679 moving, 644 resources, 643 screen coordinates, 643 s h a p e , 644 C u r s o r T o p r o c e d u r e , 518 C u t c o m m a n d , 15 C u t T e x t e d i t o r c o m m a n d , 32
D $ D + c o m p i l e r directive, 6 2 0 data c o m b i n i n g w i t h c o d e , 83 declaring, 88 exchanging with clipboard, 344-345 h a n d l e s t o c l i p b o a r d , 641 h i d i n g , 871 m a n i p u l a t i o n , 82 m e m b e r s , 871 p l a c i n g i n c l i p b o a r d , 345 r e s o u r c e s , storing, 243
s e g m e n t s , 4 6 , 297-298 m a x i m u m size, 6 0 6 m o v a b l e , 284 sharing b e t w e e n a p p l i c a t i o n s , 353-354 data h a n d l e s , 705 data types, 50-56 data-flow d i a g r a m s , 386-387 data-sharing, 343 d a t e a n d t i m e , current, 568 setting, 570-571 D D E ( d y n a m i c data e x c h a n g e ) , 343-344, 353-354, 871 c o n v e r s a t i o n s , 355-356 D e b u g I n f o in E X E o p t i o n , 23 d e b u g g i n g , 18, 2 3 , 72-75, 587-589 declarations external, 6 9 , 3 7 0 forward, 69 procedure, 69 D e f D l g P r o c f u n c t i o n , 6 4 8 , 714 DeferWindowPos function, 660 D e f F r a m P r o c f u n c t i o n , 715 DefHookProc function, 669 DefineHandleTable function, 744, 7 7 0 D e f M D I C h i l d P r o c f u n c t i o n , 715 DefWindowProc function, 716 D e l e t e B l o c k e d i t o r c o m m a n d , 32 DeleteAtom function, 726 D e l e t e D C f u n c t i o n , 811 D e l e t e M e n u function, 683 DeleteMetaFile function, 838 DeleteObject function, 820 deleting atoms, 726 b l o c k s , 32 items from c o l l e c t i o n , 4 2 2 derivation, 871 derived type, 8 4 d e s c e n d a n t , 871 d e s i g n i n g for c h a n g e , 389-391 designs o b j e c t - o r i e n t e d , 388 structured, 3 8 6
Index
d e s k t o p files, 8 6 7 DestroyCaret procedure, 636 DestroyCursor function, 643 destroying carets, 6 3 6 cursors, 6 4 3 m e n u s , 683 modeless dialog boxes, 716 destroying editors, 228 DestroyMenu function, 683 DestroyWindow function, 716 destructors, 6 2 3 d e v i c e c o n t e x t attributes, 312 device points, 808 d e v i c e capabilities c o n s t a n t s , 8 4 1 dialog b o x units, 657 d i a l o g b o x e s , 128, 2 4 2 , 256-261, 434-435, 6 6 5 , 8 7 2 base units, 653 c a n c e l l i n g , 263 captions, 658 C o m p i l e r - O p t i o n s , 22 Configuration-Save-As, 2 7 c o n t r o l h a n d l e s , 654 control objects, 267 controls, 257 creating, 2 5 7 Directories, 23 Error A d d r e s s , 75 F i l e - O p e n , 11 File-Save-As, 12 Find-Error, 18, 7 4 , 589 Find-Text, 16 G o t o L i n e N u m b e r , 17 L i n k e r - O p t i o n s , 23 messages in, 257 m o d a l , 649-650 terminating, 6 5 3 m o d e l e s s , 646-648 destroying, 7 1 6 messages, 656 O p e n - C o n f i g u r a t i o n - F i l e , 26 Parameters, 19 Preferences, 25
Primary File, 20-21 private w i n d o w class, 6 4 8 text, 6 5 8 c o n v e r t i n g t o string v a l u e , 6 5 7 Replace-Text, 5, 16-17 Select-Printer, 13 Task-List, 9 DialogBox function, 649 DialogBoxIndirect function, 649 DialogBoxIndirectParam function, 650 DialogBoxParam function, 650 d i a l o g s , 265 d e f i n i n g , 266 file, 134-135 executing, 227 File O p e n , 135 messages, 257 m o d a l , 130-131 m o d e l e s s , 130 windows, 5 directives, i n l i n e , 6 9 directories current, 573 listing, 651 n a m e s , 24 removing, 629 subdirectories, 572 Directories c o m m a n d , 23 Directories d i a l o g b o x , 23 Directories list b o x e s , 28 disabling input keyboard, 666 m o u s e , 666 m e n u items, 227 print c o m m a n d , 12 discarding m e m o r y blocks, 286 d i s c o v e r i n g o b j e c t s , 394-395, 400-401 disk drives, 574 disks full, 6 0 0 reading, 629
899
900
T u r r j )
° Pascal for W i n d o w s B i b l e
r e a d i n g b l o c k s f r o m , 33 user, 224 writing, 6 3 0 writing b l o c k s t o , 33 D i s k S i z e p r o c e d u r e , 574 DispatchMessage function, 692 display area, filling, 796 display c o n t e x t s , 302-305, 8 7 2 , 701-702 attributes, 126, 313-314 P a i n t D C , 192 surface, 314 D i s p o s e S t r p r o c e d u r e , 506 DlgDirList f u n c t i o n , 651 D l g D i r L i s t C o m b o B o x f u n c t i o n , 651 DlgDirSelect function, 652 DlgDirSelectComboBox function, 652-653 D L L ( d y n a m i c link libraries), 8 7 2 dMenuIndirect function, 688 D M T ( d y n a m i c m e t h o d t a b l e ) , 872 D O reserved w o r d , 6 0 6 D o n e W i n C r t p r o c e d u r e , 518 DOS
p e n , 3 0 6 , 322 text, 126-127, 6 9 9 t o o l s , 304-306, 322 drawing m o d e , 817 d r a w i n g s , c l i p p e d , 314 DrawingWindow, 307 D r a w M e n u B a r p r o c e d u r e , 684 DrawText function, 699 drives, 6 2 9 D S K d e s k t o p file, 8 6 7 dynamic binding, 90, 872 i n d e x m e t h o d , d u p l i c a t e d , 625 links, 3 7 0 o b j e c t s , 91 styles, 91-92 systems, 169-170 variables, 9 2 , 8 7 3 d y n a m i c data e x c h a n g e ( D D E ) , 343, 871 d y n a m i c link libraries ( D L L ) , 2 9 8 , 344, 369-380, 8 7 2 d y n a m i c m e t h o d table ( D M T ) , 872
file streams, 2 0 0 f u n c t i o n calls, 583 functions, 627 streams, 2 0 0 v e r s i o n n u m b e r , 584 D O S 3 C a l l p r o c e d u r e , 761 D o s E r r o r variable, 567 D o s V e r s i o n f u n c t i o n , 584 D O W N T O reserved w o r d , 6 0 9 DPtoLP function, 808 D r a w F o c u s R e c t p r o c e d u r e , 6 9 9 , 852 Drawlcon function, 699 drawing arcs, 8 3 0 b o r d e r s , 701 figures, 322-323 f u n c t i o n s , 327-340 g r a p h i c s , 126-127 icons, 699 lines, 831
E early b i n d i n g , 9 0 , 8 7 0 edit fields, 256 Edit m e n u s , 14-15 edit m o d e s Alternate, 12 C U A , 12 Edit w i n d o w , 5-6 C o n t r o l m e n u , 9-10 default size, 9 E d i t o r O p t i o n s g r o u p , 25 editors, 3 1 , 222-223 bitmap, 276 destroying, 228 File w i n d o w , 224-225 M D I , 233 r e s o u r c e , 244-255 Ellipse f u n c t i o n , 8 5 2
Index
e m X X X X c o n s t a n t s , 501 EmptyClipboard function, 346, 638 EnableHardwarelnput function, 666 EnableMenuItem function, 684 EnableMenuItems m e t h o d , 227 EnableWindow function, 676 e n c a p s u l a t i o n , 82-84, 8 7 3 EndDeferWindowPos procedure, 660 EndDialog procedure, 653 EndPaint procedure, 700 E n u m C h i l d W i n d o w s function, 672 EnumClipboardFormats function, 639 e n u m e r a t e d variable types, 54 EnumFonts function, 829 EnumMetaFile function, 839 E n u m O b j e c t s function, 824 E n u m P r o p s f u n c t i o n , 705 E n u m T a s k W i n d o w s f u n c t i o n , 672 E n u m W i n d o w s function, 672 EqualRect function, 842 EqualRgn function, 848 equations linear, 163 logistic, 170 Erase r o u t i n e , 6 2 8 Error A d d r e s s d i a l o g b o x , 75 error m e s s a g e s c o m p i l e r , 591-626 r u n - t i m e , 5 9 1 , 626-632 errors, 4 0 8 c o n d i t i o n s , 501 critical, 621 d e t e c t i o n , 501 heap, 298 INLINE, 619 l o c a t i o n , 591 r e p o r t i n g , 567 r u n - t i m e , 7 2 , 298 Escape function, 827 E s c a p e C o m m F u n c t i o n f u n c t i o n , 731 event-driven architecture, 149 event-flow, 385
events, 106 keyboard, 666 m o u s e , 124, 6 6 6 timer, 666-678 ExcludeClipRect function, 800 ExcludeUpdateRgn function, 700 . E X E files, 2 0 , 243 c h e c k b o x , 18 E x e c D i a l o g m e t h o d , 131 executing a p p l i c a t i o n s , 724 dialogs, 227 Exit c o m m a n d , 14 ExitWindows function, 786 export indexes, 626 export names, 626 expressions C h a r type, 619 integer type, 614 p o i n t e r type, 6 1 4 real t y p e , 614 string type, 611 e x t e n d e d views, 92-93 extending a p p l i c a t i o n s , 394 o b j e c t s , 383 external declaration, 370 ExtFloodFill function, 796 ExtTextOut function, 855
F $ F + c o m p i l e r directive, 3 7 0 Fail p r o c e d u r e , 624 fields order, 617 r e f e r e n c i n g , 71 figures d r a w i n g , 322-323 filled, 322 file d i a l o g s , 134-135 executing, 227 o b j e c t s , 198
901
902
T
u
r
b
o
Pascal for W i n d o w s B i b l e
file editors, 227 File m e n u , 10-14 File O p e n d i a l o g , 135 file types, 6 1 0 , 6 1 3 , 6 1 7 file w i n d o w editor, 224-225 F i l e - N a m e i n p u t b o x , 26-27 F i l e - O p e n d i a l o g b o x , 11 File-Save-As d i a l o g b o x , 12 F i l e E x p a n d f u n c t i o n , 577 F i l e O p e n m e t h o d , 197 files, 5 9 , 651 . E X E , 2 0 , 243 access c o d e , 6 2 9 access d e n i e d , 6 2 3 a p p l i c a t i o n , 23 assigning, 6 3 0 attributes, 580-581 AUTOEXEC.BAT, 4 B M P , 276 C D E c o n f i g u r a t i o n file, 8 6 7 c l o s e d , 14 c o m p i l i n g , 21 copying resources between, 267 creating, 10, 224 desktop, 867 listings, 14 handles, 629 names e x p a n d i n g , 577 invalid, 6 0 0 splitting, 578 n e s t e d , 599 N O N A M E , 11 o p e n , 11, 3 7 , 2 2 4 , 5 9 9 , 628-630 printing, 12 r e s o u r c e , 255 r e s o u r c e specifications, c o p y i n g b e t w e e n , 266 saving, 12, 3 7 , 224 script, 2 4 5 , 2 5 5 searching, 579 s e a r c h i n g for, 578 Files list b o x , 26 FileSave m e t h o d , 197 FileSearch f u n c t i o n , 578
FileSplit f u n c t i o n , 578 FileWindow m e t h o d s , 226 F i l e W i n d o w object, 224-226 filled figures, 322 filling display area, 7 9 6 rectangles, 7 0 0 r e g i o n s , 848-850 FillRect f u n c t i o n , 7 0 0 FillRgn f u n c t i o n , 8 4 8 filter f u n c t i o n , 6 7 0 filter f u n c t i o n s , 6 6 9 F i n d c o m m a n d , 16 F i n d Place M a r k e r e d i t o r c o m m a n d , 37 Find-Error d i a l o g b o x , 18, 7 4 , 589 Find-Text d i a l o g b o x , 16 FindAtom function, 726 FindFirst p r o c e d u r e , 579 FindResource function, 763 FindWindow function, 673 fixed m e m o r y , 2 8 0 flag c o n s t a n t s , 503 flagging error c o n d i t i o n s , 501 F l a s h W i n d o w f u n c t i o n , 664 floating p o i n t n o t a t i o n , 55 o p e r a t i o n s , 6 2 2 , 632 overflow, 6 3 2 underflow, 632 F l o o d F i l l f u n c t i o n , 796 F l u s h C o m m f u n c t i o n , 731 f l u s h i n g buffers, 413-414 font r e s o u r c e s , 8 2 8 f o n t s , 126 F O R statement, 6 6 , 6 1 6 F o r E a c h iterator m e t h o d , 192 formats c l i p b o a r d , 3 4 5 , 639-641 names, 639 n u m e r i c , 631 fractals, 175 F r a m e R e c t p r o c e d u r e , 701 FrameRgn function, 848 free m e m o r y , 2 7 9
Index
FreeLibrary p r o c e d u r e , 7 5 7 FreeModule function, 758 F r e e M u l t i S e l p r o c e d u r e , 506 FreeProcInstance procedure, 758 FreeResource function, 763 FreeSelector function, 770 functions _lclose, 737 _lcreate, 737 J l s e e k , 738 lopen, 738 _lread, 739 J w r i t e , 739 A c c e s s R e s o u r c e , 762 A d d A t o m , 726 AddFontResource, 828 AllocDStoCSAlias, 768 A l l o c M u l t i S e l , 506 AllocResource, 763 AllocSelector, 769 AnsiLower, 779 AnsiLowerBuff, 7 7 9 AnsiNext, 779 AnsiPrev, 7 8 0 A n s i T o O e m , 780 A n s i U p p e r , 781 A n s i U p p e r B u f f , 781 A n y P o p u p , 671 A p p e n d M e n u , 681 ArrangelconicWindows, 659 Arc, 830 BeginDeferWindowPos, 659 BeginPaint, 698 BitBlt, 794 B u i l d C o m m D C B , 730 CallMsgFilter, 6 6 9 CallWindowProc, 692 Catch, 786 C h a n g e C l i p b o a r d C h a i n , 638 ChangeSelector, 769 C h e c k M e n u I t e m , 682 ChildWindowFromPoint, 671, 807 C h o r d , 852 C h r , 54
C l e a r C o m m B r e a k , 730 CloseClipboard, 638 C l o s e C o m m , 730 CloseMetaFile, 838 C M C o p y T e x t , 347 C o m b i n e R g n , 845 CopyMetaFile, 838 CopyText, 347 C o u n t V o i c e N o t e s , 773 C r e a t e B i t m a p , 795 C r e a t e B i t m a p I n d i r e c t , 795 CreateBrushlndirect, 822 C r e a t e C o m p a t i b l e - B i t m a p , 314 C r e a t e C o m p a t i b l e B i t m a p , 795 C r e a t e C o m p a t i b l e D C , 314, 809 CreateCursor, 642 C r e a t e D C , 810 CreateDialog, 646 CreateDialoglndirect, 647 CreateDialoglndirectParam, 647 CreateDialogParam, 648 CreateDIBitmap, 314, 812 CreateDIBPatternBrush, 822 CreateDiscardableBitmap, 796 C r e a t e E l l i p t i c R g n , 845 CreateEllipticRgnlndirect, 846 CreateFont, 825, 828 CreateFontlndirect, 825, 829 CreateHatchBrush, 823 CreateIC, 810 CreateMenu, 683 CreateMetaFile, 838 CreatePalette, 804 CreatePatternBrush, 823 CreatePen, 824 CreatePenlndirect, 824 CreatePolygonRgn, 846 CreatePolyPolygonRgn, 846 C r e a t e P o p u p M e n u , 683 CreateRectRgn, 847 CreateRectRgnlndirect, 847 CreateRoundRectRgn, 847 CreateSolidBrush, 823 C r e a t e W i n d o w , 712 C r e a t e W i n d o w E x , 713
903
904
T u r b o Pascal for Windows
Bible
D e f D l g P r o c , 6 4 8 , 714 DeferWindowPos, 660 D e f F r a m P r o c , 715 DefHookProc, 669 DefineHandleTable, 744, 770 D e f M D I C h i l d P r o c , 715 DefWindowProc, 716 DeleteAtom, 726 D e l e t e D C , 811 D e l e t e M e n u , 683 DeleteMetaFile, 838 DeleteObject, 820 DestroyCursor, 643 DestroyMenu, 683 DestroyWindow, 716 DialogBox, 649 DialogBoxIndirect, 649 DialogBoxIndirectParam, 650 DialogBoxParam, 650 DispatchMessage, 692 DlgDirList, 651 D l g D i r L i s t C o m b o B o x , 651 DlgDirSelect, 652 D l g D i r S e l e c t C o m b o B o x , 652-653 dMenuIndirect, 688 D O S , 583, 627 D o s V e r s i o n , 584 DPtoLP, 808 Drawlcon, 699 d r a w i n g , 327-340 DrawText, 699 Ellipse, 8 5 2 EmptyClipboard, 346, 638 EnableHardwarelnput, 666 E n a b l e M e n u I t e m , 684 EnableWindow, 676 E n u m C h i l d W i n d o w s , 672 EnumClipboardFormats, 639 EnumFonts, 829 EnumMetaFile, 839 E n u m O b j e c t s , 824 E n u m P r o p s , 705 EnumTaskWindows, 672 E n u m W i n d o w s , 672
EqualRect, 842 EqualRgn, 848 Escape, 827 E s c a p e C o m m F u n c t i o n , 731 ExcludeClipRect, 800 ExcludeUpdateRgn, 700 ExitWindows, 786 ExtFloodFill, 796 ExtTextOut, 855 FileExpand, 577 F i l e S e a r c h , 578 FUeSplit, 578 FillRect, 7 0 0 FillRgn, 8 4 8 filter, 669-670 FindAtom, 726 F i n d R e s o u r c e , 763 FindWindow, 673 F l a s h W i n d o w , 664 FloodFill, 796 F l u s h C o m m , 731 FrameRgn, 848 FreeModule, 758 F r e e R e s o u r c e , 763 FreeSelector, 770 G D I ( G r a p h i c s D e v i c e Interface), 793 b i t m a p , 794-800 c l i p p i n g , 800-802 c o l o r palette, 803-807 coordinate-translation, 807-809 device-context, 809-811 device-independent bitmap, 812-814 drawing-attribute, 815-818 d r a w i n g - t o o l , 819-825 e n v i r o n m e n t , 826-827 font, 827-830 line-drawing, 830-832 m a p p i n g , 832-837 metafile, 837-840 printer-control, 8 4 1 r e c t a n g l e , 842-844
Index
r e g i o n , 844-851 s h a p e - d r a w i n g , 851-854 text-drawing, 855-858 GetActiveWindow, 677 G e r A r g C o u n t , 575 G e t A r g C o u n t , 576 GetAsyncKeyState, 666 GetAtomHandle, 727 G e t A t o m N a m e , 727 GetBitmapBits, 797 G e t B i t m a p D i m e n s i o n , 797 G e t B k C o l o r , 816 G e t B k M o d e , 816 G e t B r u s h O r g , 821 GetCapture, 677 GetCaretBlinkTime, 636 GetCharWidth, 829 G e t C l a s s I n f o , 716 GetClassLong, 717 GetClassName, 717 GetClassWord, 717 GetClipboardData, 639 GetClipboardFormatName, 639 G e t C l i p b o a r d O w n e r , 640 GetClipboardViewer, 640 G e t C l i p B o x , 801 G e t C o d e H a n d l e , 758 G e t C o m m E r r o r , 731 G e t C o m m E v e n t M a s k , 732 G e t C o m m S t a t e , 732 G e t C u r r e n t P D B , 787 GetCurrentTask, 787 GetCurrentTime, 677, 710 G e t D C , 701 G e t D C O r g , 811 GetDialogBaseUnits, 653 GetDIBits, 813 G e t D l g C t r l l D , 654 G e t D l g l t e m , 654 GetDlgltemlnt, 654 G e t D l g l t e m T e x t , 655 GetDOSEnvironment, 787 GetDoubleClickTime, 677 G e t D r i v e T y p e , 735
GetEnvironment, 826 G e t E n v V a r , 576 GetFocus, 677 G e t F r e e S p a c e , 745 GetlnputState, 666 GetlnstanceData, 758 G e t K B C o d e P a g e , 667 GetKeyNameText, 667 GetKeyState, 667 GetLastActivePopup, 718 G e t M a p M o d e , 833 G e t M e n u , 684 GetMenuCheckMarkDimensions, 685 G e t M e n u I t e m C o u n t , 685 G e t M e n u I t e m I D , 685 G e t M e n u S t a t e , 685 GetMenuString, 686 GetMessage, 693 GetMessagePos, 693 GetMessageTime, 693 GetMetaFile, 839 GetMetaFileBits, 840 GetModuleFileName, 759 G e t M o d u l e H a n d l e , 759 GetModuleUsage, 759 G e t N e a r e s t P a l e t t e l n d e x , 7 8 9 , 804 G e t N e x t D l g G r o u p I t e m , 655 GetNextDlgTabltem, 655 G e t N e x t W i n d o w , 673 G e t N u m T a s k s , 787 G e t O b j e c t , 821 G e t O b j e c t P t r , 506 GetPaletteEntries, 804 GetParent, 673 GetPixel, 797 GetPolyFillMode, 816 GetPriorityClipboardFormat, 640 GetPrivateProfilelnt, 7 4 0 GetPrivateProfileString, 741 GetProcAddress, 760 G e t P r o f i l e l n t , 741 GetProfileString, 741 G e t P r o p , 705
905
906
T
u
r
r
j
o
Pascal for Windows
Bible
GetRgnBox, 849 G e t R O P 2 , 817 GetScrollPos, 707 GetStockObject, 322, 826 GetStretchBltMode, 817 G e t S u b M e n u , 687 GetSysColor, 710 GetSystemMenu, 687 GetSystemMetrics, 710 GetSystemPaletteEntries, 805 G e t S y s t e m P a l e t t e U s e , 805 GetTabbedTextExtent, 855 G e t T e m p D r i v e , 736 G e t T e m p F i l e N a m e , 736 GetTextAlign, 856 GetTextColor, 817 GetTextExtent, 856 GetTextFace, 856 GetTextMetrics, 857 G e t T h r e s h o l d E v e n t , 773 G e t T h r e s h o l d S t a t u s , 774 G e t T i c k C o u n t , 678 G e t T o p W i n d o w , 674 GetVersion, 760 GetViewportExt, 833 GetViewportOrg, 833 G e t U p d a t e R e c t , 701 G e t U p d a t e R g n , 702 G e t W i n d o w , 674 G e t W i n d o w D C , 702 GetWindowExt, 833 G e t W i n d o w L o n g , 718 G e t W i n d o w O r g , 834 GetWindowsDirectory, 737 G e t W i n d o w T a s k , 674 G e t W i n d o w T e x t , 661 G e t W i n d o w T e x t L e n g t h , 661 G e t W i n d o w W o r d , 718 G e t W i n F l a g s , 745 G l o b a l A d d A t o m , 727 G l o b a l A l l o c , 3 7 1 , 745 G l o b a l C o m p a c t , 746 GlobalDeleteAtom, 728 GlobalDiscard, 746
G l o b a l D o s A l l o c , 746 GlobalDosFree, 747 GlobalFindAtom, 728 GlobalFlags, 747 GlobalFree, 747 G l o b a l G e t A t o m N a m e , 728 G l o b a l H a n d l e , 748 G l o b a l L o c k , 748 G l o b a l l R U N e w e s t , 748 GlobalLRUOldest, 749 G l o b a l P a g e L o c k , 771 G l o b a l P a g e U n l o c k , 771 GlobalRealioc, 749 G l o b a l S i z e , 750 G l o b a l U n f r x , 772 GlobalUnlock, 750 G l o b a l U n W i r e , 750 G l o b a l W i r e , 751 g r a p h i c s , 327-340 G r a y S t r i n g , 702 h e a d e r s , 621 HiByte, 789 HiliteMenuItem, 687 HiWord, 790 h o o k , 669-670 identifiers, 6 2 6 InitAtomTable, 729 I n S e n d M e s s a g e , 694 InsertMenu, 688 IntersectClipRect, 801 IntersectRect, 8 4 3 invalid, 6 2 2 InvertRgn, 8 4 9 I s C h a r A l p h a , 781 I s C h a r A l p h a N u m e r i c , 782 I s C h a r L o w e r , 782 I s C h a r U p p e r , 782 I s C h i l d , 675 IsClipboardFormatAvailable, 640 IsDialogMessage, 656 IsDlgButtonChecked, 656 I s l c o n i c , 661 I s W i n d o w , 675 IsWindowEnabled, 678
Index
I s W i n d o w V i s i b l e , 662 I s Z o o m e d , 662 KeyPressed, 520 KillTimer, 6 7 8 L i n e T o , 831 LoadAccelerators, 764 LoadBitmap, 764, 798 L o a d C u r s o r , 6 4 3 , 765 L o a d l c o n , 765 LoadLibrary, 7 6 0 L o a d M e n u , 765 L o a d M o d u l e , 724 LoadResource, 766 L o a d S t r i n g , 766 LoByte, 790 LocalAlloc, 284, 751 L o c a l C o m p a c t , 752 L o c a l D i s c a r d , 752 LocalFlags, 752 L o c a l F r e e , 753 L o c a l H a n d l e , 753 Locallnit, 7 5 3 LocalLock, 753 L o c a l R e a l l o c , 754 L o c a l S h r i n k , 754 L o c a l S i z e , 755 L o c a l U n l o c k , 2 8 5 , 755 L o c k D a t a , 755 LockResource, 767 L o c k S e g m e n t , 7 5 5 , 772 L o n g D i v , 507 L o n g M u l , 507 LowMemory, 507 LoWord, 790 LPtoDP, 808 lstrcat, 782 l s t r c m p , 783 lstrcmpi, 7 8 3 lstrcpy, 783 lstrlen, 784 M a k e l n t A t o m , 7 2 9 , 791 M a k e l n t R e s o u r c e , 2 6 4 , 791 M a k e L o n g , 791 M a k e P o i n t , 791
M a k e P r o c I n s t a n c e , 761 MapVirtualKey, 668 M e m A l l o c , 507 m e m o r y m a n a g e m e n t , 506-508 M e s s a g e B o x , 665 ModifyMenu, 689 M o v e T o , 831 M u l D i v , 791 N e w S t r , 508 OemKeyScan, 668 O e m T o A n s i , 784 O f f s e t C l i p R g n , 801 OffsetRgn, 850 OffsetWindowOrg, 834 O p e n C l i p b o a r d , 641 O p e n C o m m , 732 O p e n F i l e , 739 O p e n l c o n , 663 O p e n S o u n d , 774 O r d , 54 PaintRgn, 850 P a l e t t e R G B , 792 PatBlt, 798 PeekMessage, 694 Pie, 8 5 3 PlayMetaFile, 8 4 0 Polygon, 853 Polyline, 8 3 2 PolyPolygon, 853 P o s t A p p M e s s a g e , 694 P o s t M e s s a g e , 695 PtlnRect, 844 PtlnRegion, 850 R e a d B u f , 520 R e a d C o m m , 733 R e a d K e y , 521 RealizePalette, 805 R e c t a n g l e , 854 R e c t l n R e g i o n , 851 RectVisible, 8 0 2 RegisterClass, 7 1 9 R e g i s t e r C l i p b o a r d F o r m a t , 641 R e l e a s e D C , 704 RemoveFontResource, 830
907
908
T
u
r
D
O
Pascal for W i n d o w s B i b l e
R e m o v e M e n u , 689 R e m o v e P r o p , 706 R e s t o r e D C , 811 R G B , 792 RoundRect, 854 S a v e D C , 812 S c a l e V i e w p o r t E x t , 835 ScaleWindowExt, 835 ScrollDC, 707 SelectClipRgn, 802 S e l e c t O b j e c t , 821 SelectPalette, 8 0 6 SendDlgltemMessage, 657 SendMessage, 696 SetActiveWindow, 679 SetBitmapBits, 799 SetBitmapDimension, 799 SetBkColor, 817 SetBkMode, 818 SetBrushOrg, 822 SetCapture, 679 SetClassLong, 719 SetClassWord, 720 S e t C l i p b o a r d D a t a , 3 4 6 , 641 S e t C l i p b o a r d V i e w e r , 642 S e t C o m m B r e a k , 733 S e t C o m m E v e n t M a s k , 733 S e t C o m m S t a t e , 734 S e t C u r s o r , 644 SetDIBits, 813 S e t D I B i t s T o D e v i c e , 814 SetEnvironment, 826 SetErrorMode, 788 SetFocus, 679 SetHandleCount, 740 SetMapMode, 836 SetMapperFlags, 830 SetMenu, 690 SetMenuItemBitmaps, 690 SetMessageQueue, 696 SetMetaFileBits, 8 4 0 SetPaletteEntries, 8 0 6 SetParent, 675 SetPixel, 7 9 9
SetPolyFillMode, 818 SetProp, 706 SetResourceHandler, 767 SetROP2, 818 SetScrollPos, 708 S e t S o u n d N o i s e , 774 SetStretchBltMode, 819 SetSwapAreaSize, 756 SetSysModalWindow, 680 SetSystemPaletteUse, 8 0 6 SetTextAlign, 8 5 7 SetTextColor, 819 SetTextJustiiication, 8 5 7 SetTimer, 680 SetViewportExt, 836 SetViewportOrg, 836 S e t V o i c e A c c e n t , 774 S e t V o i c e E n v e l o p e , 775 S e t V o i c e N o t e , 775 SetVoiceQueueSize, 776 SetVoiceSound, 776 SetVoiceThreshold, 777 SetWindowExt, 837 S e t W i n d o w L o n g , 720 SetWindowOrg, 837 SetWindowsHook, 670 SetWindowWord, 720 S h o w C u r s o r , 644 S h o w W i n d o w , 664 SizeOf, 202 SizeofResource, 767 StartSound, 777 S t o p S o u n d , 777 StrCat, 540 S t r C o m p , 541 S t r C o p y , 542 S t r D i s p o s e , 542 S t r E C o p y , 543 S t r E n d , 543 StretchBlt, 8 0 0 StretchDIBits, 815 Strings unit, 5 3 9 , 540 StrLCat, 544 S t r L C o m p , 544-545
Index
S t r L C o p y , 546 StrLen, 546 S t r L I C o m p , 547 StrLower, 547 S t r M o v e , 548 S t r N e w , 548 StrPas, 549 S t r P C o p y , 550 StrPos, 550 StrRScan, 551 S t r S c a n , 551 S t r U p p e r , 552 SwapMouseButton, 680 SyncAllVoices, 778 S y s t e m unit, 557 TabbedTextOut, 858 TextOut, 858 ToAscii, 785 T r a c k P o p u p M e n u , 691 TranslateAccelerator, 6 9 6 TranslateMDISysAccel, 697 TranslateMessage, 697 T r a n s m i t C o m m C h a r , 734 U n g e t C o m m C h a r , 734 U n h o o k W i n d o w s H o o k , 670 UnionRect, 844 UnlockData, 756 UnlockResource, 768 U n l o c k S e g m e n t , 7 5 7 , 772 UnrealizeObject, 822 U n r e g i s t e r C l a s s , 721 UpdateColors, 807 variables, 622 VkKeyScan, 668 WaitSoundState, 778 W h e r e X , 522 W h e r e Y , 523 W i n D o s unit, 566-567 W i n C r t unit, 515-516 W i n d o w M a n a g e r Interface, 636-792 WindowFromPoint, 675, 809 W i n E x e c , 724 W i n H e l p , 725
W r i t e C o m m , 735 WritePrivateProfileString, 742 WriteProfileString, 742 wvsprintf, 785 Yield, 788
G $G+ c o m p i l e r directive, 625 G D I ( G r a p h i c s D e v i c e Interface), 301 procedures and functions, 793-858 G D I . E X E p r o g r a m , 95 G e t c o m m a n d , 202 GetActiveWindow function, 677 G e t A r g C o u n t f u n c t i o n , 575-576 GetAsyncKeyState function, 666 GetAtomHandle function, 727 G e t A t o m N a m e function, 727 GetBitmapBits function, 797 G e t B i t m a p D i m e n s i o n f u n c t i o n , 797 G e t B k C o l o r function, 816 G e t B k M o d e function, 816 G e t B r u s h O r g f u n c t i o n , 821 GetCapture function, 677 GetCaretBlinkTime function, 636 GetCaretPos procedure, 636 G e t C B r e a k p r o c e d u r e , 585 GetCharWidth function, 829 G e t C h i l d r e n object m e t h o d , 2 2 9 G e t C l a s s I n f o f u n c t i o n , 716 GetClassLong functions, 717 G e t C l a s s N a m e function, 717 GetClassWord function, 717 GetClientRect procedure, 660 GetClipboardData function, 639 GetClipboardFormatName function, 639 G e t C l i p b o a r d O w n e r function, 640 GetClipboardViewer function, 640 G e t C l i p B o x f u n c t i o n , 801 G e t C o d e H a n d l e f u n c t i o n , 758 G e t C o d e l n f o p r o c e d u r e , 771
909
910
T
u
r
b
o
Pascal for W i n d o w s B i b l e
G e t C o m m E r r o r f u n c t i o n , 731 G e t C o m m E v e n t M a s k f u n c t i o n , 732 G e t C o m m S t a t e f u n c t i o n , 732 G e t C u r D i r p r o c e d u r e , 572 G e t C u r r e n t P D B function, 787 GetCurrentTask function, 787 GetCurrentTime function, 677, 710 GetCursorPos procedure, 643 G e t D a t e p r o c e d u r e , 568 G e t D C f u n c t i o n , 701 G e t D C O r g f u n c t i o n , 811 GetDialogBaseUnits function, 653 GetDIBits function, 813 G e t D l g C t r l l D f u n c t i o n , 654 G e t D l g l t e m f u n c t i o n , 654 G e t D l g l t e m l n t f u n c t i o n , 654 G e t D l g l t e m T e x t f u n c t i o n , 655 G e t D O S E n v i r o n m e n t function, 787 G e t D o u b l e C l i c k T i m e function, 677 G e t D r i v e T y p e f u n c t i o n , 735 GetEnvironment function, 826 G e t E n v V a r f u n c t i o n , 576 GetFA tt r p r o c e d u r e , 580 GetFocus function, 677 G e t F r e e S p a c e f u n c t i o n , 745 G e t F T i m e p r o c e d u r e , 568 GetlnputState function, 666 G e t l n s t a n c e D a t a f u n c t i o n , 758 G e t l n t V e c p r o c e d u r e , 581 G e t K B C o d e P a g e function, 667 GetKeyboardState procedure, 666 GetKeyNameText function, 667 GetKeyState function, 667 G e t L a s t A c t i v e P o p u p f u n c t i o n , 718 G e t M a p M o d e function, 833 G e t M e n u f u n c t i o n , 684 GetMenuCheckMarkDimensions
function, 640 GetPrivateProfilelnt f u n c t i o n , 7 4 0 GetPrivateProfileString f u n c t i o n , 741 GetProcAddress function, 760 G e t P r o f i l e l n t f u n c t i o n , 741 GetProfileString f u n c t i o n , 741 G e t P r o p f u n c t i o n , 705 G e t R g n B o x function, 849 G e t R O P 2 function, 817 GetScrollPos function, 707 GetScrollRange procedure, 707 GetStockObject function, 322, 826 GetStretchBltMode function, 817 G e t S u b M e n u function, 687 GetSysColor function, 710 GetSystemDirectory procedure, 736 GetSystemMenu function, 687 GetSystemMetrics function, 710 GetSystemPaletteEntries f u n c t i o n ,
f u n c t i o n , 685 G e t M e n u I t e m C o u n t f u n c t i o n , 685 G e t M e n u I t e m I D f u n c t i o n , 685 G e t M e n u S t a t e f u n c t i o n , 685 GetMenuString function, 686 G e t M e s s a g e f u n c t i o n , 693 GetMessagePos function, 693 GetMessageTime function, 693
805 G e t S y s t e m P a l e t t e U s e f u n c t i o n , 805 GetTabbedTextExtent function, 855 G e t T e m p D r i v e function, 736 G e t T e m p F i l e N a m e function, 736 GetTextAlign function, 856 GetTextColor function, 817 GetTextExtent function, 856
GetMetaFile function, 839 GetMetaFileBits function, 840 G e t M o d u l e F i l e N a m e function, 759 G e t M o d u l e H a n d l e function, 759 G e t M o d u l e U s a g e function, 759 GetNearestPalettelndex function, 789, 804 G e t N e x t D l g G r o u p I t e m function, 655 G e t N e x t D l g T a b l t e m f u n c t i o n , 655 G e t N e x t W i n d o w function, 673 GetNumTasks function, 787 G e t O b j e c t function, 821 G e t O b j e c t P t r f u n c t i o n , 506 GetPaletteEntries f u n c t i o n , 8 0 4 GetParent function, 673 GetPixel function, 797 GetPolyFillMode function, 816 GetPriorityClipboardFormat
Index
GetTextFace function, 856 GetTextMetrics function, 857 GetThresholdEvent function, 773 G e t T h r e s h o l d S t a t u s f u n c t i o n , 774 GetTickCount function, 678 G e t T i m e p r o c e d u r e , 569 G e t T o p W i n d o w f u n c t i o n , 674 GetVerify p r o c e d u r e , 585 GetVersion function, 760 GetViewportExt function, 833 GetViewportOrg function, 833 G e t U p d a t e R e c t f u n c t i o n , 701 G e t U p d a t e R g n f u n c t i o n , 702 G e t W i n d o w C l a s s m e t h o d , 228 G e t W i n d o w f u n c t i o n , 674 G e t W i n d o w D C f u n c t i o n , 702 GetWindowExt function, 833 G e t W i n d o w L o n g function, 718 G e t W i n d o w O r g function, 834 G e t W i n d o w R e c t p r o c e d u r e , 661 GetWindowsDirectory function, 737 G e t W i n d o w T a s k f u n c t i o n , 674 G e t W i n d o w T e x t f u n c t i o n , 661 GetWindowTextLength function, 661 G e t W i n d o w W o r d function, 718 G e t W i n F l a g s f u n c t i o n , 745 G H a n d l e m e m o r y h a n d l e , 282 global m e m o r y b l o c k s , 290-296 heaps, 283 m e m o r y , 283-284, 8 7 3 scope, 876 GlobalAddAtom function, 727 G l o b a l A l l o c f u n c t i o n , 3 7 1 , 745 G l o b a l C o m p a c t f u n c t i o n , 746 GlobalDeleteAtom function, 728 GlobalDiscard function, 746 GlobalDosAlloc function, 746 GlobalDosFree function, 747 GlobalFindAtom function, 728 G l o b a l F i x p r o c e d u r e , 771 GlobalFlags function, 747 GlobalFree function, 747 G l o b a l G e t A t o m N a m e f u n c t i o n , 728
G l o b a l H a n d l e f u n c t i o n , 748 GlobalLock function, 748 GlobalLRUNewest function, 748 GlobalLRUOldest function, 749 GlobalNotify procedure, 749 G l o b a l P a g e L o c k f u n c t i o n , 771 G l o b a l P a g e U n l o c k f u n c t i o n , 771 GlobalRealloc function, 749 GlobalSize function, 750 G l o b a l U n f i x f u n c t i o n , 772 G l o b a l U n l o c k function, 750 GlobalUnWire function, 750 G l o b a l W i r e f u n c t i o n , 751 G o t o L i n e N u m b e r c o m m a n d , 17 G o t o L i n e N u m b e r d i a l o g b o x , 17 g o t o statement, 66 G o t o X Y p r o c e d u r e , 519 G r a p h i c a l U s e r Interface ( G U I ) , 4 3 , 9 3 , 113-114, 8 7 3 graphics d r a w i n g , 126-127 f u n c t i o n s , 327-340 o b j e c t s , 861-865 G r a p h i c s D e v i c e Interface ( G D I ) , 301 procedures and functions, 793-858 graphing x v a l u e , 163 y v a l u e , 163 G r a y S t r i n g f u n c t i o n , 702 g r o u p boxes, 270 g r o u p lists, 3 6 7 G r o u p - U n d o o p t i o n , 15 G U I ( G r a p h i c a l U s e r Interface), 4 3 , 9 3 , 113-114, 8 7 3
H H a n d l e L i s t B o x l M s g m e t h o d , 258 handles, 873 accessing m e m o r y , 286 c o n t r o l , 654 data, 705
911
912
T
u
r
D
O
Pascal for W i n d o w s B i b l e
file, 6 2 9 G H a n d l e , 282 memory, 282, 347 m e n u , 684 pop-up m e n u s , 687 window, 677 parent, 673 handling keyboard, 411 streams, 195-196 h a t c h e d b r u s h e s , 323 headers f u n c t i o n , 4 5 , 621 p r o c e d u r e , 4 5 , 621 unit, 4 8 H e a p E r r o r variable, 2 9 8 heaps, 46, 873 errors, 298 g l o b a l , 283 local, 284 o v e r f l o w i n g , 631 strings allocating, 548 d i s p o s i n g of, 542 h e l p i n d e x , 29 H e l p m e n u , 29-31 h e l p w i n d o w s , 232-236 adding, 229 creating, 2 3 0 H e l p / T o p i c S e a r c h c o m m a n d , 29 H e l p / U s i n g H e l p c o m m a n d , 29-30 H e l p W n d unit, 229 H e r c u l e s v i d e o adapter, 4 HiByte function, 789 HideCaret procedure, 637 hiding scroll bars, 7 0 9 w i n d o w s , 664 h i d i n g data, 871 hierarchical charts, 387-388 hierarchies, 8 7 3 O b j e c t W i n d o w s , 112-115 highlighting m e n u items, 687
HiliteMenuItem function, 687 HiWord function, 790 h o o k function, 669, 670 h o s t types, 54 h o t link, 354
I I/O, 107-108 i c o n i c w i n d o w s , 661 i c o n s , 127-128, 2 4 2 , 874 arranging, 2 8 , 6 5 9 drawing, 699 flashing, 664 loading, 228 i d _ X X X X c o n s t a n t s , 502 I D E (Integrated D e v e l o p m e n t E n v i r o n m e n t ) , 867-868 identifiers, 50-56 constructor, 623 destructors, 6 2 3 d u p l i c a t e , 598 e n u m e r a t i n g , 54 function, 626 m e t h o d , 623 procedure, 626 qualified, 51 r e s o u r c e , 625 s y m b o l i c , 151 task, 674 type, 599 u n k n o w n , 598 variable, 6 0 0 i f . . . t h e n . . . e l s e statements, 6 7 illegal a s s i g n m e n t , 605 illegal characters, 598 i m p l e m e n t a t i o n , 874 I M P L E M E N T A T I O N reserved w o r d , 612 I n c l u d e - D i r e c t o r i e s i n p u t b o x , 24 index, 29,, 633 indirect r e f e r e n c e s , 622 InflateRect p r o c e d u r e , 8 4 3
Index
information boxes C o m p i l e , 21 Compile-Status, 20 i n h e r i t a n c e , 84-86, 8 7 4 inheriting a p p l i c a t i o n s , 112, 115 w i n d o w s , 117 Init, 121 InitAtomTable function, 729 initialization, 8 7 4 initializing o b j e c t s , 6 3 2 I n i t W i n C r t p r o c e d u r e , 519 inline directives, 6 9 I N L I N E error, 6 1 9 inline statement, 68 input cursor, 6 7 9 k e y b o a r d , 6 6 6 , 676-678 m o u s e , 6 6 6 , 676-678 input boxes F i l e - N a m e , 26-27 I n c l u d e - D i r e c t o r i e s , 24 O b j e c t - D i r e c t o r i e s , 24 Options/Directories, 24 R e s o u r c e - D i r e c t o r i e s , 24 Tab-Size, 26 Unit-Directories, 24 i n p u t s c r e e n s , see d i a l o g b o x e s I n S e n d M e s s a g e f u n c t i o n , 694 InsertMenu function, 688 installing T u r b o Pascal for Windows, 4 instance l i n k a g e , 115 instances, 8 7 4 , 8 7 7 integer types, 6 0 4 , 614-618 integers c o n s t a n t s , 598, 6 0 2 division, 507 Integrated D e v e l o p m e n t E n v i r o n m e n t ( I D E ) , 867-868 i n t e r c e p t i n g m e s s a g e s , 123 interface e l e m e n t s , 105, 243 interface o b j e c t s , 105, 2 7 0 I N T E R F A C E reserved w o r d , 6 0 8
interfaces, 113, 874 interrupt p r o c e d u r e s , 6 1 9 interrupts, 582 IntersectClipRect f u n c t i o n , 8 0 1 IntersectRect f u n c t i o n , 8 4 3 Intr p r o c e d u r e , 582 InvalidateRect p r o c e d u r e , 7 0 3 InvalidateRgn p r o c e d u r e , 7 0 3 invalid drive n u m b e r , 6 2 9 file types, 6 1 0 file n a m e s , 6 0 0 floating p o i n t o p e r a t i o n s , 622 f u n c t i o n s , 622 indirect r e f e r e n c e s , 622 p r o c e d u r e s , 622 string l e n g t h , 601 s y m b o l references, 625 variable r e f e r e n c e s , 6 2 0 inverting c o l o r s , 704 InvertRect p r o c e d u r e , 704 InvertRgn function, 849 I s C h a r A l p h a f u n c t i o n , 781 I s C h a r A l p h a N u m e r i c f u n c t i o n , 782 I s C h a r L o w e r f u n c t i o n , 782 I s C h a r U p p e r f u n c t i o n , 782 I s C h i l d f u n c t i o n , 675 IsClipboardFormatAvailable function, 640 IsDialogMessage function, 656 I s D l g B u t t o n C h e c k e d function, 656 I s l c o n i c f u n c t i o n , 661 I s W i n d o w f u n c t i o n , 675 IsWindowEnabled function, 678 IsWindowVisible function, 662 I s Z o o m e d function, 662 iteration, 398 iterator m e t h o d s , 192
913
914
T
u
r
b
o
Pascal for W i n d o w s B i b l e
K
linking dynamically, 3 7 0 files, 2 3 , 6 0 5 instance l i n k a g e , 115 statically, 3 7 0
K E R N E L . E X E p r o g r a m , 95 k e y n a m e strings, 6 6 7 keyboard
t o P r o g r a m M a n a g e r , 357-366 links c o l d , 354
accelerators, 242 events, 666 h a n d l i n g , 411 input, 676, 678 keyboards accelerators, 6 9 6 input, 666 k e y b o a r d s , r e a d i n g characters 521 KeyPressed f u n c t i o n , 5 2 0 keys, accelerator, 128 keys, 666-667 KillTimer function, 678
l $L c o m p i l e r directive, 605 labels, 6 1 4 late b i n d i n g , 9 0 , 8 7 0 _lcreate function, 737 leveling, 386 libraries d y n a m i c link, 2 9 8 , 369-370 O b j e c t G r a p h i c s , 861-865 O b j e c t W i n d o w s , 8 0 , 383 r u n - t i m e , 45 L i m i t E m s P a g e s p r o c e d u r e , 751 linear e q u a t i o n s , 163 L i n e D D A p r o c e d u r e , 831 lines d r a w i n g , 831 l o n g , 599 segments, 832 LineTo function, 831 link buffer, 23 L i n k Buffer File o p t i o n s , 23 L i n k e r - O p t i o n s d i a l o g b o x , 23
from,
hot, 354 very c o l d , 354 warm, 354 list b o x e s , 135, 138, 2 5 6 , 260-261, 652, 874 attributes, 262 c o d e , 139 D i r e c t o r i e s , 28 Files, 2 6 llseek f u n c t i o n , 7 3 8 L o a d m e t h o d , 196 LoadAccelerators f u n c t i o n , 764 LoadBitmap function, 764, 798 L o a d C u r s o r f u n c t i o n , 6 4 3 , 765 L o a d F i l e m e t h o d , 198 L o a d l c o n f u n c t i o n , 765 loading i c o n s , 228 m e n u s , 688 LoadLibrary f u n c t i o n , 7 6 0 L o a d M e n u f u n c t i o n , 765 L o a d M o d u l e f u n c t i o n , 724 LoadResource function, 766 LoadString function, 766 LoByte function, 790 local h e a p s , 284 m e m o r y , 283-284, 8 7 3 o b j e c t types, 6 2 3 scope, 876 LocalAlloc f u n c t i o n , 2 8 4 , 751 L o c a l C o m p a c t f u n c t i o n , 752 L o c a l D i s c a r d f u n c t i o n , 752 LocalFlags f u n c t i o n , 752 L o c a l F r e e f u n c t i o n , 753
Index
L o c a l H a n d l e f u n c t i o n , 753 Locallnit f u n c t i o n , 753 L o c a l L o c k f u n c t i o n , 753 L o c a l R e a l l o c f u n c t i o n , 754 L o c a l S h r i n k f u n c t i o n , 754 LocalSize f u n c t i o n , 755 L o c a l U n l o c k f u n c t i o n , 2 8 5 , 755 L o c k D a t a f u n c t i o n , 755 l o c k i n g m e m o r y b l o c k s , 285 LockResource function, 767 L o c k S e g m e n t f u n c t i o n , 7 5 5 , 772 lclose f u n c t i o n , 7 3 7 logical brushes, 823 c o l o r palettes, 8 0 4 o r i g i n , 318 pens, 824 points, 808 logistic e q u a t i o n s , 170 L o n g D i v f u n c t i o n , 507 L o n g M u l function, 507 L o n g R e c r e c o r d type, 509 loops, message-processing, 510 _ l o p e n f u n c t i o n , 738 lower b o u n d , 602 L o w M e m o r y f u n c t i o n , 507 L o W o r d function, 790 LPtoDP function, 808 lread f u n c t i o n , 7 3 9 lstrcat f u n c t i o n , 782 l s t r c m p f u n c t i o n , 783 lstrcmpi f u n c t i o n , 783 lstrcpy f u n c t i o n , 783 lstrlen f u n c t i o n , 784 _lwrite function, 739
M $M c o m p i l e r directive, 284 m a c h i n e - c o d e instructions, 68-69 M a k e l n t A t o m f u n c t i o n , 7 2 9 , 791 M a k e l n t R e s o u r c e f u n c t i o n , 2 6 4 , 791 M a k e L o n g f u n c t i o n , 791 M a k e P o i n t f u n c t i o n , 791
M a k e P r o c I n s t a n c e f u n c t i o n , 761 M a p File o p t i o n s , 23 MapDialogRect procedure, 657 m a p p i n g c o o r d i n a t e s , 126 m a p p i n g m o d e s , 315-316 metric, 3 1 7 M M T E X T , 319-321 MapVirtualKey function, 668 m a t h e m a t i c attraction, 170-171 M a x i m i z e c o m m a n d , 8-10 maximizing windows, 8 MDI child w i n d o w , 216, 226 editors, 2 3 3 interface, 217-218 m e s s a g e s , 221-222 models, 219 w i n d o w s , 216 M D I (multiple d o c u m e n t interface), 214, 2 3 3 , 875 M e m A l l o c f u n c t i o n , 507 m e m o r y , 393 access direct, 2 9 7 indirect, 2 8 6 allocating, 6 5 9 allocation, 2 8 0 b l o c k s , 279-282 allocating, 291 discarding, 2 8 1 , 286 f i x e d , 283 freeing, 291 global, 290-293, 296 local, 284-286 locking, 285 u n l o c k i n g , 283-285 compacted, 280 fixed, 2 8 0 free, 2 7 9 g l o b a l , 283-284, 8 7 3 handles, 347 local, 283-284, 8 7 3 m a n a g e m e n t , 506-508 moving, 279
915
916
T
u
r
b
o
Pascal for W i n d o w s B i b l e
physical l o c a t i o n , 282 references, 624 r u n n i n g o u t of, 597 sharing, 279-280 states, 508 m e n u bars, 684 m e n u handles, 684 m e n u options, 7 m e n u - r e s p o n s e m e t h o d s , 303 m e n u s , 127, 150-155, 875 child w i n d o w , 216 C o m p i l e , 19-21 Control, 7 creating, 151, 6 5 3 deleting items, 683 destroying, 6 8 3 Edit, 14-15 File, 10-14 H e l p , 29-31 items, 227 highlighting, 687 loading, 688 O p t i o n s , 22-28 pop-up, 683 redrawing, 690 removing, 689 R u n , 18-19 S e a r c h , 16-18 selections, 128 W i n d o w , 28 m e s s a g e b o x e s , 141, 287-288 m e s s a g e - p r o c e s s i n g l o o p , 510 m e s s a g e - r e s p o n s e m e t h o d s , 124 M e s s a g e B e e p p r o c e d u r e , 665 M e s s a g e B o x f u n c t i o n , 665 M e s s a g e L o o p m e t h o d , 120 m e s s a g e s , 88-89, 107, 123, 875 c h i l d , 502 c o m p i l e r error, 592-626 C r e a t e W i n d o w , 103 dialog, 257 dialog boxes, 656 intercepting, 123 Paint, 186
posting to applicqations, 694 p r o c e s s i n g , 120, 715-716 accelerator, 4 1 0 M D I , 221-222 r u n - t i m e error, 626-632 w m C o m p a c t i n g , 299 W M D D E A C K , 354 W M D D E A D V I S E , 354 W M D D E I N I T I A T E , 354 W M D D E R E Q U E S T , 354 W M D D E T E R M I N A T E , 354 w m L B u t t o n D o w n , 123 w m M D I A c t i v a t e , 222 w m P a i n t , 186 m e t h o d s , 8 8 , 875 C a n C l o s e , 408 c m l t e r a t e , 156 C M F i l l e d R e c t a n g l e , 322 C M I t e r a t e , 162 C M N e w F i l e , 227 C M O p e n F i l e , 227 C M P e n S i z e , 303 C M P e n S t y l e , 303 d y n a m i c i n d e x , 625 EnableMenuItems, 227 E x e c D i a l o g , 131 F i l e O p e n , 197 FileSave, 197 FileWindow, 226 G e t W i n d o w C l a s s , 228 H a n d l e L i s t B o x l M s g , 258 identifiers, 6 2 3 iterator, 192 L o a d , 196 L o a d F i l e , 198 m e n u - r e s p o n s e , 303 m e s s a g e - r e s p o n s e , 124 M e s s a g e L o o p , 120 object, 2 2 9 overriding, 2 2 7 Paint, 193 response, 258 R u n , 120 S e n d D l g l t e m M s g , 257
Index
SetupWindow, 227 static, 8 7 7 S t o r e , 196 T B u f S t r e a m , 413-414 T B u t t o n , 415 T C h e c k B o x , 417-419 T C o l l e c t i o n , 421-426 T C o m b o B o x , 428-430 T C o n t r o l , 430-431 T D i a l o g , 433-436 TDlgWindow, 437 T D o s S t r e a m , 438-439 TEdit, 441-447 T E m s S t r e a m , 449-450 T G r o u p B o x , 451-452 T L i s t B o x , 453-456 TMDIClient, 458 T M D I W i n d o w , 460-464 T O b j e c t , 464-465 T R a d i o B u t t o n , 465 T S c r o l l B a r , 467-471 TScroller, 476-478 T S o r t e d C o l l e c t i o n , 480-481 TStatic, 482-484 T S t r C o l l e c t i o n , 485-486 T S t r e a m , 196, 487-491 T W i n d o w , 493-498 virtual, 8 7 8 metric m a p p i n g m o d e s , 317 Microsoft R e s o u r c e C o m p i l e r , 255 Microsoft W i n d o w s , 4, 93-95 M i n i m i z e c o m m a n d , 8-10 minimizing windows, 8 mistakes, 587 M M T E X T m a p p i n g m o d e , 319-321 m o d a l d i a l o g s , 130-131 m o d a l d i a l o g b o x e s , 649-650 terminating, 6 5 3 m o d e l e s s d i a l o g b o x , 646-647 m o d e l e s s d i a l o g b o x e s , 647-648 destroying, 7 1 6 messages, 656 m o d e l system multitasking c o d e , 175-184
m o d e l tasks, 162-163 m o d e l e s s d i a l o g s , 130 m o d e l i n g , 163-169 m o d e l s , 2 1 9 , 875 modes C r e a t e G r o u p , 356-367 drawing, 817 edit, 12 filling, 8 1 6 m a p p i n g , 315-316 metric m a p p i n g , 3 1 7 stretching retrieving, 8 1 7 setting, 8 1 9 Tab, 37 ModifyMenu function, 689 m o u s e , 26 buttons, 680 b u t t o n o b j e c t s , 262 captures, 678 clicks, 6 7 9 input, 676, 678 disabling, 6 6 6 e v e n t s , 124, 6 6 6 interface, 123 p o i n t e r , 385 M o v e c o m m a n d , 8-9 M o v e e d i t o r c o m m a n d , 32 M o v e T o function, 831 M o v e W i n d o w procedure, 662 moving bitmaps, 800 b l o c k s , 32 cursor, 518-519, 6 4 4 memory, 279 windows, 9 M s D o s p r o c e d u r e , 583 M u l D i v f u n c t i o n , 791 m u l t i p l e d o c u m e n t interface ( M D I ) , 875 multitasking,, 162 multitasking e n v i r o n m e n t , 9 2
917
918
T
u
r
b
o
Pascal f o r W i n d o w s B i b l e
N $ N + c o m p i l e r directive, 6 1 9 names directory, 24 export, 626 natural b o u n d a r i e s , 3 9 4 n e s t e d files, 5 9 9 N e t B I O S C a l l procedure, 762 N e w c o m m a n d , 11 N e w p r o c e d u r e , 188, 8 7 5 NewStr function, 508 N e x t c o m m a n d , 10 n f _ X X X X c o n s t a n t s , 502 non-supported operations, 622 N O N A M E file, 11 nontyped pointers in collections, 187 notification c o d e s , 2 6 3 null-terminated strings, 4 5 , 5 3 9 c o n v e r t i n g , 549 c o n v e r t i n g f r o m Pascal, 129 numeric constants, 602 n u m e r i c format, 6 3 1
o o b j e c t types, 5 8 , 8 3 abstract, 5 0 6 local, 6 2 3 registering, 511-512 ObjectWindows, 102-105 Object-Directories input boxes, 24 object-oriented a p p l i c a t i o n d e s i g n , 392-393 d e s i g n , 386-388 p r o g r a m m i n g ( O O P ) , 7 9 , 101-102 techniques, 388 O b j e c t G r a p h i c s library, 861-865 o b j e c t s , 80-81, 9 2 , 8 7 5 a p p l i c a t i o n , 114-116, 214 b a s e type, 8 3 B a s i c A p p l i c a t i o n , 122-124 Basiclnterface, 114
button, 262, 415 c o l l e c t i o n s , 194 c o m b i n i n g data a n d c o d e i n , 8 3 construction, 393 control, 267 discovering, 400-401 discovery, 393-395 dynamic, 91 extending, 383 F i l e W i n d o w , 224-226 g r a p h i c s , 861-865 group boxes, 270 interaction, 3 9 3 interface, 1 0 5 , 2 7 0 MainWindow, 214 natural b o u n d a r i e s , 3 9 4 O b j e c t W i n d o w s , 405-498 registering, 2 0 3 reusing, 394 stock brushes, 322 d r a w i n g t o o l s , 322 pens, 322 streamable, 194 T A p p l i c a t i o n , 1 1 3 , 119-120, 406-411 T a s k W i n d o w , 153 T B u f S t r e a m , 411-412 T B u t t o n , 414-415 T C h e c k B o x , 416-419 T C o l l e c t i o n , 187, 419-427 T C o m b o B o x , 427-430 T C o n t r o l , 430-431 T D i a l o g , 432-436 T D l g W i n d o w , 436-437 T D o s S t r e a m , 437-439 TEdit, 440-447 T E m s S t r e a m , 447-450 T G r o u p B o x , 450-452 T L i s t B o x , 452-456 T M D I C l i e n t , 457-458 T M D I W i n d o w , 459-464 T O b j e c t , 188, 464-465 TRadioButton, 465
Index
T S c r o l l B a r , 466-471 T S c r o l l e r , 471-478 T S o r t e d C o l l e c t i o n , 479-481 TStatic, 482-484 T S t r C o l l e c t i o n , 484-486 T S t r e a m , 486-491 T W i n d o w , 113, 116, 186, 491-498 uninitialized, 6 3 2 w i n d o w , 114-116 O b j e c t W i n d o w s , 3 0 , 79-80, 506-508 hierarchy, 112-115 library, 8 0 , 383 o b j e c t s , 405-498 O E M tables, 6 6 7 O e m K e y S c a n function, 668 O e m T o A n s i f u n c t i o n , 784 O e m T o A n s i B u f f p r o c e d u r e , 784 O F reserved w o r d , 6 0 7 O f f s e t C l i p R g n f u n c t i o n , 801 OffsetRect p r o c e d u r e , 8 4 3 OffsetRgn function, 850 O f f s e t V i e w p o r t O r g f u n c t i o n , 834 OffsetWindowOrg function, 834 O O P (object-oriented p r o g r a m m i n g ) , 101-102 o p c o d e , 624 O p e n c o m m a n d , 11 O p e n File e d i t o r c o m m a n d , 3 7 Open-Configuration-File dialog b o x , 26 O p e n C l i p b o a r d f u n c t i o n , 641 O p e n C o m m f u n c t i o n , 732 O p e n F i l e function, 739 O p e n l c o n function, 663 opening c l i p b o a r d , 641 files, 11, 3 7 , 224 w i n d w s , 29 O p e n S o u n d f u n c t i o n , 774 operands, 624 operations floating p o i n t , 622-632 non-supported, 622 p o i n t e r , 631
o p e r a t o r s , ( : = ) a s s i g n m e n t , 64 O p t i m a l Fill o p t i o n , 3 7 options A u t o Save, 26 C o m m a n d Set, 26 c o m p i l e r , 39-40 D e b u g I n f o i n E X E , 23 E d i t o r O p t i o n s g r o u p , 25 G r o u p - U n d o , 15 L i n k Buffer File, 23 M a p File, 23 menu, 7 O p t i m a l Fill, 37 Right M o u s e B u t t o n , 26 O p t i o n s m e n u , 22-28 O p t i o n s / C o m p i l e r c o m m a n d , 22 Options/Directories i n p u t b o x e s , 24 Options/Linker c o m m a n d , 23 O p t i o n s / O p e n c o m m a n d , 26 Options/Preferences m e n u c o m m a n d , 25 Options/Save As c o m m a n d , 2 7 Options/Save c o m m a n d , 26 O r d f u n c t i o n , 54 o r d i n a l types, 5 2 , 601-602, 6 0 5 , 618 o r d i n a l variable types, 52 origins, logical, 318 o v e r l a p p e d w i n d o w s , 712 overriding m e t h o d s , 2 2 7
p P a c k T i m e p r o c e d u r e , 569 Paint m e s s a g e , 186 Paint m e t h o d , 193 P a i n t D C display c o n t e x t , 192 p a i n t i n g , 186, 194, 6 9 8 end, 700 pixels, 799 PaintRgn function, 850 P a l e t t e R G B f u n c t i o n , 792 palettes Alignment, 257 Tools, 257
919
920
T
u
r
r
j
o
Pascal for W i n d o w s B i b l e
Parameters d i a l o g b o x , 19 parent w i n d o w s e n u m e r a t i o n , 672 h a n d l e s , 673 top-level, 673 parsing, 169 PAS (Pascal) c o d e , 127 Paste c o m m a n d , 15 Paste from C l i p b o a r d e d i t o r c o m m a n d , 33 pasting from c l i p b o a r d , 348-352 PatBlt f u n c t i o n , 798 P C o l l e c t i o n t y p e , 188 P e e k M e s s a g e f u n c t i o n , 694 P E N . R E S r e s o u r c e file, 303 pens creating, 322 default, 322 logical, 8 2 4 m o d i f y i n g , 307-311 stock, 322 size, 306 P F i l e D i a l o g p o i n t e r , 135 p h a s e s p a c e , 170 Pie f u n c t i o n , 8 5 3 pixels, 113-114, 128, 875 painting, 799 place markers, 37 PlayMetaFile f u n c t i o n , 8 4 0 PlayMetaFileRecord p r o c e d u r e , 8 4 0 p o i n t e r types, 60-62, 6 1 0 , 614 p o i n t e r s , 60-61, 2 1 5 , 875 buffer, 4 1 2 m o u s e , 385 n o n t y p e d , 187 o p e r a t i o n s , 631 PFileDialog, 135 string, 543 type, 6 0 0 v a l u e s , 510 V M T , 200 points attractors, 167 c a l c u l a t e d , 186
calculating, 186 collecting, 189-192 deriving, 188 device, 808 floating overflow, 632 underflow, 632 i n streams, 199 logical, 8 0 8 r e a d i n g , 202 saving, 201 sets, 186 storing, 198 stream, retrieving from, 201-203 polymorphism, 90 Polygon function, 853 p o l y g o n s , filling m o d e , 8 1 6 Polyline f u n c t i o n , 832 p o l y m o r p h i c c o l l e c t i o n s , 187, 8 7 6 p o l y m o r p h i c type, 8 7 6 p o l y m o r p h i s m , 86-88, 157, 2 0 3 , 8 7 6 PolyPolygon function, 853 pop-up menus creating, 6 8 3 floating, 6 9 1 handles, 687 p o p - u p w i n d o w s , 671 creating, 7 1 2 retreiving, 7 1 8 P o s t A p p M e s s a g e f u n c t i o n , 694 P o s t M e s s a g e f u n c t i o n , 695 P o s t Q u i t M e s s a g e p r o c e d u r e , 695 Preferences d i a l o g b o x , 25 Primary File d i a l o g b o x , 20-21 Print c o m m a n d , 12 Printer S e t u p c o m m a n d , 13 printers, setting u p , 13 printing, 12 p r o c e d u r a l types, 62 procedure calls, 6 9 headings, 69 statement, 6 9
Index
procedures Abstract, 506 A d j u s t W i n d o w R e c t , 712 A d j u s t W i n d o w R e c t E x , 712 AnimatePalette, 803 AnsiToOemBuff, 780 A s s i g n C r t , 516 BringWindowToTop, 659 CheckDlgButton, 646 CheckRadioButton, 646 ClientToScreen, 808 C l i p C u r s o r , 642 C l o s e S o u n d , 773 CloseWindow, 659 C l r E o l , 517 C l r S c r , 517 CopyRect, 842 CreateCaret, 636 C r e a t e D i r , 572 C u r s o r T o , 518 declaration, 69 DestroyCaret, 636 D i s k S i z e , 574 D i s p o s e S t r , 506 D o n e W i n C r t , 518 D O S 3 C a l l , 761 DrawFocusRect, 699, 852 D r a w M e n u B a r , 684 EndDeferWindowPos, 660 EndDialog, 653 EndPaint, 700 Fail, 624 FindFirst, 579 F r a m e R e c t , 701 FreeLibrary, 7 5 7 F r e e M u l t i S e l , 506 F r e e P r o c I n s t a n c e , 758 G D I ( G r a p h i c s D e v i c e Interface), 7 9 3 , 856-858 b i t m a p , 794-800 c l i p p i n g , 800-802 c o l o r palette, 803-807 coordinate-translation, 807-809
device-context, 809-811 device-independent bitmap, 812-814 drawing-attribute, 815-818 d r a w i n g - t o o l , 819-825 e n v i r o n m e n t , 826-827 font, 827-830 line-drawing, 830-832 m a p p i n g , 832-837 metafile, 837-840 printer-control, 841 r e c t a n g l e , 842-844 r e g i o n , 844-851 s h a p e - d r a w i n g , 851-854 text-drawing, 855-858 GetCaretPos, 636 G e t C B r e a k , 585 GetClientRect, 660 G e t C o d e l n f o , 771 G e t C u r D i r , 572 GetCursorPos, 643 G e t D a t e , 568 GetFAttr, 580 G e t F T i m e , 568 G e t l n t V e c , 581 GetKeyboardState, 666 GetScrollRange, 707 GetSystemDirectory, 736 G e t T i m e , 569 GetVerify, 585 G e t W i n d o w R e c t , 661 G l o b a l F i x , 771 GlobalNotify, 749 G o t o X Y , 519 headers, 621 HideCaret, 637 identifiers, 6 2 6 InflateRect, 8 4 3 InitWinCrt, 519 interrupt, 6 1 9 Intr, 582 invalid, 6 2 2 InvalidateRect, 7 0 3 InvalidateRgn, 703
921
922
T u r b o Pascal for W i n d o w s B i b l e
InvertRect, 704 L i m i t E m s P a g e s , 751 L i n e D D A , 831 MapDialogRect, 657 m e m o r y m a n a g e m e n t , 508 M e s s a g e B e e p , 665 MoveWindow, 662 M s D o s , 583 N e t B I O S C a l l , 762 N e w , 188, 875 O e m T o A n s i B u f f , 784 OffsetRect, 8 4 3 P a c k T i m e , 569 PlayMetaFileRecord, 8 4 0 P o s t Q u i t M e s s a g e , 695 RegisterType, 508 R e g i s t e r W O b j e c t s , 508 ReleaseCapture, 678 R e m o v e D i r , 573 R e p l y M e s s a g e , 695 R e s t o r e M e m o r y , 508 ScreenToClient, 809 S c r o l l T o , 521 ScroUWindow, 708 SetCaretBlinkTime, 637 SetCaretPos, 637 S e t C B r e a k , 586 S e t C u r D i r , 573 S e t C u r s o r P o s , 644 S e t D a t e , 570 SetDlgltemlnt, 657 SetDlgltemText, 658 SetDoubleClickTime, 679 SetFAttr, 581 S e t F T i m e , 571 S e t l n t V e c , 584 SetKeyboardState, 668 SetRectEmpty, 844 S e t R e c t R g n , 851 SetScrollRange, 709 S e t S y s C o l o r s , 711 S e t T i m e , 571 SetVerify, 586 SetWindowPos, 663
SetWindowText, 663 ShowCaret, 637 S h o w O w n e d P o p u p s , 663 ShowScrollBar, 709 stream, 508 S w i t c h S t a c k B a c k , 756 S y s t e m unit, 557 T h r o w , 788 T r a c k C u r s o r , 522 U p d a t e W i n d o w , 704 U n p a c k T i m e , 571 ValidateRect, 704 V a l i d a t e R g n , 705 variables, 6 2 2 WaitMessage, 698 W i n C r t unit, 515-516 W i n D o s unit, 566-568 W i n d o w M a n a g e r Interface, 636-792 WriteBuf, 523 W r i t e C h a r , 524 p r o c e s s i n g m e s s a g e s , 120 P r o g r a m M a n a g e r , 344, 385 l i n k i n g t o , 357-366 p r o g r a m m i n g lines, structured, 44 programs components, 69 creating from o b j e c t s , 9 2 figure-drawing, 323-326 figure-filling, 323-326 G D I . E X E , 95 K E R N E L . E X E , 95 U S E R . E X E , 95 p r o p e r t y lists a d d i n g entries, 7 0 6 r e m o v i n g entries, 706 PtlnRect f u n c t i o n , 844 PtlnRegion function, 850 PtrRec r e c o r d type, 510 P U B L I C definition, 6 0 6 p u s h b u t t o n s , 256 Put c o m m a n d , 2 0 0 PutChildren object m e t h o d , 229
Index
Q qualified identifiers, 51 q u e u e system, 6 6 6
R e c t l n R e g i o n f u n c t i o n , 851 RectVisible f u n c t i o n , 8 0 2 R e d o c o m m a n d , 15 redrawing m e n u bars, 684
R $R c o m p i l e r directive, 129, 243 radio buttons, 270, 646 ranges c h e c k i n g , 631 subrange, 616 R e a d B l o c k from D i s k e d i t o r c o m m a n d , 33 R e a d B u f f u n c t i o n , 520 R e a d C o m m function, 733 R e a d K e y f u n c t i o n , 521 real types, 6 1 4 , 6 1 8 real variable types, 55 RealizePalette f u n c t i o n , 805 r e c o r d types, 6 1 2 L o n g R e c , 509 PtrRec, 510 TDialogAttr, 510 T M e s s a g e , 510 T M u l t i S e l R e c , 511 T S c r o l l B a r T r a n s f e r R e c , 511 T S t r e a m R e c , 511-512 T W i n d o w A t t r , 512 W i n D o s unit, 563 W o r d R e c , 513 records d e c l a r a t i o n , 57 fields, 71 Rectangle function, 854 rectangles, 3 2 7 coordinates, 843 filling, 3 2 2 , 7 0 0 f o c u s style, 6 9 9 intersection, 8 4 3 size, 712 u n i o n , 844
m e n u s , 690 references function, 622 indirect, 6 2 2 memory, 624 p r o c e d u r e s , 622 resolving, 9 0 s y m b o l , 625 variable, 6 2 0 regions borders, 848 clipping, 314, 800-801, 870 comparing, 848 filling, 848-850 u p d a t e , 702 register c o m b i n a t i o n , 624 RegisterClass f u n c t i o n , 7 1 9 RegisterClipboardFormat function, 641 registering o b j e c t types, 511-512 o b j e c t s , 203 streams, 195 w i n d o w classes, 7 1 9 RegisterType p r o c e d u r e , 508 R e g i s t e r W O b j e c t s p r o c e d u r e , 508 registration stream, 6 3 2 ReleaseCapture procedure, 678 R e l e a s e D C f u n c t i o n , 704 R e m o v e D i r p r o c e d u r e , 573 RemoveMenu function, 689 R e m o v e P r o p f u n c t i o n , 706 RemoveFontResource function, 830 Rename routine, 628 r e p e a t . . . u n t i l statement, 7 0 R e p l a c e c o m m a n d , 16 Replace-Text d i a l o g b o x , 5, 16-17 r e p l a c i n g text, 16 ReplyMessage procedure, 695
923
924
T
u
r
D
O
Pascal for W i n d o w s B i b l e
R E S (Resource) c o d e , 127 reserved w o r d s , 3 0 , 62-63 A S M , 625 D O , 606 D O W N T O , 609 I M P L E M E N T A T I O N , 612 I N T E R F A C E , 608 O F , 607 T H E N , 609 T O , 609 U N I T , 614 Reset r o u t i n e , 6 2 8 Resize c o r n e r , 10 resource data, 128, 243 editors, 2 4 4 , 255 creating b i t m a p s , 276-278 files, 255 PEN.RES, 303 identifiers, 625 script files, 245-255 specifications, 2 6 6 Resource-Directories i n p u t b o x , 24 r e s o u r c e s , 127-129, 2 4 2 , 8 7 6 attaching, 243 bitmap, 798 c o p y i n g , 243 b e t w e e n files, 2 6 7 files, 244 font, 8 2 8 I D s , 150-155 m i x i n g , 243 script files, 244 string, 8 7 7 r e s p o n s e m e t h o d s , 258 Restore c o m m a n d , 8-9 RestoreDC function, 811 R e s t o r e M e m o r y p r o c e d u r e , 508 restoring c u r s o r - m o v e m e n t , 14 edits, 14 states, 228-229 restricting access, 385 retrieving p o i n t s from s t r e a m , 201-203
R G B color, 797 R G B f u n c t i o n , 792 Right M o u s e B u t t o n o p t i o n s , 26 RoundRect function, 854 routines A p p e n d , 628 Erase, 6 2 8 Rename, 628 Reset, 6 2 8 Rewrite, 6 2 8 R u n m e n u , 18-19 R u n m e t h o d , 120 r u n - t i m e error m e s s a g e s , 626-632 r u n - t i m e errors, 7 2 , 2 9 8 , 5 0 6 , 5 9 1 , 626-632 r u n - t i m e library, 45 R u n / D e b u g g e r c o m m a n d , 18 Run/Parameters c o m m a n d , 19 Run/Run c o m m a n d , 18
s Save All c o m m a n d , 12 Save A s c o m m a n d , 12 Save c o m m a n d , 12 Save File e d i t o r c o m m a n d , 3 7 S a v e D C function, 812 saving files, 12, 3 7 , 224 p o i n t s , 201 states, 228 S c a l e V i e w p o r t E x t f u n c t i o n , 835 ScaleWindowExt function, 835 scope global, 876 local, 8 7 6 screen units, 657 s c r e e n s , clearing, 5 1 7 ScreenToClient procedure, 809 script files, 255 r e s o u r c e , 245-255 Scriptfile r e s o u r c e , 244
Index
scrollbars hiding, 709 positions, 707 thumbs, 707 ScrollDC function, 707 S c r o l l T o p r o c e d u r e , 521 S c r o l l W i n d o w p r o c e d u r e , 708 S e a r c h A g a i n c o m m a n d , 16 S e a r c h m e n u , 16-18 Search/Find Error c o m m a n d , 18, 620 S e a r c h / S h o w Last C o m p i l e Error c o m m a n d , 18 searching, 224 a t o m table, 7 2 6 b y t o p i c , 29 files, 579 for files, 578 for text, 16 segments code, 46 data, 4 6 line, 832 stack, 46 Select-Printer d i a l o g b o x , 13 SelectClipRgn function, 802 S e l e c t O b j e c t f u n c t i o n , 821 SelectPalette f u n c t i o n , 8 0 6 SendDlgltemMessage function, 657 SendDlgltemMsg method, 257 SendMessage function, 696 separating c o d e a n d r e s o u r c e s , 128 server, 353-354 Set Place e d i t o r c o m m a n d , 3 7 SetActiveWindow function, 679 SetBitmapBits function, 799 SetBitmapDimension function, 799 SetBkColor function, 817 SetBkMode function, 818 SetBrushOrg function, 822 SetCapture function, 679 SetCaretBlinkTime procedure, 637 SetCaretPos procedure, 637 S e t C B r e a k p r o c e d u r e , 586
SetClassLong function, 719 SetClassWord function, 720 S e t C l i p b o a r d D a t a f u n c t i o n , 3 4 6 , 641 S e t C l i p b o a r d V i e w e r f u n c t i o n , 642 S e t C o m m B r e a k f u n c t i o n , 733 S e t C o m m E v e n t M a s k f u n c t i o n , 733 S e t C o m m S t a t e f u n c t i o n , 734 S e t C u r D i r p r o c e d u r e , 573 SetCursor function, 644 S e t C u r s o r P o s p r o c e d u r e , 644 SetDate procedure, 570 SetDIBits function, 813 SetDIBitsToDevice function, 814 SetDlgltemlnt procedure, 657 SetDlgltemText procedure, 658 SetDoubleClickTime procedure, 679 SetEnvironment function, 826 S e t E r r o r M o d e f u n c t i o n , 788 SetFAttr p r o c e d u r e , 581 S e t F T i m e p r o c e d u r e , 571 SetFocus function, 679 SetHandleCount function, 740 S e t l n t V e c p r o c e d u r e , 584 SetKeyboardState procedure, 668 S e t M a p M o d e function, 836 SetMapperFlags function, 830 SetMenu function, 690 SetMenuItemBitmaps function, 690 SetMessageQueue function, 696 SetMetaFileBits f u n c t i o n , 8 4 0 SetPaletteEntries f u n c t i o n , 8 0 6 SetParent f u n c t i o n , 675 SetPixel f u n c t i o n , 7 9 9 SetPolyFillMode function, 818 SetProp function, 706 SetRectEmpty procedure, 844 SetRectRgn procedure, 851 SetResourceHandler function, 767 SetROP2 function, 818 sets, 59 SetScrollPos f u n c t i o n , 708 SetScrollRange procedure, 709 S e t S o u n d N o i s e f u n c t i o n , 774 SetStretchBltMode function, 819
925
926
T
u
r
D
O
Pascal for W i n d o w s B i b l e
SetSwapAreaSize function, 756 S e t S y s C o l o r s p r o c e d u r e , 711 SetSysModalWindow function, 680 SetSystemPaletteUse f u n c t i o n , 8 0 6 SetTextAlign f u n c t i o n , 8 5 7 SetTextColor function, 819 SetTextJustification f u n c t i o n , 8 5 7 S e t T i m e p r o c e d u r e , 571 SetTimer function, 680 S e t u p W i n d o w m e t h o d , 227 SetWindowLong function, 720 SetWindowPos procedure, 663 SetWindowsHook function, 670 SetWindowText procedure, 663 SetWindowWord function, 720 SetVerify p r o c e d u r e , 586 SetViewportExt function, 836 SetViewportOrg function, 836 S e t V o i c e A c c e n t f u n c t i o n , 774 S e t V o i c e E n v e l o p e f u n c t i o n , 775 S e t V o i c e N o t e f u n c t i o n , 775 SetVoiceQueueSize function, 776 SetVoiceSound function, 776 SetVoiceThreshold function, 777 SetWindowExt function, 837 SetWindowOrg function, 837 S h o w Last C o m p i l e Error e d i t o r c o m m a n d , 37 ShowCaret procedure, 637 S h o w C u r s o r f u n c t i o n , 644 S h o w O w n e d P o p u p s procedure, 663 ShowScrollBar procedure, 709 S h o w W i n d o w f u n c t i o n , 664 single inheritance, 84 Size c o m m a n d , 8-10 S i z e O f f u n c t i o n , 202 SizeofResource function, 767 sizing w i n d o w s , 10 s o u r c e c o d e , 151 space p h a s e , 170 state, 167-170 speakers, 665 Specific Interface, 157
s p e e c h - r e c o g n i t i o n system, 169 stack s e g m e n t , 4 6 stacks, 631 standard m a p , 170 s t a n d a r d u n i t s , 31 StartSound function, 777 state s p a c e , 167, 170 statements brackets, 64 case, 65 conditions, 67 errors, 6 1 9 F O R , 616 for, 66 goto, 66 if...then...else, 67 inline, 68 large, 6 2 0 procedure, 69 repeat...until, 70 r e p e a t e d e x e c u t i o n , 70-71 w h i l e . . . d o , 70-71 w i t h . . . d o , 71 states button, 499 check boxes, 499 m e m o r y , 508 o f systems, 166 restoring, 228-229 saving, 228-229 v a l u e s , 171 virtual keys, 6 6 6 static constructors, 623 binding, 90 instances, 8 7 7 links, 3 7 0 method, 877 S t o p S o u n d function, 777 Store m e t h o d , 196 storing c a l c u l a t e d p o i n t s , 186 c h e c k b o x e s , 418 p o i n t s in arrays, 187 r e s o u r c e data, 2 4 3
Index
storing p o i n t s , 198
creating s p a c e , 508
strange attractors, 166-171, 8 7 7 c o d e , 172-174 StrCat f u n c t i o n , 540 S t r C o m p f u n c t i o n , 541 S t r C o p y f u n c t i o n , 542 S t r D i s p o s e f u n c t i o n , 542 stream h a n d l i n g c o d e , 196 stream registration r e c o r d , 195 stream types
key n a m e , 6 6 7 length, 601, 617
TBufStream, 200 TDosStream, 200 streamable o b j e c t s , 194 streams, 194-210, 8 7 7 a d d i n g , 392 c o l l e c t i o n s , 194 c o n s t a n t s , 195, 502 D O S , 200 h a n d l i n g , 195 p o i n t s in, 199 procedures, 508 registering, 195, 632 retrieving p o i n t s , 201-203 S t r E C o p y f u n c t i o n , 543 S t r E n d f u n c t i o n , 543 StretchBlt f u n c t i o n , 8 0 0 S t r e t c h D I B i t s f u n c t i o n , 815 stretching m o d e retrieving, 8 1 7 setting, 8 1 9 string variable types, 55-56 strings, 128, 2 4 2 , 8 7 7 allocating o n h e a p s , 548 appending, 540 atom, 727 character, 355 c o m p a r i n g , 541-545 constants, 599, 617 converting t o u p p e r c a s e , 552 t o l o w e r c a s e , 547 c o p y i n g , 542-543 characters, 546 characters b e t w e e n , 548
null-terminated, 4 5 , 129, 539 Pascal, c o n v e r t i n g t o n u l l t e r m i n a t e d , 129 p o i n t e r s , 543 resource, 877 types, 611 unit, 129 Strings unit, 4 5 , 5 3 9 f u n c t i o n s , 539-552 StrLCat f u n c t i o n , 544 S t r L C o m p f u n c t i o n , 544-545 S t r L C o p y f u n c t i o n , 546 StrLen f u n c t i o n , 546 StrLIComp function, 547 S t r L o w e r f u n c t i o n , 547 S t r M o v e f u n c t i o n , 548 S t r N e w f u n c t i o n , 548 StrPas f u n c t i o n , 549 S t r P C o p y f u n c t i o n , 550 StrPos f u n c t i o n , 550 StrRScan f u n c t i o n , 551 StrScan f u n c t i o n , 551 structure, 95-96, 100-101 structured b l o c k s , 386-388 programming and design, 386, 878 types, 56-59 structures, 6 0 1 S t r U p p e r f u n c t i o n , 552 s t X X X X c o n s t a n t s , 502 styles, d y n a m i c , 91-92 subdirectories, 572-573 subrange, 616 S u b r a n g e variable types, 54 surfaces, 314 SwapMouseButton function, 680 Switch T o c o m m a n d , 9 SwitchStackBack procedure, 756 s y m b o l r e f e r e n c e s , 625 s y m b o l i c identifiers, 151
927
928
T
u
r
b
o
Pascal for W i n d o w s B i b l e
symbols, 620, 626
T B u t t o n , 414-415
c o n d i t i o n a l , 621 relocatable, 624 SyncAUVoices f u n c t i o n , 7 7 8 system _ c o l o r s , 711 queue, 666 s p e a k e r , 665 system r e q u i r e m e n t s , 4 system timers, 6 8 0 S y s t e m unit, 45
T C h e c k B o x , 416-419 T C o l l e c t i o n , 419-427 T C o m b o B o x , 427-430
c o n s t a n t s , 554 f u n c t i o n s a n d p r o c e d u r e s , 557 variables, 553 systems c h a o t i c , 171 d y n a m i c , 169 s p e e c h - r e c o g n i t i o n , 169 state of, 166 t w o - d i m e n s i o n a l , 163
T Tab m o d e , 37 Tab-Size i n p u t b o x , 26 TabbedTextOut function, 858 tables ANSI, 667 atom, 726 e d i t o r c o m m a n d s , 33-36 O E M , 667 T A p p l i c a t i o n fields, 407-411 T A p p l i c a t i o n o b j e c t s , 113, 119-120, 406-411 target addresses, 6 2 0 task w i n d o w s , 157-158 Task-List d i a l o g b o x , 9 T a s k C o n t r o l a p p l i c a t i o n , 271-272 tasks, 156-162 m o d e l , 162-163 see also multitasking T a s k W i n d o w object, 153 T B u f S t r e a m , 41-414 T B u f S t r e a m stream type, 2 0 0
T C o n t r o l , 430-431 T D a t e T i m e type, 565 T D i a l o g , 433-436 T D i a l o g A t t r r e c o r d type, 5 1 0 T D l g W i n d o w , 436-437 T D o s S t r e a m , 437-439 T D o s S t r e a m stream type, 2 0 0 TEdit, 440-447 T E m s S t r e a m , 447-450 terminating m o d a l dialog boxes, 653 text c o l o r , 126 c o n t r o l , 654-655 c o p y i n g , 15, 32 cutting, 15, 32 d r a w i n g , 126-127 editing, 222-223 formatted, 699 gray, 702 i n d e n t i n g , 36 pasting, 15 r e m o v i n g , 16 r e p l a c i n g , 16 s e a r c h i n g for, 16 setting, 6 6 3 strings, 128 text editors, 8 7 TextOut function, 858 t f _ X X X X c o n s t a n t s , 503 T G r o u p B o x , 450-452 T H E N reserved w o r d , 6 0 9 T h r o w procedure, 788 tiling w i n d o w s , 2 8 t i m e , 569-571 since r e b o o t , 6 7 7 , 7 1 0 since system started, 6 7 8 timer events, 6 6 6 , 6 7 8 timers, system, 6 8 0 tide bars, 8 T L i s t B o x , 452-456 T M D I C l i e n t , 457-458
Index
T M D I W i n d o w , 459-464 T M e s s a g e r e c o r d t y p e , 510 T M u l t i S e l R e c r e c o r d t y p e , 511 T O reserved w o r d , 6 0 9 ToAscii f u n c t i o n , 785 T O b j e c t , 464-465 T O b j e c t o b j e c t type, 188 toolkits W h i t e w a t e r G r a p h i c s , 861-865 Whitewater Resource Toolkit, 112, 127, 151 T o o l s palette, 2 5 7 top-level w i n d o w s , 6 7 3 , 6 7 9 T P W C o m m a n d - l i n e compiler, 38 T r a c k C u r s o r p r o c e d u r e , 522 T r a c k P o p u p M e n u f u n c t i o n , 691 TRadioButton, 465 TranslateAccelerator f u n c t i o n , 6 9 6 TranslateMDISysAccel function, 697 TranslateMessage function, 697 transmission character, 7 3 0 T r a n s m i t C o m m C h a r f u n c t i o n , 734 TRegisters t y p e , 565 T S c r o l l B a r , 467-471 TScrollBarTransferRec record type, 511 T S c r o l l e r , 471-478 T S e a r c h R e c type, 566 T S o r t e d C o l l e c t i o n , 479-481 TStatic, 482-484 T S t r C o l l e c t i o n , 484-486 T S t r e a m , 487-491 T S t r e a m m e t h o d , 196, 487-491 T S t r e a m R e c r e c o r d t y p e , 511-512 T W i n d o w , 113, 116, 186, 491-498 T W i n d o w A t t r r e c o r d t y p e , 512 t w o - d i m e n s i o n a l systems, 163 two-way c o m m u n i c a t i o n , see d i a l o g type extensibility, 8 7 8 type identifiers, 599 typecasts, 6 1 0 types, 6 0 1 , 8 7 8 abstract, 156, 187, 8 6 9 base, 869
built-in, 8 7 0 case, 6 1 2 C h a r type, 6 1 9 constant, 612 derived, 84 file, 6 1 3 , 6 1 7 integer, 6 0 4 , 614-618 o r d i n a l , 601-605, 6 1 8 P C o l l e c t i o n , 188 pointer, 610, 614 polymorphic, 876 real, 6 1 4 , 6 1 8 record, 612 string, 611 T D a t e T i m e , 565 TRegisters, 565 T S e a r c h R e c , 566 user-defined, 878
u U n d o c o m m a n d , 14, 224 U n g e t C o m m C h a r f u n c t i o n , 734 U n h o o k W i n d o w s H o o k function, 670 Unindent editor c o m m a n d , 37 UnionRect function, 844 U N I T reserved w o r d , 614 Unit-Directories i n p u t b o x e s , 24 u n i t s , 44-50, 8 7 8 base, 653 dialog box, 657 headings, 48 H e l p W n d , 229 layout, 4 8 n a m e m i s m a t c h , 611 precompiled, 47 screen converting, 657 s t a n d a r d , 31 Strings, 4 5 , 129, 539 S y s t e m , 4 5 , 553 v e r s i o n m i s m a t c h , 611
929
930
T u f
t > o Pascal for W i n d o w s B i b l e
W i n C r t , 4 5 , 107-108, 5 1 5 , 525-526, 8 7 8 W i n D o s , 4 5 , 561-563 W i n P r o c s , 114, 8 7 9 W i n T y p e s , 4 5 , 114, 8 7 9 W O b j e c t s , 114, 8 7 9 UnlockData function, 756 U n l o c k R e s o u r c e f u n c t i o n , 768 U n l o c k S e g m e n t f u n c t i o n , 7 5 7 , 772 U n p a c k T i m e p r o c e d u r e , 571 UnrealizeObject function, 822 U n r e g i s t e r C l a s s f u n c t i o n , 721 UpdateColors function, 807 U p d a t e W i n d o w p r o c e d u r e , 704 u p p e r b o u n d , 602 u s e r disk, 224 u s e r - d e f i n e d type, 8 7 8 U S E R . E X E p r o g r a m , 95
V ValidateRect p r o c e d u r e , 704 V a l i d a t e R g n p r o c e d u r e , 705 validating client areas, 704 values attributes, 7 2 0 p l o t t i n g , 171 variable references, 6 2 0 variable types, 50-51, 56 B o o l e a n , 52 C h a r , 53 e n u m e r a t e d , 54 ordinal, 52, 618 real, 55 string, 55 s u b r a n g e , 54 variables control, 616 D o s E r r o r , 567 d o u b l e - w o r d - l e n g t h , 509 dynamic, 92, 873 excessive, 6 1 6
file type, 6 1 3 function, 622 HeapError, 298 identifiers, 6 0 0 integer t y p e , 616-618 p o i n t e r type, 6 1 0 p r o c e d u r e , 622 reading, 610 real type, 6 1 8 r e c o r d type, 6 1 2 string types, 611 S y s t e m unit, 553 very c o l d link, 354 v i d e o adapters, 4 views, 92-93 virtual c o n s t r u c t o r s , 623 virtual keys, 6 6 7 state, 6 6 6 VIRTUAL keyword, 623 VkKeyScan function, 668 V M T (virtual m e t h o d t a b l e ) , 8 7 8 V M T pointer, 200
w WaitMessage procedure, 698 WaitSoundState function, 778 w a r m link, 354 w b _ X X X X c o n s t a n t s , 503 W h e r e X f u n c t i o n , 522 W h e r e Y f u n c t i o n , 523 w h i l e . . . d o statement, 70-71 Whitewater Graphics Toolkit, 861-865 W h i t e w a t e r R e s o u r c e T o o l k i t , 112, 127, 151 W i n C r t unit, 4 5 , 107-108, 525-526, 878 f u n c t i o n s , 515-516, 520-523 p r o c e d u r e s , 515-524 W i n D o s unit, 4 5 , 561-563 c o n s t a n t s , 561-563 file-attribute c o n s t a n t s , 562
Index
f i l e - m o d e c o n s t a n t s , 562 flag c o n s t a n t s , 561 f u n c t i o n s , 566-567, 575-578, 584 p r o c e d u r e s , 566-574, 579-586 r e c o r d types, 563 types, 565-566 variables, 567 w i n d o w classes d e l e t i n g , 721 registering, 7 1 9 W i n d o w M a n a g e r Interface f u n c t i o n s a n d p r o c e d u r e s , 635-721 W i n d o w m e n u , 28 w i n d o w o b j e c t s , 114-116 Window/Arrange Icons c o m m a n d , 28 W i n d o w / C a s c a d e c o m m a n d s , 28 W i n d o w / T i l e c o m m a n d , 28 WindowFromPoint function, 675, 809 windows active, 5 applications, 3 c a p t i o n s , 6 6 1 , 663 c a s c a d i n g , 28 c h i l d , 216 creating, 712 e n u m e r a t i o n , 672 parent, 671 clearing, 197 client area, 315 control, 654 create, 96-99 C R T , 519 dialog, 5 edit, 5-6 e n u m e r a t i o n , 672 flashing, 664 frame, 216 handles, 677 h e l p , 2 2 9 , 230-236 h i d i n g , 664 i c o n i c , 661 inheriting, 117
maximized, 662 maximizing, 8 minimized, 663 minimizing, 8 m o v i n g , 8-9 o b j e c t s , 102-105, 114-116 o p e n i n g , 29 o v e r l a p p e d , 712 p o p - u p , 671 creating, 712 hiding, 663 position, 663 r e s o u r c e files, attaching t o , 244 size, 6 6 3 sizing, 8, 10 structure, 95-96, 100-101 task, 157-158, 2 2 0 text, 6 6 3 tiling, 28 top-level, 6 7 9 u p d a t i n g c o n t e n t s , 186 visible, 662 Windows Application Programming Interface (API), 31 W i n d o w s G r a p h i c s D e v i c e Interface ( G D I ) , 879 W i n d o w s / C l o s e All c o m m a n d , 29 W i n E x e c f u n c t i o n , 724 W i n H e l p f u n c t i o n , 725 W i n P r o c s unit, 114, 8 7 9 W i n T y p e s unit, 4 5 , 114, 8 7 9 w i t h . . . d o statement, 71 w m C o m p a c t i n g message, 299 W M D D E A C K m e s s a g e , 354 W M D D E A D V I S E m e s s a g e , 354 W M D D E I N I T I A T E m e s s a g e , 354 W M D D E R E Q U E S T m e s s a g e , 354 W M D D E T E R M I N A T E message, 354 w m J L B u t t o n D o w n m e s s a g e , 123 w m M D I A c t i v a t e m e s s a g e , 222 w m P a i n t m e s s a g e , 186 w m X X X X c o n s t a n t s , 504 W O b j e c t s unit, 114, 8 7 9
93I
932
T u r b o Pascal for W i n d o w s B i b l e
w o r d p r o c e s s o r s , see text editors W o r d R e c r e c o r d t y p e , 513 Write B l o c k t o D i s k e d i t o r c o m m a n d , 33 W r i t e B u f p r o c e d u r e , 523 W r i t e C h a r p r o c e d u r e , 524 W r i t e C o m m f u n c t i o n , 735 WritePrivateProfileString f u n c t i o n , 742 WriteProfileString f u n c t i o n , 742 wvsprintf f u n c t i o n , 785
x-z x g r a p h i n g , 163 x-axis, 171 y g r a p h i n g , 163 y-axis, 171 Yield function, 788
IF Y O U R
COMPUTER
USES
3 1/2-INCH
DISKS
T h o u g h m a n y p e r s o n a l c o m p u t e r s u s e 5 1/4-inch disks to store i n f o r m a t i o n , s o m e n e w e r c o m p u t e r s u s e 3 1/2-inch disks. If y o u r c o m p u t e r requires 3 1/2-inch disks, return this f o r m to S A M S t o o b t a i n (free o f charge) a 3 1/2-inch disk to u s e with this b o o k . S i m p l y c o m p l e t e the i n f o r m a t i o n o n this f o r m a n d mail this p a g e t o :
Turbo Pascal for Windows™ Bible Disk Exchange @
SAMS 11711 N. College A v e n u e , Suite 140 Carmel, IN
46032
Name: _ Address: City: Phone:
State:
ZIP:
30212
TURBO PASCAL FOR WINDOWS
B I B L E T u r b o P a s c a l for W i n d o w s is r e a d y to m a k e y o u a s u c c e s s ful W i n d o w s applications develo p e r . First, you n e e d a clear, h a n d s - o n guide that s h o w s you how. S a m s T u r b o P a s c a l for Windows Bible m a k e s Windows challenging p r o g r a m m i n g style simple e n d m a n a g e a b l e ! Y o u learn f r o m a structured e n v i r o n m e n t built a r o u n d proven p r o g r a m m i n g e x a m p l e s a n d listings o n a bound-in disk. T h e b o o k quickly familiarizes y o u with O b j e c t W i n d o w s , the l a n g u a g e s y n t a x , a n d other e s s e n t i a l e l e m e n t s of application d e v e l o p m e n t . M o r e c o m p l e x a s p e c t s of W i n d o w s p r o g r a m m i n g are then explored in detail, including m e m o r y management, Dynamic Data E x c h a n g e , D y n a m i c Link Libraries, and professional d e s i g n c o n s i d e r a t i o n s that m a k e y o u r p r o g r a m m i n g efficient—and expressive. O n c e
you're c o m f o r t a b l e with the O O P b a s i c s , study this s e c t i o n . You'il b e u p to s p e e d in a hurry. T h i s b o o k a l s o c o n t a i n s the m o s t c o m p l e t e r e f e r e n c e available. A complete reference s e c t i o n — p a c k e d with the information you need — provides a n invaluable r e s o u r c e y o u c a n turn to a g a i n a n d a g a i n . It's e a s y to e n s u r e y o u r T u r b o P a s c a l for W i n d o w s s u c c e s s . G e t the big picture with t h e T u r b o P a s c a l for W i n d o w s Bible! G a r y E n t s m i n g e r is a writer, p r o g r a m m e r , a n d consultant. H e w a s a n a s s o c i a t e editor for Micro
Cornucopia
(the
t e c h n i c a l journal) for five y e a r s . In addition to writing c o l u m n s for B o r l a n d ' s Turbo Technix magazine, he has a u t h o r e d b o o k s o n objectoriented p r o g r a m m i n g .
INFORMATION CENTER INT
ADV
HOW TO REFERENCE
IBM COMPATIBLE PROGRAMMING TURBO PASCAL FOR WINDOWS
$39.95 US/$49.95 C A N
9 780672 302121
ISBN 0 672 30212 8
The T u r b o P a s c a l f o r W i n d o w s Bible
shows you the most efficient ways to: Create and develop Windows applications • Program expert graphics with the Whitewater Resource Toolkit i Design and develop your own interfaces with ObjectWindows 1 Share various object libraries with DLL • Debug and fine tune your applications Manage your Turbo Pascal for Windows projects