win32edit.cpp

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

CPP
1,837
字号
		//do not use the default Dialog wnd proc		//case WM_GETDLGCODE : {		//	result = DLGC_WANTALLKEYS;		//}		//break;/*		case WM_SETFOCUS: {			AbstractWin32Component::defaultWndProcedure( message, wParam, lParam );			DWORD s, e;			SendMessage( hwnd_, EM_GETSEL, (WPARAM)&s, (LPARAM)&e );			StringUtils::trace( Format("WM_SETFOCUS s: %d, e: %d \n") %									s % e );			currentSelLength_ = e - s;			currentSelStart_ = s;			editState_ |= esGotFocus;						result = true;			AbstractWin32Component::handleEventMessages( message, wParam, lParam, wndProcResult );		}		break;		case WM_CAPTURECHANGED : {			HWND hwndNewCapture = (HWND) lParam;			editState_ |= esCaptureChanged;			DWORD s2, e2;			SendMessage( hwnd_, EM_GETSEL, (WPARAM)&s2, (LPARAM)&e2 );			StringUtils::trace( Format("WM_CAPTURECHANGED s2: %d, e2: %d hwnd_: 0x%08X hwndNewCapture: 0x%08X\n") %									s2 % e2 % hwnd_ % hwndNewCapture );								 }			break;*/		default: {				result = AbstractWin32Component::handleEventMessages( message, wParam, lParam, wndProcResult );		}		break;	}	return result;}void Win32Edit::onTextModelTextChanged( TextEvent* event ){	if ( (NULL != event) && 		!(editState_ & esModelTextChanging) &&		!(editState_ & esKeyEvent) ){		switch ( event->getType() ) {			case TextModel::tmTextInserted : {				insertText( event->getChangeStart(),											event->getChangeText() );			}			break;			case TextModel::tmTextReplaced : {				String originalText = event->getOriginalText();				deleteText( event->getChangeStart(),											originalText.size() );				insertText( event->getChangeStart(),											event->getChangeText() );			}			break;			case TextModel::tmTextRemoved : {				deleteText( event->getChangeStart(),											event->getChangeLength() );			}			break;			case TextModel::tmTextSet : {				setText( textControl_->getTextModel()->getText() );			}			break;		}	}}int Win32Edit::getCRCount( const unsigned long& begin, const unsigned long& end, const bool& limitCountsAreExact ){	// Fixes a Microsoft bug:	//	EM_GETSEL doesn't count the '\r' characters: so the '\r' counts must be added to (begin,end) afterword	//	EM_SETSEL doesn't count the '\r' characters either: but the effect is the '\r' counts must be subtracted first	//																			before submitting (begin,end) with EM_SETSEL to the control	//	// Usage:	//		use _limitCountsAreExact = true  with setSelectionMark  ( after  EM_GETSEL )	//		use _limitCountsAreExact = false with getSelectionStart ( before EM_SETSEL )	//	in general:	//		use _limitCountsAreExact = true when the exact limit of the count of CRs is known, false otherwise	TextControl* tc = (TextControl*)this->getControl();	String text = tc->getTextModel()->getText();	unsigned long size = text.size();	unsigned long b = VCF::minVal<>( begin, size );	unsigned long e = VCF::minVal<>( end, size );	int foundCRTot = 0;	int foundCR = 0;	const VCFChar* p = text.c_str();	const VCFChar* start = p + b;	const VCFChar* finish = p + e;	const VCFChar* endText = p + size;	p = start;	// the first time counts the '\r' characters until 'finish'	// the following times the count is adjusted if 'finish' moves forward	while ( p < endText ) {		foundCR = 0;		// counts the '\r' characters between the current position and 'finish'		// note: it is really possible to have ( p < finish && p < endText ) while ( endText < finish )		while ( p < finish && p < endText ) {			if ( *p == '\r' ) {				foundCR++;			}			p++;		}		finish += foundCR;		foundCRTot += foundCR;		if ( limitCountsAreExact || 0 == foundCR ) {			break;		}	}	return foundCRTot;}void Win32Edit::setText( const VCF::String& text ){	editState_ |= esPeerTextChanging;	int firstLine1 = ::SendMessage( hwnd_, EM_GETFIRSTVISIBLELINE, (WPARAM)0, (LPARAM)0 );	DWORD start = getSelectionStart();	DWORD count = getSelectionCount();	ITextRange* range;	textDocument_->Range( 0, 0, &range );	if ( NULL != range ) {		long len = 0;		range->GetStoryLength( &len );		range->SetEnd( len );		BSTR str = SysAllocStringLen( text.c_str(), text.length() );		range->SetText( str );		SysFreeString( str );		range->Release();	}	setSelectionMark( start, count );	int firstLine2 = ::SendMessage( hwnd_, EM_GETFIRSTVISIBLELINE, (WPARAM)0, (LPARAM)0 );	if ( firstLine2 != firstLine1 ) {		// workaround necessary only while insertText is implemented with setText - MP		// if we could know the number of lines visible in the editor, we would be able		// to save these two calls.		// setText() empties the editor first, then puts back the text plus the added text,		// but in this way it looses the scrolling position information.		// At that point setSelectionMark() will make the selection visible, but at the end		// of the page.		::SendMessage( hwnd_, EM_LINESCROLL, (WPARAM)0, (LPARAM)(-(firstLine2-firstLine1)) );		// this will not move the the scrollbar if the selection is already visible		setSelectionMark( start, count );	}	editState_ &= ~esPeerTextChanging;}unsigned long Win32Edit::getSelectionStart(){	unsigned long start = 0;	unsigned long end = -1;	getSelectionMark( start, end );	return ( start );}unsigned long Win32Edit::getSelectionCount(){	unsigned long start = 0;	unsigned long end = 0;	getSelectionMark( start, end );	return ( end - start );}void Win32Edit::getSelectionMark( unsigned long & start, unsigned long & end ){	ITextSelection* selection = NULL;	textDocument_->GetSelection( &selection );	if ( NULL != selection ) {		selection->GetStart( (long*)&start );		selection->GetEnd( (long*)&end );		selection->Release();	}}void Win32Edit::clearSelection(){}void Win32Edit::setSelectionMark( const unsigned long& start, const unsigned long& count ){	unsigned long end = start + count;		::SendMessage( hwnd_, EM_SETSEL, (WPARAM)start, (LPARAM)end );	}void Win32Edit::scrollToLine( const ulong32& lineIndex ){	::SendMessage( hwnd_, EM_LINESCROLL, 0, lineIndex );}void Win32Edit::scrollToSelection( const bool& _showEndSel/*=false*/ ){	if ( _showEndSel ) {		// not implemented yet	}	::SendMessage( hwnd_, EM_SCROLLCARET, (WPARAM)0, (LPARAM)0 );}void Win32Edit::repaint( Rect* repaintRect ){	if ( NULL == repaintRect ){		RECT bounds = {0,0,0,0};		GetWindowRect( hwnd_, &bounds );		RECT tmp = {0,0,abs(bounds.right-bounds.left), abs(bounds.bottom - bounds.top)};		::InvalidateRect( hwnd_, &tmp, TRUE );	}	else {		RECT rect = {0,0,0,0};		rect.left = (long)repaintRect->left_;		rect.top = (long)repaintRect->top_;		rect.right = (long)repaintRect->right_;		rect.bottom = (long)repaintRect->bottom_;		::InvalidateRect( hwnd_, &rect, TRUE );	}}void Win32Edit::setReadOnly( const bool& readonly ){	//SendMessage( hwnd_, EM_SETREADONLY, readonly ? TRUE : FALSE, 0 );	if ( NULL != richEditCallback_ ) {		SendMessage( hwnd_, EM_SETOLECALLBACK, 0, (LPARAM)0 );		delete richEditCallback_;			}	if ( readonly ) {		richEditCallback_ = new Win32RichEditOleCallback();		SendMessage( hwnd_, EM_SETOLECALLBACK, 0, (LPARAM)richEditCallback_ );	}}ulong32 Win32Edit::getTotalPrintablePageCount( PrintContext* context ){	printPageMap_.clear();	ulong32 result = 1;	FORMATRANGE formatRange = {0};	//print everything	formatRange.chrg.cpMax = -1;	formatRange.chrg.cpMin = 0;	formatRange.hdc = (HDC)context->getPeer()->getContextID();	formatRange.hdcTarget = formatRange.hdc;	Rect printRect = context->getViewableBounds();	double dpi = GraphicsToolkit::getDPI(context);	printRect.left_ = (printRect.left_ / dpi) * 1400.0;	printRect.top_ = (printRect.top_ / dpi) * 1400.0;	printRect.bottom_ = (printRect.bottom_ / dpi) * 1400.0;	printRect.right_ = (printRect.right_ / dpi) * 1400.0;	formatRange.rcPage.left = printRect.left_;	formatRange.rcPage.top = printRect.top_;	formatRange.rcPage.right = printRect.right_;	formatRange.rcPage.bottom = printRect.bottom_;	formatRange.rc.left = printRect.left_;	formatRange.rc.top = printRect.top_;	formatRange.rc.right = printRect.right_;	formatRange.rc.bottom = printRect.bottom_;	HDC dc = GetDC( hwnd_ );	double ctrlDPI = (double)GetDeviceCaps( dc, LOGPIXELSY);	ReleaseDC( hwnd_, dc );	DWORD margins = ::SendMessage( hwnd_, EM_GETMARGINS, 0, 0 );	double lm = ((double)LOWORD(margins)/ctrlDPI) * 1400;	double rm = ((double)HIWORD(margins)/ctrlDPI) * 1400;	formatRange.rc.left += lm;	formatRange.rc.right -= lm;	formatRange.rc.top += 350; //add a 1/4"	formatRange.rc.bottom -= 350; //add a 1/4"	TextControl* tc = (TextControl*)this->getControl();	String text = tc->getTextModel()->getText();	ulong32 textSize = text.size();	SendMessage( hwnd_, EM_FORMATRANGE, 0, 0 );	printPageMap_[result] = (ulong32)-1;	DWORD index = SendMessage( hwnd_, EM_FORMATRANGE, 0, (LPARAM)&formatRange );	while ( (index <= textSize) && (formatRange.chrg.cpMin != index) ) {		printPageMap_[result] = index;		formatRange.chrg.cpMin = index;		index = SendMessage( hwnd_, EM_FORMATRANGE, 0, (LPARAM)&formatRange );		result ++;	}	SendMessage( hwnd_, EM_FORMATRANGE, 0, 0 );	return result;}void Win32Edit::print( PrintContext* context, const long& page ){	VCF_ASSERT( !printPageMap_.empty() );	if ( printPageMap_.empty() ) {		return;	}	std::map<ulong32,ulong32>::iterator found = printPageMap_.find( page );	if ( found == printPageMap_.end() ) {		//clear out of dodge! We are done printing		printPageMap_.clear();		return;	}	else {		FORMATRANGE formatRange = {0};		//print everything		formatRange.chrg.cpMax = found->second;		if ( 0 == (page-1) ) {			formatRange.chrg.cpMin = 0;		}		else {			formatRange.chrg.cpMin = printPageMap_[page-1];		}		formatRange.hdc = (HDC)context->getPeer()->getContextID();		formatRange.hdcTarget = formatRange.hdc;		Rect printRect = context->getViewableBounds();		double dpi = GraphicsToolkit::getDPI(context);		printRect.left_ = (printRect.left_ / dpi) * 1400.0;		printRect.top_ = (printRect.top_ / dpi) * 1400.0;		printRect.bottom_ = (printRect.bottom_ / dpi) * 1400.0;		printRect.right_ = (printRect.right_ / dpi) * 1400.0;		formatRange.rcPage.left = printRect.left_;		formatRange.rcPage.top = printRect.top_;		formatRange.rcPage.right = printRect.right_;		formatRange.rcPage.bottom = printRect.bottom_;		formatRange.rc.left = printRect.left_;		formatRange.rc.top = printRect.top_;		formatRange.rc.right = printRect.right_;		formatRange.rc.bottom = printRect.bottom_;		HDC dc = GetDC( hwnd_ );		double ctrlDPI = (double)GetDeviceCaps( dc, LOGPIXELSY);		ReleaseDC( hwnd_, dc );		DWORD margins = ::SendMessage( hwnd_, EM_GETMARGINS, 0, 0 );		double lm = ((double)LOWORD(margins)/ctrlDPI) * 1400;		double rm = ((double)HIWORD(margins)/ctrlDPI) * 1400;		formatRange.rc.left += lm;		formatRange.rc.right -= lm;		formatRange.rc.top += 350; //add a 1/4"		formatRange.rc.bottom -= 350; //add a 1/4"		SendMessage( hwnd_, EM_FORMATRANGE, TRUE, (LPARAM)&formatRange );	}}void Win32Edit::finishPrinting(){	SendMessage( hwnd_, EM_FORMATRANGE, 0, 0 );}void Win32Edit::onControlModelChanged( Event* e ){	EventHandler* tml = getEventHandler( "Win32TextModelHandler" );	if ( NULL == tml ) {		tml = new TextModelEventHandler<Win32Edit>( this, &Win32Edit::onTextModelTextChanged, "Win32TextModelHandler" );	}	TextModel* tm = textControl_->getTextModel();	tm->addTextModelChangedHandler( tml );	String text = tm->getText();	setText( text );}void Win32Edit::cut(){	if ( !textControl_->getReadOnly() ) {		SendMessage( hwnd_, WM_CUT, 0, 0 );	}}void Win32Edit::copy(){	SendMessage( hwnd_, WM_COPY, 0, 0 );}void Win32Edit::paste(){

⌨️ 快捷键说明

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