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 + -
显示快捷键?