Turbo Pascal Version 6.0 Turbo Vision 1990
Turbo Pascal Version 6.0 Turbo Vision 1990
Turbo PascafBJ
Version 6.0
ii
Selected and focused views . . . . . . . . . . .. 95 Chapter 5 Event-driven
Finding the focused view ........... 96 programming 109
How does a view get the focus? ... . .. 96 Bringing Turbo Vision to life ......... 109
The focus chain ... . . . . . . . . . . . . . . . .. 97 Reading the user's input ........... 109
Modal views ........................ 97 The nature of events . . . . . . . . . . . . . . . .. 111
Modifying default behavior ........... 98 Kinds of events ................... 111
The Options flag word . . . . . . . . . . . . .. 98 Mouse events .................. 112
ofSelectable ..................... 99 Keyboard events . . . . . . . . . . . . . . .. 112
ofTopSelect ..................... 99 Message events ..... . . . . . . . . . . .. 112
ofFirstClick ..................... 99 "Nothing" events ............... 112
ofFramed ....................... 99 Events and commands ............. 113
ofpreProcess .................... 99 Routing of events ................... 113
ofpostProcess . . . . . . . . . . . . . . . . . . .. 99 Where do events come from? ....... 113
ofBuffered ..................... 100 Where do events go? .............. 114
ofTileable ...................... 100 Positional events ................ 114
ofCenterX . . . . . . . . . . . . . . . . . . . . .. 100 Focused events ................. 115
ofCenterY . . . . . . . . . . . . . . . . . . . . .. 100 Broadcast events . . . . . . . . . . . . . . .. 115
ofCentered . . . . . . . . . . . . . . . . . . . .. 101 User-defined events . . . . . . . . . . . .. 116
The GrowMode flag byte ........... 101 Masking events ................... 116
gfGrowLoX .................... 101 Phase ........................... 116
gfGrowLoY .................... 101 The Phase field ................. 118
gfGrowHiX .................... 101 Commands ........................ 119
gfGrowHiY .................... 101 Defining commands .. . . . . . . . . . . . .. 119
gfGrowAll ..................... 101 Binding commands ............... 120
gfGrowRel ..................... 101 Enabling and disabling commands .. 120
The DragMode flag byte ........... 102 Handling events .................... 121
dmDragMove .................. 102 The event record .................... 122
dmDragGrow .................. 102 Clearing events . . . . . . . . . . . . . . . . . .. 123
dmLimitLoX ................... 102 Abandoned events ................ 123
dmLimitLoY ................... 102 Modifying the event mechanism ...... 124
dmLimitHiX ................... 102 Centralized event gathering ........ 124
dmLimitHiY ................... 102 Overriding GetEvent. . . . . . . . . . . . .. 125
dmLimitAll .................... 102 Using idle time ................... 125
State flag and SetState ............. 102 Inter-view communication ........... 126
Acting on a state change ......... 103 Intermediaries .................... 126
What color is your view? ............. 104 Messages among views . . . . . . . . . . .. 127
Color palettes .................... 105 Who handled the broadcast? ....... 128
Inside color palettes ............... 105 Is anyone out there? ............. 128
The GetColor method ............. 106 Who's on top? .................. 129
Overriding the default colors ....... 107 Calling HandleEvent .............. 129
Adding new colors . . . . . . . . . . . . . . .. 108 Help context ..................... 130
iii
Chapter 6 Writing safe programs 131 The stream mechanism .............. 159
All or nothing programming ......... 131 The Put process . . . . . . . . . . . . . . . . . .. 159
. The safety pool ................... 132 The Get process . . . . . . . . . . . . . . . . . .. 160
The ValidView method .......... 133 Handling nil object pointers ........ 160
Non-memory errors ............... 134 Collections on streams: A complete
Reporting errors ................ 135 example ........................... 160
Major consumers ................. 135 Adding Store methods. ,.......... 161
Registration records ............. 162
Chapter 7 Collections 137 Registering . . . . . . . . . . . . . . . . . . . .. 163
Collection objects ................... 138 Writing to the stream . . . . . . . . . . .. 163
Collections are dynamically sized ... 138 Who gets to store things? ............ 164
Collections are polymorphic . . . . . . .. 138 Subview instances ................ 164
Type checking and collections ...... 138 Peer view instances ............... 165
Collecting non-objects ........... 139 Storing and loading the desktop ...... 166
Creating a collection. . . . . . . . . . . . . . . .. 139 Copying a stream .... . . . . . . . . . . . . . .. 167
Itera tor methods .................... 141 Random-access streams .............. 167
The ForEach iterator . . . . . . . . . . . . . .. 141 Non-objects on streams .............. 168
The FirstThat and LastThat iterators 142 Designing your own streams ......... 168
Sorted collections ................... 143 Stream error handling ............. 168
String collections . . . . . . . . . . . . . . . . . . .. 144
Iterators revisited ................. 145 Chapter 9 Resources 169
Finding an item ................. 146 Why use resources? ................. 169
Polymorphic collections ............. 146 What's in a resource? ................ 170
Collections and memory management 149 Creating a resource ................. 171
Reading a resource . . . . . . . . . . . . . . . . .. 172
Chapter 8 Streams 151 String lists ......................... 173
The question: Object I/O ............. 152 Making string lists ................ 174
The answer: Streams ................ 152
Streams are polymorphic. . . . . . . . . .. 152 Chapter 10 Hints and tips 175
Streams handle objects ............. 153 Debugging Turbo Vision applications 175
Essential stream usage ............... 153 It doesn't get there ................ 176
Setting up a stream . . . . . . . . . . . . . . .. 154 Hiding behind a mask . . . . . . . . . .. 176
Reading and writing a stream ...... 154 Stolen events .... . . . . . . . . . . . . . .. 176
Putting it on . . . . . . . . . . . . . . . . . . .. 155 Blame your parents ............. 177
Getting it back . . . . . . . . . . . . . . . . .. 155 It doesn't do what I expect ......... 177
In case of error .................. 156 It hangs . . . . . . . . . . . . . . . . . . . . . . . . .. 177
Shutting down the stream . . . . . . . . .. 156 Porting applications to Turbo Vision ... 178
Making objects streamable ........... 156 Scavenge your old code. . . . . . . . . . .. 178
Load and Store methods ........... 156 Rethink your organization ......... 179
Stream registration . . . . . . . . . . . . . . .. 157 Using bitmapped fields . . . . . . . . . . . . .. 180
Object ID numbers .............. 158 Flag values. . . . . . . . . . . . . . . . . . . . . .. 180
The automatic fields . . . . . . . . . . . .. 158 Bit masks ........................ 180
Register here ..................... 159 Bitwise operations ................ 181
Registering standard objects ........ 159 Setting a bit .................... 181
iv
Clearing a bit . . . . . . . . . . . . . . . . . .. 181 The App unit . . . . . . . . . . . . . . . . . . . . . .. 196
Checking bits ................... 182 Types ........................... 196
Using masks ................... 182 Variables ........................ 196
Summary ........................ 182 The Menus unit . . . . . . . . . . . . . . . . . . . .. 197
Types ........................... 197
Part 3 Turbo Vision Reference
Procedures and functions .......... 197
Chapter 11 How to use the TMenuItem functions ........... 197
reference 185 TMenu routines ................ 197
How to find what you want .......... 185 TStatusLine functions ........... 197
Objects in general ................... 186 The Drivers unit .................... 198
Naming conventions ................ 186 Types ........................... 198
Constants ........................ 198
Chapter 12 Unit cross reference 189 Mouse button state masks ........ 198
The Objects unit .................... 189 Event codes .................... 198
Types ........................... 190 Event masks ................... 198
Type conversion records ......... 190 Keyboard state and shift masks ... 199
Objects unit types ............. .. 190 Standard command codes . . . . . . .. 199
Constants . . . . . . . . . . . . . . . . . . . . . . .. 190 TDialog standard commands ..... 199
Stream access modes ............ 190 Screen modes. . . . . . . . . . . . . . . . . .. 199
Stream error codes .............. 190 Variables ........................ 200
Maximum collection size . . . . . . . .. 191 Initialized variables ............. 200
Collection error codes ........... 191 UninitiaIized variables ........... 200
Variables ........................ 191 System error handler variables . . .. 200
Procedures and functions .......... 191 Procedures and functions .......... 201
The Views unit ..................... 192 Event manager procedures ....... 201
Types ........................... 192 Screen manager procedures ...... 201
Constants . . . . . . . . . . . . . . . . . . . . . . .. 192 Default system error handler
TView State masks .............. 192 function ....................... 201
Views unit constants ............ 193 System error handler procedures .. 201
TView Option masks ............ 193 Keyboard support functions ...... 201
TView GrowMode masks ........ 193 String formatting procedure ...... 201
TView DragMode masks. . . . . . . .. 193 Buffer move procedures ......... 202
Scroll bar part codes . . . . . . . . . . . .. 194 String length function ........... 202
Window flag masks ............. 194 Driver initialization ............. 202
TWindow palette entries ......... 194 The TextView unit .................. 202
Standard view commands . . . . . . .. 194 Types ....... _. . . . . . . . . . . . . . . . . .. 202
Variables ........................ 194 Procedure. . . . . . . . . . . . . . . . . . . . . . .. 202
Function . . . . . . . . . . . . . . . . . . . . . . . .. 195 The Memory unit ................... 202
The Dialogs unit .................... 195 Variables ........................ 203
Types ........................... 195 Procedures and functions .......... 203
Constants . . . . . . . . . . . . . . . . . . . . . . .. 195 The HistList unit . . . . . . . . . . . . . . . . . . .. 203
Button flags .................... 195 Variables ........................ 203
Procedures and functions .......... 196 Procedures and functions .......... 204
v
Chapter 13 Object reference 205 Fields ........................... 236
TSample object ..................... 206 Methods . . . . . . . . . . . . . . . . . . . . . . . .. 237
Fields ........................... 206 THistory . . . . . . . . . . . . . . . . . . . . . . . . . .. 244
Methods ... . . . . . . . . . . . . . . . . . . . . .. 206 Fields ........................... 244
TApplication ....................... 207 Methods . . . . . . . . . . . . . . . . . . . . . . . .. 245
Methods . . . . . . . . . . . . . . . . . . . . . . . .. 207 Palette . . . . . . . . . . . . . . . . . . . . . . . . . .. 245
TBackground . . . . . . . . . . . . . . . . . . . . . .. 208 THistoryViewer .................... 246
Field ............................ 208 Field· ............................ 246
Methods . . . . . . . . . . . . . . . . . . . . . . . .. 208 Methods . . . . . . . . . . . . . . . . . . . . . . . .. 246
Palette . . . . . . . . . . . . . . . . . . . . . . . . . .. 209 Palette . . . . . . . . . . . . . . . . . . . . . . . . . .. 247
TBufStream ........................ 209 THistoryWindow ................... 247
Fields ........................... 210 Field ............................ 247
Methods . . . . . . . . . . . . . . . . . . . . . . . .. 210 Methods . . . . . . . . . . . . . . . . . . . . . . . .. 247
TButton ........................... 212 Palette . . . . . . . . . . . . . . . . . . . . . . . . . .. 248
Fields ........................... 212 TInputLine . . . . . . . . . . . . . . . . . . . . . . . .. 248
Methods . . . . . . . . . . . . . . . . . . . . . . . .. 213 Fields ........................... 249
Palette ........................... 215 Methods . . . . . . . . . . . . . . . . . . . . . . . .. 250
TCheckBoxes ....................... 215 Palette . . . . . . . . . . . . . . . . . . . . . . . . . .. 252
Fields ........................... 215 TLabel ............................. 253
Methods ......................... 216 Fields ........................... 253
Palette. . . . . . . . . . . . . . . . . . . . . . . . . .. 216 Methods . . . . . . . . . . . . . . . . . . . . . . . .. 253
TCluster ........................... 217 Palette . . . . . . . . . . . . . . . . . . . . . . . . . .. 254
Fields ........................... 217 TListBox . . . . . . . . . . . . . . . . . . . . . . . . . .. 255
Methods .. . . . . . . . . . . . . . . . . . . . . . .. 218 Field ............................ 255
Palette . . . . . . . . . . . . . . . . . . . . . . . . . .. 220 Methods . . . . . . . . . . . . . . . . . . . . . . . .. 256
TCollection ........................ 221 Palette . . . . . . . . . . . . . . . . . . . . . . . . . .. 257
Fields ........................... 221 TListViewer . . . . . . . . . . . . . . . . . . . . . . .. 258
Methods . . . . . . . . . . . . . . . . . . . . . . . .. 222 Fields ........................... 258
TDeskTop . . . . . . . . . . . . . . . . . . . . . . . . .. 227 Methods . . . . . . . . . . . . . . . . . . . . . . . .. 259
Methods .. . . . . . . . . . . . . . . . . . . . . . .. 227 Palette. . . . . . . . . . . . . . . . . . . . . . . . . .. 261
TDialog . . . . . . . . . . . . . . . . . . . . . . . . . . .. 228 TMenuBar ......................... 262
Methods ... . . . . . . . . . . . . . . . . . . . . .. 229 Methods . . . . . . . . . . . . . . . . . . . . . . . .. 262
Palette . . . . . . . . . . . . . . . . . . . . . . . . . .. 229 Palette . . . . . . . . . . . . . . . . . . . . . . . . . .. 263
TDosStream . . . . . . . . . . . . . . . . . . . . . . .. 230 TMenuBox . . . . . . . . . . . . . . . . . . . . . . . .. 263
Fields ........................... 231 Methods . . . . . . . . . . . . . . . . . . . . . . . .. 263
Methods ......................... 231 Palette ........................... 264
TEmsStream ....................... 232 TMenuView. . . . . . . . . . . . . . . . . . . . . . .. 264
Fields ........................... 232 Fields ........................... 265
Methods .. . . . . . . . . . . . . . . . . . . . . . .. 233 Methods . . . . . . . . . . . . . . . . . . . . . . . .. 265
TFrame ............................ 234 Palette . . . . . . . . . . . . . . . . . . . . . . . . . .. 267
Methods .. . . . . . . . . . . . . . . . . . . . . . .. 234 TObject ............................ 267
Palette . . . . . . . . . . . . . . . . . . . . . . . . . .. 235 Methods . . . . . . . . . . . . . . . . . . . . . . . .. 267
TGroup ............................ 235 TParamText ........................ 268
vi
Fields ........................... 268 TStrListMaker ..................... . 300
Methods . . . . . . . . . . . . . . . . . . . . . . . .. 268 Methods ........................ . 301
Palette . . . . . . . . . . . . . . . . . . . . . . . . . .. 269 TTerminal ........................ . 302
TPoint ............................. 269 Fields ........................... . 302
Fields ........................... 269 Methods ........................ . 303
fProgram . . . . . . . . . . . . . . . . . . . . . . . . .. 270 Palette .......................... . 304
Methods . . . . . . . . . . . . . . . . . . . . . . . .. 270 TTextDevice ....................... . 305
Palettes . . . . . . . . . . . . . . . . . . . . . . . . .. 274 Methods ........................ . 305
TRadioButtons ..................... 276 Palette ........................... . 305
Methods . . . . . . . . . . . . . . . . . . . . . . . .. 277 TView ............................ . 306
Palette . . . . . . . . . . . . . . . . . . . . . . . . . .. 277 Fields .......................... . 306
TRect .............................. 278 Methods ........................ . 309
Fields ........................... 278 TWindow ......................... . 321
Methods . . . . . . . . . . . . . . . . . . . . . . . .. 278 Fields .......................... . 322
TResourceCollection ................ 279 Methods ........................ . 322
TResourceFile ...................... 279 Palette .......................... . 325
Fields ........................... 280
Methods . . . . . . . . . . . . . . . . . . . . . . . .. 280 Chapter 14 Global reference 327
TScrollBar ......................... 282 Sample procedure ............... '.' .. 327
Fields ........................... 282 Abstract procedure ................. . 328
Methods . . . . . . . . . . . . . . . . . . . . . . . .. 283 Application variable ................ . 328
Palette . . . . . . . . . . . . . . . . . . . . . . . . . .. 286 AppPalette variable ................ . 328
TScroller ........................... 286 apXXXX constants ................. . 329
Fields ........................... 286 AssignDevice procedure ............ . 329
Methods . . . . . . . . . . . . . . . . . . . . . . . .. 287 bfXXXX constants ................. . 329
Palette . . . . . . . . . . . . . . . . . . . . . . . . . .. 288 ButtonCount variable ............... . 330
TSortedCollection . . . . . . . . . . . . . . . . . .. 289 CheckSnow variable ................ . 330
Methods . . . . . . . . . . . . . . . . . . . . . . . .. 289 ClearHistory procedure ............. . 330
TStaticText ......................... 290 ClearScreen procedure .............. . 331
Field ............................ 291 cmXXXX constants ................ . 331
Methods . . . . . . . . . . . . . . . . . . . . . . . .. 291 coXXXX constants ................. . 334
Palette . . . . . . . . . . . . . . . . . . . . . . . . . .. 292 CStrLen function ................... . 334
TSta tusLine ........................ 292 CtrlBreakHit variable ............... . 335
Fields ........................... 293 CtrlToArrow function .............. . 335
Methods . . . . . . . . . . . . . . . . . . . . . . . .. 293 CursorLines variable ............... . 336
Palette . . . . . . . . . . . . . . . . . . . . . . . . . .. 294 DeskTop variable .................. . 336
TStream ........................... 295 DisposeMenu procedure ............ . 336
Fields ........................... 295 DisposeStr procedure ............... . 336
Methods . . . . . . . . . . . . . . . . . . . . . . . .. 296 dmXXXX constants ................ . 337
TStringCollection ................... 298 DoneEvents procedure ............. . 337
Methods . . . . . . . . . . . . . . . . . . . . . . . .. 299 DoneHistory procedure ............. . 338
TStringList . .. . . .. .. .. . . .. .. . . .. . ... 299 DoneMemory procedure ............ . 338
Methods . . . . . . . . . . . . . . . . . . . . . . . .. 300 DoneSysError procedure ............ . 338
vii
DoneVideo procedure ............... 338 MinWinSize variable ................ 356
DoubleDelay variable ............... 339 MouseButtons variable .............. 356
EmsCurHandle variable ............. 339 MouseEvents variable ............... 357
EmsCurPage variable. . . . . . . . . . . . . . .. 339 MouselntFlag variable . . . . . . . . . . . . . .. 357
evXXXX constants .................. 340 MouseWhere variable ............... 357
FNameStr type ..................... 341 MoveBuf procedure . . . . . . . . . . . . . . . .. 357
FocusedEvents variable .............. 341 MoveChar procedure . . . . . . . . . . . . . . .. 358
FormatStr procedure ................ 341 MoveCStr procedure ................ 358
FreeBufMem procedure . . . . . . . . . . . . .. 343 MoveStr procedure. . . . . . . . . . . . . . . . .. 358
GetAltChar function . . . . . . . . . . . . . . . .. 343 N ewItem function .................. 359
GetAltCode function ................ 343 NewLine function. . . . . . . . . . . . . . . . . .. 359
GetBufMem procedure .............. 344 N ewMenu function ................. 359
GetKeyEvent ptocedure ............. 344 N ewSItem function ................. 360
GetMouseEvent procedure ........... 345 NewStatusDef function .............. 360
gfXXXX constants .................. 345 NewStatusKey function .............. 360
hcXXXX constants .................. 346 NewStr function .................... 361
HideMouse procedure . . . . . . . . . . . . . .. 347 NewSubMenu function .............. 361
HiResScreen variable . . . . . . . . . . . . . . .. 347 ofXXXX constants .................. 361
HistoryAdd procedure .............. 347 PChar type. . . . . . . . . . . . . . . . . . . . . . . .. 363
HistoryBlock variable ............... 347 PositionalEvents variable ............ 363
HistoryCount function . . . . . . . . . . . . . .. 348 PrintStr procedure .................. 363
HistorySize variable . . . . . . . . . . . . . . . .. 348 PString type . . . . . . . . . . . . . . . . . . . . . . .. 364
HistoryStr function . . . . . . . . . . . . . . . . .. 348 PtrRec type ........................ 364
HistoryUsed variable ................ 348 RegisterDialogs procedure ........... 364
InitEvents procedure ................ 349 Registertype procedure .............. 364
InitHistory procedure ............... 349 RepeatDelay variable ................ 365
InitMemory procedure .............. 349 SaveCtrlBreak variable .............. 365
InitSysError procedure .............. 349 sbXXXX constants .................. 365
InitVideo procedure . . . . . . . . . . . . . . . .. 350 ScreenBuffer variable . . . . . . . . . . . . . . .. 366
kbXXXX constants ............ . . . . .. 350 ScreenHeight variable ............... 366
LongDiv function ................... 352 ScreenMode variable ................ 367
LongMul function. . . . . . . . . . . . . . . . . .. 353 ScreenWidth variable . . . . . . . . . . . . . . .. 367
LongRec type. . . . . . . . . . . . . . . . . . . . . .. 353 SelectMode type .... . . . . . . . . . . . . . . .. 367
LowMemory function ............... 353 SetMemTop procedure .............. 367
LowMemSize variable . . . . . . . . . . . . . .. 353 SetVideoMode procedure ............ 368
MaxBufMem variable ............... 354 sfXXXX constants. . . . . . . . . . . . . . . . . .. 368
MaxCollectionSize variable . . . . . . . . . .. 354 ShadowAttr variable ................ 370
MaxViewWidth constant. . . . . . . . . . . .. 354 ShadowSize variable ................ 370
mbXXXX constants ................. 354 ShowMarkers variable . . . . . . . . . . . . . .. 370
MemAlloc function. . . . . . . . . . . . . . . . .. 355 ShowMouse procedure .............. 371
MemAllocSeg function .............. 355 smXXXX constants ................. 371
MenuBar variable ... . . . . . . . . . . . . . . .. 355 SpecialChars variable . . . . . . . . . . . . . . .. 371
Message function ................... 356 stXXXX constants . . . . . . . . . . . . . . . . . .. 372
viii
StartupMode variable ............... 372 TScrollChars type ................... 379
StatusLine variable . . . . . . . . . . . . . . . . .. 373 TSItem type . . . . . . . . . . . . . . . . . . . . . . .. 379
StreamError variable ................ 373 TStatusDef type .................... 380
SysColorAttr variable ............... 373 TStatusItem type .................... 380
SysErrActive variable.·............... 374 TStreamRec type . . . . . . . . . . . . . . . . . . .. 381
SysErrorFunc variable ............... 374 TStrIndex type ..................... 382
SysMonoAttr variable ............... 374 TStrlndexRec type .................. 382
SystemError function ................ 375 TSysErrorFunc type ................. 382
TByteArray type . . . . . . . . . . . . . . . . . . .. 375 TTerminalBuffer type. . . . . . . . . . . . . . .. 383
TCommandSet type ................. 376 TTitleStr type. . . . . . . . . . . . . . . . . . . . . .. 383
TDrawBuffer type. . . . . . . . . . . . . . . . . .. 376 TVideoBuf type . . . . . . . . . . . . . . . . . . . .. 383
TEvent type ........................ 376 TWordArray type . . . . . . . . . . . . . . . . . .. 383
TItemList type . . . . . . . . . . . . . . . . . . . . .. 377 wfXXXX constants . . . . . . . . . . . . . . . . .. 383
TMenu type . . . . . . . . . . . . . . . . . . . . . . .. 377 wnNoNumber constant. . . . . . . . . . . . .. 384
TMenuItem type . . . . . . . . . . . . . . . . . . .. 378 WordRec type ...................... 384
TMenuStr type ........ : ............ 379 wpXXXX constants ................. 385
TPalette type ....................... 379
Index 387
ix
T A B L E s
2.1: Data for dialog box controls ......... 58 14.16: Special key codes ............... 351
3.1: Inheritance of view fields ........... 71 14.17: Alt-number key codes ........... 351
5.1: Turbo Vision command ranges ..... 120 14.18: Function key codes ............. 352
11.1: Turbo Vision constant prefixes .... 187 14.19: Shift-function key codes ......... 352
12.1: Turbo Vision units ............... 189 14.20: Ctrl-function key codes .......... 352
13.1: Stream error codes ............... 295 14.21: Alt-function key codes .......... 352
14.1: Application palette constants ...... 329 14.22: Mouse button constants ......... 354
14.2: Button flags ..................... 329 14.23: Option flags ................... 361
14.3: Standard command codes ........ 331 14.24: Scroll bar part constants ......... 365
14.4: Dialog box standard commands ... 332 14.25: StandardScrollBar constants ..... 366
14.5: Standard view commands ........ 333 14.26: State flag constants ............. 368
14.6: Collection error codes ............ 334 14.27: Screen mode constants .......... 371
14.7: Control-key mappings ........... 335 14.28: Stream access modes ............ 372
14.8: Drag mode constants ............ 337 14.29: Stream error codes .............. 372
14.9: Standard event flags ............. 340 14.30: System error function codes ...... 374
14.1 0: Standard event masks ........... 340 14.31: System error function return
14.11: Format specifiers and their results .342 values ........................ 374
14.12: Grow mode flag definitions ...... 346 14.32: SystemError function messages .. 375
14.13: Help context constants .......... 346 14.33: Stream record fields ............ 381
14.14: Keyboard state and shift masks ... 350 14.34: Window flag constants .......... 384
14.15: Alt-letter key codes ............. 351 14.35: Standard window palettes ....... 385
x
F G u R E s
1.1: Turbo Vision objects onscreen ....... 11 4.8: Basic Turbo Vision view tree ........ 92
1.2: The HELLO.PAS startup screen ..... 13 4.9: Desktop with file viewer added ..... 93
1.3: The HELLO.PAS Hi menu .......... 14 4.10: View tree with file viewer added ... 93
1.4: The Hello World! dialog box ........ 15 4.11: Desktop with file viewer added ..... 94
2.1: Default TApplication screen ......... 25 4.12: View tree with two file viewers
2.2: TVGUID04 with multiple windows added ........................... 94
open ............................. 35 4.13: The focus chain ................... 96
2.3: TVGUID05 with open window ...... 37 4.14: Options bit flags .................. 99
2.4: Multiple file views ................. 41 4.15: GrowMode bit flags .............. 101
2.5: File viewer with scrolling interior .... 44 4.16: DragMode bit flags .............. 102
2.6: Window with multiple panes ....... 46 4.17: State flag bit mapping ............ 103
2.7: Simple dialog box ................. 49 4.18: TScroller's default color palette .... 105
2.8: Dialog box with buttons ............ 51 4.19: Mapping a scroller's palette onto a
2.9: Dialog box with labeled clusters window ......................... 106
added ............................ 55 5.1: TEvent. What field bit mapping ...... 112
2.10: Dialog box with input line added ... 56 13.1: GrowMode bit mapping .......... 307
2.11: Dialog box with initial values set ... 59 13.2: DragMode bit mapping .......... 307
3.1: Turbo Vision object hierarchy ....... 66 13.3: Options bit flags ................. 308
4.1: Turbo Vision coordinate system ..... 84 14.1: Drag mode bit flags .............. 337
4.2: TApplication screen layout ......... 87 14.2: Event mask bit mapping .......... 340
4.3: Side view of a text viewer window ... 88 14.3: Grow mode bit mapping ......... 345
4.4: Side view of the desktop ............ 89 14.4: Options bit flags ................. 363
4.5: A simple dialog box ............... 90 14.5: Scroll bar parts .................. 366
4.6: Turbo Vision object hierarchy ....... 91 14.6: State flag bit mapping ............ 369
4.7: A simple dialog box's view tree ...... 91
xi
N T R o D u c T o N
Introduction
endlessly recreating the basic platform on which you build your
application programs.
Turbo Vision is a complete object-oriented library, including:
• Multiple, resizeable, overlapping windows
• Pull-down menus
• Mouse support
• Dialog boxes
• Built-in color installation
• Buttons, scroll bars, input boxes, check boxes and radio buttons
• Standard handling of keystrokes and mouse clicks
• And more!
Using Turbo Vision, all your applications can have this state-of-
the-art look and feel, with very little effort on your part.
Introduction 3
4 Turbo Vision Guide
p A R T
5
6 Turbo Vision Guide
c H A p T E R
Naming of parts
A Turbo Vision application is a cooperating society of views,
events, and mute objects.
Mute objects Mute objects are any other objects in the program that are not
views. They are "mute" because they do not speak to the screen
themselves. They perform calculations, communicate with
peripherals, and generally do the work of the application. When a
mute object needs to display some output to the screen, it must do
so through the cooperation of a view. This concept is very
important to keeping order in a Turbo Vision application: Only
views may access the display.
Nothing will stop your mute objects from writing to the display
with Turbo Pascal's Write or Writeln statements. However, if you
write to'the display "on your own," the text you write will disrupt
the text that Turbo Vision writes, and the text that Turbo Vision
writes (by moving or sizing windows, for example) will obliterate
this "renegade" text.
A common ulook
and feel" Because Turbo Vision was designed to take a standardized,
rational approach to screen design, your applications acquire a
familiar look and feel. That look and feel is identical to that of the
Turbo languages themselves, and is based on years of experience
and usability testing. Having a common and well-understood
look to an application is a distinct advantage to your users and to
yourself: No matter how arcane your application is in terms of
what it does, the way to use it will always be familiar ground, and
the learning curve will be easier to ascend.
onscreen 11 ....... " ... 1 ...... " ......... 11 .............................................................. I1 .... I1 .......... I .. " ............................ I1 .... IIII ........................ M........... 1 ................................... 11 .......... .
• 11 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11 . . . . . . . . . . 1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
'n." ...... II..... n'"IIII .. ' .. II...............................III ... II.I ........ "" ..............II .. lnll.. II" ....... II ................... IIIIII ............................. II . . . . 1I1I1.. IIII'"I1 ..... I1.............. IIII ... I1 ...... MIII
1.. ' ...................... 11 ............ 11 ...................... 1.......................................... 11 ............ 11 .................. 1........................................................... 11 ................. 1 ................... ..
. . . . . . . . . . . . . . . . . . . . . 11. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . , . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ." . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. .
..............1 ............................................................" .....................................................................................................................11 ....................................... 1 .. 1 ...
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . , .......................................... 1.1 .... 1...... 11 ...................... 11 .................. 6 ..................... 1.......... ,,, •••• 11 ................................................ , ... ..
...................................... 11 ........................................................................................................ , ................................. M . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. .
.. ., . . . 1.......... " .. 1 .... 111111 ....... 11 .. 11 ......... 11 ............ 11 ....... 11111111" ................. IIIIIII .. III .. III .. II ... I ............... II ... I1 ..... IIIIIIIII .. ' .......... M................. 11 ... 1.................. " ................ .
. . . . . . . . . . . 11 . . . . . . . . . . . . . . . ' . . . . 11111 .. 11 ............................................... 11 .. 11. . . . . . . . . . . . . . . . . . . . . . . . . . . 11 ...................... '.111111 . . . . . . . . . . . . . . . . . . . . . . 6110 . . . . . . . . . . . . . . . . . . . . . 1.. 1111 ........................... 11 . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11 ............................ ..
...... '"' ................................. 11 ....... 11 ...... 1 .......................... 11 .......... 11.11 ................... 11 ...... ' ... 11 ....................................................................................................... ..
. . . . . . . . ' ...... 11 ................ 11 ..... 111 •• 1................................ 11 ...... 1 .. ' ......................... 11 ........ 11 ... ' ........................ 11 .................. II," ....... H .......... H .... II ............................... ..
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .11 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11 .......................................................... " ................... " ............... 1....................................... 11 ...
......... , ................................... 11.11 .. 1 ...... ' ... 11 ..................... , ........................ II, ............ II.IIIII.II.n.II ...... I ........................ ".I.. M......... ' ... H .... II ......... I ......... H ............... .
................... H ....................................................................................................................................................... " ............. H .... H ................ H ......................... ..
..................... 1.................... 1111 .. 111 ..... 1111 .. 11 ..........................1" .. 111111 .... 11 ......... 11 ... 111111.111111.1111 .... 1 ..................... 11 •• 1111 .. 11 ................. "... 11 .. "" .. 11 .. 1............................ "
..... 1 .......... 11.1 ..... 111 ........... , .. , ........ , .............. 11 ... , ........ '.II.III .................. H ............... " ............................ " .... 11 ................ " ......... , .................................... 18 ....... 11
...................................... 111.' ....... 111 ..................... , ....................................................................... H .......... II .... II .............................................. H ......................... ..
.... 11111111 .... 11 .............. ' ........ 1... 1.. 11111.11.111 ........... , .. ,." ........ , ...... I1 ....... I1 ................ HI ... II.IIIII.II ....... I1 ......................... II.M .... I1 ......... ' ..... I ......... II ... I ..... III ........ '".II.II . . .
...... , ............ 1111........ 111 .......... 111 ...... 11111 .................... , ......... 11 ..... 11 .......................... 1111111 ....................... 1........... 11........... " .................. 11111 .. 1.... 1........................... "
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . II . . . . . . . . . . . . . . . . . . . . . . . . . . . . H . . . . . . . . . . . . . . . . . . . . . . . . 'M . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .H . . . . . . . . . . . . . . . . . .
.................................... 11111' ... 111 .. 111 ..................... , .. , ... ' .... I ".... II.H .............. , ......... " ................ II ..................... 11 ...................... "1 ................................................ "
......... II .. I1 .... N .. IIIII.IIIIII ...... I ............................. III ... III ..................... " .. 11'1111111111 ... 1111 ........ 1111 .. 111111111111111 .............. 11 ............ 11 ...... IIIIII.II ................. ".IIINIIIIIII ......... ..
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . " . . . . . . . . . . . . . . . . . . . M . . . . . . . . . . . . . . . . II . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . H . . . . . . . .
::::::::::::DeskTop:::::::::::::::::::::::::::::::::::::::::::::::::?::::::::::::::::::::::::::::=::::::::::::::::::::::::::::::::E:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::=:E:::::::::::Em
1.................. 11 ........ 11 ....................... 11 ............. 1............... 1111" .... 1 ..... 11 ..... 1111 .. ".1111 ... 1.................... 1........... 11111111111 ... " ....... 1" ....... I ...................... , ............................ .
....... 11 .. " ........ 111 ...... 111111 ................................ 1 ... 111111 .. 11 ...''' .................... 1111 ..... "" .... 11111 ..... 11 .. 111 ..... '" ........................ 11.11 ..... 11 ............................. 11 .. 111 .................... 1
...... , . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .H . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .H . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
............ 11 ....... 11 ..... " .. 1 ...... 1111 ........................................ 11 ......... , ...... 11 ............... 11 ...................... 11 ............ 1111' ................... 11 .................... 11 ......... " ......... 11 ... 1 ........... .
.... 11' .. 11111 ... 11 ..... 111111 ....................... 1 .. 1 ... 1111 .. 11' ........................ 11.11 .. 1...... 11 ................... 11111"1111 ........ 11 ................... " ... 11 .................. 1 ....... 1........................ 11 ............ .
.................................................................................................. II . . . . . . . II . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . M . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
.............. 1 .... " ..... " ............................... 11 ..................................... 1 ............... I......... II ... II'.H ... IIII .................... I1 ..... I1 ........ IIM .................... 11 .............................. " ... ..
. . . . . " . . . 11 . . . . "" .... 11 .................. 11 . . . . " . . . . . . . . . " ...... 11." ................. 11 . . . . . . . . . 111 .. 1111 ................ ' .... 1... 11111111 ......................... 1111 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
............................... H ................ H .......................................... , ............................................................................................................... H .... H' ......... I I. . . . . . . . . . . . . . . . . .
.... 0 ...................................1 ...... ' .......................... 11..... " .............11 .......... 11111 ........................ 1" .... " ......................... 1111 ... 11......................... 11" ... 11 ................... 11 .... .
... 1... 1111111 .. 11111111 ..... 1111 ................. , .............""11....................... 11111111 .. 111 ...... 1 ............... 11 .... 11111.11' ... 1....................... 11 .... 11 .. " •• " ... ' ........ 111111 .................... ".""1111111 .. 1
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .H . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . , .. , . . . . . . . . . . . . . . . H . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. .
........................... ,11 ... 11111111111111 .... 11 ................. 1111 .. 111111 .... 1 ........................ IIIIIII .. IIIIIII .. ' ......... IIII .. III .. ln.IIII .......... II ........... 1I11 ... 11 ............. 11 .......... 11 ....... 11 .............. ..
..... " ...... IIII".IIII ......................... H . . . . . . . . . . . . III ...... IIIIII ............... 11.11 .. 1........ 1 ..................... 1 ••• 11.111111 ..................................... " ............ ""11 ....... 1........................... 1111111
................................... 11 ........... 11 ................................................................ 1"'................. , .......... 1111 ............................... " ..... 11 .................................................... .
... , ................. ' .. 1111 .. 11"11 .... 111 ...... ' ................ 1111 .. ""11 ........................
1..... 11 ..... 1"......... 11 ........ , .... 11111 .... 1 ............................. """11 .. 111111111 ............................. 1 11"............
... 111' ............................... 11 ................ 111111 ...................... " ... 11.111111 ............................ 1111 ...."'" .. ' .................... 11 ................ " .... 111 .. 111.1111 ............... 11.11 ...................... ..
.............................. , ••• H ................ H . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . H .......................................... ,,, ... ,H . . . . . . . . . . . . . . . . . . . . . . H ............................ ..
............. IIII ...................... 'H .... I1'" ........................... I1 ...... IIIII ........................... 11 ...... 1............................ 111 .................... 11" .. 1 ..... " .... 11 ......................... 1 ................. .
........... 11.11 ... "1.. 111111 .. 1 ........ ' ...................... 11 ... 11.11 .. 11 .. 11 .......... ' .... 111111111.11111 .. 11 ..................... 11111 .... " ................................ ,,,.III . . . . . . . IHIII ...... IIIIII ........ ' .................... ,
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .11. . . . . H . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . , . . . . . . . . . . . . . . . . . . . . . . . . II.H . . . . . . . . . . . . . . . . . . . . . . . . . H . . . . . .
........ 11 ............ 1111 .. 11111111111 ........................................................................ 111111 ................. 11 .. 111 .................. " ....... " ......... 1111 •• 1111 ....................... 1 .................. 1...... 111 ..
....... 1111.' ...... 1............................ 1111 •• 11 .... 11 .................................. H ...... ' ...... I1 ......................... IIII .................... H ............... , ........................... II .............................. '"
............................................. " ......................................................................................... H ........ I ................................ " ............................................................ ..
.............................. I .... I1 ...................................... II.III .... I .... H .............. 11 .................. 1.............. " .... 11 ...... 11 .................................... " ........ H, ...... .., ...... II ................. ..
.............................. , ........................... H ................................. 11 .................................... 1 .................................... I ............ " ............................ II.II .... " ............. H .... II
....H............. H .......... H .......................................................................................................H ....H ............, ....................... , ... " .............H." .......H ..............................
.. 11 .................. ..,11 .. 11111.1111 .. 11 .... ' ................. 1111111 .... 111 ..... 111111 ... 11 ................. 11'" ...... 1111 ......... 11 .. 11' . . . 1111 .. 11 .. 111111111 .............. 11"' ..... "" .... , ........... 1111 ......... 11 ...... 111" ...... ..
............... 1111 .... '"1 ......... 11 .................................... 1111 ....... " .............. I1 ..... IIII .......... I1 ..... II.II ..... IIIHIII .. I ...................... IIIIII"I" ....................... 1111 ....... 111 ..................... ..
11 .......................................... " ........ 111 ................................ 11 ........................ " ...... HII .......... II ............................ II ......... II ..... I . . . . . 8 ........................... 11 ................. ..
............... I .............. IH ... III ...... I .... ' ............................. I1." ....................... 111111111" .............. " ............... 11111 ................. ' ..... 11 ............................. H.HII" ..................... ..
.... 11 .. 1111 ................................... 1111111 ................................................. "" .. ,, .................... 1...................... 1...... 111 .. 11" .. '8 .... " .......... II.NINI .................... I1 ............ IIIIII •
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .11. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. .
StatusLine
The text that appears in the status line is up to you, but typically it
displays messages about the current state of your application,
shows available hot keys, or prompts for commands that are
currently available to the user.
When a menu is pulled down, a highlight bar slides up and down
the menu's list of selections in response to movements of the
mouse or cursor keys. When you press Enter or click the left mouse
button, the item highlighted at the time of the button press is
selected. Selecting a menu item transmits a command to some
part of the application.
Your application typically communicates with the user through
one or more windows or dialog boxes, which appear and disappear
on the desktop in response to commands from the mouse or the
keyboard. Turbo Vision provides a great assortment of window
machinery for entering and displaying information. Window
interiors can be made scrollable, which enbles windows to act as
portals into larger data displays such as document files. Scrolling
the window across the data is done by moving a scroll bar along
Running
HELLO.PAS Before we dissect HELLO.PAS in detail, it would be a good idea
to load the program, compile it, and follow through its execution.
When run, Hello clears the screen, and creates a desktop like that
shown in Figure 1.2. No windows are open, and only one item
appears in the menu bar at the top of the screen: the command
Hello. Notice that the "H" in Hello is set off in a different color
from the "ello", and that the status bar contains a message: Alt-X
Exit.
Figure 1.2 Hello
IIIIIIIHINI"'IIIIIIII.,,''''HI''••• 'OI,IIIII.IIIHI.. , •• ,.II.'III,III .. IIII....., .. IIIIH." •••• I""IIII,I.'"I'"II.".IIIIIIIII'"1III"'"'. . . . . . .I .. IIIIII .... n ....... "" .................. I " "... HIIIIHI ..... '"IIII ...I " l n l ..III.HI"
. . . . . I . . . . . . . . ' ' ' . . . . . . . III . . . . . . . . . . . . . . . . . . . . . II . . . . . . IHI . . . . . . O . . . . . . . . . . . . . . . . . . 111 . . . . . . . . . ' " ' . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11.11. . . . . . . . . . . . . . . . . . . . . . . . . 11. . . . " ' " '. . . . .""11 . . .111 . . . 1 . . ' . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
The HELLO.PAS startup screen IH .................. '"III' ........ IIII .. IIII....II........ III.III •• III ... II",.. ' " ' " I I I I ' ' ' ' " I I I I ... I.IIII.'''''''N'"'"'"'.'.'"'N'"'NII'' •• 1I1•• III....... I1........ '_' ....IIH ...........' ..' ..... I••• ' ........ ,.""''''N
........" . ., .. , .. , .. , .. , ..... , .. , .. , .............. , . . . . , .. , ........ " . ,. . . . . . . . . . . . . . . . . . , ..... ' ... 11 ...' . '. . . ., ................. ,,, ... 11, ......... 11 ........... II ........ , " ,. . . . . . . . . , . ., .............. ' ... H'. . . . . . . . . " •••, . , •
............... 11 ........., ..........., ........... , ...................., ..........................................., ........................................, ........ ' ........ 11...................................................., .....
,111111....... ' ••• 11.1 ....... ,111111.......1111 . . . . . . . . . . 1., ...................11' . . . . '11 . . . . .' . . . . . . , . . . . . . . . . . . . . . . . . . ' " ' . . . . ' . . . . . " .... " ' . ' . . . . . . . , •• " ...... , . . . . 1.. 11...." ...' ...., ..... , .... , ....11. . . . . . . . . . . , ..
, ........' ... H .... H • • ' . . . . . . , .. , ...................... HII" . . . . ' ............., . ".. , . . . . " . . . ' " ' • • • ' ..1. . . . . . . . . 1..............11 ............., .. ' .... '.11.'.. ' . . . . . . ., . . . . . . . , . . . . , ........ '"1" ....11'".11'.. '"' .. , ..
' " . . . . . . . . . . . . . . . . . . . . . ' " . . . . . . . . . . . . . . . 11. . . . . . " . . . 11. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . , . . . . . . . . . 11 . . . . . . . . . .11 ..........11.11 •• 11. . . . . . . . . . . . . , . . . . . , . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11 . . . . . . . . . . . . ' " . . . . . ' . . . . . .. .
, .................. H ....... H .............................. ' . '... H ....... II ......... , ..... ' ......... ".11 ...... 1.. ' .. ' " ...11......' . " ... ' ..' " .... 11'" ........., ...................... ' .. '".II .... II ............. II ... ' ..'H'. . ' .. ' ........
' ...11 ••" .. ' ....111111..... 11'".11•••
, ................. 11.11.11 ...111 ............ '" .......
0' ... 11' .......111111.'.'
.... ' .....
......1.. ' .......... 'H'"'.. '"' .....
11 ..................'"' ... 11 ....II.'I.'" ...... ' ..'"II...... '"'.'" ...... ,....." .... '"' ..' .. '" ............" .." ... 11' .. ' ..... ' .. ' .....
11111.11 .............11 ............. 11 ...... ' .. , ...... 11 ...... 11 ..11 ............11 ....... 11 ...................11 .........1...11 .......... ..
11....... '.11.'" ... ' .. ' .....
, ........ , .......11 ......" ' ...... 11........11....................... ' " ....11 .......... I1 . . . . . . I1 .... II.II ....... I1 .... II.II' .. ' ...........".IIIIII ... I1 .... H ............. II.II' ..... '"'.. 'H'H ....... II .............................. , ••••
• II ....... II ....... H.H ........ , ........ ' ...... II ...... ' .. II ........... II.II ......... ' .....'" ............................ 11.11...................11 .... " ... ' " •••• , ....... ' ...... 0 .................................. 11...................... ..
... , ... " .........11 ............... , ........, .................... 11 .... 11 . . . . ' . . . . . 11.11 ... 1...... 11.1111.................... 11.11' ... 11 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . , . . . . . . . . . . . . 11.........................11............... ,II
.11 ... '" ...' ........ '" .......... 11 ... '.'.11 ....
11 ... '.'"'11111 ...' ... '.1111'" ...'" ... '."........" ....................... 11 ...... ' ..
11 ... , .. ' " ' " ' " ' " ' ' ' ' ' ' , . , " " ' ' ' ' ' ' ' ' " ' " ' " ' ' ' ' ' ' " ' ' ' " ' ' ' ' ' ' ' " ' ' ' ' ' ' ' ' ' ' ' ' ' " ' ' ' . " . ' . ". . . . ' . .
, ........ ' ..11•• " .........' " ' ........ ' . ' ....11............... , .... ' ••• 11 .............................. , ..... , ........ , .. , .......... , ..... ' ......11 ......... , ........ , .........11........... 11 ......, . . . . . . . . . . . . . . . . . . . . . . . .11 ... ' ....., .....
. . . . . . 11. . . . . . . . . . . . . . . . . . . . . . . . . .11.11......................... 11. . . . . . . . . . 11 .............11 ...... ' .......................................... 11.... 1111. . . . . . . . . . . . . .11 .......11 ............ '" ....... 11............... ' ...11.11 .......11 .........
... ' ... 11.....1.11 ....... ' ..... 11'.. ' ..... ,....... '.. '.11............... ' .. '" .... '.11 ..... '" ......
11'"...... , ........ , ..... , ........ ' .. ' ...11 ... ' .. ' . '.. '.1111''' ...' . ' " .......... 11.11 .... " ...... , .. , ..... ' . .
n •• II ...... II.... ' ...... IIII .. tllIlI.II' .. II. . . . . . II......".III.IIIIIIII ..II ..........11 ... "' .. '"1111.111111.1111111111'""'" ......... 11.11' ...11'.. ' ..1111 .. ' . ' " ....." " . .1... I 1 " " ' ' ' ' ' ' ' " '... I '.. ' . .' .. ' " '.. IIII .. IIIIIIII •• H
1......... 11'"1...... 11'.
................ 11.11 ...............................11 ....11 ••' ... 1111..............11 ...1..........11••11.11.11 ............, ............11 ...' ...... 11 ... 11..... 1111....................11 ...................11 .......11 .... 11..................
,' ........ '" .... 11' ..' ...11 ... '"' .. ' ..'"11.... '".11 ..........11 .....• .... " '....'" ...... 1................. 111........ 111 ...... ' ..'"'"'.""' .. '".......11....II .......II ............... '".II'"... ' ...... H .... II ... ' " ' " . . . . . ' ..... ' "
... 11'"....11.11 ...... 1.. ' ..... ' ..... '"'...............11 .... 11 ... 11....... , . . . .' " • •' " ......... 11.11.11 ...................... 11 ... ' .. ' ............11 ......... , ................. ' ...11 ...... 11....... 11 ............... , ........ ' ... 11 ......
, ......... 11.11 ..........11 ...... '" ...... ' ... 11'".11 .... 11 ............. 11."'... 11' .....'".......... 11.11.11.11'.........11 ... ' .............., ......, ... 11 ......11..... 11 ......' .........11 ........., .. , .........11.11 .... 11...' .. ' ........ , .
'".11 .....' .. ' ... 11...... 1.......... ' ....'"'"'"' ............... " ............... '"' ..... '",......... 11.11 ....1111••11 ..... , .... , ..... ' .. ' .. '"."'...... " .....' .. 1.........11 ... ' ..... ,",.. ' .. ' ... 11' .. 1111 .. ' ....' ..... , ........ , ..
... ,""""".,"••, .. ,"''''"'''''''.''''''1'''"11"",,,,",,,'"'.11''
............................ .. 1 ... 11 .... 11.11.11
11............ 11.11.11 ............................................ ...' " '.. ' .. ' .. ' .. ' ...11'"'" ..................... , ....., ..."'"'"''''"'"'.'"''''"''''.'''''''''''''''' ... 11 ...........' .. '"'"'"'''
, ........... , ..... , ......... 11 ................11 ..............................' ......11.......11............................ 11 ...'"'...... 11. . . ..
... ' ••11'"11......... ' " '..'"1 .... '.'."111 .....' ..... 11.'"'.. '"' .. 111'"111............ 11'" ••• 11'"'"'.'.'.. ' ...
111.. ' ..." ... '" ....11 ....... " ' " •• ' .. ' ... 11' ....
'.1 .. ' ...... 11 ...' .. ' ....' ...11' .. '.1 ......' ....... 11,... ..
............ ' ...11'"' ..............11. . . . . . . . . .11 •••11' .. ' ...11'........ , ........... , . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11 ....11.11 ... ' ....., ..... , ........ 111 ....11'... 11 .................. , ................... 111... '".11..... ' .......
.......11 .... 11 ... 11. . . . .11............... , ..............' •• 11. . .111 ........ 11. . . . . . . . .' • • 11 ........., ................................................., ...11 ............................11 ...' ..... ' ..' ...11 .............................
11.....11...... ' " ' " ' ... 11...... " .... ' .......11.. ' .. ' ..' . , .., . '.. ' ...11 ...... ' ...1I ... ' .. ' " ...... ' . ' .. ' .. III ....... H' ........ IIII ..... ' .........I'"' ............. ' ...... 11'..... 1........ ' ........ , ..' ..' ....1111.".11... '".11 ...... 1..
, . . . . . 11.... ' . . '".".11111 .......11' ..........11 . . ' ............................. 1...11 ....." " .... 11 .......... 11 ............... , ....., .... , ...11.11' ...11.......11.... N . . . . . . . . . . . . . . , . . . . . . . . , . . . . . . . . , . . ' . . . . . . II . . . . . . . . . ' . . . . . II . . . . . . . ' .
, .................. 11.................'" ......'".".11.11 ......." .................. , ........................ 11 ..............................11 .... _ .........11.... 11 ....11 ....................., . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .11 ......' ..
'"'.......... ' .. '"... '"' .. ' ... " ......... 1.... 1.......1' .....'" .....
," ... ' ... I ... '".I ...'"........ 11 ....... ' ... II,,,,o,,..... II'.'"'... 1I... ,.' ......
1.. 11I""",,,,,,,.. ,",I'I'...... II'"''''U, •• 11' ...111................. '" •• ' ...11'"'"'" ...' .. " ..... "'"
I ............................. ' ..
'" ............... 11............... , .............. " ..... 11 .... 11 ... ' ...................., .................. ,.H ....11...........
HIIIIIII ......., .. ,.,.... ' .. '.'".111 .......
H............II....
11' ...11 ...' ..... ' .. ' ...11 ............. 11 ....11' ..... ' .. , ...........' ... 11' ..... ' ............................
I ......... II ............................11............, .. , ..............11.11 ............... , ....., . ...
.....' .....' " .....I1.. ' .. ' ......' ..... ' "... ' " ' " ' " ' " ... ' ..... ' ... ' ..n'"'11•• ' .. ' .... , ........... , ..' .. ' .. ' " ' . ' " ............ '"."' .. ' .. '111"'"11.'"' .. III' .. II••• I .. ' .. ' ....... ' .. '.'lln' .. ' ....I ••
1.... , ....... 'n'....................... ,........ ' ..' .. '".H.II ••• II ............... ' 8 ...' ... II'... H . . . . . . . . . . .0.1I.1I ........... , " .... II.... II... 'H'H ..................... 11'..' ..... '".".11' ..' ...... 11 .............11'"... ' •••
'".II...... ,..........
.............11 ................11 ....11 .................................. 11 .... " ...... , ............... 11.11............11. . . . . . . . . . . . . . . . . . . , , , . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .11 ....... 11 .... " ...................................... ..
• II, .. ' .. ' . ' " ...... '"."'"'.. I .. ' .. ' .. '"I .. '.'".II.II'HI" ............ ' .. I"'I'"'"III ... ,",.,I....II'.,I1''',I1''".,,,'''''''I'".II'.'H.II ...... ' ...II.II .......II.II' ..'" ... ' .. '".IIII.'".I1 ............. H ... ' ..III'.'.
11.'" •• ' ........ , .. ,",",.. ,",.. ," ....... " ...... 11.........,.. ,.. '".11'".11....... 11'.'.. ' ..... 11.... 11'"... 11....'" ..............
1..... ' .. '"'"' .. '"'11" •• 11.11.1111.. 1.. '"'.......' ... 11 ...1..... ' ..1........' .. ' .. '" ••' .. ' .
' . . . . .11 ........., . , .. , ...................................... _ , .................................. H ......... ' .......................... II ............ _ ......, .. ,,,...... , ........................ ,, .......... H ........., " . . . . . . . . . . ..
' ..'" ......... , .. '"' .. '.1.' ...... 11' .. '" ... 1.' ..... '.,","..... '" .... " ...... ' •• '.1111 .. '"' .. '"...... ' ....
'"'UII.II""IIIIIIIIII"''''"III'I'.. '"'"I",,,,,,,,,,"., ... '"' .. '.II•• 11 ... '"11...
................ ,".11, ..11.......
"'...,................................................. 1........' ........ , .. , ..' .. '.1111"'.1"1111 .. ' ........ '"....0 ... ' ....1 ...' ......'" ........, .. , ..
11.'.'11.11...'" .... "'.,.""''''"
11' ..."'"'"'.' .. ... 1....1...... 11 • • • • "111"''',,,,,,,"",,,,,,", .. ,",,,,,,,,,,,,,,,
' ......11.11 .....................................................' ...11'.. ' ...11 ....... ' ................. ,................... 11 .............11.11 ......' .......... , .. , .. , ............11
................... 11 .....................11.11...............11.......... 11 .......................................11 ...........11 ............................11." .............................. , ....................... ' .. '"' ..... ' .. , .. , ..
'.11.. "'..... ' .....
• 1I... IIIII ... '"III ...... II ... I1.' .. ' ... I1' .. ' ....' , .." . , ..." '...... H ... ' ........ '.11 .. 11. . . . . . 1".11 ............ ,.,.. ' .. ' .. '".11.11' ..... '"'... 11 ........... , ..... ' .. ' "... ' . . ' ..... ' . .11.'.. 1.. ' ......11 ...... , ..
..1.1111...................... , ........, ........................11......, ..... , .... I... II .... H ...................II...... ' .... ' ...II'"'.. II....' ... II .......II.II.1I ... ' .............. I1.'..... III.H.II'..I .........I1 ..........II.II.... II'..
' ... II •• I1.. ' ........... , .. , .. ' .. ' .. ' ..III .... II.H'... II.II ......... , ...... I1 ............... , ...I1 ...... ' ...... II'HII... ' .... ' .. II •• I1'.. ' .. I11 ... ' " '..... , . . . . . . . ' ..' "•••11'........ , .., ••11 ........, .... , ........ ' .. '"'" ... ' .. ' ....
'".II... '"I ...... II... ,"...'"'"...'.. '" ...,........ 'HI ........ '"'.. '"'... I1 ... '"I..........,.. ,........
'"IH' .. '.III'"I1.'"'.. ' ..' .... '" •• II.' ......II' .. ' •• ,I, .......n.n.II' .. ' .. ' ..I ......"' ..,",..
..............................'".H.............. " ......................... II . . . . . . . . .11.......... , .............. ' ..." ...11•• 11 ............... " ..................... ," ............ 1................................ ' " ' ..... ' . . . . . . . . . . . H
'".n' .... '.. ,....
'"'.. '.11"'.'0' ..' ..... ' ..'"'"'.. '"' .... ," .....'" ••• 11.1· ..·' .......... 111'.11".11"1 ...' ... 11,11''''.'.' ..... '"' .. ' ..1.....
.... 11'.1111'...0.0...'" ............... ' ...11.11111 ... ' .. ' .. ,", ............... 111' ..'"' •• 11 ....11 ... ' .. '" .... 11•••11 .............
1,,,.,.'"
"1.' ........ ... 111'........ ,.........11'.... '"'.' ..
,11' ...... 11 ••• 11 ........................ , .. , ..
'".11 ........................... ' ..' ...II •• I .. ' ................ II....... H.II .....
...." ........................11 ...' ... 11 ..................................11 ••• 1111..... 11...... 11...................... , .....................11.....' ... 11 ............' ......11' .............. ' ...11' .......' ••11........... , .. , ........ , ..
111.11 ... '"... 11........ '"•• ' ••••• ' ...11 ••• 11.............. 111' ..... ' .... ' ..... '"...... 11........
... ' .. ' .. ' ..11111.... ' .. 11••• ' .. 111...... ' ..' .. ' .. '"'.'" .... " ..... , ..... , ... 11.11 ... ' ..... 11' ..... '"... ' .. '"'"' ..... '" .....
11 .. '"11.....11 ................, ..... , .. , ..... ," ...... , .............. ' .. 1..' .... ' •• 11'.. ' ..
'".11'"'" ............, .. , ........ 11 ... 1.. ' ....... ' ..."'" ......1...11'" ••• 111.......' ..... '"' .. ' ...... 1.... ' .. '.,.. ,.....,......... ,..
... ' .. 111 ............. 11 ......................11 ... ' ........11 .....................' ...... 11...... 11. . . . . . . . . . . . 11..... 11 ...................... 11 ................... "1111."" ................. _ •• , ....................11............... ..
... ' •• 11....
•11.1111 ....,"",,,,,",
11'.'.. ' .. ,.....
..' ...'" ... 1111 .. '.1111'".'"11
11'" ..........,,,",
11.11'.11 .. ' ...
' ....... ,,,,,
.. '".. ...
,.. ,'"'
.. ,11.....
...1................ 11 .. ,."...
1"""",",",", .. ,11...,", .... ,",",."",",",,,,",",...... 111' .. '"' ........ ' ...
0.11,",",.,,,,.,.,,,,"," ....
11"""'"'"''' ... '".............. ' .....
11'..
111'1...... '"'..... '0 ••' ....
11•• "'"'" ......... ,..11' ...........
......11' ..... ' ........ ,•
' .......
11.. ' ..
..................................... 11...............1111 ..............................11 ............... ' ...11......' ...... 11 ....
11 ............. 0111 ............,11........' ... 11 .............11 ...... 11.11....11 ...." ...................... ..
... ' .. '"'.. ' ... 11 ... ' .......... ' .......1'.'".11' .....' ... 11 ............. 11 ......' .. '"'"'" .... II .................. 'H ... ' ..... , .. , .... ,", ..... , ....... , ..... ' ....11"'................• ... , .............. , .......... ' " ' ... 11 .......11,..
,................. '"' .....11 ... ' .. ' .. 11........11 ......... , .. , .., ... '.' ... 11 ......... ' ..... '".I1' ..... ' ... I1 ... '".I1 ......'U....... III ............ I1 ...... , .. , .. , ........," ..., ... " ...." ......' .. 1........... ' ........ '"'" ...... , ..... ..
, ..... 1..... ' ... 11 ... 1..........................'"'... 11'...............11 ................ 11 ......' ......... 11.11 ....11 .......11 ................ ." ..................... 11 ............. 11 ... , ....... ' ..'"111'............. , ... 11 ............ , ..
'"'.'"'.. '".11.111 ........... ' .. '" ... ' .. ' ...1'" ....".111 ......11.11 ........1111'"'..... '".11 .... 11'" ..............., . , ..... ' . ' " ' .. ' . ' .. , . . . . . . , .....................II.II ... ' .. ' . . , . .' ..... 'HI ... II'..... ' .. , ........ , .. , ..... , ..
.......... I1, .. , .. , ..... ' ...... II.H... 11.'........II ...III •• '" ... III ......." ... I.. ' ..... ' ........ ,",..... ,I'.. '".n ....... II"...., .. , ....... ' .. '"'... II' .., .. , .. , . ' ..."'.. 1 .......... , .. , ..... ,"'" ....11."'" .....' .. '"'"1 .....
....... 11...' ......11.11.11 ............... , .................... , .............. , ...11'.. ' ..' ........ , ..... , ...............11111 .......... " ......' ........ 1.. ' ........' ...... 11 ... ' ........ , ........ " ........11' .. ' ...................... 11 ......
,",I, .. 'u,........ ".'"'.II'.""'"'" ..I •• '" ••• I ... ' .. ' ... I.I""'"1"'.'"'"'"'"''''"'''''''"11"",",,,,",,,,",",",,,,",,,'".11'"'''.11,..... , ........'.1 .. ' .. ' ..111'.. '"'.... ' ....... , .............. ' .." ••11 ...
.... II .... U ... , .....'"'"'..".I ••• ' .. '" ...... ,",..... , .. ,"'.'"'"I .. '.''''.'"''''''" .. 'I''".II, ..I"II.'"'"III'I' .. 'H,.,",,,,,,,,,, ..'H'"',,' ... 11'"' .. '"1.' ....... , ..' .. ' .....11111......... , ........' ...11 ...1"'.. ' •
................ " .... 11.11............................11 ........................................... 11•••11.............. 11 ....... 11.......11.11......' ... 11.11.11.11.11............................... 81........................11 ............
Alt-X Exit
This is a good time to point out two general rules for program-
ming in any user environment: Never put the user at a loss as to what
to do next, and always give the user a way forward and a way back.
Before doing anything at all, the user of Hello has two clear
choices: Either select the menu item Hello or press Alt-X to leave
the program entirely.
You can select a menu item either from the keyboard or with the
mouse. The arrow keys move the highlight bar up and down the
menu. Selecting a highlighted item from the keyboard is done by
pressing Enterwhen the desired item is under the highlight bar.
More interesting is selection by mouse: You "grasp" the highlight
bar by pressing the left mouse button down while the mouse
pointer is on the highlight bar and holding the button down. As long
as you hold the button down, you can move the bar up and down
the list of menu items within the menu. You select one of the
menu items by letting go of the mouse button when the highlight
bar is over the menu item that you wish to select.
The dialog box has a title, "Hello, World!", and a close icon at its
upper left corner. The close icon, when clicked by the mouse,
closes the dialog box and make it disappear. Inside the dialog box
is a short text string: "How are you?" This is an example of static
text, which is text that can be read but which contains no
interactive power. In other words, static text is used to label
things, but nothing happens if you click on it.
Buttons
The four rectangles on the right side of the box are the most
interesting parts of the "Hello, World!" dialog box. These are
called buttons, and are examples of controls. They are called
controls because they resemble the controls on electronic
instruments. Each button has a label, which indicates what
happens when that button is pushed.
You push a button by clicking on it with the mouse, or by making
the button the default (described later in this section)and then
pressing Enter. Try pressing one of the buttons with the mouse
(holding down the mouse button while the pointer is on the
button) and see what happens: The body of the button moves one
position to the right, and its shadow vanishes. The illusion is that
of a rectangular button being pressed "downward" toward the
Getting out
Pressing any of the buttons in Hello "puts away" the dialog box
and leaves you with an empty desktop. You can pull down the
Hello menu again, and bring up the dialog box again, any number
of times. To exit the program, you can either select the Exit item in
the Hello menu, or simply press the Exit shortcut, Alt-X. Note that
this shortcut is presented both inside the Hello menu and in the
status line at the bottom of the screen.
This is good practice: Always make it easy for the user to exit the
program. Frustrated users who can't find the door are quite likely
to reboot the system, preventing your application from closing
files or otherwise cleaning house before shutting down.
Inside HELLO.PAS
That's what Hello does if you run it. Now, how does it make all
this happen? Much-in fact, most-of the code comprising Hello
is inherited from predefined objects provided in Turbo Vision. So
much is inherited that when the program runs, how it works may
first seem a bit of a mystery. Tracing execution with the integrated
debugger will not show you the whole picture, since Turbo Vision
is provided as compiled units. Fortunately, if you take the time to
understand what is going on, the exact how won't be necesssary.
The application
object The cornerstone object of any application is the TApplication
object. Actually, you never create an instance of object type
TApplication. TApplication is an abstract object type-just bones, no
meat. It doesn't do anything. You use TApplication by creating a
descendant object type of TApplication that contains the meat of
the program you're writing.
In Hello, that descendant object type is THelloApp:
PHelloApp = ATHelloApp;
THelloApp = object (TApplication)
procedure GreetingBox;
procedure HandleEvent(var Event: TEvent); virtual;
procedure InitMenuBar; virtual;
procedure InitStatusLine; virtual;
end;
As shown here, it's a good idea to define a pointer type to every
object type that you define, since most serious work with objects
operates through pointer references. Polymorphism works
primarily through pointer references.
THelloApp contains much more than just these four methods, of
course; a descendant object inherits everything from its ancestor. In
defining THelloApp, you define how the new object differs from its
ancestor, TApplication. Everything that you do not redefine is
inherited unchanged from TApplication.
If you think about it, the four method definitions in THelloApp pin
down the ''big picture" of your entire application:
• How the application functions is dictated by what events it
responds to, and how it responds to them. You must define a
HandleEvent method to fulfill this all-important requirement. A
HandleEvent method is defined in TApplication to deal with
Flow of execution
and debugging Because Turbo Vision applications are event-driven, the code is
structured somewhat differently than conventional programs.
Specifically, event-driven programs separate the control
structures that read and evaluate user input (and other events)
from the procedures and functions that act on that input.
Conventional programs typically contain many blocks of code,
each of which involves getting some input, deciding which code
gets that input, calling the appropriate routine(s) to process the
input, then doing the same thing again. In addition, the code that
finishes processing the input must then know where to give
control for the next round of input.
Event-driven programs, on the other hand, have a central event-
dispatching mechanism, so the bulk of your program does not
have to worry about fetching input and deciding what to do with
it. Your routines simply wait for the central dispatcher to hand
them input to process. This has important implications for
For more hints and tips on debugging your programs: You will probably want to rethink
debugging Turbo Vision
applications, see Chapter 70,
your debugging strategies, setting breakpoints in event-handling
"Hints and tips.
H
routines to check the dispatching of messages, and setting
breakpoints in your event-responding code to check that it
functions properly.
HELLO's main
program At the very highest level, the main program portion of all Turbo
Vision applications look pretty much like HELLO:
var
HelloWorld: THelloApp;
begin
HelloWorld.lnit;
HelloWorld.Run;
HelloWorld. Done;
end.
Summary
In this chapter you've had just a taste of what Turbo Vision is all
about. You have seen objects interacting in an event-driven
framework and gotten some idea of the kinds of tools that Turbo
Vision provides.
At this point you may feel confident enough to try modifying the
HELLO.PAS program to do some other things. Feel free to do so.
One of the nicest features of Turbo Vision is the freedom it gives
you to change your programs with very little effort.
The next chapter will take you through the steps of building a
Turbo Vision program of your own from the skeleton we provide.
Alt-X Exit
Objects used: TFirst's desktop, menu bar, and status line are created by the
TView
TMenuView
TApplication methods InitDeskTop, InitMenuBar, and InitStatusLine.
TMenuBar These three methods are called by TApplication.lnit, so you never
TMenuBox need to call them directly. Instead, your application's Init method
TStatusLine will call TApplication.lnit in its first line. For example:
TGroup
TDeskTop procedure TMyApp.lnit;
begin
TApplication.lnit; { call ancestor's method first
{ initialization code specific to your application goes here }
end;
Objects and their units are Note that you'll need to add some Turbo Vision units to the uses
cross-referenced in
Chapter 12.
line in the program. In order to use menus and the status bar and
the standard key definitions, you'll need to use Objects, Menus,
and Drivers in addition to App.
If your program doesn't need to do any special initialization, you
simply use the inherited Init method. Because the Init and
InitDeskTop, InitMenuBar, and InitStatusLine methods are virtual,
calling the inherited Init calls the proper InitStatusLire and
The desktop
The~esktop is an extremely important object, but it needs little
attention from you. You should never need to override the
inherited initialization method. Let T Application.InitDeskTop
handle it. DeskTop is owned by MyApp, and whenever MyApp
instantiates a new view in response to the user clicking on a menu
selection, it should attach the new view to DeskTop. Beyond this,
the desktop knows how to manage views by itself.
Creating new Note that cmQuit and cmClose, the commands you bound to the
commands status line items, are standard Turbo Vision commands, so you
don't have to define them. In order to use customized commands,
you simply declare your commands as constant values. For
example, you can define a new command for opening a new
window:
Turbo Vision reserves some const
constants for its own cmNewWin = 199;
commands. See "Defining
commands u in Chapter 5. Next you can bind that command to a hot key and a status line
item:
.~'"T::II
cmFileOpen = 200; { define a new command }
procedure TMyApp.lnitMenuBar;
::::::::::::::::::::4::::::::::::::::::::::: var R: TRect;
begin
GetExtent(R); { get area of the application}
R.B.Y := R.A.Y + 1; { set bottom 1 line below top}
MenuBar := New(PMenuBar, Init(R, NewMenu( {create bar with menu}
NewSubMenu('~F~ile', hcNoContext, NewMenu( { define menu}
Newltem('~O~pen', 'F3', kbF3, cmFileOpen, hcNoContext, {item}
nil) ) , { no more items }
nil) { no more submenus }
))); { end of the bar}
end;
The single menu produced by this code is called 'File,' and the
single menu selection is called 'Open.' The tildes (..... ) make Fthe
shortcut letter in 'File,' and O'the shortcut letter in 'Open,' and the
F3 key is bound as a hot key for 'Open.'
All Turbo Vision views can have a help context number associat-
ed with them. The number makes it easy for you to implement
context-sensitive help throughout your application. By default,
views have a context of hcNoContext, which is a special context
that doesn't change the current context. Help context numbers
···"···";55i'I'
......... "1 .. "..
::::::::::::::::::
1 .. 111111111111."
II................
11I1I1I.. n.1I1I1I
.... ".111111111........
u .................
1I1I..............
Zoom
u....
111I1
::
..
IIII
II
.1
'1
'1
........ 11' ... 11 .... 111 ... 11 ......... 1111 ..... 1111 ... .,111 .. '"111111
NewSubMenu('-F-ile', hcNoContext, NewMenu(
Newltem('-O-pen', 'F3', kbF3, cmFileOpen, hcNoContext,
Newltem('-N-ew', 'F4', kbF4, cmNewWin, hcNoContext,
nil))), {closing parens for menu selections}
NewSubMenu('-W-indow', hcNoContext, NewMenu(
Newltem('-N-ext', 'F6', kbF6, cmNext, hcNoContext,
Newltem('-Z-oom', 'FS', kbFS, cmZoom, hcNoContext,
nil) ),
nil))) {closing parens for menus}
)));
A note on
structure At this point, a number of commands are available, but most of
them are disabled, and the cmNew Win and cmFileOpen commands
don't yet perform any actions.
If your initial reaction is one of disappointment, it shouldn't be-
you've accomplished a lot! In fact, what you've just discovered is
one of the big advantages of event-driven programming: You
separate the function of getting your input from the function of
responding to that input.
With traditional programming techniques, you would need to go
back into the code you've just written and start adding code to
open windows and such. But you don't have to do that: You've
got a solid engine that knows how to generate commands. All you
need to do is write a few routines that respond to those
commands. And that's just what you'll do in the next section.
The Turbo Vision application framework takes you one step
beyond traditional modular programming. Not only do you break
your code up into functional, reusable blocks, but those blocks
can be smaller, more independent, and more interchangeable.
Your program now has several different ways to generate a
command (cmNewWin) to open a window: a status line item, a
menu item, and a hot key. In a moment, you'll see how easy it is
to tell your application to open a window when that command
shows up. The most important thing is that the application
doesn't care how the command was generated, and neither will
the window. All that functionality is independent.
If, later on, you decide you want to change the binding of the
command-move the menu selection, remap the hot keys,
Opening a window
Objects used: If you're a typical programmer, you may have jumped directly to
TRect
this section as soon as you opened the book. After all, what's more
TView
TWindow central to writing a windowed application than making a
TGroup window?
TScrol/er
TScrollBar It's true that if Turbo Vision were a collection of traditional library
routines, then jumping right to this section and trying to get right
to work might be a good idea. You could very well get a good
sense of the library's overall quality and organization.
But Turbo Vision isn't a traditional library. If you've read the
preceding chapters, you already know that. In order to program
in Turbo Vision, there are some things you need to do before it
makes sense to create a window. You need to understand just
what a Turbo Vision window is (it's an object!), and how it is
different from windows you might have used before. When
you've done this, you will be further along in your first
application than you'd ever imagine.
So, if you've jumped into the cookbook at this point, you need to
go back to the preceding sections and lay a little groundwork. It
will be well worth it.
Standard window
equipment A Turbo Vision window is an object, and built into it is the ability
to respond to much of the user's input without you having to
write a line of code. A Turbo Vision window already knows how
to open, resize, move, and close. But you don't write on a Turbo
Vision window. A Turbo Vision window is a container that holds
and manages other objects: It is these objects that represent
themselves on the screen, not the window itself. The window
manages the views, and your application's unique functionality is
in the views that the window owns and manages. The views you
create retain great flexibility about where and how they will
appear.
Window
initialization You need to give a Turbo Vision window three parameters for it
to initialize itself: its size and position on the screen, a title, and a
window number.
The TRect object is described The first parameter, determining the window's size and position,
in detail in Chapter 4, is a TRect, Turbo Vision's rectangle object. TRect is a very simple
"Views. '"
object. Its Assign method gives it a size and position, based on its
top-left comer and its bottom-right comer. There are several other
ways to assign or change the values of a TRect object. Consult
Chapte~ 14, "Global reference," for complete descriptions.
you are inserting Window into the desktop. You may insert any
number of views into a group object like the desktop. The group
you insert a view into is called the owner view, and the view you
insert into it is called a subview. Note that a sub view may itself be
a group, and may have its own subviews. For instance, when you
insert a window into the desktop, the window is a subview, but
Closing a window Clicking the close icon on a window generates the same emClose
command you bound to the AIt-F3 keystroke and a status line item.
By default, opening a window (with F4 or the File IOpen menu
choice) automatically enables the em Close command and the
views that generate it (as well as other window-related com-
mands like emZoom and emNext).
You don't have to write any new code to close the window. When
the user clicks on the window's close icon, Turbo Vision does the
rest. By default, a window responds to the em Close command by
calling its Done destructor:
Dispose(MyWindow, Done);
As part of the window's Done method, it calls the Done methods of
all its subviews. If you've allocated any additional memory your-
self in the window's constructor, you need to make sure that you
deallocate it in the window's Done method.
Window behavior
Take some time to play with the program you've written. It has a
great deal of capability already. It knows how to open, close,
select, move, resize, and zoom multiple windows on the desktop.
Not bad for fewer than 100 lines of code!
After TMyApp initializes the window, it inserts it into the desktop.
As you recall, DeskTop is a group, which means that its purpose is
to own and manage subviews, like your window. If you compile
and run the code, you'll notice that you can resize, move, and
close the new window. Your mouse input is being turned into a
series of events and routed from the desktop to the new window,
which knows how to handle them.
If you keep invoking emNewWin, more windows will appear on
the desktop, each with a unique number. These windows can be
resized, selected, and moved over one another. Figure 2.2 shows
the desktop as it appears with several windows open.
windows open
1
::::::::::ELi
--
............
--
6 .... ·····W·i~d~;··2·-·. . ·····i§
Demo Win~dOW
WIndow
.. .
9=['l~~~fi~
I. . . . . . . . . . . . . . . . . . . . . . . . . . .
--
.... I " " ' " ' ' ' ' " ' ' . , I I , .. II." .... IIIIIIIII .... II'"IIII,IIIUIHIIIIIII1I1 .......................... llIlnlnl.....'O'.. IIIIUI ..." ............ II.IIII""H'"I""IIIIIIIIII'"III""'"'''"IIIII"II"""""HIII"""III""I"II1111.1'"111
.1I.1I1 .. 11I1"11I11I ... IIII ... I1I .. II1I ...... III""IIII.'HI ..... I .. II. . I1I .. I111 .. 1.. 11I....... III"I"'"I • • • IIII"" ..... III.HI .. I .. IIIIIIIHI ..... I"... 1..... 1""11 ....... 11"11. . . . . '"" .. 1. . 1.. 111" ........1 ...111 ... 11 ....111.....
1............... I1 ........................ IIII ... H.II .............. , .. , •• , ".... 11 .... 1111.'.'.1"' .. 111.1111..... " ......' " ................" ... ' ...11'II.II .... H .... III .............. III ................... II.III ......... II.II .... 11111
...,.,..................,............................. ,.................................,................................,.....,..,.......................,............................................,.........,....................
... ,", .. , . , ...................", .............. , . . . . . . . . . . . , ............. ," . . . . . . . . . . . . . . . . . . . . . . 11 ... '11 •• ' . . . . . . , ..... '" ... '11' ......... '11' ..... 'U .......... , .............. '.I' ... I1'..... ' .. ' .. III' ..... '".II'II ..I1..... ""
... , .. , ........... ' .. I ........ _ ...... , .. ' . . . . 'H'"."'"' ..... ' .. ," ... , ... " . . . . . . . . . . . . . . . . ' ... 11 . . . . . ' .......... , .. , .. , ............................. , .. , ........... , .. , ........ , .. , .. , .. , ........ ,", ..... , .. , .. , .. , .. , ........ , ... ..
,,,,,,.11, .. , ..... , .. , ..... , .. , ..... , .. , .. , .. ' .. ' .. 1.. '11, .. , .. , .. '11 ... ' ..... 1.. , ..... ' ..... ' .. 1.. ' .. ' .. 1.. ' ..... ' .. 1.. ' .. ' .. 1.. 1 .. ' ..... 1.. ' .. '"' .. , .. , ..... , .. , .. , .. , ....................... , ......................................... ' .. '11
, ..................... I ..I .........u ............ ' ..III.II.II .......... H ................ H ......, .............. , ................. II........ ",,,,,,,,,,,,,,,'''''' ............ ' " ....1........... " ... ' ... " . . . . . . . . . . . . . . . . . . . . . . . . ' " ' •
. . . . . , . . . . . . . . . , . ' . . . . . 11 . . . . . . . . . . . . . . . , .. , . , . . . . . . . . . . . . . . . . . . . . . , .. , . . . . . . . . . , . . . . , . . . . . . . . . . . . . . . . 11 . . . . . . . . . . . . . . . . . . . . . ' .. ' ... 11 ... 111' . . . . . . , ... " ............... , . . . . . . . , ........... 11 •• 11 ............ , .. , .. , ... ..
, .................... , ..... , ........... I .. ' ...... H.II' ........, ..... II., .. , ....... , ..... , ....... , ............ , ....... ' .. ' .. 1................. " .... , ....................... , .. , ..........., ..........1, ..", ......... , .. , ...., ...... ' ...... 11
, .................. I .......................................... H ............ , ..... , .......................... , . . . . , .. ' . . . . . 11 ...................... , • • • , .. , ..... , .................... , .. , .......................... , ..................... ..
' ... , ....... ' .................... , .. , ... ", ..... , ..... , ........... , ..... , ...... " ... , .......... , ...................................... , ..... , .......................... '11' .. ' .. ' .. , ........ , ..... ' .. ' ..... 111 ... ' ..... , .. ' .. ' ... 11' ........ ,.
" .... ,,, ...... ,.. ,.. ,..,.. ,..... ,..... '.. '.. '" ..."11.........1'.. '.. '.. '"' .. '" ... '...... 11' ..'"' .. ' ..... ' ..... '" ... '.1' .. '.. '........................ 11." ...... , ..... '...
11 .... 11 ... ' ..... ' ....... 111 ....... ' . .'"' ............. , .... ..
. . . , . . . . . . . . . . . ' " . . . . . . . . . . . . . . . . . . . . . , . . . . . . . . . . . . . . . . . . . . . . . ' . . ' " '. . . . . . . . . . . , . . , . . . . . . . . , . . . . . . . , . . . . . . . . . . ., . . . . . . . . . . . . . 11. . . . . . . ' . . . . . . . . . . . , . . . . . . . . . " . . . . . . , ..... , . . . " . . . , . . . . . . . . . . . . . . . " . . . . . . . . . . . . . . . . . . . . . . . . ." . . . . . . . . . . . .
, ........ , ...... 11.11 .......... 11 . . . . . , ........ , ........... "., .. , ..... , ..... , ... 11'" ............" .... , ............. , .............. 11 ....... ' ... 11' .............. , ....................... , ........... '"'" ... ' ..' .. , .. ,., .. ,,', .. , ...... ..
......... '"'"' ..... ' .. , .. , .. , ........ , ........ , .. , ........ , ..................... , .. , ..... , .. , ..... ' ... H ...... 'H ...... ' ...... II ... ' .. ' ........... , .. , .. , •• , ..... 11 .... ' ........ , .. ''' ...'"." ............. 11 ...... '" ... ' ..... , ........ , ..
... , ... " .................. , .. , ....., ..... , .. , .. , ..... ' .....1.. ' ......................' ... 11'........ ,.............. , ........ , ........ , ........ , ............ 11 ............ '.. '.. '" .... "' ........... , .. , .............., ..... , ............... ..
.. 1' ..... 111111 .. 11 .. ' .. ' .. ' .. , ..... ' ..... 1111111 .. ' .. ' .. ' .. , .. , .............. , .. , ..... 11 .... 1111 .. ' .. '11' ..... ' .......... 11111 .. '"' ..... ' .. , .. ,.'"111'11 ...... " ......................... U .. II ............... ' .. '" ...................... ..
, ........ , ... 11 . . . . . , . . . . . . '.11 .... 11 .............
11' ...... 11'" ... ' .. ' .. '" ....... , ........ , ..... , .............. ' ...... 11 ............ , ........... ,", .. , ......., ... '"'.. '.. '".1,............... '...... "' ..1.. '.. '"' ..... '.. '"' ..... '..
'11
. . . . . . . . . . . . . . . . " . . . . " . " . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . , . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . , . . . . . . . . , . . . . . . . . I I . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . , . . . . . . . . .. .
'.. ''''.11.. '.. '..111 ......11'"' ......... "
,........... ,..... ,.. ,..... ,................,.....,..... ,........... ,........................................................................................
... , .. ",,", ......... ", ..... ,", .. '"' ........ ' ... "'"'........ , .. , .......... , ...... " ....... ".11'" ...... , ........ 11 . . . ' ..."'" ...... ' ........... ' .. 1..... ' .. '"' ...... 11 ...'"' .. " .... , ..
.........,...............................
. ,.....................................
......,....................... ,... "... ,.......................... ,....................................................................... ,................., ...........
, ........ ' ... 11 ... ' .. ' .. " .. " .......... "" .. , ...... "".... "" .............",...... " .. 11 ..................................'" ... III'.'I ......... II ... II' .. I ...... II.II'""IIH.1I'" ............... 11 .. ' .... ' ........ 11 .. 11' .. '''.'' .... ..
Hello, World!
What do you
see? All Turbo Vision views know how to draw themselves. A view's
drawing takes place within the method Draw. If you create a
descendant view with a new screen representation, you need to
override its ancestor's Draw method and teach the new object how
to represent itself on the screen. Tlnterior is a descendant of TView,
and it needs a new Draw method.
Notice that the new Tlnterior.Draw first calls the Draw of its
ancestor, TView, which in this case just clears the rectangle of the
view. Normally you would not do this: Your interior view's Draw
method should take care of its entire region, making the
TView.Draw call redundant.
If you really have something to put into a window's interior, you
won't want to call the inherited Draw method anyway. Calling
TView.Draw will tend to cause flickering, because parts of the
interior are being drawn more than once.
As an exercise, you might try recompiling TVGUIDOS.PAS with
the call to TView.Draw commented out. Then move and resize the
window. This should make quite clear why a view needs to take
responsibility for covering its entire region!
Turbo Vision calls a view's Draw method whenever the user
opens, closes, moves, or resizes views. If you need to ask a view
A better way to Write While you can make Turbo Pascal's Write procedure work in
Turbo Vision, it is the wrong tool for the job. First, if you simply
write something, there's no way you can keep a window or other
view from eventually coming along and obliterating it. Second,
you need to write to the current view's local coordinates, and clip
to the view's boundary. Third, there is the question of what color
to use when writing.
Turbo Vision's WriteStr not only knows how to write with local
coordinates and how to be clipped by the view's boundaries, but
also how to use the view's color palette. The WriteStr procedure
takes x- and y-coordinates, the string to be written, and a color
index as parameters.
Similar to WriteStr is WriteChar, defined as
WriteChar(X, Y, Ch, Color, Count)
Like WriteStr, WriteChar positions its output at x- and y-
coordinates within the view, and writes Count copies of the
character Ch in the color indicated by the Color'th entry in the
view's palette.
Each of these Write methods should only be called from within a
view's Draw method. That's the only place you need to write
anything in Turbo Vision.
A simple file
viewer In this section you'll add some new functionality to your window
and put something real in the interior. You'll add methods to read
a text file from disk and display it in the interior.
Warningl This program will display some "garbage" characters. Don't
worry-we did that on purpose!
This is TVGUl006.PAS. const
MaxLines = 100; { This is an arbitrary number of lines
var
LineCount: Integer;
Lines: array[O .. MaxLines - 1] of PString;
PInterior = ATInterior;
Reading a text file Your application needs to call ReadFile to load the text file into the
array Lines, and DoneFile after executing to deallocate the space
used by Lines.
In ReadFile, the Turbo Vision global type PString is a string
pointer. Turbo Vision also supplies a function called NewStr that
stores a string on the heap and returns a pointer to it. Even
though NewStr returns a pointer, don't use Dispose to get rid of it.
Buffered drawing
You will notice that when you run this program, there are
garbage" characters displayed on the screen where there should
1/
The draw buffer To take care of this, create a new Draw that assembles each line in
a buffer before writing it in the window. TDrawBuffer is a global
type:
MaxViewWidth is 732 TDrawBuffer = array[O .. MaxViewWidth-l] of Word;
characters.
TDrawBuffer holds alternating attribute and character bytes.
The new Tlnterior.Draw looks like this:
This is TVGUID07.PAS procedure TInterior.Draw; { corrected Draw method }
var
Color: Byte;
Y: Integer;
B: TDrawBuffer;
begin
Color := GetColor(I);
for Y := 0 to Size.Y - 1 do
begin
MoveChar(B, , " Color, Size.X); { fill line with spaces
if (Y < LineCount) and (Lines[Y] <> nil) then
MoveStr(B, Copy(Lines[Y]A, 1, Size.X), Color); {copy in text
WriteLine(O, Y, Size.X, 1, B); { write the line
end;
end;
Figure 2.4 shows TVGUID07 with several windows open.
Moving text into a Turbo Vision supplies four global procedures for moving text into
buffer a TDrawBuffer: MoveStr, which you just looked at, and MoveChar,
MoveCStr, and MoveBut, which move characters, control strings
(strings with tildes for menus and status items), and other buffers,
respectively, into a buffer. All these procedures are explained in
detail in Chapter 14, "Global reference."
Writing buffer contents Turbo Vision provides two different procedures for writing the
contents of a buffer to a view. One, WriteLine(X, Y, W, H, Buf), was
shown in TVGUID07.
In Tlnterior.Draw, WriteLine writes TDrawBuffer on one line. If the
fourth parameter, H (for height), is greater than I, WriteLine
repeats the buffer on subsequent lines. Thus, if But holds "Hello,
World!", Wri teLine (0,0, 13,4, Buf) will write
Hello, World!
Hello, World!
Hello, World!
Hello, World!
Knowing how much to Note that Tlnterior.Draw draws just enough of the file to fill the
write interior. Otherwise, Draw would spend much of its time writing
parts of the file that would just end up being clipped by the
boundaries of Tlnterior.
If a view requires a lot of time to draw itself, you can first call
GetClipRect. GetCIipRect returns the rectangle that is exposed
within the owner, so you only need to draw the part of the view
that is exposed. For example, if you have a complex dialog box
with a number of controls in it, and you move it most of the way
off the screen so you can look at something behind it, calling
GetClipRect before drawing would save having to redraw the
parts of the dialog box that are temporarily off the screen.
Scrolling up and
down Obviously, a file viewer isn't much use if you can only look at the
first few lines of the file. So next you'll change the interior to a
scrolling view, and give it scroll bars, so that Tlnterior becomes a
scrollable window on the textfile. You'll also change
TDemoWindow, giving it a Makelnterior method to separate that
function from the mechanics of opening the window.
This is TVGUID08.PAS type
Plnterior = ATlnterior;
The horizontal and vertical scroll bars are initialized and inserted
in the group, and then are passed to TScroller in its initialization.
A scroller is a view designed to display part of a larger virtual
view. A scroller and its scroll bars cooperate to produce a
scrollable view with remarkably little work by you. All you have
to do is provide a Draw method for the scroller so it displays the
proper part of the virtual view. The scroll bars automatically
control the scroller values Delta.X (the column to begin
displaying) and Delta.Y (the first line to begin displaying).
You must override a TScroller's Draw method in order to make a
useful scroller. The Delta values will change in response to the
scroll bars, but it won't display anything by itself. The Draw
method will be called whenever Delta changes, so that is where
you need to put the response to Delta.
J
Window with multiple panes =[1] Demo Window 1 [t]91
procedure DoneFil e, It.
Note that you do not have to call SizeLimits. You just override it,
and it will be called at the appropriate times. This is the same
thing you did with the Draw method: You told the view how to
draw itself, but not when. Turbo Vision already knew when to call
Draw. The same applies to SizeLimits: You set the limits, and the
view knows the appropriate times to check them.
There are really very few differences between this dialog box and
your earliest windows, except for the following:
• The default color of the dialog box is gray instead of blue.
• The dialog box is not resiza,ble or zoomable.
• The dialog box has no window number.
Note that you can close the dialog box either by clicking on its
close icon, clicking the Alt-FS status line item, or pressing the Esc
key. By default, the Esc key cancels the dialog box.
This is an example of what is called a non-modal (or "modeless")
dialog box. Dialog boxes are usually modal, which means that they
define a mode of operation. Usually when you open a dialog box,
the dialog box is the only thing active: it is the modal view.
Clicking on other windows or the menus will have no effect as
Modal views are discussed in long as you are in the dialog box's mode. There may be occasions
Chapter 4, "Views. ,.
when you want to use non-modal dialog boxes, but in the vast
majority of cases, you will want to make your dialog boxes modal.
Executing a
modal dialog box So how do you make your dialog box modal? It's really very easy.
Instead of inserting the dialog box object into the desktop, you
execute it, by calling the DeskTopl\.ExecView function:
This is TVGUID72.PAS procedure TMyApp.NewDialog;
v'!-r
Dialog: PDialog;
R: TRect;
Control: Word;
begin
R.Assign (O, 0, 40, 13);
R.Move{Random(39), Random{lO)):
Dialog := New{PDialog, Init{R, 'Demo Dialog'));
Control := DeskTopA.ExecView{Dialog);
end;
Taking control
Of course, a dialog box with nothing in it is not much of a dialog
box! To make this interesting, you need to add controls. Controls
are various elements within a dialog box that allow you to
manipulate information. The important thing to remember about
controls is that they only affect things within the dialog box.
Command handling is The only exception to this rule is the case of a button in a
explained more in Chapter 5, modeless dialog box. Because buttons generate commands, those
"Event-driven programming."
commands will spread downward from the current modal view.
If the dialog box is not the modal view, those commands will go
to places outside the dialog box, which may have unintended
effects.
In general, when setting up controls in a dialog box, you can
separate the visual presentation from the handling of data. This
means you can easily design an entire dialog box without having
to create the code that sets up or uses the data provided in the
dialog box, just as you were able to set up menus and status items
without having code that acted on the commands generated.
Button, button... One of the simplest control objects is the TButton. It works very
much like a fancy status line item: It's a colored region with a text
label on it, and if you click on it, it generates a command. There is
also a shadow "behind" the button, so that when you click on the
button it gives a sort of three-dimensional movement effect.
Most dialog boxes have at least one or two buttons. The most
common are buttons for "OK" (meaning "I'm done. You may
close the dialog box and accept the results.") and "Cancel"
(meaning "I want to close the dialog box and ignore any changes
1. the region the button will cover (Remember to leave room for
the shadow!)
2. the text that will appear on the button
3. the command to be bound to the button
4. a flag indicating the type of button (normal or default)
Figure 2.8 [ 1 ] = Demo Dialog Box = = = 9 1
Dialog box with buttons
Normal and default Whenever you create a button, you give it a flag, either bfNormal
buttons or bfDefault. Most buttons will be bfNormal. A button flagged with
bfDefault will be the default button, meaning that it will be
"pressed" when you press the Enter key. Turbo Vision does not
check to ensure that you have only one default button-that is
your responsibility. If you designate more than one default
control, the results will be unpredictable.
Usually, the "OK" button in a dialog box is the default button,
and users become accustomed to pressing Enter to close a dialog
box and accept changes made in it.
Focused controls Notice that when a dialog box is open, one of the controls in it is
always highlighted. That is the active, or focused, control. Focus of
controls is most useful for directing keyboard input and for
activating controls without a mouse. For example, if a button has
the focus, the user can "press" the button by pressing Spacebar.
Characters can only be typed into an input line if the input line
has the focus.
Labels are discussed later in The user can press the Tab key to move the focus from control to
this chapter.
control within the dialog box. Labels won't accept the focus, so
the Tab key skips over them.
Tob order is important! You will want the user to be able to Tab around the dialog box in
some logical order. The Tab order is the order in which the objects
were inserted into the dialog box. Internally, the objects owned by
the dialog box are maintained in a circular linked list, with the last
object inserted linked to the first object.
By default, the focus ends up at the last object inserted. You can
move the focus to another control either by using the dialog box's
SelectNext method or by calling the control's Select method
directly. SelectNext allows you to move either forward or
backward through the list of controls. SelectNext(False) moves you
forward through the circular list (in Tab order); SelectNext(True)
moves you backward.
Creating a cluster There is probably no reason you would ever want to create an
instance of a plain TCluster. Since the process for setting up a
check box cluster is the same as that for setting up a cluster of
radio buttons, you only need to look at the process in detail once.
Add the following code to the TMyApp.NewDialog method, after
the dialog box is created but before the buttons are added. Keep
the buttons as the last items inserted so they will also be last in
Tab order.
[ ] Hvarti var
[ ] Til set B: PView;
[ ] Jarl sberg R.Assign (3, 3, 18, 6);
B := New(PCheckBoxes, Init(R,
NewSltem('~H~varti' ,
NewSltem('~T~ilset' ,
NewSltem('~J~arlsberg' ,
nil)) )
));
Insert(B);
The initialization is quite simple. You designate a rectangle to
hold the items (remembering to allow room for the check boxes
themselves), and then create a linked list of pointers to strings
that will show up next to the check boxes, terminated by a nil.
Delivery instructions
The input line also has a label for clarity, since unlabeled input
lines can be even more confusing to users than unlabeled clusters.
Setting and
getting data Now that you have constructed a fairly complex dialog box, you
need to figure out how to use it. You have set up the user interface
end; now you need to set up the program interface. Having
controls isn't much help if you don't know how to get
information from them!
There are basically two things you need to be able to do: Set the
initial values of the controls when the dialog box is opened, and
read the values back when the dialog box is closed. Note that you
don't want to modify any data outside the dialog box until you
successfully close the box. If the user decides to cancel the dialog
box, you have to be able to ignore any changes made while the
dialog box was open.
Views that have no data (such as labels and buttons) use the
GetData method they inherit from TView, which does nothing at
all, so you don't need to concern yourself with them here. This
means that when getting and setting data, you can skip over
labels and buttons.
Thus, you are only concerned with three of the views in the dialog
box: the check boxes, the radio buttons, and the input line. As
noted earlier, each of the cluster items stores its data in a Word-
type field. The input line's data is stored in a string. You can set
up a data record for this dialog box in a global type declaration:
DialogData = record
CheckBoxData: Word;
RadioButtonData: Word;
InputLineData: string[128];
end;
Now all you have to do is initialize the record when you start up
the program (MyApp.Init is a good place), set the data when you
enter the dialog box, and read it back when the dialog box closes
successfully. It's almost easier to say that in Pascal than it was in
English! Once you've declared the type as we did here, you
declare a global variable:
var
DemoDialogData: DialogData;
then add one line before executing the dialog box and one after:
DialogA.SetData(DemoDialogData);
control := DeskTopA.ExecView(Dialog);
if Control <> cmCancel then DialogA.GetData(DemoDialogData);
and add six lines to the TMyApp.Init method to set the initial
values for the dialog box:
This is TVGUlD 76.PAS with DemoDialogData do
DeliVVf.j instructions
'R,uid..".!,,!-
Static text
TStaticText is a view that simply displays the string passed to it.
The string is word wrapped within the view's rectangle. The text
will be centered if the string begins with a Ctr/-C and line breaks
can be forced with etr/-M. By default, the text can't get the focus,
and of course, the object gets no data from the data record.
List viewer
A TListViewer will display a single or multiple column list, from
which the user can select items. A ListViewer can also
communicate with two scroll bars.
TListViewer is meant to be a building block, and is not usable by
itself. It has the ability to handle a list, but does not itself contain a
list. Its abstract method GetText loads the list members for its
Draw method. A working descendant of TListViewer needs to
override GetText to load actual data.
List box
TListBox is a working descendant of TListViewer. It owns a
TCollection that is assumed to be pointers to strings. TListBox only
supports one scroll bar. An example of a list box is the file
History
THistory implements an object that works together with an input
line and a related list box. By clicking on the arrow icon next to
the input line, the user brings up a list of previous values given
for the input line, any of which may then be selected. This saves
on repetitive typing.
THistory objects are used in many places in the Turbo Pascal
integrated environment, such as the File I Open dialog box and in
the Search I Find dialog box.
63
64 Turbo Vision Guide
c H A p T E R
Object typology
Not all object types are created equal in Turbo Vision. You can
separate their functions into three distinct groups: primitive
objects, view objects, and mute objects. Each of these is described
in a separate section of this chapter.
Within each of these groups there are also different sorts of
objects, some of which are useful objects that you can instantiate
and use, and others of which are abstract objects that serve as the
basis for deriving related, useful objects. Before we look at the
objects in the Turbo Vision hierarchy, it will be helpful to
understand a little about these abstract objects.
Abstract objects
Many object types exist as "abstract" bases from which more
specialized and immediately useful object types can be derived.
The reason for having abstract types is partly conceptual but
largely serves the practical aim of reducing coding effort.
Take the TRadioButtons and TCheckBoxes types, for example. They
could each be derived directly from TView without difficulty.
However, they share a great deal in common: They both represent
sets of c0ntrols with similar responses. A set of radio buttons is a
lot like a set of check boxes within which only one box can be
checked, although there are a few other technical differences. This
commonality warrants an abstract class called TCluster.
TRadioButtons and TCheckBoxes are then derived from TCluster
with the addition of a few specialized methods to provide their
individual functionalities.
Abstract types are never usefully instantiated. An instance of
TCluster, MyCluster, for example, would not have a useful Draw
method: It inherits TView.Draw without overriding, so
MyCluster.Draw would simply display an empty rectangle of the
default color. If you want a fancy cluster of controls with
properties different from radio buttons or check boxes, you might
try deriving a TMyCluster from TCluster, or it might be easier to
derive your special cluster from TRadioButtons or TCheckBoxes,
Abstract methods
Whether you can usefully instantiate an object type depends
entirely on the circumstances. Many of Turbo Vision's standard
types have abstract methods that must be defined in descendant
types. Standard types may also have pseudo-abstract methods
offering minimal default actions that may suit your purposes-if
not, a derived type will be needed.
A general rule is that as you travel down the Turbo Vision
hierarchy, the standard types become more specialized and less
"abstract." Their names reveal the functionality encapsulated in
their fields and methods. For most applications there will be
obvious base types from which you can create a "standard"
interface: a desktop, menu bar, status line, dialog boxes, and so
on.
Instantiation
Creating an instance of an object is usually accomplished by a
variable declaration, either static or dynamic:
MyScrollBar: TScrollBar;
SomeButton: PButton;
MyScrollBar would be initialized by TScrollBar.lnit with certain
default field values. These can be found by consulting the
TScrollBar.lnit entry in Chapter 13,"Object reference." Since
TScrollBar is a descendant of TView, TScrollBar.lnit calls TView.lnit
to set the fields inherited from TView. Similarly, TView.lnit is a
Derivation
You can easily derive a new object type from an existing one:
PNewScrollBar = ATNewScrollBar;
TNewScrollBar = object(TScrollBar)
end;
You do not yet have any instances of this new object type. Before
declaring any TNewScrollBar objects, you need to define new
methods or override some of TScrollBar's methods and possibly
add some new fields; otherwise there would be no reason to
create a new scroll bar object type. The new or revised methods
and fields you define constitute the process of adding
functionality to TScrollBar. Your new Init method would
determine the default values for your new scroll bar objects.
Abstract methods
In the base object type, an abstract method has no defining body
(or a body containing the statement Abstract set to trap illegal
calls). Abstract methods must be defined by a descendant before
they can be used. Abstract methods are always virtual methods.
An example of this is TStream.Read.
Virtual methods
Virtual methods use the virtual directive in their prototype
declarations. A virtual method can be redefined (overridden) in
descendants but the redefined method must itself be virtual and
match the original method's header exactly. Virtual methods need
not be overridden, but the usual intention is that they will be
overridden sooner or later. An example of this is TView.DataSize.
Static methods
A static method cannot be overridden per se. A descendant type
may define a method with the same name using entirely different
arguments and return types, if necessary, but static methods do
not operate polymorphically. This is most critical when you call
methods of dynamic objects. For example, if PGeneric is a pointer
variable of type PView, you can assign pointers of any type from
the hierarchy to it. However, when you dereference the variable
and call a static method, the method called will always be TView's,
since that is the type of the pointer as determined at compile time. .
In other words, PGeneric".StaticMethod is always equivalent to
TView.StaticMethod, even if you have assigned a pointer of some
other type to PGeneric. An example is TView.Init.
Notice that TGroup inherits all the fields of TView and adds
several more that are pertinent to group operation, such as
pointers to the current and last views in the group. TWindow in
turn inherits all of TGroup's fields and adds yet more which are
needed for window operation, such as the title and number of the
window.
In order to fully understand TWindow, you need to keep in mind
that a window is a group and also a view.
TRect
This object represents a rectangle. Its fields, A and B, are TPoint
objects defining the rectangle's upper-left and lower-right points.
TRect has methods Assign, Copy, Move, Grow, Intersect, Union,
Contains, Equals, and Empty. TRect objects are not visible views
and cannot draw themselves. However, all views are rectangular:
Their Init constructors all take a Bounds parameter of type TRect to
determine the region they will cover.
TObject
TObject is an abstract base type with no fields. It is the ancestor of
all Turbo Vision objects except TPoint and TRect. TObject provides
three methods: Init, Free, and Done. The constructor, Init, forms the
base for all Turbo Vision constructors by providing memory
allocation. Free disposes of this allocation. Done is an abstract
destructor that must be overriden by descendants. Any objects
that you intend to use with Turbo Vision's streams must be
derived ultimately from TObject.
TObject's descendants fall into one of two families: views or non-
views. Views are descendants of TView, which gives them special
properties not shared by non-views. Views can draw themselves
and handle events sent to them. The non-view objects provide a
host of utilities for handling streams and collections of other
objects, including views, but they are not directly "viewable."
Views
The displayable descendants of TObject are known as views, and
are derived from TView, an immediate descendant of TObject. You
Views overview
A view is any object that can be drawn (displayed) in a
rectangular portion of the screen. The type of a view object must
be a descendant of TView. TView itself is an abstract object
representing an empty rectangular screen area. Having TView as
an ancestor, though, ensures that each derived view has at least a
rectangular portion of the screen and a minimal virtual Draw
method (forcing all immediate descendants to supply a specific
Draw method).
Most of your Turbo Vision programming will use the more
specialized descendants of TView, but the functionality of TView
permeates the whole of Turbo Vision, so you'll need to
understand what it offers.
Groups
The importance of TView is literally apparent from the hierarchy
chart shown in Figure 3.1. Everything you can see in a Turbo
Vision application derives in some way from TView. But some of
those visible objects are also important for another reason: They
allow several objects to act in concert.
The abstract group TGroup lets you handle dynamically chained lists of related,
interacting subviews via a designated view called the owner of the
group. Each view has an Owner field of type PView that points to
the owning TGroup object. A nil pointer means that the view has
no owner. A field called Next provides a link to the next view in
the view chain. Since a group is a view, there can be subviews that
are groups owning their own subviews, and so on.
The state of the chain is constantly changing as the user clicks and
types during an application. New groups can be created and
subviews can be added to (inserted) and deleted from a group.
During its lifespan, a subview can be hidden or exposed by
actions performed on other subviews, so the group needs to
coordinate many activities.
Windows TWindow objects, with help from associated TFrame objects, are
the popular bordered rectanglar displays that you can drag,
resize, and hide using methods inherited from TView. A field
called Frame points to the window's TFrame object. A TWindow
object can also zoom and close itself using its own methods.
TWindow handles the Tab and Shift-Tab key method for selecting
the next and previous selectable subviews in a window.
TWindow's event handler takes care of close, zoom, and resize
commands. Numbered windows can be selected with AIt-n hot
keys.
Menus TMenu View and its two descendants, TMenuBar and TMenuBox,
provide the basic objects for creating pull-down menus and
submenus nested to any level. You supply text strings for the
menu selections (with optional highlighted shortcut letters)
together with the commands associated with each selection. The
HandleEvent methods take care of the mechanics of mouse and/or
keyboard (including shortcut and hot key) menu selection.
Input lines TlnputLine is a specialized view that provides a basic input line
string editor. It handles all the usual keyboard entries and cursor
movements (including Home and End). It offers deletes and inserts
with selectable insert and overwrite modes and automatic cursor
shape control. The mouse can be used to block mark text.
List viewers The TListViewer object type is an abstract base type from which to
derive list viewers of various kinds, such as TListBox. TListViewer's
fields and methods let you display linked lists of strings with
control over one or two scroll bars. The event handler permits
mouse or key selection (with highlight) of items on the list. The
Draw method copes with resizing and scrolling. TListViewer has
an abstract GetText method, so you need to supply the mechanism
for creating and manipulating the text of the items to be
displayed.
TListBox, derived from TListViewer, implements the most
commonly used list boxes, namely those displaying lists of strings
such as file names. TListBox objects represent displayed lists of
such items in one or more columns with an optional vertical scroll
bar. The horizontal scroll bars of TListViewer are not supported.
The inherited TListViewer methods let you select (and highlight)
items by mouse and keyboard cursor actions. TListBox has an
additional field called List, pointing to a TCollection object. This
provides the items to be listed and selected. The contents of the
collection are your responsibility, as are the actions to be
performed when an item is selected.
Static text TStaticText objects are simple views used to display fixed strings
provided by the field Text. They ignore any events sent to them.
The TLabel type adds the property that the view holding the text,
known as a label, can be selected (highlighted) by mouse-click,
cursor key, or shortcut Alt-Ietter keys. The additional field Link
associates the label with another view, usually a control view that
handles all label events. Selecting the label selects the linked
control and selecting the linked control highlights the label as
well as the control.
Non-visible elements
The non-view families derived from TObject provide streams,
resource files, collections, and string lists.
Streams
A stream is a generalized object for handling input and output. In
traditional device and file I/O, separate sets of functions must be
devised to handle the extraction and conversion of different data
types. With Turbo Vision streams, you can create polymorphic
1/ a methods such as Read and Write that know how to process
their own particular stream contents.
TStream is the base abstract object providing polymorphic 110 to
and from a storage device. TStream provides a Status field
indicating the access mode (read only, write only, read/write) and
an Errorlnfo field to report I/O failures. There are seven virtual
methods: Flush, GetPos, GetSize, Read, Seek, Truncate, and Write.
These must be overridden to derive specialized stream types.
You'll see that Turbo Vision adopts this strategy to derive
TDosStream, TEmsStream, and TBufStream. Other methods include
CopyFrom, Error, Get, ReadStr, Reset, and WriteStr.
Resources
A resource file is a special kind of stream where generic objects
("items") can be indexed via string keys. Rather than derive
resource files from TStream, TResouceFile has a field, Stream,
associating a stream with the resource file. Resource items are
accessed with Get(Key) calls where Key is the string index. Other
methods provided are Put (store an item with a given key), KeyAt
(get the index to a given item), Flush (write all changes to the
stream), Delete (erase the item at a given key), and Count (return
the number of items on file).
Collections
TCollection implements a general set of items, including arbitrary
objects of different types. Unlike the arrays, sets, and lists of non-
OOP languages, a Turbo Vision collection allows for dynamic
sizing. TCollection is an abstract base for more specialized
String lists
TStringList implements a special kind of string resource in which
strings can be accessed via a numerical index using the Get
method. A Count field holds the number of strings in the object.
TStringList simplifies internationalization and multilingual text
applications. String lists can be read from a stream using the Load
constructor. To create and add to string lists, you use
TStrListMaker.
TStringList offers access only to existing numerically indexed
string lists. TStrListMaker supplies the Put method for adding a
string to a string list, and a Store method for saving string lists on
a stream.
Views
By now, you should have a sense, from reading Chapters 1 and 2
and from looking at the integrated environment, of what a Turbo
Vision application looks like from the outside. But what's behind
the scenes? That's the subject of the next two chapters.
One of the adjustments you make when you use Turbo Vision is
that you give up writing directly to the screen. Instead of using
Write and Writeln to convey information to the user, you give the
information to Turbo Vision, which makes sure the information
appears in the right places at the right time.
The basic building block of a Turbo Vision application is the view.
A view is a Turbo Pascal object that manages a rectangular area of
the screen. For example, the menu bar at the top of the screen is a
view. Any program action in that area of the screen (for example,
clicking the mouse on the menu bar) will be dealt with by the
view that controls that area.
Menus are views, as are windows, the status line, buttons, scroll
bars, dialog boxes, and usually even a simple line of text. In
general, anything that shows up on the screen of a Turbo Vision
program must be a view, and the most important property of a
view is that it knows how to represent itself on the screen. So, for
example, when you want to make a menu system, you simply tell
Chapter 4, Views 81
Turbo Vision that you want to create a menu bar containing
certain menus, and Turbo Vision handles the rest.
The most visible example of a view, but one you probably would
not think of as a view, is the program itself. It controls the entire
screen, but you don't notice that because the program sets up
other views (called its subviews) to handle its interactions with the
user. As you will see, what appears to the user as a single object
(like a window) is often a group of related views.
Getting the TPoint The TPoint type is extremely simple. It has only two fields, called X
and Y, which are its coordinates. It has no methods. Turbo Vision
uses the TPoint object to allow views to specify their coordinates
as a single field.
Getting into a TRect For convenience, TPoints are rarely dealt with directly in Turbo
Vision. Since each view object has both an origin and a size, they
are usually handled together in an object called TRect. TRect has
two fields, A and B, each of which is a TPoint. When specifying
the boundaries of a view object, those boundaries are passed to
the constructor in a TRect.
TRect and TView both provide useful methods for manipulating
the size of a view. For example, if you want to create a view that
fits just inside a window, you can get the window to tell you how
big it is, then shrink that size and assign it to the new inside view.
ThisWindow and PlnsideView procedure ThisWindow.MakeInside;
are just made up for this var
example.
R: TRect;
Inside: PInsideView;
begin
GetExtent(R); { sets R to size of ThisWindow }
R.Grow(-l, -1); shrinks the rectangle by 1, both ways}
Inside := New(PInsideView, Init(R)); { creates inside view}
Insert(Inside); { insert the new view into the window}
end;
GetExtent is a TView method that sets the argument TRect to the
coordinates of a rectangle covering the entire view. Grow is a
Chapter 4, Views 83
TRect method that increases (or with negative parameters,
decreases) the horizontal and vertical sizes of a rectangle.
Making an
appearance The appearance of a view object is determined by its Draw
method. Nearly every new type of view will need to have its own
Draw, since it is, generally, the appearance of a view that
distinguishes it from other views.
There are a couple of rules that apply to all views with respect to
appearance. A view must
• cover the entire area for which it is responsible, and
• be able to draw itself at any time.
Both of these properties are very important and deserve some
discussion.
Drawing on demand In addition, a view must always be able to represent itself on the
screen. That's because other views may cover part of it but then be
removed, or the view itself might move. In any case, when called
upon to do so, a view must always know enough about its present
state to show itself properly.
Note that this may mean that the view does nothing at all: It may
be entirely covered, or it may not even be on the screen, or the
window that holds it might have shrunk to the point that the view
is not visible at all. Most of these situations are handled
automatically, but it is important to remember that your view
must always know how to draw itself.
This is different from a lot of other windowing schemes, where
the writing on a window, for example, is persistent: You write it
there and it stays, even if something covers it up then moves
away. In Turbo Vision, you can't assume that a view you uncover
is correct-after all, something may have told it to change while it
was covered!
Putting on your
best behavior The behavior of a view is almost entirely determined by a method
called HandleEvent. HandleEvent is passed an event record, which
it must process in one of two ways. It can either perform some
action in response to the event and then mark the event as having
been handled, or it can pass the event along to the next view (if
any) that should see it.
Event handling is covered in The key to behavior, really, is how the view responds to certain
detail in Chapter 5, "Event-
driven programming. H
events. For example, if a window receives an event containing a
em Close command, the expected behavior is that the window
would close. It is possible that you might devise some other
response to that command, but not likely.
Chapter 4, Views 85
Complex views
You've already learned something about the most important
immediate descendant of TView, the TGroup. TGroup and its
descendants are collectively referred to as groups. Views not
descended from TGroup are called terminal views.
Basically a group is just an empty box that contains and manages
other views. Technically, it is a view, and therefore responsible for
all the things that any view must be able to do: manage a
rectangular area of the screen, visually represent itself at any time,
and handle events in its screen region. The difference is really in
how it accomplishes these things: most of it is handled by
subviews.
Groups and
subviews A subview is a view that is owned by another view. That is, some
view (a group) has delegated part of its region on the screen to be
handled by another view, called a sub view, which it will manage.
An excellent example is TApplication. TApplication is a view that
controls a region of the screen-the whole screen, in fact.
TApplication is also a group that owns three subviews: the menu
bar, the desktop, and the status line. The application delegates a
region of the screen to each of these subviews. The menu bar gets
the top line, the status line gets the bottom line, and the desktop
gets all the lines in between. Figure 4.2 shows a typical
TApplication screen.
StatusLi ne P
Getting into a
group How does a subview get attached to a group? The process is
called insertion. Subviews are created and then inserted into
groups. In the previous example, the constructor T Application.lnit
creates three objects and inserts them into the application:
InitDeskTop;
InitStatusLine;
InitMenuBar;
if DeskTop <> nil then Insert(DeskTop);
if StatusLine <> nil then Insert(StatusLine);
if MenuBar <> nil then Insert(MenuBar);
Only when they have been inserted are the newly created views
part of the group. In this particular case, TApplication has divided
its region into three separate pieces and delegated one to each of
its subviews. This makes the visual representation fairly
straightforward, as the sub views do not overlap at all.
There is no reason, however, that views cannot overlap. Indeed,
one of the big advantages of a windowed environment is the
ability to have multiple, overlapping windows on the desktop.
Luckily, groups (including the desktop) know how to handle
overlapping sub views.
Chapter 4, Views 87
Groups keep track of the order in which sub views are inserted.
That order is referred to as Z-order. As you will see, Z-order
determines the order in which subviews get drawn and the order
in which events get passed to them.
Another angle on Z- The term Z-order refers to the fact that subviews have a three-
order dimensional spatial relationship. As you've already seen, every
view has a position and size within the plane of the view as you
see it (the X and Y dimensions), determined by its Origin and Size
fields. But views and subviews can overlap, and in order for
Turbo Vision to know which view is in front of which others, we
have to add a third dimension, the Z-dimension.
Z-order, then, refers to the order in which you encounter views as
you start closest to you and move back "into" the screen. The last
view inserted is the "front" view.
Rather than thinking of the screen as a flat plane with things
written on it, consider it a pane of glass providing a portal onto a
three-dimensional world of views. Indeed, every group may be
thought of as a "sandwich" of views, as illustrated in Figure 4.3.
Figure 4.3
Side view of a text viewer
window
TWindow - ~---~
(a pane of glass)
TScroller _
TScrollbar _
TFrame -
TDesktop
TWindow,
active and inactive
TBackground
Again, the group (this time the desktop) is a pane of glass. Its first
subview is a TBackground object, so that view is ''behind'' all the
others. This view also shows two windows with scrolling interior
views on the desktop.
Group portraits
Groups are sort of an exception to the rule that views must know
how to draw themselves, because a group does not draw itself per
se. Rather, a TGroup asks its subviews to draw themselves.
The subviews are called upon to draw themselves in Z-order,
meaning that the first sub view inserted into the group is the first
Chapter 4, Views 89
one drawn. That way, if subviews overlap, the one most recently
inserted will be in front of any others.
The subviews owned by a group must cooperate to cover the
entire region controlled by the group. A dialog box, for example,
is a group, and its subviews-frame, interior, controls, and static
text-must combine to fully "cover" the full area of the dialog box
view. Otherwise, "holes" in the dialog box would appear, with
unpredictable (and unpleasant!) results.
When the subviews of a group draw themselves, their drawing is
automatically clipped at the borders of the group. Because
subviews are clipped, when you initialize a view and give it to a
group, the view needs to reside at least partially within the
group's boundaries. (You can grab a window and move it off the
desktop until only one corner remains visible, for example, but
something must remain visible for the view to be useful.) Only
the part of a subview that is within the bounds of its owner group
will be visible.
You may wonder where the desktop gets its visible background if
it is a TGroup. At its initialization, the desktop creates and owns a
subview called TBackGround, whose sole purpose is to draw in a
uniform background for the whole screen. Since the background
is the first subview inserted, it is obscured by the other views
drawn in front of it.
Relationships
between views Views are related to each other in two distinct ways: They are
members of the Turbo Vision object hierarchy, and they are
members of the view tree. When you are new to Turbo Vision, it is
important to remember the distinction.
For example, consider the simple dialog box in Figure 4.5. It has a
frame, a one-line text message, and a single button that closes the
dialog box. In Turbo Vision terms, that's a TDialog view that owns
a TFrame, a TStaticText, and a TButton.
Figure 4.5 [ . ] = Sample dialog box ===;r
A simple dialog box This is a dialog box text message
Ownership The other way that views are related is in a view tree. In the view
tree diagram (Figure 4.7), the TDialog owns the TButton. Here the
relationship is not between hierarchical object types (TDialog is not
an ancestor of TButton!), but between instances of objects, between
owner and subview.
Figure 4.7
A simple dialog box's view
tree
Chapter 4, Views 91
the object hierarchy only grows when you derive new object types
from the standard objects.
Subviews and
view trees As noted earlier, the TApplication view owns and manages the
three subviews that it creates. You can think of this relationship as
forming a view tree. Application is the trunk, and MenuBar,
DeskTop, and StatusLine form the branches, as shown in Figure 4.8.
Figure 4.8
Basic Turbo Vision view tree
StatusLine
Now suppose the user clicks on the same menu selection and
creates another file viewer window. Turbo Vision will create a
second window and attach it to the desktop, as shown in Figure
4.11.
Chapter 4, Views 93
Figure 4.11 MenuBar
Desktop with file viewer
added
StatusLi ne
Chapter 4, Views 95
Figure 4.13
The focus chain
Finding the
focused view The currently focused view is usually highlighted in some way on
the screen. For example, if you have several windows open on the
desktop, the active window is the one with the double-lined
frame; the others' frames will be single-lined. Within a dialog box,
On monochrome displays, the focused control (controls are views, too!) is brighter than the
Turbo Vision adds arrow
characters to indicate the
others, indicating that it is the one that will be acted upon if you
focus. press Enter. The focused control is therefore the default control, as
well.
Modal views
A mode is a way of acting or functioning. A program may have a
number of modes of operation, usually distinguished by different
control functions or different areas of control. Turbo Pascal's
integrated environment, for example, has an editing and
debugging mode, a compiler mode, and a run mode. Depending
on which of these modes is active, keys on the keyboard may
have varying effects (or no effect at all).
A Turbo Vision view may define a mode of operation, in which
case it is called a modal view. The classic example of a modal view
is a dialog box. Usually, when a dialog box is active, nothing
outside it functions. You can't use the menus or other controls not
owned by the dialog box. In addition, clicking the mouse outside
the dialog box has no effect. The dialog box has control of your
program until closed. (Some dialog boxes are non-modal, but
these are rare exceptions.)
When you instantiate a view and make it modal, only that view
and its subviews can interact with the user. You can think of a
modal view as defining the "scope" of a portion of your program.
When you create a block in a Turbo Pascal program (such as a
function or a procedure), any identifiers declared within that
block are only valid within that block. Similarly, a modal view
determines what behaviors are valid within it-events are
Chapter 4, Views 97
handled only by the modal view and its subviews. Any part of the
view tree that is not the modal view or owned by the modal view
is inactive.
The status line is a/ways "hot, " There is actually one exception to this rule, and that is the status
no matter what view is
modal.
line. Turbo Vision "cheats" a little, and keeps the status line
available at all times. That way you can have active status line
items, even when your program is executing a modal dialog box
that does not own the status line. Events and commands
generated by the status line, however, will be handled as if they
were generated within the modal view.
There is always a modal view when a Turbo Vision application is
running. When you start the program, and often for the duration
of the program, the modal view is the application itself, the
TApplication object at the top of the view tree.
ofSelectable If set, the user can select the view with the mouse. If the view is in
a group, the user can select it with the mouse or Tab key. If you
put a purely informatiomil view on the screen, you might not
want the user to be able to select it. Static text objects and window
frames, for example, are usually not selectable.
ofTopSelect The view will be moved to the top of the owner's subviews if the
view is selected. This option is designed primarily for windows
on the desktop. You shouldn't use it for views in a group.
ofFirstClick The mouse click that selects the view is sent on to the view. If a
button is clicked, you definitely want the process of selecting the
button and operating it to happen with one click, so a button has
ofFirstClick set. But if someone clicks on a window, you mayor
may not want the window to respond to the selecting mouse click
other than by selecting itself.
of Framed If set, the view has a visible frame around it. This is useful if you
create multiple "panes" within a window, for example.
of PreProcess If set, allows the view to process focused events before the
focused view sees them. See the "Phase" section in Chapter 5,
"Event-driven programming" for more details.
ofPostProcess If set, allows the view to handle focused events after they have
been seen by the focused view, assuming the focused view has
not cleared the event. See the "Phase" section in Chapter 5,
"Event-driven programming" for more details.
ofBuffered When this bit is set, groups can speed their output to the screen.
When a group is first asked to draw itself, it automatically stores
the image of itself in a buffer if this bit is set and if enough
memory is available. The next time the group is asked to draw
itself, it copies the buffered image to the screen instead of asking
all its subviews to draw themselves. If a New or GetMem call runs
out of memory, Turbo Vision's memory manager will begin
disposing of these group buffers until the memory request can be
satisfied.
If a group has a buffer, a call to Lock will stop all writes of the
group to the screen until the method Unlock is called. When
Unlock is called, the group's buffer is written to the screen.
Locking can decrease flicker during complicated updates to the
screen. For example, the desktop locks itself when it is tiling or
cascading its subviews.
ofTileable The desktop can tile or cascade the windows that are currently
open. If you don't want a window to be tiled, you can clear this
bit. The window will then stay in the same position, while the rest
of the windows will be automatically tiled.
Tiling or cascading views from TApplication.HandleEvent is simple:
cmTile:
begin
DeskTopA.GetExtent(R);
DeskTopA.Tile(R);
end;
cmCascade:
begin
DeskTopA.GetExtent(R);
DeskTopA.Cascade(R);
end;
The GrowMode
flag byte A view's GrowMode field determines how the view will change
when its owner group is resized.
The GrowMode bits are defined as follows:
Figure 4.15 ,...--,.---r---r---<lfGrowA11
GrowMode bit flags
fGrowLoX
fGrowLoY
'-----afGrowHiX
'------QfGrowHi Y
'-------<JfGrowRel
gfGrowLoX If set, the left side of the view will maintain a constant distance
from its owner's left side.
gfGrowLoY If set, the top of the view will maintain a constant distance from
the top of its owner.
gfGrowHiX If set, the right side of the view will maintain a constant distance
from its owner's right side.
gfGrowHiY If set, the bottom of the view will maintain a constant distance
from the bottom of its owner.
gfGrowAIl If set, the view will always remain the same size, and will move
with the lower right corner of the owner.
gfGrowRel If set, the view will maintain its size relative to the owner's size.
You should only use this option with TWindows (or descendants
of TWindow) that are attached to the desk top. The window will
maintain its relative size when the user switches the application
between 25- and 43/50-line mode. This flag isn't designed to be
used with views within a window.
dmDragMove When this bit is set, when you click on the top of a window's
frame, you can drag it.
dmLimitLoX If set, the left side of the view cannot go out of the owner view.
dmLimitLoY If set, the top of the view is not allowed to go out of the owner
view.
dmLimitHiX If set, the right side of the view cannot go out of the owner view.
dmLimitHiY If set, the bottom of the view cannot go out of the owner view.
dmLimitAII If set, no part of the view can go out of the owner view.
Acting on a state Views often take some action when SetState is called, depending
change on the resulting state flags. A button, for example, watches State
and changes its color to cyan when it gets the focus. Here's a
typical SetState for a descendant of TView:
procedure TButton.SetState(AState: Word; Enable: Boolean);
begin
TView.SetState(AState, Enable); { set/clear state bits
if AState and (sf Selected + sfActive) <> 0 then DrawView;
if AState and sfFocused <> 0 then MakeDefault(Enable);
end;
Notice that you should always call TView.SetState from within a
new SetState method. TView.SetState does the actual setting or
Color palettes
Palettes for all standard When a Turbo Vision view draws itself, it asks to be drawn, not
views are listed in Chapter
13, "Object reference."
with a specific color, but with a color indicated by a position in its
palette. For example, the palette for TScroller looks like this:
CScroller = #6#7;
Color palettes are actually stored in strings, which allows them to
be flexible arrays of varying length. CScroller, then, is a two-
character string, which you can think of as two palette entries.
The layout of the TScroller palette is defined as
{ Palette layout }
{ 1 = Normal }
{ 2 = Highlight }
but it might be more useful to look at it this way:
Figure 4.18 1 2
TScroller's default color
palette
CScroller B
I 1 - '-
1 - .- - -
-
-
- -
-
-
-
-
-
-
-
-
-
Highlighted text
Nonnal text
GetColor is a TView method. This means there are two kinds of text a scroller object knows
how to display: normal and highlighted. The default color of each
is determined by the palette entries. When displaying normal text,
the Draw method needs to call GetColor(1), meaning it wants the
color indicated by the first palette entry. To show highlighted text,
the call would be GetColor(2).
Selecting non-default colors If all you want to do is display the default colors, that's really all
is described in the next
you need to know. The palettes are set up so that any reasonable
section.
combination of objects should produce decent looking colors.
Inside color
palettes Palette entries are actually indexes into their owner's palette, not
the colors themselves. If a scroller is inserted into a window, you
get normal text by calling for the normal text color in the scroller's
palette, which contains the number 6. To translate that into a
color, you find the sixth entry in the owner's palette. Figure 4.19
shows TWindow's palette.
~
Scroll bar page
~
Scroll bar controls
Scroller normal text
r-::::
rr=r=
Scroller selected text
I IReserved
4 5 7 8
The GetColor
method Color palette mapping is done by the virtual TView function
GetColor. GetColor climbs up the view tree from the object being
drawn to its owner, to the owner's owner, and so on, until it gets
to the application object. At each object along that chain, GetColor
calls GetPalette for that object. The end result is a color attribute.
A view's palette contains offsets into its owner's palette, except the
application, whose palette contains color attributes.
Adding new
colors You may want to add additional colors to the window object type,
which will allow for a variety of colors to be used for new views
you create. For example, you might decide you want a third color
in your scroller for a different type of highlight, such as the one
used for the breakpoints in the IDE editor. This can be done by
deriving a new object type from the existing TWindow, and
adding to the default palette, as shown here:
type
TMyWindow = object (TWindow)
function GetPalette: PPalette; virtual;
end;
function TMyWindow.GetPalette: PPalette;
Palettes are strings, so you const
can use string operations like CMyWindow = CBlueWindow + #84;
"+. ' P: string[Length(CMyWindow)] = CMyWindow;
begin
GetPalette := @P;
end;
Now TMyWindow has a new palette entry that contains this new
type of hightlight. CWindow is a string constant containing
TWindow's default palette. You will have to change the GetPalette
routine of MyScroller to take advantage of this:
function TMyScroller.GetPalette: PPalette;
const
CMyScroller = #6#7#9;
P: string[Length(CMyScroller)] = CMyScoller;
begin
GetPalette := @P;
end;
The scroller's palette entry 3 is now the new highlight color (in
this case bright white on red). If you use this new GetPalette using
the CMyScroller that accesses the ninth element in its owner's
palette, be sure that the owner is indeed using the CMyWindow
palette. If you try to access the ninth element in an eight-element
palette, the results are undefined.
Event-driven programming
The purpose of Turbo Vision is to provide you with a working
framework for your applications so you can focus on creating the
"meat" of your applications. The two major Turbo Vision tools are
built-in windowing support and handling of events. Chapter 4
explained views, and this chapter will deal with how to build
your programs around events.
Reading the
user's input In a traditional Pascal program, you typically write a loop of code
that reads the user's keyboard, mouse, and other input, and you
make decisions based on that input within the loop. You'll call
procedures or functions, or branch to a code loop somewhere else
that again begins reading the user's input:
Kinds of events
Let's look at the possible values of Event. What a little more closely.
There are basically four classes of event: mouse events, keyboard
events, message events, and "nothing" events. Each class has a
mask defined, so your objects can determine quickly which
general type of event occurred without worrying about what
specific sort it was. For instance, rather than checking for each of
the four different kinds of mouse events, you can simply check to
see if the event flag is in the mask. Instead of
if Event.What and (evMouseDown or evMouseUp or evMouseMove or
evMouseAuto) <> 0 then ...
vMouseDown = $0001
vMouseUp = $0002
'-----evMouseMove = $0004
'-----evMouseAuto = $0008
L...--------evKeyDown II $0010
'-------------evCorrmand II $0100
'-------------evBroadcast = $0200
Mouse events There are basically four kinds of mouse events: an up or down
click with either button, a change of position, or an "auto" mouse
event. Pressing down a mouse button results in an evMouseDown
event. Letting the button back up generates an evMouseUp event.
Moving the mouse produces an evMouseMove event. And if you
hold down the button, Turbo Vision will periodically generate an
evMouseAuto event, allowing your application to perform such
actions as repeated scrolling. All mouse event records include the
position of the mouse, so an object that processes the event knows
where the mouse was when it happened.
Keyboard events Keyboard events are even simpler. When you press a key, Turbo
Vision generates an evKeyDown event, which keeps track of which
key was pressed.
Message events Message events come in three flavors: commands, broadcasts and
user messages. The difference is in how they are handled, which
is explained later. Basically, commands are flagged in the What
field by evCommand, broadcasts byevBroadcast, and user-defined
messages by some user-defined constant.
Events and
commands Ultimately, most events end up being translated into commands
of some sort. For example, clicking the mouse on an item in the
status line generates a mouse event. When it gets to the status line
object, that object responds to the mouse event by generating a
command event, with the Command field value determined by the
command bound to the status line item. A mouse click on Alt-X
Exit generates the cmQuit command, which the application
interprets as an instruction to shut down and terminate.
Routing of events
Turbo Vision's views operate on the principle "Speak only when
spoken to." That is, rather than actively seeking out input, they
wait passively for the event manager to tell them that an event
has occurred to which they need to respond.
In order to make your Turbo Vision programs act the way you
want them to, you not only have to tell your views what to do
when certain events occur, you also need to understand how
events get to your views. The key to getting events to the right
place is correct routing of the events. Some events get broadcast all
over the application, while others are directed rather narrowly to
particular parts of the program.
Where do events
come from? As noted in Chapter 1, "Inheriting the wheel," the main process-
ing loop of a TApplication, the Run method, calls TGroup.Execute,
which is basically a repeat loop that looks something like this:
var E: TEventi
E.What := evNothingi { indicate no event has occurred}
repeat
if E.What <> evNothing then EventError(E)i
GetEvent(E)i { pack up an event record}
HandleEvent(E)i { route the event to the right place}
Where do events
go? Events always begin their routing with the current modal view.
For normal operations, this usually means your application object.
When you execute a modal dialog box, that dialog box object is
the modal view. In either case, the modal view is the one that
initiates event handling. Where the event goes from there
depends on the nature of the event.
Events are routed in one of three ways, depending on what kind
of event they are. The three possible routings are positional,
focused, and broadcast. It is important to understand how each
kind of event gets routed.
Positional events Positional events are virtually always mouse events (evMouse).
The modal view gets the positional event first, and starts looking
at its subviews in Z-order until it finds one that contains the
Z-order is explained in position where the event occurred. The modal view then passes
Chapter 4, "Views. H
the event to that view. Since views can overlap, it is possible that
more than one view will contain that point. Going in Z-order
guarantees that the topmost view at that position will be the one
that receives the event. After all, that,'s the one the user clicked on!
This process continues until an object cannot find a view to pass
the event to, either because it is a terminal view (one with no
subviews) or because there is no subview in the position where
the event occurred (such as clicking on open space in a dialog
box). At that point, the event has reached the object where the
positional event took place, and that object handles the event.
User-defined events As you become more comfortable with Turbo Vision and events,
you may wish to define whole new categories of events, using the
high-order bits in the What field of the event record. By default,
Turbo Vision will route all such events as broadcast events. But
you may wish your new events to be focused or positional, and
Turbo Vision provides a mechanism to allow this.
Manipulating bits in masks is Turbo Vision defines two masks, Positional and Focused, which
explained in Chapter 70,
"Hints and tips. "
contain the bits corresponding to events in the event record's What
field that should be routed by position and by focus, respectively.
By default, Positional contains all the evMouse bits, and Focused
contains evKeyboard. If you define some other bit to be a new kind
of event that you want routed either by position or focus, you
simply add that bit to the appropriate mask.
MaskinQ events
Every view object has a bitmapped field called EventMask which
is used to determine which events the view will handle. The bits
in the EventMask correspond to the bits in the TEvent. What field. If
the bit for a given kind of event is set, the view will accept that
kind of event for handling. If the bit for a kind of event is cleared,
the view will ignore that kind of event.
Phase
There are certain times when you want a view other than the
focused view to handle focused events (especially keystrokes). For
example, when looking at a scrolling text window, you might
want to use keystrokes to scroll the text, but since the text
window is the focused view, keystroke events go to it, not to the
scroll bars that can scroll the view.
Commands
Most positional and focused events wind up getting translated
into commands by the objects that handle them. That is, an object
often responds to a mouse click or a keystroke by generating a
command event.
For example, by clicking on the status line in a Turbo Vision
application, you generate a positional (mouse) event. The
application determines that the click was positioned in the area
controlled by the status line, so it passes the event to the status
line object, StatusLine.
StatusLine determines which of its status items controls the area
where you clicked, and reads the status item record for that item.
That item usually will have a command bound to it, so StatusLine
creates a pending event record with the What field set to
evCommand and the Command field set to whatever command was
bound to that status item. It then clears the mouse event, meaning
that the next event found by GetEvent will be the command event
just generated.
Defining
commands Turbo Vision has many predefined commands, and you will
define many more yourself. When you create a new view, you
will also create a command that will be used to invoke the view.
Commands may be called anything, but Turbo Vision's
convention is that a command identifier should start with "cm."
The actual mechanics of creating a command are simple-you just
create a constant:
const
cmConfuseTheCat = 100;
Binding
commands When you create a menu item or a status line item, you bind a
command to it.. When the user chooses that item, an event record
is generated, with the What field set to evCommand, and the
Command field set to the value of the bound command. The
command may be either a Turbo Vision standard command or
one you have defined. At the same time you bind your command
to a menu or status line item, you may also bind it to a hot key.
That way, the user can invoke the command by pressing a single
key as a shortcut to using the menus or the mouse.
The important thing to remember is that defining the command
does not specify what action will be taken when that command
appears in an event record. You will have to tell the appropriate
objects how to respond to that command.
Enabling and
disabling There are times when you want certain commands to be
commands unavailable to the user for a period of time. For example, if you
have no windows open, it makes no sense for the user to be able
to generate em Close, the standard window closing command.
Turbo Vision provides a way to disable and enable sets of
commands.
Handling events
Once you have defined a command and set up some kind of
control to generate it-for example, a menu item or a dialog box
button-you need to teach your view how to respond when that
command occurs.
Every view inherits a HandleEvent method that already knows
how to respond to much of the user's input. If you want a view to
do something specific for your application, you need to override
its HandleEvent and teach the new HandleEvent two things-how·
to respond to new commands you've defined, and how to
respond to mouse and keyboard events the way you want.
A view's HandleEvent method determines how it behaves. Two
views with identical HandleEvent methods will respond to events
in the same way. When you derive a'new view type, you
generally want it to behave more-or-Iess like its ancestqr vlew,
with some changes. By far the easiest way to accomplish this is to
call the ancestor's HandleEvent as part of the new object's
HandleEvent method.
The general layout of a descendant's HandleEvent would look like
this:
procedure NewDescendant.HandleEvent(var Event: TEvent);
begin
{ code to change or eliminate parental behavior }
Parent.HandleEvent(Event);
{ code to perform additional functions
end;
Clearing events
When a view's HandleEvent method has handled an event, it
finishes the process by calling its ClearEvent method. ClearEvent
sets the Event. What field equal to evNothing and Event.InfoPtr to
@Se1f, which are the universal signals that the event has been
handled. If the event then gets passed to another object, that
object should ignore this "nothing" event.
Abandoned
events Normally, every event will be handled by some view in your
application. If no view can be found that handles an event, the
modal view calls EventError. EventError calls the view owner's
EventError and so forth up the view tree until
TApplication.EventError is called.
TApplication.EventError by default does nothing. You may find it
useful during program development to override EventError to
bring up an error dialog box or issue a beep. Since the end user of
your software isn't responsible for the failure of the software to
Centralized event
gathering One of the greatest advantages of event-driven programming is
that your code doesn't have to know where its events come from.
A window object, for example, just needs to know that when it
sees a em Close command in an event, it should close. It doesn't
care whether that command came from a click on its close icon, a
menu selection, a hot key, or a message from some other object in
the program. It doesn't even have to worry about whether that
command is intended for it. All it needs to know is that it has
been given an event to handle, and since it knows how to handle
that event, it does.
The key to these "black box" events is the application's GetEvent
method. GetEvent is the only part of your program that has to
concern itself with the source of events. Objects in your
application simply call GetEvent and rely on it to take care of
reading the mouse, the keyboard, and the pending events
generated by other objects.
If you want to create new kinds of events (for example, reading
characters from a serial port),' you would simply override
Overriding
GetEvent The current modal view's GetEvent calls its owner's GetEvent, and
so on, all the way back up the view tree to T Application.GetEvent,
which is where the next event is always actually fetched.
Because Turbo Vision always uses TApplication.GetEvent to
actually fetch events, you can modify events for your entire
application by overriding just this one method. For example, to
implement keystroke macros, you could watch the events
returned by GetEvent, grab certain keystrokes, and unfold them
into macros. As far as the rest of the application would know, the
stream of events would be coming straight from the user.
procedureTMyApp.GetEvent(var Event: TEvent);
begin
TApplication.GetEvent(Event);
{ special processing here }
end;
Intermediaries
If indeed the program design is sound, and the views still need to
communicate with each other, it may be that the proper path is to
create an intermediary view.
For example, suppose you have a spreadsheet object and a word
processor object, and you want to be able to paste something from
the spreadsheet into the word processor, and vice-versa. In a
Turbo Vision application, you can accomplish this with direct
view-to-view communication. But suppose that at a later date you
wanted to add, say, a database to this group of objects, and to
paste to and from the database. You will now need to duplicate
the communication you established between the first two objects
between all three.
A better solution is to establish an intermediary view-in this
case, say, a clipboard. An object would then need to know only
how to copy something to the clipboard, and how to paste
something from the clipboard. No matter how many new objects
you add to the group, the job will never become any more
complicated than this.
Is anyone out there? Here's a concrete example. In the Turbo Pascal IDE, if the user
asks to open a watch window, the code which opens watch
windows needs to check to see if there is already a watch window
open. If there isn't, it opens one; if there is, it brings it to the front.
Sending off the broadcast message is easy:
AreYouThere := Message (DeskTop, evBroadcast, crnFindWindow, nil);
In the code for a watch window's HandleEvent method is a test to
respond to cmFindWindow by clearing the event:
case Event.Command of
cmFindWindow: ClearEvent(Event);
end;
ClearEvent, remember, not only sets the event record's What field
to evNothing, it also sets the InfoPtr field to @Self. Message reads
these fields, and if the event has been handled, it returns a pointer
to the object who handled the message event. In this case, that
would be the watch window. So following the line that sends the
broadcast, we include
if AreYouThere = nil then
Who's on top? Using the same techniques outlined earlier, you can also
determine, for example, which window is the topmost view of its
type on the desktop. Because a broadcast event is sent to each of
the modal view's subviews in Z-order (reverse insertion order),
the most recently inserted view is the view "on top" of the
desktop.
Consider for a moment the situation encountered in the IDE when
the user has a watch window open on top of the desktop while
stepping through code in an editor window. The watch window
can be the active window (double-lined frame, top of the stack),
but the execution bar in the code window needs to keep tracking
the executing code. If you have multiple editor windows open on
the desktop, they might not overlap at all, but the IDE needs to
know which one of the editors it is supposed to be tracking in.
The answer, of course, is the front, or topmost editor window,
which is defined as the last one inserted. In order to figure out
which one is "on top," the IDE broadcasts a message that only
editor windows know how to respond to. The first editor window
to receive the broadcast will be the one most recently inserted; it
will handle the event by clearing it, and the IDE will then know
which window to use for code tracking by reading the result
returned by Message.
Calling
HandleEvent You can also create or modify an event, then call a HandleEvent
directly. You can make three types of calls:
"Peer' views are subviews 1. You can have a view call a peer subview's HandleEvent
with the same owner.
directly. The event won't propagate to other views. It goes
directly to the other HandleEvent, then control returns to you.
2. You can call your owner's HandleEvent. The event will then
propagate down the view chain. (If you are calling the
HandleEvent from within your own HandleEvent, your
Help context
Turbo Vision has built-in tools that help you implement context-
sensitive help within your application. You can assign a help
context number to a view, and Turbo Vision ensures that
whenever that view becomes focused, its help context number
will become the application's current help context number.
To create global context-sensitive help, you can implement a
HelpView that knows about the help context numbers that you've
defined. When HelpView is invoked (usually by the user pressing
F1 or some other hot key), it should ask its owner for the current
help context by calling the method GetHelpCtx. Help View can then
read and display the proper help text. An example HelpView is
included on your Turbo Pascal distribution disks.
Context-sensitive help is probably one of the last things you'll
want to implement in your application, so Turbo Vision objects
are initialized with a default context of hcNoContext, which is a
predefined context that doesn't change the current context. When
the time comes, you can work out a system of help numbers, then
plug the right number into the proper view by setting the view's
HelpCtx field right after you construct the view.
Help contexts are also used by the status line to determine which
views to display. Remember that when you create a status line,
you call NewStatusDef, which defines a set of status items for a
given range of help context values. When a new view receives the
focus, the help context of that item determines which status line is
displayed.
Non-memory
errors Of course, not all errors are memory related. For example, a view
could be required to read a disk file for some information, and the
file might be missing or invalid. This type of error must also be
reported to the user. Fortunately, Va lid View has a "hook" built in
for handling non-memory errors: It calls the view's Valid,method.
TView.Valid returns True by default. TGroup.Valid only returns
True if all the subviews owned by the group return True from
their Valid functions. In other words, a group is valid if all the
subviews of the group are valid. When you create a view that
may encounter non-memory errors, you will need to override
Valid for that view to return True only if it has been successfully
instantiated.
Valid can be used to indicate that a view should not be used for
any reason; for example, if the view could not find its file. Note
that what Valid checks for and how it checks are entirely up to
you. A typical Valid method would look something like this:
function TMyView.Valid(Command: Word): Boolean;
begin
Valid := True;
if Command = crnValid then
begin
if ErrorEncountered then
begin
ReportError;
Valid := False;
end;
end;
end;
When a view is first instantiated, its Valid method should be
called with a Command parameter of em Valid to check for any
non-memory related errors involved in the creation of the view.
Valid View (X) calls X.Valid(emValid) automatically, as well as
checking the safety pool, so calling ValidView before using any
new view is a good idea.
Valid is also called whenever a modal state terminates, with the
Command parameter being the command that terminated the
Reporting errors Before a Valid method returns False, it should let the user know
about whatever error occurred, since the view is not going to
show up on the screen. This is what the ReportError call in the
previous example does. Typically this involves popping up a
message dialog box. Each individual view, then, is responsible for
reporting any errors, so the program itself does not have to know
how to check each and every possible condition.
This is an important advance in programming technique, because
it lets you program as if things were going right, instead of
always looking for things going wrong. Group objects, including
applications, don't have to worry about checking for errors at all,
except to see if any of the views they own were invalid, in which
case the group simply disposes of itself and its subviews and
indicates to its owner that it was invalid. The group can assume that
its invalid subview already notified the user of the problem.
Using Valid allows the construction of windows and dialog boxes
to be treated as atomic operations. Each subview that makes up
the window can be constructed without checking for failure; if the
constructor fails, it simply sets Valid to False. The window then
goes through its entire construction, at which point the entire
window can be passed to ValidView. If any of the subviews of the
window are invalid, the entire window returns False from the
valid check. Va lid View will dispose of the window and return nil.
All that needs to be done is to check the return result from
ValidView.
Major consumers
The Valid function can also handle major consumers, which are
views that allocate memory greater than the size of the safety
pool, such as reading the entire contents of a file into memory.
Major consumers should check LowMemory themselves, instead of
waiting until they have finished all construction and then
allowing ValidView to do so for them.
Collections
Pascal programmers traditionally spend much programming time
creating code that manipulates and maintains data structures,
such as linked lists and dynamically-sized arrays. Virtually the
same data structure code tends to be written and debugged again
and again.
As powerful as traditional Pascal is, it only provides you with
built-in record and array types. Any structure beyond that is up to
you.
For example, if you're going to store data in an array, you
typically need to write code to create the array, to import data into
the array, to extract array data for processing, and perhaps to
export data to 110 devices. Later, when the program needs a new
array element type, you start all over again.
Wouldn't it be great if an array type came with code that would
handle many of the operations you normally perform on an
array? An array type that could also be extended without
disturbing the original code?
That's the aim of Turbo Vision's TCollection type. It's an object that
stores a collection of pointers and provides a host of methods for
manipulating them.
Collections are
dynamically sized The size of a standard Turbo Pascal array is fixed at compile time,
which is fine if you know exactly what size your array will always
need to be, but it may not be a particularly good fit by the time
someone is actually running your code. Changing the size of an
array requires changing the code and recompiling.
With a collection, however, you set an initial size, but it can
dynamically grow at run-time to accommodate the data stored in
it. This makes your application much more flexible in its compiled
form.
Collections are
polymorphic A second aspect of arrays that can be limiting to your application
is the fact that each element in the array must be of the same type,
and that type must be determined when the code is compiled.
Collections get around this limitation by using untyped pointers.
Not only is this fast and efficient, but a collection can then consist
of objects (and even non-objects) of different types and sizes. Just
like a stream, a collection doesn't need to know anything about
the objects it is handed. It just holds on to them and gives them
back when asked.
Type checking
and collections A collection is an end-run around Pascal's traditional strong type
checking. That means that you can put anything into a collection,
and when you take something back out, the compiler has no way
to check your assumptions about what that something is. You can
put in a PHedgehog and read it back out as a PSheep, and the
collection will have no way of alerting you.
As a Turbo Pascal programmer, you may rightfully feel nervous
about such an end-run. Pascal's type checking, after all, saves
hours and hours of hunting for some very elusive bugs. So you
Collecting non-objects You can even add something to a collection that isn't an object at
all, but this raises another serious point of caution. Collections
expect to receive untyped pointers to something. But some of
TCollection's methods act specifically on a collection of TObject-
derived instances. These include the stream access methods
PutItem and GetItem as well as the standard FreeItem procedure.
This means that you can store a PString in a collection, for
example, but if you try to send that collection to a stream, the
results aren't going to be pretty unless you override the
collection's standard GetItem and Putltem methods. Similarly,
when you attempt to deallocate the collection, it will try to
dispose of each item using FreeItem. If you plan to use non-TObject
items in a collection, you need to redefine the meaning of "item"
in GetItem, PutItem, and FreeItem. That is precisely what
TStringCollection, for example, does.
If you proceed with prudence, you will find collections (and the
descendants of collections that you build) to be fast, flexible,
dependable data structures.
Creating a collection
Creating a collection is really just as simple as defining the data
type you wish to collect. Suppose you're a consultant, and you
want to store and retrieve the account number, name, and phone
number of each of your clients. First you define the client object
(TClient) that will be stored in the collection:
type
Remember to define a PClient = ATClient;
pointer for each new object TClient = object(TObject)
type. Account, Name, Phone: PString;
constructor Init(NewAccount, NewName, NewPhone: String);
destructor Done; virtual;
end;
Iterator methods
Insert and deleting items aren't the only common collection
operations. Often you'll find yourself writing for loops to range
over all the objects in the collection to display the data or perform
some calculation. Other times, you'll want to find the first or last
item in the collection that satisfies some search criterion. For these
purposes, collections have three iterator methods: ForEach,
FirstThat, and LastThat. Each of these takes a pointer to a
procedure or function as its only parameter.
The ForEach
iterator ForEach takes a pointer to a procedure. The procedure has one
parameter, which is a pointer to an item stored in the collection.
ForEach calls that procedure once for each item in the collection, in
the order that the items appear in the collection. The PrintAll
procedure in TVGUID17 shows an example of a ForEach iterator.
procedure PrintAII(C: PCollection); { print info for all clients
procedure PrintClient(P: PClient); far; { local procedure}
begin
with p do
A
Sorted collections
Sometimes you need to have your data in a certain order. Turbo
Vision provides a special type of collection that allows you to
order your data in any manner you want: the TSortedCollection.
TSortedCollection is a descendant of TCollection which
automatically sorts the objects it is given. It also automatically
checks the collection when a new member is added and rejects
duplicate members.
TSortedCollection is an abstract type. To use it, you must first
decide what type of data you're going to collect and define two
methods to meet your particular sorting requirements. To do this,
you will need to derive a new collection type from
TSortedCollection. In this case, call it TClientColiection.
Your TClientCollection already knows how to do all the real work
of a collection. It can Insert new client records and Delete existing
ones-it inherited all this basic behavior from TCollection. All you
have to do is teach TClientCollection which field to use as a sort
key and how to compare two clients and decide which one
belongs ahead of the other in the collection. You do this by
overriding the KeyOf and Compare methods and implementing
them as shown here:
PClientCollection = ATClientCollection;
TClientCollection = object(TSortedCollection)
function KeyOf(Item: Pointer): Pointer; virtual;
function Compare(Keyl, Key2: Pointer): Integer; virtual;
end;
function TClientCollection. KeyOf (Item,: Pointer): Pointer;
begin
KeyOf := PClient(Item)A.Name;
begin
ClientList := New(PClientCollection, Init(50, 10));
end.
Notice also how easy it would be if you wanted the client list
sorted by account number instead of by name. All you would
have to do is change the KeyOfmethod to return the Account field
instead of the Name field.
String collections
Many programs need to keeping track of sorted strings. For this
purpose, Turbo Vision provides a special purpose collection,
TStringCollection. Note that the elements in a TStringCollection are
not objects-they are pointers to Turbo Pascal strings. Since a
begin
WordList := New(PStringCollection, Init(lO, 5));
Iterators revisited
The ForEach method traverses the entire collection one item at a
time, and passes each one to a procedure you provide. Continuing
with the previous example, the procedure Print Word is given a
pointer to a string to display. Note that PrintWord is a nested (or
local) procedure. Wrapped around it is another procedure, Print,
which is given a pointer to a TStringCollection. Print uses the
ForEach iterator method to pass each item in its collecton to the
Print WJrd procedure.
Finding an item Sorted collections (and therefore string collections) have a Search
method that returns the index of an item with a particular key.
But how do you find an item in a collection that may not be
sorted? Or when the search criteria don't involve the key itself?
The answer, of course, is to use FirstThat and LastThat. You simply
define a Boolean function to test for whatever criteria you want,
and call FirstThat.
Polymorphic collections
You've seen that collections can store any type of data
dynamically, and there are plenty of methods to help you access
collection data efficiently. In fact, TCollection itself defines 23
methods. When you use collections in your programs, you'll be
equally impressed by their speed. They're designed to be flexible
and implemented to be fast.
But now comes the real power of collections: items can be treated
polymorphically. That means you can do more than just store an
object type on a collection; you can store many different objects
types, from anywhere in your object hierarchy.
As you can see, the for loop inserts 20 graphical objects into the
List collection. All you know is that each object in List is some
kind of TGraphObject. But once inserted, you'll have no idea
whether a given item in the collection is a circle, point or
rectangle. Thanks to polymorphism, you don't need to know
since each object contains the data and the code (Draw) it needs.
Just traverse the collection using an iterator method and have
each object display itself:
procedure DrawAII(C: PCollection);
procedure CalIDraw(P: PGraphObject); far;
begin
pA.Draw; { Call the Draw method }
end;
begin { DrawAll
CA.ForEach(@CalIDraw); { Draw each object }
end;
var
GraphicsList: PCollection;
begin
DrawAII(GraphicsList);
end.
Streams
Object-oriented programming techniques and Turbo Vision give
you a powerful way of encapsulating code and data, and
powerful ways of building an interrelated structure of objects. But
what if you want to do something simple, like store some objects
on disk?
Back in the days when data sat by itself in a record, writing data
to disk was pretty dear-cut, but the data within a Turbo Vision
program is largely bound up within objects. You could, of course,
separate the data from the object and write the data to a disk file.
But you've achieved something important by joining the two
together in the first place, and it would be a step backwards to
take them a part.
Couldn't OOP and Turbo Vision themselves somehow be enlisted
in solving this problem? That's what streams are all about.
... rT"t .. • • -.
Streams are
polymorphic A Turbo Vision stream gives you the best of both typed and
untyped files: type checking is still there, but what you intend to
send to a stream doesn't have to be determined at compile time.
The reason is that streams know they are dealing with objects, so
as long as the object is a descendant of TObject, the stream can
handle it. In fact, different Turbo Vision objects can as easily be
written to the same stream as a group of identical objects.
Reading and
writing a stream TStream, the basic stream object implements three basic methods
you need to understand: Get, Put, and Error. Get and Put roughly
correspond to the Read and Write procedures you would use for
ordinary file I/O operations. Error is a procedure that gets called
whenever a stream error occurs.
Getting it back Getting objects back from the stream is just as easy. All you have
to do is call the stream's Get function:
PSomeObject := SomeStream.Get;
where again, SomeStream is an initialized Turbo Vision stream,
and PSomeObject is a pointer to any type of Turbo Vision object.
Get simply returns a pointer to whatever it has pulled off the
stream. How much data it has pulled, and what type of VMT it
has assigned to that data, is determined not by the type of
PSomeObject, but by the type of object found on the stream. Thus,
if the object at the current position
______ • _______ nf"' _____ " l . ! __
of SomeStream
_._!11 __
is not of the
t..1_""] !_1: _ _ _ _ L! __
L ___ • • L ___
tJUJ..LL""" '"J Y ..... '-4v.L vv" ....... '-'Vj ..... ""' .. , J '-''-4. Y .. .£..A..L b""'''' blL4.L...., ... """""" ...... L.A."' ...... .L .............. " ' ......
As with Put, Get will retrieve complex objects. Thus, if the object
you retrieve from a stream is a view that owns subviews, the
subviews will be loaded as well.
Shutting down
the stream When you're finished using a stream, you call its Done method,
much as you would normally call Close for a disk file. As with any
Turbo Vision object, you do this as
Dispose (SorneStream, Done);
so as to dispose of the stream object as well as shutting it down.
Stream
registration In addition to defining the Load and Store methods for a new
object, you will also have to register your new object type with the
streams. Registration is a simple, two-step process: you define a
stream registration record, and you pass it to the global procedure
RegisterType.
Turbo Vision registers 01/ the To define a stream registration record, just follow the format.
standard objects, so you
Stream registration records are Pascal records of type TStreamRec,
don't have to.
which is defined as follows:
PStrearnRec = ATStreamRec;
TStrearnRec = record
Object 10 numbers The ObjType field is really the only part of the record you need to
think about; the rest is mechanical. Each new type you define will
need its own, unique type-identifier number. Turbo Vision
reserves the registration numbers 0 through 99 for the standard
objects, so your registration numbers can be anything from 100
through 65,535.
It is your responsibility to create and maintain a library of 10.
numbers for all your new objects that will be used in stream I/O,
and to make the IDs available to users of your units. As with
command constants, the numbers you assign may be completely
arbitrary, as long as they are unique.
The automatic fields The VmtLink field is a link to the objects virtual method table
(VMT). You simply assign it as the offset of the type of your
object:
RSomeObject.VmtLink := Ofs(TypeOf(TSomeObject)A);
The Load and Store fields contain the addresses of the Load and
Store methods of your object, respectively.
RSomeObject.Load := @TSomeObject.Load;
RSomeObject.Store := @TSomeObject.Store;
The final field, Next, is assigned by RegisterType, and requires no
intervention on your part. It simply facilitates the internal use of a
linked list of stream registration records.
RegisterType(RMagritte)i
That's all there is to it. Now you can Put instances of your new
object type to any Turbo Vision stream and read instances back
from streams.
Registering
standard objects Turbo Vision defines stream registration records for all its
standard objects. In addition, each Turbo Vision unit defines a
RegisterXXXX procedure that automatically registers all of the
objects in that unit.
Handling nil
object pointers You can write a nil object to a stream. However, when you do, a
word of 0 is written to the stream. On reading an ID word of 0,
the stream returns a nil pointer. 0 is therefore reserved, and cannot
be used as a stream object ID number.
Adding Store methods Here are the Store methods. Notice that PGraphPoint doesn't need
one, since it doesn't add any fields to those it inherits from
PGraphObject
type
PGraphObject = ~TGraphObject;
TGraphObject = object(TObject)
PGraphCircle = ~TGraphCircle;
TGraphCircle = object(TGraphObject)
Radius: Integer;
Registration records Defining a registration record constant for each of the descendent
types is our last step. It's a good idea to follow the Turbo Vision
naming convention of using an R as the initial letter, replacing the
type's T.
Remember, each registration record gets a unique object ID
number (Dbjtype). Turbo Vision reserves 0 through 99 for its
standard objects. It's a good idea to keep track of all your objects
stream ID numbers in one central pl~ce to avoid duplication.
const
RGraphPoint: TStreamRec = (
ObjType: 150;
VmtLink: Ofs(TypeOf(TGraphPoint)~);
Load: nil; { No load method yet }
Store: @TGraphPoint.Store);
RGraphCircle: TStreamRec = (
ObjType: 151;
VmtLink: Ofs(TypeOf(TGraphCircle)~);
Load: nil; { No load method yet }
Store: @TGraphCircle.Store);
RGraphRect: TStreamRec = (
ObjType: 152;
VmtLink: Ofs(TypeOf(TGraphRect)~);
Load: nil; { No load method yet }
Store: @TGraphRect.Store);
Writing to the stream All that's left to follow is the normal file I/O sequence of: create a
stream; put the data (a collection) onto it; close the stream. You
don't have to write a ForEach iterator to stream each collection
item. You just tell the stream to Put the collection on the stream:
This is TVGUlD21.PAS. var
GraphicsList: PCollectionj
GraphicsStream: TBufStream;
begin
StreamRegistration; { Register all streams }
end.
This creates a disk file that contains all the information needed to
"read" the collection back into memory. When the stream is
Subview
instances Many times you'll find it convenient to store pointers to a group's
subviews in local instance variables. For example, a dialog box
will often store pointers to its control objects in mnemonically
named fields for easy access (fields like OKButton or
FilelnputLine). When that view is then inserted into the view tree,
the owner has two pointers to the subview, one in the field and
one in the subview list. If you don't make allowances for this,
reading back the object from a stream will result in duplicate
instances.
The solution is provided in the TGroup methods called
GetSubViewPtr and PutSubViewPtr. When storing a field that is
also a subview, rather than writing the pointer as if it were just
another variable, you call PutSubViewPtr, which stores a reference
Peer view
instances A similar situation can arise when a view has a field that points to
one of its peers. A view is called a peer view of another if both
views are owned by the same group. An excellent example is that
of a scroller. Because the scroller has to know about two scroll
bars which are also members of the same window that contains
the scroller, it has two fields that point to those views.
As with subviews, you can run into problems when reading and
writing references to peer views to streams. The solution,
Copying a stream
TStream has a method CopyFrom(S,Count), which copies Count
bytes from the given stream S. CopyFrom can be used to copy the
entire contents of a stream to another stream. If you repeatedly
access a disk-based stream, for example, you may want to copy it
to an EMS stream for more rapid access:
NewStream := New(TEmsStream, Init(OldStreamA.GetSize));
OldStreamA.Seek(O);
NewStream A. CopyFrom (OldStream, OldStreamA.GetSize);
Random-access streams
So far, we have dealt with streams as sequential devices: you Put
objects at the end of a stream, and Get them back in the same
order. But Turbo Vision provides more capabilities than that.
Specifically, it allows you to treat a stream as a virtual, random-
access device. In addition to Get and Put, which correspond to
Read and Write on a file, streams provide features analogous to a
file's Seek, FilePos, FileSize, and Truncate.
• The Seek procedure of a stream moves the current stream
pointer to a specified position (in bytes from the beginning of
the stream), just like the standard Turbo Pascal Seek procedure.
• The GetPos function is the inverse of the Seek procedure. It
returns a Longint with the current position of the stream.
• The GetSize function returns the size of the stream in bytes.
• The Truncate procedure deletes all data after the current stream
position, making the current position the end of the stream.
Resources are discussed in While these routines are useful, random access streams require
Chapter 9, "Resources. H
Stream error
handling TStream has a method called Error(Code, Info), which is called
whenever the stream encounters an error. Error simply sets the
stream's Status field to one of the constants listed in Chapter 14,
"Global reference" under "stXXXX constants."
The ErrorInfo field is undefined except when Status is stGetError or
stPutError. If Status is stGetError, the ErrorInfo field contains the
stream ID number of the unregistered type. If Status is stPutError,
the ErrorInfo field contains the VMT offset of the type you tried to
put onto the stream. You can override TStream.Error to generate
any level of error handling, including run-time errors.
Resources
A resource file is a Turbo Vision object that will save objects
handed to it, and can then retrieve them by name. Your
application can then retrieve the objects it uses from a resource
rather than initializing them. Instead of making your application
initialize the objects it uses, you can have a separate program
create all the objects and save them to a resource.
The mechanism is really fairly simple: a resource file works like a
random-access stream, with objects accessed by keys, which are
simply unique strings identifying the resources.
Unlike other portions of Turbo Vision, you probably won't need
or want to change the resource mechanism. As provided,
resources are robust and flexible. You really should only need to
learn to use them.
What's in a resource?
Before digging into the details of resources, you might want to
make sure you're comfortable with streams and collections,
because the resource mechanism uses both of them. You can use
resources without needing to know just how they work, but if you
plan to alter them in any way, you need to know what you're
getting into.
A TResourceFile contains both a sorted string collection and a
stream. The strings in the collection are keys to objects in the
stream. TResourceFile has an Init method that takes a stream, and a
Get method that takes a string and returns an object.
Reading a resource
Retrieving a resource from a resource file is just as simple as
getting an object from a stream: You just call the resource file's Get
function with the desired resource's key as a parameter. Get
returns a generic PObject pointer.
The status line resource created in the previous example can be
retrieved and used by an application in this way:
program MyApp;
uses Objects, Drivers, Views, Menus, Dialogs, App;
var
MyRez: TResourceFile;
type
PMyApp = ATMyApp;
TMyApp = object(TApplication)
constructor Init;
procedure InitStatusLine; virtual;
end;
constructor TMyApp.lnit;
const
MyRezFileName: FNameStr = 'MY.REZ';.
begin
MyRez.lnit(New(PBufStream, Init(MyRezFileName, stOpen, 1024)));
if MyRez.StreamA.Status <> 0 then Halt(l);
RegisterType(RStatusLine);
TApplication.lnit;
end;
procedure TMyApp.lnitStatusLine;
begin
StatusLine := PStatusLine(MyRez.Get('Waldo'));
end;
var Wa1doApp: TMyApp;
begin
WaldoApp.lnit;
WaldoApp.Run;
Wa1doApp.Done;
String lists
In addition to the standard resource mechanism, Turbo Vision
provides a pair of specialized objects that handle string lists. A
string list is a special resource access object that allows your
program to access resourced strings by number (usually
represented by an integer constant) instead of a key string. This
allows a program to store strings out on a resource file for easy
customization and internationalization.
For example, the Turbo Pascal IDE uses a string list object for all
its error messages. This means the program can simply call for an
error message by number, and different versions in different
countries will find different strings in their resources.
The string list object is by design not very flexible, but it is fast
and convenient when used as designed.
The TStringList object is used to access the strings. To create the
string list requires the use of the TStrListMaker object. The
registration records for both have the same object type number.
The string list object has no Init method. The only constructor it
has is a Load method, because string lists only exist on resource
files. Similarly, since the string list is essentially a read-only
resource, it has a Get function, but no Put procedure.
10
Hiding behind a mask Keep in mind, however, that there are a couple of reasons why
your object may never get to see the event you intend it to handle.
The first and simplest mistake is leaving a type of event out of
your object's event mask. If you haven't told your object that it is
allowed to handle a certain kind of event, it won't even look at
those events!
Stolen events A second possibility you need to consider is that some other
object is "stealing" the event. That is, the event is being handled
and cleared by some object other than the one you intended to
give it to.
There are a couple of things which could cause this. The first is
duplicate command declarations: if two commands have been
assigned the same constant value, they could be handled
interchangeably. This is why it is crucial to keep track of which
constants you have assigned which values, particularly in a
situation when you are reusing code modules.
Another possible cause of this would be duplicate command
labels, particularly in reused code. Thus, if you assign a command
Blame your parents Finally, check to make sure that the event isn't being handled in a
call to the object's ancestor. Often, the HandleEvent method of a
derived type will rely on the event handler of its ancestor to deal
with most events, and it may be handling one that you didn't
expect. Try trapping the event before the call to the ancestor's
HandleEvent.
It doesn't do
what I expect Perhaps your window does show up, but it displays garbage, or
something other than what you expected. That indicates that the
event is being handled properly, but the code that responds to the
event is either incorrect or perhaps overridden. In this instance, it
is best to set a breakpoint in the routine that gets called when the
event occurs. Once execution breaks, you can step or trace
through your code normally.
It hangs
Hang bugs are among the most difficult to track down, but they
can be found. First you might try some combination of the
breakpointing methods suggested previously to narrow down
just where the hang occurs. The second thing to look for is
pointers being disposed of twice. This can happen when a view is
disposed of by its owner, and then you try to dispose of it directly.
For example:
Warningl var
This code will hang your Bruce, Pizza: PGroup;
system. Do not run itllt is only
an illustration.
R: TRect;
begin
R.Assign(5, 5, 10, 10);
Pizza := New(PGroup, Init(R));
R.Assign(10, 10, 20, 20);
Bruce := New(PGroup, Init(R));
BruceA.lnsert(Pizza);
Dispose (Bruce, Done); { dispose of Bruce and subviews }
Dispose (Pizza, Done); { This will hang your system }
end;
Scavenge your
old code There is an easier way. By now, you know that the essence of
programming a specific application in Turbo Vision is
concentrated in the application's Init, Draw, and HandleEvent
methods. The better approach to porting an existing application is
first to write a Turbo Vision interface that parallels your existing
one, and then scavenge your old code into your new application.
Most of the scavenged code will end up in new view's Init, Draw,
and HandleEvent methods.
You need to spend some time thinking about the essence of your
application, so you can divide your interface code from the code
that carries out the work of your application. This can be difficult,
because you have to think differently about your application.
The job of porting will involve some rewriting to teach the new
objects how to represent themselves, but it will also involve a lot
of throwing away of old interface code. This shouldn't introduce a
lot of new bugs, and can actually be a fun thing to do.
If you port an application, you will be amazed to discover how
much of your code is dedicated to handling the user interface.
When you let Turbo Vision work for you, a lot of the user
interface work you did before will simply disappear.
We discovered how rewarding this can be when we ported Turbo
Pascal's integrated environment to Turbo Vision. We scavenged
the compiler, the editor, the debugger-all the various engines-
Rethink your
organization Programming in this new paradigm takes some getting used to. In
traditional programming, we tend to think of the program from
the perspective of the code. We are the code, and the data is "out
there," something on which we operate. At first glance, we might
be tempted to organize a program such as Turbo Pascal's
integrated environment around an editor object. After all, that's
what you're doing most of the time in the environment, editing.
The editor would edit, and at intervals, it would call the compiler.
But we need to make some shifts in perspective to use the true
power of object-oriented programming. It makes more sense in
the integrated environment to make the application itself the
organizing object. When it's time to edit, the application calls up
an editor. When it's time to compile, the application brings up the
compiler, initializes it, and tells it what files to compile.
If the compiler hits an error, how is the user returned to the point
of error in the source code? The application calls the compiler, and
it gets a result back from it. If the compiler returns an error result,
it also returns a file name and a line number. The application
looks to see if it already has an editor open for that file, and if not,
it opens it. It passes the error information, including the line
number, to the editor and constructs an error message string for
the editor.
There's no reason for the editor to know anything about a
compiler, or the compiler to know about an editor. The center of it
all is the application itself. It's the application that needs the editor
and the annliC'rltion thrlt npPc1~ thp rm,,!'ilpr Aftpr ~ 11, 't.o\T'h~t;ro;: ~n
Flag values
In the diagram, msb indicates the "most significant bit", also
called the "high-order bit" because in constructing a binary
number that bit has the highest value (2 15). The bit at the lowest
end of the binary number is marked Isb, for "least significant bit,"
also called the "low-order bit."
So, for example, the fourth bit is called ofFramed. If the ofFramed bit
is set to 1, it means the view has a visible frame around it. If the
bit is a 0, the view has no frame.
As it turns out, you really don't have to worry about what the
actual values of the flag bits are unless you plan to define your
own, and even in that case, you really only need to be concerned
that your definitions be unique. For instance, the six highest bits
in the Options word are presently undefined by Turbo Vision. You
may define any of them to mean anything to the views you
derive.
Bit masks
A mask is simply a shorthand way of dealing with a group of bit
flags together. For example, Turbo Vision defines masks for
different kinds of events. The evMouse mask simply contains all
four bits that designate different kinds of mouse events, so if a
view needs to check for mouse events, it can compare the event
type to see if it's in the mask, rather than having to check for each
of the individual kinds of mouse events.
Seiting a bit To set a bit, use the or operator. For instance, to set the
ofPostProcess bit in the Options field of a button called MyButton,
you would use this code:
MyButton.Options := MyButton.Options or ofPostProcess;
Note that you should not use addition to set bits unless you are
absolutely sure what you are doing. For example, if instead of the
preceding code, you used
Don't do this! MyButton.Options := MyButton.Options + ofPostProcess;
your operation would work if and only if the ofPostProcess bit was
not already set. If the bit was set before you added another one,
the binary add would carry over into the next bit <ofBuffered),
setting or clearing it, depending on whether it was clear or set to
start with.
In other words: adding bits can have unwanted side effects. Use
the or operation to set bits instead.
Before leaving the topic of setting bits, note that you can set
several bits in one operation by oring the field with several bits at
once. The following code would set two different grow mode
flags at once in a scrolling view called MyScroller:
MyScroller.GrowMode := MyScroller.GrowMode or (gfGrowHiX +
gfGrowHiY);
Clearing a bit Clearing a bit is just as easy as setting it. You just use a different
operation. The best way to do this is actually a combination of
two bitwise operations, and and not. For instance, to clear the
dmLimitLoX bit in the DragMode field of a label called ALabel, you
would use
ALabel.DragMode := ALabel.DragMode and not dmLimitLoX;
As with setting bits, multiple bits may be set in a single operation.
Using masks Much like checking individual bits, you can use and to check to
see'if one or more masked bits are set. For example, to see if an
event record contains some sort of mouse event, you could check
if Event.What and evMouse <> 0 then ...
Summary
The following list summarizes the bitmap operations:
Setting a bit:
field := field or flag;
Clearing a bit:
field := field and not flag;
Checking if a flag is set:
if field and flag = flag then ...
Checking if a flag is in a mask:
if flag and mask <> 0 then ...
183
184 Turbo Vision Guide
c H A p T E R
11
Objects in general
Remember that each object (apart from the base object TObjeet,
and the two special objects TPoint and TReet) inherits the fields
and methods of its parent object. New objects that you derive will
also inherit their parents' methods and fields. Many of the
standard objects have abstract methods which must be overridden
by your derived objects. Other methods are marked virtual,
meaning that you will normally want to override them. There are
other methods that provide useful default actions in the absence
of overrides.
Naming conventions
All the standard Turbo Vision object types have a set of names
using a mnemonic set of prefixes. The first letter of the identifier
tells you whether you are dealing with the object type, a pointer
to it, its stream registration record, or its color palette.
• Object types start with T: TObjeet
• Pointers to objects start with P: PObjeet = ATObject
• Stream registration records start with R: RObjeet
• Color palettes start with C: CObjeet
All Turbo Vision constants have two-letter mnemonic prefixes
that indicate their usage.
12
Constants
Variables
Variable Type Initial value Meaning
EmsCurHandle Word $FFFF Current EMS handle
EmsCurPage Word $FFFF Current EMS page
Procedures and
functions Procedure Operation
Abstract Default routine for methods that must be
overridden
DisposeStr Disposes of a string created with NewStr
RegisterType Registers an object type with Turbo Vision
t"' ....... n,." .......... ~
Function Operation
LongDiv Divides a long integer by an integer
LongMul Multiplies two integers into a long integer
NewStr Allocates a string on the heap
Types
Type Use
TCommandSet Allows groups of commands to be enabled or
disabled
TDrawBuffer . Buffer used by draw methods
TFrame Frame object used by windows
TGroup Abstract object for complex views
TLis tViewer Base type for list boxes and such
TPalette Color palette type used by all views
TScrollBar Object defining a scroll bar
TScrollChars Scroll bar component characters
TScroller Base object for scrolling text windows
TTitleStr Title string used by TFrame
TVideoBuf Video buffer used by screen manager
TView Abstract object; base of all visible objects
TWindow Base object for resizable windows
Constants
Niew State masks Constant Value Meaning
sfVisible $0001 View is visible
sfCursorVis $0002 View has visible cursor
sfCursorlns $0004 View's cursor is block for insert mode
sfShadow $0008 View has a shadow
sfActive $0010 View is, or is owned by, the active window
sfSelected $0020 View is owner's selected view
sfFocused $0040 View has the focus
sfDragging $0080 View is being dragged
sfDisabled $0100 View is disabled
sfModal $0200 View is in modal state
sfExposed $0800 View is attached to the application
T\/io'A,llrrtl""tl\lIrv-lo
-O";;r
\ionstam
- 0 0 0 __ 0 _
Variables
Variable Type Initial value Meaning
MinWinSize TPoint (X: 16; Y: 6) Minimum window size
ShadowSize TPoint (X: 2; Y: 1) Window shadow size
ShadowAttr Byte $08 Window attribute
Types
Type Use
TButton Pushbuttons to generate commands
TCheckBoxes Clusters of on/off toggle switches
TCluster Abstract type for check boxes and radio buttons
TDialog Specialized window for dialog boxes
THistory List of previous entries for an input line
TlnputLine Text input editor
TLabel Smart label for a cluster or an input line
TListBox Scrollable list for user choices
TParamText Formatted static text
TRadioButtons Cluster of buttons, only one of which may be
pressed at a time
TSltem String items in a linked list, used by clusters
TStaticText Plain text
Constants
Procedure Operation
RegisterDialogs Registers all objects in the Dialogs unit for use with
streams
Types
Type Use
TApplication Application object with event manager, screen
manager, error handling, and memory management
TBackground Colored background for desktop
TDeskTop Group object to hold windows and dialog boxes
TProgram Abstract application object
Variables
Variable Type Initial value Meaning
Application PProgram nil Pointer to current
application
DeskTop PDeskTop nil Pointer to current desktop
StatusLine PStatusLine nil Pointer to current status
line
MenuBar PMenuView nil Pointer to current menu
bar
Types
Type Use
TMenu Linked list of TMenuItem records
TMenuBar Horizontal menu header, connected to menus
TMenuBox Pull-down or pop-up menu box
TMenultem Record linking a label text, a hot key, a command, and
a help context for use within a menu
TMenuStr String type for menu labels
TMenuView Abstract object type for menu bars and menu boxes
TStatusDef Record linking a range of help contexts with a list of
status line items
TStatusItem Record linking a label text, a hot key, and a command
for use on a status line
TStatusLine Message line for the bottom of the application screen,
including a list of TStatusDef records
Procedures and
functions
TMenultem functions Function Operation
NewItem Creates a new menu item
NewLine Creates a line across a menu box
NewSubMenu Creates a menu off a menu bar or menu box
IIVIC;:::IIU IUUIIIIC;:::~
Routine Operation
NewMenu function Allocates a menu on the heap
DisposeMenu procedure Deallocates menu from heap
Types
Type Use
TEvent Event record type
TSysErrorFunc System error handler function type
Constants
Mouse button state Constant Value Meaning
masks
mbLeftButton $01 Left mouse button
mbRightButton $02 Right mouse button
Types
Type Use
TTerminal TTY-like scrolling text device
TTerminalBuffer Circular text buffer for TTerminal
TTextDevice Abstract text device object
Procedure
Procedure Operation
AssignDevice Assigns a text file device for input and/or output
Procedures and
functions
Procedure Operation
DoneMemory Shuts down the memory manager
FreeBufMem Deallocate cache buffer for a group
GetBufMem Allocate cache buffer for a group
InitMemory Initializes the memory manager
SetMemTop Sets top of application's memory block
Function Operation
LowMemory Indicates whether safety pool has been eaten into
MemAIloc Allocates memory with safety pool check
MemAIlocSeg Allocates segment-aligned memory block
Variables
vanaole Iype mltlal value Meaning
HistoryBlock Pointer nil Memory buffer to hold all
history list items
HistorySize Word 1024 Size of history block
History Used Word 0 Offset into history block
indicating amount of
block used
Function Operation
HistoryCount Returns the number of strings in a history list
HistoryStr Returns a particular string from a history list
13
Object reference
This chapter contains an alphabetical listing of all the standard Turbo
Vision object types, with explanations of their general purposes and
usage, their fields, methods and color palettes.
To find information on a specific object, keep in mind that many of the
properties of the objects in the hierarchy are inherited from ancestor
objects. Rather than duplicate all that information endlessly, this chapter
only documents fields and methods that are new or changed for a
particular object.
To save you some For example, if you want to know about the Owner field of a TLabel object,
hunting, all fields
and methods are
you might first look under TLabel's fields, where you won't find Owner
indexed. listed. You would then check TLabel's immediate ancestor in the hierarchy,
TStaticText. Again, Owner will not be listed. You would next check
TStaticText's immediate ancestor, TView. There you will find complete
information about Owner. which is inherited unchanQ"ed bv TLabel.
Each object's entry in this chapter has a graphical representation of the
object's ancestors and immediate descendants, so it should be easy for you
to find the objects from which fields and methods are inherited.
Each object's entry is laid out in the following format:
Fields
This section will list all fields for each object, alphabetically. In addition to
showing the declaration of the field and an explanation of its use, there is
a Read only or Read/write designation. Read-only fields are generally
fields that are set up and maintained by the object's methods, and they
should not be on the left side of an assignment statement.
AField AField: SomeType; Read only
AField is a field that holds some information about this sample object. This
text explains how it functions, what it means, and how you use it.
See also: related fields, methods, objects, global functions, etc.
AnotherField AnotherField: Word; Read/write
AnotherField has similar information to that for AField.
Methods
This section lists all methods which are either newly defined for this
object or which override inherited methods. For virtual methods, an
indication will be given as to how often you will probably need to
override the method: Never, Seldom, Sometimes, Often, or Always.
Init constructor Init (AParameter: SomeType);
Init creates a new sample object, setting the AField field to AParameter.
Zilch procedure Zilch; virtual;
Override: The Zilch procedure causes the sample object to perform some action.
Sometimes
See also: TSomethingElse.Zilch
Methods
Init constructor Initi
The actual implementation of TApplication.Init is shown below:
constructor TApplication.Init;
begin
InitMemory;
InitVideo;
InitEvents;
InitSysError;
InitHistory;
TProgram. Init;
end;
See also: TProgram.Init
TBackground App
Field
PaHern Pattern: Char; Read only
The bit pattern giving the view's background.
Methods
Init constructor Init(var Bounds: TRect; APattern: Char);
Creates a TBackground object with the given Bounds by calling TViewlnit.
GrowMode is set to gfGrowHiX + gfGrowHiY, and the Pattern field is set to
APattern.
See also: TView.Init, TBackground.Pattern
Load constructor Load (var S: TStream);
Palette
Background objects use the default palette CBackground to map onto the
first entry in the application palette.
CBackground II ~ II
Color
TBufStream Objects
J TOb~.ct J
TStrp.ilm
Fields
Buffer Buffer: Pointer; Read only
A painter to the start of the stream's buffer
BufSize BufSize: Word; Read only
The size of the buffer in bytes
BufPtr BufPtr: Word; Read only
An offset from the Buffer pointer indicating the current position within the
buffer.
BufEnd BufEnd: Word; Read only
If the buffer is not full, BufEnd gives an offset from the Buffer pointer to the
last used byte in the buffer.
Methods
Init constructor Init (FileName: FNameStr; Mode, Size: Word);
Creates and opens the named file with access mode Mode by calling
TDosStream.Init. Also creates a buffer of Size bytes with a GetMem call. The
Handle, Buffer and BufSize fields are suitably initialized. Typical buffer
sizes range from 512 bytes to 2,048 bytes.
See also: TDosStream.Init
Done destructor Done; virtual;
Override: Never Closes and disposes of the file stream; flushes and disposes of its buffer.
See also: TBufStream.Flush
Flush procedure Flush; virtual;
Override: Never Flushes the calling file stream's buffer provided the stream is stOK.
See also: TBufStream.Done
Note that Bufis not the stream's buffer, but an external buffer to hold the
data being written to the stream. When Write is called, Buf will point to
the variable whose value is being written.
See also: TBufStream.Read, st WriteError
TButton Dialogs
Fields
Methods
Init constructor Init(var Bounds: TRect; ATitle: TTitleStr; ACornmand: Word;
AFlags: Byte);
Creates a TButton object with the given size by calling TView.Init.
NewStr(ATitle) is called and assigned to Title. AFlags serves two purposes:
If AFlags and bfDefault is nonzero, AmDefault is set to True; in addition,
AFlags indicates whether the title should be centered or left-justified by
testing whether AFlags and bfLeftJust is nonzero.
Options is set to (ofSelectable + ofFirstClick + ofPreProcess + ofPostProcess).
EventMask is set to evBroadcast. If the given ACommand is not enabled,
sfDisabled is set in the State field.
See also: TView.lnit, bfXXXX button flag constants
Load constructor Load (var s: TStream);
r"" ___ L_ ...... ,..,.,n ... .l.,L_ .... _1-!.-_L __ ...J ! __ !L!_1! ___ !I. r______ .1 _ _ _ ~ ______ , _____ 1 ".
_ ... _ _ .. _v _ .... ...., ......... v, .. ....,J,J)"-"- ... I,A..a.L"""", ..L.&.L.L ........ U..&..L~"""'~ .... '" .&..&.V .... .&.L "'.l.L\wo 5.1." ~.I.L .::JL.l.CU.L.l.l V) \".uJ.J..L.1L5
TView.Load(S). Other fields are set via S.Read calls, and State is set
according to whether the command in the Command field is enabled. Used
in conjunction with TButton.Store to save and retrieve TButton objects on a
TStream.
See also: TView.Load, TButton.Store
Done destructor Done; virtual;
Override: Never Disposes the memory assigned to the button's Title, then calls TView.Done
to destroy the view.
See also: TView.Done
Palette
Button objects use the default palette CButton to map onto CDiaiog palette
entries 10 through 15.
23456 8
CButton
Text Nomal Shadow
Text Default,----' Shortcut Sel ected
Text Sel ected-------I L.....------'Shortcut Defaul t
Text Disabled-----....J L.....------'Shortcut Nomal
TCheckBoxes Dialogs
up nuns se!ecrea In rnls way). \....neCK DOX C!llSrerS are orren aSSOClarea WlIn
TLabel objects.
Fields
None apart from Value and Sel, which are inherited from TCluster. The
Value word is interpreted as a set of 16 bits (0 through 15), with a 1 in the
Item'th bit position meaning that the Item'th check box is marked.
Methods
Note that TCheckBoxes does not override the TCluster constructors,
destructor, or event handler. Derived object types, however, may need to
override them.
Draw procedure Draw; virtual;
Override: Seldom Draws the TCheckBoxes object by calling the inherited TCluster.DrawBox
method. The default check box is 1 when unselected and [Xl
II [ II II II
when selected.
Note that if the boundaries of the view are sufficiently wide, check boxes
may be displayed in multiple columns.
See also: TCluster.DrawBox
~ark function Mark(Item: Integer): Boolean; virtual;
Override: Seldom Returns True if the Item'th bit of Value is set, that is, if the Item'th check
box is marked. You can override this to give a different interpretation of
the Value field. By default, the items are numbered 0 through 15.
See also: TCheckBoxes.Press
Press procedure Press(Item: Integer); virtual;
Toggles the Item'th bit of Value. You can override this to give a different
interpretation of the Value field. By default, the items are numbered 0
through 15.
See also: TCheckBoxes.Mark
Palette
By default, check boxes objects use CCluster, the default palette for all
cluster objects.
2 3 4
CClu.ter Jg; I 17 I I~
Text Normal
Text Selected
I. Shortcut Selected
Shortcut Nonnal
TCluster Dialogs I
A cluster is a group of controls that all respond in the same way. TCluster
is an abstract object type from which the useful group controls
TRadioButtons and TCheckBoxes are derived. Cluster controls are often
associated with TLabel objects, letting you select the control by selecting
on the adjacent explanatory label.
While buttons are used to generate commands and input lines are used to
edit strings, clusters are used to toggle bit values in the Value field, which
is of type Word. The two standard descendants of TCluster use different
algorithms when changing Value: TCheckBoxes simply toggles a bit, while
TRadioButtons toggles the enabled one and clears the previously selected
bit. Both inherit almost all of their behavior from TCluster.
Fields
Value Value: Word; Read only
Methods
Init constructor Init (var Bounds: TRect; AStrings: PSItern);
Clears the Value and Sel fields. The AStrings parameter is usually a series
of nested calls to the global function NewSItem. In this way, an entire
cluster of radio buttons or check boxes may be created in one constructor
call:
var
Control: PView;
Override: Seldom Returns the size of Value. Must be overridden in derived object types that T.
change Value or add other data fields, in order to work with GetData and
SetData.
See also: TCluster.GetData, TCluster.SetData
DravvBox procedure DrawBox(Icon: Strlng; Marker: Char);
Called by the Draw methods of descendant types to draw the box in front
of the string for each item in the cluster. Icon is a 5-character string (, [ ] ,
for check boxes,' ( ) 'for radio buttons). Marker is the character to use
to indicate the box has been marked (' X' for check boxes, ' .' for radio
buttons).
See also: TCheckBoxes.Draw, TRadioButtons.Draw
(7etData procedure GetData(var Rec); virtual;
Override: Seldom Writes the Value field to the given record and DrawView's the cluster.
Must be overridden in derived object types that change the Value field, in
order to work with DataSize and SetData.
See also: TCluster.DataSize, TCluster.SetData, TView.DrawView
(7etHelpCtx function GetHelpCtx: Word; virtual;
Override: Seldom Returns the value of Sel added to HelpCtx. This enables you to have
separate help contexts for each item in the cluster. Reserve a range of help
contexts equal to HelpCtx plus the number of cluster items minus one.
(7etPalette function Getpalette: PPalette; virtual;
Override: Returns a pointer to the default palette, CCluster.
Sometimes
HandleEvent procedure HandleEvent (var Event: TEvent); virtual;
Override: Seldom Calls TView.HandleEvent then handles all mouse and keyboard events
appropriate to this cluster. Controls are selected by mouse click or cursor
-. - - - - --
movement Keys unclualng i:JpaceUafj. 1 ne ClUSter IS rearawn to snow tne
selected controls.
See also: TView.HandleEvent
~ark function Mark (Item: Integer): Boolean; virtual;
Override: Always Called by Draw to determine which items are marked. The default
TCluster.Mark returns False. Mark should be overridden to return True if
the Item'th control in the cluster is marked, otherwise False.
~ovedTo procedure MovedTo (Item: Integer); virtual;
Override: Seldom Called by HandleEvent to move the selection bar to the Item'th control of
the cluster.
Press procedure Press (Item: Integer); virtual;
Override: Always Called by HandleEvent when the Item'th control in the cluster is pressed
either by mouse click or keyboard event. This abstract method must be
overridden.
SetData procedure SetData(var Rec); virtual;
Override: Seldom Reads the Value field from the given record and DrawView's the cluster.
Must be overridden in derived cluster types that require other fields to
work with DataSize and GetData.
See also: TCluster.DataSize, TCluster.GetData, TView.DrawView
SetState procedure SetState(AState: Word; Enable: Boolean); virtual;
Override: Seldom Calls TView.SetState, then DrawView's the cluster if AState is sfSelected.
See also: TView.SetState, TView.DrawView
store procedure Store(var S: TStream);
Stores the TCluster object on the given stream by calling TView.Store(S),
writing Value and Sel to S, then storing the cluster's Strings field by using
its Store method. Used in conjunction with TCluster.Load to save and
retrieve TCluster objects on a stream.
See also: TCluster.Load, TStream. Write
Palette
TCluster objects use CCluster, the default palette for all cluster objects, to
map onto entries 16 through 18 of the standard dialog box palette.
1 234
TCollection Objects m
Fields
Items Items: PItemList; Read only
A pointer to an array of item pointers.
See also: TItemList type
,-.,... ........ ,",,_ •• __ L .
vvu.~",\.. ..
'T_L __ ~ ___ •
Methods
Init constructor Init (ALimit, ADelta: Integer);
Creates a collection with Limit set to ALimit and Delta set to ADelta. The
initial number of items will be limited to ALimit, but the collection is
allowed to grow in increments of ADelta until memory runs out or the
number of items reaches MaxCollectionSize.
See also: TCollection.Limit, TCollection.Delta
Load constructor Load (var S: TStream);
Creates and loads a collection from the given stream. TCollection.Load calls
GetItem for each item in the collection.
See also: TCollection.GetItem
Done destructor Done; virtual;
Override: Often Deletes and disposes of all items in the collection by calling
TColiection.FreeAli and setting Limit to 0
See also: TCollection.FreeAll, TCollection.Init
At function At (Index: Integer): Pointer;
Returns a pointer to the item indexed by Index in the collection. This
method lets you treat a collection as an indexed array. If Index is less than
zero or greater than or equal to Count, the Error method is called with an
argument of coIndexError, and a value of nil is returned.
See also: TColiection.IndexOf
AtDelete procedure AtDelete(Index: Integer);
Deletes the item at the Index'th position and moves the following items up
by one position. Count is decremented by 1, but the memory allocated to
the collection (as given by Limit) is not reduced. If Index is less than zero
Override: The FreeItem method must dispose the given Item. The default
Sometimes
TCollection.FreeItem assumes that Item is a pointer to a descendant of
TObject, and thus calls the Done destructor:
if Item <> nil then Dispose (PObject (Item) , Done);
FreeItem is called by Free and FreeAll, but it should never be called directly.
See also: TCollection.Free, TCollection.FreeAll
Getltem function TCollection.GetItem(var S: TStream): Pointer; virtual;
Override: Called by TCollection.Load for each item in the collection. This method can
Sometimes
be overridden but should not be called directly. The default
TCollection.GetItem assumes that the items in the collection are
descendants of TObject, and thus calls TStream.Get to load the item:
GetItem := S.Get;
See also: TStream.Get, TCollection.Load, TCollection.Store
IndexOf function IndexOf (Item: Pointer): Integer; virtual;
Override: Never Returns the index of the given Item. The converse operation to
TCollection.At. If Item is not in the collection, IndexOfreturns -1.
See also: TCollection.At
Insert procedure Insert (Item: Pointer); virtual;
Override: Never Inserts Item into the collection, and adjusts other indexes if necessary. By
default, insertions are made at the end of the collection by calling
AtInsert(Count, Item);
See also: TCollection.AtInsert
LastThct function LastThat (Test: Pointer): Pointer;
LastThat applies a Boolean function, given by the function pointer Test, to
each item in the collection in reverse order until Test returns True. The
result is the item pointer for which Test returned True, or nil if the Test
function returned False for all items. Test must point to a far local function
taking one Pointer parameter and returning 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;
See also: TCollection.FirstThat, TCollection.ForEach
Pack procedure Pack;
Deletes all nil pointers in the collection.
See also: TColiection.Delete, TColiection.DeleteAli
Putltem procedure PutItem(var S: TStream; Item: Pointer); virtual;
Override: Called by TColiection.Store for each item in the collection. This method can
Sometimes be overridden but should not be called directly. The default
TCollection.PutItem assumes that the items in the collection are
descendants of TObject, and thus calls TStream.Put to store the item:
S .Put (Item) ;
TDeskTop App
TDeskTop is a simple group that owns the TBackground view upon which
the application's windows and other views appear. TDeskTop represents
the desktop area of the screen between the top menu bar and bottom
status line.
Methods
Init constructor Init (var Bounds: TRect);
Creates a TDeskTop group with size Bounds. The default GrowMode is
gfGrowHiX + gfGrowHiY. Init also calls NewBackground to insert a
TBackground view into the group.
See also: TDeskTop.NewBackground, TGroup.lnit, TGroup.Insert
Cascade procedure Cascade (var R: TRect);
Redisplays all tileable windows owned by the desktop in cascaded
format. The first tileable window in Z-order (the window "in back") is
zoomed to fill the desktop, and each succeeding window fills a region
hpO"inninO" nnp linp lmATPr ;:tnn nnp sn;:tC'P f;:trthpr to the ri2:ht than the one
before. The active window appears·"on top," as the sm~iIest window.
See also: ofI'ileable, TDeskTop.Tile
NewBackground function NewBackground: PView; virtual;
Override: Returns a pointer to the background to be used in the desktop. This
Sometimes method is called in the TDeskTop.Init method. Descendant objects can
change the background type by overriding this method.
See also: TDeskTop.Init
HandleEvent procedure HandleEvent (var Event: TEvent); virtual;
Override: Seldom Calls TGroup.HandleEvent and takes care of the commands cmNext
(usually the hot key F6) and cmPrevious by cycling through the windows
(starting with the currently selected view) owned by the desktop.
See also: TGroup.HandleEvent, cmXXXX command constants
Tile procedure Tile (var R: TRect);
Redisplays all ofTileable views owned by the desktop in tiled format.
See also: TDeskTop.Cascade, ofTileable
TlleError procedure TileError; virtual;
Override: TileError is called if an error occurs during TDeskTop. Tile or
Sometimes TDeskTop.Cascade. By default it does nothing. You may wish to override it
to notify the user that the application is unable to rearrange the windows.
See also: TDeskTop. Tile, TDeskTop.Cascade
TDialog Dialogs
Methods
Init constructor Init(var Bounds: TRect; ATitle: TTitleStr);
Creates a dialog box with the given size and title by calling
TWindow.Init(Bounds, ATitle, wnNoNumber). GrowMode is set to 0, and
Flags is set to wfMove + wfClose. This means that, by default, dialog boxes
can move and close (via the close icon) but cannot grow (resize).
Note that TDialog does not define its own destructor, but uses Close and
Done inherited via TWindow, TGroup, and TView.
See also: TWindow.lnit
HandleEvent procedure HandleEvent(var Event: TEvent); virtual;
Override: Calls TWindow.HandleEvent(Event), then handles Enter and Esc key events
Sometimes
specially. In particular, Esc generates a cmCancel command, and the Enter
key broadcasts a cmDefault command. This method also handles cmOK,
cmCancel, cmYes, and cmNo command events by ending the modal state of
the dialog box. For each of the above events handled successfully, this
method calls ClearEvent.
See also: TWindow.HandleEvent
GetPaleHe function GetPalette: PPalette; virtual;
Override: Seldom This method returns a pointer to the default palette, CPalette.
Valid function Valid (Command: Word): Boolean; virtual;
Override: Seldom Returns True if the command given is cmCancel or if all the group controls
return True.
See also: TGroup.Valid
Dialog box objects use the default palette CDialog to map onto the 32nd
through 63rd entries in the application palette.
CDialog
Frame Passive-------I Label Shortcut
Frame Active-------' Label Highl ight
Frame I c o n - - - - - - - - - ' '-----Label Nonnal
Scroll Bar Page:-----------I ' - - - - - - - S t a t i cText
Scroll Bar Control s - - - - - - - - - - '
10 11 12 13 14 15 16 17 18
CDtalog
19 20 21 22 23 24 25
CDtalog
26 27 28 29 30 31 32
CDtalog
TDosStream Objects
Fields
Handle Handle: Word Read only
Handle is the DOS file handle used to access an open file stream.
Methods
Init constructor Init (FileName: FNameStr; Mode: Word);
Creates a DOS file stream with the given FileName and access mode. If
successful, the Handle field is set with the DOS file handle. Failure is
signaled by a call to Error with an argument of stInitError.
The Mode argument must be set to one of the values stCreate, stOpenRead,
stOpen Write, or stOpen. These constant values are explained in Chapter 14
under UstXXXX stream constants."
Done destructor Done; virtual;
Override: Never Closes and disposes of the DOS file stream
See also: TDosStream.Init
G7etPos function GetPos: Longint; virtual;
Override: Never Returns the value of the calling stream's current position.
See also: TDosStream.Seek
GefSize function GetSize: Longint; virtual;
Override: Never Returns the total size in bytes of the calling stream.
Read procedure Read (var Buf; Count: Word); virtual;
Override: Never Reads Count bytes into the Bufbuffer starting at the calling stream's
current position.
See also: TDosStream. Write, stReadError
Seek procedure Seek (Pos: Longint); virtual;
Override: Never Resets the current position to Pos bytes from the beginning of the calling
stream.
See also: TDosStream.GetPos, TDosStream.GetSize
Truncate procedure Truncate; virtual;
Override: Never Deletes all data on the calling stream from the current position to the end.
TEmsStream Objects
Fields
Handle Handle: Word; Read only
The EMS handle for the stream.
PageCount PageCount: Word; Read only
The number of allocated pages for the stream, with 16K per page.
Size Size: Longint; Read only
Methods
Inlt constructor Init (MinSize: Longint);
Creates an EMS stream with the given minimum size in bytes. Calls
TStream.Init then sets Handle, Size and PageCount. Calls Error with an
argument of stInitError if initialization fails.
See also: TEmsStream.Done
Done destructor Done; virtual;
Override: Never Disposes of the EMS stream and releases EMS pages used.
See also: TEmsStream.Init
G7etPos function Getpos: Longint; virtual;
Override: Never Returns the value of the calling stream's current position.
See also: TEmsStream.Seek
G7etSize function GetSize: Longint; virtual;
Override: Never Returns the total size of the calling stream.
Read procedure Read(var Buf; Count: Word); virtual;
Override: Never Reads Count bytes into the But buffer starting at the calling stream's
current position.
See also: TEmsStream. Write, stReadError
Seek procedure Seek(Pos: Longint); virtual;
Override: Never Resets the current position to Pos bytes from the start of the calling
stream.
See also: TEmsStream.GetPos, TEmsStream.GetSize
Truncate procedure Truncate; virtual;
Override: Never Deletes all data on the calling stream from the current position to the end.
The current position is set to the new end of the stream.
See also: TEmsStream.GetPos, TEmsStream.Seek
Write procedure Write(var Buf; Count: Word); virtual;
Override: Never Writes Count bytes from the Bufbuffer to the calling stream, starting at the
current position.
TFrame Views
Methods
Init constructor Init (var Bounds: TRect);
Calls TView.Init, then sets GrowMode to gfGrowHiX + gfGrowHiY and sets
EventMask to EventMask or evBroadcast, so TFrame objects default to
handling broadcast events.
See also: TView.Init
Draw procedure Draw; virtual;
Override: Seldom Draws the frame with color attributes and icons appropriate to the current
State flags: active, inactive, being dragged. Adds zoom, close and resize
icons depending on the owner window's Flags. Adds the title, if any, from
the owner window's Title field. Active windows are drawn with a double-
lined frame and any icons, inactive windows with a single-lined frame
and no icons.
See also: sfXXXX state flag constants, wfXXXX window flag constants
GetPaleHe function GetPalette: PPalette; virtual;
Override: Seldom Returns a pointer to the default frame palette, CFrame.
HandleEvent procedure HandleEvent (var Event: TEvent); virtual;
Override: Seldom Calls TView.HandleEvent, then handles mouse events. If the mouse is
clicked on the close icon, TFrame generates a cmClose event. Clicking on
the zoom icon or double-clicking on the top line of the frame generates a
cmZoom event. Dragging the top line of the frame moves the window, and
dragging the resize icon moves the lower-right corner of the view and
therefore changes its size.
See also: TView.HandleEvent
SetState procedure SetState{AState: Word; Enable: Boolean); virtual;
Override: Seldom Calls TView.SetState, then if the new state is sfActive or sfDragging, calls
Palette
DrawView to redraw the view.
See also: TView.SetState I
Frame objects use the default palette, CFrame, to map onto the first three
entries in the standard window palette.
CFrame
Passi ve Fram
21
Passive T i t l -
2
I
3
I
4 5
I 1 I 2 I 2r:g3I
Icons
Active Title
Active Frame-e- - - - ' .
TGroup Views
I IUlalog I I TApplication I
TGroup objects and their derivatives (which we call groups for short)
provide the central driving power to Turbo Vision. A group is a special
breed of view. In addition to all the fields and methods derived from
TView, a group has additional fields and methods (including many
overrides) allowing it to control a dynamically linked list of views
(including other groups) as though they were a single object. We often talk
about the sub views of a group even when these subviews are often
groups in their own right.
Fields
ExecView saves the current context (the selected view, the modal view,
and the command set), makes P modal by calling pA.SetState(sfModal,
True), inserts P into the group (if it isn't already inserted), and calls
pA .Execute. When pA .Execute returns, the group is restored to its previous
state, and the result of PA.Execute is returned as the result of the ExecView
call. If P is nil upon a call to ExecView, a value of cmCancel is returned.
See also: TGroup.Execute, sfModal.
Execute function Execute: Word; virtual;
Override: Seldom Overrides TView.Execute. Execute is a group's main event loop: It repeat-
edly gets events using GetEvent and handles them using HandleEvent. The
event loop is terminated by the group or some sub view through a call to
EndModal. Before returning, however, Execute calls Valid to verify that the
modal state can indeed be terminated.
The actual implementation of TGroup.Execute is shown below. Note that
EndState is a private field in TGroup which gets set by a call to EndModal.
function TGroup.Execute: Word;
var
E: TEvent;
begin
repeat
EndState : = 0;
repeat
GetEvent(E);
HandleEvent(E);
if E.What <> evNothing then EventError(E);
until EndState <> 0;
until Valid(EndState);
Execute := EndState;
end;
See also: TGroup.GetEvent, TGroup.HandleEvent, TGroup.EndModal,
TGroup. Valid
First function First: PView;
Returns a pointer to the first subview (the one closest to the top in Z-
order), or nil if the group has no subviews.
See also: TGroup.Last
FirstThat function FirstThat (Test: Pointer): PView;
FirstThat applies a boolean function, given by the function pointer Test, to
each subview in Z-order until Test returns True. The result is the sub view
pointer for which Test returned True, or nil if the Test function returned
False for all subviews. Test must point to a far local function taking one
Pointer parameter and returning a Boolean value. For example:
function MyTestFunc(P: PView): Boolean; far;
The SubViewAt method shown below returns a pointer to the first
subview that contains a given point.
function TMyGroup.SubViewAt(Where: TPoint): PView;
function ContainsPoint(P: PView): Boolean; far;
var
Bounds: TRect;
begin
PA.GetBounds(Bounds);
ContainsPoint := (pA.State and sfVisible <> 0) and
Bounds.Contains(Where);
end;
begin
SubViewAt := FirstThat(@ContainsPoint);
end;
See also: TGroup.ForEach
ForEach procedure ForEach (Action: Pointer);
ForEach applies an action, given by the procedure pointer Action, to each
subview in the group in Z-order. Action must point to a far local
procedure taking one Pointer parameter, for example:
procedure MyActionProc(P: PView); far;
The MoveSubViews method show below moves all subviews in a group by
a given Delta value. Notice the use of Lock and Unlock to limit the number
of redraw operations performed, thus eliminating any unpleasant flicker.
procedure TMyGroup.MoveSubViews(Delta: TPoint);
procedure DoMoveView(P: PView); far;
begin
PA.MoveTo(PA.Origin.X + Delta.X, PA.Origin.Y + Delta.Y);
end;
begin
Lock;
ForEach(@DoMoveView);
Unlock;
end;
See also: TGroup.FirstThat
(;etData procedure GetData(var Rec); virtual;
Override: Seldom Overrides TView.GetData. Calls GetData for each sub view in reverse Z-
order, incrementing the location given by Rec'by the DataSize of each
subview.
See also: TView.GetData, TGroup.SetData
GetHelpCtx function GetHelpCtx: Word; virtual;
Override: Seldom Returns the help context of the current focused view by calling the
selected subviews' GetHelpCtx method. If no help context is specified by
GetSubViewPtr
any sub view, GetHelpCtx returns the value of its own HelpCtx field.
procedure GetSubViewPtr (var S: TStreami var P);
Loads a subview pointer P from the stream S. GetSubViewPtr should only
I
be used inside a Load constructor to read pointer values that were written
by a call to PutSubViewPtr from a Store method.
See also: TView.PutSubViewPtr, TGroup.Load, TGroup.Store
HandleEvent procedure HandleEvent (var Event: TEvent) i virtual;
Override: Often Overrides TView.HandleEvent. A group basically handles events by
passing them on to the HandleEvent methods of one or more of its
subviews. The actual routing, however, depends on the event class.
For focused events (by default evKeyDown and evCommand, see
FocusedEvents variable), event handling is done in three phases: First, the
group's Phase field is set to phPreProcess and the event is passed to
HandleEvent of all subviews that have the ofPreProcess flag set. Next, Phase
is set to phFocused and the event is passed to HandleEvent of the currently
selected view. Finally, Phase is set to phPostProcess and the event is passed
to HandleEvent of all sub views that have the ofPostProcess flag set.
For positional events (by default evMouse, see PositionalEvents variable),
the event is passed to the HandleEvent of the first subview whose
1..~ •• _..l:_~ _~_L __ ~l ____ L_: __ Lt.. _ _ _ !_L _! _____ 1 ___ T"_._ •• L TA71._ •• _
- - - .. _ ........ 0 ........ -~- .....b.A. .... _"' ....... ~......... v ~4L ..... ,t''''.l.41.''' O .... V""'.&.L "'-'J ~V"''''''. r 1', ...... ,,,.
For broadcast events (events that aren't focused or positional), the event is
passed to the HandleEvent of each subview in the group in Z-order.
If a subview's EventMask field masks out an event class,
TGroup.HandleEvent will never send events of that class to the sub view.
For example, the default EventMask of TView disables evMouseUp,
evMouseMove, and evMouseAuto, so TGroup.HandleEvent will never send
such events to a standard TView.
See also: FocusedEvents, PositionalEvents, evXXXX event constants,
TView.EventMask, HandleEvent methods
I
procedure SetData(var Rec); virtual;
Override: Seldom Overrides TView.SetData. Calls SetData for each subview in reverse Z-
order, incrementing the location given by Rec by the DataSize of each
subview.
See also: TGroup.GetData, TView.SetData
SefSfafe procedure SetState(AState: Word; Enable: Boolean); virtual;
Override: Seldom Overrides TView.SetState. First calls the inherited TView.SetState, then
updates the subviews as follows:
If AState is sfActive, sfExposed, or sfDragging then each sub view's SetState is
called to update the subview correspondingly.
If AState is sfFocused then the currently selected subview is called to focus
itself correspondingly.
See also: TView.SetState
Store procedure Store(var S: TStream);
Stores an entire group on a stream by first calling the inherited
TView.Store and then using TStream.Put to write each subview.
If an object type derived from TGroup contains fields that point to
subviews, it should use PutSubViewPtr within its Store to write these
fipln~
Overrides TView.Valid. Returns True if all the subview's Valid calls return
True. TGroup.Valid is used at the end of the event handling loop in
TGroup.Execute to confirm that termination is allowed. A modal state
cannot terminate until all Valid calls return True. A subview can return
False if it wants to retain control.
See also: TView.Valid, TGroup.Execute
THistory Dialogs
Fields
Link Link: PInputLine; Read only
A pointer to the linked TlnputLine object.
HistorylD HistoryID: Word; Read only
Each history list has a unique ID number, assigned by the programmer.
Different history objects in different windows may share a history list by
using the same history rD.
Methods
Init constructor Init(var Bounds: TRect; ALink: PInputLine; AHistoryId: Word);
Creates a THistory object of the given size by calling TView.lnit, then
setting the Link and Historyld fields with the given argument values. The
Options field is set to ofPostProcess and EventMask to evBroadcast.
See also: TView.Init
Load constructor Load (var S: TStrearn);
Draw
Creates and initializes a THistory object from the given TStream by calling
TView.Load(S) and reading Link and Historyld from S.
See also: TView.Store
procedure Draw; virtual;
III
Override: Seldom Draws the THistory icon in the default palette.
GetPaleHe function GetPalette: PPalette; virtual;
Override: Returns a pointer to the default palette, CHistory.
Sometimes
Store procedure Store(var S: TStrearn);
Saves a THistory object on the target TStream by calling TView.Store(S)
then writing Link and Historyld to S.
See also: TView.Load
Palette
History icons use the default palette, CHis tory, to map onto the 22nd and
23rd entries in the standard dialog box palette.
1 2
THistoryViewer Dialogs
THistoryViewer is a rather straightforward descendant of TListViewer. It is
used by the history list system, and appears inside the history window set
up by clicking on the history icon. For details on how THistory,
THistoryWindow, and THistoryViewer cooperate, see the entry for THistory
in this chapter.
Field
Hlstoryld HistoryId: Word; Read only
HistoryID is the ID number of the history list to be displayed in the view.
Methods
Init constructor Init(var Bounds: TRect; AHScrollBar, AVScrollBar: PScrollBar;
AHistoryId: Word);
Initializes the viewer list by first calling TListViewer.Init to set up the
boundaries, a single column, and the two scroll bars passed in
AHScrollBar and AVScrollBar. The view is then linked to a history list,
with the HistoryID field set to the value passed in AHistory. That list is
then checked for length, so the range of the list is set to the number of
Items in the list. The first item in the history list is given the focus, and the
horizontal scrolling range is set to accommodate the widest item in the
list.
See also: TListViewer.lnit
GetPaleHe function GetPalette: PPalette; virtual;
Override: Returns a pointer to the default palette, CHistoryViewer.
Sometimes
GetText function Get Text (Item: Integer; MaxLen: Integer): String; virtual;
Override: Seldom Returns the Item'th string in the associated history list. GetText is called by
the virtual Draw method for each visible item in the list.
See also: TListViewer.Draw, HistoryStr function
HandleEvent procedure HandleEvent(var Event: TEvent); virtual;
Override: The history viewer handles two kinds of events itself; all others are passed
Sometimes to TListViewer.HandleEvent. Double clicking or pressing the Enter key will
terminate the modal state of the history window with a cmOK command.
Pressing the Esc key, or any cmCancel command event, will cancel the
history list selection.
See also: TListViewer.HandleEvent
HlstoryWidth function HistoryWidth: Integer i
Returns the length of the longest string in the history list associated with
HistoryID.
Palette
History viewer objects use the default palette CHistoryViewer to map onto
the 6th and 7th entries in the standard dialog box palette.
234
CHistoryViewer I
~r===r=9=='====;=!:::y:::!J
Acti ve-------l ivider
Inactive------' '-----:Se 1ected
Focused---------I
THistoryWindow Dialogs
THis tory Window is a specialized descendant of TWindow used for holding
a history list viewer when the user clicks on the history icon next to an
input line. By default, the window has no title and no number. The history
window's frame has a close icon so the window can be closed, but cannot
be resized or zoomed.
For details on the use of history lists and their associated objects, see the
entry for THistory in this chapter.
Field
Viewer Viewer: PListViewer i Read only
Viewer points to a list viewer to be contained in the history window.
Methods
Init constructor Init (var Bounds: TRecti Historyld: Word) i
Calls TWindow.lnit to set up a window with the given bounds, a null title
string, and no window number (wnNoNumber). The TWindow.Flags field is
set to wfClose to provide a close icon, and a history viewer object is created
to show the items in the history list given by HistoryID.
See also: TWindow.Init, THistoryWindow.InitViewer
GetPaleHe function Getpalette: PPalette; virtual;
Override: Returns a pointer to the default palette, CHistoryWindow.
Sometimes
GetSelection function GetSelection: String; virtual;
Override: Never Returns the string value of the focused item in the associated history
viewer.
See also: THistoryViewer.GetText
InitViewer procedure InitViewer (Historyld: Word); virtual;
Override: Never Instantiates and inserts a THistoryViewer object inside the boundaries of
the history window for the list associated with the ID Historyld. Standard
scroll bars are placed on the frame of the window to scroll the list.
See also: THistoryViewer.Init
Palette
History window objects use the default palette CHis tory Window to map
onto the 19th through 25th entries in the standard dialog box palette.
5
TlnputLine Dialogs
Fields
Methods
Init constructor Init (var Bounds: TRect; AMaxLen: Integer);
Creates an input box control with the given argument values by calling
TlnputLine.lnit. State is set to sfCursorVis, Options is set to (ofSelectable +
ofFirstClick), and MaxLen is set to AMaxLen. Memory is allocated and
cleared for AMaxlen+l bytes and the Data field set to point at this
allocation.
See also: TView.Init, TView.sfCursorVis, TView.ofSelectable,
TView.ofFirstClick
III
selected (block marked) characters are drawn with the appropriate
palette.
(;etData procedure GetData(var Ree); virtual;
Override: Writes DataSize bytes from the string Datal\. to given record. Used with
Sometimes TlnputLine.SetData for a variety of applications, e.g., temporary storage or
passing on the input string to other views. Override this method if you
define descendants to handle non-string data types. Use this method to
convert from a string to your data type after editing by TlnputLine.
See also: TlnputLine.DataSize, TlnputLine.SetData
(;etPaleHe function GetPalette: PPalette; virtual;
Override: Returns a pointer to the default palette, ClnputLine.
Sometimes
HandleEvent procedure HandleEvent(var Event: TEvent); virtual;
Override: Calls TView.HandleEvent, then handles all mouse and keyboard events if
Sometimes the input box is selected. This method implements the standard editing
capability of the box.
1=<rl;Mn,..,. ~n"""""' ..nC' ;n,.,l"rl,..,. h1",.,1.- "'"' ......1.-;n,..,. TH;4-h
" , " , " " C O ,.,1;,.,1.- ""nrl ...1 .. "",..,.. "h1("\,...1.-
- -------0 - ---- --- -- ----- ---- -- - -- --- -----------0 - - ---- --- - --- - --- -- - ---- -- --- --0' - - - ---
deletion; insert or overwrite control with automatic cursor shape change;
automatic and manual scrolling as required (depending on relative sizes
of Data string and Size.X); manual horizontal scrolling via mouse clicks on
the arrow icons; manual cursor movement by arrow, Home, and End keys
(and their standard Clrl key equivalents); character and block deletion with
Del and CtrJ-G. The view is redrawn as required and the TlnputLine fields
are adjusted appropriately.
See also: sfCursorlns, TView.HandleEvent, TlnputLine.SelectAll
SelectAIi procedure SelectAll (Enable: Boolean);
Sets CurPos, FirstPos, and SelStart to O. If Enable is set True, SelEnd is set to
Length (Da ta/\) thereby selecting the whole input line; if Enable is set False,
SelEnd is set to 0, thereby deselecting the whole line. Finally, the view is
redrawn by calling DrawView.
See also: TView.DrawView
SetOata procedure SetData(var Rec)i virtual;
Override: By default, reads DataSize bytes from given record to the Data/\ string and
Sometimes
calls SelectAll(True) to reset CurPos, FirstPos, and SelStart to zero; SelEnd is
set to the last character of Data/\ and the view is DrawView' d. Override
this method if you define descendants to handle non-string data types.
Use this method to convert your data type to a string for editing by
TlnputLine.
See also: TlnputLine.DataSize, TlnputLine.GetData, TView.DrawView
SetState procedure SetState(AState: Word; Enable: Boolean); virtual;
Override: Seldom Called when the input box needs redrawing (for example, palette
changes) following a change of State. Calls TView.SetState to set or clear
the view's State field with the given AState bit(s). Then if AState is sfSelected
or if AState is sfActive and the input box is sfSelected, SelectAll(Enable) is
called.
See also: TView.SetState, TView.DrawView
Store procedure Store(var S: TStream);
Stores the view on the given stream by calling TView.Store(S), then stores
the five integer fields and the Data string with S. Write calls. Used in
conjunction with TlnputLine.Load for saving and restoring entire
TlnputLine objects. Override this method if you define descendants that
contain additional fields.
See also: TView.Store, TlnputLine.Load, TStream. Write
Palette
Input lines use the default palette, ClnputLine, to map onto the 19th
through 21st entries in the standard dialog palette.
Passiv Arrow
Aeti ve--------' '----:Se 1eeted
TLabel Dialogs
Methods
Init constructor Init (var Bounds: TRect; AText: String; ALink: PView);
Creates a TLabel object of the given size by calling TStaticText.lnit, then
sets the Link field to Alink for the associated control (make ALink nil if no
control is needed). The Options field is set to ofPreProcess and ofPostProcess.
The EventMask is set to evBroadcast. The AText field is assigned to the Text
field by TStaticText.Init. AText can designate a shortcut letter for the label
by surrounding the letter with tildes (/ .... /).
See also: TStaticText.lnit
Load constructor Load (var S: TStrearn);
Creates and loads a TLabel object from the given stream by calling
TStaticText.Load, then calling GetPeerViewPtr(S, Link) to reestablish the link
to the associated control (if any).
See also: TLabel.Store
Draw procedure Draw; virtual;
Override: Never Draws the view with the appropriate colors from the default palette.
GetPalette function Getpalette: PPalette; virtual;
Override: Returns a pointer to the default palette, CLabel.
Sometimes
HandleEvent procedure HandleEvent (var Event: TEvent); virtual;
Override: Never Handles all events by calling TStaticText.HandleEvent. If an evMouseDown
or shortcut key event is received, the appropriate linked control (if any) is
selected. This method also handles cmReceivedFocus and cmReleasedFocus
broadcast events from the linked control in order to adjust the value of the
Light field and redraw the label as necessary.
See also: TView.HandleEvent, cmXXXX command constants
Store procedure Store(var S: TStream);
Stores the view on the given stream by calling TStaticText.Store, then
records the link to the associated control by calling PutPeerViewPtr.
See also: TLabel.Load
Palette
Labels use the default palette, CLabel, to map onto the 7th, 8th and 9th
entries in the standard dialog palette.
234
CLabel
TListBox Dialogs
Field
List List: PCollection; Read only
List points at the collection of items to scroll through. Typically, this might
be a collection of PStrings representing the item texts.
Methods
Inlt constructor Init(var Bounds: TRect; ANumCols: Word; AScrollBar:
PScrollBar) ;
Creates a list box control with the given size, number of columns, and a
vertical scroll bar referenced by the AScrollBar pointer. This method calls
TListViewer.Init with a nil horizontal scroll bar argument.
The List field is initially nil (empty list) and the inherited Range field is set
to zero. Your application must provide a suitable TCollection holding the
strings (or other objects) to be listed. The List field must be set to point to
this collection using NewList.
See also: TListViewer.Init, TListBox.NewList
Load constructor Load (var S: TStream);
Creates a TListBox object and loads it with values from the given TStream.
This method calls TListViewer.Load then sets List by reading a List pointer
from S with S.Get.
See also: TListViewer.Load, TListBox.Store, TStream.Get
DataSize . function DataSize: Word; virtual;
Override: Returns the size of the data read and written to the records passed to
Sometimes
TListBox.GetData and TListBox.SetData. These three methods are useful for
initializing groups. By default TListBox.DataSize returns the size of a
pointer plus the size of a word (for the List and the selected item). You
may need to override this method for your own applications.
See also: TListBox.GetData, TListBox.SetData
GetData procedure GetData(var Rec); virtual;
Override: Writes TListBox object data to the target record. By default, this method
Sometimes
writes the current List and Focused fields to Rec. You may need to override
this method for your own applications.
See also: TListBox.DataSize, TListBox.SetData
GetText function GetText(Item: Integer; MaxLen: Integer): String; virtual;
Override: Returns a string from the calling TListBox object. By default, the returned
Sometimes
string is obtained from the Jtem'th item in the TCollection using
PString(List".At(Item»". If List contains non-string objects, you will need
to override this method. If List is nil, Get Text returns an empty string.
Store
See also: TListBox.DataSize, TListBox.GetData, TListBox.NewList
procedure Store(var s: TStream)i
Writes the list box to the given TStream by calling TListViewer.Store and
I
then puts the collection onto the stream by calling S.Put(List).
See also: TListBox.Load, TListViewer.Store, TStream.Put
Palette
List boxes use the default palette, CListViewer, to map onto the 26th
through 29th entries in the standard application palette.
1 2 3 4 5
CLi stVi ewer I 26 I 26 I 27 I 28 I 20
Active-e_ _----II I I I ~lvider
~~~~~!~e I L----:)e I ectea
TListViewer Views
The TListViewer object type is essentially a base type from which to derive
list viewers of various kinds, such as TListBox. TListViewer's basic fields
and methods offer the following functionality:
• A view for displaying linked lists of items (but no list)
• Control over one or two scroll bars
• Basic scrolling of lists in two dimensions
• Loading and storing the view and its scroll bars from and to a TStream
• Ability to mouse or key select (highlight) items on list
• Draw method that copes with resizing and scrolling
TListViewer has an abstract GetText method, so you need to supply the
mechanism for creating and manipulating the text of the items to be
displayed.
TListViewer has no list storage mechanism of its own. Use it to display
scrollable lists of arrays, linked lists, or similar data structures. You can
also use its descendants, such as TListBox, which associates a collection
with a list viewer.
Fields
HScrollBar HScrollBar: PScrollBari Read only
Pointer to the horizontal scroll bar associated with this view. If nil, the
view does not have such a scroll bar.
VScrollBar VScrollBar: PScrollBar i Read only
Pointer to the vertical scroll bar associated with this view. If nil, the view
does not have such a scroll bar.
NumCols NumCols: Integer i Read only
Methods
Init constructor Init(var Bounds: TRect; ANurnCols: Integer; AHScrollBar,
AVScrollBar: PScrollBar);
Creates and initializes a TListViewer object with the given size by first
calling TView.lnit. The NumCols field is set ANumCols. Options is set to
(ofFirstClick + ofSelectable) so that mouse clicks that select this view will be
passed first to TListViewer.HandleEvent. The EventMask is set to evBroadcast.
The initial values of Range and Focused are zero. Pointers to vertical
and/or horizontal scroll bars can be supplied via the A VScrollBar and
AHScrollBar arguments. Set either or both to nil if you do not want scroll
bars. These two pointer arguments will be assigned to the VScrollBar and
HScrollBar fields.
If you provide valid scroll bars, their PgStep and ArStep fields will be
adjusted according to the TListViewer size and number of columns. For a
single-column TListViewer, for example, the default vertical PgStep is
Size. Y - 1, and the default vertical ArStep is 1.
See also: TView.Init, TScrollBar.SetStep
Load constructor Load (var S: TStrearn);
selects the currently focused item; the arrow keys, PgUp, PgDn, Ctrl-PgDn,
Ctrl-PgUp, Home, and End keys are tracked to set the focused item. Finally,
broadcast events from the scroll bars are handled by changing the focused
item and redrawing the view as required.
See also: TView.HandleEvent, TListViewer.FocusItem
Selectltem procedure SelectItem (Item: Integer); virtual;
Override: An abstract method for selecting the item indexed by Item.
Sometimes
See also: TListViewer.FocusItem
SetRange procedure SetRange (ARange: Integer);
Sets the Range field to ARange. If a vertical scroll bar has been assigned, its
parameters are adjusted as necessary. If the currently focused item falls
outside the new Range, the Focused field is set to zero.
See also: TListViewer.Range, TScrollBar.SetParams
SetState procedure SetState(AState: Word; Enable: Boolean); virtual;
Override: Seldom Calls TView.SetState to change the TListViewer object's state if Enable is
True. Depending on the AState argument, this can result in displaying or
hiding the view. Additionally, if AState is sfSelected and sfActive, the scroll
bars are redrawn; if AState is sfSelected but not sfActive, the scroll bars are
hidden.
See also: TView.SetState, TScrollBar.Show, TScrollBar.Hide
Store procedure Store(var S: TStream);
Calls TView.Store to save the TListViewer object on the target stream, then
stores the scroll bar objects (if any) using calls to PutPeerViewPtr, and
finally saves the integer fields using S. Write.
See also: TView.Store, TListViewer.Load
Palette
List viewers use the default palette, CListViewer, to map onto the 26th
through 29th entries in the standard application palette.
CListViewer
Active----' ivider
Inactive-----i Selected
Focused---------'
TMenuBar Menus
TMenuBar objects represent the horizontal menu bars from which menu
selections can be made by:
• direct clicking
• F10 selection and shortcut keys
• selection (highlighting) and pressing Enter
• hot keys
The main menu selections are displayed in the top menu bar. This is
represented by an object of type TMenuBar usually owned by your
TApplication object. Submenus are displayed in objects of type TMenuBox.
Both TMenuBar and TMenuBox are descendants of the abstract type
TMenuView (a child of TView).
For most Turbo Vision applications, you will not be involved directly with
menu objects. By overriding TApplication.InitMenuBar with a suitable set
of nested New, NewSubMenu, NewItem and NewLine calls, Turbo Vision
takes care of it.
Methods
Init constructor Init (var Bounds: TRecti AMenu: PMenu) i
Creates a menu bar with the given Bounds by calling TMenuView.lnit. The
grow mode is set to gfGrowHiX. The Options field is set to ofPreProcess to
allow hot keys to operate. The Menu field is set to AMenu, providing the
menu selections.
See also: TMenuView.Init, gfXXXX grow mode flags, ofXXXX option flags,
TMenuView.Menu
Draw procedure Draw; virtual;
Override: Seldom Draws the menu bar with the default palette. The Name and Disabled fields
of each TMenultem record in the linked list are read to give the menu
legends in the correct colors. The Current (selected) item is highlighted.
GetltemRect procedure GetItemRect (Item: PMenuItem; var R: TRect); virtual;
Override: Never. Overrides the abstract method in TMenuView. Returns the rectangle
occupied by the given menu item in R. It is used to determine if a mouse
click has occurred on a given menu selection.
See also: TMenuView.GetItemRect
Palette
Menu bars, like all menu views, use the default palette CMenu View to
map onto the 2nd through 7th entries in the standard application palette.
1 2 3 4 5 6
~ I I I I
~
CMenuVfew 3 4 5
Text Normal
Text Disabled I I I Se1ected Shortcut
Selected Disabled
Text Shortcut Selected Normal
TMenuBox Menus II
Methods
Init constructor Init(var Bounds: TRect; AMenu: PMenui AParentMenu:
PMenuView) ;
Init adjusts the Bounds parameter to accommodate the width and length of
the items in AMenu, then creates a menu box by calling TMenuView.lnit.
The ofPreProcess bit in the Options field is set so that hot keys will operate.
State is set to include sfShadow. The Menu field is set to AMenu, which
provides the menu selections. The ParentMenu field is set to AParentMenu.
See also: TMenuView.Init, sfXXXX state flags, ofXXXX option flags,
TMenu View.Menu, TMenu View.ParentMenu
Draw procedure Draw; virtual;
Override: Seldom Draws the framed menu box and menu items in the default colors.
GetltemRect procedure GetIternRect (Item: PMenuItern; var R: TRect); virtual;
Override: Seldom Overrides the abstract method in TMenuView. Returns the rectangle
occupied by the given menu item. It is used to determine if a mouse click
has occurred on a given menu selection.
See also: TMenuView.GetItemRect
Palette
Menu boxes, like all menu views, use the default palette CMenuView to
map onto the 2nd through 7th entries in the standard application palette.
234 6
CMenuView
Text Normal Se1ected Shortcut
Text Oisabledl-----' Se1ected 01 sab 1ed
Text Shortcut:------' '-----Selected Normal
TMenuView Menus
TMenu View provides an abstract menu type from which menu bars and
menu boxes (either pull-down or pop-up) are derived. You will probably
never instantiate a TMenuView itself.
Fields
ParentMenu ParentMenu: PMenuViewi Read only
A pointer to the TMenuView (or descendant) object that owns this menu.
Note that TMenuView is not a group. Ownership here is a much simpler
concept than TGroup ownership, allowing menu nesting: the selection of
submenus and the return back to the "parent" menu. Selections from
menu bars, for example, usually result in a submenu being "pulled
down." The menu bar in that case is the parent menu of the menu box.
See also: TMenuBox.lnit
Menu Menu: PMenui Read only
A pointer to the TMenu record for this menu, which holds a linked list of
menu items. The Menu pointer allows access to all the fields of the menu
items in this menu view.
See also: TMenuView.FindItem, TMenuView.GetItemRect, TMenu type
Current Current: PMenuItemi Read only
A pointer to the currently selected menu item.
Methods
Init constructor Init (var Bounds: TRect);
Calls TView.lnit to create a TMenuView object of size Bounds. The default
EventMask is set to evBroadcast. This method is not intended to be used for
instantiating TMenu View objects. It is designed to be called by its
descendant types, TMenuBar and TMenuBox.
See also: TView.lnit. evBroadcast. TMenuBar.lnit. TMenuBox.lnit
Load constructor TMenuView.Load(var s: TStream)i
Creates a TMenu View object and loads it from the stream S by calling
TView.Load and then loading the items in the menu list.
See also: TView.Load, TMenu View. Store
Execute function Execute: Wordi virtuali
Override: Never Executes a menu view until the user selects a menu item or cancels the
process. Returns the command assigned to the selected menu item, or
zero if the menu was canceled. This method should never be called except
by ExecView.
See also: TGroup.ExecView
Findlfem function FindItem(Ch: Char): PMenuItem;
Returns a pointer to the menu item that has Ch as its shortcut key (the
highlighted character). Returns nil if no such menu item is found or if the
menu item is disabled. Note that Ch is case-insensitive.
GetltemRect procedure GetItemRect (Item: PMenuItem; var R: TRect); virtual;
Override: Always This method returns the rectangle occupied by the given menu item in R.
It is used to determine if a mouse click has occurred on a given menu
selection. Descendants of TMenuView must override this method in order
to respond to mouse events.
See also: TMenuBar.GetItemRect, TMenuBox.GetItemRect
GetHelpCtx function GetHelpCtx: Word; virtual;
Override: By default, this method retuIns the help context of the current menu
Sometimes selection. If this is hcNoContext, the parent menu's current context is
checked. If there is no parent menu, GetHelpCtx returns hcNoContext.
See also: hcXXXX help context constants
GetPaleHe function GetPalette: PPalette; virtual;
Override: Returns a pointer to the default CMenuBar palette.
Sometimes
HandleEvent procedure HandleEvent (var Event: TEvent); virtual;
Override: Never Called whenever a menu event needs to be handled. Determines which
menu item has been mouse or keyboard selected (including hot keys) and
generates the appropriate command event with PutEvent.
See also: TView.HandleEvent, TView.PutEvent.
HotKey function HotKey(KeyCode: Word): PMenultem;
Returns a pointer to the menu item associated with the hot key given by
KeyCode. Returns nil if no such menu item exists, or if the item is disabled.
Hot keys are usually function keys or Alt key combinations, determined by
arguments in NewItem and NewSubMenu calls during InitMenuBar. This
method is used by TMenuView.HandleEvent to determine whether a
keystroke event selects an item in the menu.
Store procedure Store(var s: TStream);
Saves the calling TMenuView object (and any of its submenus) on the
stream S by calling TView.Store and then writing each menu item to the
stream.
See also: TMenuView.Load
Palette
All menu views use the default palette CMenuView to map onto the 2nd
through 7th entries in the standard application palette.
CHennVie.
Text Normal---=:J
Text Disabled
123
QI I I I 3
I
4
I I
r::g5
4 5 6
TObject Objects
II
TObject is the starting point of Turbo Vision's object hierarchy. As the base
object, it has no parents but many descendants. Apart from TPoint and
TRect, in fact, all of Turbo Vision's standard objects are ultimately derived
____ ,..,.,,,,_: __ ,
r._~ __ • • 1 __ • . . ___
A _____ 1_~ ....1 __ ~ r . . -,-,-. or
,,{T!_! _ .• , __ • _
L '-'VJ .........
...... V ..... .A. LJ
.J. .... I;;"........, ... C;.,
VLlJ,.;. .... L L.A.."L U.,,.;.., ... U ... LlV V ... ., ... V .... ., .,L... U.~ ......... L ... IHU~~
Methods
InH constructor Init;
Allocates space on the heap for the object and fills it with zeros. Called by
all derived objects' constructors. Note that TObject.lnit will zero all fields
in descendants, so you should always call TObject.Init before initializing
any fields in the derived objects' constructors.
TParamText Dialogs
TParamText is a derivative of TStaticText that uses parameterized text
strings for formatted output, using the FormatStr procedure.
Fields
ParamCount ParamCount: Integer;
ParamCount indicates the number of parameters contained in ParamList.
See also: TParamText.ParamList
ParamList ParamList: Pointer;
ParamList is an untyped pointer to an array or record of pointers or
Longint values to be used as formatted parameters for a text string.
Methods
Init constructor Init(var Bounds: TRect; AText: String; AParamCount: Integer);
Initializes a static text object by calling TStaticText.lnit with the given
Bounds and a text string, AText, that may contain format specifiers in the
form %[ -] [nnn] x, which will be replaced by the parameters passed at run-
time. The parameter count, passed in AParamCount, is assigned to the
ParamCount field. Format specifiers are described in detail in the entry for
the FormatStr procedure.
See also: TStaticText.Init, FormatStr procedure
Load constructor Load (var S: TStream);
Allocates a TParamText object on the heap and loads its value from the
stream S by first calling TStaticText.Load and then reading the ParamCount
field from the stream.
See also: TStaticText.Load
DataSize function DataSize: Word; virtual;
Returns the size of the data required by the object's parameters, that is,
ParamCount * SizeOf(Longint).
c;etText procedure GetText(var S: String); virtual;
Produces a formatted text string in S, produced by merging the
parameters contained in ParamList into the text string in Text, using a call
to FormatStr(S, TextA, ParamUstA).
See also: FormatStr procedure
SetOata procedure SetData(var Rec); virtual;
The view reads DataSize bytes into ParamList from Rec.
See also: TView.SetData
Store procedure Store(var s: TStream)i
Stores the object on the stream S by first calling TStaticText.Store and then
writing the ParamCount field to the stream.
See also: TStaticText.Store
Palette
TParamText objects use the default palette CStaticText to map onto the
sixth entry in the standard dialog palette.
CStaticText
Text
/1 ~ II
I
TPoint Objects
TPoint is a simple object representing a point on the screen.
Fields
X x: Integer
X is the screen column of the point.
Y Y: Integer
Y is the screen row of the point.
TProgram App
TProgram provides the basic template for all standard Turbo Vision
applications. All such programs must be derived from TProgram or its
child, TApplication. TApplication differs from TProgram only in its default
constructor and destructor methods. Both object types are provided for
added flexibility when designing nonstandard applications. For most
Turbo Vision work, your program will be derived from T Application.
TProgram is a TGroup derivative since it needs to contain your TDeskTop,
TStatusLine, and TMenuBar objects
Methods
Init constructor Init;
Override: Sets the Application global variable to @Self; calls TProgram.InitScreen to
Sometimes initialize screen mode dependent variables; calls TGroup.lnit passing a
Bounds rectangle equal to the full screen; sets the State field to sfVisible +
sfSelected + sfFocused + sfModal + sfExposed; sets the Options field to zero;
sets the Buffer field to the address of the scre~n buffer given by
ScreenBuffer; and finally calls InitDeskTop, InitStatusLine, and InitMenuBar,
and inserts the resulting views into the TProgram group.
See also: TGroup.lnit, TProgram.InitDeskTop, TProgram.InitStatusLine,
TProgram.lnitMenuBar
Done destructor Done; virtual;
Override: Disposes the DeskTop, MenuBar, and StatusLine objects, and sets the
Sometimes
Application global variable to nil.
See also: TGroup.Done
(;etEvent procedure GetEvent(var Event: TEvent); virtual;
Override: Seldom The default TView.GetEvent simply calls its owner's GetEvent, and since a
TProgram (or TApplication) object is the ultimate owner of every view,
every GetEvent call will end up in TProgram.GetEvent (unless some view
along the way has overridden GetEvent).
TProgram.GetEvent first checks if TProgram.PutEvent has generated a
pending event; if so, GetEvent returns that event. If there is no pending
event, GetEvent calls GetMouseEvent; if that returns evNothing, it then calls
GetKeyEvent. If both return evNothing, indicating that no user input is
available, GetEvent calls TProgram.Idle to allow "background" tasks to be
performed while the application is waiting for user input. Before
returning, GetEvent passes any evKeyDown and evMouseDown events to the
StatusLine for it to map into associated evCommand hot key events.
See also: TProgram.PutEvent, GetMouseEvent, GetKeyEvent
HandleEvent
Override: Always
procedure HandleEvent (var Event: TEvent); virtual;
Handles Alt-1 through AIt-9 keyboard events by generating an evBroadcast
event with a Command value of cmSelect WindowNum and an InfoInt value
of 1..9. TWindow.HandleEvent reacts to such broadcasts by selecting the
II
window if it has the given number.
Handles an evCommand event with a Command value of cmQuit by calling
EndMndal{r.mOuitL whiC'h in pffprt tprmin::ltp~ thp ::lnnlir::ltinn.
Palettes
The palette for an application object controls the final color mappings for
all views in the application. All other palette mappings eventually result
in the selection of an entry in the application's palette, which provides text
attributes.
The first entry is used by TBackground for the background color. Entries 2
through 7 are used by both menu views and status lines.
23456
CColor 1$71 1$70 1$78 1$74 1$20 1$28 1$24 I
I I
CBlackWhite 1$70 I$70 I$78 I$7F I$07 I$07 I$OF I
I I
CMonochrome I I I I I I I
1$70 $07 $07 $OF $70 $70 $70
Background~
I I I l
L-s hortcut sel ecti on
Normal Tex t
Disabled Text
I ..ormal
-" isabled selection
selection
Shortcut t ext
CMonochrome
Frame Passi v eserved
Frame Activ Scroller Selected Text
Frame Icon Scroller Normal Text
Scroll Bar Page Scroll Bar Reserved
16 17 18 19 20 21 22 23
CColor I
1$37 1$3F 1$3A 1$13 1$13 1$3E 1$21 1$00
I I
CBlackWhit e 1$07 I$OF I$07 I$70 I$70 I$07 I$70 I$00 I
I I
CMonochrome 1$07 I$OF I$07 I$70 I$70 I$07 I$70 I$00 I
Frame Pass ive-J
I L=:Scroller
Reserved
I
Frame Actf v_
Frame Icon I I I
Selected Text
Scroller Normal Text
Scroll Bar Pag Scro 11 Bar Reserved
Entries 32 through 63 are used by dialog box objects. See TDialog for
individual entries.
32 33 34 35 36 37 38 39 40
CColor $70 1$7F 1$7A 1$13 1$13 1$70 1$70 1$7F IS7E
CBlackWhit e
CMonochrome
Frame Pass iv
I
1$70 1$7F 1$7F 1$70 1$07 1$70 1$70 1$7F IS7F
I I I I I I I I I
1$70 $70 $70 $07 $07 $70 $70 $70 $7F
I
I
I I
L-ILabel Shortcut
I
I
I
I I
Frame Acti v Label Highlight
Frame Icon
Scroll Bar Page
Scroll Bar Controls
I Label Normal
StaticText
41 42 43 44 45 46 47 48 49
CColor 11~?n I~?R I~?F I~7R I~?F It7n 1(':10 I(':IF I(':IF I
II
CBlackWhite S07 I$OF I$OF I$78 I$OF I$78 I$07 I$OF I$OF
I I
CMonochrome I I I I I I I I I
1$07 $07 $OF $70 $OF $70 $07 $OF $OF
I ~ 11uster
I I
Button Normal Shortcut
Button
Button
Button
Button
Oefaul t
Sel ect ed
Oi sabl ed
Shortc ut
I I I uster Selected
,. luster Normal
;;
utton Shadow
50 51 52 53 54 55 56
CColor I I I I I I I
I$IF $2F $1A $20 $72 $31 $31
I I
CBlackWh1te I$OF I$70 I$OF I$07 I$70 I$70 I$70 I
I I
CMonochrome 1$07 I$70 I$07 I$07 I$70 I$07 I$07 I
Inputlfne No nnal
I l ~1istoryW1ndow Scroll Bar controls
Inputlfne Se lecte:!
InputLine Ar rows
H1 story Arro
I I I storyW1 ndow Scroll Bar
u
i story S1 des
page
57 58 59 60 61 62 63
CColor /$30 1$2F IS3E 1$31 1$13 1$00 1$00 I
I I
CBlackWhite I I I I I
1$07 S70 $OF $07 $07 $00 1$00 !
CMonochrome
If stVi ewer Nonna1 eserved
If stVi ewer Focused,------' '----R'eserved
ListViewer Selectedl------' '------InfoPane
L1stV1ewer Divider---------'
TRadioButtons Dialogs
Methods
Draw procedure Draw; virtual;
Override: Seldom Draws buttons as" ( ) "surrounded by a box.
~ark function Mark(Item: Integer): Boolean; virtual;
Overide: Never Returns True if Item = Value, that is, if the Item'th button represents the
current Value field (the "pressed" button).
See also: TCluster.Value, TCluster.Mark
~ovedTo procedure MovedTo (Item: Integer); virtual;
Override: Never Assigns Item to Value.
See also: TCluster.MovedTo, TRadioButtons.Mark
Press procedure Press(Item: Integer); virtual;
Override: Never Assigns Item to-Value. Called when the Item'th button is pressed.
SetData procedure SetData(var Rec); virtual;
Override: Seldom Calls TCluster.SetData to set the Value field, then sets Sel field equal to
Value, since the selected item is the "pressed" button at startup.
See also: TCluster.SetData
Palette
TRadioButtons objects use CCluster, the default palette tor all cluster
I
objects, to map onto the 16th through 18th entries in the standard dialog
palette.
123 4
CCluster 1116 117 118 118 II
Text Normal--=:J
Text Selected
I iF_nShortcut Selected
~Shortcut Normal
TRect Objects
Fields
A A: TPoint
A is the point defining the top left corner of a rectangle on the screen.
B B: TPoint
B is the point defining the bottom right corner of a rectangle on the screen.
Methods
Assign procedure Assign (XA, YA, XB, YB: Integer);
This method assigns the parameter values to the rectangle's point fields.
XA becomes A.X, XB becomes X.B, etc.
Copy procedure Copy (R: TRect);
Copy sets all fields equal to those in rectangle R.
Move procedure Move (ADX, ADY: Integer);
Moves the rectangle by adding ADX to A.X and B.X and adding ADY to
A.YandB.Y.
Grow procedure Grow(ADX, ADY: Integer);
Changes the size of the rectangle by subtracting ADX from A.X, adding
ADX to B.X, subtracting ADY from A.Y, and adding ADY to B.Y.
Intersect procedure Intersect (R: TRect);
Changes the location and size of the rectangle to the region defined by the
intersection of the current location and that of R.
Union procedure Union (R: TRect);
Changes the rectangle to be the union of itself and the rectangle Ri that is,
to the smallest rectangle containing both the object and R.
Contains function Contains(P: TPoint): Boolean;
Returns true if the rectangle contains the point P.
Equals function Equals (R: TRect): Boolean;
TResourceColiection Objects
TResourceCollection type) along with the position and size of the resource
data in the resource file.
As is the case with streams, the types of objects written to and read from
resource files must have been registered using RegisterType.
Fields
Stream Stream: PStream; Read only
Pointer to the stream asso~iated with this resource file
Modified Modified: Boolean; Read/write
Set True if the resource file has been modified.
See also: TResourceFile.Flush
Methods
Init constructor Init (AStream: PStream);
Override: Never Initializes a resource file using the stream given by AStream and sets the
Modified field to False. The stream must have already been initialized. For
example:
ResFile.lnit(New(TBufStream, Init('MYAPP.RES', stOpenRead, 1024)));
During initialization, Init will look for a resource file header at the current
position of the stream. The format of a resource file header is
type
TResFileHeader = record
Signature: array[1 .. 4] of Char;
ResFileSize: Longint;
IndexOffset: Longint;
end;
where Signature contains 'FBPR', ResFileSize contains the size of the entire
resource file excluding the Signature and ResFileSize fields (i.e. the size of
the resource file minus 8 bytes), and IndexOffset contains the offset of the
index collection from the beginning of the header.
If Init does not find a resource file header at the current position of
AStream, it assumes that a new resource file is being created, and thus
instantiates an empty index.
If Init sees an .EXE file signature at the current position of the stream, it
seeks the stream to the end of the .EXE file image, and then looks for a
resource file header there. Likewise, Init will skip over an overlay file that
was appended to the .EXE file (as will Ovrlnit skip over a resource file).
This means that you can append both your overlay file and your resource
file (in any order) to the end of your application's .EXE file. (This is, in fact,
what the IDE's executable file, TURBO.EXE, does.)
See also: TResourceFile.Done
Done destructor Done; virtual;
Override: Never Flushes the resource file, using TResourceFile.Flush, and then disposes of
the index and the stream given by the Stream field.
See also: TResourceFile.lnit, TResourceFile.Flush
Count function Count: Integer;
Returns the number of resources stored in the calling resource file.
See also: TResourceFile.KeyOf
Delete procedure Delete(Key: String);
Deletes the resource indexed by Key from the calling resource file. The
space formerly occupied by the deleted resource is not reclaimed. You can
reclaim this memory by using SwitchTo to create a packed copy of the file
on a new stream.
See also: TResourceFile.SwitchTo
Flush procedure Flush;
If the resource file has been modified (checked using the Modified field),
Flush stores the updated index at the end of the stream and updates the
resource header at the beginning of the stream. It then resets Modified to
False.
See also: TResourceFile.Done, TResourceFileModified
Get function Get (Key: String): PObject;
Searches for the given Key in the resource file index. Returns nil if the key
is not found. Otherwise, seeks the stream to the position given by the
index, and calls StreamA.Get to create and load the object identified by Key.
An example:
DeskTopA.lnsert(ValidView(ResFile.Get('EditorWindow')));
See also: TResourceFile.KeyAt, TResourceFile.Put
KeyAf function KeyAt (I: Integer): String;
Returns the string key of the I'th resource in the calling resource file. The
index of the first resource is zero and the index of the last resource is
TResourceFile.Count minus one. Using Count and KeyAt you can iterate
over all resources in a resource file.
See also: TResourceFile.Count
Put procedure Put (Item: PObject; Key: String);
Adds the object given by P to the resource file with the key string given by
Key. If the index already contains the Key, then the new object replaces the
old object. The object is appended to the existing objects in the resource
file using Streaml\.Put.
See also: TResourceFile.Get
SwitchTo function SwitchTo (AStream: PStreami Pack: Boolean): PStreami
Switches the resource file from the stream it is on to the stream passed in
AStream, and returns a pointer to the original stream as a result.
If the Pack parameter is True, the stream will eliminate empty and unused
space from the resource file before writing it to the new stream. Thisis the
only way to compress resource files. Copying with the Pack parameter
False, however, provides faster copying, but without the compression.
TScroliBar Views
Fields
Value Value: Integer; Read only
The Value field represents the current position of the scroll bar indicator.
This specially colored marker moves along the scroll bar strip to indicate
the relative position (horizontally or vertically depending on the scroll bar
orientation) of the scrollable text being viewed relative to the total text
available for scrolling. Many events can directly or indirectly change
Value, such as mouse clicking on the designated scroll bar parts, resizing
-Ii
ArStep is the amount added or subtracted to the scroll bar's Value field
when an arrow area is clicked (sbLeftArrow, sbRightArrow, sbUpArrow, or
"hn"7""'" Ll ......"7"'1 ,.... ....."h" "rf":;"T ... l,..~ ... l/"'''T ........ ,....l/,.. .......... rI,.. 'T'C,....."l1"R"' ... T'M;~ ... ,.. ......
- - - - -- .. - _ .. - --, - - ---- --1---' ------- --- J - -- - - - - --------. - - -. - ----- •• -. --- - - - -
ArStep to 1 by default.
See also: TScrollBar.SetStep, TScrollBar.SetParam, TScrollBar.ScrollStep
Methods
to 1. The shapes of the scroll bar parts are set to the defaults in
TScrollChars.
If Bounds produces Size.X = 1, you get a vertical scroll bar; otherwise, you
get a horizontal scroll bar. Vertical scroll bars have the GrowMode field set
to gfGrowLoX + gfGrowHiX + gfGrowHiY; horizontal scroll bars have the
GrowMode field set to gfGrowLoY + gfGrowHiX + gfGrowHiY;
Load constructor Load (var S: TStream);
Creates then loads the scroll bar on the stream S by calling TView.Load and
then T('ading the five integer fields with S.Read.
See also: TScrollBar.Store
Dravv procedure Draw; virtual;
Overide: Never Draws the scroll bar depending on the current Bounds, Value and palette.
See also: TScrollBar.ScrollDraw, TScrollBar.Value
GetPaleHe function GetPalette: PPalette; virtual;
Override: Returns a pointer to CScrollBar, the default scroll bar palette.
Sometimes
HandleEvent procedure HandleEvent (var Event: TEvent); virtual;
Override: Never Handles scroll bar events by calling TView.HandleEvent then analyzing
Event. What. Mouse events are broadcast to the scroll bar's owner (see
Message function) which must handle the implications of the scroll bar
changes (for example, by scrolling text). TScrollBar.HandleEvent also
determines which scroll bar part has received a mouse click (or equivalent
keystroke). The Value field is adjusted according to the current ArStep or
PgStep values and the scroll bar indicator is redrawn.
See also: TView.HandleEvent
ScroliDraw procedure ScrollDraw; virtual;
Override: Seldom ScrollDraw is called whenever the Value field changes. This pseudo-
abstract methods defaults by sending a cmScrollBarChanged message to the
scroll bar's owner:
Message (Owner, evBroadcast, cmScrollBarChanged, @Self);
PgStep. The Part argument should be one of the sbXXXX scroll bar part
constants described in Chapter 14.
See also: TScrollBar.SetStep, TScrollBar.SetPara"ms
SetParanns procedure SetParams(AValue, AMin, AMax, APgStep, AArStep: Integer);
SetParams sets the Value, Min, Max, PgStep, and ArStep fields with the
given argument values. Some adjustments are made if your arguments
conflict. For example, Min cannot be set higher than Max, so if AMax <
AMin, Max is set to AMin. Value must lie in the closed range [Min,Max], so
if AValue < AMin, Value is set to AMin; and if AValue > AMax, Value is set
to AMax. The scroll bar is redrawn by calling DrawView. If Value is
changed, ScrollDraw is also called.
See also: TView.DrawView, TScrollBar.ScrollDraw, TScrollBar.SetRange,
TScrollBar.Set Value
SetRange procedure SetRange (AMin, AMax: Integer);
SetRange sets the legal range for the Value field by setting Min and Max to
the given arguments AMin and AMax. SetRange calls SetParams, so
DrawView and ScrollDraw will be called if the changes require the scroll
bar to be redrawn.
See also: TScrollBar.SetParams
SetStep procedure SetStep (APgStep, AArStep: Integer);
SetStep sets the fields PgStep and ArStep to the given arguments APgStep
and AArStep. This method calls SetParams with the other arguments set to
their current values.
See also: TScrollBar.SetParams, TScrollBar.ScrollStep
-It;
SetValue procedure SetValue (AValue: Integer);
SetValue sets the Value field to A Value by calling SetParams with the other
_~ o. ,_ f'. 0-" _
_ .1 _ _ ,.,.. .. __ ~ ._T7~ __ . _ _ _ , 1"""_ ••• 11T"""\. ___ . _____ !111._
UJ.5UJ.J.L\':;J.LL~ ~CL LV LJ.LCJ.J. '-UJ.J.CJ.LL VUJ.UC~. vc
L.JIULV" £I'LV UJ.LU ..... L..IUUL.JIULV VVJ.J.J.
Palette
Scroll bar objects use the default palette, CScrollBar, to map onto the 4th
and 5th entries in the standard application palette.
2 3
CScrol1Bar
ll=;;==!==;='=;::dJ
Page------' Indicator
Arrows------J
TScrolier Views
Fields
HScrollBar HScrollBar: PScrollBar i Read only
HScrollBar points to the horizontal scroll bar associated with the scroller. If
there is no such scroll bar, HScrollBar is nil.
VScrollBar VScrollBar: PScrollBar; Read only
VScrollBar points to the vertical scroll bar associated with the scroller. If
there is no such scroll bar, VScrollBar is nil.
Delta Delta: TPoint; Read only
Delta holds the X (horizontal) and Y (vertical) components of the scroller's
position relative to the virtual view being scrolled. Automatic scrolling is
achieved by changing either or both of these components in response, for
example, to scroll bar events that change the Value field(s). Conversely,
manual scrolling changes Delta, triggers changes in the scroll bar Value
fields, and leads to updating of the scroll bar indicators.
Methods
Init constructor Init(var Bounds: TRect; AHScrollBar, AVScrollBar:
PScrollBar) ;
Creates and initializes a TScroller object with the given size and scroll bars.
Calls TView.Init to set the view's size. Options is set to ofSelectable and
EventMaskis set to evBroadcast. AHScrollBar should be nil if you do not
want a horizontal scroll bar; similarly AVScrollBar should be nil if you do
not want a vertical scroll bar.
See also: TView.Init, TView.Options, TView.EventMask
Load constructor Load (var S: TStream);
Loads the scroller view from the stream S by calling TView.Load, then
restores pointers to the scroll bars using GetPeerViewPtr, and finally reads
the Delta and Limit fields using S.Read.
See also: TScroller.Store
Change Bounds procedure ChangeBounds (var Bounds: TRect); virtual;
Override: Never Changes the scroller's size by calling SetBounds. If necessary, the scroller
-IIi1
and scroll bars are then redrawn by calling DrawView and SetLimit.
See also: TView.SetBounds, TView.DrawView, TScroller.SetLimit
Getpalene function GetPalette: PPalette; virtual;
Override: Returns a pointer to CScroller, the default scroller palette.
Sometimes
HandleEvent procedure HandleEvent (var Event: TEvent); virtual;
Override: Seldom Handles most events by calling TView.HandleEvent. Broadcast events with
the command cmScrollBarChanged, if they come from either HScrollBar or
VScrollBar, result in a call to TScroller.ScrollDraw.
See also: TView.HandleEvent, TScroller.ScrollDraw
Scro"Oraw procedure ScrollDraw; virtual;
Override: Never Checks to see if Delta matches the current positions of the scroll bars. If
not, Delta is set to the correct value and DrawView is called to redraw the
scroller.
See also: TView.DrawView, Tscroller.Delta, Tscroller.HscrnHBar,
Tscroller. VscrollBar
ScroliTo procedure ScrollTo (X, Y: Integer);
Sets the scroll bars to (X,Y) by calling HscrollBar/\.setValue(X) and
VscrollBar/\.setValue(Y), and redraws the view by calling DrawView.
See also: TView.DrawView, Tscroller.setValue
SetLimit procedure SetLimit (X, Y: Integer);
Sets Limit.X to X and Limit.Y to Y, then calls HscrollBar/\.setParams and
VscrollBar/\ .setParams (if these scroll bars exist) to adjust their Max
field(s). These calls may trigger scroll bar redraws. Finally, DrawView is
invoked to redraw the scroller if necessary.
See also: Tscroller.Limit, Tscroller.HscrollBar, Tscroller. VscrollBar,
TscrollBar.setParams
SetState procedure SetState(AState: Word; Enable: Boolean); virtual;
Override: Seldom This method is called whenever the scroller's state changes. Calls
TView.setstate to set or clear the state flags in Astate. If the new state is
sfSelected and sfActive, setstate displays the scroll bars, otherwise they are
hidden.
See also: TView.setstate
Store procedure Store(var S: TStream);
Writes the scroller to the stream 5 by calling TView.store, then stores
references to the scroll bars using PutPeerViewPtr, and finally writes the
values of Delta and Limit using S. Write.
See also: Tscroller.Load, Tstream. Write
Palette
Scroller objects use the default palette, Cscroller, to map onto the 6th and
7th entries in the standard application palette.
CScroller
Nonnal~
1
QI tL
2
ighlight
TSortedColiection Objects
Methods
Compare function Compare (Key!, Key2: Pointer): Integer; virtual;
Override: Always Compare is an abstract method that must be overridden in all descendant
types. Compare should compare the two key values, and return a result as
follows:
-1
(l
1
if Keyl < Key2
;/= Y01,7 - Y01'?
ifK~i >K~2
Keyl and Key2 are pointer values, as extracted from their corresponding
collection items by the TSortedCollection.KeyOf method. The
-Ii
TSortedCollection.Search method implements a binary search through the
collection's items using Compare to compare the items.
See also: TSortedCollection.KeyOf, TSortedCollection.Compare
IndexOf function IndexOf (Item: Pointer): Integer; virtual;
Override: Never Uses TSortedCoIlection.Search to find the index of the given Item. If the item
is not in the collection, IndexOfreturns -1. The actual implementation of
TSortedCollection.IndexOf is:
if Search(KeyOf(Item), I) then IndexOf := I else IndexOf := -1;
See also: TSortedCollection.Search
Insert procedure Insert(Item: Pointer); virtual;
Override: Never If the target item is not found in the sorted collection, it is inserted at the
correct index position. Calls TSortedCollection.Search to determine if the
item exists, and if not, where to insert it. The actual implementation of
TSortedCoIlection.Insert is:
if not Search(KeyOf(Item), I) then AtInsert(I, Item);
See also: TSortedCollection.Search
KeyOf function KeyOf(Item: Pointer): Pointer; virtual;
Override: Given an Item from the collection, KeyOf should return the corresponding
Sometimes key of the item. The default TSortedCollection.KeyOf simply returns Item.
KeyOfis overridden in cases where the key of the item is not the item
itself.
See also: TSortedCollection.IndexOf
Search function Search (Key: Pointer; var Index: Integer): Boolean; virtual;
Override: Seldom Returns True if the item identified by Key is found in the sorted collection.
If the item is found, Index is set to the found index; otherwise Index is set
to the index where the item would be placed if inserted.
See also: TSortedCollection.Compare, TSortedCollection.Insert
TStaticText Dialogs
Field
Text Text: PString; Read only
A pointer to the text string to be displayed in the view.
Methods
Init constructor Init (var Bounds: TRect; AText: String);
Creates a TStaticText object of the given size by calling TView.Init, then
sets Text to NewStr(AText).
See also: TView.Init
Load constructor Load (var s: TStrearn);
Creates and initializes a TStaticText object off the given stream. Calls
TView.Load and sets Text with S.ReadStr. Used in conjunction with
TStaticText.Store to save and retrieve static text views on a stream.
See also: TView.Load,TStaticText.Store, TStream.ReadStr
Done destructor Done; virtual;
Override: Seldom Disposes of the Text string then calls TView.Done to destroy the object.
-iii
Draw procedure Draw; virtual;
Override: Seldom Draws the text string inside the view, word wrapped if necessary. A Ctrl-M
in the text IndIcates the begmning ot a new llne. A llne or text IS centereci
in the view if the line begins with Ctr/~C.
GetPalette function GetPalette: PPalette; virtual;
Override: Returns a pointer to the default palette, CStaticText.
Sometimes
GetText procedure Get Text (var S: String); virtual;
Override: Returns the string pointed to by Text in S.
Sometimes
Store procedure TStaticText.Store(var s: TStream);
Palette
Static text objects use the default palette, CStaticText, to map onto the 6th
entry in the standard dialog palette.
CStatiCTe:t II ~ II
Text colo
TStatusLine Menus
Fields
Items Items: PStatusItem; Read only
A pointer to the current linked list of TStatusItem records.
See also: TStatusItem
Defs Defs: PStatusDefi Read only
A pointer to the current linked list of TStatusDef records. The list to use is
determined by the current help context.
See also: TStatusDef, TStatusLine.Update, TStatusLine.Hint
Methods
Init constructor Init (var Bounds: TRect; ADefs: P'StatusDef);
Creates a TStatusLine object with the given Bounds by calling TView.Init.
The ofPreProcess bit in Options is set, EventMask is set to include
evBroadcast, and GrowMode is set to gfGrowLoY + gfGrowHiX + gfGrowHiY.
The Defs field is set to ADefs. If ADefs is nil, Items is set to nil, otherwise,
Items is set to ADefsA .Items
See also: TView.Init
Load constructor Load (var S: TStream);
Creates a TStatusLine object and loads it from the stream S by calling
TView.Load and then reading the Defs and Items from the stream.
Done
Override: Never
See also:
TView.Done.
TVi~w.Load,
Palette
Status lines use the default palette CStatusLine to map onto the 2nd
through 7th entries in the standard application palette.
2 3 4 5
CStatusLine
TStream Objects
Fields
Status Status: Integer Read/write
Indicates the current status of the stream as follows:
Table 13.1
Stream error codes TStream error codes
stOk No error
stError Access error
stInitError Cannot initialize stream
stReadError Read beyond end of stream
-II
st WriteError Cannot expand stream
stGetError Get of unregistered object type
stPutError Put of unregistered object type
If Status is not stOk all operations on the stream are suspended until Reset
is called.
ErrorInfo contains the VMT data segment offset (the VmtLink field of a
TStreamRec) of the unregistered object type.
Methods
CopyFrom procedure CopyFrom (var S: TStreami Count: Longint);
Copy Count bytes from stream S to the calling stream object. For example:
{Create a copy of entire stream}
NewStream := New(TEmsStream, Init(OldStreamA.GetSize));
OldStreamA.Seek(O);
NewStreamA.CopyFrom(OldStream, OldStreamA.GetSize);
See also: TStream.GetSize, TObject.Init
Error procedure Error(Code, Info: Integer); virtual;
Override: Called whenever a stream error occurs. The default TStream.Error stores
Sometimes
Code and Info in the Status and ErrorInfo fields and then, if the global
variable StreamError is not nil, calls the procedure pointed to by
StreamError. Once an error has occurred, all stream operations on the
stream are suspended until Reset is called.
See also: TStream.Reset, StreamError variable
Flush procedure Flush; virtual;
Override: An abstract method that must be overridden if your descendant
Sometimes
implements a buffer. This method can flush any buffers by clearing the
read buffer, by writing the write buffer, or both. The default TStream.Flush
does nothing.
See also: TDosStream.Flush
Get function Get: PObject;
Reads an object from the stream. The object must have been previously
written to the stream by TStream.Put. Get first reads an object type IO (a
word) from the stream. It then finds the corresponding object type by
comparing the IO to the ObjType field of all ,registered object types (see the
TStreamRec type), and finally calls the Load constructor of that object type
to create and load the object. If the object type IO read from the stream is
zero, Get returns a nil pointer; if the object type IO has not been registered
(using RegisterType), Get calls TStream.Error and returns a nil pointer;
otherwise, Get returns a pointer to the newly created object.
See also: TStream.Put, RegisterType, TStreamRec, Load methods
m
n~_...l~ ~L...! __ L-~_ L1.. _ _ • _ _ _ L_~~!L!~_ ~C.L1.. ~L.._!___ _
TStringColiection Objects
ordering. You can override Compare to allow for other orderings, such as
those for non-English character sets.
Methods
Compare function Compare (Keyl, Key2: Pointer): Integer; virtual;
Override: Compares the strings Keyl/\ and Key2/\ as follows: return -1 if Keyl <
Sometimes
Key2; 0 if Keyl = Key2; and +1 if Keyl > Key2.
See also: TStringCollection.Search
Freeltem procedure FreeItem(Item: Pointer); v1rtual;
Override: Seldom Removes the string Item/\ from the sorted collection and disposes of the
string.
Getltem function GetItem(var S: TStream): Pointer; virtual;
Override: Seldom By default, reads a string from the TStream by calling S.ReadStr.
See also: TStream.ReadStr
Putltem procedure PutItem(var S: TStream; Item: Pointer); virtual;
Override: Seldom By default, writes the string Item/\ on to the TStream by calling S. WriteStr.
See also: TStream. WriteStr
TStringList Objects
Note that TStringList and TStrListMaker have the same object type ID
(ObjType field in a TStreamRec), and that they can therefore not both be
registered and used in the same program.
Methods
Load constructor Load (var S: TStream);
Loads the string list index from the stream S and stores internally a
reference to S so that TStringList.Get can later access the stream when
reading strings.
Assuming that TStringList has been registered using
RegisterType(RStringList), here's how to instantiate string list (created
using TStrListMaker and TResourceFile.Put) from a resource file:
ResFile.lnit(New(TBufStream, Init('MYAPP.RES', stOpenRead, 1024)));
Strings :; PStringList(ResFile.Get('Strings'));
See also: TStrListMaker.lnit, TStringList.Get
Done destructor Done; virtual;
Override: Never Deallocates the memory allocated to the string list.
See also: TStrListMaker.lnit, TStringList.Done
Get function Get (Key: Word): String;
Returns the string given by Key, or an empty string if there is no string
with the given Key. An example:
P :; @FileName;
FormatStr(S, StringsA.Get(sLoadingFile), P);
See also: TStrListMaker.Put
TStrListMaker Objects
TStrListMaker is a simple object type used to create string lists for use with
TStringList.
The following code fragment shows how to create and store a string list in
a resource file.
const
sInformation = 100;
sWarning = 101;
sError = 102;
sLoadingFile = 200;
sSavingFile = 201;
var
ResFile: TResourceFile;
S: TStrListMaker;
begin
RegisterType(RStrListMaker);
ResFile.Init(New(TBufStream, Init('MYAPP.RES', stCreate, 1024)));
S. Init (16384, 256);
S.Put(sInformation, 'Information');
S.Put(sWarning, 'Warning');
S.Put(sError, 'Error');
S.Put(sLoadingFile, 'Loading file %s.');
S.Put(sSavingFile, 'Saving file %s.');
ResFile.Put(@S, 'Strings');
S.Done;
ResFile. Done;
end;
Methods
-iii
Inn constructor Init(AStrSize, AlndexSize: Word);
Creates an in-memory string list of size AStrSize with an index of
Ll T""rin'VC:';...,n "'1"' ...... "' ... '-... A ... ,-: ... ~ 1-. •• CC~_ ~ ... ...:I __ :_...:1 ~~. 1-_.L:L:~_ ~L: L1- ____ _ !t:! _..l
- - ...... - ..... - '"'-- ----.... - ......- ..... - .......... 0 - _ ...... _ ... _ .... - _ ............. - ..... ,'" """ ................. A ""' .... "' ... L ...... ,"",!"""","-...A..&. ... """"'"
lTerminal TextView
Fields
BufSize BufSize: Word; Read only
The size of the terminal's buffer in bytes.
Buffer Buffer: PTerminalBuffer; Read only
Points to the first byte of the terminal's buffer.
QueFront QueFront: Word; Read only
Offset (in bytes) of the first byte stored in the terminal buffer.
QueBeck QueBack: Word; Read only
Offset (in bytes) of the last byte stored in the terminal buffer.
Methods
Init constructor Init(var Bounds: TRect; AHScrollBar, AVScrollBar: PScrollBar;
ABufSize: Word);
Creates a TTerminal object with the given Bounds, horizontal and vertical
scroll bars, and buffer by calling TTextDevice.lnit with the Bounds and
scroller arguments, then creating a buffer (pointed to by Buffer) with
BufSize equal to ABufSize. GrowMode is set to gfGrowHiX + gfGrowHiY.
QueFront and QueBack are both initialized to 0, indicating an empty buffer.
The cursor is shown at the view's origin, (0,0).
See also: TScroller.Init
Done destructor Done; virtual;
Override: Deallocates the buffer and calls TTextDevice.Done to dispose the object.
Sometimes
See also: TScroller.Done, TTextDevice.Done
BufDec procedure BufDec (var Val: Word);
Used to manipulate queue offsets with wrap around: If Val is zero, Val is
set to (BufSize -1); otherwise, Val is decremented.
See also: TTerminal.BufInc
Buflnc procedure BufInc (var Val: Word);
Used to manipulate a queue offsets with wrap around: Increments Val by
1, then if Val >= BufSize, Val is set to zero.
See also: TTerminal.BufDec
CalcWidth function CalcWidth: Integer;
Returns the length of the longest line in the text buffer.
- -
\"UIIIII~tm
-
tunctl.on Can Insert (Amount: Word): Boolean;
Returns True if the number of bytes given in Amount canbe inserted into
the terminal buffer without having to discard the top line.
Draw procedure Draw; virtual;
Override: Seldom Called whenever the TTerminal scroller needs to be redrawn, for example,
when the scroll bars are clicked on, the view is unhidden or resized, the
Delta values are changed, or when added text forces a scroll.
NextLine function NextLine (Pas: Word): Word;
Returns the buffer offset of the start of the line that follows the position
given by Pos.
See also: TTerminal.PrevLines
PrevLines function PrevLines (Pos :Word; Lines: Word): Word;
Returns the offset of the start of the line that is Lines lines previous to the
position given by Pos.
See also: TTerminal.NextLine
StrRead function StrRead(var s: TextBuf): Byte; virtual;
Override: Abstract method returning O. You must override if you want a derived
Sometimes type to be able to read strings from the text buffer.
StrWrite procedure StrWrite{var s: TextBuf; Count: Byte); virtual;
Override: Seldom Inserts Count lines of the text given by S into the terminal's buffer. This
method handles any scrolling required by the insertion and selectively
redraws the view with DrawView.
See also: TView.Draw View
~ueEnnpty function QueEmpty: Boolean;
Returns true if QueFront is equal to QueBack.
See also: TTerminal.QueFront, TTerminal.QueBack
Palette
Terminal objects use the default palette, CScroller, to map onto the 6th and
7th entries in the standard application palette.
2
CScroller ij6 I ~
Nonnal~ ighlight
11extDevice TextView
Methods
StrRead function StrRead (var S: TextBuf): Byte; virtual;
Override: Often Abstract method returning 0 by default. You must override in any derived
type to read a string from a text device into S. The method returns the
number of lines read.
StrWrite procedure StrWrite (var S: TextBuf; Count: Byte); virtual;
Override: Always Abstract method to write a string to the device. It must be overridden by
derived types. For example, TTenninal.StrWrite inserts Count lines of the
text given by S into the terminal's buffer and redraws the view.
Palette
Text device objects use the default palette CScroller to map onto the 6th
and 7th entries in the standard application palette.
1 2
CS.."l1er Q I [.
Nonnal~ ighlight
TView Views
Fields
Owner Owner: PGroup i Read only
Owner points to the TGroup object that owns this view. If nil, the view has
no owner. The view is displayed within its owner's view and will be
clipped by the owner's bounding rectangle.
Next Next: PViewi Read only
Pointer to next peer view in Z-order. If this is the last sub view, Next points
to Owner's first subview.
The (X, Y) coordinates, relative to the owner's Origin, of the top-left corner
of the view.
See also: MoveTo, Locate
Size Size: TPoint; Read only
The size of the view.
See also: GrowTo, Locate
Cursor Cursor: TPoint; Read only
The location of the hardware cursor within the view. The cursor is visible
only if the view is focused (sfFocused) and the cursor turned on
(s!CursorVis). The shape of the cursor is either underline or block
(determined by sfCursorlns).
See also: SetCursor, ShowCursor, HideCursor, NormalCursor, BlockCursor
GrowMode GrowMode: Byte; Read/write
Determines how the view will grow when its owner view is resized.
GrowMode is assigned one or more of the following GrowMode masks:
Figure 13.1 .--.---r---r--ofGrowA11 = $OF
GrowMode bit
mapping
fGrowLoX .. $01
fGrowLoY .. $02
L..----afGrowHiX = $04
'------gfGrowHiY = $08
'--------afGrowRe1 .. $10
undJined
I
II I
fSel ectabl e
L. fTopSelect
fFi rstCl i ck
fFramed
= $0001
"$0002
"$0004
.. $0008
fPreProcess "$0010
fPostProcess .. $0020
fBuffered " $0040
fTileable = $0080
fCenterX .. $0100
fCenterY .. $0200
For detailed descriptions of the option flags, see " ofXXXX option flag
constants" in Chapter 14.
EventMask EventMask: Word; Read/write
EventMask is a bit mask that determines which event classes will be
recognized by the view. The default EventMask enables evMouseDown,
evKeyDown, and evCommand. Assigning $FFFF to EventMask causes the
view to react to all event classes; conversely, a value of zero causes the
view to not react to any events. For detailed descriptions of event classes,
see "evXXXX event constants" in Chapter 14.
See also: HandleEvent methods
Methods
Init constructor Init (var Bounds: TRect);
Override: Often Creates a TView object with the given Bounds rectangle. Init calls
TObject.Init and sets the fields of the new TView to the following values:
Owner nil
Next nil
Origin (Bounds.A.X, Bounds.A.Y)
Size (Bounds.B.x - Bounds.A.x, Bounds.B.Y - Bounds.A.Y)
Cursor (0,0)
GrowMode o
DragMode dmLimitLoY
HelpCtx hcNoContext
State sfVisible
Options o
EventMask evMouseDown + evKeyDown + evCommand
Note that TObject.Init will zero all fields in TView descendants. Always
call TView.Init before initializing any fields.
See also: TObject.Init
Load constructor Load (var s: TStrearn);
Override: Often Creates a TView object and loads it from the stream S. The size of the data
read from the stream must correspond exactly to the size of the data
written to the stream by the view's Store method. If the view contains peer
view pointers, Load should use GetPeerViewPtr to read these pointers. An
overridden Load constructor should always call its parent's Load
constructor.
The default TView.Load sets the Owner and Next fields to nil, and reads the
remaining fields from the stream.
rt _ _ _ 1 __ f"rjTT~ .... ,.." ,.,..,,.,, ......, , ,.,..,,.,,
IJ~'" u..I..::IV. .I. .. ~"U/.v"'VI '" .L V/.-/ "~/".\JC", .L v H c~II,.r.u"
disable and enable commands as you wish; when you return to the
previous modal state, however, the original command set will be restored.
See also: TView.DisableCommand, TView.EnableCommand,
TView.SetCommimds.
UL~
entire area of the view. This method must be overridden appropriately for
each descendant. Draw is seldom called directly, since it is more efficient
to use DrawView, which draws only views that are exposed, that is, some
or all of the view is visible on the screen. If required, Draw can call
GetClipRect to obtain the rectangle that needs redrawing, and then only
draw that area. For complicated views, this can improve performance
noticeably.
DrawView
See also: TView.DrawView
procedure DrawViewi I
Chapter 73, Object reference 311
TView
Returns, in the Clip variable, the minimum rectangle that needs redrawing
during a call to Draw. For complicated views, Draw can use GetClipRect to
improve performance noticeably.
See also: TView.Draw
GetColor function GetColor (Color: Word): Word;
Maps the palette indices in the low and high bytes of Color into physical
character attributes by tracing through the palette of the view and the
palettes of all its owners.
See also: TView.GetPalette.
GetCommands procedure GetCommands (var Commands: TCommandSet);
Returns, in the Commands argument, the current command set.
See also: TView.CommandsEnabled, TView.EnableCommands,
TView.DisableCommands, TView.SetCommands.
GetOata procedure GetData(var Rec); virtual;
Override: Seldom GetData must copy DataSize bytes from the view to the data record given
by Rec. The data record mechanism is typically used only in views that
implement controls for dialog boxes.
The default TView.GetData does nothing.
See also: TView.DataSize, TView.SetData
GetEvent procedure GetEvent (var Event: TEvent); virtual;
Override: Seldom Returns the next available event in the TEvent argument. Returns
evNothing if no event is available. By default, it calls the view's owner's
GetEvent.
See also: TView.EventAvail, TProgram.ldle, TView.HandleEvent,
TView.PutEvent
GetExtent procedure GetExtent(var Extent: TRect);
Returns, in the Extent variable, the extent rectangle of the view. Extent.A is
set to (0,0), and Extent.B is set to Size.
See also: TView.Origin, TView.Size, TView.CalcBounds,
TView.ChangeBounds, TView.SetBounds, TView.GetBounds
GetHelpCtx
Override: Seldom
function GetHelpCtx: Word; virtual;
GetHelpCtx must return the view's help context.
I
Chapter 73, Object reference 313
TView
TView.HandleEvent(Event)i
case Event.What of
evMouseDown:
begin
repeat
MakeLocal(Event.Where, Mouse);
SetCursor(Mouse.X, Mouse.Y)i
until not MouseEvent(Event, evMouseMove)i
ClearEvent(Event);
endi
end;
end;
Selects the view (see sfSelected). If the view's owner is focused then the
view also becomes focused (see sfFocused). If the view has the ofI'opSelect
flag set in its Options field then the view is moved to the top of its owner's
subview list (using a call to TView.MakeFirst).
See also: sfSelected, sfFocused, ofI'opSelect, TView.MakeFirst
SetBounds procedure SetBounds (var Bounds: TRect);
Sets the bounding rectangle of the view to the value given by the Bounds
parameter. The Origin field is set to Bounds.A, and the Size field is set to
the difference between Bounds.B and Bounds.A. The SetBounds method is
intended to be called only from within an overridden ChangeBounds
method-you should never call Set Bounds directly.
See also: TView.Origin, TView.Size, TView.CalcBounds,
TView .ChangeBounds, TView.GetBounds, TView.Get Extent
SetCommonds procedure SetCommands (Commands: TCornmandSet);
Changes the current command set to the given Commands argument.
See also: TView.EnableCommands, TView.DisableCommands
SetCursor procedure SetCursor (X, Y: Integer);
Moves the hardware cursor to the point (X,Y) using view-relative (local)
coordinates. (0,0) is the top-left comer.
See also: TView.MakeLocal, TView.HideCursor, TView.ShowCursor
SetDoto procedure SetData(var Rec); virtual;
Override: Seldom GetData must copy DataSize bytes from the data record given by Rec to the
view. The data record mechanism is typically used only in views that
implement controls for dialog boxes.
The default TView.SetData does nothing.
See also: TView.DataSize, TView.GetData
SetState procedure SetState(AState: Word; Enable: Boolean); virtual;
Override: Sets or clears a state flag in the TView.State field. The AState parameter
Sometimes specifies the state flag to modify (see sfXXXX), and the Enable parameter
specifies whether to turn the flag off (False) or on (True). TView.SetState
then carries out any appropriate action to reflect the new state, such as
redrawing views that become exposed when the view is hidden (sfVisible),
or reprogramming the hardware when the cursor shape is changed
(sfCursorVis and sfCursorlns).
the view's Load constructor. If the view contains peer view pointers, Store
should use PutPeerViewPtr to write these pointers. An overridden Store
method should always call its parent's Store method.
The default TView.Store writes all fields but Owner and Next to the stream.
See also: TView.Load, TStream.Get, TStream.Put
TopView function TopView: PView;
Writes the given buffer to the screen starting at the coordinates (X,Y), and
filling the region of width Wand height H. Should only be used in Draw
methods. The But parameter is typically of type TDrawBuffer, but it can be
any array of words, each word containing a character in the low byte and
an attribute in the high byte.
See also: TView.Draw
WrlteChar procedure TView. WriteChar (X, Y: Integer; Ch: Char; Color: Byte; Count:
Integer) ;
Beginning at the point (X,Y), writes Count copies of the character Ch in the
color determined by the Color'th entry in the current view's palette.
Should only be used in Draw methods.
See also: TView.Draw
WriteLine procedure TView. WriteLine (X, Y, W, H: Integer; var Buf);
Writes the line contained in the buffer But to the screen, beginning at the
point (X,Y), and within the rectangle defined by the width Wand the
height H. If H is greater than 1, the line will be repeated H times. Should
only be used in Draw methods. The But parameter is typically of type
TDrawBuffer, but it can be any array of words, each word containing a
character in the low byte and an attribute in the high byte.
See also: TView.Draw
WriteStr procedure TView.WriteStr(X, Y: Integer; Str: String; Color: Byte);
Writes the string Str with the color attributes of the Color'th entry in the
view's palette, beginning at the point (X,Y). Should only be used in Draw
methods.
See also: TView.Draw
TWindow Views
and scrollers. Numbered windows from 1-9 can be selected with the Alt-n
keys (n = 1 to 9).
Fields
Flags Flags: Bytei Read/write
The Flags field contains combinations of the following bits:
fMove II$01
fGrow = $02
'------wfClose .. $04
'-------wfZoom .. $08
Methods
Init constructor Init(var Bounds: TRecti ATitle: TTitleStri ANumber: Integer)i
Calls TGroup.Init(Bounds). Sets default State to sfShadow. Sets default
Options to (ofSelectable + ofTopSelect). Sets default GrowMode to gfGrowAll +
Palette
Window objects use the default palettes CBlueWindow (for text windows),
CCyanWindow (for messages), and CGrayWindow (for dialog boxes).
2 3 4 5 6 8
CGrayWtndow
CCyanWt ndow
14
Global reference
This chapter describes all the elements of Turbo Vision that are not part of
the Turbo Vision standard object hierarchy. The standard objects are all
described in Chapter 13, "Object reference."
The elements listed in this chapter include types, constants, variables,
procedures, and functions defined in the Turbo Vision units. A typical
entry looks like this:
Function Constants beginning with /lap" are used to designate which of three
standard color palettes a Turbo Vision application should use. The three
palettes are used for color, black and white, and monochrome displays.
Function
Function Set to the starting and ending scan lines of the cursor by InitVideo. The
format used is that expected by BIOS interrupt $10, function 1 to set the
cursor type. .
See also InitVideo, TView.ShowCursor, TView.HideCursor, TView.BlockCursor,
TView.NormalCursor
dmXXXX constants
Values The DragMode bits are defined as follows:
Views I
Figure 14.1 r---r---.---.-------arnLirni tAll = $FO
Drag mode bit flags
mDragMove = $01
mDragGrow = $02
L-------<lrnLirnitLoX = $10
L--------<lrnLirnitLoY = $20
'---------arnLirnitHfX = $40
L-----------<lrnLirnitHiY = $80
Function The drag mode constants are used to compose the Mode parameter of the
TView.DragView method. They specify whether the view is allowed to
move and/or change size, and how to interpret the Limits parameter.
The drag mode constants are defined as follows:
Table 14.8
Drag mode Constant Meaning
constants dmDragMove Allow the view to move.
dmDragGrow Allow the view to change size.
dmLimitLoX The view's left-hand side cannot move outside Limits.
dmLimitLoY The view's top side cannot move outside Limits.
dmLimitHiX The view's right-hand side cannot move outside Limits.
dmLimitHiY The view's bottom side cannot move outside Limits.
dmLimitAll No part of the view can move outside Limits.
Function Terminates Turbo Vision's video manager by restoring the initial screen
mode (given by StartupMode), clearing the screen, and restoring the cursor.
Called automatically by TApplication.Done.
See also TApplication.Done, InitVideo, StartupMode variable
DoubleDelay variable
Declaration DoubleDelay: Word = 8;
Drivers I
Function Defines the time interval (in 1/18.2 parts of a second) between mouse-
button presses in order to distinguish a double-click from two distinct
clicks. Used by GetMouseEvent to generate a Double event if the clicks
occur within this time interval.
See also TEvent.Double, GetMouseEvent
Function Holds the current EMS logical page number as mapped into EMS physical
_~~~ 1"11-__ ~ """T:' ••• ~("L •• ~~ ••• """T"._.~("L.. __ .. _ ____ !..1 ____ .1._ ro, IU'" .. _____ . __ • . "
r-l:)- v ..., J ,...., ... ~".IJ~'" ""' ..... ",. • ..I. LJ""IJ.....,,,, .......... " ..
U. Y \J.1.\.A..t.:l '-VCI&.J..J .&...:.l.Y,La....I J..\;;J..llUYYllL5 \..UJ..1.,
by caching the state of EMS. If your program uses EMS for other pur-
poses, be sure to set EmsCurHandle and EmsCurPage to $FFFF before using
a TEmsStream-this will force the TEmsStream to restore its mapping.
See also TEmsStream.Page
vMouseDown = $0001
vMouseUp .. $0002
L..----evMouseMove .. $0004
'------evMouseAuto = $0008
'-------evKeyDown .. $0010
'------------evCorrmand .. $0100
'--------------evBroadcast = $0200
Function
FNarneStr = string [79] i
Function A generalized string formatting routine that works much like the C
languag~'s vsprintf function. Given a string in Format that includes format
specifiers and a list of parameters in Params, FormatStr produces a
formatted output string in Result.
The Format parameter can contain any number of format specifiers
t" .... ....
---- ------0 ...,h""
-----.... --------
~;'t"n,..,"";...,rr T ..
-- .....-,.... '\...-.1"'\
~.,
-- ....----
~,... ,.,,....A A.:,... ....... l ......... .,. ....t....1"'\ ___ ..... _""'...---" .... __ :_ D_ ........
-1-,.....
.- ---r--J ~
--.- r-----·----- -_. - .'0 ..... 4AA,..
~.
MyFileName := 'WARTHOG.ASM';
with OopsRec do
begin
FileName := @MyFileName;
I
LineNo := 42;
end;
ForrnatStr(TestStr, TernplateMsg, OopsRec);
Writeln(TestStr);
DarnArray[O) := Longint(@MyFileName);
DarnArray[l) := 24;
ForrnatStr(TestStr, TernplateMsg, DarnArray);
Writeln(TestStr);
end.
See also SystemError function, TParamText object
Function Returns the character, Ch, for which Alt-Ch produces the 2-byte scan code
given by the argument KeyCode. This function gives the reverse mapping
to GetAltCode.
See also GetAItCode
Function Returns the 2-byte scan code (keycode) corresponding to Alt-Ch. This
function gives the reverse mapping to GetAItChar.
See also GetAItChar
Function Allocates a cache buffer of Size bytes and stores a pointer to the buffer in
P. If there is no room for a cache buffer of the requested size, P is set to nil.
Cache buffers differ from normal heap blocks (allocated by New, GetMem,
or MemAlloc) in that they can be moved or disposed by the memory
manager at any time to satisfy a normal memory allocation request. The
pointer passed to GetBufMem becomes the cache buffer's master pointer,
and it (and only it) is updated when the buffer is moved by the memory
manager. If the memory manager decides to dispose the buffer, it sets the
master pointer to nil. A cache buffer can be manually disposed through a
call to FreeBufMem. Cache buffers will occupy any unallocated heap space
between HeapPtr and HeapEnd, including the area set aside for the
application's safety pool.
Turbo Vision uses cache buffers to cache the contents of TGroup objects
(such as windows, dialog boxes, and the desktop) whenever these objects
have the ofBuffered flag set-this greatly increases performance of redraw
operations.
See also FreeBuffMem, InitMemory, TGroup.Draw
Function Checks whether a keyboard event is available by calling the BIOS INT
16H service. If a key has been pressed, Event. What is set to evKeyDown and
Event.KeyCode is set to the scan code of the key. Otherwise, Event. What is
set to eVNothing. GetKeyEvent is called by TProgram.GetEvent.
See also TProgram.GetEvent, evXXXX constants, TView.HandleEvent
Function
procedure GetMouseEvent (var Event: TEvent);
Table 14.12
Grow mode flag Constant Meaning
definitions
gfGrowLoX If set, the left-hand side of the view will maintain a constant
distance from its owner's right-hand side.
gfGrowLoY If set, the top of the view will maintain a constant distance from
the bottom of its owner.
gfGrowHiX If set, the right-hand side of the view will maintain a constant
distance from its owner's right side.
gfGrowHiY If set, the bottom of the view will maintain a constant distance
from the bottom of its owner's.
gfGrowAIl If set, the view will move with the lower-right corner of its
owner.
gfGrowRel For use with TWindow objects that are in the desktop: The view
will change size relative to the owner's size. The window will
maintain its relative size with respect to the owner even when
switching between 25 and 43/50 line modes.
Note that LoX = left side; LoY = top side; HiX = right side; HiY =bottom
side.
See also TView.GrowMode
The following values define keyboard scan codes and can be used when
examining the TEvent.KeyCode field of an evKeyDown event record:
Table 14.15
Alt-Ietter key codes Constant Value Constant Value
kbAltA $lEOO kbAltN $3100
kbAltB $3000 kbAltO $1800
kbAltC $2EOO kbAltP $1900
kbAltD $2000 kbAltQ $1000
kbAltE $1200 kbAltR $1300
kbAltF $2100 kbAltS $lFOO
kbAltG $2200 kbAltT $1400
kbAltH $2300 kbAltU $1600
kbAltI $1700 kbAltV $2FOO
kbAltJ $2400 kbAltW $1100
kbAltK $2500 kbAltX $2DOO
kbAltL $2600 kbAlty $1500
I
kbAltM $3200 kbAltZ $2COO
Table 14.16
Special key codes Constant Value Constant Value
kbAltEqual $8300 kbEnd $4FOO
kbAltMinus $8200 kbEnter $lCOD
kbAltSpace $0200 kbEsc $Ol1B
kbBack $OE08 kbGrayMinus $4A2D
kbCtrlBack $OE7F kbHome $4700
kbCtrlDel $0600 kblns $5200
kbCtrlEnd $7500 kbLeft $4BOO
kbCtrlEnter $lCOA kbNoKey $0000
kbCtrlHome $7700 kbPgDn $5100
kbCtrlIns $0400 kbPgUp $4900
kbCtrlLeft $7300 kbrayPlus $4E2B
kbCtrlPgDn $7600 kbRight $4DOO
kbCtrlPgUp $8400 kbShiftDel $0700
kbCtrlPrtSc $7200 kbShiftIns $0500
kbCtrlRight $7400 kbShiftTab $OFOO
kbDel $5300 kbTab $OF09
kbDown $5000 kbUp $4800
Table 14.17
Alt-number key Constant Value Constant Value
codes
kbAltl $7800 kbAlt6 $7D00
kbAlt2 $7900 kbAlt7 $7E00
kbAlt3 $7AOO kbAlt8 $7F00
kbAlt4 $7BOO kbAlt9 $8000
kbAlt5 $7COO kbAltO $8100
Table 14.18
Function key codes Constant Value Constant Value
Table 14.19
Shift-function key Constant Value Constant Value
codes
kbShiftFl $5400 kbShiftF6 $5900
kbShiftF2 $5500 kbShiftF7 $5AOO
kbShiftF3 $5600 kbShiftFB $5BOO
kbShiftF4 $5700 kbShiftF9 $5COO
kbShiftF5 $5800 kbShiftF10 $5DOO
Table 14.20
Ctrl-function key Constant Value Constant Value
codes
kbCtrlFl $5EOO kbCtrlF6 $6300
kbCtrlF2 $5FOO kbCtrlF7 $6400
kbCtrlF3 $6000 kbCtrlFB $6500
kbCtrlF4 $6100 kbCtrlF9 $6600
kbCtrlF5 $6200 kbCtrlF10 $6700
Table 14.21
Alt-function key Constant Value Constant Value
codes
kbAltFl $6800 kbAltF6 $6DOO
kbAltF2 $6900 kbAltF7 $6EOO
kbAltF3 $6AOO kbAltFB $6FOO
kbAltF4 $6BOO kbAltF9 $7000
kbAltF5 $6COO kbAltFI0 $7100
See also evKeyDown, GetKeyEvent
Function A fast, inline assembly coded multiplication routine, returning the long
integer value X * Y.
Function Returns True if memory is low, otherwise False. True means that a memory
allocation call (for example, by a coristructor) was forced to "dip into" the
memory safety pool. The size of the safety pool is defined by the
LowMemSize variable.
See also Chapter 6, "Writing safe programs," InitMemory, TView.Valid,
LowMemSize
Function Sets the size of the safety pool in 16-byte paragraphs. The default value is
the usual pratical minimum, but it can be increased to suit your
application.
See also InitMemory, Safety pool, TView.Valid, LowMemory
Function Allocates Size bytes of memory on the heap and returns a pointer to the
block. If a block of the requested size cannot be allocated, a value of nil is
returned. As opposed to the New and GetMem standard procedures,
MemAlloc will not allow the allocation to dip into the safety pool. A block
allocated by MemAlloc can be disposed using the FreeMem standard
procedure.
See also New, GetMem, Dispose, FreeMem, MemAllocSeg
Function Message sets up a command event with the arguments What, Command and
InfoPtr then, if possible, invokes ReceiverA.HandleEvent to handle this
event. Message returns nil if Receiver is nil, or if the event is not handled
successfully. If the event is handled successfully (that is, if HandleEvent
returns Event. What as evNothing), the function returns Event.InfoPtr. The
latter can be used to determine which view actually handled the
dispatched event. The What argument is usually set to evBroadcast. For
example, the default TScrollBar.ScrollDraw sends the following message to
the scroll bar's owner:
Message (Owner, evBroadcast, cmScrollBarChanged, @Self);
The above message ensures that the appropriate views are redrawn
whenever the scroll bar's Value changes.
See also TView.HandleEvent, TEvent type, cmXXXX constants, evXXXX constants
Function Min Win Size defines the minimum size of a TWindow or a descendant of
TWindow. The value is returned in the Min parameter on a call to
TWindow.SizeLimits. Any change to Min Win Size will affect all windows,
unless a window's SizeLimits method is overridden.
See also TWindow.SizeLimits
Function Contains the current state of the mouse buttons. MouseButtons is updated
by the mouse interrupt handler whenever a button is pressed or released.
The mbXXXX constants can be used to examine MouseButtons.
See also mbXXX constants
Function Used internally by Turbo Vision mouse driver and by views. Set
whenever a mouse event occurs.
Function Allocates and returns a pointer to a new TMenuItem record that represents
a menu item (NewStr is used to allocate the Name and Param string pointer
fields). The Name parameter must be a non-empty string, and the
Command parameter must be non-zero. Calls to Newltem, NewLine,
NewMenu, and NewSubMenu can be nested to create entire menu trees in
one Pascal statement; for examples of this, refer to Chapter 2, "Writing
Turbo Vision applications."
See also TApplication.InitMenuBar, TMenuView type, NewLine, NewMenu,
NewSubMenu #
Function Allocates and returns a pointer to a new TMenuItem record that represents
See also
a separator line in a menu box.
T Application.InitMenuBar, TMenu View type, NewMenu, NewSubMenu,
NewItem
I
NewMenu function Menus
Declaration function NewMenu (Items: PMenuItern): PMenu;
Function Allocates and returns a pointer to a new TMenu record. The Items and
Default fields of the record are set to the value given by the Items
parameter.
See also TApplication.InitMenuBar, TMenuView type, NewLine, NewSubMenu,
Newltem
Function Dynamic string routine. If 5 is nul, New5tr returns a nil pointer; otherwise,
Length(5)+1 bytes is allocated containing a copy of 5, and a pointer to the
first byte is returned.
Strings created with NewStr should be disposed of with DisposeStr.
See also DisposeStr
I ~ fTopSelect
I I fSel ectabl e = $0001
= $0002
unde};ned
I fFirstCl i ck
fFramed
fPreProcess
= $0004
= $0008
a $0010
fPostProcess = $0020
fBuffered .. $0040
fTil eab 1e = $0080
fCenterX = $0100
fCenterY = $0200
Table 14.24
Scroll bar part
constants
actual scroll step values. Although defined, the sblndicator constant is
never passed to TScrollBar.ScrollStep.
Constant
sbLeftArrow
sbRightArrow
sbPageLeft
Value
o
1
2
Meaning
Left arrow of horizontal scroll bar
Right arrow of horizontal scroll bar
Left paging area of horizontal scroll bar
-III
sbPageRight 3 Right paging area of horizontal scroll bar
sbUpArrow 4 Top arrow of vertical scroll bar
sbDownArrow 5 Bottom arrow of vertical scroll bar
s bPageUp 6 Upper paging area of vertical scroll bar
sbPageDown 7 Lower paging area of vertical scroll bar
sblndicator 8 Position indicator on scroll bar
Sjblndi cator-----t.~t--sbPageDOWn
;t--sbDownArrow
;::::::::::::::::::f:::::::::::::::::::::::::::a::::::::::::::::::::::f:::::::::::::::::::::::::::::::::::::::,
I sbPageLeft sbPageRight I
sbLeftArrow sbRightArrow
Function Holds the current video mode. Set initially by the initialization code of the
Drivers unit, ScreenMode can be changed using SetVideoMode. ScreenMode
values are usually set using the smXXXX screen mode mnemonics.
See also InitVideo, SetVideoMode, smXXXX
Function Set by In itVideo to the screen width (number of characters per line).
See also InitVideo
Function Sets the top of the application's memory block. The initial memory top
corresponds to the value stored in the HeapEnd variable. SetMemTop is
typically used to shrink the application's memory block before executing a
DOS shell or another program, and to expand the memory block
I
afterward.
Function Sets the video mode. Mode is one of the constants smC080, smBW80, or
smMono, optionally with smFont8x8 added to select 43- or 50-line mode on
an EGA or VGA. SetVideoMode initializes the same variables as InitVideo
(except for the StartupMode variable, which isn't affected). SetVideoMode is
normally not called directly. Instead, you should use
TApplication.SetScreenMode, which also adjusts the application palette.
See also InitVideo, smXXXX constants, TApplication.SetScreenMode
I
See also TView.State
Function This value controls the size of the shadow effect available on those views
with the sfShadow bit set. The shadow is usually a thin, dark region
displayed just beyond the view's right and bottom edges giving a 3-D
illusion. The default size is 2 in the X direction, and 1 in the Y direction.
TProgram.InitScreen initializes ShadowSize as follows: If the screen mode is
smMono, Shadow Size is set to (0,0). Otherwise ShadowSize is set to (2, 1),
unless smFont8x8 (43- or 50-line mode) is selected, in which case it is set to
(1, 1)~
Function The InitVideo routine stores the current screen mode in this variable before
it switches to the screen mode given by ScreenMode. DoneVideo restores the
screen mode to the value stored in StartupMode.
See also InitVideo, DoneVideo, ScreenMode
I
the status line. The previous status line is saved and restored when
conditions allow.
See also SystemError, SysMonoAttr
Where: TPoint);
evKeyDown: (
case Integer of
0: (KeyCode: Word);
1: (CharCode: Char;
ScanCode: Byte));
evMessage: (
Conunand: Word;
case Word of
0: (InfoPtr: Pointer);
1: (InfoLong: Longint);
2: (InfoWord: Word);
3: (InfoInt: Integer);
4: (InfoByte: Byte);
5: (InfoChar: Char));
end;
Function The TEvent variant record type plays a fundamental role in Turbo Vision's
event handling strategy. Both outside events, such as mouse and
keyboard events, and command events generated by inter-communicating
views, are stored and transmitted as TEvent records.
See also evXXXX, HandleEvent methods, GetKeyEvent, GetMouseEvent
TI\I1Anl I t\lnA
- - - I ,- -
I\AAnll~
has a Menu field that points to a TMenu. TMenu records are created and
destroyed using the NewMenu and DisposeMenu routines.
See also TMenuView, TMenuItem, NewMenu, DisposeMenu, TMenuView.Menu field
II
Chapter 74, Global reference 379
TStatusDef type
Turbo Vision reserves object type IDs (ObjType) values 0 through 999 for
its own use. Programmers can define their own values in the range 1,000
to 65,535.
By convention, a TStreamRec for a Txxxx object type is called Rxxxx. For
example, the TStreamRec for a TCalculator type is called RCalculator, as
shown in the following code:
type
TCalculator = object(TDialog)
I
Chapter 74, Global reference 381
TStreamRec type
end;
const
RCalculator: TStrearnRec =
ObjType: 2099;
VrntLink: Ofs(TypeOf(TCalculator)A);
Load: @TCalculator.Load;
Store: @TCalculator.Store);
begin
RegisterType(RCalculator);
end;
See also RegisterType
Values
window can move, grow, close, or zoom.
The window flags are defined as follows: I
Chapter 74, Global reference 383
wfXXXX constants
fMove = $01
fGrow = $02
'------wfClose = $04
'-------wfZoom = $08
Table 14.34
Window flag Constant Value Meaning
constants wfMove $01 Window can be moved
wfGrow $02 Window can be resized and has a grow icon in the lower-
right corner.
wfClose $04 Window frame has a close icon that can be mouse-clicked
to close the window.
wfZoom $08 Window frame has a zoom icon that can be mouse-clicked
to zoom the window
A tracing execution 16
A AppPalette variable 328
TRect field 278 apXXXX constants 328
abstract ArStep
methods 68, 69, 186, 328 TScrollBar field 283
objects 67 Assign
Abstract procedure 328 TRect method 84, 278
AmDefault AssignDevice procedure 329
TButton field 213 At
ancestor views TCollection method 222
vs. owner views 91 AtDelete
Application variable 328 TCollection method 222
applications 17, 74, 206, 269 AtInsert
appearance of 271, 328 TCollection method 223
as groups 74 atomic operations 131
as modal views 98 safety pool and 132
as views 86 Valid method and 135
behavior of 271 AtPut
constructor 25, 207, 270 TCollection method 223
example 20
debugging 16 B
default behavior 24 B
designing 179 TRect field 278
desktop and 272 background 208
destructor 21,207, 270 appearance of 209, 227
examole 21
events and 270 of desktop 90
execution 273 pattern 208
flow of execution 19 bfXXXX constants 329
global variable 328 bitmapped fields 180, 181, 182
idle time 271 bits
main block 8, 24 checking 182
example 19 clearing 181
menu bars and 272 masking 182
Run method 113,273 setting 181
example 20 BlockCursor
status lines and 272 TView method 310
storing on streams 166 BMenuView palette 263, 264, 267
Index 387
Bounds BufSize
TView field 72 TBufStream field 210
breakpoints 175 TTerminal field 302
in HandleEvent 176 ButtonCount variable 330
in views 177 buttons 12,15,50,75,211
program hangs and 177 appearance of 213,214,215
broadcast events See events, broadcast behavior of 118,214
BufDec Cancel 16,51
TTerminal method 303 commands 50, 212
BufEnd binding 51
TBufStream field 210 constructor 51, 213
Buffer default 16,52,213,214,329
TBufStream field 210 destructor 213
TGroup field 236 example 51
TTerminal field 302 flags 213,329
buffered labels 50,212, 329
drawing 40, 376 left-justified 213
example 40 mouse 330, 354, 356
locking and 242 normal 213, 329
unlocking 243 OK 52
streams 209 phase and 118
views 100 streams and 213, 214
buffers
group 236
memory
c
CalcBounds
assigning 343
TView method 310
freeing 343
CalcWidth
moving 357
TTerminal method 303
moving characters into 357
Cancel button 16
moving strings into 358
CanInsert
screen 366
streams 210 TTerminal method 303
Cascade
end pointer 210
TDeskTop method 227
flushing 210
position pointer 210 CBackground palette 209
size of 210 CButton palette 215
CCluster palette 216, 220, 277
terminal 303
beginning 302 CDialog palette 229
end 302 centering See views, centering
CFrame palette 235
position 303
size of 302 ChangeBounds
TGroup method 237
video 383
TListViewer method 260
writing to screen 320
TScroller method 287
Bufinc
TView method 310
TTerminal method 303
characters
BufPtr
pointers to 363
TBufStream field 210
Index 389
dialog boxes 49 static text See also text, static
standard 51,332 values
disabling 27, 120,311 setting 56
enabling 120,310,312 conventions
events and 113 naming 186
focused events and 119 coordinate system 83, 84, 269, 277
positional events and 119 coordinates
reserved by Turbo Vision 119, 331 global 315
sets of 313,318,375 local 315
standard 27, 331 Copy
dialog boxes 51 TRect method 278
dialogs 332 CopyFrom
Compare TStream method 167, 296
TSortedColIection method 289 Count
TStringCollection method 299 TCollection field 221
constants TResourceFile method 281
application palettes 328 coXXXX constants 334
button flags 329 CScrollBar palette 286
collections 334 CScroller palette 288, 304, 305
commands 331 CStaticText palette 292
grow mode 345 CStatusLine palette 294
help context 346 CStrLen function 334
keyboard 350 CtrlBreakHit variable 335
option flags 361 CtrlToArrow function 335
prefixes 186 CurPos
screen modes 371 TInputLine field 249
scroll bar parts 365 Current
state flags 368 TGroup field 236
stream 371 TMenuView field 265
constructors 2 Cursor
Contains TView field 307
TRect method 278 cursor
controls See also dialog boxes, controls hiding 314
binding labels to 55, 253 location of 318
button See also buttons mouse
cluster See also clusters hiding 346
default 16 showing 370
dialog boxes and 50, 74 position 307
focused 52, 96 input lines 249
default 52 size of 336
history lists See also history lists type 310,316,368
input lines See also input lines visible 319, 368
label See also labels CursorLines variable 336
list boxes See also list boxes customization 169, 170
list viewers See also list viewers string lists and 173
phase and 118 CWindow palette 325
Index 391
DisableCommands TButton method 213
TView method 311 TCheckBoxes method 216
display access 10 TFrame method 234
DisposeMenu procedure 336 TGroup method 238
DisposeStr procedure 39, 336 THistory method 245
dmXXXX constants 336 TInputLine method 251
Done TLabel method 254
TApplication method 207 TListViewer method 260
TBufStream method 210 TMenuBar method 262
TButton method 213 TMenuBox method 264
TCluster method 218 TRadioButtons method 277
TCollection method 222 TScrollBar method 284
TDosStream method 231 TStaticText method 291
TEmsStream method 233 TStatusLine method 293
TGroup method 237 TTerminal method 303
TInputLine method 250 TView method 37, 73, 82, 84, 311
TObject method 268 draw buffer 40, 376
TProgram method 270 palettes and 42
TResourceFile method 281 writing to screen 320
TStaticText method 291 DrawBox
TStatusLine method 293 TCluster method 219
TStringList method 300 DrawView
TStrListMaker method 301 TView method 37, 311
TTerminal method 303 dynamic variables 2
TView method 309
TWindow method 323 E
DoneEvents procedure 337
Empty
DoneHistory procedure 337
TRect method 279
DoneMemory procedure 338
EmsCurHandle variable 339
DoneSysError procedure 338
EmsCurPage variable 339
DoneVideo procedure 338
EnableCommands
DoubleDelay variable 338
DragMode TView method 312
EndModal
constants 336
TGroup method 238
TView field 98, 102, 307
TView method 51, 312
DragView
Enter key
TView method 311
Draw dialog boxes and 52
environment
buffered 40, 376
saving 166
example 40
example 166
procedures 41
Equals
clipping 90, 312
TRect method 278
colors and 104
groups and 89 Error
requirements for 42 TCollection method 149, 223
TStream method 154, 156, 168, 296
TBackground method 209
overriding 168
Index 393
First Frame
TGroup method 239 TWindow field 322
FirstPos frames 234
TInputLine field 249 appearance of 234, 235
FirstThat behavior of 234
TCollection method 142, 223 constructor 234
TGroup method 239 views 99, 362
Flags windows 35, 75, 92, 322
TButton field 213 active 96
TWindow field 322 creating 324
flags 98, 180, 182 Free
buttons 213, 329 TCollection method 224
checking 182 TObject method 267
clearing 181 FreeAll
defining 180 TCollection method 224
interpreting 180 FreeBufMem procedure 343
option 180,308,361 FreeItem
Options 99 TCollection method 139, 224
setting 181 TStringCollection method 299
state 98, 308, 368
window 322
windows 383
G
Flush Get
TBufStream method 210 TResourceFile method 281
TResourceFile method 281 TStream method 154, 155, 160, 296
TStream method 296 TStringList method 300
FNameStr type 340 GetAltChar function 343
focus chain See also views, focused GetAltCode function 343
events and 115 GetBounds
Focused TView method 312
TListViewer field 259 GetBufMem procedure 343
focused See also selected GetClipRect
control 52, 96 TView method 42, 312
default 52 GetColor
events 341, See events, focused palettes and 106
item TView method 105, 106, 31 ~
history list 248 GetCommands
list viewer 259, 260 TView method 313
views 10, 95, 96, 368 GetData
default 96 TCluster method 219
FocusedEvents variable 341 TGroup method 240
FocusItem TInputLine method 251
TListViewer method 260 TListBox method 256
ForEach TView method 313
TCollection method 141,224 GetEvent
TGroup method 240 modifying 125
FormatStr procedure 341 overriding 125
Index 395
GrowMode Run method 20
constants 345 help context 130, 346
TView field 98, 101,307 focused view and 130
GrowTo groups and 241
TView method 314 menu items 28
menus and 266
H reserved 346
status lines and 130, 293
Handle
views and 307, 313
TDosStream field 231
HelpCtx
TEmsStream field 232
TView field 307
handle
Hide
DOS file 231
TView method 314
EMS
HideCursor
current 339
TView method 314
HandleEvent See also events, handling
HideMouse procedure 346
calling directly 129
Hint
general layout 121
TStatusLine method 294
inheriting 121
hints
overriding 121
status lines and 294
TButton method 214
HiResScreen variable 347
TCluster method 219
history lists 62, 76, 244
TDeskTop method 227
appearance of 245
TDialog method 229
constructor 245
TFrame method 234
icon 245
TGroup method 241
ID numbers 246
THistoryViewer method 246
input lines and 244
TlnputLine method 251
viewers 245
TLabel method 254
appearance of 246, 247
TListViewer method 260
behavior of 246
TMenuView method 266
constructor 246
TProgram method 271
size of 247
TScrollBar method 284
text 246
TScroller method 287
windows and 247
TStatusLine method 294
windows 247
TView method 85, 114, 121,309
appearance of 248
TWindow method 323
constructor 247
hanging programs
viewers and 247
debugging 177
HistoryAdd procedure 347
hcNoContext constant 28, 130
HistoryBlock variable 347
hcXXXX constants 346
HistoryCount function 347
heap
HistoryID
safety pool 131
THistory field 244
top of 367
THistoryViewer field 246
HELLO.PAS 12, 12-21
HistorySize variable 348
constructor 20
HistoryStr function 348
main block 19
HistoryUsed variable 348
Index 397
history lists and 244 keyboard See also events, focused
length constants 350
maximum 249 events 112, 315, 344
phase and 118 scan codes 343
selected 249, 250, 251 KeyEvent
streams and 250 TView method 315
value KeyOf
setting 251,252 TSortedCollection method 290
Insert keys
TCollection method 225 resources and 169,281
TGroup method 33, 87, 241 sorted collections 290
TSortedCollection method 290
InsertBefore L
TGroup method 242
labels 55, 252
insertion point See input lines, cursor
appearance of 254
instantiating objects 68
behavior of 254
interactive programming 12-21
binding to controls 55, 253
basic principles 13, 16
error handling 131 constructor 253
example 55
intermediary objects 126
selected 253
internationalization 173
Last
resources and 170
Intersect TGroup field 236
LastThat
TRect method 278
TCollection method 142, 225
IsSelected
Light
TListViewer method 260
TLabel field 253
Items
Limit
TCollection field 221
TCollection field 221
items See also collections
TScroller field 287
collections and 221
lines
list boxes and 255, 256
writing to screen 321
list viewer
Link
number 259
THistory field 244
iterator methods 79, 141,223,224,225
TLabel field 253
collections and 141
List
example 141, 142
TListBox field 255
far local requirement 141, 142
FirstThat 142 list boxes 61, 76,254
ForEach 141 appearance of 257
collections and 76, 255
groups and 239, 240
constructor 256
LastThat 142
data
size of 256
K items 255
kbXXXX constants 350 replacing 257
KeyAt retrieving 256
TResourceFile method 281
Index 399
Menu virtual 70, 186
TMenuView field 265 Min
menu bars 261 TScrollBar field 283
appearance of 262, 263 MinWinSize variable 356
constructor 28, 262 modal
example 28, 29 dialog boxes 49, 97
creation by application 272 terminating 51
global variable 355 views 97, 369
help context and 28 applications as 98
mouse and 263 current 320
menu boxes 263 events and 114
appearance of 264 executing 238,312
constructor 263 scope and 97
mouse and 264 status line and 98
MenuBar variable 26, 355 terminating 238,312
menus 75,261,264,377, See also menu boxes, modeless dialog boxes See dialog boxes,
See also menu bars modeless
appearance of 266,267 Modified
behavior of 266 TResourceFile field 280
components 11 mouse
constructor 265 buttons 330, 354, 356
creating 359 cursor
disposing of 336 showing 370
help context and 266, 378 driver 338, 364
hot keys and 28, 266, 378 events 112, 315, 338, 344, 356, 362, 364
items 265, 266, 378 hiding cursor 346
creating 358 location of 316,357
disabling 378 MouseButtons variable 356
selected 265 MouseEvent
shortcuts 266 TView method 315
lines MouseEvents variable 356
creating 359 MouseIntFlag variable 357
links between 265 MouseInView
operating 14 TView method 316
shortcuts and 28, 266 MouseWhere variable 357
streams and 266 Move
submenus TRect method 278
creating 361 MoveBuf procedure 357
Message function 355 MoveChar procedure 41, 357
messages 355 MoveCStr procedure 358
events 112 MovedTo
methods TCluster method 219
abstract 68, 69, 186, 328 TRadioButtons method 277
iterator See also iterator methods MoveStr procedure 41, 358
overriding 69, 70 MoveTo
pseudo-abstract 70 TView method 316
static 70 multiple interiors 45
Index 401
PageCount PInputLine See TInputLine object
TEmsStream field 232 PLabel See TLabel object
Palette PListBox See TListBox object
TWindow field 322 PListViewer See TListViewer object
palettes 105, 379 PMenuBar See TMenuBar object
default 105 PMenuBox See TMenuBox object
overriding 107 PMenuView See TMenuView object
expanding 108 PObject See TObject object
GetColor and 106,313 pointers to objects 2, 17
layout 105 points 269
mapping 105 polymorphism 2, 17, 70, 138
nil 106 streams and 152
string functions and 107 porting applications to Turbo Vision 178
windows 384 Position
PApplication See TApplication object TEmsStream field 232
ParamCount positional events See events, positional
TParamText field 268 PositionalEvents variable 363
ParamList postprocess See phase
TParamText field 268 PParamText See TParamText object
ParentMenu PProgram See TProgram object
TMenuView field 265 PRadioButtons See TRadioButtons object
Pattern preprocess See phase
TBackground field 208 PResourceCollection See TResourceCollection
PBackground See TBackground object object
PBufStream See TBufStream object PResourceFile See TResourceFile object
PButton See TButton object Press
PChar type 363 TCheckBoxes method 216
PCheckBoxes See TCheckBoxes object TCluster method 220
PCluster See TCluster object TRadioButtons method 277
PCollection See TCollection object Prev
PDeskTop See TDeskTop object TView method 316
PDialog See TDialog object PrevLines
PDosStream See TDosStream object TTerminal method 304
peer views 165,314,317 PrevView
PEmsStream See TEmsStream object TView method 317
PFrame See TFrame object PrintStr procedure 363
PGroup See TGroup object PScrollBar See TScrollBar object
PgStep PScroller See TScroller object
TScrollBar field 283 pseudo-abstract methods 70
Phase 60, See also phase PSortedCollection See TSortedCollection object
TGroup field 118, 237 PStaticText See TStaticText object
phase 237 PStatusLine See TStatusLine object
postprocess 99, 117, 362 PStream See TStream object
preprocess 99, 117, 362 PString type 363
PHistory See THistory object PStringCollection See TStringCollection object
PHistoryViewer See THistoryViewer object PStringList See TStringList object
PH;istoryWindow See THistoryWindow object PStrListMaker See TStrListMaker object
Index 403
string lists and 173 paging 283
uses of 169 parts 284, 365, 379
vs. streams 167 phase and 117
writing 282 scrollers and 284, 286
Run standard 324
TProgram method 273 value 282, 284
maximum 283
setting 285
5 minimum 283
safe programming 131 setting 285
example 136 setting 285
safety pool 131, 132 ScrollDraw
default size 132 TScrollBar method 284
error checking and 133 TScroller method 287
example 133 scrollers 76, 286
LowMemory function and 132 appearance of 287, 288
major consumers and 135 behavior of 287
size of 132, 353 constructor 44, 287
ValidViewand 133 Delta values 44, 286
vs. traditional error checking 133 limits 287
SaveCtrlBreak variable 365 setting 288
sbXXXX constants 365 scroll bars and 284, 286
scan codes size of
keyboard 343 changing 287
scope ScrollStep
modal views and 97 TScrollBar method 284
screen ScrollTo
buffer 366 TScroller method 288
clearing 330 Search
high resolution 347 TSortedCollection method 290
mode 366,371,372 Seek
setting 273 TBufStream method 211
size of 366, 367 TDosStream method 231
writing characters to 320 TEmsStream method 233
writing draw buffer to 320 TStream method 167, 297
writing lines to 321 Sel
writing strings to 321 TCluster field 217
ScreenBuffer variable 366 Select See also focused, views
ScreenHeight variable 366 modes 367
ScreenMode variable 366 Options field and 99, 361
ScreenWidth variable 367 TView method 96, 317
scroll bars 77, 282 SelectAlI
appearance of 284, 286 TInputLine method 251
arrows 283 SelectItem
behavior of 284 TListViewer method 261
constructor 283, 284 SelectMode type 367
list viewers and 258
Index 405
appearance of 293, 294 TWindow method 324
behavior of 294 Stream
binding hot keys with 27 TResourceFile field 280
commands StreamError variable 373
binding 26, 120 streams 78, 151, 294
generating 119 access modes 372
constructor 26, 293 buffered 79, 154, 209, 372, See also buffers,
example 26, 27 streams
creation by application 272 constructor 210
definitions 293, 379 destructor 210
creating 360 position 210
destructor 293 setting 211
global variable 372 reading from 211
help context and 130,293 size of 211
hints 294 truncating 211
items 293, 380 writing to 211
keys constructor 154
creating 360 copying 167, 296
modal views and 98 defined 151
positional events and 119 designing 168
streams and 293, 294 destructor 156
updating 294 DOS 79, 154, 230, 372
usage 11 constructor 231
Status Line variable 26, 372 destructor 231
events and 119 file handle 231
Store position 231
methods 156, 159, 166 reading from 231
example 157 size 231
TBackground method 209 truncating 231
TButton method 214 writing to 232
TCluster method 220 EMS 79, 154, 232
TCollection method 226 constructor 233
TGroup method 243 destructor 233
THistory method 245 handle 232
TInputLine method 252 position 232, 233
TLabel method 254 reading from 233
TListBox method 257 size 232, 233
TListViewer method 261 truncating 233
TMenuView method 266 writing to 233
TParamText method 269 error codes 168, 295, 372
TScrollBar method 285 error-handling 156, 295, 296, 297
TScroller method 288 errors 373
TStaticText method 291 flushing 296
TStatusLine method 294 groups and 155, 243
TStreamRec field 158 indexed 154
TStrListMaker method 302 Load methods and 156
TView method 319 mechanism 159
Index 407
focused control and 96 THistoryViewer object 245, See also history
Tab order 52, 53, 96, See also Z-order lists, viewers
TApplication object 23, 74,206, See also THistoryWindow object 247, See also history
applications lists, windows
TProgram vs. 207 Tile
TBackground object 90, 208, See also TDeskTop·method 228
background TileError
TBufStream object 79, 154, 209, See also TDeskTop method 228
streams, buffered tiling windows 35, 100, 228, 362
TButton object 75,211, See also buttons errors 228
TByteArray type 375 TlnputLine object 76, 248, See also input lines
TCheckBoxes object 215, See also check boxes TItemList type 377
TCluster object 75,216, See also clusters Title
TCollection object 79, 137, 220, See also TButton field 212
collections TWindow field 322
TCommandSet type 375 title strings
TDeskTop object 74,226, See also desktop buttons 212
TDialog object 74, 228, See also dialog boxes windows 322, 323, 383
TDosStream object 79, 154, 230, See also TLabel object 252, See also labels
streams, DOS TListBox object 76, 254, See also list boxes
TDrawBuffer type 40, 376 TListViewer object 76,257
TEmsStream object 79, 154, 232, See also TMenu type 377
streams, EMS TMenuBar object 261, See also menus
terminal views 75 TMenuBox object 263, See also menus
TEvent type 122, 376, See also event record TMenuItem type 378
Text TMenuStr type 378
TStaticText field 291 TMenuView object 75, 264, See also menus
text TObject object 72,267, See also objects, base
devices 77, 302, 304 TopItem
appearance of 303, 304, 305 TListViewer field 259
assigning 329 TopView
constructor 303, 305 TView method 320
destructor 303, 305 TPalette type 379
lines 303, 304 TParamText object 268
terminal buffer 302, 303, 382 TPoint object 72, 82, 83, 269
size of 302 TProgram object 74,269, See also applications
formatted 268 TRadioButtons object 276, See also radio
history lists 246 buttons
static 15,61, 77, 290 TRect object 72, 83, 277
appearance of 291, 292 TResourceCollection object 80, 279, See also
centering 291 collections, resources
constructor 291 TResourceFile object 79, 170, 279, See also
destructor 291 resources
TFrame object 75, 92, 234, See also frames Truncate
TGroup object 73, 235, See also groups TBufStream method 211
fields 73 TDosStream method 231
THistory object 76, 244, See also history lists TEmsStream method 233
Index 409
appearance of 37, 73,81,82,84,311,313, resizing 101
314 selectable 99, 361
applications as 82, 86 selected 95,236,243,317, 368
behavior of 121,309 shadowed 368, 369, 370
buffered 100 size of 72, 82, 83, 307, 356
centering 100, 101, 362 changing 310,314
color palettes 104, 313, 314 limits 319
communication between 126,355 maximum 354
constructor 309 state flags 308
data subviews 33
reading 313 terminal 75,86
setting 318 events and 114
size of 311 topmost
debugging 177 finding 129
destructor 309 trees 34, See also view trees
detecting 128 unhiding 319
disabled 369 valid 320
drag modes 307 visible 319, 368
dragging 311,369 virtual method tables
enabled 369 files and 152
error-handling 320 streams and 158
events and 82, 85, 121,309,320 virtual methods 70
exposed 312 VmtLink
focused 10, 95, 96, 97, 368 TStreamRec field 158
events and 115 VMTs See virtual method tables
framed 99, 362 VScrollBar
groups of 33, 86 TListViewer field 258
grow modes 307, 345 TScroller field 286
help context 307, 313
hiding 314
inserting 33, 241, 242
w
wfXXXX constants 383
interior 35
windows 74, 321
example 36
active 95, 96, 368
framed 36
appearance of 37, 322, 323, 325, 384
location of 72, 82, 306, 312, 313,362
as groups 92
changing 310,315,316
behavior of 323
maximum width 40
cascading 227
messages between 127
closing 34, 124, 323
modal 312, 369, See modal, views
icon 384
current 320
constructor 31, 322, 323, See also windows,
events and 114, 115
opening
option flags 308, 361
parameters 33
overlapping 87
default
owner See owner views
appearance 35
peer 165,314,317
behavior 31, 34
position
destructor 323
setting 318
Index 411
6.0
TURBO
VISION
GUIDE
B 0 R L A N D
c.".,.t. H.~.. r1If1: lloa Gr.n HIUI R.... P.O. 101 1100111 . Scotti ~"'.y. CA '5017-00111 . (401) 431-5300
J.,.••
Ollie" I.: AlIltral"'. 0._1\. f ...,..... Fraoc •• G~.y. Italy. 114 S..... . Perl. llMM-PAS04-IO • lOR 1153