win32tree.cpp

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

CPP
1,700
字号
//Win32Tree.cpp/*Copyright 2000-2004 The VCF Project.Please see License.txt in the top level directorywhere you installed the VCF.*/#ifdef __GNUWIN32__#define _WIN32_IE   0x0400  //this may be a bogus thing to do !#endif//__GNUWIN32__#include "vcf/ApplicationKit/ApplicationKit.h"#include "vcf/ApplicationKit/ApplicationKitPrivate.h"#include "vcf/ApplicationKit/Win32Tree.h"#include "vcf/ApplicationKit/TreeControl.h"#include "vcf/ApplicationKit/DefaultTreeItem.h"/**this is redifined here because the mingw version is WRONG! (or the MS iversion iswrong, depends on how you look at it :) ).*/#if (_WIN32_IE >= 0x0400)typedef struct tagNMCUSTOMDRAWINFO__ {    NMHDR  hdr;    DWORD  dwDrawStage;    HDC    hdc;    RECT   rc;    DWORD  dwItemSpec;    UINT   uItemState;    LPARAM lItemlParam;} NMCUSTOMDRAW__, FAR * LPNMCUSTOMDRAW__;#endiftypedef struct tagNMTVCUSTOMDRAW__ {    NMCUSTOMDRAW__ nmcd;    COLORREF clrText;    COLORREF clrTextBk;#if (_WIN32_IE >= 0x0400)    int iLevel;#endif} NMTVCUSTOMDRAW__, *LPNMTVCUSTOMDRAW__;#ifdef __GNUWIN32__#if (_WIN32_IE >= 0x0300)#define LPTV_HITTESTINFO   LPTVHITTESTINFO#define   TV_HITTESTINFO     TVHITTESTINFO#else#define tagTVHITTESTINFO    _TV_HITTESTINFO#define    TVHITTESTINFO     TV_HITTESTINFO#define  LPTVHITTESTINFO   LPTV_HITTESTINFO#endiftypedef struct tagTVHITTESTINFO {    POINT       pt;    UINT        flags;    HTREEITEM   hItem;} TVHITTESTINFO, FAR *LPTVHITTESTINFO;#if (_WIN32_IE >= 0x0400)#define TVN_GETINFOTIPA         (TVN_FIRST-13)#define TVN_GETINFOTIPW         (TVN_FIRST-14)#define TVN_SINGLEEXPAND        (TVN_FIRST-15)#endif // 0x400#if (_WIN32_IE >= 0x0400)// for tooltipstypedef struct tagNMTVGETINFOTIPA{    NMHDR hdr;    LPSTR pszText;    int cchTextMax;    HTREEITEM hItem;    LPARAM lParam;} NMTVGETINFOTIPA, *LPNMTVGETINFOTIPA;typedef struct tagNMTVGETINFOTIPW{    NMHDR hdr;    LPWSTR pszText;    int cchTextMax;    HTREEITEM hItem;    LPARAM lParam;} NMTVGETINFOTIPW, *LPNMTVGETINFOTIPW;#ifdef UNICODE	#define TVN_GETINFOTIP          TVN_GETINFOTIPW	#define NMTVGETINFOTIP          NMTVGETINFOTIPW	#define LPNMTVGETINFOTIP        LPNMTVGETINFOTIPW#else	#define TVN_GETINFOTIP          TVN_GETINFOTIPA	#define NMTVGETINFOTIP          NMTVGETINFOTIPA	#define LPNMTVGETINFOTIP        LPNMTVGETINFOTIPA#endif#endif //_WIN32_IE#endif //__GNUWIN32__using namespace VCFWin32;using namespace VCF;Win32Tree::Win32Tree( TreeControl* tree ):	AbstractWin32Component( tree ),	treeControl_( tree ),	imageListCtrl_(NULL),	stateImageListCtrl_(NULL),	internalTreeItemExpanded_(false){}Win32Tree::~Win32Tree(){	if ( NULL != imageListCtrl_ ) {		BOOL err = ImageList_Destroy( imageListCtrl_ );	}	if ( NULL != stateImageListCtrl_ ) {		BOOL err = ImageList_Destroy( stateImageListCtrl_ );	}}void Win32Tree::create( Control* owningControl ){	init();	CreateParams params = createParams();	backColor_ = *treeControl_->getColor();	Win32ToolKit* toolkit = (Win32ToolKit*)UIToolkit::internal_getDefaultUIToolkit();	HWND parent = toolkit->getDummyParent();	String className = getClassName();	if ( System::isUnicodeEnabled() ) {		hwnd_ = ::CreateWindowExW( params.second,										 WC_TREEVIEWW,										 NULL,										 params.first,										 0,										 0,										 1,										 1,										 parent,										 NULL,										 ::GetModuleHandleW(NULL),										 NULL );	}	else {		hwnd_ = ::CreateWindowExA( params.second,										 WC_TREEVIEWA,										 NULL,										 params.first,										 0,										 0,										 1,										 1,										 parent,										 NULL,										 ::GetModuleHandleA(NULL),										 NULL );	}	if ( NULL != hwnd_ ){		treeControl_ = (TreeControl*)owningControl;		peerControl_ = owningControl;		Win32Object::registerWin32Object( this );		subclassWindow();				registerForFontChanges();		peerControl_->ControlModelChanged +=			new GenericEventHandler<Win32Tree>( this, &Win32Tree::onControlModelChanged, "Win32Tree::onControlModelChanged" );		COLORREF backColor = backColor_.getColorRef32();		TreeView_SetBkColor( hwnd_, backColor );	}	else {		//throw exception	}	setCreated( true );}void Win32Tree::init(){	itemAddedHandler_ =		new ItemEventHandler<Win32Tree>( this, &Win32Tree::onItemAdded, "Win32Tree::onItemAdded" );	itemDeletedHandler_ =		new ItemEventHandler<Win32Tree>( this, &Win32Tree::onItemDeleted, "Win32Tree::onItemDeleted" );	itemChangedHandler_ =		new ItemEventHandler<Win32Tree>( this, &Win32Tree::onItemChanged, "Win32Tree::onItemChanged" );	itemSelectedHandler_ =		new ItemEventHandler<Win32Tree>( this, &Win32Tree::onItemSelected, "Win32Tree::onItemSelected" );	itemPaintedHandler_ =		new ItemEventHandler<Win32Tree>( this, &Win32Tree::onItemPaint, "Win32Tree::onItemPaint" );}Win32Object::CreateParams Win32Tree::createParams(){	Win32Object::CreateParams result;	result.first = BORDERED_VIEW | TVS_HASBUTTONS | TVS_HASLINES | TVS_LINESATROOT | /*TVS_NOTOOLTIPS | */ TVS_SHOWSELALWAYS;	result.first &= ~WS_BORDER;	result.first &= ~WS_VISIBLE;	result.first |= WS_HSCROLL | WS_VSCROLL;	result.first |= TVS_DISABLEDRAGDROP;	result.second = 0;	return result;}TreeModel* Win32Tree::getTreeModel(){	return NULL;}void Win32Tree::setTreeModel( TreeModel* model ){}double Win32Tree::getItemIndent(){	return TreeView_GetIndent( hwnd_ );}void Win32Tree::setItemIndent( const double& indent ){	BOOL err = TreeView_SetIndent( hwnd_, (int)indent );}ImageList* Win32Tree::getImageList(){	return NULL;}void Win32Tree::setImageList( ImageList* imageList ){	if ( NULL != imageListCtrl_ ) {		BOOL err = ImageList_Destroy( imageListCtrl_ );	}	imageListCtrl_ = NULL;	TreeView_SetImageList( hwnd_, imageListCtrl_, TVSIL_NORMAL );	if ( imageList != NULL ) {		imageListCtrl_ = ImageList_Create( imageList->getImageWidth(), imageList->getImageHeight(),										ILC_COLOR24|ILC_MASK, imageList->getImageCount(), 4 );		Image* masterImage = imageList->getMasterImage();		Win32Image* win32Img = (Win32Image*)masterImage;		/*		JC added this cause it appears that for 32bit images the alpa val		matters! If it's not set back to 0 then the transparency affect doesn't		work? Bizarre		*/		SysPixelType* pix = win32Img->getImageBits()->pixels_;		int sz = win32Img->getWidth() * win32Img->getHeight();		unsigned char* oldAlpaVals = new unsigned char[sz];		do {			sz --;			oldAlpaVals[sz] = pix[sz].a;			pix[sz].a = 0;		} while( sz > 0 );		HBITMAP hbmImage = win32Img->getBitmap();		COLORREF transparentColor = RGB(0,0,0);		if ( masterImage->isTransparent() ) {			Color* c = masterImage->getTransparencyColor();			transparentColor = RGB( c->getRed() * 255, c->getGreen() * 255, c->getBlue() * 255 );		}		else {			transparentColor = ::GetPixel( win32Img->getDC(), 0, 0 );		}		//JEC 11/05/2002 currently on NT4 this call seems to fail, returning the same		//HBITMAP value as hbmImage. This is running on NT4 in VMWare perhaps this is		//some weird bug within VMWare? Need to test this on a "real" NT4 install		HBITMAP hBMPcopy = (HBITMAP)CopyImage( hbmImage, IMAGE_BITMAP,												0,												0,												NULL );		int err = ImageList_AddMasked( imageListCtrl_, hBMPcopy, transparentColor );		if ( err < 0 ) {			//error condition !		}		DeleteObject( hBMPcopy );		sz = win32Img->getWidth() * win32Img->getHeight();		do {			sz --;			pix[sz].a = oldAlpaVals[sz];		} while( sz > 0 );		delete [] oldAlpaVals;		TreeView_SetImageList( hwnd_, imageListCtrl_, TVSIL_NORMAL );		EventHandler* imgListHandler = getEventHandler( "Win32Tree::onImageListImageChanged" );		if ( NULL == imgListHandler ) {			imgListHandler =				new ImageListEventHandler<Win32Tree>(this, &Win32Tree::onImageListImageChanged, "Win32Tree::onImageListImageChanged" );		}		imageList->SizeChanged.addHandler( imgListHandler );		imageList->ImageAdded.addHandler( imgListHandler );		imageList->ImageDeleted.addHandler( imgListHandler );	}}bool Win32Tree::handleEventMessages( UINT message, WPARAM wParam, LPARAM lParam, LRESULT& wndProcResult, WNDPROC defaultWndProc ){	bool result = 0;	wndProcResult = 0;	switch ( message ) {		case WM_PAINT:{			PAINTSTRUCT ps;			HDC dc = BeginPaint( hwnd_, &ps );			RECT paintRect;			GetClientRect( hwnd_, &paintRect );			if ( NULL == memDC_ ) {				//create here				HDC tmpDC = ::GetDC(0);				memDC_ = ::CreateCompatibleDC( tmpDC );				::ReleaseDC( 0,	tmpDC );			}			VCF::GraphicsContext* ctx = peerControl_->getContext();			ctx->setViewableBounds( Rect(paintRect.left, paintRect.top,									paintRect.right, paintRect.bottom ) );			memBMP_ = ::CreateCompatibleBitmap( dc,					paintRect.right - paintRect.left,					paintRect.bottom - paintRect.top );			memDCState_ = ::SaveDC( memDC_ );			originalMemBMP_ = (HBITMAP)::SelectObject( memDC_, memBMP_ );			POINT oldOrg = {0};			::SetViewportOrgEx( memDC_, -paintRect.left, -paintRect.top, &oldOrg );			Color* color = peerControl_->getColor();			COLORREF backColor = color->getColorRef32();			HBRUSH bkBrush = CreateSolidBrush( backColor );			FillRect( memDC_, &paintRect, bkBrush );			DeleteObject( bkBrush );			ctx->getPeer()->setContextID( (OSHandleID)memDC_ );			((ControlGraphicsContext*)ctx)->setOwningControl( NULL );			int gcs = ctx->saveState();			//paint the control here - double buffered						peerControl_->internal_beforePaint( ctx );			peerControl_->paint( ctx );			peerControl_->internal_afterPaint( ctx );			ctx->restoreState( gcs );			//reset back to original origin			::SetViewportOrgEx( memDC_, -paintRect.left, -paintRect.top, &oldOrg );			//let the tree control's DefWndProc do windwos painting			defaultWndProcedure( WM_PAINT, (WPARAM)memDC_, 0 );			//NOW reset the owning control of teh graphics context here			((ControlGraphicsContext*)ctx)->setOwningControl( peerControl_ );			::BitBlt( dc, paintRect.left, paintRect.top,					  paintRect.right - paintRect.left,					  paintRect.bottom - paintRect.top,					  memDC_, paintRect.left, paintRect.top, SRCCOPY );			::RestoreDC ( memDC_, memDCState_ );			::DeleteObject( memBMP_ );			memBMP_ = NULL;			originalMemBMP_ = NULL;			memDCState_ = 0;			EndPaint( hwnd_, &ps );			wndProcResult = 1;			result = true;		}		break;		case WM_NCCALCSIZE: {			wndProcResult = handleNCCalcSize( wParam, lParam );			result = true;		}		break;		case WM_NCPAINT: {			wndProcResult = handleNCPaint( wParam, lParam );			result = true;		}		break;		case WM_ERASEBKGND :{			Color* color = treeControl_->getColor();			if ( backColor_ != *color ) {				COLORREF backColor = color->getColorRef32();				TreeView_SetBkColor( hwnd_, backColor );				backColor_ = *color;			}			wndProcResult = 0;			result = true;		}		break;		case WM_LBUTTONDOWN : {			result = AbstractWin32Component::handleEventMessages( message, wParam, lParam, wndProcResult );			TVHITTESTINFO hitTestInfo;			memset( &hitTestInfo, 0, sizeof(TVHITTESTINFO) );			hitTestInfo.pt.x = Win32UIUtils::getXFromLParam( lParam );			hitTestInfo.pt.y = Win32UIUtils::getYFromLParam( lParam );			HTREEITEM hItem = TreeView_HitTest( hwnd_, &hitTestInfo );			if ( NULL != hItem ) {				if( hitTestInfo.flags & TVHT_ONITEMSTATEICON ) {					TVITEM tvItem;					memset( &tvItem, 0, sizeof(TVITEM) );					tvItem.mask = TVIF_PARAM | TVIF_HANDLE ;					tvItem.hItem = hItem;					if ( TreeView_GetItem( hwnd_, &tvItem ) ) {						TreeItem* item = (TreeItem*)tvItem.lParam;						ItemEvent event( item, TreeControl::ITEM_STATECHANGE_REQUESTED );						treeControl_->handleEvent( &event );					}				}			}		}		break;		case WM_CREATE:{			result = AbstractWin32Component::handleEventMessages( message, wParam, lParam, wndProcResult );		}		break;		case WM_LBUTTONDBLCLK: case WM_MBUTTONDBLCLK: case WM_RBUTTONDBLCLK:{			Win32MSG msg( hwnd_, message, wParam, lParam, peerControl_ );			Event* event = UIToolkit::createEventFromNativeOSEventData( &msg );			if ( NULL != event && (peerControl_->getComponentState() != Component::csDestroying) ) {				peerControl_->handleEvent( event );				event->free();			}			//DO NOT, REPEAT: DO NOT allow the DefaultWndProc to get called!			wndProcResult = 1;			result = true;		}		break;		case TVN_BEGINDRAGW:{			NMTREEVIEWW* treeview = (NMTREEVIEWW*)lParam ;			TreeItem* item = (TreeItem*)treeview->itemNew.lParam;			if ( NULL != item ) {				Point pt( treeview->ptDrag.x, treeview->ptDrag.y );				TreeItem* oldItem = treeControl_->getSelectedItem();				if ( item != oldItem ) {					//hmm, we haven't selected this item before, so					//let's go ahead and make it selected now					//we do this because the TVN_SELECTIONCHANGED					//won't get called at this point					item->setSelected( true );					ItemEvent event( treeControl_, TREEITEM_SELECTED );					event.setUserData( (void*)item );					event.setPoint( &pt );					treeControl_->handleEvent( &event );					if ( NULL != oldItem ) {						oldItem->setSelected( false );					}				}				SHORT keyState = GetKeyState( VK_SHIFT );				ulong32 keyMask = kmUndefined;

⌨️ 快捷键说明

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