/*! * This function should be called inside the parent window @c WM_NCCALCSIZE * message handler to help eliminate flickering. * * @param bAfterDefault Flag that specifies wether the call is made before * or after the default handler * @param lpncsp Pointer to the @c NCCALCSIZE_PARAMS structure that is * passed to the message handler * @param lResult Reference to the result of the message handler. * It contains the default handler result on input and the value to * return from the window procedure on output. * * @remarks This function fixes the annoying flickering effect that is * visible when resizing the top or left edges of the window * (at least on a "left to right" Windows localized version). */ void CResizableLayout::HandleNcCalcSize(BOOL bAfterDefault, LPNCCALCSIZE_PARAMS lpncsp, LRESULT &lResult) { // prevent useless complication when size is not changing // prevent recursion when resetting the window region (see below) if ((lpncsp->lppos->flags & SWP_NOSIZE) #if (_WIN32_WINNT >= 0x0501) || m_bNoRecursion #endif ) return; if (!bAfterDefault) { // save a copy before default handler gets called m_rectClientBefore = lpncsp->rgrc[2]; } else // after default WM_NCCALCSIZE msg processing { if (lResult != 0) { // default handler already uses an advanced validation policy, give up return; } // default calculated client rect RECT &rectClientAfter = lpncsp->rgrc[0]; // intersection between old and new client area is to be preserved // set source and destination rects to this intersection RECT &rectPreserve = lpncsp->rgrc[1]; ::IntersectRect(&rectPreserve, &rectClientAfter, &m_rectClientBefore); lpncsp->rgrc[2] = rectPreserve; lResult = WVR_VALIDRECTS; // FIX: window region must be updated before the result of the // WM_NCCALCSIZE message gets processed by the system, // otherwise the old window region will clip the client // area during the preservation process. // This is especially evident on WinXP when the non-client // area is rendered with Visual Styles enabled and the // windows have a non rectangular region. // NOTE: Implementers of skin systems that modify the window region // should not rely on this fix and should handle non-client // window messages themselves, to avoid flickering #if (_WIN32_WINNT >= 0x0501) if ((real_WIN32_WINNT >= 0x0501) && (real_ThemeSettings & STAP_ALLOW_NONCLIENT)) { CWnd* pWnd = GetResizableWnd(); DWORD dwStyle = pWnd->GetStyle(); if ((dwStyle & (WS_CAPTION|WS_MAXIMIZE)) == WS_CAPTION) { m_bNoRecursion = TRUE; pWnd->SetWindowRgn(NULL, FALSE); m_bNoRecursion = FALSE; } } #endif } }
LRESULT OnPaint( HWND hWnd ) { CWnd* pWnd = CWnd::FromHandle(hWnd); CPaintDC dc(pWnd); CString Text; CRect RC; CFont Font; CFont *pOldFont; CBrush Brush; CBrush *pOldBrush; CPoint PT(2,2); dc.SetBkMode( TRANSPARENT ); Font.CreateFont( 12, 0, 0, 0, FW_HEAVY, 0, 0, 0, ANSI_CHARSET, \ OUT_TT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, \ VARIABLE_PITCH | FF_SWISS, "MS Sans Serif" ); pOldFont = dc.SelectObject( &Font ); if( m_State == bsNormal) { if (m_Style==2) { CBitmap bmp; bmp.LoadBitmap(IDB_BKBUTTON); Brush.CreatePatternBrush(&bmp); } else Brush.CreateSolidBrush( RGB( 200, 200, 200 ) ); dc.SetTextColor( RGB( 80, 80, 80) ); } else if( m_State == bsDown ) { Brush.CreateSolidBrush( RGB( 160, 160, 160 ) ); dc.SetTextColor( RGB( 50, 50, 250 ) ); } else if( m_State == bsHot ) { Brush.CreateSolidBrush( RGB( 100, 100, 180 ) ); dc.SetTextColor( RGB( 250, 250, 0 ) ); } pOldBrush = dc.SelectObject( &Brush ); pWnd->GetClientRect( &RC ); dc.RoundRect( &RC, PT ); HRGN hRgn = CreateRectRgn( RC.left, RC.top, RC.right, RC.bottom ); pWnd->SetWindowRgn( hRgn, TRUE ); DeleteObject( hRgn ); pWnd->GetWindowText(Text ); dc.DrawText( Text, &RC, DT_CENTER | DT_VCENTER | DT_SINGLELINE ); dc.SelectObject( pOldFont ); dc.SelectObject( pOldBrush ); return TRUE; }
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(); }
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(); }