void CFlashingWnd::SetUpRegion(const CRect& cRect, int type) { /////////////////////////////////////////////////// // // Under construction ...! // (Just to get an idea how it works now and what previously developers had in mind) // // There is currently a pixel fault in defined region and recorded region // Right pixel column and Top pixel row are not recorded. E.g. Area 200x200 becone 199x199 // Don't know if this is only with manual setup region the case or with other screen copies as well // // // +--- wndRgn --------------------+ // | +--- rgnTemp--------------+ | // // wndRgn defines a new rect with the size of the requested area but something bigger because the border lines are included either. // rgnTemp relative points to the area with the size of the area off interrest but inside wndRgn // rgnTemp2 ?? // rgnTemp3 ?? // /////////////////////////////////////////////////// CRgn wndRgn; CRgn rgnTemp; m_cRect = cRect; // TRACE( _T("## CFlashingWnd::SetUpRegion / m_cRect before / L=%d R=%d T=%d B=%d / W=%d H=%d\n"), m_cRect.left , m_cRect.right , m_cRect.top , m_cRect.bottom, m_cRect.Width(), m_cRect.Height() ); // Type=0 stands for ... cProgramOpts.m_bAutoPan == false if (type == 0) { CRgn rgnTemp2; CRgn rgnTemp3; // ToDo: Check if all +1 are applied correctly. Parameters in function below are not checked. // Check if we have forgotten to apply a few or don't we need them (the +1's) at all.? wndRgn.CreateRectRgn( 0 , 0 , m_cRect.Width() + DOUBLETHICKNESS , m_cRect.Height() + DOUBLETHICKNESS ); rgnTemp.CreateRectRgn( THICKNESS , THICKNESS , m_cRect.Width() + THICKNESS + 1 , m_cRect.Height() + THICKNESS + 1 ); rgnTemp2.CreateRectRgn( 0 , SIDELEN2 , m_cRect.Width() + DOUBLETHICKNESS , m_cRect.Height() - SIDELEN + 1 ); rgnTemp3.CreateRectRgn( SIDELEN2 , 0 , m_cRect.Width() - SIDELEN + 1 , m_cRect.Height() + DOUBLETHICKNESS ); wndRgn.CombineRgn(&wndRgn,&rgnTemp,RGN_DIFF); wndRgn.CombineRgn(&wndRgn,&rgnTemp2,RGN_DIFF); wndRgn.CombineRgn(&wndRgn,&rgnTemp3,RGN_DIFF); wndRgn.OffsetRgn( m_cRect.left - THICKNESS , m_cRect.top - THICKNESS ); } else { wndRgn.CreateRectRgn( 0 , 0 , m_cRect.Width() + DOUBLESMALLTHICKNESS , m_cRect.Height() + DOUBLESMALLTHICKNESS); rgnTemp.CreateRectRgn( SMALLTHICKNESS, SMALLTHICKNESS, m_cRect.Width() + SMALLTHICKNESS + 1 , m_cRect.Height() + SMALLTHICKNESS + 1); wndRgn.CombineRgn(&wndRgn, &rgnTemp, RGN_DIFF); wndRgn.OffsetRgn(m_cRect.left - SMALLTHICKNESS, m_cRect.top - SMALLTHICKNESS); } SetWindowRgn(wndRgn, TRUE); }
BOOL CResizableLayout::EnumAndClipChildWindow(HWND hWnd, LPARAM lParam) { CResizableLayout* pThis = (CResizableLayout*)lParam; // only direct children if (::GetParent(hWnd) != pThis->GetResizableWnd()->GetSafeHwnd()) return TRUE; if (!::IsWindowVisible(hWnd)) return TRUE; // skip invisible windows // go clipping? if (!pThis->LikesClipping(hWnd)) return TRUE; // obtain window position CRect rect; ::GetWindowRect(hWnd, &rect); pThis->GetResizableWnd()->ScreenToClient(&rect); // use window region if any CRgn rgn; rgn.CreateRectRgn(0,0,0,0); if (COMPLEXREGION == ::GetWindowRgn(hWnd, rgn)) { rgn.OffsetRgn(rect.TopLeft()); pThis->m_pClipDC->SelectClipRgn(&rgn, RGN_DIFF); } else { pThis->m_pClipDC->ExcludeClipRect(&rect); } return TRUE; }
void CResizableLayout::EnumAndClipChildWindow(HWND hWnd, CDC* pDC) { // obtain window position CRect rect; ::GetWindowRect(hWnd, &rect); GetResizableWnd()->ScreenToClient(&rect); pDC->DPtoLP(&rect); // use window region if any CRgn rgn; rgn.CreateRectRgn(0,0,0,0); if (COMPLEXREGION == ::GetWindowRgn(hWnd, rgn)) { rgn.OffsetRgn(rect.TopLeft()); } else { rgn.SetRectRgn(&rect); } // go clipping? if (LikesClipping(hWnd)) pDC->SelectClipRgn(&rgn, RGN_DIFF); else pDC->SelectClipRgn(&rgn, RGN_OR); }
void CResizableLayout::ClipChildWindow(const CResizableLayout::LayoutInfo& layout, CRgn* pRegion) { // obtain window position CRect rect; ::GetWindowRect(layout.hWnd, &rect); ::MapWindowPoints(NULL, GetResizableWnd()->m_hWnd, (LPPOINT)&rect, 2); // use window region if any CRgn rgn; rgn.CreateRectRgn(0,0,0,0); switch (::GetWindowRgn(layout.hWnd, rgn)) { case COMPLEXREGION: case SIMPLEREGION: rgn.OffsetRgn(rect.TopLeft()); break; default: rgn.SetRectRgn(&rect); } // get the clipping property BOOL bClipping = layout.properties.bAskClipping ? LikesClipping(layout) : layout.properties.bCachedLikesClipping; // modify region accordingly if (bClipping) pRegion->CombineRgn(pRegion, &rgn, RGN_DIFF); else pRegion->CombineRgn(pRegion, &rgn, RGN_OR); }
// support legacy code (will disappear in future versions) void CResizableLayout::ClipChildren(CDC* pDC) { CRgn rgn; GetClippingRegion(&rgn); // the clipping region is in device units rgn.OffsetRgn(-pDC->GetWindowOrg()); pDC->SelectClipRgn(&rgn); }
// Create the "4 corner" region surrounding cRect void CFlashingWnd::MakeFixedRegion(CRgn &wndRgn, CRgn &rgnTemp, CRgn &rgnTemp2, CRgn &rgnTemp3) { CRect rectWnd(0, 0, m_cRect.Width() + THICKNESS + THICKNESS, m_cRect.Height() + THICKNESS + THICKNESS); CRect rectTemp(THICKNESS, THICKNESS, m_cRect.Width() + THICKNESS + 1, m_cRect.Height() + THICKNESS + 1); CRect rectTemp2(0, SIDELEN2, m_cRect.Width() + THICKNESS + THICKNESS, m_cRect.Height() - SIDELEN + 1); CRect rectTemp3(SIDELEN2, 0, m_cRect.Width() - SIDELEN + 1, m_cRect.Height() + THICKNESS + THICKNESS); VERIFY(wndRgn.CreateRectRgnIndirect(rectWnd)); VERIFY(rgnTemp.CreateRectRgnIndirect(rectTemp)); VERIFY(rgnTemp2.CreateRectRgnIndirect(rectTemp2)); VERIFY(rgnTemp3.CreateRectRgnIndirect(rectTemp3)); VERIFY(ERROR != wndRgn.CombineRgn(&wndRgn, &rgnTemp, RGN_DIFF)); VERIFY(ERROR != wndRgn.CombineRgn(&wndRgn, &rgnTemp2, RGN_DIFF)); VERIFY(ERROR != wndRgn.CombineRgn(&wndRgn, &rgnTemp3, RGN_DIFF)); VERIFY(ERROR != wndRgn.OffsetRgn(m_cRect.left - THICKNESS, m_cRect.top - THICKNESS)); }
/*! * @internal This function adds or removes a control window region * to or from the specified clipping region, according to its layout * properties. */ void CResizableLayout::ClipChildWindow(const LAYOUTINFO& layout, CRgn* pRegion) const { // obtain window position CRect rect; ::GetWindowRect(layout.hWnd, &rect); #if (_WIN32_WINNT >= 0x0501) //! @todo decide when to clip client only or non-client too (themes?) //! (leave disabled meanwhile, until I find a good solution) //! @note wizard97 with watermark bitmap and themes won't look good! // if (real_WIN32_WINNT >= 0x501) // ::SendMessage(layout.hWnd, WM_NCCALCSIZE, FALSE, (LPARAM)&rect); #endif ::MapWindowPoints(NULL, GetResizableWnd()->m_hWnd, (LPPOINT)&rect, 2); // use window region if any CRgn rgn; rgn.CreateRectRgn(0,0,0,0); switch (::GetWindowRgn(layout.hWnd, rgn)) { case COMPLEXREGION: case SIMPLEREGION: rgn.OffsetRgn(rect.TopLeft()); break; default: rgn.SetRectRgn(&rect); } // get the clipping property BOOL bClipping = layout.properties.bAskClipping ? LikesClipping(layout) : layout.properties.bCachedLikesClipping; // modify region accordingly if (bClipping) pRegion->CombineRgn(pRegion, &rgn, RGN_DIFF); else pRegion->CombineRgn(pRegion, &rgn, RGN_OR); }
//**************************************************************************************** void CBCGPControlBarImpl::DrawNcArea () { CWindowDC dc(m_pBar); CRect rectClient; m_pBar->GetClientRect(rectClient); CRect rectWindow; m_pBar->GetWindowRect(rectWindow); m_pBar->ScreenToClient(rectWindow); rectClient.OffsetRect(-rectWindow.left, -rectWindow.top); dc.ExcludeClipRect (rectClient); BOOL bRTL = m_pBar->GetExStyle() & WS_EX_LAYOUTRTL; { MSG* pMsg = &AfxGetThreadState()->m_lastSentMsg; ASSERT (pMsg->hwnd == m_pBar->m_hWnd); ASSERT (pMsg->message == WM_NCPAINT); CRgn* pRgn = NULL; if (pMsg->wParam != 1 && (pRgn = CRgn::FromHandle ((HRGN) pMsg->wParam)) != NULL) { CRect rect; m_pBar->GetWindowRect (rect); if (bRTL) { CRect rect2; pRgn->GetRgnBox(&rect2); rect2.OffsetRect(rect.right - rect2.right - rect2.left, -rect.top); CRgn rgn; rgn.CreateRectRgnIndirect(&rect2); dc.SelectClipRgn(&rgn, RGN_AND); } else { pRgn->OffsetRgn (- rect.TopLeft ()); dc.SelectClipRgn (pRgn, RGN_AND); } } } if (!m_pBar->m_bIsTransparentBorder) { // draw borders in non-client area rectWindow.OffsetRect(-rectWindow.left, -rectWindow.top); CBCGPVisualManager::GetInstance ()->OnDrawBarBorder (&dc, m_pBar, rectWindow); // erase parts not drawn dc.IntersectClipRect(rectWindow); CBCGPVisualManager::GetInstance ()->OnFillBarBackground (&dc, m_pBar, rectWindow, CRect (0, 0, 0, 0), TRUE /* NC area */); } else { GetBackgroundFromParent(&dc); } // draw gripper in non-client area if ((m_pBar->GetBarStyle () & (CBRS_GRIPPER|CBRS_FLOATING)) != CBRS_GRIPPER) { dc.SelectClipRgn (NULL); return; } CRect rectGripper; GetGripperRect (rectGripper); if (rectGripper.Width() >= 1 && rectGripper.Height() >= 1) { BOOL bHorz = (m_pBar->GetBarStyle () & CBRS_ORIENT_HORZ) ? TRUE : FALSE; CBCGPVisualManager::GetInstance ()->OnDrawBarGripper ( &dc, rectGripper, bHorz, m_pBar); } dc.SelectClipRgn (NULL); }
LRESULT CRegionSelect::OnLButtonUp(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) { if(!Down) return 0; Down = false; End.x = LOWORD(lParam)+1; End.y = HIWORD(lParam)+1; CRgn newRegion; RECT winRect; SHORT shiftState = GetAsyncKeyState(VK_SHIFT); WORD fwKeys = wParam; m_bPictureChanged = true; if(m_SelectionMode == smFreeform) { Finish(); return 0; } if(m_SelectionMode != smWindowHandles || (abs(End.x-Start.x)>7 && abs(End.y-Start.y)>7)) newRegion.CreateRectRgn(Start.x,Start.y,End.x,End.y); else { ::GetWindowRect(hSelWnd, &winRect); newRegion.CreateRectRgnIndirect(&winRect); newRegion.OffsetRgn(topLeft); RECT invRect; newRegion.GetRgnBox(&invRect); Start.x = invRect.left; Start.y = invRect.top; End.x = invRect.right; End.y = invRect.bottom; if(fwKeys & MK_CONTROL) m_SelectedWindowsRegion.AddWindow(hSelWnd, false); else m_SelectedWindowsRegion.AddWindow(hSelWnd, true); //hSelWnd = 0; } if(fwKeys & MK_CONTROL) { m_SelectionRegion.CombineRgn(newRegion, RGN_DIFF); } else if(shiftState& 0x8000) // shift is down { m_SelectionRegion.CombineRgn(newRegion, RGN_OR); } else { m_SelectionRegion.CombineRgn(newRegion, RGN_OR); Finish(); return 0; } if(!RectCount) { RectCount++; Invalidate(); } else{ RectCount++; RECT RectToRepaint; //if(m_SelectionMode != smWindowHandles) { RectToRepaint.left = min(Start.x, End.x) - m_brushSize; RectToRepaint.top = min(Start.y, End.y) - m_brushSize; RectToRepaint.right = max(Start.x, End.x) + m_brushSize; RectToRepaint.bottom = max(Start.y, End.y) + m_brushSize; InvalidateRect(&RectToRepaint); } } Start.x = -1; Start.y = -1; End.x = -1; End.y = -1; return 0; }
LRESULT CRegionSelect::OnMouseMove(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) { int cx = LOWORD(lParam); int cy = HIWORD(lParam); DWORD fwKeys = wParam; POINT point = {cx, cy}; HWND hNewSelWnd; /*CRect toolbarRC; Toolbar.GetWindowRect(&toolbarRC); toolbarRC.InflateRect(30,70); bool HideToolBar = true; if(toolbarRC.PtInRect(point)) { if(!(fwKeys & MK_LBUTTON) && !(fwKeys & MK_RBUTTON)) { HideToolBar = false; if(!m_btoolWindowTimerRunning) { SetTimer(1,400); m_btoolWindowTimerRunning = true; } } //do smth } else { if(m_btoolWindowTimerRunning) KillTimer(1); m_btoolWindowTimerRunning = false; Toolbar.ShowWindow(SW_HIDE); }*/ bool bUpdateWindow = false; if(m_SelectionMode == smWindowHandles) { POINT newP=point; ClientToScreen(&newP ); if ((hNewSelWnd = WindowUnderCursor(newP,m_hWnd)) == 0) hNewSelWnd = ::GetDesktopWindow(); else { /*HWND hChildWnd = MyChildWindowFromPoint(hNewSelWnd, point); if ( hChildWnd ) hNewSelWnd = hChildWnd;*/ } if(hNewSelWnd != hSelWnd) { CRgn FullScreenRgn; FullScreenRgn.CreateRectRgnIndirect(&m_screenBounds); RECT SelWndRect; ::GetWindowRect( hNewSelWnd, &SelWndRect ); CRgn WindowRgn; if(::GetWindowRgn(hNewSelWnd, WindowRgn) != ERROR) { //WindowRegion.GetRgnBox( &WindowRect); WindowRgn.OffsetRgn( SelWndRect.left, SelWndRect.top); } CBrush br; br.CreateSolidBrush(RGB(200,0,0)); m_bPictureChanged = true; m_PrevWindowRect = SelWndRect; CRgn repaintRgn; repaintRgn.CreateRectRgnIndirect(&SelWndRect); repaintRgn.OffsetRgn(topLeft); if(!m_prevWindowRgn.IsNull()) repaintRgn.CombineRgn(m_prevWindowRgn, RGN_OR); m_prevWindowRgn = repaintRgn; InvalidateRgn(repaintRgn); repaintRgn.Detach(); bUpdateWindow = true; } hSelWnd = hNewSelWnd; if(!(wParam & MK_RBUTTON)) { bUpdateWindow = true; } } //else { if(fwKeys & MK_LBUTTON && Down ) { HDC dc = GetDC(); SelectObject(dc, pen); if(m_SelectionMode!=smFreeform) { SetROP2(dc, R2_NOTXORPEN); if(End.x>-1) Rectangle(dc, Start.x,Start.y, End.x, End.y); End.x = LOWORD(lParam); End.y = HIWORD(lParam); bool Draw = true; if(m_SelectionMode == smWindowHandles) { if(abs(End.x-Start.x)<7 && abs(End.y-Start.y)<7) { Draw=false; } else { m_SelectionMode = smRectangles; hSelWnd = 0; m_bPictureChanged = true; /*Invalidate();*/ bUpdateWindow = true; } } if(Draw) Rectangle(dc, Start.x,Start.y, End.x, End.y); } else { SetROP2(doubleDC, R2_COPYPEN); POINT p = m_curvePoints.back(); MoveToEx(doubleDC, p.x, p.y,0); SelectObject(doubleDC, pen); POINT newPoint = {LOWORD(lParam), HIWORD(lParam)}; LineTo(doubleDC, newPoint.x, newPoint.y); m_curvePoints.push_back(newPoint); RECT RectToRepaint; RectToRepaint.left = min(p.x, newPoint.x) - m_brushSize; RectToRepaint.top = min(p.y, newPoint.y) - m_brushSize; RectToRepaint.right = max(p.x, newPoint.x) + m_brushSize; RectToRepaint.bottom = max(p.y, newPoint.y) + m_brushSize; InvalidateRect(&RectToRepaint, false); } ReleaseDC(dc); } } if(wParam & MK_RBUTTON) { HGDIOBJ oldPen2 = SelectObject(memDC2, DrawingPen); if(cxOld != -1) { SHORT shiftState = GetAsyncKeyState(VK_SHIFT); if(shiftState& 0x8000) { if (!lineType ) { lineType = abs(cx-cxOld) >= abs(cy-cyOld) ? 1 : 2; } if ( lineType == 1 ) { cy = cyOld; } else { cx = cxOld; } } SelectClipRgn(memDC2, 0); MoveToEx(memDC2, cxOld, cyOld,0); LineTo(memDC2, cx,cy); RECT RectToRepaint; RectToRepaint.left = min(cxOld, cx) - m_brushSize; RectToRepaint.top = min(cyOld, cy) - m_brushSize; RectToRepaint.right = max(cxOld, cx) + m_brushSize; RectToRepaint.bottom = max(cyOld, cy) + m_brushSize; CRgn rgn; rgn.CreateRectRgnIndirect(&RectToRepaint); m_bPictureChanged = true; m_bDocumentChanged = true; InvalidateRect(&RectToRepaint); UpdateWindow(); } cxOld = cx; cyOld = cy; } if(bUpdateWindow) UpdateWindow(); return 0; }
LRESULT CRegionSelect::OnPaint(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled) { PAINTSTRUCT ps; BeginPaint(&ps); HDC dc = ps.hdc; int w = ps.rcPaint.right-ps.rcPaint.left; int h = ps.rcPaint.bottom-ps.rcPaint.top; if(m_bPictureChanged) { if(Down) return 0; RECT rc; GetClientRect(&rc); CRgn newRegion; newRegion.CreateRectRgn(0,0,rc.right,rc.bottom); SelectClipRgn(doubleDC, newRegion); BitBlt(doubleDC,ps.rcPaint.left,ps.rcPaint.top,w,h,memDC2, ps.rcPaint.left,ps.rcPaint.top,SRCCOPY); newRegion.CombineRgn(m_SelectionRegion,RGN_DIFF); CBrush br; SelectClipRgn(doubleDC, newRegion); br.CreateSolidBrush(RGB(200,200,0)); BLENDFUNCTION bf ; //настройки прозрачности bf.BlendOp = AC_SRC_OVER; bf.BlendFlags = 1; bf.SourceConstantAlpha = 40; // прозрачность 50% (0 - 255) bf.AlphaFormat = 0;///*0 */ /*AC_SRC_ALPHA*/0; if(RectCount) if(AlphaBlend(doubleDC, ps.rcPaint.left, ps.rcPaint.top, w,h, alphaDC, ps.rcPaint.left, ps.rcPaint.top, w,h, bf)==FALSE) { //MessageBox(_T("Alphablend failed")); }; newRegion.DeleteObject(); newRegion.CreateRectRgn(0,0,rc.right,rc.bottom); SelectClipRgn(doubleDC, newRegion); RECT SelWndRect; if(hSelWnd) { CRgn WindowRgn = GetWindowVisibleRegion(hSelWnd); WindowRgn.OffsetRgn(topLeft); WindowRgn.GetRgnBox(&SelWndRect); CRect DrawingRect = SelWndRect; DrawingRect.DeflateRect(2, 2); SelectObject(doubleDC, pen); SetROP2(doubleDC, R2_NOTXORPEN); SelectClipRgn(doubleDC, 0); Rectangle(doubleDC, DrawingRect.left,DrawingRect.top, DrawingRect.right, DrawingRect.bottom); } m_bPictureChanged = false; } BitBlt(dc,ps.rcPaint.left, ps.rcPaint.top,w,h,doubleDC,ps.rcPaint.left, ps.rcPaint.top,SRCCOPY); EndPaint(&ps); m_bPainted = true; return 0; }