// 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;
}
Esempio n. 2
0
//
//	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;
}