win32edit.cpp

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

CPP
1,837
字号
//Win32Edit.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/ApplicationKitPrivate.h"#include "vcf/ApplicationKit/Win32Edit.h"#include "vcf/ApplicationKit/TextControl.h"#include "vcf/FoundationKit/Dictionary.h"#if defined(VCF_MINGW)  /* mingw misses some richedit defines */#include "imm.h"#define RICHEDIT_CLASSA		"RichEdit20A"#define RICHEDIT_CLASSW		L"RichEdit20W"#endif#include <richedit.h>#include "thirdparty/win32/Microsoft/TOM.h"#include "thirdparty/win32/Microsoft/textserv.h"#include <Richole.h>using namespace VCFWin32;using namespace VCF;namespace VCF {class Win32RichEditOleCallback : public  IRichEditOleCallback {public:	STDMETHODIMP QueryInterface( REFIID iid, void ** ppvObject ) {		String uuidStr;				if ( iid == IID_IRichEditOleCallback ) {			*ppvObject = (void*) (IRichEditOleCallback*)this;		}		else if ( iid == IID_IUnknown ) {			*ppvObject = (void*) (IUnknown*)this;		}		else {			*ppvObject = NULL;			return E_NOINTERFACE;		}		return S_OK;	}	STDMETHODIMP_(ULONG) AddRef() {		return 0;	}	STDMETHODIMP_(ULONG) Release() {		return 0;	}	// *** IRichEditOleCallback methods ***	STDMETHODIMP GetNewStorage ( LPSTORAGE FAR * lplpstg) {		return E_NOTIMPL;	}    STDMETHODIMP GetInPlaceContext(LPOLEINPLACEFRAME FAR * lplpFrame,								  LPOLEINPLACEUIWINDOW FAR * lplpDoc,								  LPOLEINPLACEFRAMEINFO lpFrameInfo) {		return E_NOTIMPL;	}	STDMETHODIMP ShowContainerUI(BOOL fShow) {		return E_NOTIMPL;	}	STDMETHODIMP QueryInsertObject(LPCLSID lpclsid, LPSTORAGE lpstg,		LONG cp) {		return E_NOTIMPL;	}	STDMETHODIMP DeleteObject( LPOLEOBJECT lpoleobj) {		return E_NOTIMPL;	}	STDMETHODIMP QueryAcceptData (LPDATAOBJECT lpdataobj,								CLIPFORMAT FAR * lpcfFormat, DWORD reco,								BOOL fReally, HGLOBAL hMetaPict) {		if ( !fReally ) {					}		return S_FALSE;	}	STDMETHODIMP ContextSensitiveHelp ( BOOL fEnterMode) {		return E_NOTIMPL;	}	STDMETHODIMP GetClipboardData ( CHARRANGE FAR * lpchrg, DWORD reco,		LPDATAOBJECT FAR * lplpdataobj) {		return E_NOTIMPL;	}	STDMETHODIMP GetDragDropEffect ( BOOL fDrag, DWORD grfKeyState,		LPDWORD pdwEffect) {		if ( fDrag ) {			*pdwEffect = 0;		}		return S_OK;	}	STDMETHODIMP GetContextMenu ( WORD seltype, LPOLEOBJECT lpoleobj,									CHARRANGE FAR * lpchrg,									HMENU FAR * lphmenu) {		return E_NOTIMPL;	}};}; // namespace VCFstatic bool Win32RicheditLibraryLoaded = false;Win32Edit::Win32Edit( TextControl* component, const bool& isMultiLineControl ):	AbstractWin32Component( component ),	Win32TextPeer(),	textControl_(component),	backgroundBrush_(NULL),	editState_(0),	currentSelLength_(0),	currentSelStart_(-1),	richEditCallback_(NULL){	if ( isMultiLineControl ) {		editState_ |= esMultiLined; 	}}Win32Edit::~Win32Edit(){	if ( NULL != backgroundBrush_ ) {		DeleteObject( backgroundBrush_ );	}	if ( NULL != richEditCallback_ ) {		SendMessage( hwnd_, EM_SETOLECALLBACK, 0, (LPARAM)0 );		delete richEditCallback_;			}}void Win32Edit::create( Control* owningControl ){	if ( NULL == textControl_ ){		//throw exception !!!!!!	}	Win32ToolKit* toolkit = (Win32ToolKit*)UIToolkit::internal_getDefaultUIToolkit();	HWND parent = toolkit->getDummyParent();	String className;	AnsiString richeditLibrary = "RICHED20.Dll";	if ( !Win32RicheditLibraryLoaded ) {		if  ( NULL != LoadLibraryA( richeditLibrary.c_str() ) ) {			Win32RicheditLibraryLoaded = true;		}		else {			String errMsg =				StringUtils::format( Format("Failed to load \"%s\", a required DLL when using richedit controls. \n"\				"Please make sure this DLL is located in your Windows system, or application directory.") %				richeditLibrary.c_str() );			throw RuntimeException( errMsg );		}	}	if ( System::isUnicodeEnabled() ) {		className = RICHEDIT_CLASSW;	}	else {		className = RICHEDIT_CLASSA;	}	CreateParams params = createParams();	if ( System::isUnicodeEnabled() ) {		hwnd_ = ::CreateWindowExW( params.second,									 className.c_str(),									 NULL,									 params.first,									 0,									 0,									 1,									 1,									 parent,									 NULL,									 ::GetModuleHandleW(NULL),									 NULL );	}	else {		hwnd_ = ::CreateWindowExA( params.second,									 className.ansi_c_str(),									 NULL,									 params.first,									 0,									 0,									 1,									 1,									 parent,									 NULL,									 ::GetModuleHandleA(NULL),									 NULL );	}	if ( NULL != hwnd_ ){		Win32Object::registerWin32Object( this );		subclassWindow();		registerForFontChanges();		//make sure that we get ALL richedit change notfications!		::SendMessage( hwnd_, EM_SETEVENTMASK, 0, ENM_CHANGE | ENM_SELCHANGE );				textControl_->ControlModelChanged +=			new GenericEventHandler<Win32Edit>( this, &Win32Edit::onControlModelChanged, "Win32Edit::onControlModelChanged" );		initFromRichEdit( hwnd_ );	}	else {		//throw exception		throw RuntimeException( "Runtime Exception: " + Win32Utils::getErrorString( ::GetLastError() ) );	}	setCreated( true );}Win32Object::CreateParams Win32Edit::createParams(){	Win32Object::CreateParams result;	result.first = WS_CHILD;// SIMPLE_VIEW;	result.first &= ~WS_BORDER;	result.first &= ~WS_VISIBLE;	// this is a temporary solution: it would be better to implement	// a method giving the option to the user, and painting the selection	// in an unfocused control with a light gray on the background - MP.	result.first |= ES_AUTOHSCROLL | ES_SAVESEL /*| ES_NOHIDESEL*/;	if ( editState_ & esMultiLined ) {		result.first |= ES_SAVESEL | ES_MULTILINE | WS_HSCROLL | WS_VSCROLL;// | ES_WANTRETURN;	}	return result;}OSHandleID Win32Edit::getTextObjectHandle(){	return Win32TextPeer::getTextObjectHandle();}void Win32Edit::setRightMargin( const double & rightMargin ){	editState_ |= esStyleChanging;	::SendMessage( hwnd_, EM_SETMARGINS, EC_RIGHTMARGIN, (long)rightMargin );	editState_ &= ~esStyleChanging;}void Win32Edit::setLeftMargin( const double & leftMargin ){	editState_ |= esStyleChanging;	::SendMessage( hwnd_, EM_SETMARGINS, EC_LEFTMARGIN, (long)leftMargin );	editState_ &= ~esStyleChanging;}unsigned long Win32Edit::getLineCount(){	return ::SendMessage( hwnd_, EM_GETLINECOUNT, 0, 0 );}Rect Win32Edit::getContentBoundsForWidth(const double& width){	return Win32TextPeer::getContentBoundsForWidth(width);}unsigned long Win32Edit::getCurrentLinePosition(){	DWORD pos = getSelectionStart();	ulong32 result = ::SendMessage( hwnd_, EM_LINEFROMCHAR, pos, 0 );	return result;}double Win32Edit::getLeftMargin(){	double result = 0.0;	DWORD margin = ::SendMessage( hwnd_, EM_GETMARGINS, 0, 0 );	result = LOWORD(margin);	return result;}double Win32Edit::getRightMargin(){	double result = 0.0;	DWORD margin = ::SendMessage( hwnd_, EM_GETMARGINS, 0, 0 );	result = HIWORD(margin);	return result;}void Win32Edit::insertText( unsigned int start, const String& text ){	editState_ |= esPeerTextChanging;	Win32TextPeer::insertText( start, text );	editState_ &= ~esPeerTextChanging;}void Win32Edit::deleteText( unsigned int start, unsigned int length ){	editState_ |= esPeerTextChanging;	Win32TextPeer::deleteText( start, length );	editState_ &= ~esPeerTextChanging;}unsigned int Win32Edit::getTextLength(){	return Win32TextPeer::getTextLength();}String Win32Edit::getText( unsigned int start, unsigned int length ){	return Win32TextPeer::getText(start,length);}String Win32Edit::getText(){		String result;	ITextRange* range;	textDocument_->Range( 0, 0, &range );	if ( NULL != range ) {		long len = 0;		range->GetStoryLength( &len );		range->SetEnd ( len );		BSTR str = SysAllocString( NULL );		range->GetText( &str );		/**		don't copy the very last character as this will be a 		0x0D, from MSDN:		"Another important feature is that all stories contain 		an undeletable final CR (0xD) character at the end. So 		even an empty story has a single character, namely the 		final CR."		*/		result.assign( str, SysStringLen(str)-1 );		SysFreeString( str );		range->Release();	}	return result;}void Win32Edit::paint( GraphicsContext* context, const Rect& paintRect ){	Win32TextPeer::paint( context, paintRect );}void Win32Edit::setTopMargin( const double & topMargin ){	editState_ |= esStyleChanging;	Win32TextPeer::setTopMargin( topMargin );	editState_ &= ~esStyleChanging;}void Win32Edit::setBottomMargin( const double & bottomMargin ){	editState_ |= esStyleChanging;	Win32TextPeer::setBottomMargin( bottomMargin );	editState_ &= ~esStyleChanging;}double Win32Edit::getTopMargin(){	return Win32TextPeer::getTopMargin();}double Win32Edit::getBottomMargin(){	return Win32TextPeer::getBottomMargin();}void Win32Edit::setStyle( unsigned int start, unsigned int length, Dictionary& styles ){	editState_ |= esStyleChanging;	Win32TextPeer::setStyle( start, length, styles );	editState_ &= ~esStyleChanging;}void Win32Edit::getStyle( unsigned int start, unsigned int length, Dictionary& styles, Color& color ){	Win32TextPeer::getStyle( start, length, styles, color );}void Win32Edit::setDefaultStyle( Dictionary& styles ){	editState_ |= esStyleChanging;	Win32TextPeer::setDefaultStyle( styles );	editState_ &= ~esStyleChanging;}VCF::Point* Win32Edit::getPositionFromCharIndex( const unsigned long& index ){	DWORD pos = ::SendMessage( hwnd_, EM_POSFROMCHAR, index, 0 );	posAtChar_.x_ = LOWORD(pos);	posAtChar_.y_ = HIWORD(pos);	return &posAtChar_;}

⌨️ 快捷键说明

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