Retired Document
Important: This sample code may not represent best practices for current development. The project may use deprecated symbols and illustrate technologies and techniques that are no longer recommended.
SampleUtils.c
/* |
file SampleUtils.c |
Description: |
This file contains a number of utility routines used by the |
HTMLSampleApplication. These routines have been moved |
here to a separate file to simplify the example. |
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 "SampleUtils.h" |
#ifdef __APPLE_CC__ |
#include <Carbon/Carbon.h> |
#else |
#include <Carbon.h> |
#endif |
#include <string.h> |
/* SUstrlen Sample Utilities strlen. Here so we don't have to link |
with the standard C libraries. */ |
long SUstrlen(char const* stt) { |
long count; |
char const* rover; |
for (count = 0, rover = stt; *rover; rover++, count++) |
/* empty loop */; |
return count; |
} |
/* SUstrcmp Sample Utilities strcmp. Here so we don't have to link |
with the standard C libraries. */ |
long SUstrcmp(char const* a, char const* b) { |
long res; |
char const *aa, *bb; |
aa = a; |
bb = b; |
while (*aa && *bb) |
if ((res = (*aa++ - *bb++)) != 0) |
return res; |
return (*aa - *bb); |
} |
/* SetWindowStandardStateSize sets the window's standard state rectangle |
to a rectangle of the size suggested in the width and height parameters. |
In the end, it may set the standard size to something smaller than the |
width and height parameters so the entire window remains visible. The |
standard rectangle is also centered on the main screen. The window's |
standard state rectangle is used by ZoomWindow whenever when it |
is called with the inZoomOut partcode. */ |
void SetWindowStandardStateSize(WindowPtr window, short width, short height) { |
Rect standard, stdRect, global, device, c, s, diffs; |
RgnHandle tempRgn; |
GDHandle theDevice; |
CGrafPtr wport; |
Point origin; |
/* make the window's port the current port */ |
wport = GetWindowPort(window); |
SetPort(wport); |
SetPt(&origin, 0, 0); |
LocalToGlobal(&origin); |
/* find the window's global coordinates */ |
GetPortBounds(wport, &global); |
OffsetRect(&global, origin.h, origin.v); |
/* get the maximum intersecting screen */ |
theDevice = GetMaxDevice(&global); |
device = (**theDevice).gdRect; |
/* if it's the main screen, adjust it for the menu bar height */ |
if (theDevice == GetMainDevice()) |
device.top += GetMBarHeight(); |
/* calculate the difference between the window's content rectangle and its frame */ |
tempRgn = NewRgn(); |
GetWindowRegion(window, kWindowContentRgn, tempRgn); |
GetRegionBounds(tempRgn, &c); |
GetWindowRegion(window, kWindowStructureRgn, tempRgn); |
GetRegionBounds(tempRgn, &s); |
DisposeRgn(tempRgn); |
SetRect(&diffs, c.left - s.left + 2, c.top - s.top + 2, s.right - c.right + 2, s.bottom - c.bottom + 2); |
/* calculate the maximum bounds for the standard rectangle */ |
SetRect(&standard, device.left + diffs.left, device.top + diffs.top, device.right - diffs.right, device.bottom - diffs.bottom); |
/* set up our 'desired' rectangle */ |
SetRect(&stdRect, 0, 0, width, height); |
OffsetRect(&stdRect, standard.left, standard.top); |
/* fit it inside of the maximum allowable rectangle */ |
SectRect(&stdRect, &standard, &stdRect); |
/* center it in the maximum allowable rectangle */ |
OffsetRect(&stdRect, (standard.right - stdRect.right)/2, (standard.bottom - stdRect.bottom)/2); |
/* set the standard state rectangle */ |
SetWindowStandardState(window, &stdRect); |
} |
/* GetApplicationFolder returns a URL referring to the folder |
containing the application. If successful, *url is set |
to a new handle containing the URL. It is the caller's |
responsibility to dispose of this handle. */ |
OSStatus GetApplicationFolderURL(Handle *url) { |
OSStatus err; |
FSSpec spec; |
Handle theURL; |
/* set up locals to a known state */ |
theURL = NULL; |
/* find the application's folder */ |
err = GetApplicationFolder(&spec); |
if (err != noErr) goto bail; |
/* create a new handle for storing the URL */ |
theURL = NewHandle(0); |
if (theURL == NULL) { err = memFullErr; goto bail; } |
/* ask the HTML rendering library to convert |
the FSSpec into a URL */ |
err = HRUtilGetURLFromFSSpec(&spec, theURL); |
if (err != noErr) goto bail; |
/* add a slash at the end of the name, if one is not there */ |
if ( (*theURL)[GetHandleSize(theURL) - 2] != '/') |
Munger(theURL, (GetHandleSize(theURL) - 1), NULL, 0, "/", 1); |
/* return the URL */ |
*url = theURL; |
return noErr; |
bail: |
if (theURL != NULL) DisposeHandle(theURL); |
return err; |
} |
/* GetApplicationFolder returns the volume reference number and |
directory id of the folder containing the application. */ |
OSStatus GetApplicationFolder(FSSpec *spec) { |
OSStatus err; |
FCBPBRec fcpb; |
Str255 name; |
CInfoPBRec cat; |
Handle h; |
h = GetResource('vTeZ', 0); |
if (h == NULL) return resNotFound; |
BlockZero(&fcpb, 0); |
fcpb.ioVRefNum = 0; |
fcpb.ioNamePtr = name; |
fcpb.ioFCBParID = 0; |
fcpb.ioRefNum = HomeResFile(h); |
fcpb.ioFCBIndx = 0; |
if ((err = PBGetFCBInfoSync(&fcpb)) != noErr) return err; |
BlockZero(&cat, 0); |
cat.dirInfo.ioNamePtr = name; |
cat.dirInfo.ioVRefNum = fcpb.ioFCBVRefNum; |
cat.dirInfo.ioFDirIndex = -1; |
cat.dirInfo.ioDrDirID = fcpb.ioFCBParID; |
err = PBGetCatInfoSync(&cat); |
if (err != noErr) return err; |
err = FSMakeFSSpec(fcpb.ioFCBVRefNum, cat.dirInfo.ioDrParID, name, spec); |
if (err != noErr) return err; |
return noErr; |
} |
/* DrawGrowIconWithoutScrollLines draws the grow icon in the bottom |
right corner of the frontmost window without drawing the scroll bar |
lines. It does this by setting the clip region to the bottom right corner |
before calling DrawGrowIcon. */ |
void DrawGrowIconWithoutScrollLines(WindowPtr window) { |
RgnHandle clip; |
CGrafPtr wport; |
Rect r = { 0, 0, 16, 16 }, pbox; |
/* set the window to the current port */ |
wport = GetWindowPort(window); |
SetPort(wport); |
GetPortBounds(wport, &pbox); |
/* save the old clipping region */ |
clip = NewRgn(); |
if (clip == NULL) return; |
GetClip(clip); |
/* set the clipping region to the bottom right corner of the window */ |
OffsetRect(&r, pbox.right-15, pbox.bottom-15); |
ClipRect(&r); |
/* draw the grow icon */ |
DrawGrowIcon(window); |
SetPort(wport); |
SetClip(clip); |
DisposeRgn(clip); |
} |
/* GrayOutBox grays out an area of the screen in the current grafport. |
*theBox is in local coordinates in the current grafport. This routine |
is for direct screen drawing only. */ |
void GrayOutBox(Rect *theBox) { |
long response; |
Rect globalBox; |
GDHandle maxDevice; |
RGBColor rgbWhite = {0xFFFF, 0xFFFF, 0xFFFF}, rgbBlack = {0, 0, 0}, sForground, sBackground; |
PenState penSave; |
Pattern qdgray, qdblack; |
/* save the current drawing state */ |
GetPenState(&penSave); |
/* if no color quickdraw, fail...*/ |
if (Gestalt(gestaltQuickdrawVersion, &response) != noErr) response = 0; |
if (response >= gestalt8BitQD) { |
/* get the device for the rectangle */ |
globalBox = *theBox; |
LocalToGlobal((Point*) &globalBox.top); |
LocalToGlobal((Point*) &globalBox.bottom); |
maxDevice = GetMaxDevice(&globalBox); |
if (maxDevice != NULL) { |
/* calculate the best gray */ |
if ( GetGray(maxDevice, &rgbWhite, &rgbBlack)) { |
/* draw over the area in gray using addMax transfer mode */ |
GetForeColor(&sForground); |
GetBackColor(&sBackground); |
RGBForeColor(&rgbBlack); |
RGBBackColor(&rgbWhite); |
PenMode(addMax); |
PenPat(GetQDGlobalsBlack(&qdblack)); |
PaintRect(theBox); |
RGBForeColor(&sForground); |
RGBBackColor(&sBackground); |
/* restore the pen state and leave */ |
SetPenState(&penSave); |
return; |
} |
} |
} |
/* fall through to using the gray pattern */ |
GetQDGlobalsGray(&qdgray); |
PenPat(&qdgray); |
PenMode(notPatBic); |
PaintRect(theBox); |
SetPenState(&penSave); |
} |
Copyright © 2003 Apple Computer, Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2003-01-30