Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » FAQ VC++ / MFC » CFindReplaceDialog

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 <
000
18.01.2003, 14:49 Uhr
Uwe
C/C++ Master
(Administrator)


Erstellt von Uwe

Bei den Standarddialogen (Dialogfeldern) ist der CFindReplaceDialog implementiert. Dieser Dialog sammelt jedoch nur die Benutzereingaben. Den eigentlichen Suchen- und Ersetzenvorgang muß man jedoch selbst programmieren. Das folgende Beispiel soll als kleine Hilfe dienen. Etwas wichtiges gleich zu Anfang der Erläuterungen. CFindReplaceDialog ist ein nichtmodaler Dialog. Er bleibt am Monitor angezeigt während der User andere Vorgänge tätigt. Wir können somit keine lokale Variable nutzen (welche ja nur innerhalb der Nachrichtenbehandlungsroutine Gültigkeit hat), wir benötigen hierfür eine Zeigervariable.
Als erstes legen wir ein neues Projekt mit dem Namen FindReplace an. Als Art der Anwendung wählen wir Einzelnes Dokument (SDI). Bis zum Schritt 6 von 6 übernehmen wir die Standardeinstellungen. Hier nun aktivieren wir als Basisklasse "CEditView" und lassen unser Projekt erstellen. Nun legen wir im Header der Ansichtsklasse unsere Zeigervariable fest.

C++:
.......
.......// Implementierung
public:
    afx_msg LONG OnFindReplace(WPARAM  wParam, LPARAM lParam);
        virtual ~CFindReplaceView();
#ifdef _DEBUG
        virtual void AssertValid() const;
        virtual void Dump(CDumpContext& dc) const;
#endif

private:
    // Unser Eintrag Anfang

        CFindReplaceDialog * m_pFindReplace;

  // Unser Eintrag Ende
protected:

// Generierte Message-Map-Funktionen
protected:
    //{{AFX_MSG(CFindReplaceView)
    afx_msg void OnBearbeitenSuchenersetzen();
    //}}AFX_MSG
    DECLARE_MESSAGE_MAP()
};


Weiterhin muß der Zeiger auf NULL gesetzt werden. Im Konstruktor schreiben wir.

C++:
CFindReplaceView::CFindReplaceView()
{
    // ZU ERLEDIGEN: Hier Code zur Konstruktion einfügen,

    // Unser Eintrag Anfang

    m_pFindReplace=NULL;

    // Unser Eintrag Ende
}


Jetzt fügen wir einen neuen Menübefehl unter Bearbeiten mit dem Eintrag Suchen Erseten ein. Mit dem Klassenassistenten legen wir eine Nachrichtenbehandlungsroutine an und erzeugen unser Objekt.

C++:
/////////////////////////////////////////////////////////////////////////////
// CFindReplaceView Nachrichten-Handler

void CFindReplaceView::OnBearbeitenSuchenersetzen()
{
    // TODO: Code für Befehlsbehandlungsroutine hier einfügen

    // Unser Eintrag Anfang

    if(!m_pFindReplace)
    {
        m_pFindReplace=new CFindReplaceDialog;
        m_pFindReplace->Create(TRUE,"",NULL,FR_DOWN |FR_HIDEWHOLEWORD,this);
    }

    // Unser Eintrag Ende
}


Das Neuerstellen des Objektes erfolgt nur, wenn m_pFindReplace den Wert NULL hat.
Der erste Parameter von Create() ist übrigens dafür verantwortlich ob der Suchen oder Suchen- Ersetzen- Dialog angezeigt wird. Beim zweiten kann eine Voreinstellung für die Suchkette getroffen werden. Der vierte legt das Erscheinungsbild des Dialoges fest (näheres dazu in der MSDN oder per Mail. Der letzte ist ein Zeiger auf das übergeordnete Fenster. Achtung! Der Dialog darf nicht mit delete gelöscht werden. Dieser Dialog löscht sich selbst. Als nächstes sollten wir uns daran machen, eine Nachricht an die Ansichtsklasse vom Typ FINDMSGSTRING zu schicken, da der Dialog ja nicht geschlossen wird, aber trotzdem "suchen" soll. Mit

C++:
UINT WM_FINDREPLACE = RegisterWindowMessage(FINDMSGSTRING);


definieren wir eine neue Windows-Nachricht. Diese fügen wir in der FindReplaceView.cpp ein.

C++:
// FindReplaceView.cpp : Implementierung der Klasse CFindReplaceView
//

#include "stdafx.h"
#include "FindReplace.h"

#include "FindReplaceDoc.h"
#include "FindReplaceView.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

// Unser Eintrag Anfang

UINT WM_FINDREPLACE=RegisterWindowMessage(FINDMSGSTRING);

// Unser Eintrag Ende

/////////////////////////////////////////////////////////////////////////////
// CFindReplaceView

IMPLEMENT_DYNCREATE(CFindReplaceView, CEditView)


Nun sollte das Makro On_REGISTERED_MESSAGE verwendet werden um unsere Nachricht bereitzustellen.

C++:
....
....
UINT WM_FINDREPLACE=RegisterWindowMessage(FINDMSGSTRING);
/////////////////////////////////////////////////////////////////////////////
// CFindReplaceView

IMPLEMENT_DYNCREATE(CFindReplaceView, CEditView)

BEGIN_MESSAGE_MAP(CFindReplaceView, CEditView)
    //{{AFX_MSG_MAP(CFindReplaceView)
    ON_COMMAND(ID_BEARBEITEN_SUCHENERSETZEN, OnBearbeitenSuchenersetzen)
    //}}AFX_MSG_MAP
    // Standard-Druckbefehle
    ON_COMMAND(ID_FILE_PRINT, CEditView::OnFilePrint)
    ON_COMMAND(ID_FILE_PRINT_DIRECT, CEditView::OnFilePrint)
    ON_COMMAND(ID_FILE_PRINT_PREVIEW, CEditView::OnFilePrintPreview)

    // Unser Eintrag Anfang

    ON_REGISTERED_MESSAGE(WM_FINDREPLACE,OnFindReplace)

    // Unser Eintrag Ende
END_MESSAGE_MAP()
....
....


Wie wir sehen, wird die Nachricht mit einer Funktion OnFindReplace in Zusammenhang gebracht, welche wir noch schreiben müssen. In der Ansichtsklasse fügen wir mit dem Assistenten oder per Hand folgendes ein:

C++:
....
....
    // Überladungen
    // Vom Klassenassistenten generierte Überladungen virtueller Funktionen
    //{{AFX_VIRTUAL(CFindReplaceView)
    public:
    virtual void OnDraw(CDC* pDC);  // überladen zum Zeichnen dieser Ansicht
    virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
    protected:
    virtual BOOL OnPreparePrinting(CPrintInfo* pInfo);
    virtual void OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo);
    virtual void OnEndPrinting(CDC* pDC, CPrintInfo* pInfo);
    //}}AFX_VIRTUAL

// Implementierung
public:
  // Unser Eintrag Anfang

    afx_msg LONG OnFindReplace(WPARAM  wParam, LPARAM lParam);

  // Unser Eintrag Ende

    virtual ~CFindReplaceView();
#ifdef _DEBUG
    virtual void AssertValid() const;
    virtual void Dump(CDumpContext& dc) const;
#endif

private:
....
....


Wurde mit dem Assistenten gearbeitet wurde der Funktionsrumpf bereits angelegt, wenn nicht müssen wir dies per Hand erledigen und schreiben wie folgt:

C++:
LONG CFindReplaceView::OnFindReplace(WPARAM wParam, LPARAM lParam)
{
    if (m_pFindReplace->IsTerminating())
    {
       m_pFindReplace = NULL;
    }

    else if (m_pFindReplace->FindNext())
    {
       OnFindNext(m_pFindReplace->GetFindString(),
       m_pFindReplace->SearchDown(),
       m_pFindReplace->MatchCase());
    }

    else if (m_pFindReplace->ReplaceAll())
    {
       OnReplaceAll(m_pFindReplace->GetFindString(),
       m_pFindReplace->GetReplaceString(),
       m_pFindReplace->MatchCase());
    }

    else if (m_pFindReplace->ReplaceCurrent())
    {
       OnReplaceSel(m_pFindReplace->GetFindString(),
       m_pFindReplace->SearchDown(),
       m_pFindReplace->MatchCase(),
       m_pFindReplace->GetReplaceString());
    }

    return 0;
}


Die beiden letzten Blöcke sind natürlich bei einem reinem Suchen - Dialog nicht notwendig.
Das Beispiel steht als Projekt für VC++ im Downloadbereich zur Verfügung.
--
"Es ist schwierig, ein Programm wirklich idiotensicher zu machen, weil Idioten so genial sind."

Bis dann...
Uwe

Dieser Post wurde am 18.01.2003 um 14:50 Uhr von Uwe editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 <     [ FAQ VC++ / MFC ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: