CEdit ::撤消功能& EM_UNDO消息 [英] CEdit::Undo function & EM_UNDO message

查看:86
本文介绍了CEdit ::撤消功能& EM_UNDO消息的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经从CEdit继承了CEditEx的子类,所以覆盖基类CWnd::OnChar时,在子类的类(CEditEx::OnChar)上,函数CEditEx::Undo 将无效(丢失),但是功能:CEditEx::CutCEditEx::CopyCEditEx::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 calling C:OnChar() from your CEditEx::OnChar(), the default Undo should still work.

Because the default Undo of an edit control can only undo the last operation, implementation is simple: In CEditEx::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 your CEditEx::Undo() restore the content by passing the text from the undo member variable to SetWindowText().

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆