CEdit ::撤消功能& EM_UNDO消息 [英] CEdit::Undo function & EM_UNDO message
问题描述
我已经从CEdit
继承了CEditEx
的子类,所以当覆盖基类CWnd::OnChar
时,在子类CEditEx::OnChar
)上,函数CEditEx::Undo
将无效(丢失),但是功能:CEditEx::Cut
,CEditEx::Copy
和CEditEx::Paste
是有效的.
我发现CEdit::Undo
函数的定义如下:
I have subclassed CEditEx
from CEdit
, so when overriding the base class CWnd::OnChar
, on the subclassed CEditEx
class (CEditEx::OnChar
), the function CEditEx::Undo
will have no effect (lost), but the functions: CEditEx::Cut
, CEditEx::Copy
and CEditEx::Paste
are functional.
I have found that the definition of C:Undo
function is as folows:
_AFXWIN_INLINE BOOL CEdit::Undo()
{ ASSERT(::IsWindow(m_hWnd)); return (BOOL)::SendMessage(m_hWnd, EM_UNDO, 0, 0); }
不幸的是,它是不可调试的.因此,我需要重写CEditEx::Undo
函数.
谁能给我该功能的算法
谢谢您的理解.
更新:
这是我的CEditEx::OnChar
函数:
Unfortunately, it is not debugable. And because of that I need to rewrite the CEditEx::Undo
function.
Can anyone give me an algorithm of that function
Thank you for your understand.
Update:
This is my CEditEx::OnChar
function:
void CEditEx::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)
{
// TODO: Add your message handler code here and/or call default
if (nChar == VK_BACK)
return;
if (!_istdigit(nChar))
{
::MessageBeep((UINT)-1);
return;
}
CString strWindowText;
int nStartChar, nEndChar;
GetWindowText(strWindowText);
GetSel(nStartChar, nEndChar);
if (nStartChar != nEndChar)
strWindowText.Delete(nStartChar, nEndChar - nStartChar);
else
ValidateWindowText(strWindowText, nStartChar, TRUE);
strWindowText.Insert(nStartChar ++, nChar);
ValidateWindowText(strWindowText, nStartChar);
nEndChar = nStartChar;
//GetWindowText(m_strWindowTextUndo);
SetWindowText(strWindowText);
SetSel(nStartChar, nEndChar);
//SetModify();
//CEdit::OnChar(nChar, nRepCnt, nFlags);
}
推荐答案
如果您要从CEditEx::OnChar()
调用CEdit::OnChar()
,则默认的撤消仍将起作用.
因为编辑控件的默认撤消只能撤消上一个操作,所以实现很简单:在CEditEx::OnChar()
中,当要更改内容时(例如,不处理光标键时),将文本存储在撤消成员变量中.在您的CEditEx::Undo()
中,通过将文本从undo成员变量传递到SetWindowText()
来还原内容.
要支持撤消复制,剪切和粘贴操作,请在这些处理程序中将文本复制到同一变量.
更新后的问题的更新答案:
将这些添加到您的班级:
If you are callingC:OnChar()
from yourCEditEx::OnChar()
, the default Undo should still work.
Because the default Undo of an edit control can only undo the last operation, implementation is simple: InCEditEx::OnChar()
store the text in an undo member variable when the content is to be changed (e.g. when not handling a cursor key). In yourCEditEx::Undo()
restore the content by passing the text from the undo member variable toSetWindowText()
.
To support undo for copy, cut, and paste operations, copy the text to the same variable in these handlers.
Updated answer for the updated question:
Add these to your class:
class CEditEx : public CEdit
{
...
public:
inline BOOL CanUndo() const { return m_bCanUndo; }
protected:
void SaveUndoText();
BOOL m_bCanUndo;
CString m_strWindowTextUndo;
...
public:
afx_msg void OnCut();
afx_msg void OnUndo();
}
并将这些实施到您的实施中:
And these to your implementation:
CEditEx::CEditEx()
{
m_bCanUndo = FALSE;
}
BEGIN_MESSAGE_MAP(CEditEx, CEdit)
...
ON_COMMAND(ID_EDIT_CUT, OnCut)
ON_COMMAND(ID_EDIT_UNDO, OnUndo)
END_MESSAGE_MAP
void CEditEx::SaveUndoText()
{
GetWindowText(m_strWindowTextUndo);
m_bCanUndo = TRUE;
}
void CEditEx::OnUndo()
{
if (m_bCanUndo)
{
CString strRedo;
GetWindowText(strRedo);
SetWindowText(m_strWindowTextUndo);
m_strWindowTextUndo = strRedo;
}
}
void CEditEx::OnCut()
{
// Must check for selection. Otherwise undo would not work.
int nStartChar, nEndChar;
GetSel(nStartChar, nEndChar);
if (nStartChar != nEndChar)
{
SaveUndoText();
CEdit::Cut();
}
}
void CEditEx::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)
{
...
// Before changing the content.
SaveUndoText();
...
}
像OnCut()
一样实现OnClear()
和OnPaste()
.
Implement OnClear()
and OnPaste()
like OnCut()
.
这篇关于CEdit ::撤消功能& EM_UNDO消息的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!