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); }
////////////////////////////////////////////////////////////////////////// // 画透明异形图的函数 // 注:在这里特别感谢CSDN网友: 黄凯飞, ID: hkf314 void CAnimateButton::AlphaBitmap(int nItem) { CDC* pDC = GetDC(); CDC TmpDC; TmpDC.CreateCompatibleDC(pDC); //当然,TmpBmp用来记录画的内容 CBitmap TmpBmp; TmpBmp.CreateCompatibleBitmap(pDC, m_aniBtnWidth, m_aniBtnHeight); TmpDC.SelectObject(&TmpBmp); //把按钮下的背景拷贝过来 TmpDC.BitBlt(0, 0, m_aniBtnWidth, m_aniBtnHeight, pDC, 0, 0, SRCCOPY); //把内存DC中的图像透明地画出来 AlphaBlend(TmpDC.m_hDC, 0, 0, m_aniBtnWidth, m_aniBtnHeight, m_pMemDC->m_hDC, nItem * m_aniBtnWidth, 0, m_aniBtnWidth, m_aniBtnHeight, m_bf); //填充异形图像以外的区域为mask色 CRgn rgn; rgn.CreateRectRgn(0, 0, m_aniBtnWidth, m_aniBtnHeight); rgn.CombineRgn(&rgn, CRgn::FromHandle(m_arBmpRgn[nItem]), RGN_DIFF); // TRACE("CRgn::FromHandle(m_arBmpRgn[nItem]): %d\n", nItem); CBrush maskBrh; maskBrh.CreateSolidBrush(m_clrTrans); TmpDC.FillRgn(&rgn, &maskBrh); // TmpDC.FillRgn(CRgn::FromHandle(m_arBmpRgn[nItem]), &maskBrh); //抠除mask色,直接画出来 ::TransparentBlt(pDC->m_hDC, 0, 0, m_aniBtnWidth, m_aniBtnHeight, TmpDC.m_hDC, 0, 0, m_aniBtnWidth, m_aniBtnHeight, m_clrTrans); // pDC->BitBlt(0, 0, m_aniBtnWidth, m_aniBtnHeight, &TmpDC, 0, 0, SRCCOPY); // pDC->FillRgn(CRgn::FromHandle(m_arBmpRgn[nItem]), &maskBrh); ReleaseDC(pDC); }
void CScoreView::SetupRgn(CDC *pDC,CSkinImage bImage,COLORREF TransColor) { //bImage.GetWidth()/5; tagImageLoadInfo ImageIDB; bImage.GetLoadInfo(ImageIDB); CBitmap cBitmap; cBitmap.LoadBitmap(ImageIDB.uResourceID);//这个BITMAP是5倍长的,所以会有问题死机。 CDC memDC; //创建与传入DC兼容的临时DC memDC.CreateCompatibleDC(pDC); CBitmap *pOldMemBmp=NULL; //将位图选入临时DC pOldMemBmp=memDC.SelectObject(&cBitmap); CRgn wndRgn; //创建总的窗体区域,初始region为0 wndRgn.CreateRectRgn(0,0,0,0); BITMAP bit; cBitmap.GetBitmap (&bit);//取得位图参数,这里要用到位图的长和宽 int y; for(y=0;y<=bit.bmHeight ;y++) { CRgn rgnTemp; //保存临时region int iX = 0; do { //跳过透明色找到下一个非透明色的点. while (iX <= bit.bmWidth && memDC.GetPixel(iX, y) == TransColor) iX++; //记住这个起始点 int iLeftX = iX; //寻找下个透明色的点 while (iX <= bit.bmWidth && memDC.GetPixel(iX, y) != TransColor) ++iX; //创建一个包含起点与重点间高为1像素的临时“region” rgnTemp.CreateRectRgn(iLeftX, y, iX, y+1); //合并到主"region". wndRgn.CombineRgn(&wndRgn, &rgnTemp, RGN_OR); //删除临时"region",否则下次创建时和出错 rgnTemp.DeleteObject(); }while(iX <bit.bmWidth ); iX = 0; } if(pOldMemBmp) memDC.SelectObject(pOldMemBmp); CWnd * pWnd = pDC->GetWindow(); pWnd->SetWindowRgn(wndRgn,TRUE); pWnd->SetForegroundWindow(); }
// CPhotoPubView 绘制 void CPhotoPubView::DrawImage(CDC *pDC,IplImage *pImg) { int wid=0,hi=0; CRect ClipBox; GetClientRect(&ClipBox); if (!pImg) { CBitmap bkg; bkg.LoadBitmap(IDB_BACKGROUND); CBrush brush(&bkg); pDC->FillRect(&ClipBox,&brush); return; } wid=int(pImg->width*m_ratio); hi=int(pImg->height*m_ratio); IplImage *pStub=pImg; IplImage *pTmp=NULL; if (wid!=pImg->width) { pTmp=cvCreateImage(cvSize(wid,hi),IPL_DEPTH_8U,3); cvResize(pImg,pTmp); pStub=pTmp; } CRgn WindowRgn; WindowRgn.CreateRectRgnIndirect(&ClipBox); CRect ImageRect(0,0,wid,hi); int top=max((ClipBox.Height()-hi)/2,0); int left=max((ClipBox.Width()-wid)/2,0); ImageRect.MoveToXY(left,top); CRgn ImageRgn; ImageRgn.CreateRectRgnIndirect(&ImageRect); WindowRgn.CombineRgn(&WindowRgn,&ImageRgn,RGN_DIFF); CBitmap bkg; bkg.LoadBitmap(IDB_BACKGROUND); CBrush brush(&bkg); pDC->FillRgn(&WindowRgn,&brush); memset(m_bmih_buffer, 0, sizeof(*m_bmih_buffer)); m_bmih_buffer->biSize = sizeof(BITMAPINFOHEADER); m_bmih_buffer->biWidth = wid; m_bmih_buffer->biHeight = -hi; m_bmih_buffer->biPlanes = 1; m_bmih_buffer->biBitCount = 24; m_bmih_buffer->biCompression = BI_RGB; SetDIBitsToDevice( pDC->m_hDC, ImageRect.left,ImageRect.top,pStub->width,pStub->height, 0, 0, 0, hi, pStub->imageData, m_bmi_buffer, DIB_RGB_COLORS ); cvReleaseImage(&pTmp); }
void CScoreView::SetupRgn(CDC *pDC, //窗体的DC指针 CBitmap &cBitmap, //含有窗体形状的位图对象 // CSkinImage skinImage, COLORREF TransColor) //透明色 { CDC memDC; //创建与传入DC兼容的临时DC memDC.CreateCompatibleDC(pDC); CBitmap *pOldMemBmp=NULL; //将位图选入临时DC pOldMemBmp=memDC.SelectObject(&cBitmap); CRgn wndRgn; //创建总的窗体区域,初始region为0 wndRgn.CreateRectRgn(0,0,0,0); BITMAP bit; cBitmap.GetBitmap (&bit);//取得位图参数,这里要用到位图的长和宽 int y; for(y=0;y<=bit.bmHeight ;y++) { CRgn rgnTemp; //保存临时region int iX = 0; do { //跳过透明色找到下一个非透明色的点. while (iX <= bit.bmWidth && memDC.GetPixel(iX, y) == TransColor) iX++; //记住这个起始点 int iLeftX = iX; //寻找下个透明色的点 while (iX <= bit.bmWidth && memDC.GetPixel(iX, y) != TransColor) ++iX; //创建一个包含起点与重点间高为1像素的临时“region” rgnTemp.CreateRectRgn(iLeftX, y, iX, y+1); //合并到主"region". wndRgn.CombineRgn(&wndRgn, &rgnTemp, RGN_OR); //删除临时"region",否则下次创建时和出错 rgnTemp.DeleteObject(); }while(iX <bit.bmWidth ); iX = 0; } if(pOldMemBmp) memDC.SelectObject(pOldMemBmp); //HRGN wndRgn=skinImage.CreateImageRegion(RGB(255,0,255)); CWnd * pWnd = pDC->GetWindow(); pWnd->SetWindowRgn(wndRgn,TRUE); pWnd->SetForegroundWindow(); }
// 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)); }
void CMyBalloon::SetupWindowRgn() { CRect rcWnd (0,0,0,0); CSize sizeReq = m_pContent->getRequiredSize (); rcWnd.right = sizeReq.cx; rcWnd.bottom = sizeReq.cy; rcWnd.InflateRect (3, 3); rcWnd.left += 3; rcWnd.right += 3; rcWnd.top += 3; rcWnd.bottom += 3; int cxScreen = GetSystemMetrics (SM_CXSCREEN); int cyScreen = GetSystemMetrics (SM_CYSCREEN); m_bLeaderAtRight = false; m_bLeaderAtTop = false; if (m_ptAnchor.x + rcWnd.Width () > cxScreen) m_bLeaderAtRight = true; if (m_ptAnchor.y - rcWnd.Height () - CY_LEADER < 0) m_bLeaderAtTop = true; if (m_bLeaderAtTop) { rcWnd.top += CY_LEADER; rcWnd.bottom += CY_LEADER; } CPoint ptLeader [3]; ptLeader[0].x = m_bLeaderAtRight ? rcWnd.Width () - CX_ROUNDED - CX_LEADER_MARGIN : CX_ROUNDED + CX_LEADER_MARGIN; ptLeader[0].y = m_bLeaderAtTop ? rcWnd.top + CY_ROUNDED : rcWnd.Height() - CY_ROUNDED; ptLeader[1].x = ptLeader[0].x; ptLeader[1].y = m_bLeaderAtTop ? ptLeader[0].y - CY_ROUNDED - CY_LEADER : ptLeader[0].y + CY_ROUNDED + CY_LEADER; ptLeader[2].x = m_bLeaderAtRight ? ptLeader[0].x - CX_ROUNDED - CX_LEADER - CX_LEADER_MARGIN - 10 : ptLeader[0].x + CX_ROUNDED + CX_LEADER + CX_LEADER_MARGIN + 10; ptLeader[2].y = m_bLeaderAtTop ? rcWnd.top + CY_ROUNDED + CY_LEADER : rcWnd.Height() - CY_ROUNDED - CY_LEADER; CRgn rgnLeader, rgnContent; rgnContent.CreateRoundRectRgn (rcWnd.left, rcWnd.top, rcWnd.right, rcWnd.bottom, CX_ROUNDED, CY_ROUNDED); rgnLeader.CreatePolygonRgn (ptLeader, 3, ALTERNATE); CRgn rgn; rgn.CreateRectRgn (0, 0, rcWnd.Width (), rcWnd.Height () + CY_LEADER); rgn.CombineRgn (&rgnContent, &rgnLeader, RGN_OR); SetWindowPos (CWnd::FromHandle (HWND_TOPMOST), (m_bLeaderAtRight ? m_ptAnchor.x - rcWnd.Width () + CX_ROUNDED + CX_LEADER_MARGIN : m_ptAnchor.x - CX_ROUNDED - CX_LEADER_MARGIN), (m_bLeaderAtTop ? m_ptAnchor.y : m_ptAnchor.y - rcWnd.Height () - CY_LEADER), rcWnd.Width (), rcWnd.Height () + CY_LEADER, 0); SetWindowRgn (rgn, FALSE); }
BOOL CVisualManager::OnSetWindowRegion (CWnd* pWnd, CSize sizeWindow) { ASSERT_VALID (pWnd); if (pWnd->GetSafeHwnd () == NULL) { return FALSE; } if (!CanDrawImage ()) { return FALSE; } if (globalData.DwmIsCompositionEnabled ()) { return FALSE; } CSize sz (0, 0); if (DYNAMIC_DOWNCAST (CBCGPFrameWnd, pWnd) != NULL) { if (pWnd->IsZoomed ()) { pWnd->SetWindowRgn (NULL, TRUE); return TRUE; } sz = CSize (9, 9); } if (sz != CSize (0, 0)) { CRgn rgn; BOOL bCreated = FALSE; bCreated = rgn.CreateRoundRectRgn (0, 0, sizeWindow.cx + 1, sizeWindow.cy + 1, sz.cx, sz.cy); if (bCreated) { if (pWnd->IsKindOf (RUNTIME_CLASS (CMDIChildWnd))) { CRgn rgnWinodw; rgnWinodw.CreateRectRgn (0, sz.cy, sizeWindow.cx, sizeWindow.cy); rgn.CombineRgn (&rgn, &rgnWinodw, RGN_OR); } pWnd->SetWindowRgn ((HRGN)rgn.Detach (), TRUE); return TRUE; } } return FALSE; }
HRGN CSkinWin::GetRegion(int w, int h) { CWnd *pWnd = CWnd::FromHandle(m_hWnd); CRect wr; pWnd->GetWindowRect(wr); //SKIN_SHANG 右边框 //wr.left+=m_BorderRightWidth; CRgn rgn; if ( m_bTrans ) { CDC *pDC = pWnd->GetDC(); CDC memDC; CMyBitmap bmp; CBitmap *obmp; memDC.CreateCompatibleDC(pDC); bmp.CreateCompatibleBitmap( pDC, w, m_TitleHeight ); obmp = memDC.SelectObject(&bmp); /* memDC.FillSolidRect( 0, 0, w, h, 0 ); DrawFrame( &memDC, 0, 0, w, h, 0 ); */ DrawTitle( &memDC, m_BorderLeftWidth , 0, wr.Width() - m_BorderRightWidth - m_BorderLeftWidth + 1, 0 ); DrawLeft( &memDC, 0, 0, m_bmpLeft.Height(), 0 ); //SKIN_SHANG 右边框 DrawRight( &memDC, wr.Width() - m_BorderRightWidth , 0, m_bmpRight.Height(), 0 ); memDC.SelectObject(obmp); //wyw memDC.DeleteDC(); pWnd->ReleaseDC( pDC ); rgn.CreateRectRgn( 0, m_TitleHeight, wr.Width(), wr.Height() ); HRGN hrgn = bmp.CreateRgnFromFile( m_colTrans ); CRgn newrgn; newrgn.CreateRectRgn( 0, m_TitleHeight, wr.Width(), wr.Height() ); newrgn.CombineRgn( &rgn, CRgn::FromHandle(hrgn), RGN_XOR ); //wyw bmp.DeleteObject(); DeleteObject(hrgn); rgn.DeleteObject(); return (HRGN)newrgn.Detach(); } else rgn.CreateRectRgn( 0, 0, wr.Width(), wr.Height() ); return (HRGN)rgn.Detach(); }
void COXTabViewContainer::OnPaint() { CPaintDC dc(this); // device context for painting // TODO: Add your message handler code here CWnd* pWnd=GetActivePage(); if(pWnd!=NULL) { CRect rect; pWnd->GetWindowRect(rect); ScreenToClient(rect); if(m_rectPage!=rect && !rect.IsRectEmpty()) { CRgn rgnInTheory; CRgn rgnInReality; if(rgnInTheory.CreateRectRgnIndirect(m_rectPage) && rgnInReality.CreateRectRgnIndirect(rect)) { if(rgnInTheory.CombineRgn(&rgnInTheory,&rgnInReality, RGN_DIFF)!=ERROR) { CBrush* pBrush=NULL; CBrush brush; HBRUSH hBrush=(HBRUSH)(INT_PTR)::GetClassLongPtr(pWnd->m_hWnd, GCL_HBRBACKGROUND); if(hBrush==NULL) { if(brush.CreateSolidBrush(::GetSysColor(COLOR_WINDOW))) pBrush=&brush; else pBrush=dc.GetCurrentBrush(); } else { pBrush=CBrush::FromHandle(hBrush); } if(pBrush!=NULL) dc.FillRgn(&rgnInTheory,pBrush); } } } } DrawScrollButtons(&dc); DrawSplitter(&dc); DrawSizeBar(&dc); DrawTabBtnArea(&dc); // Do not call CWnd::OnPaint() for painting messages }
void CBmpButton::SetWndRng() { if (NULL == m_pBmpUncheckedNormal) return; CRect rcDlgRect; GetWindowRect(rcDlgRect); BITMAP BmpInfo; m_pBmpUncheckedNormal->GetBitmap(&BmpInfo); MoveWindow(rcDlgRect.left, rcDlgRect.top, BmpInfo.bmWidth, BmpInfo.bmHeight); const int iBitWidth = BmpInfo.bmBitsPixel / 8; if(iBitWidth == 4) { //有alpha通道,则裁窗口形状 CRgn rgn; rgn.CreateRectRgn(0, 0, BmpInfo.bmWidth, BmpInfo.bmHeight); int iBitSize = BmpInfo.bmWidth * BmpInfo.bmHeight * iBitWidth; BYTE *pBits = new BYTE[iBitSize]; m_pBmpUncheckedNormal->GetBitmapBits(iBitSize, pBits); for (int y = 0; y < BmpInfo.bmHeight; y++) { int iRow = y * BmpInfo.bmWidth; for (int x = 0; x < BmpInfo.bmWidth; x++) { int iPos = (iRow + x) * iBitWidth; if (pBits[iPos + 3] == 0)//检测alpha是否为透明 { CRgn rgnCut; rgnCut.CreateRectRgn(x, y, x+1, y+1); rgn.CombineRgn(&rgn, &rgnCut, RGN_XOR); } } } SetWindowRgn(rgn, FALSE); delete []pBits; } }
bool ASSISTANT::Oval::ContainsPoint(Gdiplus::PointF &ptMouse) { if (!visible) return false; CRect rcObject; GetBoundingBox(rcObject); CRgn rgnElliptic; double dMaxDistance = (double)lineWidth / 2 + 0.5; BOOL bRet = TRUE; if (IsFilled()) { CRgn rgnElliptic; bRet = rgnElliptic.CreateEllipticRgnIndirect(rcObject); if (!bRet) return false; if (rgnElliptic.PtInRegion((int)ptMouse.X, (int)ptMouse.Y)) return true; } else { CRect rcOutside = rcObject; rcOutside.InflateRect(dMaxDistance, dMaxDistance, dMaxDistance, dMaxDistance); bRet = rgnElliptic.CreateEllipticRgnIndirect(rcOutside); if (!bRet) return false; CRgn rgnElliptic2; CRect rcInside = rcObject; rcInside.DeflateRect(dMaxDistance, dMaxDistance, dMaxDistance, dMaxDistance); bRet = rgnElliptic2.CreateEllipticRgnIndirect(rcInside); if (!bRet) return false; rgnElliptic.CombineRgn(&rgnElliptic, &rgnElliptic2, RGN_DIFF); if (rgnElliptic.PtInRegion((int)ptMouse.X, (int)ptMouse.Y)) return true; } return false; }
void CBCGPSDPlaceMarkerWnd::ShowTabbedAt (CRect rect, CRect rectTab) { if (!m_bTabbed || m_rectLast != rect || m_rectTab != rectTab) { Hide (); CRgn rgnMain; CBCGPTabbedControlBar::m_bTabsAlwaysTop ? rgnMain.CreateRectRgn (0, rectTab.Height (), rect.Width(), rect.Height() + rectTab.Height ()) : rgnMain.CreateRectRgn (0, 0, rect.Width(), rect.Height()); CRgn rgnTab; if (CBCGPTabbedControlBar::m_bTabsAlwaysTop) { rgnTab.CreateRectRgn (rectTab.left, 0, rectTab.Width (), rectTab.Height ()); } else { rgnTab.CreateRectRgnIndirect (rectTab); } rgnMain.CombineRgn (&rgnMain, &rgnTab, RGN_OR); SetWindowRgn (rgnMain, FALSE); m_bTabbed = TRUE; m_rectLast = rect; m_rectTab = rectTab; if (CBCGPTabbedControlBar::m_bTabsAlwaysTop) { SetWindowPos (&CWnd::wndTop, rect.left, rectTab.top, rect.Width(), rect.Height() + m_rectTab.Height (), SWP_NOACTIVATE | SWP_SHOWWINDOW | SWP_NOREDRAW); } else { SetWindowPos (&CWnd::wndTop, rect.left, rect.top, rect.Width(), rect.Height() + m_rectTab.Height (), SWP_NOACTIVATE | SWP_SHOWWINDOW | SWP_NOREDRAW); } m_bShown = TRUE; RedrawWindow (); } }
// -------------------------------------------------------------------------- void CToolTipWnd::OnPaint() { CPaintDC dc( this ); // device context for painting CRect rectCl; GetClientRect( &rectCl ); CRgn rgnComb; rgnComb.CreateRectRgn( rectCl.left+10,rectCl.top,rectCl.right,rectCl.bottom ); int iRetComb = rgnComb.CombineRgn( &m_rgnTri, &m_rgn, RGN_OR ); if ( iRetComb == ERROR ) { AfxMessageBox( (LPCTSTR)"ERROR in Combining Region" ); return; } CBrush pBrush; pBrush.CreateSolidBrush( m_clrFrameColor ); CBrush pBrush1; pBrush1.CreateSolidBrush( m_clrBkColor ); dc.FillRgn( &rgnComb, &pBrush1 ); dc.FrameRgn( &rgnComb, &pBrush, 2, 1 ); dc.SetBkMode( TRANSPARENT ); dc.SetTextColor( m_clrTextColor ); CFont *pFont = dc.SelectObject( &m_strTextFont ); CSize czTextWidth = dc.GetTextExtent( m_strText ); if ( czTextWidth.cx < m_rectText.Width() ) dc.DrawText( m_strText, m_rectText, DT_CENTER | DT_VCENTER | DT_SINGLELINE ); else dc.DrawText( m_strText, m_rectText, DT_CENTER | DT_WORDBREAK ); dc.SelectObject( pFont ); }
void CDrawCommon::GetRegionFromImage(CRgn& rgn, CBitmap &cBitmap, int threshold) { CDC memDC; memDC.CreateCompatibleDC(NULL); CBitmap *pOldMemBmp = NULL; pOldMemBmp = memDC.SelectObject(&cBitmap); //创建总的窗体区域,初始region为0 rgn.CreateRectRgn(0, 0, 0, 0); BITMAP bit; cBitmap.GetBitmap(&bit);//取得位图参数,这里要用到位图的长和宽 int y; for (y = 0; y<bit.bmHeight; y++) { CRgn rgnTemp; //保存临时region int iX = 0; do { //跳过透明色找到下一个非透明色的点. while (iX < bit.bmWidth && GetColorBritness(memDC.GetPixel(iX, y)) <= threshold) iX++; int iLeftX = iX; //记住这个起始点 //寻找下个透明色的点 while (iX < bit.bmWidth && GetColorBritness(memDC.GetPixel(iX, y)) > threshold) ++iX; //创建一个包含起点与重点间高为1像素的临时“region” rgnTemp.CreateRectRgn(iLeftX, y, iX, y + 1); rgn.CombineRgn(&rgn, &rgnTemp, RGN_OR); //删除临时"region",否则下次创建时和出错 rgnTemp.DeleteObject(); } while (iX < bit.bmWidth); } }
// @pymethod int|PyCRgn|CombineRgn|Creates a new GDI region by combining two existing regions. The regions are combined as specified by nCombineMode // Return Values: success or failure flag (BOOL) PyObject * PyCRgn::combine_rgn(PyObject *self, PyObject *args) { CRgn *pRgn = PyCRgn::GetRgn(self); if (!pRgn) return NULL; PyObject *objRgn1 = Py_None; PyObject *objRgn2 = Py_None; int nCombineMode=RGN_AND; if (!PyArg_ParseTuple(args,"OOi:CombineRgn", &objRgn1,&objRgn2,&nCombineMode)) return NULL; CRgn *pRgn1 = PyCRgn::GetRgn(objRgn1); if (!pRgn1) return NULL; CRgn *pRgn2 = PyCRgn::GetRgn(objRgn2); if (!pRgn2) return NULL; int result=pRgn->CombineRgn(pRgn1,pRgn2,nCombineMode); return Py_BuildValue("i",result); }
//************************************************************************************ void CBCGPRadialMenu::SetRgn() { if (m_pRadialMenuObject != NULL) { CRect rect; GetClientRect(rect); int cx = rect.Width(); int cy = rect.Height(); CRgn rgn; rgn.CreateEllipticRgn(0, 0, cx, cy); if (!m_pRadialMenuObject->m_bHasCenterButton) { double rx = INTERNAL_PART * cx; double ry = INTERNAL_PART * cy; int x1 = (int)(.5 + .5 * cx - rx); int x2 = (int)(.5 + .5 * cx + rx); int y1 = (int)(.5 +.5 * cy - ry); int y2 = (int)(.5 + .5 * cy + ry); CRgn rgnCenter; rgnCenter.CreateEllipticRgn(x1, y1, x2, y2); rgn.CombineRgn(&rgn, &rgnCenter, RGN_XOR); } SetWindowRgn(rgn, FALSE); } else { SetWindowRgn(NULL, FALSE); } }
void CTTCheckBtnGroup::OnPaint() { CPaintDC dc(this); CRect clientRect; GetClientRect(clientRect); if (clientRect.Width() <= 0 || clientRect.Height() <= 0) return; CMemDC memDC(dc, clientRect); CDC* pDC = &memDC.GetDC(); DrawThemeParentBackground(GetSafeHwnd(), memDC.GetDC().GetSafeHdc(), clientRect); Graphics graphics(pDC->GetSafeHdc()); graphics.SetSmoothingMode(SmoothingModeAntiAlias); graphics.SetInterpolationMode(InterpolationModeHighQualityBicubic); graphics.SetTextRenderingHint(TextRenderingHintSingleBitPerPixel); // clear background CRgn bkgndRgn; CRect bkgndRect(clientRect); bkgndRect.left += 1; bkgndRect.top += 1; CreateRectRgnInDevicePoints(pDC, &bkgndRgn, bkgndRect, m_CornerRadius); pDC->SelectClipRgn(&bkgndRgn); pDC->FillSolidRect(&clientRect, RGB(255, 255, 255)); CRgn clientRgn; CreateRectRgnInDevicePoints(pDC, &clientRgn, clientRect); pDC->SelectClipRgn(&clientRgn); // Whole border Gdiplus::Rect borderRect(clientRect.left, clientRect.top, clientRect.Width(), clientRect.Height()); borderRect.Inflate(-1, -1); if (m_Buttons.size() == 0) { COLORREF borderColor = m_ColorMap.GetColor(Normal, Border); DrawRectArea(borderRect, graphics, borderColor, m_CornerRadius, m_BorderPenWidth); } for (int btnId = 0; btnId < m_Buttons.size(); ++btnId) { BtnInfo* pBtnInfo = &m_Buttons[btnId]; CRgn btnRgn; CRect t(pBtnInfo->m_rect); t.right += 1; t.bottom += 1; CreateRectRgnInDevicePoints(pDC, &btnRgn, t); btnRgn.CombineRgn(&btnRgn, &bkgndRgn, RGN_AND); pDC->SelectClipRgn(&btnRgn); ControlState buttonState = GetButtonState(pBtnInfo); // Highlight if (buttonState != Press) pDC->FillSolidRect(pBtnInfo->m_rect, m_ColorMap.GetColor(buttonState, BorderLight)); // Border graphics.SetClip(btnRgn); COLORREF borderColor = m_ColorMap.GetColor(buttonState, Border); DrawRectArea(borderRect, graphics, borderColor, m_CornerRadius, m_BorderPenWidth); graphics.ResetClip(); CRgn offsetRgn1; offsetRgn1.CreateRectRgn(0, 0, 0, 0); offsetRgn1.CopyRgn(&btnRgn); offsetRgn1.OffsetRgn(m_BorderPenWidth + 1, m_BorderPenWidth + 1); CRgn offsetRgn2; offsetRgn2.CreateRectRgn(0, 0, 0, 0); offsetRgn2.CopyRgn(&btnRgn); offsetRgn2.OffsetRgn(-(m_BorderPenWidth + 1), -(m_BorderPenWidth + 1)); CRgn backRgn; backRgn.CreateRectRgn(0, 0, 0, 0); backRgn.CombineRgn(&offsetRgn1, &offsetRgn2, RGN_AND); pDC->SelectClipRgn(&backRgn); if (buttonState != Mouseover) { DrawGradient(pDC, t); /*Draw4ColorsGradientRect(t, *pDC, m_ColorMap.GetColor(buttonState, BackgroundTopGradientStart), m_ColorMap.GetColor(buttonState, BackgroundTopGradientFinish), m_ColorMap.GetColor(buttonState, BackgroundBottomGradientStart), m_ColorMap.GetColor(buttonState, BackgroundBottomGradientFinish), m_CornerRadius, TRUE);*/ } COLORREF textColor = RGB(80,80,80);//COLOR_GRAYTEXT;//COLOR_BTNTEXT; /*if (buttonState == Press) textColor = RGB(0, 122, 224);*/ pDC->SelectClipRgn(&btnRgn); CFont* pFont = GetFont(); int nFormat = DT_CENTER | DT_VCENTER | DT_SINGLELINE | DT_END_ELLIPSIS; CTTButton::DrawCaptionText(pDC, &pBtnInfo->m_rect, &pBtnInfo->m_rect, pBtnInfo->m_text, nFormat, pFont, textColor); } pDC->SelectClipRgn(&clientRgn); for (int btnId = 1; btnId < m_Buttons.size(); ++btnId) { BtnInfo* pPrevBtnInfo = &m_Buttons[btnId - 1]; BtnInfo* pCurBtnInfo = &m_Buttons[btnId]; ControlState prevBtnState = GetButtonState(pPrevBtnInfo); ControlState curBtnState = GetButtonState(pCurBtnInfo); ControlState state = Normal; if (prevBtnState == Press || curBtnState == Press) state = Press; else if (prevBtnState == Mouseover || curBtnState == Mouseover) state = Mouseover; COLORREF borderColor = m_ColorMap.GetColor(state, Border); CPen borderPen(PS_SOLID, m_BorderPenWidth, borderColor); pDC->SelectObject(borderPen); pDC->MoveTo(pPrevBtnInfo->m_rect.right, pPrevBtnInfo->m_rect.top); pDC->LineTo(pPrevBtnInfo->m_rect.right, pPrevBtnInfo->m_rect.bottom); } }
void CImconView::OnDraw(CDC* pDC) { CImconDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); // TODO: add draw code for native data here if (pDC->IsPrinting()) { // Print image pDC->SetMapMode(MM_TWIPS); pDoc->m_Dib.Stretch(pDC->m_hDC, pDoc->m_hPal, pDoc->m_uLeftMargin, - (int) pDoc->m_uTopMargin, pDoc->m_uHorzPrintSize, - (int) pDoc->m_uVertPrintSize); } else { // Draw image on screen // Draw background RECT Rect; CBrush Brush; Brush.CreateHatchBrush(HS_BDIAGONAL, RGB(192, 192, 192)); GetClientRect(&Rect); Rect.right = max(Rect.right, (int) pDoc->m_uWidth); Rect.bottom = max(Rect.bottom, (int) pDoc->m_uHeight); CPoint ptScrollPos = GetScrollPosition(); pDC->SetBrushOrg(-ptScrollPos.x, -ptScrollPos.y); CRgn rgnImage; CRgn rgnWindow; rgnImage.CreateRectRgn(0, 0, pDoc->m_uWidth, pDoc->m_uHeight); rgnWindow.CreateRectRgnIndirect(&Rect); rgnWindow.CombineRgn(&rgnWindow, &rgnImage, RGN_DIFF); pDC->FillRgn(&rgnWindow, &Brush); // pDC->FillRect(&Rect, &Brush); // Draw image HPALETTE hPal; CPalette *pOldPal = NULL; if (m_bActive) hPal = pDoc->m_hPal; else { hPal = NULL; CPalette *pPal = CPalette::FromHandle(pDoc->m_hPal); pOldPal = pDC->SelectPalette(pPal, TRUE); pDC->RealizePalette(); } RECT rcClientArea; GetClientRect(&rcClientArea); if (m_bScaleToWindow) if (m_bUseDib) pDoc->m_Dib.Stretch(pDC->m_hDC, hPal, 0, 0, rcClientArea.right - rcClientArea.left, rcClientArea.bottom - rcClientArea.top); else pDoc->m_Ddb.Stretch(pDC->m_hDC, hPal, 0, 0, rcClientArea.right - rcClientArea.left, rcClientArea.bottom - rcClientArea.top); else if (m_bUseDib) pDoc->m_Dib.Draw(pDC->m_hDC, hPal, 0, 0); else pDoc->m_Ddb.Draw(pDC->m_hDC, hPal, 0, 0); if (pOldPal) pDC->SelectPalette(pOldPal, FALSE); // Draw selection if (m_bSelection) { LPRECT lpRect = &m_rectSelection; pDC->PatBlt(lpRect->left, lpRect->top, lpRect->right - lpRect->left, 1, DSTINVERT); pDC->PatBlt(lpRect->left, lpRect->bottom, 1, -(lpRect->bottom - lpRect->top), DSTINVERT); pDC->PatBlt(lpRect->right - 1, lpRect->top, 1, lpRect->bottom - lpRect->top, DSTINVERT); pDC->PatBlt(lpRect->right, lpRect->bottom - 1, -(lpRect->right - lpRect->left), 1, DSTINVERT); } } }
void CDC::DrawDragRect(LPCRECT lpRect, SIZE size, LPCRECT lpRectLast, SIZE sizeLast, CBrush* pBrush, CBrush* pBrushLast) { ASSERT(AfxIsValidAddress(lpRect, sizeof(RECT), FALSE)); ASSERT(lpRectLast == NULL || AfxIsValidAddress(lpRectLast, sizeof(RECT), FALSE)); // first, determine the update region and select it CRgn rgnNew; CRgn rgnOutside, rgnInside; rgnOutside.CreateRectRgnIndirect(lpRect); CRect rect = *lpRect; rect.InflateRect(-size.cx, -size.cy); rect.IntersectRect(rect, lpRect); rgnInside.CreateRectRgnIndirect(rect); rgnNew.CreateRectRgn(0, 0, 0, 0); rgnNew.CombineRgn(&rgnOutside, &rgnInside, RGN_XOR); CBrush* pBrushOld = NULL; if (pBrush == NULL) pBrush = CDC::GetHalftoneBrush(); if (pBrushLast == NULL) pBrushLast = pBrush; CRgn rgnLast, rgnUpdate; if (lpRectLast != NULL) { // find difference between new region and old region rgnLast.CreateRectRgn(0, 0, 0, 0); rgnOutside.SetRectRgn(lpRectLast); rect = *lpRectLast; rect.InflateRect(-sizeLast.cx, -sizeLast.cy); rect.IntersectRect(rect, lpRectLast); rgnInside.SetRectRgn(rect); rgnLast.CombineRgn(&rgnOutside, &rgnInside, RGN_XOR); // only diff them if brushes are the same if (pBrush->m_hObject == pBrushLast->m_hObject) { rgnUpdate.CreateRectRgn(0, 0, 0, 0); rgnUpdate.CombineRgn(&rgnLast, &rgnNew, RGN_XOR); } } if (pBrush->m_hObject != pBrushLast->m_hObject && lpRectLast != NULL) { // brushes are different -- erase old region first SelectClipRgn(&rgnLast); GetClipBox(&rect); pBrushOld = SelectObject(pBrushLast); PatBlt(rect.left, rect.top, rect.Width(), rect.Height(), PATINVERT); SelectObject(pBrushOld); pBrushOld = NULL; } // draw into the update/new region SelectClipRgn(rgnUpdate.m_hObject != NULL ? &rgnUpdate : &rgnNew); GetClipBox(&rect); pBrushOld = SelectObject(pBrush); PatBlt(rect.left, rect.top, rect.Width(), rect.Height(), PATINVERT); // cleanup DC if (pBrushOld != NULL) SelectObject(pBrushOld); SelectClipRgn(NULL); }
STDMETHODIMP CMyCom1::DrawOffset(unsigned long m_pDC, unsigned long m_pOffset, double m_Scale, unsigned long m_pGraphInfo, BOOL scale_flag, BOOL m_active_flag) { AFX_MANAGE_STATE(AfxGetStaticModuleState()) // TODO: Add your implementation code here CClientDC * pDC = (CClientDC*) m_pDC; GraphInfo * pGraphInfo; //设置 if ( m_pGraphInfo != NULL ) { pGraphInfo = (GraphInfo*)m_pGraphInfo; m_GraphInfo.SetGraphInfo(*pGraphInfo); } else pGraphInfo = &m_GraphInfo; //计算偏移量 if ( m_pOffset != NULL ) { CPoint * offset = (CPoint *)m_pOffset; OffsetRgn((unsigned long)offset); } //设置激活标志 isActive = m_active_flag; double scale = 0; m_scale_flag = scale_flag; if ( m_scale_flag ) scale = m_Scale; else scale = 1; CFont * sysFont = pDC->SelectObject(&(pGraphInfo->font)); CPen * pen = new CPen( pGraphInfo->normal_penStyle, pGraphInfo->normal_linewidth, pGraphInfo->normal_linecolor ); //构造画笔 CPen * sysPen = pDC->SelectObject(pen); CBrush * normalBrush = new CBrush( pGraphInfo->normal_regioncolor ); //普通显示的画刷 CBrush * activeBrush = new CBrush( pGraphInfo->active_regioncolor ); //激活后的画刷 CBrush * blackBrush = new CBrush( BLACKBRUSHCOLOR ); CRgn outRgn; outRgn.CreateRectRgn(0, 0, 5, 5); CRect smallRect; //判断是否激活了,如果激活,添加outRect if ( isActive ) //激活 { if ( m_scale_flag ) //如果是在modelview区域 { //选中后,在外边画一个方框 outRgn.CombineRgn(&upRgn, &downRgn, RGN_OR); outRgn.GetRgnBox(&outRect); outRect.InflateRect(5, 5); pDC->MoveTo(outRect.left, outRect.top); pDC->LineTo(outRect.right, outRect.top); pDC->LineTo(outRect.right, outRect.bottom); pDC->LineTo(outRect.left, outRect.bottom); pDC->LineTo(outRect.left, outRect.top); //画出upRgn, downRgn, 和连线 //pDC->FillRgn(&upRgn, normalBrush); CRect upRect; upRgn.GetRgnBox(upRect); pDC->Rectangle(upRect); pDC->MoveTo(upPoints[2]); pDC->LineTo(upPoints[5]); pDC->MoveTo(topPoint); pDC->LineTo(bottomPoint); pDC->MoveTo(leftPoint); pDC->LineTo(rightPoint); pDC->FillRgn(&downRgn, normalBrush); inRect.SetRect(upPoints[0].x, upPoints[0].y, upPoints[2].x, upPoints[2].y); pDC->SetTextColor(pGraphInfo->textcolor); pDC->DrawText(m_name, inRect, TEXTOUTFOMAT); //|DT_END_ELLIPSIS); //在矩形的角上,画四个小矩形,5*5象素 smallRect.SetRect(outRect.left, outRect.top, outRect.left+5, outRect.top+5); pDC->FillRect(smallRect, blackBrush); smallRect.SetRect(outRect.right-5, outRect.top, outRect.right, outRect.top+5); pDC->FillRect(smallRect, blackBrush); smallRect.SetRect(outRect.right-5, outRect.bottom-5, outRect.right, outRect.bottom); pDC->FillRect(smallRect, blackBrush); smallRect.SetRect(outRect.left, outRect.bottom-5, outRect.left+5, outRect.bottom); pDC->FillRect(smallRect, blackBrush); } else //如果是在comview区域 { //选中后,在外边画一个方框 downRgn.GetRgnBox(&outRect); outRect.InflateRect(5, 5); pDC->MoveTo(outRect.left, outRect.top); pDC->LineTo(outRect.right, outRect.top); pDC->LineTo(outRect.right, outRect.bottom); pDC->LineTo(outRect.left, outRect.bottom); pDC->LineTo(outRect.left, outRect.top); //画出downRgn pDC->FillRgn(&downRgn, normalBrush); //在矩形的角上,画四个小矩形,5*5象素 smallRect.SetRect(outRect.left, outRect.top, outRect.left+5, outRect.top+5); pDC->FillRect(smallRect, blackBrush); smallRect.SetRect(outRect.right-5, outRect.top, outRect.right, outRect.top+5); pDC->FillRect(smallRect, blackBrush); smallRect.SetRect(outRect.right-5, outRect.bottom-5, outRect.right, outRect.bottom); pDC->FillRect(smallRect, blackBrush); smallRect.SetRect(outRect.left, outRect.bottom-5, outRect.left+5, outRect.bottom); pDC->FillRect(smallRect, blackBrush); } } else //未激活 { if ( m_scale_flag ) //如果是在modelview区域 { //画出upRgn, downRgn, 和连线 //pDC->FillRgn(&upRgn, normalBrush); CRect upRect; upRgn.GetRgnBox(upRect); pDC->Rectangle(upRect); pDC->MoveTo(upPoints[2]); pDC->LineTo(upPoints[5]); pDC->MoveTo(topPoint); pDC->LineTo(bottomPoint); pDC->MoveTo(leftPoint); pDC->LineTo(rightPoint); pDC->FillRgn(&downRgn, normalBrush); inRect.SetRect(upPoints[0].x, upPoints[0].y, upPoints[2].x, upPoints[2].y); pDC->SetTextColor(pGraphInfo->textcolor); pDC->DrawText(m_name, inRect, TEXTOUTFOMAT); //|DT_END_ELLIPSIS); } else //如果是在comview区域 { //画出downRgn pDC->FillRgn(&downRgn, normalBrush); } } //释放 pDC->SelectObject(sysFont); pDC->SelectObject(sysPen); delete(pen); delete(normalBrush); delete(activeBrush); delete(blackBrush); return S_OK; }
void CControlResizer::DoReSize(int incrX, int incrY) { INT_PTR arrayCount = m_ResizePropArray.GetCount(); CRgn updateRgn; updateRgn.CreateRectRgn(0, 0, 0, 0); bool bIsEmptyUpdateRgn(true); for (INT_PTR i = 0; i < arrayCount; i++) { const ResizeProp &rszProp(m_ResizePropArray.GetAt(i)); if (IsHidden(rszProp.controlID)) continue; if (rszProp.uFlags & RSZF_NO_RESIZE) continue; RECT controlRect; CWnd *pControlWnd = m_pDialog->GetDlgItem(rszProp.controlID); pControlWnd->GetWindowRect(&controlRect); MapWindowPoints(NULL, m_pDialog->m_hWnd, (LPPOINT)&controlRect, 2); CRgn srcRgn; if (rszProp.uFlags & RSZF_RESIZE_UPDATE) { srcRgn.CreateRectRgn(controlRect.left, controlRect.top, controlRect.right, controlRect.bottom); } int widht = controlRect.right - controlRect.left; int height = controlRect.bottom - controlRect.top; int cx = incrX; int cy = incrY; if (rszProp.uFlags & RSZF_RESIZE_OPPOSITE) { cx = -cx; cy = -cy; } if (cx) { if (rszProp.uFlags & RSZF_SIZEX_FIXED) { OffsetRect(&controlRect, cx, 0); } else if (rszProp.uFlags & RSZF_RIGHT_FIXED) { controlRect.left = controlRect.right - widht - cx; } else if (rszProp.uFlags & RSZF_LEFT_FIXED) { controlRect.right = controlRect.left + widht + cx; } } if (cy) { if (rszProp.uFlags & RSZF_SIZEY_FIXED) { OffsetRect(&controlRect, 0, cy); } else if (rszProp.uFlags & RSZF_BOTTOM_FIXED) { controlRect.top = controlRect.bottom - height - cy; } else if (rszProp.uFlags & RSZF_TOP_FIXED) { controlRect.bottom = controlRect.top + height + cy; } } if (rszProp.uFlags & RSZF_RESIZE_UPDATE) { CRgn dst; dst.CreateRectRgn(controlRect.left, controlRect.top, controlRect.right, controlRect.bottom); updateRgn.CombineRgn(&srcRgn, &dst, RGN_OR); bIsEmptyUpdateRgn = false; } widht = controlRect.right - controlRect.left; height = controlRect.bottom - controlRect.top; pControlWnd->SetWindowPos(NULL, controlRect.left, controlRect.top, widht, height, SWP_NOZORDER); } if (!bIsEmptyUpdateRgn) { m_pDialog->InvalidateRgn(&updateRgn); m_pDialog->UpdateWindow(); } }
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; }
// this routine calculates the size and position of the window relative // to it's anchor point, and moves the window accordingly. The region is also // created and set here. void CBalloonHelp::PositionWindow() { CSize sizeWnd = CalcWindowSize(); CPoint ptTail[3]; CPoint ptTopLeft(0,0); CPoint ptBottomRight(sizeWnd.cx, sizeWnd.cy); // force recalculation of desktop m_screenRect.SetRectEmpty(); switch (GetBalloonQuadrant()) { case BQ_TOPLEFT: ptTopLeft.y = nTIP_TAIL; ptTail[0].x = (sizeWnd.cx-nTIP_TAIL)/4 + nTIP_TAIL; ptTail[0].y = nTIP_TAIL+1; ptTail[2].x = (sizeWnd.cx-nTIP_TAIL)/4; ptTail[2].y = ptTail[0].y; ptTail[1].x = ptTail[2].x; ptTail[1].y = 1; break; case BQ_TOPRIGHT: ptTopLeft.y = nTIP_TAIL; ptTail[0].x = (sizeWnd.cx-nTIP_TAIL)/4*3; ptTail[0].y = nTIP_TAIL+1; ptTail[2].x = (sizeWnd.cx-nTIP_TAIL)/4*3 + nTIP_TAIL; ptTail[2].y = ptTail[0].y; ptTail[1].x = ptTail[2].x; ptTail[1].y = 1; break; case BQ_BOTTOMLEFT: ptBottomRight.y = sizeWnd.cy-nTIP_TAIL; ptTail[0].x = (sizeWnd.cx-nTIP_TAIL)/4 + nTIP_TAIL; ptTail[0].y = sizeWnd.cy-nTIP_TAIL-2; ptTail[2].x = (sizeWnd.cx-nTIP_TAIL)/4; ptTail[2].y = ptTail[0].y; ptTail[1].x = ptTail[2].x; ptTail[1].y = sizeWnd.cy-2; break; case BQ_BOTTOMRIGHT: ptBottomRight.y = sizeWnd.cy-nTIP_TAIL; ptTail[0].x = (sizeWnd.cx-nTIP_TAIL)/4*3; ptTail[0].y = sizeWnd.cy-nTIP_TAIL-2; ptTail[2].x = (sizeWnd.cx-nTIP_TAIL)/4*3 + nTIP_TAIL; ptTail[2].y = ptTail[0].y; ptTail[1].x = ptTail[2].x; ptTail[1].y = sizeWnd.cy-2; break; default: ASSERT(FALSE); } // adjust for very narrow balloons if ( ptTail[0].x < nTIP_MARGIN ) ptTail[0].x = nTIP_MARGIN; if ( ptTail[0].x > sizeWnd.cx - nTIP_MARGIN ) ptTail[0].x = sizeWnd.cx - nTIP_MARGIN; if ( ptTail[1].x < nTIP_MARGIN ) ptTail[1].x = nTIP_MARGIN; if ( ptTail[1].x > sizeWnd.cx - nTIP_MARGIN ) ptTail[1].x = sizeWnd.cx - nTIP_MARGIN; if ( ptTail[2].x < nTIP_MARGIN ) ptTail[2].x = nTIP_MARGIN; if ( ptTail[2].x > sizeWnd.cx - nTIP_MARGIN ) ptTail[2].x = sizeWnd.cx - nTIP_MARGIN; // get window position CPoint ptAnchor = GetAnchorPoint(); CPoint ptOffs(ptAnchor.x - ptTail[1].x, ptAnchor.y - ptTail[1].y); // adjust position so all is visible CRect rectScreen; GetAnchorScreenBounds(rectScreen); int nAdjustX = 0; int nAdjustY = 0; if ( ptOffs.x < rectScreen.left ) nAdjustX = rectScreen.left-ptOffs.x; else if ( ptOffs.x + sizeWnd.cx >= rectScreen.right ) nAdjustX = rectScreen.right - (ptOffs.x + sizeWnd.cx); if ( ptOffs.y + nTIP_TAIL < rectScreen.top ) nAdjustY = rectScreen.top - (ptOffs.y + nTIP_TAIL); else if ( ptOffs.y + sizeWnd.cy - nTIP_TAIL >= rectScreen.bottom ) nAdjustY = rectScreen.bottom - (ptOffs.y + sizeWnd.cy - nTIP_TAIL); // reposition tail // uncomment two commented lines below to move entire tail // instead of just anchor point //ptTail[0].x -= nAdjustX; ptTail[1].x -= nAdjustX; //ptTail[2].x -= nAdjustX; ptOffs.x += nAdjustX; ptOffs.y += nAdjustY; // place window MoveWindow(ptOffs.x, ptOffs.y, sizeWnd.cx, sizeWnd.cy, TRUE); // apply region CRgn region; CRgn regionRound; CRgn regionComplete; region.CreatePolygonRgn(&ptTail[0], 3, ALTERNATE); regionRound.CreateRoundRectRgn(ptTopLeft.x,ptTopLeft.y,ptBottomRight.x,ptBottomRight.y,nTIP_MARGIN*3,nTIP_MARGIN*3); regionComplete.CreateRectRgn(0,0,1,1); regionComplete.CombineRgn(®ion, ®ionRound, RGN_OR); if ( NULL == m_rgnComplete.m_hObject ) m_rgnComplete.CreateRectRgn(0,0,1,1); if ( !m_rgnComplete.EqualRgn(®ionComplete) ) { m_rgnComplete.CopyRgn(®ionComplete); SetWindowRgn((HRGN)regionComplete.Detach(), TRUE); // There is a bug with layered windows and NC changes in Win2k // As a workaround, redraw the entire window if the NC area changed. // Changing the anchor point is the ONLY thing that will change the // position of the client area relative to the window during normal // operation. RedrawWindow(NULL, NULL, RDW_UPDATENOW| RDW_ERASE | RDW_INVALIDATE | RDW_FRAME | RDW_ALLCHILDREN); } }
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; }
//设置区域 VOID CLayeredWindow::InitLayeredArea(CDC * pDCImage, BYTE cbAlpha, CRect & rcUnLayered, CPoint & PointRound, bool bUnLayeredChild) { //效验参数 ASSERT((pDCImage!=NULL)&&(pDCImage->m_hDC!=NULL)); if ((pDCImage==NULL)||(pDCImage->m_hDC==NULL)) return; //变量定义 BITMAP Bitmap; ZeroMemory(&Bitmap,sizeof(Bitmap)); //获取图像 CBitmap * pBitmap=pDCImage->GetCurrentBitmap(); if (pBitmap!=NULL) pBitmap->GetBitmap(&Bitmap); //获取大小 CSize SizeImage; SizeImage.SetSize(Bitmap.bmWidth,Bitmap.bmHeight); //效验大小 ASSERT((SizeImage.cx>0)&&(SizeImage.cy>0)); if ((SizeImage.cx==0)||(SizeImage.cy==0)) return; //变量定义 BLENDFUNCTION BlendFunction; ZeroMemory(&BlendFunction,sizeof(BlendFunction)); //设置参数 BlendFunction.BlendOp=0; BlendFunction.BlendFlags=0; BlendFunction.AlphaFormat=AC_SRC_ALPHA; BlendFunction.SourceConstantAlpha=cbAlpha; //设置分层 CPoint ImagePoint(0,0); CClientDC ClientDC(this); UpdateLayeredWindow(&ClientDC,NULL,&SizeImage,pDCImage,&ImagePoint,0L,&BlendFunction,ULW_ALPHA); //创建区域 CRgn RegionResult; RegionResult.CreateRectRgn(0,0,SizeImage.cx,SizeImage.cy); //窗口排除 if (bUnLayeredChild==true) { //变量定义 tagEnumChildInfo EnumChildInfo; ZeroMemory(&EnumChildInfo,sizeof(EnumChildInfo)); //设置变量 EnumChildInfo.pWndLayered=this; EnumChildInfo.pWndControl=m_pWndControl; EnumChildInfo.pRegionResult=&RegionResult; //枚举窗口 ASSERT(m_pWndControl->GetSafeHwnd()!=NULL); EnumChildWindows(m_pWndControl->m_hWnd,EnumChildProc,(LPARAM)&EnumChildInfo); } //区域排除 if (rcUnLayered.IsRectEmpty()==FALSE) { //创建区域 CRgn RegionUnLayered; RegionUnLayered.CreateRoundRectRgn(rcUnLayered.left,rcUnLayered.top,rcUnLayered.right+1,rcUnLayered.bottom+1,PointRound.x,PointRound.y); //合并区域 RegionResult.CombineRgn(&RegionResult,&RegionUnLayered,RGN_DIFF); } //设置区域 SetWindowRgn(RegionResult,TRUE); return; }