win32context.cpp

来自「这是VCF框架的代码」· C++ 代码 · 共 2,636 行 · 第 1/5 页

CPP
2,636
字号
	::SelectObject( dc_, oldFont );	::DeleteObject( font );	releaseHandle();	return textSize.cy;}void Win32Context::setTextAlignment( const bool& alignTobaseline ){	alignToBaseline_ = alignTobaseline;}bool Win32Context::isTextAlignedToBaseline(){	return alignToBaseline_;}/***Utility function to draw a transparent bitmap from MSDN*HOWTO: Drawing Transparent Bitmaps*Article ID: Q79212*JC: This is an awfult lot of shit to just draw a transparent bmp.*Maybe this will be revisited ???*/void Win32Context::drawTransparentBitmap(HDC hdc, HBITMAP hBitmap, long xStart,                           long yStart, COLORREF cTransparentColor){	BITMAP     bm;	COLORREF   cColor;	HBITMAP    bmAndBack, bmAndObject, bmAndMem, bmSave;	HBITMAP    bmBackOld, bmObjectOld, bmMemOld, bmSaveOld;	HDC        hdcMem, hdcBack, hdcObject, hdcTemp, hdcSave;	POINT      ptSize;	hdcTemp = CreateCompatibleDC( NULL );//hdc);	SelectObject(hdcTemp, hBitmap);   // Select the bitmap	GetObject(hBitmap, sizeof(BITMAP), (LPSTR)&bm);	ptSize.x = bm.bmWidth;            // Get width of bitmap	ptSize.y = bm.bmHeight;           // Get height of bitmap	DPtoLP(hdcTemp, &ptSize, 1);      // Convert from device	// to logical points	// Create some DCs to hold temporary data.	hdcBack   = CreateCompatibleDC(hdc);	hdcObject = CreateCompatibleDC(hdc);	hdcMem    = CreateCompatibleDC(hdc);	hdcSave   = CreateCompatibleDC(hdc);	// Create a bitmap for each DC. DCs are required for a number of	// GDI functions.	// Monochrome DC	bmAndBack   = CreateBitmap(ptSize.x, ptSize.y, 1, 1, NULL);	// Monochrome DC	bmAndObject = CreateBitmap(ptSize.x, ptSize.y, 1, 1, NULL);	bmAndMem    = CreateCompatibleBitmap(hdc, ptSize.x, ptSize.y);	bmSave      = CreateCompatibleBitmap(hdc, ptSize.x, ptSize.y);	// Each DC must select a bitmap object to store pixel data.	bmBackOld   = (HBITMAP)SelectObject(hdcBack, bmAndBack);	bmObjectOld = (HBITMAP)SelectObject(hdcObject, bmAndObject);	bmMemOld    = (HBITMAP)SelectObject(hdcMem, bmAndMem);	bmSaveOld   = (HBITMAP)SelectObject(hdcSave, bmSave);	// Set proper mapping mode.	SetMapMode(hdcTemp, GetMapMode(hdc));	// Save the bitmap sent here, because it will be overwritten.	BitBlt(hdcSave, 0, 0, ptSize.x, ptSize.y, hdcTemp, 0, 0, SRCCOPY);	// Set the background color of the source DC to the color.	// contained in the parts of the bitmap that should be transparent	cColor = SetBkColor(hdcTemp, cTransparentColor);	// Create the object mask for the bitmap by performing a BitBlt	// from the source bitmap to a monochrome bitmap.	BitBlt(hdcObject, 0, 0, ptSize.x, ptSize.y, hdcTemp, 0, 0,		SRCCOPY);	// Set the background color of the source DC back to the original	// color.	SetBkColor(hdcTemp, cColor);	// Create the inverse of the object mask.	BitBlt(hdcBack, 0, 0, ptSize.x, ptSize.y, hdcObject, 0, 0,		NOTSRCCOPY);	// Copy the background of the main DC to the destination.	BitBlt(hdcMem, 0, 0, ptSize.x, ptSize.y, hdc, xStart, yStart,		SRCCOPY);	// Mask out the places where the bitmap will be placed.	BitBlt(hdcMem, 0, 0, ptSize.x, ptSize.y, hdcObject, 0, 0, SRCAND);	// Mask out the transparent colored pixels on the bitmap.	BitBlt(hdcTemp, 0, 0, ptSize.x, ptSize.y, hdcBack, 0, 0, SRCAND);	// XOR the bitmap with the background on the destination DC.	BitBlt(hdcMem, 0, 0, ptSize.x, ptSize.y, hdcTemp, 0, 0, SRCPAINT);	// Copy the destination to the screen.	BitBlt(hdc, xStart, yStart, ptSize.x, ptSize.y, hdcMem, 0, 0,		SRCCOPY);	// Place the original bitmap back into the bitmap sent here.	BitBlt(hdcTemp, 0, 0, ptSize.x, ptSize.y, hdcSave, 0, 0, SRCCOPY);	// Delete the memory bitmaps.	DeleteObject(SelectObject(hdcBack, bmBackOld));	DeleteObject(SelectObject(hdcObject, bmObjectOld));	DeleteObject(SelectObject(hdcMem, bmMemOld));	DeleteObject(SelectObject(hdcSave, bmSaveOld));	// Delete the memory DCs.	DeleteDC(hdcMem);	DeleteDC(hdcBack);	DeleteDC(hdcObject);	DeleteDC(hdcSave);	DeleteDC(hdcTemp);}void Win32Context::setClippingRect( Rect* clipRect ){	checkHandle();	if ( NULL != clipRGN_ ) {		if ( !::DeleteObject( clipRGN_ ) ) {			StringUtils::traceWithArgs( Format("Error in DeleteObject( %p )\n") % clipRGN_ % GetLastError() );		}	}	clipRGN_ = NULL;	if ( NULL != clipRect ) {		if ( !clipRect->isNull() ) {			clipRGN_ = CreateRectRgn( (long)clipRect->left_ + origin_.x_,										(long)clipRect->top_ + origin_.y_,										(long)clipRect->right_ + origin_.x_,										(long)clipRect->bottom_  + origin_.y_);		}		else {			clipRGN_ = NULL;		}	}	if ( ERROR == ::SelectClipRgn( dc_, clipRGN_ ) ){		StringUtils::traceWithArgs( Format( "Error in SelectClipRgn( %p, %p )\n" ) % dc_ % clipRGN_ % GetLastError() );	}	releaseHandle();}void Win32Context::setClippingPath( Path* clippingPath ){	checkHandle();	if ( NULL != clipRGN_ ) {		::DeleteObject( clipRGN_ );	}	clipRGN_ = NULL;	if ( NULL != clippingPath ) {		::BeginPath( dc_ );		std::vector<PathPoint> points;		Matrix2D* currentXFrm = context_->getCurrentTransform();		clippingPath->getPoints( points, currentXFrm );		std::vector<PathPoint>::iterator it = points.begin();		while ( it != points.end() ) {			const PathPoint& pt = *it;			switch ( pt.type_ ){				case PathPoint::ptMoveTo: {					MoveToEx( dc_, (long)pt.point_.x_ + origin_.x_, (long)pt.point_.y_ + origin_.y_, NULL );				}				break;				case PathPoint::ptLineTo: {					LineTo( dc_, (long)pt.point_.x_ + origin_.x_, (long)pt.point_.y_ + origin_.y_ );				}				break;				case PathPoint::ptQuadTo: {				}				break;				case PathPoint::ptCubicTo: {				}				break;				case PathPoint::ptClose: {					LineTo( dc_, (long)pt.point_.x_ + origin_.x_, (long)pt.point_.y_ + origin_.y_ );				}				break;			}			it++;		}		::EndPath( dc_ );		clipRGN_ = ::PathToRegion( dc_ );	}	::SelectClipRgn( dc_, clipRGN_ );	releaseHandle();}void Win32Context::drawThemeSelectionRect( Rect* rect, DrawUIState& state ){	checkHandle();	RECT r = {0,0,0,0};	r.left = (long)rect->left_;	r.top = (long)rect->top_;	r.right = (long)rect->right_;	r.bottom = (long)rect->bottom_;	int err = ::DrawFocusRect( dc_, &r );	releaseHandle();}void Win32Context::drawThemeFocusRect( Rect* rect, DrawUIState& state ){	checkHandle();	RECT r = {0,0,0,0};	r.left = (long)rect->left_;	r.top = (long)rect->top_;	r.right = (long)rect->right_;	r.bottom = (long)rect->bottom_;	int err = ::DrawFocusRect( dc_, &r );	releaseHandle();}void Win32Context::drawThemeButtonFocusRect( Rect* rect ){	Rect focusRect = *rect;	focusRect.inflate( -4, -4 );	DrawUIState state;	drawThemeFocusRect( &focusRect, state );}void Win32Context::drawThemeButtonRect( Rect* rect, ButtonState& state, Rect* captionRect ){	checkHandle();	RECT btnRect;	btnRect.left = rect->left_;	btnRect.top = rect->top_;	btnRect.right = rect->right_;	btnRect.bottom = rect->bottom_;	HTHEME theme = NULL;	if ( Win32VisualStylesWrapper::IsThemeActive() ) {		theme = Win32VisualStylesWrapper::OpenThemeData( NULL, L"BUTTON" );	}	if ( theme ) {		int dcs = SaveDC( dc_ );		int btnState = 0;		if ( !state.isEnabled() ) {			btnState =	PBS_DISABLED;		}		else {			btnState |= state.isHighlighted() ? PBS_HOT	: PBS_NORMAL;			btnState |=	state.isDefaultButton()	? PBS_DEFAULTED : PBS_NORMAL;			btnState = state.isPressed() ? PBS_PRESSED	: btnState;		}		Win32VisualStylesWrapper::DrawThemeBackground(theme, dc_, BP_PUSHBUTTON, btnState, &btnRect, 0);		SetBkMode(dc_, TRANSPARENT);		VCF::Font btnFont = *context_->getCurrentFont();		HFONT font = NULL;		if ( System::isUnicodeEnabled() ) {			LOGFONTW* lf = (LOGFONTW*) btnFont.getFontPeer()->getFontHandleID();			font = ::CreateFontIndirectW( lf );			::SelectObject( dc_, font );		}		else {			LOGFONTA* lf = (LOGFONTA*) btnFont.getFontPeer()->getFontHandleID();			font = ::CreateFontIndirectA( lf );			::SelectObject( dc_, font );		}		btnRect.left += 5;		btnRect.right -= 5;		Win32VisualStylesWrapper::DrawThemeText(theme, dc_, BP_PUSHBUTTON, btnState,			state.buttonCaption_.c_str(),			state.buttonCaption_.length(),			DT_SINGLELINE | DT_CENTER | DT_VCENTER, NULL,			&btnRect);		Win32VisualStylesWrapper::CloseThemeData( theme );		RestoreDC(dc_, dcs );		DeleteObject( font );	}	else {		COLORREF backColor = ::GetSysColor( COLOR_3DFACE );		HBRUSH backBrush = CreateSolidBrush( backColor );		HPEN hilightPen = CreatePen( PS_SOLID, 0, ::GetSysColor( COLOR_3DHIGHLIGHT ) );		HPEN shadowPen = CreatePen( PS_SOLID, 0, ::GetSysColor( COLOR_3DSHADOW ) );		HPEN blackPen = CreatePen( PS_SOLID, 0, 0 );		HBRUSH oldBrush = (HBRUSH)::SelectObject( dc_, backBrush );		::FillRect( dc_, &btnRect, backBrush );		bool isPressed = state.isPressed();		HPEN oldPen = NULL;		RECT tmpRect = btnRect;		//InflateRect( &tmpRect, -1, -1 );		if ( state.isDefaultButton() ) {			InflateRect( &tmpRect, -1, -1 );		}		RECT capRect = btnRect;		if ( NULL != captionRect ) {			capRect.left = captionRect->left_;			capRect.top = captionRect->top_;			capRect.right = captionRect->right_;			capRect.bottom = captionRect->bottom_;		}		if ( true == isPressed ) {			HBRUSH shadowBrush = CreateSolidBrush( ::GetSysColor( COLOR_3DSHADOW ) );			::FrameRect( dc_, &tmpRect, shadowBrush );			DeleteObject( shadowBrush );			::OffsetRect( &capRect, 1, 1 );		}		else {			oldPen = (HPEN) ::SelectObject( dc_, hilightPen );			::MoveToEx( dc_, tmpRect.right, tmpRect.top, NULL );			::LineTo( dc_, tmpRect.left, tmpRect.top );			::LineTo( dc_, tmpRect.left, tmpRect.bottom-1 );			::SelectObject( dc_, shadowPen );			::MoveToEx( dc_, tmpRect.right-2, tmpRect.top+1, NULL );			::LineTo( dc_, tmpRect.right-2, tmpRect.bottom-2 );			::LineTo( dc_, tmpRect.left, tmpRect.bottom-2 );			::SelectObject( dc_, blackPen );			::MoveToEx( dc_, tmpRect.right-1, tmpRect.top, NULL );			::LineTo( dc_, tmpRect.right-1, tmpRect.bottom-1 );			::LineTo( dc_, tmpRect.left-1, tmpRect.bottom-1 );			/*			::MoveToEx( dc_, tmpRect.right, tmpRect.top, NULL );			::LineTo( dc_, tmpRect.left, tmpRect.top );			::LineTo( dc_, tmpRect.left, tmpRect.bottom );			  ::SelectObject( dc_, shadowPen );			  ::MoveToEx( dc_, tmpRect.right-1, tmpRect.top+1, NULL );			  ::LineTo( dc_, tmpRect.right-1, tmpRect.bottom-1 );			  ::LineTo( dc_, tmpRect.left, tmpRect.bottom-1 );				::SelectObject( dc_, blackPen );				::MoveToEx( dc_, tmpRect.right-1, tmpRect.top, NULL );				::LineTo( dc_, tmpRect.right, tmpRect.bottom );				::LineTo( dc_, tmpRect.left, tmpRect.bottom );			*/		}		bool enabled = state.isEnabled();		HFONT font = NULL;		HFONT oldFont = NULL;		VCF::Font btnFont = *context_->getCurrentFont();		Rect centerRect( capRect.left, capRect.top, capRect.right, capRect.bottom );		if ( System::isUnicodeEnabled() ) {			LOGFONTW* lf = (LOGFONTW*) btnFont.getFontPeer()->getFontHandleID();			font = ::CreateFontIndirectW( lf );			oldFont = (HFONT) ::SelectObject( dc_, font );			::DrawTextW( dc_, state.buttonCaption_.c_str(), -1, &capRect, DT_WORDBREAK | DT_CENTER | DT_CALCRECT);		}		else {			LOGFONTA* lf = (LOGFONTA*) btnFont.getFontPeer()->getFontHandleID();			font = ::CreateFontIndirectA( lf );			oldFont = (HFONT) ::SelectObject( dc_, font );			::DrawTextA( dc_, state.buttonCaption_.ansi_c_str(), -1, &capRect, DT_WORDBREAK | DT_CENTER | DT_CALCRECT);		}		::OffsetRect( &capRect,			(centerRect.getWidth() - (capRect.right - capRect.left))/2,			(centerRect.getHeight() - (capRect.bottom - capRect.top))/2 );		int oldBkMode = SetBkMode( dc_, TRANSPARENT );		COLORREF textColor = 0;		if ( true == enabled ) {			textColor = ::GetSysColor( COLOR_BTNTEXT );		}		else {			textColor = ::GetSysColor( COLOR_GRAYTEXT );		}		COLORREF oldTextColor = SetTextColor( dc_, textColor );		if ( false == enabled ) {			SetTextColor( dc_, ::GetSysColor( COLOR_BTNHIGHLIGHT ) );			OffsetRect( &capRect, 1, 1 );			if ( System::isUnicodeEnabled() ) {				::DrawTextW( dc_, state.buttonCaption_.c_str(), -1, &capRect, DT_WORDBREAK | DT_CENTER);			}			else {				::DrawTextA( dc_, state.buttonCaption_.ansi_c_str(), -1, &capRect, DT_WORDBREAK | DT_CENTER);			}			OffsetRect( &capRect, -1, -1 );			SetTextColor( dc_, textColor );		}		if ( System::isUnicodeEnabled() ) {			::DrawTextW( dc_, state.buttonCaption_.c_str(), -1, &capRect, DT_WORDBREAK | DT_CENTER);		}		else {			::DrawTextA( dc_, state.buttonCaption_.ansi_c_str(), -1, &capRect, DT_WORDBREAK | DT_CENTER);		}		SetTextColor( dc_, oldTextColor );		SetBkMode( dc_, oldBkMode );		::SelectObject( dc_, oldFont );		::DeleteObject( font );		/*if ( state.isFocused() ) {		RECT focusRect = btnRect;		InflateRect( &focusRect, -4, -4 );		  ::DrawFocusRect( dc_, &focusRect );	}*/		if ( state.isDefaultButton() ) {			RECT defRect = btnRect;			//defRect.right -= 1;			//defRect.bottom -= 1;			FrameRect( dc_, &defRect, (HBRUSH)GetStockObject(BLACK_BRUSH) );		}		if ( NULL != oldBrush ) {			::SelectObject( dc_, oldBrush );		}		if ( NULL != oldPen ) {			::SelectObject( dc_, oldPen );		}		::DeleteObject( hilightPen );		::DeleteObject( shadowPen );		::DeleteObject( blackPen );		::DeleteObject( backBrush );	}	releaseHandle();}void Win32Context::drawThemeCheckboxRect( Rect* rect, ButtonState& state ){	checkHandle();	Rect tmp = *rect;	HTHEME theme = NULL;	if ( Win32VisualStylesWrapper::IsThemeActive() ) {		theme = Win32VisualStylesWrapper::OpenThemeData( NULL, L"BUTTON" );

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?