ホーム ATL/WTL
リッチエディット
ドキュメント種別 ATL/WTL に関する文書
最終更新日 2004/10/02
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内
// リッチエディットコントロールのバージョン1.0を使用することを定義
#define _RICHEDIT_VER  0x0100

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

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

// maindlg.h内
class CMainDlg : public CDialogImpl<CMainDlg>
{
public:
    enum { IDD = IDD_MAINDLG };

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

    // メッセージマップ
    BEGIN_MSG_MAP_EX(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()

    LRESULT OnInitDialog(HWND hWnd, LPARAM lParam){
        // スクリーンの中央に配置
        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(HWND hWnd, CPoint pt){
        // [Shift]+[F10]キーが押された場合は座標を選択文字列の最後に設定
        if(pt.x == -1 && pt.y == -1){
            LONG start, end;
            m_rich_emphasis.GetSel(start, end);
            pt = m_rich_emphasis.PosFromChar(end);
            m_rich_emphasis.ClientToScreen(&pt);
        }

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

    void OnMenuDefault(UINT uNotifyCode, int nID, HWND hWndCtl){
        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, HWND hWndCtl){
        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, HWND hWndCtl){
        EndDialog(nID);
    }

    void OnCancel(UINT uNotifyCode, int nID, HWND hWndCtl){
        EndDialog(nID);
    }
};
			

// Control.cpp内
#include "stdafx.h"

#include "resource.h"

#include "maindlg.h"

CAppModule _Module;

int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE, LPTSTR lpCmdLine, 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_COOL_CLASSES | ICC_WIN95_CLASSES);

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

    int nRet = 0;
    // BLOCK: アプリケーション実行
    {
        CMainDlg dlgMain;
        nRet = dlgMain.DoModal();
    }

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

    FreeLibrary(hRich);

    return nRet;
}
			

 まず、リソースを作成します。ダイアログにリッチエディットコントロールを配置し、 リソースIDを次のように指定します。 なお、リッチエディットコントロールの[スタイル]ではデフォルトに加え[複数行]、 [水平スクロールバー]、[垂直スクロールバー]、[垂直オートスクロール]、 [改行を許可]にチェックを入れます。

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

さらに、ポップアップメニューのためのメニューリソースをプロジェクトに追加します。 メニューリソースのIDはIDR_MENU_POPUPとし、トップレベルに[index0]を、 その下に[デフォルトスタイルに戻す]メニューアイテムと[強調スタイルにする]メニューアイテムを追加します。 アイテムにはそれぞれID_MENUITEM_DEFAULTID_MENUITEM_EMPHASISというIDを設定します。



 次に、stdafx.h内では、CRichEditCtrlクラスを使用するためにatlctrls.hヘッダをインクルードします。 また、今回の例ではバージョン1.0のリッチエディットコントロールを使用するので、 _RICHEDIT_VER を 0x0100 に定義します。 なお、これはAppWizardを使用するとデフォルトで定義されています。

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

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

 次に、ポップアップメニューのアイテムを選択したときのコマンドメッセージハンドラを追加します。 [デフォルトスタイルに戻す](ID:ID_MENUITEM_DEFAULT)のコマンドメッセージハンドラOnMenuDefault()では、 GetDefaultCharFormat()によってデフォルトの文字フォーマットを取得して、 SetSelectionCharFormat()によって選択部分にそのフォーマットを適用しています。

[強調スタイルにする](ID:ID_MENUITEM_EMPHASIS)のコマンドメッセージハンドラOnMenuEmphasis()では、 赤い太字を表示するためのCHARFORMAT構造体を作成し、 SetSelectionCharFormat()によって選択部分にそのフォーマットを適用しています。

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

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