検索置換ダイアログ


サンプル・プログラムのダイアログクラスのソースです。

// finddlgsapDlg.cpp : インプリメンテーション ファイル
//

#include "stdafx.h"
#include "finddlgsap.h"
#include "finddlgsapDlg.h"

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

/////////////////////////////////////////////////////////////////////////////
// アプリケーションのバージョン情報で使われている CAboutDlg ダイアログ

class CAboutDlg : public CDialog
{
public:
	CAboutDlg();

// ダイアログ データ
	//{{AFX_DATA(CAboutDlg)
	enum { IDD = IDD_ABOUTBOX };
	//}}AFX_DATA

	// ClassWizard は仮想関数のオーバーライドを生成します
	//{{AFX_VIRTUAL(CAboutDlg)
	protected:
	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV のサポート
	//}}AFX_VIRTUAL

// インプリメンテーション
protected:
	//{{AFX_MSG(CAboutDlg)
	//}}AFX_MSG
	DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
	//{{AFX_DATA_INIT(CAboutDlg)
	//}}AFX_DATA_INIT
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CAboutDlg)
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
	//{{AFX_MSG_MAP(CAboutDlg)
		// メッセージ ハンドラがありません。
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CFinddlgsapDlg ダイアログ

CFinddlgsapDlg::CFinddlgsapDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CFinddlgsapDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(CFinddlgsapDlg)
	m_text1 = _T("");
	//}}AFX_DATA_INIT
	// メモ: LoadIcon は Win32 の DestroyIcon のサブシーケンスを要求しません。
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CFinddlgsapDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CFinddlgsapDlg)
	DDX_Control(pDX, IDC_EDIT1, m_edit1);
	DDX_Text(pDX, IDC_EDIT1, m_text1);
	//}}AFX_DATA_MAP
}

//検索ダイアログ用(追加コード)
static UINT WM_FINDREPLACE = ::RegisterWindowMessage( FINDMSGSTRING );

BEGIN_MESSAGE_MAP(CFinddlgsapDlg, CDialog)
	//{{AFX_MSG_MAP(CFinddlgsapDlg)
	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_BN_CLICKED(IDC_BUTTON1, OnButton1)
	ON_BN_CLICKED(IDC_BUTTON2, OnButton2)
	//}}AFX_MSG_MAP

	//検索ダイアログ用のメッセージ(追加コード)
	ON_REGISTERED_MESSAGE(WM_FINDREPLACE, OnFindReplace)

END_MESSAGE_MAP()

//検索ダイアログ用の初期化処理
CFindReplaceDialog* myDLGSAVE = NULL;
int myDLGTYP = 0;

/////////////////////////////////////////////////////////////////////////////
// CFinddlgsapDlg メッセージ ハンドラ

BOOL CFinddlgsapDlg::OnInitDialog()
{
	CDialog::OnInitDialog();

	// "バージョン情報..." メニュー項目をシステム メニューへ追加します。

	// IDM_ABOUTBOX はコマンド メニューの範囲でなければなりません。
	ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
	ASSERT(IDM_ABOUTBOX < 0xF000);

	CMenu* pSysMenu = GetSystemMenu(FALSE);
	if (pSysMenu != NULL)
	{
		CString strAboutMenu;
		strAboutMenu.LoadString(IDS_ABOUTBOX);
		if (!strAboutMenu.IsEmpty())
		{
			pSysMenu->AppendMenu(MF_SEPARATOR);
			pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
		}
	}

	// このダイアログ用のアイコンを設定します。フレームワークはアプリケーションのメイン
	// ウィンドウがダイアログでない時は自動的に設定しません。
	SetIcon(m_hIcon, TRUE);			// 大きいアイコンを設定
	SetIcon(m_hIcon, FALSE);		// 小さいアイコンを設定
	
	// TODO: 特別な初期化を行う時はこの場所に追加してください。
	
	return TRUE;  // TRUE を返すとコントロールに設定したフォーカスは失われません。
}

void CFinddlgsapDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
	if ((nID & 0xFFF0) == IDM_ABOUTBOX)
	{
		CAboutDlg dlgAbout;
		dlgAbout.DoModal();
	}
	else
	{
		CDialog::OnSysCommand(nID, lParam);
	}
}

// もしダイアログボックスに最小化ボタンを追加するならば、アイコンを描画する
// コードを以下に記述する必要があります。MFC アプリケーションは document/view
// モデルを使っているので、この処理はフレームワークにより自動的に処理されます。

void CFinddlgsapDlg::OnPaint() 
{
	if (IsIconic())
	{
		CPaintDC dc(this); // 描画用のデバイス コンテキスト

		SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);

		// クライアントの矩形領域内の中央
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;

		// アイコンを描画します。
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialog::OnPaint();
	}
}

// システムは、ユーザーが最小化ウィンドウをドラッグしている間、
// カーソルを表示するためにここを呼び出します。
HCURSOR CFinddlgsapDlg::OnQueryDragIcon()
{
	return (HCURSOR) m_hIcon;
}

//-----------------------------
//検索ダイアログを開く
void CFinddlgsapDlg::OnButton1() 
{
	if(myDLGTYP == 1) return;
	if(myDLGTYP == 2) myDLGSAVE->DestroyWindow();	//置換ダイアログを消す
	
	m_edit1.GetWindowText(m_text1);		//m_text1にデータを格納

	UpdateData(FALSE);

	CFindReplaceDialog* myDLG = new CFindReplaceDialog;

	//ダイアログが起動していない時の処置
	if(myDLG->GetSafeHwnd() == NULL){
		myDLG->Create(TRUE, "", "");	//ダイアログボックスの起動	
		myDLGSAVE = myDLG;				//ポインタの退避
		myDLGTYP = 1;					//種別
	}
}

//--------------------------------
//置換ダイアログを開く
void CFinddlgsapDlg::OnButton2() 
{
	if(myDLGTYP == 2) return;
	if(myDLGTYP == 1) myDLGSAVE->DestroyWindow();	//置換ダイアログを消す
	
	m_edit1.GetWindowText(m_text1);		//m_text1にデータを格納

	UpdateData(FALSE);

	CFindReplaceDialog* myDLG = new CFindReplaceDialog;

	//ダイアログが起動していない時の処置
	if(myDLG->GetSafeHwnd() == NULL){
		myDLG->Create(FALSE, "", "");	//ダイアログボックスの起動	
		myDLGSAVE = myDLG;				//ポインタの退避
		myDLGTYP = 2;					//種別
	}
}

//---------------------------------------------------------------
//開かれた検索ダイアログを操作
LONG CFinddlgsapDlg::OnFindReplace(WPARAM wParam, LPARAM lParam)
{
	CString wkss,str1,str2;
	int StPos,EdPos,savePos1,savePos2,len1,NewPos,nn;

	CFindReplaceDialog* myDLG = CFindReplaceDialog::GetNotifier(lParam);
	UpdateData();
	if(myDLG->IsTerminating()){
		//-------------------
		//閉じた時の処理
		myDLG->DestroyWindow();
		myDLGSAVE = NULL;
		myDLGTYP = 0;
	}
	else if(myDLG->FindNext()){
		//----------------------
		//「次を検索」処理
		m_edit1.GetSel(StPos,EdPos);				//現在のカーソル位置取得
		str1 = myDLG->GetFindString();				//検索文字列の取得
		len1 = str1.GetLength();					
		wkss = m_text1.Mid(StPos + 1);
		NewPos = wkss.Find(str1);					//文字列検索
		if(NewPos != -1){
			StPos = StPos + 1 + NewPos;
			m_edit1.SetSel(StPos, StPos + len1);

		}
		UpdateData(FALSE);
	}
	else if(myDLG->ReplaceCurrent()){
		//-------------------------
		//「置換して次ぎへ」処理
		savePos1 = savePos2 = -1;
		m_edit1.GetSel(StPos,EdPos);				//現在のカーソル位置取得
		str1 = myDLG->GetFindString();				//検索文字列の取得
		str2 = myDLG->GetReplaceString();			//置換文字列の取得
		len1 = str1.GetLength();					
		wkss = m_text1.Mid(StPos,len1);
		if(wkss == str1){
			m_edit1.ReplaceSel(str2);
			UpdateData();
			savePos1 = StPos;
			savePos2 = StPos + str2.GetLength();
			StPos = savePos2 - 1;
		}
		wkss = m_text1.Mid(StPos + 1);
		NewPos = wkss.Find(str1);
		if(NewPos != -1){
			StPos = StPos + 1 + NewPos;
			m_edit1.SetSel(StPos, StPos + len1);
		}
		else{
			if(savePos1 != -1){
				m_edit1.SetSel(savePos1,savePos1);
			}
			UpdateData(FALSE);
		}
	}
	else if(myDLG->ReplaceAll()){
		//----------------------
		//「全て置換」処理
		str1 = myDLG->GetFindString();					//検索文字列の取得
		str2 = myDLG->GetReplaceString();				//置換文字列の取得
		len1 = str1.GetLength();
		while((nn = m_text1.Find(str1)) != -1){			//m_text1の検索
			m_edit1.SetSel(nn,nn + len1);
			m_edit1.ReplaceSel(str2);					//置換
			UpdateData();
		}
	}
	return 1L;
}