ホーム ATL/WTL
リッチエディット
ドキュメント種別 ATL/WTL に関する文書
最終更新日 2007/03/21
PR
 WTLではコモンコントロールのリッチエディットコントロールをCRichEditCtrlT というクラステンプレートでカプセル化しています。 テンプレート引数にはクラスを指定しますが、 そのクラスはCRichEditCtrlTの基底クラスとして使用されます。 atlctrls.hヘッダではtypedefによって次のように宣言されています。

// atlctrls.h
typedef CRichEditCtrlT<ATL::CWindow>   CRichEditCtrl;
			

これは、CRichEditCtrlクラスはCWindowクラスの派生クラスであることを意味します。

 WTLのCRichEditCtrlクラスは、MFCの同名のクラスとほぼ同じメンバ関数を用意しているほか、 リッチエディットコントロールのバージョン2.0および3.0用のメンバ関数も備えています。 以下に示すのは、CRichEditCtrlクラスを使用する例です。 リッチエディットコントロール上で右クリックするとポップアップメニューが表示され、 [強調スタイルにする]を実行するとリッチエディットコントロール上の選択文字列が赤い太字になります。


プロジェクトファイル ダウンロード
// stdafx.h
#pragma once

#include <atlbase.h>
#include <atlapp.h>
extern CAppModule _Module;
#include <atlwin.h>

#include <atlcrack.h>
#include <atlmisc.h>
#include <atlctrls.h>  // コントロール用クラスを使用するため
			

// MainDlg.h
#pragma once

class CMainDlg : public CDialogImpl<CMainDlg>
{
public:
    enum { IDD = IDD_MAINDLG };

    CRichEditCtrl m_rich_emphasis;  // リッチエディット

    BEGIN_MSG_MAP(CMainDlg)
        MSG_WM_INITDIALOG(OnInitDialog)
        MSG_WM_CONTEXTMENU(OnContextMenu)
        COMMAND_ID_HANDLER_EX(ID_MENUITEM_DEFAULT, OnMenuDefault)
        COMMAND_ID_HANDLER_EX(ID_MENUITEM_EMPHASIS, OnMenuEmphasis)
        COMMAND_ID_HANDLER_EX(IDOK, OnOK)
        COMMAND_ID_HANDLER_EX(IDCANCEL, OnCancel)
    END_MSG_MAP()

    BOOL OnInitDialog(CWindow wndFocus, LPARAM lInitParam){
        // スクリーンの中央に配置
        CenterWindow();

        // 大きいアイコン設定
        HICON hIcon = AtlLoadIconImage(IDR_MAINFRAME, LR_DEFAULTCOLOR,
            ::GetSystemMetrics(SM_CXICON), ::GetSystemMetrics(SM_CYICON));
        SetIcon(hIcon, TRUE);
        
        // 小さいアイコン設定
        HICON hIconSmall = AtlLoadIconImage(IDR_MAINFRAME, LR_DEFAULTCOLOR,
            ::GetSystemMetrics(SM_CXSMICON), ::GetSystemMetrics(SM_CYSMICON));
        SetIcon(hIconSmall, FALSE);

        // コントロール設定
        m_rich_emphasis = GetDlgItem(IDC_RICHEDIT_EMPHASIS);

        return TRUE;
    }

    void OnContextMenu(CWindow wnd, CPoint point){
        // [Shift]+[F10]キーが押された場合は座標を選択文字列の最後に設定
        if(point.x == -1 && point.y == -1){
            LONG start, end;
            m_rich_emphasis.GetSel(start, end);
            point = m_rich_emphasis.PosFromChar(end);
            m_rich_emphasis.ClientToScreen(&point);
        }

        // 座標がリッチエディットコントロール内の場合のみポップアップメニューを表示
        CRect rc;
        m_rich_emphasis.GetClientRect(&rc);
        m_rich_emphasis.ClientToScreen(&rc);
        if(rc.PtInRect(point)){
            CMenu menuPopup;
            menuPopup.LoadMenu(IDR_MENU_POPUP);
            menuPopup.GetSubMenu(0).TrackPopupMenu(
                TPM_LEFTALIGN | TPM_TOPALIGN | TPM_LEFTBUTTON, 
                point.x, point.y, m_hWnd);
        }else{
            SetMsgHandled(false);
        }
    }

    void OnMenuDefault(UINT uNotifyCode, int nID, CWindow wndCtl){
        CString strText;
        if(m_rich_emphasis.GetSelText(strText) != 0){
            CHARFORMAT cf = {sizeof(CHARFORMAT)};
            m_rich_emphasis.GetDefaultCharFormat(cf);
            m_rich_emphasis.SetSelectionCharFormat(cf);
        }
    }

    void OnMenuEmphasis(UINT uNotifyCode, int nID, CWindow wndCtl){
        CString strText;
        if(m_rich_emphasis.GetSelText(strText) != 0){
            CHARFORMAT cf = {sizeof(CHARFORMAT)};
            cf.dwMask = CFM_COLOR | CFM_BOLD;
            cf.dwEffects = CFE_BOLD;
            cf.crTextColor = RGB(255, 0, 0);
            m_rich_emphasis.SetSelectionCharFormat(cf);
        }
    }

    void OnOK(UINT uNotifyCode, int nID, CWindow wndCtl){
        EndDialog(nID);
    }

    void OnCancel(UINT uNotifyCode, int nID, CWindow wndCtl){
        EndDialog(nID);
    }
};
			

// SampleProject.cpp
#include "stdafx.h"
#include "resource.h"
#include "MainDlg.h"

CAppModule _Module;

int WINAPI _tWinMain(HINSTANCE hInstance, 
    HINSTANCE /*hPrevInstance*/, LPTSTR /*lpstrCmdLine*/, int /*nCmdShow*/)
{
    // リッチエディットコントロール初期化
    HINSTANCE hRich = LoadLibrary(CRichEditCtrl::GetLibraryName());
    if(hRich == NULL){
        AtlMessageBox(NULL, _T("リッチエディットコントロール初期化失敗"),
            _T("エラー"), MB_OK | MB_ICONERROR);
        return 0;
    }

    HRESULT hRes = ::CoInitialize(NULL);
    ATLASSERT(SUCCEEDED(hRes));

    ::DefWindowProc(NULL, 0, 0, 0L);

    AtlInitCommonControls(ICC_BAR_CLASSES);

    hRes = _Module.Init(NULL, hInstance);
    ATLASSERT(SUCCEEDED(hRes));

    CMainDlg dlg;
    int nRet = (int) dlg.DoModal();

    _Module.Term();
    ::CoUninitialize();

    FreeLibrary(hRich);

    return nRet;
}
			

 まず、リソースを作成します。ダイアログにリッチエディットコントロールを配置し、 [ID]を次のように設定します。 なお、リッチエディットコントロールの[プロパティ]では[Auto VScroll]、 [Horizontal Scroll]、[Vertical Scroll]、[MultiLine]、[Want Return] を[True]に設定します。

コントロール名 ID
リッチエディット IDC_RICHEDIT_EMPHASIS

さらに、プロジェクトにポップアップメニュー用のメニューリソースを追加し、 [ID]、[Caption]、[Prompt]を次のように設定します。

リソース名 ID Caption Prompt
メニュー IDR_MENU_POPUP - -
メニューアイテム(トップレベル) - index0 -
メニューアイテム ID_MENUITEM_DEFAULT デフォルトスタイルに戻す(&D) 選択部分をデフォルトスタイルに戻す\nデフォルトスタイルに戻す
メニューアイテム ID_MENUITEM_EMPHASIS 強調スタイルにする(&E) 選択部分を強調スタイルにする\n強調スタイルにする



 次に、stdafx.hヘッダでは、CRichEditCtrlクラスを使用するためにatlctrls.hヘッダをインクルードします。

 CMainDlgクラスでは、 リッチエディットコントロール用にCRichEditCtrlクラスのインスタンスをメンバ変数として宣言します。 これを使うためには、WM_INITDIALOGメッセージハンドラでコントロールのハンドルを代入する必要があります。

 次に、WM_CONTEXTMENUメッセージハンドラを追加します。 ここでは座標がリッチエディットコントロール内かどうかを確認し、 ポップアップメニューを表示します。

 次に、リソースIDがID_MENUITEM_DEFAULTWM_COMMANDメッセージハンドラとしてOnMenuDefault()を追加します。 このハンドラ関数では、GetDefaultCharFormat()を呼び出してデフォルトの文字フォーマットを取得し、 SetSelectionCharFormat()を呼び出して選択部分にそのフォーマットを適用します。

 次に、リソースIDがID_MENUITEM_EMPHASISWM_COMMANDメッセージハンドラとしてOnMenuEmphasis()を追加します。 このハンドラ関数では、赤い太字を表示するためのCHARFORMAT構造体を作成し、 SetSelectionCharFormat()を呼び出して選択部分にそのフォーマットを適用します。

 最後に、_tWinMain()でリッチエディットコントロールを初期化します。 CRichEditCtrl::GetLibraryName()は、 _RICHEDIT_VERが0x0100の場合は_T("RICHED32.DLL")を返し、 0x0200以上の場合は_T("RICHED20.DLL")を返します。

 このように、リッチエディットコントロールを使用する場合は、 エディットコントロールのバージョンを_RICHEDIT_VERで定義し、 LoadLibrary()を呼び出して初期化をする必要があります。