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