// window instance management NWindow* NCarbonWindowManager::New(const NString & sImplementationName, const NRect & rWindBounds, const NString & sWindCaption, bool bWindowVisible) { OSStatus err; NWindow *aWindow = NULL; WindowRef macWindow = NULL; DialogRef macDialog = NULL; NWindowImplementation *refImp = GetWindowImpByName(sImplementationName); Rect r = rWindBounds.AsQDRect(); NUInt32 iRC; // need an implementation if(refImp == NULL) return NULL; // extract info from implementation, convert to mac style class + attr NWindowClass iWinClass = refImp->ImplementationWindowClass(); NWindowFeatures iWinFeatures = refImp->ImplementationWindowFeatures(); WindowClass iMacClass = 0; WindowAttributes iMacAttrs = 0; if(iWinClass == kWindowClassDialog) { // get dialog items Handle h = refImp->GetInitialMacDialogItems(); if(h == NULL) return NULL; // create dialog macDialog = NewFeaturesDialog(NULL, &r, "\p", bWindowVisible, kWindowDocumentProc, (WindowPtr)-1, (iWinFeatures & kWindowFeatureHasCloseBox) != 0, 0, h, kDialogFlagsUseThemeBackground | kDialogFlagsUseControlHierarchy | kDialogFlagsUseThemeControls); if(macDialog == NULL) return NULL; } else { // create a WindowRef if(iWinClass == kWindowClassUtility) { iMacClass = kUtilityWindowClass; } else { if(iWinFeatures & kWindowFeatureHasBorder) iMacClass = kDocumentWindowClass; else iMacClass = kFloatingWindowClass; } if((iWinFeatures & kWindowFeatureIsResizeableH) || (iWinFeatures & kWindowFeatureIsResizeableV)) iMacAttrs |= kWindowResizableAttribute; if(iWinFeatures & kWindowFeatureHasCloseBox) iMacAttrs |= kWindowCloseBoxAttribute; if(iWinFeatures & kWindowFeatureIsMinimizable) iMacAttrs |= kWindowCollapseBoxAttribute; if(iWinFeatures & kWindowFeatureIsMaximizable) iMacAttrs |= kWindowFullZoomAttribute; // create mac window err = CreateNewWindow(iMacClass, iMacAttrs, &r, &macWindow); if(err != noErr) return NULL; } // determine window handle to pass as refcon for NWindow if(iWinClass == kWindowClassDialog) iRC = (NUInt32)GetDialogWindow(macDialog); else iRC = (NUInt32)macWindow; // create NWindow, link macwindow/nwindow aWindow = new NWindow("CarbonWindow", iWinClass, iWinFeatures, rWindBounds, refImp->Clone(), iRC); if(iWinClass == kWindowClassDialog) SetWRefCon(GetDialogWindow(macDialog), (NUInt32)aWindow); else SetWRefCon(macWindow, (NUInt32)aWindow); // set caption, make visible aWindow->SetCaption(sWindCaption); aWindow->SetVisible(bWindowVisible); if(bWindowVisible) aWindow->BringToFront(); return aWindow; }
// // AskIfNewResolutionWorks() creates a dialog box in the center of the screen. The dialog asks the // user if the current display setting works. This is necessary because a number of display settings // listed by the OS dont actually work and leave the user with a black screen. The dialog has a 5 // second timeout. If the user does not hit ok within 5 seconds the cancel item is chosen automatically // for him. This feature allows the user to do nothing (which he will probably do if confronted by a // black screen) and still be ok. The method that I have employed to do the timeout requires Appearances // 1.1. I believe this was introduced with OS 8.5. If you want to support back to OS 8.1, then you will // have to do your own modal dialog event proc that implements a timeout. The dialog has not default // button by default. Cmd-period and esc trigger the cancel button. // // OSStatus AskIfNewResolutionWorks( ScreenRef screen ) { DEBUGMESSAGE( "Querying user whether the new resolution works...." ); if( ! screen ) return noErr; //Read the new screen dimensions RLDrawInfo screenData; Rect dialogBounds = {0,0,130, 340}; OSStatus error = GetCurrentScreenDrawingInfo( screen, &screenData ); if( error ) { DEBUGMESSAGE( "Unable to get current screen drawing information. Got back error # " << error ); return error; } //Make a copy of our dialog item list. This will be destroyed when the dialog is destroyed. Handle ditlCopy = LoadDITL(); HandToHand( &ditlCopy ); //Center the dialog rect on the screen { SInt32 horizontalOffset = (SInt32( screenData.bounds.right) + SInt32( screenData.bounds.left ) - SInt32(dialogBounds.right) + SInt32(dialogBounds.left) ) / 2; SInt32 verticalOffset = (SInt32( screenData.bounds.bottom) + SInt32( screenData.bounds.top ) - SInt32(dialogBounds.bottom) + SInt32(dialogBounds.top) ) / 2; dialogBounds.left += horizontalOffset; dialogBounds.right += horizontalOffset; dialogBounds.top += verticalOffset; dialogBounds.bottom += verticalOffset; } //Init a new dialog hidden DialogPtr dialog = NewFeaturesDialog( NULL, &dialogBounds, "\pResolution Verification", true, kWindowModalDialogProc, (WindowPtr) -1L, false, TickCount(), ditlCopy, 0 ); if( ! dialog ) { DEBUGMESSAGE( "Unable to init the \"AskIfNewResolutionWorks\" dialog window. Perhaps there is insufficient free memory or the DITL did not load properly at library startup?" ); return rlOutOfMemory; } //Make sure the dialog cancel item is button # 2 SetDialogCancelItem( dialog, 2 ); //Set dialog to timeout after 5 seconds SetDialogTimeout( dialog, 2, 5 ); for( bool done = false; !done; ) { short itemHit = 0; ModalDialog ( NULL, &itemHit ); switch( itemHit ) { case 2: //cancel DEBUGMESSAGE( "The user hit cancel or the dialog timed out. The new resolution is probably not good." ); done = true; error = rlRezNotFound; break; case 3: //ok DEBUGMESSAGE( "The user hit ok. The new resolution seems to be Okay!" ); done = true; error = noErr; break; } } DisposeDialog( dialog ); return error; }