-
Notifications
You must be signed in to change notification settings - Fork 3
/
listing52.html
executable file
·1445 lines (1188 loc) · 50.8 KB
/
listing52.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
<!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>QISA - /QISA.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/Networking/index.html">Networking</a> > <a href="../../samplecode/Networking/idxDarwin-date.html">Darwin</a> > <A HREF="javascript:location.replace('index.html');">QISA</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 -->
<!-- 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">QISA</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>/QISA.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">/MoreIsBetter Bits/MoreIsBetter/MIB-Libraries/MoreAppearance/MoreAppearance.cp</option>
<option value="listing2.html">/MoreIsBetter Bits/MoreIsBetter/MIB-Libraries/MoreAppearance/MoreAppearance.h</option>
<option value="listing3.html">/MoreIsBetter Bits/MoreIsBetter/MIB-Libraries/MoreAppleEvents/MoreAEDataModel.c</option>
<option value="listing4.html">/MoreIsBetter Bits/MoreIsBetter/MIB-Libraries/MoreAppleEvents/MoreAEDataModel.h</option>
<option value="listing5.html">/MoreIsBetter Bits/MoreIsBetter/MIB-Libraries/MoreAppleEvents/MoreAEObjects.c</option>
<option value="listing6.html">/MoreIsBetter Bits/MoreIsBetter/MIB-Libraries/MoreAppleEvents/MoreAEObjects.h</option>
<option value="listing7.html">/MoreIsBetter Bits/MoreIsBetter/MIB-Libraries/MoreAppleEvents/MoreAppleEvents.cp</option>
<option value="listing8.html">/MoreIsBetter Bits/MoreIsBetter/MIB-Libraries/MoreAppleEvents/MoreAppleEvents.h</option>
<option value="listing9.html">/MoreIsBetter Bits/MoreIsBetter/MIB-Libraries/MoreCarbonEvents/MoreCarbonEvents.c</option>
<option value="listing10.html">/MoreIsBetter Bits/MoreIsBetter/MIB-Libraries/MoreCarbonEvents/MoreCarbonEvents.h</option>
<option value="listing11.html">/MoreIsBetter Bits/MoreIsBetter/MIB-Libraries/MoreCFQ/MoreCFQ.c</option>
<option value="listing12.html">/MoreIsBetter Bits/MoreIsBetter/MIB-Libraries/MoreCFQ/MoreCFQ.h</option>
<option value="listing13.html">/MoreIsBetter Bits/MoreIsBetter/MIB-Libraries/MoreControls/MoreControls.cp</option>
<option value="listing14.html">/MoreIsBetter Bits/MoreIsBetter/MIB-Libraries/MoreControls/MoreControls.h</option>
<option value="listing15.html">/MoreIsBetter Bits/MoreIsBetter/MIB-Libraries/MoreDialogs/MoreDialogs.cp</option>
<option value="listing16.html">/MoreIsBetter Bits/MoreIsBetter/MIB-Libraries/MoreDialogs/MoreDialogs.h</option>
<option value="listing17.html">/MoreIsBetter Bits/MoreIsBetter/MIB-Libraries/MoreInterfaceLib/MoreInterfaceLib.c</option>
<option value="listing18.html">/MoreIsBetter Bits/MoreIsBetter/MIB-Libraries/MoreInterfaceLib/MoreInterfaceLib.h</option>
<option value="listing19.html">/MoreIsBetter Bits/MoreIsBetter/MIB-Libraries/MoreInterfaceLib/RemoteAccessInterface.h</option>
<option value="listing20.html">/MoreIsBetter Bits/MoreIsBetter/MIB-Libraries/MoreMemory/MoreMemory.c</option>
<option value="listing21.html">/MoreIsBetter Bits/MoreIsBetter/MIB-Libraries/MoreMemory/MoreMemory.h</option>
<option value="listing22.html">/MoreIsBetter Bits/MoreIsBetter/MIB-Libraries/MoreOSUtils/MoreOSUtils.c</option>
<option value="listing23.html">/MoreIsBetter Bits/MoreIsBetter/MIB-Libraries/MoreOSUtils/MoreOSUtils.h</option>
<option value="listing24.html">/MoreIsBetter Bits/MoreIsBetter/MIB-Libraries/MoreProcesses/MoreProcesses.cp</option>
<option value="listing25.html">/MoreIsBetter Bits/MoreIsBetter/MIB-Libraries/MoreProcesses/MoreProcesses.h</option>
<option value="listing26.html">/MoreIsBetter Bits/MoreIsBetter/MIB-Libraries/MoreQuickDraw/MoreQuickDraw.cp</option>
<option value="listing27.html">/MoreIsBetter Bits/MoreIsBetter/MIB-Libraries/MoreQuickDraw/MoreQuickDraw.h</option>
<option value="listing28.html">/MoreIsBetter Bits/MoreIsBetter/MIB-Libraries/MoreSCF/MoreSCF.c</option>
<option value="listing29.html">/MoreIsBetter Bits/MoreIsBetter/MIB-Libraries/MoreSCF/MoreSCF.h</option>
<option value="listing30.html">/MoreIsBetter Bits/MoreIsBetter/MIB-Libraries/MoreSCF/MoreSCFCCLScanner.c</option>
<option value="listing31.html">/MoreIsBetter Bits/MoreIsBetter/MIB-Libraries/MoreSCF/MoreSCFCCLScanner.h</option>
<option value="listing32.html">/MoreIsBetter Bits/MoreIsBetter/MIB-Libraries/MoreSCF/MoreSCFDigest.c</option>
<option value="listing33.html">/MoreIsBetter Bits/MoreIsBetter/MIB-Libraries/MoreSCF/MoreSCFDigest.h</option>
<option value="listing34.html">/MoreIsBetter Bits/MoreIsBetter/MIB-Libraries/MoreSCF/MoreSCFHelpers.c</option>
<option value="listing35.html">/MoreIsBetter Bits/MoreIsBetter/MIB-Libraries/MoreSCF/MoreSCFHelpers.h</option>
<option value="listing36.html">/MoreIsBetter Bits/MoreIsBetter/MIB-Libraries/MoreSCF/MoreSCFPortScanner.c</option>
<option value="listing37.html">/MoreIsBetter Bits/MoreIsBetter/MIB-Libraries/MoreSCF/MoreSCFPortScanner.h</option>
<option value="listing38.html">/MoreIsBetter Bits/MoreIsBetter/MIB-Libraries/MoreSecurity/MoreSecurity.c</option>
<option value="listing39.html">/MoreIsBetter Bits/MoreIsBetter/MIB-Libraries/MoreSecurity/MoreSecurity.h</option>
<option value="listing40.html">/MoreIsBetter Bits/MoreIsBetter/MIB-Libraries/MoreSetup.h</option>
<option value="listing41.html">/MoreIsBetter Bits/MoreIsBetter/MIB-Libraries/MoreTextUtils/MoreTextUtils.cp</option>
<option value="listing42.html">/MoreIsBetter Bits/MoreIsBetter/MIB-Libraries/MoreTextUtils/MoreTextUtils.h</option>
<option value="listing43.html">/MoreIsBetter Bits/MoreIsBetter/MIB-Libraries/MoreUNIX/MoreUNIX.c</option>
<option value="listing44.html">/MoreIsBetter Bits/MoreIsBetter/MIB-Libraries/MoreUNIX/MoreUNIX.h</option>
<option value="listing45.html">/MoreIsBetter Bits/MoreIsBetter/MIB-Libraries/MoreWindows/MoreWindows.cp</option>
<option value="listing46.html">/MoreIsBetter Bits/MoreIsBetter/MIB-Libraries/MoreWindows/MoreWindows.h</option>
<option value="listing47.html">/MoreIsBetter Bits/MoreIsBetter/MIB-Libraries/NetworkSetup/MoreNetworkSetup.c</option>
<option value="listing48.html">/MoreIsBetter Bits/MoreIsBetter/MIB-Libraries/NetworkSetup/MoreNetworkSetup.h</option>
<option value="listing49.html">/MoreIsBetter Bits/MoreIsBetter/MIB-Libraries/NetworkSetup/NetworkSetupHelpers.c</option>
<option value="listing50.html">/MoreIsBetter Bits/MoreIsBetter/MIB-Libraries/NetworkSetup/NetworkSetupHelpers.h</option>
<option value="listing51.html">/MoreIsBetter Bits/MoreIsBetter/MIB-Libraries/NetworkSetup/OldStyleAPI/OldOTConfigLib.h</option>
<option value="listing52.html">/QISA.c</option>
<option value="listing53.html">/QISA.h</option>
<option value="listing54.html">/QISAPanels.c</option>
<option value="listing55.html">/QISAPanels.h</option>
<option value="listing56.html">/QISAPlatform.c</option>
<option value="listing57.html">/QISAPlatform.h</option>
<option value="listing58.html">/QISAPlatformCFM/QISAPlatformCFM.c</option>
<option value="listing59.html">/QISAPlatformCFM/QISAPlatformCFMPrefix.h</option>
<option value="listing60.html">/QISAPlatformMach-O/QISAPlatformMach-O.c</option>
<option value="listing61.html">/QISAPlatformMach-O/QISASetupTool.c</option>
<option value="listing62.html">/ReadMeAboutQISA.html</option></select>
</p>
</form>
<p><strong><a href="QISA.zip">Download Sample</a></strong> (“QISA.zip”, 610.6K)<BR>
<strong><a href="QISA.dmg">Download Sample</a></strong> (“QISA.dmg”, 903.9K)</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: QISA.c Contains: Main application for QISA program. Written by: DTS Copyright: Copyright © 2002 by Apple Computer, Inc., All Rights Reserved. Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc. ("Apple") in consideration of your agreement to the following terms, and your use, installation, modification or redistribution of this Apple software constitutes acceptance of these terms. If you do not agree with these terms, please do not use, install, modify or redistribute this Apple software. In consideration of your agreement to abide by the following terms, and subject to these terms, Apple grants you a personal, non-exclusive license, under Apple's copyrights in this original Apple software (the "Apple Software"), to use, reproduce, modify and redistribute the Apple Software, with or without modifications, in source and/or binary forms; provided that if you redistribute the Apple Software in its entirety and without modifications, you must retain this notice and the following text and disclaimers in all such redistributions of the Apple Software. Neither the name, trademarks, service marks or logos of Apple Computer, Inc. may be used to endorse or promote products derived from the Apple Software without specific prior written permission from Apple. Except as expressly stated in this notice, no other rights or licenses, express or implied, are granted by Apple herein, including but not limited to any patent rights that may be infringed by your derivative works or by other works in which the Apple Software may be incorporated. The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. Change History (most recent first):*//////////////////////////////////////////////////////////////////// System interfaces#if defined(__MACH__) #include <Carbon/Carbon.h>#else #include <Gestalt.h> #include <Dialogs.h> #include <Menus.h> #include <IBCarbonRuntime.h> #include <PLStringFuncs.h>#endif#include <stdio.h>#include <stdlib.h>#include <assert.h>// MoreIsBetter interfaces#include "MoreCFQ.h"#include "MoreDialogs.h"#include "MoreControls.h"#include "MoreAppleEvents.h"#include "MoreOSUtils.h"// Our interfaces#include "QISAPanels.h"#include "QISA.h"#include "QISAPlatform.h"/////////////////////////////////////////////////////////////////#pragma mark ***** State and Panels// Right now the panels are managed via a large constant data structure. // I don't support plug-in panels. The main reason for this is time: // I wanted to ship and doing plug-in panels would have slowed me down. // However, I have kept a high degree of separation between the panels // and QISA itself, so there's very little excluding plug-in panels in // the future.enum { kQISAStatePanelCount = 4};// QISAState represents the state for a QISA setup window. // Within this structure there is an array that holds the // state for each panel.//// A reference to this state is stored in the window's refCon.static const OSType kQISAStateMagic = 'QISA';struct QISAState { OSType magic; // must be kQISAStateMagic WindowRef mainWindow; // the setup window EventHandlerRef eventHandler; // reference to our event handler ControlRef tabControl; // reference to the tab control within the window Rect tabBounds; // bounds of tabControl, in window coordinates ControlRef leftButton; // reference to the left button control within the window ControlRef rightButton; // reference to the right button control within the window QISAPanel * currentPanel; // reference to the current panel, always points within state->panels QISAPanel panels[kQISAStatePanelCount]; // an array of per-panel data structures ControlRef focusedControl[kQISAStatePanelCount]; // for each panel, a reference to the control that had // the keyboard focus when we switched from the panel CFMutableDictionaryRef globalValues; // global values, see "QISA.h" for the API that accesses this};static const OSType kQISAPanelMagic = 'PANL';extern Boolean QISAIsPanelValid(const QISAPanel *panel) // See comment in header.{ return (panel->magic == kQISAPanelMagic) && (panel->state != NULL) && (panel->index >= 0) && (panel->index < kQISAStatePanelCount) && (panel->window != NULL) && (panel->Initialise != NULL) && (panel->Terminate != NULL) && (panel->SwitchTo != NULL) && (panel->SwitchFrom != NULL) ;}static Boolean QISAIsStateValid(const QISAState *state) // For debugging. Returns true if state is valid.{ Boolean result; int panel; result = (state->magic == kQISAStateMagic)// && (state->mainWindow != NULL) // window can be NULL invalid during termination && (state->tabControl != NULL) && (state->leftButton != NULL) && (state->rightButton != NULL) && (state->currentPanel >= &state->panels[0]) && (state->currentPanel <= &state->panels[ kQISAStatePanelCount - 1]) && (state->globalValues != NULL); ; if (result) { for (panel = 0; panel < kQISAStatePanelCount; panel++) { if (state->panels[panel].initialised && ! QISAIsPanelValid(&state->panels[panel]) ) { result = false; } } } return result;}extern Boolean QISAIsButtonEnabled(QISAPanel *panel, QISAPanelSwitchDirection direction) // See comment in header.{ Boolean result; ControlRef button; assert(QISAIsPanelValid(panel)); assert(QISAIsStateValid(panel->state)); switch (direction) { case kQISAPanelSwitchDirectionForward: button = panel->state->rightButton; break; case kQISAPanelSwitchDirectionBackward: button = panel->state->leftButton; break; default: assert(false); button = NULL; result = false; break; } if (button != NULL) { result = IsControlActive(button); } return result;}extern void QISASetButtonEnable(QISAPanel *panel, QISAPanelSwitchDirection direction, Boolean enable) // See comment in header.{ ControlRef button; assert(QISAIsPanelValid(panel)); assert(QISAIsStateValid(panel->state)); switch (direction) { case kQISAPanelSwitchDirectionForward: button = panel->state->rightButton; break; case kQISAPanelSwitchDirectionBackward: button = panel->state->leftButton; break; default: assert(false); button = NULL; break; } if (button != NULL) { SetControlActive(button, enable); }}extern OSStatus QISAGetGlobalValue(const QISAPanel *panel, CFStringRef key, CFPropertyListRef *value) // See comment in header.{ OSStatus err; assert(QISAIsPanelValid(panel)); assert(QISAIsStateValid(panel->state)); assert(key != NULL); assert(value != NULL); if ( CFDictionaryGetValueIfPresent(panel->state->globalValues, key, (const void **) value) ) { err = noErr; } else { *value = NULL; err = kCFQKeyNotFoundErr; } assert( (err == noErr) == (*value != NULL) ); return err;}extern OSStatus QISASetGlobalValue(const QISAPanel *panel, CFStringRef key, CFPropertyListRef value) // See comment in header.{ OSStatus err; assert(QISAIsPanelValid(panel)); assert(QISAIsStateValid(panel->state)); assert(key != NULL); if (value == NULL) { CFDictionaryRemoveValue(panel->state->globalValues, key); err = noErr; } else { CFDictionarySetValue(panel->state->globalValues, key, value); err = noErr; } return err;}extern OSStatus QISACopyGlobalsDict(const QISAPanel *panel, CFMutableDictionaryRef *result) // See comment in header.{ OSStatus err; assert(QISAIsPanelValid(panel)); assert(QISAIsStateValid(panel->state)); assert( result != NULL); assert(*result == NULL); *result = CFDictionaryCreateMutableCopy(NULL, 0, panel->state->globalValues); err = CFQError(*result); assert( (err == noErr) == (*result != NULL) ); return err;}static OSStatus SwitchFromPanel(QISAState *state, QISAPanelSwitchDirection direction, QISAPanel **nextPanel) // Switches away from the current panel in the specified // direction and returns the next panel that should be // switched to. This is called as part of handling // the forward and back buttons (ChangeToNewPanel).{ OSStatus err; OSStatus junk; assert(QISAIsStateValid(state)); assert(nextPanel != NULL); err = state->currentPanel->SwitchFrom(state->currentPanel, direction, nextPanel); if (err == noErr) { // Save the keyboard focus for the panel we just switched from // and then clear the focus. If you don't do this, then weird // things happen (for example, an insertion point in an edit // text control in the hidden panel will keep blinking on top // of the new panel!). junk = GetKeyboardFocus(state->mainWindow, &state->focusedControl[state->currentPanel->index]); assert(junk == noErr); junk = ClearKeyboardFocus(state->mainWindow); assert(junk == noErr); // Hide the current panel's root control (which hides all of // its embedded sub-controls). HideControl(state->currentPanel->panelControl); } assert( (err != noErr) || (*nextPanel >= &state->panels[0]) && (*nextPanel <= &state->panels[kQISAStatePanelCount - 1]) ); return err;}static OSStatus SwitchToPanel(QISAState *state, QISAPanel *newPanel) // Switches to a new panel. This is called as part of handling // the forward and back buttons (ChangeToNewPanel) but is also called // when the window is created to switch to the initial panel.{ OSStatus err; OSStatus junk; assert(QISAIsStateValid(state)); assert( (newPanel >= &state->panels[0]) && (newPanel <= &state->panels[kQISAStatePanelCount - 1]) ); // If the panel plug-in has not yet been initialised, initialise it. // Wow, lazy code. Bertrand would be so happy. err = noErr; if ( ! newPanel->initialised ) { err = newPanel->Initialise(newPanel); newPanel->initialised = (err == noErr); } // Switch the tab control to the right panel and show that panel's // sub-controls. if (err == noErr) { SetControlValue(state->tabControl, (SInt16) (newPanel->index + 1)); ShowControl(newPanel->panelControl); } // Run the plug-in's SwitchTo routine. if (err == noErr) { err = newPanel->SwitchTo(newPanel); } // Restore the panel's saved keyboard focus (if any). // If the SwitchTo proc established focus, leave that alone, // otherwise see whether we've remembered focus from a previous // switch from this panel and restore that, otherwise use // AdvanceKeyboardFocus to focus the first item. if (err == noErr) { ControlRef focusedControl; if ( (GetKeyboardFocus(state->mainWindow, &focusedControl) != noErr) || (focusedControl == NULL) ) { focusedControl = state->focusedControl[newPanel->index]; if (focusedControl == NULL) { junk = AdvanceKeyboardFocus(state->mainWindow); assert( (junk == noErr) || (junk == errCouldntSetFocus) ); } else { junk = SetKeyboardFocus(state->mainWindow, focusedControl, kControlFocusNextPart); assert(junk == noErr); } } } // Finally, record the new panel as the current panel. if (err == noErr) { state->currentPanel = newPanel; } assert(QISAIsStateValid(state)); // post condition return err;}static OSStatus ChangeToNewPanel(QISAState *state, QISAPanelSwitchDirection direction) // Change to the next panel in the specified direction. Called when // the user clicks on the forward or back buttons. { OSStatus err; OSStatus junk; QISAPanel * oldPanel; QISAPanel * nextPanel; assert(QISAIsStateValid(state)); oldPanel = state->currentPanel; err = SwitchFromPanel(state, direction, &nextPanel); // At this point we're in a weird state because currentPanel no longer // matches the controls in the window. Let's get out of that state ASAP, // and hopefully without errors. if (err == noErr) { assert( (nextPanel >= &state->panels[0]) && (nextPanel <= &state->panels[kQISAStatePanelCount - 1]) ); err = SwitchToPanel(state, nextPanel); // If the new panel opened cleanly, we're good. Otherwise, // try to switch back to the old panel. We ignore any // errors coming from the SwitchToPanel(state, oldPanel) // because we're already going to return a (hopefully valid) // error that we get from SwitchToPanel(state, nextPanel). if (err != noErr) { junk = SwitchToPanel(state, oldPanel); assert(junk == noErr); } } return err;}static QISAState *GetWindowQISAState(WindowRef window) // Returns the QISA state for a window. This will tolerate // window being NULL, and return NULL in that case.{ QISAState *state; state = NULL; if (window != NULL) { state = (QISAState *) GetWRefCon(window); } if (state != NULL) { assert(QISAIsStateValid(state)); } return state;}static void DisposeQISAState(QISAState *state) // Disposes of the QISA state and it's corresponding // sub-structures.{ OSStatus junk; int panel; assert(state->magic == kQISAStateMagic); for (panel = 0; panel < kQISAStatePanelCount; panel++) { if (state->panels[panel].initialised) { (void) state->panels[panel].Terminate(&state->panels[panel]); } } // Remove the event handler *before* disposing of the window // because otherwise WindowEventHandler will be sent the // kEventClassWindow/kEventWindowClosed event and will // call DisposeQISAState, which is bad. if (state->eventHandler != NULL) { junk = RemoveEventHandler(state->eventHandler); assert(junk == noErr); } if (state->mainWindow != NULL) { DisposeWindow(state->mainWindow); } CFQRelease(state->globalValues); state->magic = 'Free'; // overwrite magic to detect double dispose free(state);}/////////////////////////////////////////////////////////////////#pragma mark ***** Default Panel// The default panel routines represent the default implementation // of the panel callbacks. If a panel does not specifically // override those callbacks, this is what they do. See the // panel initialisation routines in "QISAPanels.c" for examples // of how these routines are overridden.static OSStatus DefaultPanelInitialise(QISAPanel *panel) // See PanelInitialiseProc comments. Default implementation.{ #pragma unused(panel) assert( QISAIsPanelValid(panel) ); assert( QISAIsStateValid(panel->state) ); return noErr;}static void DefaultPanelTerminate(QISAPanel *panel) // See PanelTerminateProc comments. Default implementation.{ #pragma unused(panel) assert( QISAIsPanelValid(panel) ); assert( QISAIsStateValid(panel->state) );}static OSStatus DefaultPanelSwitchTo(QISAPanel *panel) // See PanelSwitchToProc comments. Default implementation.{ QISAState *state; assert( QISAIsPanelValid(panel) ); assert( QISAIsStateValid(panel->state) ); state = panel->state; // Enables the forward button if this isn't the last panel, // and the backward button if this isn't the first panel. QISASetButtonEnable(panel, kQISAPanelSwitchDirectionForward, (panel != &state->panels[kQISAStatePanelCount - 1]) ); QISASetButtonEnable(panel, kQISAPanelSwitchDirectionBackward, (panel != &state->panels[0]) ); return noErr;}static OSStatus DefaultPanelSwitchFrom(QISAPanel *panel, QISAPanelSwitchDirection direction, QISAPanel **nextPanel) // See PanelSwitchFromProc comments. Default implementation.{ assert( QISAIsPanelValid(panel) ); assert( QISAIsStateValid(panel->state) ); assert(nextPanel != NULL); // Returns the next or previous panel. if (direction == kQISAPanelSwitchDirectionForward) { *nextPanel = (panel + 1); } else { assert(direction == kQISAPanelSwitchDirectionBackward); *nextPanel = (panel - 1); } assert( (*nextPanel >= &panel->state->panels[0]) && (*nextPanel <= &panel->state->panels[kQISAStatePanelCount - 1]) ); return noErr;}/////////////////////////////////////////////////////////////////#pragma mark ***** UI Commands// These HI commands are sent when the forward and back buttons // are pressed (or their equivalent menu commands are chosen).enum { kHICommandLeft = 'LEFT', kHICommandRight = 'RGHT'};static EventHandlerUPP gWindowEventHandlerUPP; // -> WindowEventHandler static const EventTypeSpec kWindowEvents[] = { {kEventClassCommand, kEventCommandProcess}, {kEventClassWindow, kEventWindowClose}, {kEventClassWindow, kEventWindowClosed} };static pascal OSStatus WindowEventHandler(EventHandlerCallRef inHandlerCallRef, EventRef inEvent, void *inUserData) // The Carbon event handler for the window. This processes the // left and right button HI commands and a two stage close operation.{ OSStatus err; UInt32 eventClass; UInt32 eventKind; QISAState * state; #pragma unused(inHandlerCallRef) state = (QISAState *) inUserData; assert( QISAIsStateValid(state) ); eventClass = GetEventClass(inEvent); eventKind = GetEventKind(inEvent); if ( (eventClass == kEventClassCommand) && (eventKind == kEventCommandProcess) ) { HICommand command; err = GetEventParameter(inEvent, kEventParamDirectObject, typeHICommand, NULL, sizeof(command), NULL, &command); if (err == noErr) { switch (command.commandID) { case kHICommandLeft: case kHICommandRight: err = ChangeToNewPanel(state, command.commandID == kHICommandRight ? kQISAPanelSwitchDirectionForward : kQISAPanelSwitchDirectionBackward); QISADisplayError(NULL, err, CFSTR("SwitchingToThePanel")); err = noErr; break; default: err = eventNotHandledErr; break; } } } else if ( (eventClass == kEventClassWindow) && (eventKind == kEventWindowClose) ) { // The user has asked to close the window. If we're on any panel other than // the first panel, then call SwitchFromPanel to stop the current panel. // If the panel is busy, it can put up a dialog requesting user confirmation, // and return userCanceledErr if it did. err = noErr; if (state->currentPanel != &state->panels[0]) { QISAPanel *junkNextPanel; err = SwitchFromPanel(state, kQISAPanelSwitchDirectionBackward, &junkNextPanel); } // If we get no error, then we're ready to close the window. We return // eventNotHandledErr, which causes the standard close handler to run. // This calls DisposeWindow on our window, which sends us the event // kEventClassWindow/kEventWindowClosed, which we use to dispose of our // state. if (err == noErr) { err = eventNotHandledErr; } } else if ( (eventClass == kEventClassWindow) && (eventKind == kEventWindowClosed) ) { // The window is already being disposed of. NULL out our reference // so that DisposeQISAState does not try to dispose it again. state->mainWindow = NULL; // Get rid of our per-window state. DisposeQISAState(state); err = noErr; } else { assert(false); // this event shouldn't have been delivered to us err = eventNotHandledErr; } return err;}static OSStatus CopyGlobalValuesFromFile(CFMutableDictionaryRef *result) // This routine is called by QISACommandNew to initialise the // global values dictionary from the contents of a plist file // within the application package.{ OSStatus err; CFURLRef url; CFMutableDictionaryRef localResult; CFDictionaryRef platformDict; assert( result != NULL); assert(*result == NULL); localResult = NULL; platformDict = NULL; // Read default prefs from a resource within the application package. url = CFBundleCopyResourceURL(CFBundleGetMainBundle(), CFSTR("SetupInfo"), CFSTR("plist"), NULL); err = CFQError(url); if (err == noErr) { err = CFQPropertyListCreateFromXMLCFURL(url, kCFPropertyListMutableContainers, (CFPropertyListRef *) &localResult); } if (err == noErr) { if ( CFGetTypeID(localResult) != CFDictionaryGetTypeID() ) { err = kCFQDataErr; } } // Merge in the properties from the platform plug-in. if (err == noErr) { err = QISACopyPlatformProperties(&platformDict); } if (err == noErr) { err = CFQDictionaryMerge(localResult, platformDict); } // In the debug build, merge in preferences from another debugging version // of the file. This allows me to have an Apple-private dialup line configured // while I'm debugging, but not ship that info as part of the sample. #if ! defined(NDEBUG) if (err == noErr) { CFDictionaryRef debugDict; CFQRelease(url); debugDict = NULL; url = CFBundleCopyResourceURL(CFBundleGetMainBundle(), CFSTR("SetupInfoDebug"), CFSTR("plist"), NULL); err = CFQError(url); if (err == noErr) { err = CFQPropertyListCreateFromXMLCFURL(url, kCFPropertyListImmutable, (CFPropertyListRef *) &debugDict); } if (err == noErr) { if ( CFGetTypeID(debugDict) != CFDictionaryGetTypeID() ) { err = kCFQDataErr; } } if (err == noErr) { err = CFQDictionaryMerge(localResult, debugDict); } CFQRelease(debugDict); if (err != noErr) { DebugStr("\pCopyGlobalValuesFromFile: Error loading SetupInfoDebug.plist ; g"); err = noErr; } } // CFShow(localResult); #endif // Clean up. if (err == noErr) { *result = localResult; } else { CFQRelease(localResult); } CFQRelease(url); CFQRelease(platformDict); assert( (err == noErr) == (*result != NULL) ); return err;}// The following array is used to construct the per-panel data structure. // It contains the initialisation routine for each panel, in order. This // is currently hard-wired, and is one of the key things that would have // to change if panel plug-ins were used.static const PanelInitialiseProc kPanelInitialisers[kQISAStatePanelCount] = { PortCCLPanelInitialise, UserPassPanelInitialise, SetupPanelInitialise, DefaultPanelInitialise };static OSStatus QISACommandNew(void) // Handles the "New" HI command by creating a new setup window.{ OSStatus err; IBNibRef nibRef; QISAState * state; int panel; nibRef = NULL; // Allocate the per-window state. err = noErr; state = (QISAState *) calloc(1, sizeof(*state)); if (state == NULL) { err = memFullErr; } if (err == noErr) { state->magic = kQISAStateMagic; } // Create the window from the NIB. if (err == noErr) { err = CreateNibReference(CFSTR("QISAWindow"), &nibRef); } if (err == noErr) { err = CreateWindowFromNib(nibRef, CFSTR("MainWindow"), &state->mainWindow); } // Initialise the state based on the window. if (err == noErr) { SetWRefCon(state->mainWindow, (long) state); } if (err == noErr) { err = GetControlByIDQ(state->mainWindow, 'TAB!', 0, &state->tabControl); } if (err == noErr) { (void) GetControlBounds(state->tabControl, &state->tabBounds); } if (err == noErr) { err = GetControlByIDQ(state->mainWindow, 'LBTN', 0, &state->leftButton); } if (err == noErr) { err = GetControlByIDQ(state->mainWindow, 'RBTN', 0, &state->rightButton); } if (err == noErr) { err = CopyGlobalValuesFromFile(&state->globalValues); } // Setup each panel. We don't actually call the Initialise proc // here, but instead do it lazily in SwitchToPanel. if (err == noErr) { for (panel = 0; panel < kQISAStatePanelCount; panel++) { state->panels[panel].magic = kQISAPanelMagic; state->panels[panel].state = state; state->panels[panel].index = panel; state->panels[panel].window = state->mainWindow; state->panels[panel].Initialise = kPanelInitialisers[panel]; state->panels[panel].Terminate = DefaultPanelTerminate; state->panels[panel].SwitchTo = DefaultPanelSwitchTo; state->panels[panel].SwitchFrom = DefaultPanelSwitchFrom; err = GetControlByIDQ(state->mainWindow, 'Panl', panel, &state->panels[panel].panelControl); if (err == noErr) { HideControl(state->panels[panel].panelControl); } if (err != noErr) { break; } } } // Install the window's Carbon event handler. if (err == noErr) { if (gWindowEventHandlerUPP == NULL) { gWindowEventHandlerUPP = NewEventHandlerUPP(WindowEventHandler); assert(gWindowEventHandlerUPP != NULL); } err = InstallWindowEventHandler(state->mainWindow, gWindowEventHandlerUPP, GetEventTypeCount(kWindowEvents), kWindowEvents, state, &state->eventHandler); } // Switch to the first panel. if (err == noErr) { state->currentPanel = &state->panels[0]; err = SwitchToPanel(state, state->currentPanel); } // Show the window, and we're done. if (err == noErr) { ShowWindow(state->mainWindow); } // Clean up. if (nibRef != NULL) { DisposeNibReference(nibRef); } if (err != noErr && state != NULL) { DisposeQISAState(state); } QISADisplayError(NULL, err, CFSTR("CreatingTheNewDocument")); return err;}static OSStatus QISACommandAbout(void) // Handles the "About" HI command.{ OSStatus err; ProcessSerialNumber myPSN; CFStringRef errStr; CFStringRef expStr; SInt16 junkHit; errStr = NULL; expStr = NULL; // First line of alert is the name of the application, from the "Info.plist". myPSN.highLongOfPSN = 0; myPSN.lowLongOfPSN = kCurrentProcess; errStr = NULL; err = CopyProcessName(&myPSN, &errStr); // Second line is a string from "Localizable.strings". if (err == noErr) { expStr = CFCopyLocalizedString(CFSTR("AboutBoxCopyright"), CFSTR("ASampleInternetSetupAssistantBlahBlahBlah")); err = CFQError(expStr); } // Now display an alert using our StandardAlert wrapper. if (err == noErr) { err = StandardAlertCFStringCompat(kAlertNoteAlert, errStr, expStr, NULL, &junkHit); } CFQRelease(expStr); CFQRelease(errStr); QISADisplayError(NULL, err, CFSTR("DisplayingTheAboutBox")); return err;}static EventHandlerUPP gApplicationEventHandlerUPP; // -> ApplicationEventHandlerstatic const EventTypeSpec kApplicationEvents[] = { {kEventClassCommand, kEventCommandProcess} };static pascal OSStatus ApplicationEventHandler(EventHandlerCallRef inHandlerCallRef, EventRef inEvent, void *inUserData) // The Carbon event handler for the application. This processes the // "New" and "About" HI commands.{ OSStatus err; HICommand command; #pragma unused(inHandlerCallRef) #pragma unused(inUserData) assert( GetEventClass(inEvent) == kEventClassCommand ); assert( GetEventKind(inEvent) == kEventCommandProcess); err = GetEventParameter(inEvent, kEventParamDirectObject, typeHICommand, NULL, sizeof(command), NULL, &command); if (err == noErr) { switch (command.commandID) { case kHICommandAbout: (void) QISACommandAbout(); break; case kHICommandNew: (void) QISACommandNew(); break; default: err = eventNotHandledErr; break; } } return err;}static EventHandlerUPP gEditMenuEventHandlerUPP; // -> EditMenuEventHandlerstatic const EventTypeSpec kEditMenuEvents[1] = { {kEventClassMenu, kEventMenuEnableItems} };static pascal OSStatus EditMenuEventHandler(EventHandlerCallRef inHandlerCallRef, EventRef inEvent, void *inUserData) // The Carbon event handler for the Edit menu. This enables // and disables the forward and back menu commands base // on the state of the buttons (which are kept up-to-date // by the panels).{ OSStatus err; MenuRef menuH; #pragma unused(inHandlerCallRef) #pragma unused(inUserData) assert( GetEventClass(inEvent) == kEventClassMenu ); assert( GetEventKind( inEvent) == kEventMenuEnableItems ); err = GetEventParameter(inEvent, kEventParamDirectObject, typeMenuRef, NULL, sizeof(menuH), NULL, &menuH); if (err == noErr) { QISAState * state; Boolean leftEnable; Boolean rightEnable; leftEnable = false; rightEnable = false; state = GetWindowQISAState(FrontWindow()); if (state != NULL) { leftEnable = IsControlActive(state->leftButton ); rightEnable = IsControlActive(state->rightButton); } if (leftEnable) { EnableMenuCommand(menuH, kHICommandLeft); } else { DisableMenuCommand(menuH, kHICommandLeft); } if (rightEnable) { EnableMenuCommand(menuH, kHICommandRight); } else { DisableMenuCommand(menuH, kHICommandRight); } } return err;}/////////////////////////////////////////////////////////////////#pragma mark ***** Apple event handlingstatic AEEventHandlerUPP gNewAppleEventHandlerUPP; // -> NewAppleEventHandlerstatic pascal OSErr NewAppleEventHandler(const AppleEvent *theAppleEvent, AppleEvent *reply, long handlerRefcon) // The Apple event handler for the 'oapp' and 'rapp' Apple events. // This basically just calls QISACommandNew. Note that it only calls // QISACommandNew if it's an "open application" event or it's a // "re-open application" event and there's no front window.{ OSStatus err; assert(theAppleEvent != NULL); assert(reply != NULL); assert( (handlerRefcon == kAEOpenApplication) || (handlerRefcon == kAEReopenApplication) ); err = MoreAEGotRequiredParams(theAppleEvent); if (err == noErr) { if ( (handlerRefcon == kAEOpenApplication) || (FrontWindow() == NULL) ) { err = QISACommandNew(); } } return (OSErr) err;}/////////////////////////////////////////////////////////////////#pragma mark ***** Error Handling// Change the "1" to a "0" to have QISADisplayError print each // of its temporary strings. This greatly helps in debugging.#if 1 || defined(NDEBUG) #define CFShowDebugString(str) #else static void CFShowDebugString(CFStringRef str) // Show a CFString in a way that can be seen on both traditional // Mac OS and Mac OS X. { Str255 pStr; if ( MoreRunningOnMacOSX() ) { CFShow(str); } else { if ( CFStringGetPascalString(str, pStr, sizeof(pStr), kCFStringEncodingMacRoman) ) { (void) PLstrcat(pStr, "\p;g"); DebugStr(pStr); } } } #endifextern void QISADisplayError(QISAPanel *panel, OSStatus errNum, CFStringRef actionKey) // See comment in header.{ assert( (panel == NULL) || (QISAIsPanelValid(panel)) ); assert(actionKey != NULL); if ( (errNum != noErr) && (errNum != userCanceledErr) && (AEInteractWithUser(1 * 60 * 60, NULL, NULL) == noErr) ) { OSStatus err; SInt16 junkItemHit; CFStringRef localizedAction; CFStringRef errNumKey; CFStringRef localizedErrNum; CFStringRef errStrFormat; CFStringRef expStrFormat; CFStringRef errStr; CFStringRef expStr; localizedAction = NULL; errNumKey = NULL; localizedErrNum = NULL; errStrFormat = NULL; expStrFormat = NULL; errStr = NULL; expStr = NULL; // Localize the action. localizedAction = CFCopyLocalizedString(actionKey, NULL); err = CFQError(localizedAction); CFShowDebugString(localizedAction); // Localize the error. if (err == noErr) { errNumKey = CFStringCreateWithFormat(NULL, NULL, CFSTR("%ld"), errNum); err = CFQError(errNumKey); CFShowDebugString(errNumKey); } if (err == noErr) { localizedErrNum = CFBundleCopyLocalizedString(CFBundleGetMainBundle(), errNumKey, NULL, CFSTR("Errors")); err = CFQError(localizedErrNum); CFShowDebugString(localizedErrNum); if ( (err == noErr) && CFEqual(localizedErrNum, errNumKey) ) { CFQRelease(localizedErrNum); localizedErrNum = CFBundleCopyLocalizedString(CFBundleGetMainBundle(), CFSTR("default"), NULL, CFSTR("Errors")); err = CFQError(localizedErrNum); CFShowDebugString(localizedErrNum); } } // Create the error and explanation strings. if (err == noErr) { errStrFormat = CFCopyLocalizedString(CFSTR("ErrorStringFormat"), CFSTR("Error%@")); err = CFQError(errStrFormat); CFShowDebugString(errStrFormat); } if (err == noErr) { errStr = CFStringCreateWithFormat(NULL, NULL, errStrFormat, localizedAction); err = CFQError(errStr); CFShowDebugString(errStr); } if (err == noErr) { expStrFormat = CFCopyLocalizedString(CFSTR("ErrorExplanationStringFormat"), CFSTR("TheOperationFailedBecause%@(%@)")); err = CFQError(expStrFormat); CFShowDebugString(expStrFormat); } if (err == noErr) { expStr = CFStringCreateWithFormat(NULL, NULL, expStrFormat, localizedErrNum, errNumKey); err = CFQError(expStr); CFShowDebugString(expStr); } // Display the dialog. if (err == noErr) { err = StandardAlertCFStringCompat(kAlertStopAlert, errStr, expStr, NULL, &junkItemHit); } // If the above fails, use an emergency non-localized dialog. if (err != noErr) { #if defined(NDEBUG) (void) StandardAlert(kAlertStopAlert, "\pUnknown error", "\p", NULL,o &junkItemHit); #else DebugStr("\pQISADisplayError: Got an error displaying the error!"); #endif } CFQRelease(localizedAction); CFQRelease(errNumKey); CFQRelease(localizedErrNum); CFQRelease(errStrFormat); CFQRelease(expStrFormat); CFQRelease(errStr); CFQRelease(expStr); }}/////////////////////////////////////////////////////////////////#pragma mark ***** Startupstatic SInt16 kEditMenuID = 130;static OSStatus SetupMenus(void) // Sets up the menu bar.{ OSStatus err; IBNibRef nibRef; Handle menuBar; nibRef = NULL; menuBar = NULL; // Use a different NIB depending on whether you're running // on traditional Mac OS or Mac OS X. if ( MoreRunningOnMacOSX() ) { err = CreateNibReference(CFSTR("QISAMenus"), &nibRef); } else { err = CreateNibReference(CFSTR("QISAMenus9"), &nibRef); } if (err == noErr) { err = CreateMenuBarFromNib(nibRef, CFSTR("MainMenuBar"), &menuBar); } if (err == noErr) { SetMenuBar(menuBar); } // Install a Carbon event handler for the Edit menu to handler // enabling and disabling of the forward and back menu items. if (err == noErr) { MenuRef menuH; menuH = GetMenuHandle(kEditMenuID); assert(menuH != NULL); gEditMenuEventHandlerUPP = NewEventHandlerUPP(EditMenuEventHandler); assert(gEditMenuEventHandlerUPP != NULL); err = InstallMenuEventHandler(menuH, gEditMenuEventHandlerUPP, GetEventTypeCount(kEditMenuEvents), kEditMenuEvents, NULL, NULL); } // Clean up. if (nibRef != NULL) { DisposeNibReference(nibRef); } if (menuBar != NULL) { DisposeHandle(menuBar); } return err;}int main(int argc, char **argv) // The application's entry point! Some platform version checking, // following by some initialisation, following by the main event loop.{ OSStatus err; UInt32 version; #pragma unused(argc) #pragma unused(argv) #if !defined(NDEBUG) && TARGET_RT_MAC_CFM if ( GetCurrentKeyModifiers() & optionKey ) { DebugStr("\pQISA main"); } #endif err = noErr; version = GetSystemVersion(); if (version < 0x0910) { // Right now we've only tested on 9.1 and above. We should bring this // requirement down at some later time. err = 5500; } else if ( (GetSystemVersion() >= 0x01000) && (GetSystemVersion() < 0x01010) ) { // 10.0.x is not supported because it does not have a public // System Configuration framework API. err = 5501; } if (err == noErr) { err = Gestalt(gestaltCarbonVersion, (SInt32 *) &version); } if ( (err == noErr) && (GetSystemVersion() < 0x01000) && (version < 0x00000160) ) { // We've only tested with CarbonLib 1.6, so we won't run on earlier versions. // However, we only care about gestaltCarbonVersion on Mac OS 9. Versions of // Mac OS X prior to 10.2 have lower gestaltCarbonVersion and that's OK. err = 5502; } if ( (err == noErr) && MoreRunningOnClassic() ) { err = 5503; } if (err == noErr) { err = QISAPlatformInit(CFBundleGetMainBundle()); } if (err == noErr) { err = SetupMenus(); } if (err == noErr) { gApplicationEventHandlerUPP = NewEventHandlerUPP(ApplicationEventHandler); assert(gApplicationEventHandlerUPP != NULL); err = InstallApplicationEventHandler(gApplicationEventHandlerUPP, GetEventTypeCount(kApplicationEvents), kApplicationEvents, NULL, NULL); } if (err == noErr) { gNewAppleEventHandlerUPP = NewAEEventHandlerUPP(NewAppleEventHandler); assert(gNewAppleEventHandlerUPP != NULL); err = AEInstallEventHandler(kCoreEventClass, kAEOpenApplication, gNewAppleEventHandlerUPP, kAEOpenApplication, false); if (err == noErr) { err = AEInstallEventHandler(kCoreEventClass, kAEReopenApplication, gNewAppleEventHandlerUPP, kAEReopenApplication, false); } } if (err == noErr) { RunApplicationEventLoop(); } QISADisplayError(NULL, err, CFSTR("StartingUp")); 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/QISA/listing52.html%3Fid%3DDTS10000714-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/QISA/listing52.html%3Fid%3DDTS10000714-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/QISA/listing52.html%3Fid%3DDTS10000714-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>