Die
nachfolgende Klasse erweitert die Klasse CEditView um
einen Überschreibmodus.
Binden Sie
statt CEditView einfach COverEditView in Ihr Projekt ein.
overedit.h
//////////////////////////////////////////////////////////////////////////
//
// COverEditView - 1995 Wolfgang Rolke
//
// COverEditView erweitert die Klasse CEditView um einen
Überschreibmodus.
//
//////////////////////////////////////////////////////////////////////////
#ifndef
__OVEREDIT_H__
#define __OVEREDIT_H__
//////////////////////////////////////////////////////////////////////////
class
COverEditView : public CEditView
{
DECLARE_DYNCREATE(COverEditView)
protected:
// Überschreibmodus
global für alle Objekte gleich
static
BOOL m_bOverwrite; // TRUE, wenn im
Überschreibmodus
static BOOL m_bOverwriteOld; // Überschreibmodus
bei Initialisierung
// Konstruktoren
public:
COverEditView();
// Attribute
// Liefert den
aktuellen Schreibmodus
BOOL
GetOverwriteMode() const { return m_bOverwrite; }
// Setzt den
Schreibmodus
BOOL
SetOverwriteMode(BOOL bOverwrite = TRUE);
// Operationen
// Initialisierung
und Speicherung des Überschreibmodus
static
void Initialize();
static void Terminate();
// Liefert den
Text zwischen zwei Zeichenpositionen
void
GetSubText(CString& strSubText, int nStartPos, int
nEndPos) const;
// Markiert das
aktuelle Wort
int
SelectWord() const;
// Ermittelt die
Position der Schreibmarke
BOOL
GetCaretIndex(int& nLine, int& nColumn) const;
// Implementation
private:
// Setzt im Überschreibmodus
die korrekte Zeichenmarkierung
void
CheckSelection(UINT message, WPARAM wParam, LPARAM lParam);
protected:
virtual WNDPROC* GetSuperWndProcAddr();
// Aktualisiert im
Überschreibmodus die Zeichenmarkierung
virtual
LRESULT DefWindowProc(UINT message, WPARAM wParam, LPARAM
lParam);
#ifdef
_DEBUG
public:
virtual void AssertValid() const;
virtual void Dump(CDumpContext& dc)
const;
#endif
protected:
//{{AFX_MSG(COverEditView)
afx_msg
void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags);
afx_msg void OnUpdateIndicatorOvr(CCmdUI*
pCmdUI);
afx_msg LRESULT OnSetOverwrite(WPARAM
Overwrite, LPARAM);
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
//////////////////////////////////////////////////////////////////////////
// Befehlsnachricht für den Schreibmodus
#define
OWM_SETOVERWRITE (WM_USER + 0x1000)
//////////////////////////////////////////////////////////////////////////
// Benachrichtigungen beim Wechsel des Schreibmodus
#if
!defined(NOPARENTNOTIFY)
#define OWN_OVERWRITE 0x1000
#define OWN_INSERT 0x1001
#endif
//////////////////////////////////////////////////////////////////////////
#endif
//__OVEREDIT_H__
//////////////////////////////////////////////////////////////////////////
overedit.cpp
//////////////////////////////////////////////////////////////////////////
//
// COverEditView - 1995 Wolfgang Rolke
//
// COverEditView erweitert die Klasse CEditView um einen
Überschreibmodus.
//
//////////////////////////////////////////////////////////////////////////
#include
"stdafx.h"
#include
"overedit.h"
#ifdef
_DEBUG
#undef THIS_FILE
static char BASED_CODE THIS_FILE[] = __FILE__;
#endif
#ifdef
WIN32
#define _fmemcpy memcpy
#endif
//////////////////////////////////////////////////////////////////////////
IMPLEMENT_DYNCREATE(COverEditView,
CEditView)
BEGIN_MESSAGE_MAP(COverEditView,
CEditView)
//{{AFX_MSG_MAP(COverEditView)
ON_WM_KEYDOWN()
ON_UPDATE_COMMAND_UI(ID_INDICATOR_OVR,
OnUpdateIndicatorOvr)
ON_MESSAGE(OWM_SETOVERWRITE,
OnSetOverwrite)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
//////////////////////////////////////////////////////////////////////////
BOOL
COverEditView::m_bOverwrite = FALSE;
BOOL COverEditView::m_bOverwriteOld = FALSE;
static
char BASED_CODE szSettings[] = "Settings";
static char BASED_CODE szOverType[] = "OverType";
//////////////////////////////////////////////////////////////////////////
// Konstruktor
COverEditView::COverEditView()
{
// Nichts zu tun
}
//////////////////////////////////////////////////////////////////////////
WNDPROC*
COverEditView::GetSuperWndProcAddr()
{
static WNDPROC NEAR pfnSuper;
return &pfnSuper;
}
//////////////////////////////////////////////////////////////////////////
// Initialisierung und Speicherung des Überschreibmodus
void
COverEditView::Initialize()
{
m_bOverwrite = AfxGetApp()->GetProfileInt(szSettings,
szOverType, 0);
m_bOverwriteOld = m_bOverwrite;
}
void
COverEditView::Terminate()
{
if (m_bOverwrite != m_bOverwriteOld)
AfxGetApp()->WriteProfileInt(szSettings,
szOverType, m_bOverwrite);
}
//////////////////////////////////////////////////////////////////////////
// Liefert den Text zwischen zwei Zeichenpositionen
void
COverEditView::GetSubText(CString& strSubText, int
nStartPos, int nEndPos) const
{
ASSERT_VALID(this);
// Endposition
darf kleiner sein als Anfangsposition
UINT
uIndex = min((UINT)nStartPos, (UINT)nEndPos);
UINT uIndexEnd = max((UINT)nStartPos, (UINT)nEndPos);
ASSERT(uIndexEnd <= GetBufferLength());
// Anzahl der zu
kopierenden Zeichen
UINT
uLen = uIndexEnd - uIndex;
// Zeiger auf den
Textanfang
LPCSTR
lpszText = ((COverEditView*)this)->LockBuffer();
// Den gewünschten
Textausschnitt kopieren
_fmemcpy(strSubText.GetBuffer(uLen),
lpszText+uIndex, uLen);
strSubText.ReleaseBuffer(uLen);
UnlockBuffer();
ASSERT_VALID(this);
}
//////////////////////////////////////////////////////////////////////////
// Diese Methode prüft, ob ein Bereich im Textfeld
ausgewählt ist.
// Ist kein Bereich markiert, wird das aktuelle Wort (in
dem sich
// die Einfügemarke befindet) ausgewählt. Die Funktion
liefert als
// Ergebnis die Anzahl der selektierten Zeichen zurück.
int
COverEditView::SelectWord() const
{
ASSERT_VALID(this);
if
(GetBufferLength() == 0)
return 0;
int
iStartChar, iEndChar;
GetEditCtrl().GetSel(iStartChar,
iEndChar);
int nSelLen = iEndChar - iStartChar;
BOOL bIsOvrSel = (nSelLen == 1)
&& m_bOverwrite;
if
(nSelLen && !bIsOvrSel)
return nSelLen;
if
(bIsOvrSel)
GetEditCtrl().SetSel(iStartChar,
iStartChar);
int
iLine = GetEditCtrl().LineFromChar();
int nLineLen = GetEditCtrl().LineLength();
if
(nLineLen > 1024)
nLineLen = 1024;
CString
strLine;
nLineLen = GetEditCtrl().GetLine(iLine,
strLine.GetBuffer(nLineLen), nLineLen);
strLine.ReleaseBuffer(nLineLen);
if
(nLineLen == 0)
return 0;
int
iChar = GetEditCtrl().LineIndex(iLine);
int iCharInLine = iStartChar - iChar;
CString
strLeftLine = strLine.Left(iCharInLine);
CString strRightLine = strLine.Right(nLineLen-iCharInLine);
const
char* pszCutOffChars = " ,.:;!?'\"=+-*/^\\<>()[]{}&|~#@
";
strLeftLine.MakeReverse();
int iLeftChar = strLeftLine.FindOneOf(pszCutOffChars);
if (iLeftChar == -1)
iStartChar = iChar;
else
iStartChar = iChar +
iCharInLine - iLeftChar;
int
iRightChar = strRightLine.FindOneOf(pszCutOffChars);
if (iRightChar == -1)
iEndChar = iChar +
nLineLen;
else
iEndChar = iChar +
iCharInLine + iRightChar;
nSelLen
= iEndChar - iStartChar;
if
(nSelLen)
GetEditCtrl().SetSel(iStartChar,
iEndChar);
ASSERT_VALID(this);
return
nSelLen;
}
//////////////////////////////////////////////////////////////////////////
// Ermittelt die Position der Schreibmarke
BOOL
COverEditView::GetCaretIndex(int& nLine, int&
nColumn) const
{
int nSelBeg, nSelEnd;
GetEditCtrl().GetSel(nSelBeg,
nSelEnd);
if ((nSelEnd == nSelBeg) || ((nSelEnd -
nSelBeg == 1) && m_bOverwrite))
{
nLine = 1 +
GetEditCtrl().LineFromChar(); // Zeile
nColumn = 1 + nSelBeg
- GetEditCtrl().LineIndex(); // Spalte
return
TRUE;
}
else
{
nLine = nSelEnd -
nSelBeg; // Anzahl
markierter Zeichen
nColumn =
GetBufferLength(); // Gesamtzahl der
Zeichen
return
FALSE;
}
}
//////////////////////////////////////////////////////////////////////////
// Setzt im Überschreibmodus die korrekte
Zeichenmarkierung
void
COverEditView::CheckSelection(UINT message, WPARAM
wParam, LPARAM)
{
if (message == WM_KEYDOWN || message ==
WM_CHAR || message == WM_LBUTTONUP || message ==
WM_SETFOCUS)
{
int nStartPos,
nEndPos;
// Nur wenn keine
Markierung vorliegt, ein Zeichen selektieren
GetEditCtrl().GetSel(nStartPos,
nEndPos);
if (nStartPos ==
nEndPos)
{
if
((UINT)nStartPos == GetBufferLength())
return;
int
iStart = 1; // Schreibmarke
links der Markierung setzen
// Sonderfall:
Markierungserweiterung nach rechts
if
(message == WM_KEYDOWN && wParam == VK_RIGHT
&& GetKeyState(VK_SHIFT) >> 15 &&
nStartPos)
// Das vorherige
Zeichen selektieren und die
// Schreibmarke
rechts der Markierung setzen
iStart
= -1;
GetEditCtrl().SetSel(nStartPos
+ iStart, nStartPos);
CString
strSelText;
GetSubText(strSelText,
nStartPos, nStartPos + iStart);
if
(strSelText == '\r') /* CR */
// Wagenrücklauf
darf nicht selektiert werden
GetEditCtrl().SetSel(nStartPos,
nStartPos);
}
}
}
//////////////////////////////////////////////////////////////////////////
// Aktualisiert im Überschreibmodus die
Zeichenmarkierung
LRESULT
COverEditView::DefWindowProc(UINT message,
WPARAM wParam, LPARAM lParam)
{
LRESULT lResult = CEditView::DefWindowProc(message,
wParam, lParam);
if
(m_bOverwrite)
CheckSelection(message,
wParam, lParam);
return
lResult;
}
//////////////////////////////////////////////////////////////////////////
// Setzt den Schreibmodus
BOOL
COverEditView::SetOverwriteMode(BOOL bOverwrite /*=TRUE*/)
{
// Sicherstellen,
daß bOverwrite == TRUE || bOverwrite == FALSE
bOverwrite
= !!bOverwrite;
if
(m_bOverwrite == bOverwrite)
return FALSE;
// Neuen
Schreibmodus setzen
m_bOverwrite
= bOverwrite;
if
(m_bOverwrite)
// Markierung
setzen
CheckSelection(WM_KEYDOWN,
0, 0L);
else
{
int nStartPos,
nEndPos;
// Wenn ein
Zeichen selektiert ist, Markierung aufheben
GetEditCtrl().GetSel(nStartPos,
nEndPos);
if (nEndPos -
nStartPos == 1)
GetEditCtrl().SetSel(nStartPos,
nStartPos);
}
#if
!defined(NOPARENTNOTIFY)
// Das
Mutterfenster über den neuen Schreibmodus
benachrichtigen
#if defined(WIN32)
GetParent()->SendMessage(WM_COMMAND,
MAKEWPARAM(GetDlgCtrlID(), m_bOverwrite ? OWN_OVERWRITE :
OWN_INSERT), (LPARAM)m_hWnd);
#else
GetParent()->SendMessage(WM_COMMAND,
GetDlgCtrlID(), MAKELPARAM(m_hWnd, m_bOverwrite ?
OWN_OVERWRITE : OWN_INSERT));
#endif
#endif
return
TRUE;
}
//////////////////////////////////////////////////////////////////////////
// Schaltet bei Betätigen der Einfügen-Taste den
Schreibmodus um und
// sorgt im Überschreibmodus für die korrekte
Behandlung der Zurück-Taste
void
COverEditView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT
nFlags)
{
int nStartPos, nEndPos;
if
((nChar == VK_INSERT) && !(GetKeyState(VK_CONTROL)
>> 15) && !(GetKeyState(VK_SHIFT) >>
15))
{
// Schreibmodus
umschalten
m_bOverwrite
= !m_bOverwrite;
if
(m_bOverwrite)
// Markierung
setzen
CheckSelection(WM_KEYDOWN,
nChar, MAKELPARAM(nRepCnt, nFlags));
else
{
// Wenn ein
Zeichen selektiert ist, Markierung aufheben
GetEditCtrl().GetSel(nStartPos,
nEndPos);
if
(nEndPos - nStartPos == 1)
GetEditCtrl().SetSel(nStartPos,
nStartPos);
}
#if
!defined(NOPARENTNOTIFY)
// Das
Mutterfenster über den neuen Schreibmodus
benachrichtigen
#if defined(WIN32)
GetParent()->SendMessage(WM_COMMAND,
MAKEWPARAM(GetDlgCtrlID(), m_bOverwrite ? OWN_OVERWRITE :
OWN_INSERT), (LPARAM)m_hWnd);
#else
GetParent()->SendMessage(WM_COMMAND,
GetDlgCtrlID(), MAKELPARAM(m_hWnd, m_bOverwrite ?
OWN_OVERWRITE : OWN_INSERT));
#endif
#endif
}
if
(m_bOverwrite)
{
if (nChar == VK_BACK)
{
// Bei Betätigen
der Rücktaste nicht das selektierte Zeichen löschen,
// sondern das
Zeichen davor!
GetEditCtrl().GetSel(nStartPos,
nEndPos);
if
(nEndPos - nStartPos == 1)
{
if
(nStartPos)
{
CString
strSelText;
GetSubText(strSelText,
nStartPos - 1, nStartPos);
if
(strSelText == '\n') /* LF */
// CR und LF müssen
zusammen selektiert werden
GetEditCtrl().SetSel(nStartPos
- 2, nStartPos);
else
GetEditCtrl().SetSel(nStartPos
- 1, nStartPos);
}
else
{
// Am Textanfang
gibt es nichts zu löschen
GetEditCtrl().SetSel(nStartPos,
nStartPos);
return;
}
}
}
if
(GetKeyState(VK_SHIFT) >> 15 && (nChar ==
VK_END || nChar == VK_DOWN || nChar == VK_NEXT || (nChar
== VK_RIGHT && GetKeyState(VK_CONTROL) >>
15)))
{
GetEditCtrl().GetSel(nStartPos,
nEndPos);
if
(nEndPos - nStartPos == 1)
GetEditCtrl().SetSel(nStartPos,
nStartPos);
}
}
CEditView::OnKeyDown(nChar,
nRepCnt, nFlags);
if
(m_bOverwrite)
CheckSelection(WM_KEYDOWN,
nChar, MAKELPARAM(nRepCnt, nFlags));
}
//////////////////////////////////////////////////////////////////////////
// Setzt den Schreibmodus
LRESULT
COverEditView::OnSetOverwrite(WPARAM Overwrite, LPARAM)
{
return (LRESULT)SetOverwriteMode((BOOL)Overwrite);
}
//////////////////////////////////////////////////////////////////////////
// Aktualisierung der Statuszeile bei Wechsel des Überschreibmodus
void
COverEditView::OnUpdateIndicatorOvr(CCmdUI* pCmdUI)
{
pCmdUI->Enable(m_bOverwrite);
}
//////////////////////////////////////////////////////////////////////////
// COverEditView diagnostics
#ifdef
_DEBUG
void COverEditView::AssertValid() const
{
CEditView::AssertValid();
}
void
COverEditView::Dump(CDumpContext& dc) const
{
CEditView::Dump(dc);
dc
<< "\nm_bOverwrite = " <<
m_bOverwrite << "\n";
}
#endif
//_DEBUG
//////////////////////////////////////////////////////////////////////////
[ overedit.h ]
[ overedit.cpp ]
[ <<
Letzter ] [ Übersicht ]
[ Nächster
>> ]
|