-
Notifications
You must be signed in to change notification settings - Fork 3
/
listing22.html
executable file
·895 lines (781 loc) · 31.6 KB
/
listing22.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/1999/REC-html401-19991224/loose.dtd">
<html>
<head>
<!-- BEGIN META TAG INFO -->
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<link rel="home" href="http://developer.apple.com/">
<link rel="find" href="http://developer.apple.com/search/">
<link rel="stylesheet" type="text/css" href="../../documentation/css/adcstyle.css" title="fonts">
<script language="JavaScript" src="../../documentation/js/adc.js" type="text/javascript"></script>
<!-- END META TAG INFO -->
<!-- BEGIN TITLE -->
<title>HTMLSample - /HTMLSample.c</title>
<!-- END TITLE -->
<script language="JavaScript">
function JumpToNewPage() {
window.location=document.scpopupmenu.gotop.value;
return true;
}
</script>
</head>
<!-- BEGIN BODY OPEN -->
<body>
<!--END BODY OPEN -->
<!-- START CENTER OPEN -->
<center>
<!-- END CENTER OPEN -->
<!-- BEGIN LOGO AND SEARCH -->
<!--#include virtual="/includes/adcnavbar"-->
<!-- END LOGO AND SEARCH -->
<!-- START BREADCRUMB -->
<div id="breadcrumb">
<table width="680" border="0" cellpadding="0" cellspacing="0">
<tr>
<td scope="row"><img width="340" height="10" src="images/1dot.gif" alt=""></td>
<td><img width="340" height="10" src="images/1dot.gif" alt=""></td>
</tr>
<tr valign="middle">
<td align="left" colspan="2">
<a href="http://developer.apple.com/">ADC Home</a> > <a href="../../referencelibrary/index.html">Reference Library</a> > <a href="../../samplecode/index.html">Sample Code</a> > <a href="../../samplecode/Carbon/index.html">Carbon</a> > <a href="../../samplecode/Carbon/idxUserExperience-date.html">User Experience</a> > <A HREF="javascript:location.replace('index.html');">HTMLSample</A> >
</td>
</tr>
<tr>
<td colspan="2" scope="row"><img width="680" height="35" src="images/1dot.gif" alt=""></td>
</tr>
</table>
</div>
<!-- END BREADCRUMB -->
<div style="width:100%; position:fixed;"><div align="center" id="watermark" style="position: relative; margin-left:auto; margin-right:auto; z-index:20; width:500px;"><div class="legacybox"><h1>Not Recommended Document<span class=closebutton><a href="javascript:closeWatermark()"><img src="../../images/closebutton.png" width="14" height="14" border="0" alt="close button"></a></span></h1>
<p><strong>Important: </strong>The information in this document is <strong>Not Recommended</strong> and should not be used for new development.</p>
<div class="reflibtopic">
<p>Current information on this Reference Library topic can be found here:</p>
<ul>
<li><a href="http://developer.apple.com/referencelibrary/Carbon/idxUserExperience-date.html" target="_blank">Carbon > User Experience</a></li>
</ul>
</div>
</div></div></div>
<!-- START MAIN CONTENT -->
<!-- START TITLE GRAPHIC AND INTRO-->
<table width="680" border="0" cellpadding="0" cellspacing="0">
<tr align="left" valign="top">
<td><h1><div id="pagehead">HTMLSample</div></h1></td>
</tr>
</table>
<!-- END TITLE GRAPHIC AND INTRO -->
<!-- START WIDE COLUMN -->
<table width="680" border="0" cellpadding="0" cellspacing="0">
<tr align="left" valign="top">
<td id="scdetails">
<h2>/HTMLSample.c</h2>
<form name="scpopupmenu" onSubmit="return false;" method=post>
<p><strong>View Source Code:</strong>
<select name="gotop" onChange="JumpToNewPage();" style="width:340px"><option selected value="ingnore">Select File</option>
<option value="listing1.html">/AboutBox.c</option>
<option value="listing2.html">/AboutBox.h</option>
<option value="listing3.html">/CIconButtons.c</option>
<option value="listing4.html">/CIconButtons.h</option>
<option value="listing5.html">/CWDefines.h</option>
<option value="listing6.html">/debugf.c</option>
<option value="listing7.html">/debugf.h</option>
<option value="listing8.html">/History.c</option>
<option value="listing9.html">/History.h</option>
<option value="listing10.html">/HTMLSample Help/buttons.html</option>
<option value="listing11.html">/HTMLSample Help/index.html</option>
<option value="listing12.html">/HTMLSample Pages/docs/display.html</option>
<option value="listing13.html">/HTMLSample Pages/docs/drawing.html</option>
<option value="listing14.html">/HTMLSample Pages/docs/generalroutines.html</option>
<option value="listing15.html">/HTMLSample Pages/docs/index.html</option>
<option value="listing16.html">/HTMLSample Pages/docs/intro.html</option>
<option value="listing17.html">/HTMLSample Pages/docs/types.html</option>
<option value="listing18.html">/HTMLSample Pages/docs/userdefined.html</option>
<option value="listing19.html">/HTMLSample Pages/docs/utilities.html</option>
<option value="listing20.html">/HTMLSample Pages/error.html</option>
<option value="listing21.html">/HTMLSample Pages/index.html</option>
<option value="listing22.html">/HTMLSample.c</option>
<option value="listing23.html">/HTMLSample.h</option>
<option value="listing24.html">/HTMLSample.r</option>
<option value="listing25.html">/RenderingWindow.c</option>
<option value="listing26.html">/RenderingWindow.h</option>
<option value="listing27.html">/SampleUtils.c</option>
<option value="listing28.html">/SampleUtils.h</option></select>
</p>
</form>
<p><strong><a href="HTMLSample.zip">Download Sample</a></strong> (“HTMLSample.zip”, 279.4K)<BR>
<strong><a href="HTMLSample.dmg">Download Sample</a></strong> (“HTMLSample.dmg”, 330.4K)</p>
<!--
<p><strong><a href="#">Download Sample</a></strong> (“filename.sit”, 500K)</p>
-->
</td>
</tr>
<tr>
<td scope="row"><img width="680" height="10" src="images/1dot.gif" alt=""><br>
<img height="1" width="680" src="images/1dot_919699.gif" alt=""><br>
<img width="680" height="20" src="images/1dot.gif" alt=""></td>
</tr>
<tr>
<td scope="row">
<!--googleon: index -->
<pre class="sourcecodebox">/*
file HTMLSample.c
Description:
This file contains the main application program for the HTMLSample.
Routines in this file are responsible for handling events directed
at the application.
HTMLSample is an application illustrating how to use the new
HTMLRenderingLib services found in Mac OS 9. HTMLRenderingLib
is Apple's light-weight HTML rendering engine capable of
displaying HTML files.
by John Montbriand, 1999.
Copyright: © 1999 by Apple Computer, Inc.
all rights reserved.
Disclaimer:
You may incorporate this sample code into your applications without
restriction, though the sample code has been provided "AS IS" and the
responsibility for its operation is 100% yours. However, what you are
not permitted to do is to redistribute the source as "DSC Sample Code"
after having made changes. If you're going to re-distribute the source,
we require that you make it clear in the source that the code was
descended from Apple Sample Code, but that you've made changes.
Change History (most recent first):
10/16/99 created by John Montbriand
*/
#include "HTMLSample.h"
#include "debugf.h"
#ifdef __APPLE_CC__
#include <Carbon/Carbon.h>
#else
#include <Carbon.h>
#endif
#include <StdIO.h>
#include <StdArg.h>
#include <string.h>
#include "RenderingWindow.h"
#include "SampleUtils.h"
#include "AboutBox.h"
/* true while the app is running */
Boolean gRunning = true;
/* OpenOneFile is called for each file the application is asked to open
either by way of Apple event or from the file menu. spec points to
a file specification record referring to the file to open. The file will
be opened in a new window. */
static OSErr OpenOneFile(FSSpec *spec) {
Handle urlHandle, errorPageLink;
WindowPtr rWindow;
Str255 errStr;
OSErr err;
/* initial state */
urlHandle = NULL;
rWindow = NULL;
/* allocate locals */
urlHandle = NewHandle(0);
if (urlHandle == NULL) { err = memFullErr; goto bail; }
errorPageLink = GetResource(kCStyleStringResourceType, kErrorPageURLString);
if (errorPageLink == NULL) { err = resNotFound; goto bail; }
/* convert the fsspec to a url */
err = HRUtilGetURLFromFSSpec(spec, urlHandle);
if (err != noErr) goto bail;
/* open the window */
err = RWOpen(&rWindow);
if (err != noErr) goto bail;
/* attempt to open the url */
MoveHHi(urlHandle);
HLock(urlHandle);
err = RWGotoURL(rWindow, *urlHandle, true);
HUnlock(urlHandle);
/* if that fails, try to show the error page */
if (err != noErr) {
MoveHHi(errorPageLink);
HLock(errorPageLink);
err = RWGotoAppRelLink(rWindow, *errorPageLink, true);
HUnlock(errorPageLink);
if (err != noErr) goto bail;
}
/* clean up and leave */
DisposeHandle(urlHandle);
return noErr;
bail:
/* we display an alert here if there's an error. returning
an error from this routine will abort any open routine that
is going on--even if we're in the middle of a list of files. */
NumToString(err, errStr);
ParamAlert(kOpenFileErrorAlert, errStr, spec->name);
if (rWindow != NULL) RWCloseWindow(rWindow);
if (urlHandle != NULL) DisposeHandle(urlHandle);
return err;
}
/* IdentifyPackage identifies a Mac OS 9 package and returns a reference
to it's main file inside of mainPackageFile. In Mac OS 9, packages are
the special folders that have their bundle bits set and contain an alias
at their topmost level referring to a file somewhere in the package. */
static Boolean IdentifyPackage(FSSpec *target, FSSpec *mainPackageFile) {
CInfoPBRec cat;
OSErr err;
long pDir;
Str255 name;
FSSpec aliasFile;
Boolean targetIsFolder, wasAliased;
/* check the target's flags */
cat.dirInfo.ioNamePtr = target->name;
cat.dirInfo.ioVRefNum = target->vRefNum;
cat.dirInfo.ioFDirIndex = 0;
cat.dirInfo.ioDrDirID = target->parID;
err = PBGetCatInfoSync(&cat);
if (err != noErr) return false;
/* if it's a folder and the bundle bit is set....*/
if (((cat.dirInfo.ioFlAttrib & 16) != 0) && ((cat.dirInfo.ioDrUsrWds.frFlags & kHasBundle) != 0)) {
/* search for a top level alias file. Here, we enumerate all of the
objects in the directory until we find a file with the alias flag set. */
pDir = cat.dirInfo.ioDrDirID;
cat.dirInfo.ioNamePtr = name;
cat.dirInfo.ioVRefNum = target->vRefNum;
cat.dirInfo.ioFDirIndex = 1;
cat.dirInfo.ioDrDirID = pDir;
while (PBGetCatInfoSync(&cat) == noErr) {
/* if the thing we're looking at is not a directory and it's alias flag is set,
try to resolve it as an alias file. */
if (((cat.dirInfo.ioFlAttrib & 16) == 0) && ((cat.dirInfo.ioDrUsrWds.frFlags & kIsAlias) != 0)) {
err = FSMakeFSSpec(target->vRefNum, pDir, name, &aliasFile);
if (err != noErr) return false;
err = ResolveAliasFile(&aliasFile, false, &targetIsFolder, &wasAliased);
if (err != noErr) return false;
if (mainPackageFile != NULL)
*mainPackageFile = aliasFile;
return true;
}
/* move on to the next file in the directory. */
cat.dirInfo.ioFDirIndex++;
cat.dirInfo.ioDrDirID = pDir;
}
}
/* we found nothing matching our criteria, so we
fail. */
return false;
}
/* OpenTheDocuments is called to open a list of documents provided by
either an open documents Apple event or one of the Navigation services
dialogs. */
static OSErr OpenTheDocuments(AEDescList *theDocuments) {
OSErr err;
long i, n;
FSSpec fileSpec, packageSpec;
AEKeyword keyWd;
DescType typeCd;
Size actSz;
/* open them */
err = AECountItems(theDocuments, &n);
if (err != noErr) goto bail;
/* and then open each one */
for (i = 1 ; i <= n; i++) {
/* get the i'th FSSpec record. NOTE: implicity, we are calling
a coercion handler because this list actually contains alias records.
In particular, the coercion handler converts them from alias records
into FSSpec records. */
err = AEGetNthPtr(theDocuments, i, typeFSS, &keyWd, &typeCd,
(Ptr) &fileSpec, sizeof(fileSpec), (actSz = sizeof(fileSpec), &actSz));
if (err != noErr) goto bail;
/* if it's a package, we'll open it's main file, otherwise
we'll open the file itself */
if (IdentifyPackage(&fileSpec, &packageSpec))
err = OpenOneFile(&packageSpec);
else err = OpenOneFile(&fileSpec);
if (err != noErr) goto bail;
}
return noErr;
bail:
return err;
}
/* MyNavFilterProc This is the filter function we provide for the Navigation services
dialogs. We only allow files of type TEXT. */
static pascal Boolean MyNavFilterProc( AEDesc* theItem, void* info, NavCallBackUserData callBackUD, NavFilterModes filterMode) {
NavFileOrFolderInfo* theInfo;
if ( theItem->descriptorType == typeFSS ) {
theInfo = (NavFileOrFolderInfo*) info;
if ( theInfo->isFolder ) return true;
if ( theInfo->fileAndFolder.fileInfo.finderInfo.fdType != 'TEXT' )
return false;
}
return true;
}
/* NavEventCallBack is the event handling call back we provide for Navigation
services. It's presence is important so our windows will be updated appropriately
when the navigation window is resized or moved. */
static pascal void NavEventCallBack( NavEventCallbackMessage callBackSelector,
NavCBRecPtr callBackParms, NavCallBackUserData callBackUD) {
if (callBackSelector == kNavCBEvent && callBackParms->eventData.eventDataParms.event->what == updateEvt) {
HandleEvent(callBackParms->eventData.eventDataParms.event);
}
}
/* MyFileFilterProc is used by the older standard file calls. We fall back to
standard file when navigation services is not present or unavailable. In this
routine, we filter out all invisible files. */
static pascal Boolean MyFileFilterProc(CInfoPBPtr pb) {
/* don't display invisible files */
return ((pb->hFileInfo.ioFlFndrInfo.fdFlags & kIsInvisible) != 0);
}
/* SelectAndOpenFile is the inner workings of the Open... command
when it is chosen from the file menu. Here, we use the navigation
services dialogs when they are available, but if they're not, then we
use the standard file ones. */
static OSStatus SelectAndOpenFile(void) {
NavDialogOptions dialogOptions;
NavReplyRecord theReply;
NavEventUPP eventf;
NavObjectFilterUPP filterf;
Boolean hasreply;
OSStatus err;
/* set up locals */
eventf = NULL;
filterf = NULL;
hasreply = false;
BlockZero(&theReply, 0);
/* if Navigation services is available, then we
use those calls. */
if (NavServicesAvailable()) {
/* allocate data */
filterf = NewNavObjectFilterUPP(MyNavFilterProc);
if (filterf == NULL) { err = memFullErr; goto bail; }
eventf = NewNavEventUPP(NavEventCallBack);
if (eventf == NULL) { err = memFullErr; goto bail; }
/* set up dialog options */
err = NavGetDefaultDialogOptions(&dialogOptions);
if (err != noErr) goto bail;
/* NOTE: by setting the kNavAllowMultipleFiles flag, we make it possible
for the user to select more than one file. And, setting the kNavSupportPackages
flag allows us to open package documents. */
dialogOptions.dialogOptionFlags = (kNavDontAutoTranslate | kNavAllowMultipleFiles | kNavSupportPackages);
GetIndString(dialogOptions.message, kMainStringList, kNavMessageString);
/* pick one or more files */
err = NavChooseFile(NULL, &theReply, &dialogOptions, eventf, NULL, filterf, NULL, NULL);
if (err != noErr) goto bail;
if (!theReply.validRecord) { err = userCanceledErr; goto bail; }
hasreply = true;
/* if we have a valid reply, then call our
open documents routine. */
err = OpenTheDocuments(&theReply.selection);
if (err != noErr) goto bail;
/* clean up the structures we allocated */
NavDisposeReply(&theReply);
DisposeNavEventUPP(eventf);
DisposeNavObjectFilterUPP(filterf);
}
return noErr;
bail:
if (hasreply) NavDisposeReply(&theReply);
if (eventf != NULL) DisposeNavEventUPP(eventf);
if (filterf != NULL) DisposeNavObjectFilterUPP(filterf);
return err;
}
/* ResetMenus is called immediately before all calls to
MenuSelect or MenuKey. In this routine, we re-build
or enable the menus as appropriate depending on the
current environment */
static void ResetMenus(void) {
WindowPtr target;
target = FrontWindow();
/* if the front most window is a rendering
window, then we let the window handle the
menu. */
if (IsARenderingWindow(target))
RWResetGotoMenu(target);
else {
MenuHandle goMenu;
/* otherwise, we clear the menu
and disable all of its commands. */
goMenu = GetMenuHandle(mGo);
DisableMenuItem(goMenu, iBack);
DisableMenuItem(goMenu, iForward);
DisableMenuItem(goMenu, iHome);
while (CountMenuItems(goMenu) >= iGoSep)
DeleteMenuItem(goMenu, iGoSep);
}
}
/* DoMenuCommand is called in response to MenuKey
or MenuSelect. Here, we dispatch the menu command
to its appropriate handler, or if it's a small action
we do it here. */
static void DoMenuCommand(long rawMenuSelectResult) {
short menu, item;
/* decode the MenuSelect result */
menu = (rawMenuSelectResult >> 16);
if (menu == 0) return;
item = (rawMenuSelectResult & 0x0000FFFF);
/* dispatch on result */
switch (menu) {
/* apple menu commands */
case mApple:
if (item == iAbout) {
WindowPtr aboutBox;
OSStatus err;
/* open the about box */
err = OpenAboutBox(&aboutBox);
if (err != noErr) {
Str255 errStr;
NumToString(err, errStr);
ParamAlert(kNoAboutBoxErrorAlert, errStr, NULL);
}
}
break;
/* file menu commands */
case mFile:
if (item == iOpen) {
SelectAndOpenFile();
} else if (item == iQuit) {
if (CloseRenderingWindows() == noErr)
gRunning = false;
}
break;
/* selections in the Go menu are handled by
the frontmost rendering window. */
case mGo:
{ WindowPtr target;
target = FrontWindow();
if (IsARenderingWindow(target))
RWHandleGotoMenu(target, item);
}
break;
}
/* unhilite the menu bar */
HiliteMenu(0);
}
/* QuitAppleEventHandler is our quit Apple event handler. this routine
is called when a quit Apple event is sent to our application. Here,
we set the gRunning flag to false. NOTE: it is not appropriate to
call ExitToShell here. Instead, by setting the flag to false we
fall through the bottom of our main loop the next time we're called.
Here, if we are unable to close all of the rendering windows,
we return an error. This will abort the shutdown process,
if that's why we were called. */
static pascal OSErr QuitAppleEventHandler(const AppleEvent *appleEvt, AppleEvent* reply, long refcon) {
if (CloseRenderingWindows() == noErr) {
gRunning = false;
return noErr;
} else return userCanceledErr;
}
/* OpenAppleEventHandler is called when our application receives
an 'open application' apple event. Here, we put up a window
referring to the default page. */
static pascal OSErr OpenAppleEventHandler(const AppleEvent *appleEvt, AppleEvent* reply, long refcon) {
WindowPtr rWin;
Handle urlHandle;
OSErr err;
/* creat a rendering window. */
err = RWOpen(&rWin);
if (err != noErr) return err;
/* get the link to the default page from the resource
file. */
urlHandle = GetResource(kCStyleStringResourceType, kDefaultPageURLString);
if (urlHandle == NULL) return memFullErr;
/* lock down the resource and point the rendering
window at it. */
MoveHHi(urlHandle);
HLock(urlHandle);
RWGotoAppRelLink(rWin, *urlHandle, true);
HUnlock(urlHandle);
/* done */
return noErr;
}
/* ReOpenAppleEventHandler is called whenever the application receives
a re-open Apple event. This will happen if the application is already
running and the user attempts to open it again by either double clicking
on its icon in the Finder or by selecting its icon and choosing Open in
the Finder's file menu. Here, if there is no window showing, then we
open a new one as we would if an open application event was received. */
static pascal OSErr ReOpenAppleEventHandler(const AppleEvent *appleEvt, AppleEvent* reply, long refcon) {
if (FrontWindow() == NULL)
return OpenAppleEventHandler(appleEvt, reply, refcon);
else return noErr;
return noErr;
}
/* OpenDocumentsEventHandler is called whenever we receive an open documents
Apple event. Here, we extract the list of documents from the event
and pass them along to our OpenTheDocuments routine. */
static pascal OSErr OpenDocumentsEventHandler(const AppleEvent *appleEvt, AppleEvent* reply, long refcon) {
OSErr err;
AEDescList documents;
/* initial state */
AECreateDesc(typeNull, NULL, 0, &documents);
/* get the open parameter */
err = AEGetParamDesc(appleEvt, keyDirectObject, typeAEList, &documents);
if (err != noErr) goto bail;
/* open the documents */
err = OpenTheDocuments(&documents);
if (err != noErr) goto bail;
bail:
AEDisposeDesc(&documents);
return err;
}
/* HandleMouseDown is called for mouse down events. Processing of
mouse down events in the HTML rendering area of windows is
handled by the HTMLRenderinLib, but clicks in the controls and
other parts of the windows are handled here. */
static void HandleMouseDown(EventRecord *ev) {
WindowPtr theWindow;
short partcode;
Rect r;
partcode = FindWindow(ev->where, &theWindow);
switch (partcode) {
/* inside the window's content area */
case inContent:
if (theWindow != FrontWindow()) {
/* if it's not the frontmost window,
then make it the frontmost window. */
SelectWindow(theWindow);
} else {
/* otherwise, if it's a rendering window,
pass the click along to the window. */
Point where;
SetPortWindowPort(theWindow);
SetOrigin(0, 0);
where = ev->where;
GlobalToLocal(&where);
if (IsARenderingWindow(theWindow))
RWHandleMouseDown(theWindow, where);
}
break;
/* menu bar clicks */
case inMenuBar:
ResetMenus();
DoMenuCommand(MenuSelect(ev->where));
break;
/* track clicks in the close box */
case inGoAway:
if (TrackGoAway(theWindow, ev->where)) {
if (IsARenderingWindow(theWindow))
RWCloseWindow(theWindow);
else if (IsAboutBox(theWindow))
AboutBoxCloseWindow(theWindow);
}
break;
/* allow window drags */
case inDrag:
{ Rect boundsRect = {0,0, 32000, 32000};
DragWindow(theWindow, ev->where, &boundsRect);
}
break;
/* allow window drags */
case inGrow:
{ Rect sizerect;
long grow_result;
SetRect(&sizerect, 300, 150, 32767, 32767);
grow_result = GrowWindow(theWindow, ev->where, &sizerect);
if (grow_result != 0) {
SizeWindow(theWindow, LoWord(grow_result), HiWord(grow_result), true);
SetPortWindowPort(theWindow);
InvalWindowRect(theWindow, GetPortBounds(GetWindowPort(theWindow), &r));
if (IsARenderingWindow(theWindow))
RWRecalculateSize(theWindow);
}
}
break;
/* zoom box clicks. NOTE: since the rendering window
always sets the standard rectangle to the 'best size' for
displaying the current HTML window, the inZoomOut partcode
will zoom the window to that size rather than the entire screen.*/
case inZoomIn:
case inZoomOut:
SetPortWindowPort(theWindow);
EraseRect(GetPortBounds(GetWindowPort(theWindow), &r));
ZoomWindow(theWindow, partcode, true);
SetPortWindowPort(theWindow);
if (IsARenderingWindow(theWindow))
RWRecalculateSize(theWindow);
break;
}
}
/* HandleEvent is the main event handling routine for the
application. ev points to an event record returned by
WaitNextEvent. */
void HandleEvent(EventRecord *ev) {
WindowPtr target;
/* process menu key events */
if (((ev->what == keyDown) || (ev->what == autoKey)) && ((ev->modifiers & cmdKey) != 0)) {
ResetMenus();
DoMenuCommand(MenuKey((char) (ev->message & charCodeMask)));
ev->what = nullEvent;
}
/* process HR events. NOTE: this call handles most of the events
for the active HTML rendering object. But, be careful it may set
the clip region and origin of that window to an unknown state. */
if (HRIsHREvent(ev))
ev->what = nullEvent;
/* process other event types */
switch (ev->what) {
/* the application may be switching in to the forground
or into the background. Either way, we need to activate
the frontmost window accordingly. */
case osEvt:
/* the high byte of the message field contains the
osEvent kind. We're only interested in the case where
our application is either switching in or out of the
forground so we can draw our windows appropriately. */
if (((ev->message >> 24) & 255) == suspendResumeMessage) {
target = FrontWindow();
if (IsARenderingWindow(target))
RWActivate(target, ((ev->message & resumeFlag) != 0));
else if (IsAboutBox(target))
AboutBoxActivate(target, ((ev->message & resumeFlag) != 0));
}
break;
/* for activate events we call the window's activate event
handler. */
case activateEvt:
target = (WindowPtr) ev->message;
if (IsARenderingWindow(target))
RWActivate(target, ((ev->modifiers&1) != 0));
else if (IsAboutBox(target))
AboutBoxActivate(target, ((ev->modifiers&1) != 0));
break;
/* for update events we call the window's update event
handler. if the window is of an unknown type, we ignore the
event. */
case updateEvt:
target = (WindowPtr) ev->message;
if (IsARenderingWindow(target))
RWUpdate(target);
else if (IsAboutBox(target))
AboutBoxUpdate(target);
else {
BeginUpdate(target);
EndUpdate(target);
}
break;
/* for mouse events we call the the HandleMouseDown routine
defined above. */
case mouseDown:
HandleMouseDown(ev);
break;
/* for key down events we call the window's key down event
handler. */
case keyDown:
case autoKey:
target = FrontWindow();
if (IsARenderingWindow(target))
RWKeyDown(target, (char) (ev->message & charCodeMask));
break;
/* Apple events. */
case kHighLevelEvent:
AEProcessAppleEvent(ev);
break;
}
}
/* FDPIdleProcedure is the idle procedure called by AEInteractWithUser while we are waiting
for the application to be pulled into the forground. It simply passes the event along
to HandleNextEvent */
static pascal Boolean MyIdleInteractProc(EventRecord *theEvent, long *sleepTime, RgnHandle *mouseRgn) {
HandleEvent(theEvent);
return ( ! gRunning ); /* quit waiting if we're not running */
}
/* ParamAlert is a general alert handling routine. If Apple events exist, then it
calls AEInteractWithUser to ensure the application is in the forground, and then
it displays an alert after passing the s1 and s2 parameters to ParamText. */
short ParamAlert(short alertID, StringPtr s1, StringPtr s2) {
AEIdleUPP aeIdleProc;
OSStatus err;
aeIdleProc = NewAEIdleUPP(MyIdleInteractProc);
if (aeIdleProc == NULL) { err = memFullErr; goto bail; }
err = AEInteractWithUser(kNoTimeOut, NULL, aeIdleProc);
if (err != noErr) goto bail;
ParamText(s1, s2, NULL, NULL);
err = Alert(alertID, NULL);
DisposeAEIdleUPP(aeIdleProc);
return err;
bail:
if (aeIdleProc != NULL) DisposeAEIdleUPP(aeIdleProc);
return err;
}
/* MyGrowZone is called by the Memory Manager whenever it
cannot fulfil a memory request. Here, we try to get back
enough memory for the request by asking the HTML rendering
library to free up some cache space. */
static pascal long MyGrowZone(Size cbNeeded) {
return HRFreeMemory(cbNeeded);
}
/* the main program */
int main(void) {
OSStatus err;
Str255 errStr;
InitCursor();
/* install our event handlers */
err = AEInstallEventHandler(kCoreEventClass, kAEOpenApplication, NewAEEventHandlerUPP(OpenAppleEventHandler), 0, false);
if (err != noErr) goto bail;
err = AEInstallEventHandler(kCoreEventClass, 'rapp', NewAEEventHandlerUPP(ReOpenAppleEventHandler), 0, false);
if (err != noErr) goto bail;
err = AEInstallEventHandler(kCoreEventClass, kAEOpenDocuments, NewAEEventHandlerUPP(OpenDocumentsEventHandler), 0, false);
if (err != noErr) goto bail;
err = AEInstallEventHandler(kCoreEventClass, kAEQuitApplication, NewAEEventHandlerUPP(QuitAppleEventHandler), 0, false);
if (err != noErr) goto bail;
/* set up the menu bar */
SetMenuBar(GetNewMBar(kMenuBarID));
DrawMenuBar();
/* set up the rendering library */
if ( ! HRHTMLRenderingLibAvailable() ) {
ParamAlert(kNoRenderingLibErrorAlert, NULL, NULL);
err = userCanceledErr;
goto bail;
}
/* install our memory manger grow zone
routine. This will have to be done differently in
Mac OS X... */
SetGrowZone(NewGrowZoneUPP(MyGrowZone));
/* initialize the rendering windows library */
err = InitRenderingWindows();
if (err != noErr) goto bail;
/* run the app */
while (gRunning) {
EventRecord ev;
/* get the next event */
if ( ! WaitNextEvent(everyEvent, &ev, GetCaretTime(), NULL))
ev.what = nullEvent;
/* call our handler to deal with it. */
HandleEvent(&ev);
}
/* close all of our windows. */
CloseRenderingWindows();
EnsureAboutBoxIsClosed();
/* unregister ourselves with the appearance manager. */
UnregisterAppearanceClient();
ExitToShell();
return 0;
bail:
NumToString(err, errStr);
if (err != userCanceledErr)
ParamAlert(kOpenApplicationErrorAlert, errStr, NULL);
ExitToShell();
return 0;
}</pre>
<!--googleoff: index -->
</td>
</tr>
</table>
<!-- END WIDE COLUMN -->
<!-- END MAIN CONTENT -->
<table width="680" border="0" cellpadding="0" cellspacing="0">
<tr>
<td><div style="width: 100%; height: 1px; background-color: #919699; margin-top: 5px; margin-bottom: 15px"></div></td>
</tr>
<tr>
<td align="center"><br/>
<table border="0" cellpadding="0" cellspacing="0" class="graybox">
<tr>
<th>Did this document help you?</th>
</tr>
<tr>
<td>
<div style="margin-bottom: 8px"><a href="http://developer.apple.com/feedback/?v=1&url=/samplecode/HTMLSample/listing22.html%3Fid%3DDTS10000579-1.0&media=dvd" target=_new>Yes</a>: Tell us what works for you.</div>
<div style="margin-bottom: 8px"><a href="http://developer.apple.com/feedback/?v=2&url=/samplecode/HTMLSample/listing22.html%3Fid%3DDTS10000579-1.0&media=dvd" target=_new>It’s good, but:</a> Report typos, inaccuracies, and so forth.</div>
<div><a href="http://developer.apple.com/feedback/?v=3&url=/samplecode/HTMLSample/listing22.html%3Fid%3DDTS10000579-1.0&media=dvd" target=_new>It wasn’t helpful</a>: Tell us what would have helped.</div>
</td>
</tr>
</table>
</td>
</tr>
</table>
<!-- START BOTTOM APPLE NAVIGATION -->
<!--#include virtual="/includes/footer"-->
<!-- END BOTTOM APPLE NAVIGATION -->
<!-- START CENTER CLOSE -->
</center>
<!-- END CENTER CLOSE -->
</body>
</html>