win32scrollpeer.cpp

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

CPP
643
字号
//Win32ScrollPeer.cpp/*Copyright 2000-2004 The VCF Project.Please see License.txt in the top level directorywhere you installed the VCF.*///Win32ScrollPeer.h#include "vcf/ApplicationKit/ApplicationKit.h"#include "vcf/ApplicationKit/ApplicationKitPrivate.h"#include "vcf/ApplicationKit/Win32ScrollPeer.h"using namespace VCF;std::map<HWND,Control*> Win32ScrollPeer::hScrollBarMap;class Win32ScrollCorner : public CustomControl {public:	Win32ScrollCorner() {	}	virtual ~Win32ScrollCorner(){};};Win32ScrollPeer::Win32ScrollPeer( Control* scrollableControl ){	this->scrollableControl_ = scrollableControl;	vScrollHWnd_ = NULL;	hScrollHWnd_ = NULL;	scrollCorner_ = NULL;	isVertSBVisible_ = false;	isHorzSBVisible_ = false;}Win32ScrollPeer::~Win32ScrollPeer(){	if ( NULL != scrollCorner_ ) {		scrollCorner_->free();	}}void Win32ScrollPeer::removeScrollBarsFromMap(){	std::map<HWND,Control*>::iterator found = Win32ScrollPeer::hScrollBarMap.find( vScrollHWnd_ );	if ( found != Win32ScrollPeer::hScrollBarMap.end() ) {		Win32ScrollPeer::hScrollBarMap.erase( found );	}	found = Win32ScrollPeer::hScrollBarMap.find( hScrollHWnd_ );	if ( found != Win32ScrollPeer::hScrollBarMap.end() ) {		Win32ScrollPeer::hScrollBarMap.erase( found );	}}void Win32ScrollPeer::addScrollBarsToMap(){	Win32ScrollPeer::hScrollBarMap[vScrollHWnd_] = scrollableControl_;	Win32ScrollPeer::hScrollBarMap[hScrollHWnd_] = scrollableControl_;}Control* Win32ScrollPeer::getScrollableControlFromHWnd( HWND scrollhWnd ){	Control* result = NULL;	std::map<HWND,Control*>::iterator found = Win32ScrollPeer::hScrollBarMap.find( scrollhWnd );	if ( found != Win32ScrollPeer::hScrollBarMap.end() ) {		result = found->second;	}	return result;}void Win32ScrollPeer::setScrollableControl( Control* scrollableControl ){	if ( NULL != scrollableControl_ )	{		removeScrollBarsFromMap();		BOOL err = DestroyWindow( vScrollHWnd_ );		err = DestroyWindow( hScrollHWnd_ );		vScrollHWnd_ = NULL;		hScrollHWnd_ = NULL;		scrollCorner_->free();	}	this->scrollableControl_ = scrollableControl;	if ( NULL != scrollableControl_ ) {		HWND hwnd = (HWND)scrollableControl_->getPeer()->getHandleID();		Application* app = Application::getRunningInstance();		HINSTANCE hInst = NULL;		if ( NULL != app ) {			hInst = (HINSTANCE)app->getPeer()->getHandleID();		}		else {			hInst = ::GetModuleHandle(NULL);		}		if ( System::isUnicodeEnabled() ) {			vScrollHWnd_ = CreateWindowExW( 0, L"SCROLLBAR", NULL, WS_CHILD | SBS_VERT | WS_VISIBLE, 0, 0, 200,			CW_USEDEFAULT, hwnd, NULL, hInst, NULL );			hScrollHWnd_ = CreateWindowExW( 0, L"SCROLLBAR", NULL, WS_CHILD | SBS_HORZ | WS_VISIBLE, 0, 0, 200,				CW_USEDEFAULT, hwnd, NULL, hInst, NULL );		}		else {			vScrollHWnd_ = CreateWindowExA( 0, "SCROLLBAR", NULL, WS_CHILD | SBS_VERT | WS_VISIBLE, 0, 0, 200,				CW_USEDEFAULT, hwnd, NULL, hInst, NULL );			hScrollHWnd_ = CreateWindowExA( 0, "SCROLLBAR", NULL, WS_CHILD | SBS_HORZ | WS_VISIBLE, 0, 0, 200,				CW_USEDEFAULT, hwnd, NULL, hInst, NULL );		}		scrollCorner_ = new Win32ScrollCorner();		HWND scHwnd = (HWND)scrollCorner_->getPeer()->getHandleID();		SetParent( scHwnd, hwnd );		addScrollBarsToMap();	}}void Win32ScrollPeer::scrollTo( const double& xPosition, const double& yPosition ){	SCROLLINFO si = {0};	Scrollable* scrollable = scrollableControl_->getScrollable();	if ( NULL != scrollable ) {		double h = scrollableControl_->getHeight();		bool hasVertSB = (scrollable->hasVerticalScrollBar()) && (::IsWindowEnabled(vScrollHWnd_));		bool hasHorzSB = (scrollable->hasHorizontalScrollBar()) && (::IsWindowEnabled(hScrollHWnd_));		int x, origX;		x = origX = 0;		int y, origY;		y = origY = 0;		if ( true == hasVertSB ) {			origY = y = GetScrollPos( vScrollHWnd_, SB_CTL );			y = (int)yPosition;			si.cbSize = sizeof(SCROLLINFO);			si.fMask = SIF_POS;			si.nPos = (long)yPosition;			SetScrollInfo( vScrollHWnd_, SB_CTL, &si, TRUE );		}		if ( true == hasHorzSB ) {			origX = x = GetScrollPos( hScrollHWnd_, SB_CTL );			x = (int)xPosition;			memset( &si, 0, sizeof(si) );			si.cbSize = sizeof(SCROLLINFO);			si.fMask = SIF_POS ;			si.nPos = (long)xPosition;			SetScrollInfo( hScrollHWnd_, SB_CTL, &si, TRUE );		}		if ( hasHorzSB || hasVertSB ) {			Container* container = scrollableControl_->getContainer();			if ( NULL != container ) {				Enumerator<Control*>* children = container->getChildren();				while ( children->hasMoreElements() ) {					Control* child = children->nextElement();					if ( !child->ignoreForParentScrolling() ) {						Rect r = child->getBounds();						r.offset( -(x-origX), -(y-origY) );						child->setBounds( &r );					}				}			}		}	}}bool Win32ScrollPeer::isVerticalScrollbarVisible() {	return isVertSBVisible_;}bool Win32ScrollPeer::isHorizontalScrollbarVisible() {	return isHorzSBVisible_;}void Win32ScrollPeer::recalcScrollPositions( Scrollable* scrollable ){	/**	*if the scrollableControl_ is lightweight then the handle represents the parent's	*hwnd, so get the control's bounds, instead of using 0,0 for left,top	*/	Rect bounds(0,0,0,0);	if ( true == scrollableControl_->isLightWeight() ) {		bounds = (scrollableControl_->getBounds());	}	else {		bounds = scrollableControl_->getClientBounds( );		//bounds.inflate( -1, -1 );	}	bool hasVertSB = scrollable->hasVerticalScrollBar();	bool hasHorzSB = scrollable->hasHorizontalScrollBar();	bool keepVertSB = scrollable->getKeepVertScrollbarVisible();	bool keepHorzSB = scrollable->getKeepHorzScrollbarVisible();	// initially set showVertSB and showHorzSB false, then check.	bool showVertSB = false;	bool showHorzSB = false;		// if hasSB and keepSB then we show them anyway	if ( hasVertSB ) {		showVertSB = keepVertSB;	}	if ( hasHorzSB ) {		showHorzSB = keepHorzSB;	}	/* 	*now we determine if the scrollbars are actually needed, no matter if we want	*to keep them visible or not, so we can enable them later if needed.	*initially set needVertSB and needHorzSB false, then check.	*/	bool needVertSB = false;		bool needHorzSB = false;	double virtViewWidth  = scrollable->getVirtualViewWidth();	double virtViewHeight = scrollable->getVirtualViewHeight();	double vertSBWidth = getVerticalScrollbarWidth();	double horzSBWidth = getHorizontalScrollbarHeight();	// determine whether or not scrollbars are needed	if ( hasHorzSB && ( virtViewWidth  > bounds.getWidth() ) ) {		needHorzSB = true;		showHorzSB = true;	}	if ( hasVertSB && ( virtViewHeight > bounds.getHeight() ) ) {		needVertSB = true;		showVertSB = true;	}	// determine having made one of the scrollbars visible requires the other to be visible also	if ( hasHorzSB && !needHorzSB && showVertSB && ( (bounds.getWidth() - vertSBWidth ) < virtViewWidth ) ) {		needHorzSB = true;	}	if ( hasVertSB && !needVertSB && showHorzSB && ( (bounds.getHeight() - horzSBWidth ) < virtViewHeight ) ) {		needVertSB = true;	}	// if needed we show them	if ( needVertSB ) {		showVertSB = true;	}	if ( needHorzSB ) {		showHorzSB = true;	}		// set isVertSBVisible_ and isHorzSBVisible_	isVertSBVisible_ = showVertSB;	isHorzSBVisible_ = showHorzSB;	SCROLLINFO scrollInfoVert = {0};	scrollInfoVert.cbSize = sizeof(SCROLLINFO);	scrollInfoVert.fMask = SIF_PAGE | SIF_POS | SIF_RANGE | SIF_DISABLENOSCROLL;	scrollInfoVert.nPage = (long)( needVertSB ? bounds.getHeight() : 0);		scrollInfoVert.nPos =  (long)scrollable->getVerticalPosition();	scrollInfoVert.nMin = 0;	scrollInfoVert.nMax = (long) ( showVertSB  ? virtViewHeight : scrollInfoVert.nMin );		if ( showHorzSB && (scrollInfoVert.nMax > 0)) {		scrollInfoVert.nMax += (long)( horzSBWidth + 1 ); 	}	SCROLLINFO scrollInfoHorz = {0};	scrollInfoHorz.cbSize = sizeof(SCROLLINFO);	scrollInfoHorz.fMask = SIF_PAGE | SIF_POS | SIF_RANGE | SIF_DISABLENOSCROLL;	scrollInfoHorz.nPage = (long)( needHorzSB ? bounds.getWidth() : 0 );	scrollInfoHorz.nPos =  (long)scrollable->getHorizontalPosition();	scrollInfoHorz.nMin = 0;	scrollInfoHorz.nMax = (long)( showHorzSB ? virtViewWidth : scrollInfoHorz.nMin );	if ( showVertSB && (scrollInfoHorz.nMax > 0) ) {		scrollInfoHorz.nMax += (long)( vertSBWidth + 1 );	}		// dimensions of the vertical scrollbar	int x1 = (long)( bounds.left_ + ( bounds.getWidth() - vertSBWidth ) );	int y1 = (long)( bounds.top_ + scrollable->getVerticalTopScrollSpace() );	int w1 = vertSBWidth;	int h1 = (long)( bounds.getHeight() - ( scrollable->getVerticalTopScrollSpace() + scrollable->getVerticalBottomScrollSpace() ) );	// dimensions of the horizontal scrollbar	int x2 = (long)( bounds.left_ + scrollable->getHorizontalLeftScrollSpace() );	int y2 = (long)( bounds.top_ + ( bounds.getHeight() - horzSBWidth ) );	int w2 = (long)( bounds.getWidth() - ( scrollable->getHorizontalLeftScrollSpace() + scrollable->getHorizontalRightScrollSpace() ) );	int h2 = horzSBWidth;	if ( showHorzSB && showVertSB ) {		// one scrollbar takes space from the other		h1 -= horzSBWidth;		w2 -= vertSBWidth;	}	if ( showVertSB ) {		::ShowWindow( vScrollHWnd_, SW_NORMAL );		MoveWindow( vScrollHWnd_, x1, y1, w1, h1, TRUE );		::InvalidateRect( vScrollHWnd_, NULL, TRUE );		UpdateWindow( vScrollHWnd_ );		if ( !needVertSB ) {			::EnableWindow( vScrollHWnd_, FALSE );			scrollInfoVert.nPage = 0;

⌨️ 快捷键说明

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