本文介绍了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);
}

推荐答案

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消息的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-27 14:06