bool ConsoleOverlayWindow::Create(DWORD consoleWindowThreadId)
{
	_hWndConsole = ::GetConsoleWindow();
	_consoleWindowThreadId = consoleWindowThreadId;

	// create the overlay window
	_hWndOverlay = CreateOverlayWindow();
	if (!_hWndOverlay)
		return false;

	// create the selection view window
	if (!_selectionView.Create(_hWndConsole, _hWndOverlay))
		return false;

	// create the tooltip for displaying the console's size while resizing
	if (!_sizeTooltip.Create(_hWndOverlay))
		debug_print("ConsoleOverlayWindow::Create - _sizeTooltip.Create failed, err=%#x\n", ::GetLastError());

	ReOpenConsoleHandles();

	SetupWinEventHooks();

	// place the overlay window directly above the console window
	AdjustOverlayPosition();
	AdjustOverlayZOrder();

	// register for OnSizeChanged notification 
	_resizeOperation.OnSizeChanged([this]() 
	{
		auto changed = ResizeConsole(_resizeOperation.GetRectangle());

		// while the resize operation continues
		if (_resizeOperation.IsActive())
		{
			// update the tooltip to display the current size of the console
			if (changed)
				UpdateSizeTooltipText();
		}
		// when the resize operation finished
		else
		{
			// hide the tooltip and adjust the overlay position for the final size of the console
			_sizeTooltip.Show(false);
			AdjustOverlayPosition();
		}
	});

	// HACK: without this the console's WinEvents are arriving with a delay. it is especially 
	// noticeable when scrolling the console while there is a selection showing.
	// experiments have shown that events are arriving just fine for other applications that
	// are not actually attached to the console.
	// TODO: find out why.
	::SetTimer(NULL, 0, 10, [](HWND, UINT, UINT_PTR, DWORD){
		// an empty timer handler also does the trick.
		// it seems that just by setting a timer, the WinEvents arriving without a delay.
		//::PostMessage(::GetConsoleWindow(), WM_NULL, 0, 0);
		//::PostThreadMessage(::GetCurrentThreadId(), WM_NULL, 0, 0);
	});

	return true;
}
Example #2
0
void wxOverlayImpl::Init( wxWindowDC* dc, int x , int y , int width , int height )
{
    wxASSERT_MSG( !IsOk() , _("You cannot Init an overlay twice") );

    m_window = dc->GetWindow();
    m_x = x ;
    m_y = y ;
    if ( dc->IsKindOf( CLASSINFO( wxClientDC ) ))
    {
        wxPoint origin = m_window->GetClientAreaOrigin();
        m_x += origin.x;
        m_y += origin.y;
    }
    m_width = width ;
    m_height = height ;

    OSStatus err = CreateOverlayWindow();
    wxASSERT_MSG(  err == noErr , _("Couldn't create the overlay window") );
#ifndef __LP64__
    err = QDBeginCGContext(GetWindowPort(m_overlayWindow), &m_overlayContext);
#endif
    CGContextTranslateCTM( m_overlayContext, 0, m_height );
    CGContextScaleCTM( m_overlayContext, 1, -1 );
    CGContextTranslateCTM( m_overlayContext, -m_x , -m_y );
    wxASSERT_MSG(  err == noErr , _("Couldn't init the context on the overlay window") );
}
Example #3
0
static	pascal	OSStatus SimpleWindowEventHandlerProc( EventHandlerCallRef inCallRef, EventRef inEvent, void* inUserData )
{
	#pragma unused ( inCallRef )
	HICommand				command;
	Point					pt;
	SInt16					value;
	Rect					r;
	WindowGroupRef			windowGroup;
	WindowGroupAttributes	windowGroupAttributes;
	UInt32					eventKind		= GetEventKind( inEvent );
	UInt32					eventClass		= GetEventClass( inEvent );
	WindowRef				window			= (WindowRef) inUserData;
	OSStatus				err				= eventNotHandledErr;
	WindowStorage			*windowStorage	= (WindowStorage*) GetWRefCon( window );

	switch ( eventClass )
	{
		case kEventClassWindow:
			if ( eventKind == kEventWindowClose )	//	Dispose extra window storage here
			{
				if ( windowStorage->overlayWindow != NULL )	SendWindowCloseEvent( windowStorage->overlayWindow );
				DisposePtr( (Ptr) windowStorage );
			}
			else if ( eventKind == kEventWindowClickContentRgn )
			{
				if ( GetControlValueByID( window, 'Butn', 0 ) == 1 )	//	If the "Line Tool" button is depressed
				{
					LineTool( window );
					SetControlValueByID( window, 'Butn', 0, 0 );		//	Pop the button back up
					err	= noErr;
				}
			}
			else if ( (eventKind == kEventWindowBoundsChanging) || (eventKind == kEventWindowBoundsChanged) )
			{
				if ( windowStorage->overlayWindow != NULL )				//	Resize the overlay window as well
				{
					(void) GetEventParameter( inEvent, kEventParamCurrentBounds, typeQDRectangle, NULL, sizeof(Rect), NULL, &r );
					SizeWindow( windowStorage->overlayWindow, r.right-r.left, r.bottom-r.top, false );
				}
			}
			break;
			
		case kEventClassCommand:
			if ( eventKind == kEventCommandProcess )
			{
				GetEventParameter( inEvent, kEventParamDirectObject, typeHICommand, NULL, sizeof(HICommand), NULL, &command );
				if ( command.commandID == kHICommandOK )								//	Change the window layering and attributes
				{
					value	= GetControlValueByID( window, 'Rdio', 0 );					//	Which group was chosen
					
					windowGroupAttributes	= 0;										//	Now set the attributes for the parent group
					if ( GetControlValueByID( window, 'Chek', 0 ) == 1 ) windowGroupAttributes	|= kWindowGroupAttrMoveTogether;
					ChangeWindowGroupAttributes( g.windowGroups[value-1], windowGroupAttributes, ~windowGroupAttributes );
					
					windowGroupAttributes	= kWindowGroupAttrMoveTogether | kWindowGroupAttrLayerTogether | kWindowGroupAttrHideOnCollapse;
					err	= CreateWindowGroup( windowGroupAttributes, &windowGroup );		//	We can only call SetWindowGroupParent() on an empty group, so create a new one
					if ( err == noErr )	err	= SetWindowGroupParent( windowGroup, g.windowGroups[value-1] );	//	Set the new parent
					if ( (err == noErr) && (windowStorage->overlayWindow != NULL) )
						err	= SetWindowGroup( windowStorage->overlayWindow, windowGroup );	//	FIRST add the overlay window so that it is on top of the "normal" window
					if ( err == noErr )
					{
						ReleaseWindowGroup( GetWindowGroup(window) );					//	Release the old group
						err	= SetWindowGroup( window, windowGroup );					//	Add the window to the new group
					}
				}
				else if ( command.commandID == 'GAtr' )									//	Get the window attributes
				{
					windowGroup	= GetWindowGroupParent( GetWindowGroup(window) );
					GetWindowGroupAttributes( windowGroup, &windowGroupAttributes );
					SetControlValueByID( window, 'Chek', 0, ((windowGroupAttributes & kWindowGroupAttrMoveTogether) != 0) );
					if ( windowGroup == g.windowGroups[0] )	SetControlValueByID( window, 'Rdio', 0, 1 );
					else if ( windowGroup == g.windowGroups[1] )	SetControlValueByID( window, 'Rdio', 0, 2 );
					else	SetControlValueByID( window, 'Rdio', 0, 3 );
				}
				else if ( command.commandID == 'Poof' )
				{
    				SetPortWindowPort( window );
					GetMouse( &pt );
					LocalToGlobal( &pt );
					pt.v	-= 50;						//	Draw the Poof 50 pixels above the mouse
					PoofItGood( pt );
				}
				else if ( command.commandID == 'Over' )
				{
					if ( windowStorage->overlayWindow == NULL )
					{
						CreateOverlayWindow( window );
					}
					else
					{
						SendWindowCloseEvent( windowStorage->overlayWindow );
					}
				}
			}
			break;
	}
    
    return( err );
}