SitemapInfoHomeTips und Tricks - Überschreibmodus

Homepage

Software,
Download

Software-
entwicklung

  Tips und Tricks

Nachrichten-
technik

Internet

Aktuelles,
Sonstiges

Infos,
Kontakt

Sitemap


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

TopHomepage » Softwareentwicklung » Tips und Tricks » Überschreibmodus