CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 1 of 1
  1. #1
    Join Date
    Feb 2000
    Location
    Indore, India
    Posts
    1,046

    MFC Edit Control: How do I introduce insert/overwrite mode to 'CEdit' derived edit co

    Q: How do I introduce insert/overwrite mode to 'CEdit' derived edit control?

    A: A normal edit control of type 'CEdit' or a derived class does not recognise insert/overwrite modes. A MFC application does not display the status of the 'INSERT' key as it does for keys like 'SCROLL', 'NUMERIC' and 'CAPITAL'. A step by step procedure is shown here to differentiate the modes in terms of cursor shape and status bar display, as it is done in many editors.

    For changing the cursor depending on the edit mode, I have coded a global function 'UpdateCaret()' which takes the pointer of the control and the edit mode as the arguments. This check whether the mode is overwrite, calculates the next character width if it is and sets the width of caret to that of the character, indicating that it is being overwritten.


    Code:
    void UpdateCaret(CEdit* pEdit, BOOL bInsert)
    {
      CFont* pFont = pEdit->GetFont();
      CDC* pDC = pEdit->GetDC();
      CFont* pOldFont = pDC->SelectObject(pFont);
      CSize sizeChar = pDC->GetTextExtent("0");
      if (bInsert)
      {
        // Insert mode, vertical line caret
        sizeChar.cx = 0;
      }
      else
      {
        // Checks whether caret is at the end of current line
        int nLineIndex = pEdit->LineIndex();
        int nLineLength = pEdit->LineLength();
        int nStart, nEnd;
        pEdit->GetSel(nStart, nEnd);
        if (nStart == nEnd && nStart != nLineIndex + nLineLength)
        {
          // No text selected & caret is not at end of line
          // So, gets next character
          char* strLine = new char[nLineLength + 1];
          pEdit->GetLine(pEdit->LineFromChar(), strLine, nLineLength);
          strLine[nStart - nLineIndex + 1] = 0;
    
          // Sets caret size as size of next character
          sizeChar = pDC->GetTextExtent(strLine + (nStart - nLineIndex));
          delete[] strLine;
        }
      }
    
      // Destroys previous caret and displays new caret
      DestroyCaret();
      pEdit->HideCaret();
      pEdit->CreateSolidCaret(sizeChar.cx, sizeChar.cy);
      pEdit->ShowCaret();
    
      // Stores caret width in application object
      ((CIOEditApp*) AfxGetApp())->m_nCaretWidth = sizeChar.cx;
      pDC->SelectObject(pOldFont);
    }
    Edit controls and views can call this function in its 'PreTranslateMessage()' function when the message is either 'WM_KEYDOWN', 'WM_KEYUP', 'WM_LBUTTONDOWN', 'WM_LBUTTONUP' or 'WM_SETFOCUS'.


    Code:
    BOOL CXEdit::PreTranslateMessage(MSG* pMsg) 
    {
      // TODO: Add your specialized code here and/or call the base class
      switch (pMsg->message)
      {
      case (WM_KEYDOWN):
      case (WM_KEYUP):
      case (WM_LBUTTONDOWN):
      case (WM_LBUTTONUP):
      case (WM_SETFOCUS):
        {
          UpdateCaret(this, m_bInsert);
          break;
        }
      case (WM_CHAR):
        {
          if (!m_bInsert && pMsg->wParam >= ' ' && pMsg->wParam <= 0xFF)
            DeleteNextChar(this);
          break;
        }
      }
      return CEdit::PreTranslateMessage(pMsg);
    }
    If it is a view, I handle its 'PreTranslateMessage()' function in the same way, but the call to 'UpdateCaret()' is replaced by


    Code:
    UpdateCaret(&GetEditCtrl(), m_bInsert);
    The function 'DeleteNextChar()' will delete the next character before writing the typed character (same as overwriting).


    Code:
    void DeleteNextChar(CEdit* pEdit)
    {
      int Start, End;
      // Removes existing selection
      pEdit->GetSel(Start, End);
      pEdit->ReplaceSel("");
      // Selects the next character and deletes it
      pEdit->SetSel(Start, End + 1);
      pEdit->ReplaceSel("");
    }
    For displaying the edit mode on status bar, I have defined an indicator 'ID_INDICATOR_INS' and handled its 'UPDATE_COMMAND_UI' message. I have defined a variable to store the current edit mode in the application, from where it is drawn for diaplay. Note' that this application class variable is set in 'UpdateCaret()' function.

    In the attached project, I have implemented this method for the view (of 'CEditView' class) and a 'CEdit' control in a dialog box. I have also shown how the current edit mode can be displayed on status bar.



    Attached Files Attached Files
    Last edited by Andreas Masur; April 2nd, 2006 at 04:34 PM.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured