introduce insert/overwrite mode to 'CEdit' derived edit control

来源:互联网 发布:做游戏的程序员 编辑:程序博客网 时间:2024/05/22 10:43

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.
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.

 

From : http://www.codeguru.com/forum/showthread.php?t=380650

 

 

原创粉丝点击