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