win32edit.cpp
来自「这是VCF框架的代码」· C++ 代码 · 共 1,837 行 · 第 1/4 页
CPP
1,837 行
unsigned long Win32Edit::getCharIndexFromPosition( VCF::Point* point ){ DWORD pos = 0; pos = MAKEWORD( (long)point->x_, (long)point->y_ ); unsigned long result = ::SendMessage( hwnd_, EM_CHARFROMPOS, 0, pos ); return result;}unsigned long Win32Edit::getCaretPosition(){ return getSelectionStart();}void Win32Edit::setCaretPosition( const unsigned long& caretPos ){}//Ugly hack for bcb6 w. Stlport w. fixed ctype.h header#if defined(__BORLANDC__) && defined(__SGI_STL_PORT) && ((__BORLANDC__ >= 0x0560) && (__BORLANDC__ < 0x0570))#define toupper std::_ltoupper#define tolower std::_ltolower#endifbool Win32Edit::stateAllowsModelChange(){ bool result = false; if ( !(editState_ & esStyleChanging) && !(editState_ & esPeerTextChanging) && !(editState_ & esKeyEvent) && !(editState_ & esExternalTextChanging) ) { result = true; } return result;}bool Win32Edit::handleEventMessages( UINT message, WPARAM wParam, LPARAM lParam, LRESULT& wndProcResult, WNDPROC defaultWndProc ){ bool result = false; wndProcResult = 0; switch ( message ) { case WM_RBUTTONDOWN : case WM_LBUTTONDOWN : { result = AbstractWin32Component::handleEventMessages( message, wParam, lParam, wndProcResult ); ulong32 start = 0; ulong32 end = 0; getSelectionMark( start, end ); currentSelLength_ = end - start; currentSelStart_ = start; } break; case WM_SETTEXT : case EM_STREAMIN : { if ( textControl_->getReadOnly() ) { wndProcResult = 0; result = true; } else { result = true; editState_ |= esPeerTextChanging; //let the default rich text code handle this! wndProcResult = defaultWndProcedure( message, wParam, lParam ); //modify the model, but ignore an change notifications to us! editState_ |= esModelTextChanging; textControl_->getTextModel()->setText( getText() ); editState_ &= ~esModelTextChanging; editState_ &= ~esPeerTextChanging; } } break;/* case WM_TIMER : { StringUtils::trace( "WM_TIMER\n" ); } break; case EM_SETSEL : { StringUtils::trace( "EM_SETSEL\n" ); } break; case EM_EXSETSEL : { StringUtils::trace( "EM_EXSETSEL\n" ); } break;*/ case WM_RBUTTONUP : case WM_LBUTTONUP : { result = true; wndProcResult = defaultWndProcedure( message, wParam, lParam ); //this causes weird double selection AbstractWin32Component::handleEventMessages( message, wParam, lParam, wndProcResult ); ulong32 start = 0; ulong32 end = 0; getSelectionMark( start, end ); if ( (currentSelLength_ != (end - start)) || (currentSelStart_ != start) ) { //selection changed TextEvent event( textControl_, start, end - start ); textControl_->SelectionChanged.fireEvent( &event ); } currentSelLength_ = end - start; currentSelStart_ = start; } break; case WM_KEYDOWN: { if ( textControl_->getReadOnly() ) { wndProcResult = 0; result = true; } else { editState_ |= esKeyEvent; ulong32 virtKeyCode = Win32UIUtils::translateVKCode( wParam ); switch ( virtKeyCode ) { case vkLeftArrow : case vkRightArrow : case vkPgUp : case vkPgDown : case vkHome : case vkEnd : case vkDownArrow : case vkUpArrow : { ulong32 start = 0; ulong32 end = 0; getSelectionMark( start, end ); currentSelLength_ = end - start; currentSelStart_ = start; } break; } if ( (peerControl_->getComponentState() != Component::csDestroying) ) { KeyboardData keyData = Win32UIUtils::translateKeyData( hwnd_, lParam ); unsigned long eventType = Control::KEYBOARD_DOWN; unsigned long keyMask = Win32UIUtils::translateKeyMask( keyData.keyMask ); //virtKeyCode = Win32UIUtils::translateVKCode( keyData.VKeyCode ); VCF::KeyboardEvent event( peerControl_, eventType, keyData.repeatCount, keyMask, (VCF::VCFChar)keyData.character, (VirtualKeyCode)virtKeyCode ); peerControl_->handleEvent( &event ); switch ( virtKeyCode ) { case vkLeftArrow : case vkRightArrow : case vkPgUp : case vkPgDown : case vkHome : case vkEnd : case vkDownArrow : case vkUpArrow : { ulong32 start = 0; ulong32 end = 0; getSelectionMark( start, end ); if ( event.hasShiftKey() && ((currentSelLength_ != (end - start)) || (currentSelStart_ != start)) ) { //selection changed TextEvent event( textControl_, start, end - start ); textControl_->SelectionChanged.fireEvent( &event ); } currentSelLength_ = end - start; currentSelStart_ = start; } break; } //wndProcResult = 1; result = true; } if ( !(peerControl_->getComponentState() & Component::csDesigning) ) { wndProcResult = defaultWndProcedure( message, wParam, lParam ); result = true; } editState_ &= ~esKeyEvent; } } break; case WM_CHAR: case WM_KEYUP:{ if ( textControl_->getReadOnly() ) { wndProcResult = 0; result = true; } else { editState_ |= esKeyEvent; /** JC I moved the defaultWndProcedure( message, wParam, lParam ); block *after* I call the peerControl_->handleEvent() method. Otherwise the caretpos is "wrong", for lack of a better word, which in turn screws up where data is removed from the model. */ if ( !peerControl_->isDestroying() && !peerControl_->isDesigning() ) { KeyboardData keyData = Win32UIUtils::translateKeyData( hwnd_, lParam ); ulong32 virtKeyCode = Win32UIUtils::translateVKCode( keyData.VKeyCode ); unsigned long eventType = 0; switch ( message ){ case WM_CHAR: { /** JC we do this to overcome getting weird virtual key values for WM_CHAR messages, as translateKeyData isn't quite right. In fact, we should conceivably look into ditching period */ eventType = Control::KEYBOARD_PRESSED; keyData.character = (VCFChar)wParam; /** JC if the character is a graphic char (like ":" or "a") then re-calculate the virtual key code, based on the character value. This was put here to overcome a bug when handling WM_CHAR's from the numpad, which gives us the right character, but a bogus virtual key */ if ( isgraph( keyData.character ) ) { virtKeyCode = Win32UIUtils::convertCharToVKCode( keyData.character ); } } break; case WM_KEYUP: { eventType = Control::KEYBOARD_UP; } break; } unsigned long keyMask = Win32UIUtils::translateKeyMask( keyData.keyMask ); VCF::KeyboardEvent event( peerControl_, eventType, keyData.repeatCount, keyMask, (VCF::VCFChar)keyData.character, (VirtualKeyCode)virtKeyCode ); peerControl_->handleEvent( &event ); result = true; } if ( !peerControl_->isDesigning() ) { wndProcResult = defaultWndProcedure( message, wParam, lParam ); result = true; } else if ( peerControl_->isDesigning() ) { wndProcResult = 0; result = true; } editState_ &= ~esKeyEvent; } } break; case WM_COMMAND:{ wndProcResult = defaultWndProcedure( message, wParam, lParam ); result = true; switch ( HIWORD(wParam) ) { case EN_CHANGE:{ if ( stateAllowsModelChange() ) { editState_ |= esModelTextChanging; VCF::TextModel* model = textControl_->getTextModel(); if ( NULL != model ) { String text = getText(); model->setText( text ); } editState_ &= ~esModelTextChanging; } } break; } } break; case EN_SELCHANGE : { wndProcResult = 0; result = true; SELCHANGE* selChange = (SELCHANGE*)lParam; //StringUtils::trace( Format("EN_SELCHANGE selChange->seltyp:%d cpMax: %d, cpMin: %d\n") % // selChange->seltyp % selChange->chrg.cpMax % selChange->chrg.cpMin ); if ( selChange->chrg.cpMax != selChange->chrg.cpMin ) { //selection changed //StringUtils::trace( "Changing sel start and sel leng\n" ); currentSelLength_ = selChange->chrg.cpMax - selChange->chrg.cpMin; currentSelStart_ = selChange->chrg.cpMin; TextEvent event( textControl_, currentSelStart_, currentSelLength_ ); textControl_->SelectionChanged.fireEvent( &event ); } } break; case WM_CUT : case EM_REDO :case EM_UNDO : case WM_PASTE : { if ( textControl_->getReadOnly() ) { wndProcResult = 0; result = true; } else { wndProcResult = 0; result = false; editState_ |= esExternalTextChanging; if ( !peerControl_->isDesigning() ) { wndProcResult = defaultWndProcedure( message, wParam, lParam ); result = true; } // copy the control's text into the model VCF::TextModel* model = textControl_->getTextModel(); if ( NULL != model ) { editState_ |= esModelTextChanging; String text = getText(); /*if ( WM_PASTE == message ) { //remove \r\n and replace with \n uint32 pos = text.find( "\r\n" ); while ( pos != String::npos ) { text.erase( pos, 1 ); //erase \r pos = text.find( "\r\n" ); } }*/ model->setText( text ); editState_ &= ~esModelTextChanging; } editState_ &= ~esExternalTextChanging; } } break; case WM_ERASEBKGND :{ wndProcResult = 1; Color* color = peerControl_->getColor(); COLORREF backColor = color->getColorRef32(); SendMessage( hwnd_, EM_SETBKGNDCOLOR, 0, (LPARAM)backColor ); result = true; } break; case WM_PAINT:{ wndProcResult = 0; result = false; } break; case WM_NCCALCSIZE: { wndProcResult = handleNCCalcSize( wParam, lParam ); result = true; } break; case WM_NCPAINT: { wndProcResult = handleNCPaint( wParam, lParam ); return true; } break; case WM_CTLCOLOREDIT : { HDC hdcEdit = (HDC) wParam; // handle to display context HWND hwndEdit = (HWND) lParam; // handle to static control if ( NULL != backgroundBrush_ ) { DeleteObject( backgroundBrush_ ); } Color* color = peerControl_->getColor(); COLORREF backColor = color->getColorRef32(); color = peerControl_->getFont()->getColor(); COLORREF textColor = color->getColorRef32(); backgroundBrush_ = CreateSolidBrush( backColor ); SetBkColor( hdcEdit, backColor ); SetTextColor( hdcEdit, textColor ); wndProcResult = (LRESULT)backgroundBrush_; return true; } break; //this may be useful to uncomment, but at the //moment it never gets called, possible because we
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?