abstractwin32component.cpp

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

CPP
2,113
字号
//AbstractWin32Component.cpp/*Copyright 2000-2004 The VCF Project.Please see License.txt in the top level directorywhere you installed the VCF.*/#include "vcf/ApplicationKit/ApplicationKit.h"#include "vcf/ApplicationKit/MenuItemPeer.h"#include "vcf/GraphicsKit/ContextPeer.h"#include "vcf/ApplicationKit/Win32Object.h"#include "vcf/ApplicationKit/AbstractWin32Component.h"#include "vcf/ApplicationKit/Win32ToolKit.h"#include "vcf/ApplicationKit/Win32MenuItem.h"#include "vcf/GraphicsKit/Win32FontManager.h"#include "vcf/ApplicationKit/Scrollable.h"#include "vcf/ApplicationKit/ScrollPeer.h"#include "vcf/ApplicationKit/Win32ScrollPeer.h"#include "vcf/FoundationKit/Win32Peer.h"#include "vcf/GraphicsKit/Win32Font.h"#include "vcf/ApplicationKit/CursorPeer.h"#include "thirdparty/win32/Microsoft/htmlhelp.h"#include "vcf/GraphicsKit/Win32VisualStylesWrapper.h"using namespace VCF;using namespace VCFWin32;AbstractWin32Component::AbstractWin32Component():	memDC_(NULL),	originalMemBMP_(NULL),	memBMP_(NULL),	mouseEnteredControl_(false),		memDCState_(0),	destroyed_(false),	canProcessMessages_(false),	currentFont_(NULL),	cachedMessages_(NULL){	init();	setPeerControl( NULL );}AbstractWin32Component::AbstractWin32Component( Control* component ):	memDC_(NULL),	originalMemBMP_(NULL),	memBMP_(NULL),	mouseEnteredControl_(false),		memDCState_(0),	destroyed_(false),	canProcessMessages_(false),	currentFont_(NULL),	cachedMessages_(NULL){	init();	setPeerControl( component );}void AbstractWin32Component::create( Control* owningControl ){	setPeerControl( owningControl );}void AbstractWin32Component::destroyControl(){	if ( !destroyed_ ) {				if ( NULL != hwnd_ ){					if ( IsWindow( hwnd_ ) ) {				BOOL err = ::DestroyWindow( hwnd_ );				if ( !err )  {					//throw RuntimeException( MAKE_ERROR_MSG_2("DestroyWindow failed") );					err = GetLastError();				}			}			else {				destroyWindowHandle();			}		}	}		if ( !destroyed_ ) {		destroyWindowHandle();		destroyed_ = true;	}		hwnd_ = NULL;	wndProc_ = NULL;	defaultWndProc_ = NULL;	peerControl_ = NULL;	if ( NULL != memDC_ ) {		DeleteDC( memDC_ );	}	memDC_ = NULL;}AbstractWin32Component::~AbstractWin32Component(){}void AbstractWin32Component::init(){	memDC_ = NULL;	mouseEnteredControl_ = false;	cachedMessages_ = new std::vector<MSG>();	}OSHandleID AbstractWin32Component::getHandleID(){	OSHandleID result = 0;	result = (OSHandleID)hwnd_;	return result;}VCF::String AbstractWin32Component::getText(){	VCF::String result;	if ( System::isUnicodeEnabled() ) {		int size = ::GetWindowTextLengthW( hwnd_ )+1;		if ( size > 1 ) {			VCFChar* tmpText = new VCFChar[size];			memset( tmpText, 0, size*sizeof(VCFChar) );			::GetWindowTextW( hwnd_, tmpText, size );			result = tmpText;			delete [] tmpText;		}	}	else {		int size = ::GetWindowTextLengthA( hwnd_ )+1;		if ( size > 1 ) {			char* tmpText = new char[size];			memset( tmpText, 0, size*sizeof(char) );			::GetWindowTextA( hwnd_, tmpText, size );			result = tmpText;			delete [] tmpText;		}	}	return result;}void AbstractWin32Component::setText( const VCF::String& text ){	if ( System::isUnicodeEnabled() ) {		const VCFChar* chars = text.c_str();		::SetWindowTextW( hwnd_, chars );	}	else {		::SetWindowTextA( hwnd_, text.ansi_c_str() );	}}void AbstractWin32Component::setBounds( VCF::Rect* rect ){		if ( !peerControl_->hasChildren() ) {		::MoveWindow( hwnd_, (int)rect->left_, (int)rect->top_, rect->getWidth(), (int)rect->getHeight(), TRUE );	}	else {		::SetWindowPos( hwnd_, NULL, (int)rect->left_, (int)rect->top_,			          (int)rect->getWidth(), (int)rect->getHeight(), SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOZORDER );	}	}bool AbstractWin32Component::beginSetBounds( const ulong32& numberOfChildren ){		//JEC - I commented this out to simplify/speed up some resize/repaint issues	bool result = true;		return result;}void AbstractWin32Component::endSetBounds(){	}VCF::Rect AbstractWin32Component::getBounds(){	VCF::Rect result;	RECT r; 	::GetWindowRect( hwnd_, &r );	DWORD style = ::GetWindowLong( hwnd_, GWL_STYLE );	HWND parent = ::GetParent( hwnd_ );	if ( style & WS_CHILD ){		POINT pt = {0,0};		pt.x = r.left;		pt.y = r.top;		::ScreenToClient( parent, &pt );		r.left = pt.x;		r.top = pt.y;		pt.x = r.right;		pt.y = r.bottom;		::ScreenToClient( parent, &pt );		r.right = pt.x;		r.bottom = pt.y;		result.setRect( r.left, r.top, r.right, r.bottom );	}	else{		result.setRect( r.left, r.top, r.right, r.bottom );	}	return result;}void AbstractWin32Component::setVisible( const bool& visible ){	if ( (peerControl_->isDesigning()) && (NULL == GetParent(hwnd_)) ) {		return; //do nothing! can't show the control till it's parented	}	if ( true == visible ){		::ShowWindow( hwnd_, SW_SHOW );	}	else{		::ShowWindow( hwnd_, SW_HIDE );	}}bool AbstractWin32Component::getVisible(){	bool result = false;	DWORD style = GetWindowLong( hwnd_, GWL_STYLE );	result =  (style & WS_VISIBLE ) != 0;	return result;}VCF::Control* AbstractWin32Component::getControl(){	return peerControl_;}void AbstractWin32Component::setControl( VCF::Control* component ){	setPeerControl( component );}void AbstractWin32Component::setParent( VCF::Control* parent ){	VCF_ASSERT(NULL != hwnd_);	Win32ToolKit* toolkit = (Win32ToolKit*)UIToolkit::internal_getDefaultUIToolkit();	HWND dummyParent = toolkit->getDummyParent();	if ( NULL == parent ) {		::ShowWindow( hwnd_, SW_HIDE );		::SetParent( hwnd_, dummyParent );	}	else {		VCF::ControlPeer* parentPeer = parent->getPeer();				if ( NULL == dynamic_cast<Frame*>(peerControl_) ){			HWND wndParent = (HWND)parentPeer->getHandleID();									if ( NULL == wndParent ){				//throw exception !!!			}						HWND currentParent = ::GetParent( hwnd_ );			::SetParent( hwnd_, wndParent );			if ( currentParent == dummyParent ) {				::ShowWindow( hwnd_, SW_NORMAL );			}				}	}}VCF::Control* AbstractWin32Component::getParent(){	return NULL;}bool AbstractWin32Component::isFocused(){	VCF_ASSERT(NULL != hwnd_);	HWND focusedHandle = ::GetFocus();	bool result = (NULL != focusedHandle) && (focusedHandle == hwnd_);	return result;}void AbstractWin32Component::setFocused(){	VCF_ASSERT(NULL != hwnd_);	::SetFocus( hwnd_ );}bool AbstractWin32Component::isEnabled(){	VCF_ASSERT(NULL != hwnd_);	return (::IsWindowEnabled( hwnd_ ) != 0);}void AbstractWin32Component::setEnabled( const bool& enabled ){	VCF_ASSERT(NULL != hwnd_);	::EnableWindow( hwnd_, enabled );}void AbstractWin32Component::setFont( Font* font ){	VCF_ASSERT(NULL != hwnd_);	if ( NULL != font ){		Win32Font* win32FontPeer = NULL;		FontPeer* fontPeer = font->getFontPeer();		win32FontPeer = dynamic_cast<Win32Font*>(fontPeer );		if ( NULL != win32FontPeer ){			HFONT fontHandle = Win32FontManager::getFontHandleFromFontPeer( win32FontPeer );			if ( NULL != fontHandle ){				::SendMessage( hwnd_, WM_SETFONT, (WPARAM)fontHandle, MAKELPARAM(TRUE, 0) );				currentFont_ = fontHandle;			}		}		else {			//what the hell is a non Win32Font doing here !!!! throw exception !!!!!		}	}}HDC AbstractWin32Component::doControlPaint( HDC paintDC, RECT paintRect, RECT* exclusionRect, int whatToPaint  ){	HDC result = NULL;	if ( !peerControl_->isDestroying() ) {				if ( NULL == memDC_ ) {			// we need a memory HDC, so we create it here one compatible 			// with the HDC of the entire screen			HDC dc = ::GetDC(0);			memDC_ = ::CreateCompatibleDC( dc );			::ReleaseDC( 0,	dc );		}											VCF::GraphicsContext* ctx = peerControl_->getContext();				Rect viewableRect(paintRect.left, paintRect.top,			paintRect.right, paintRect.bottom );		ctx->setViewableBounds( viewableRect );		Image* drawingArea = ctx->getDrawingArea();				if ( peerControl_->isUsingRenderBuffer() && 				!viewableRect.isNull() && 				!viewableRect.isEmpty() &&				(NULL != drawingArea) ) {						ctx->getPeer()->setContextID( (OSHandleID)paintDC );			((ControlGraphicsContext*)ctx)->setOwningControl( NULL );						drawingArea->getImageContext()->setViewableBounds(ctx->getViewableBounds());			if ( ctx->isRenderAreaDirty() ) {				if ( NULL != exclusionRect ) {					ExcludeClipRect( paintDC, exclusionRect->left, exclusionRect->top,								exclusionRect->right, exclusionRect->bottom );				}				GraphicsContext* paintCtx = ctx->getDrawingArea()->getImageContext();				int gcs = paintCtx->saveState();				switch( whatToPaint ) {					case cpBorderOnly : {						peerControl_->paintBorder( paintCtx );					}					break;					case cpControlOnly : {						peerControl_->internal_beforePaint( paintCtx );						peerControl_->paint( paintCtx );						peerControl_->internal_afterPaint( paintCtx );					}					break;					case cpBorderAndControl : {						peerControl_->paintBorder( paintCtx );												peerControl_->internal_beforePaint( paintCtx );						peerControl_->paint( paintCtx );						peerControl_->internal_afterPaint( paintCtx );					}					break;				}				paintCtx->restoreState( gcs );			}			ctx->flushDrawingArea();			ctx->getDrawingArea()->getImageContext()->setViewableBounds( Rect(0,0,0,0) );			((ControlGraphicsContext*)ctx)->setOwningControl( peerControl_ );						result = paintDC;		}		else if ( true == peerControl_->isDoubleBuffered() ) {			Rect dirtyRect( paintRect.left,paintRect.top,paintRect.right,paintRect.bottom);						// implements double buffering by painting everything 			//  in a memory device context first			memBMP_ = ::CreateCompatibleBitmap( paintDC,					paintRect.right - paintRect.left,					paintRect.bottom - paintRect.top );			memDCState_ = ::SaveDC( memDC_ );			originalMemBMP_ = (HBITMAP)::SelectObject( memDC_, memBMP_ );			// changes the origin of the paint coordinates, by specifying which			// point of the device context points to the origin of the window.			POINT oldOrg = {0};			::SetViewportOrgEx( memDC_, -paintRect.left, -paintRect.top, &oldOrg );						/**			* we prevents the owning control of the context to alter			* the HDC and the viewport, as this is done here using 			* the DC given by the system with the message itself.			* We temporarly use a memory context as teh current 			* HDC for the Graphics context because we are 			* doing double buffering.			*/			ctx->getPeer()->setContextID( (OSHandleID)memDC_ );			((ControlGraphicsContext*)ctx)->setOwningControl( NULL );										// save the state of Graphics control so to be fully restored after the paint.			int gcs = ctx->saveState();			switch( whatToPaint ) {				case cpBorderOnly : {					peerControl_->paintBorder( ctx );				}				break;				case cpControlOnly : {					peerControl_->internal_beforePaint( ctx );					peerControl_->paint( ctx );					peerControl_->internal_afterPaint( ctx );				}				break;				case cpBorderAndControl : {					peerControl_->paintBorder( ctx );										peerControl_->internal_beforePaint( ctx );					peerControl_->paint( ctx );					peerControl_->internal_afterPaint( ctx );				}				break;			}			ctx->restoreState( gcs );			((ControlGraphicsContext*)ctx)->setOwningControl( peerControl_ );			//reset back to original origin			::SetViewportOrgEx( memDC_, -paintRect.left, -paintRect.top, &oldOrg );						result = memDC_;				}		else {						/**			* we prevents the owning control of the context to alter			* the HDC and the viewport, as this is done here using 			* the DC given by the system with the message itself.			*/			ctx->getPeer()->setContextID( (OSHandleID)paintDC );			((ControlGraphicsContext*)ctx)->setOwningControl( NULL );			if ( NULL != exclusionRect ) {				ExcludeClipRect( paintDC, exclusionRect->left, exclusionRect->top,								exclusionRect->right, exclusionRect->bottom );			}						int gcs = ctx->saveState();			switch( whatToPaint ) {				case cpBorderOnly : {					peerControl_->paintBorder( ctx );				}				break;				case cpControlOnly : {					peerControl_->internal_beforePaint( ctx );					peerControl_->paint( ctx );					peerControl_->internal_afterPaint( ctx );				}				break;

⌨️ 快捷键说明

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