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; }
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") ); }
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 ); }