INI 編集ツール IniModifier を作成してみる (3)
過去の記事へのリンク:
INI 編集ツール IniModifier を作成してみる (1)
INI 編集ツール IniModifier を作成してみる (2)
まずは、WTL::CRichEditCtrl のヘッダを見てみることにする。
WTL は SDK のラッパであり、MFC とほぼ同機能のメソッドを持っているので迷ったら、MSDN で MFC と SDK のヘルプを見るのが常套手段。
WTL::CRichEditCtrl
// WTL::CRichEditCtrl (CRichEditCtrlT<ATL::CWindow>) の宣言
// Constructors
CRichEditCtrl( HWND hWnd = NULL );
CRichEditCtrl& operator =( HWND hWnd );
HWND Create( HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL,
DWORD dwStyle = 0, DWORD dwExStyle = 0,
ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL );
// Attributes
static LPCTSTR GetWndClassName();
static LPCTSTR GetLibraryName();
int GetLineCount() const;
BOOL GetModify() const;
void SetModify( BOOL bModified = TRUE );
void GetRect( LPRECT lpRect ) const;
DWORD GetOptions() const;
DWORD SetOptions( WORD wOperation, DWORD dwOptions );
// NOTE: first word in lpszBuffer must contain the size of the buffer!
int GetLine( int nIndex, LPTSTR lpszBuffer ) const;
int GetLine( int nIndex, LPTSTR lpszBuffer, int nMaxLength ) const;
BOOL CanUndo() const;
BOOL CanPaste( UINT nFormat = 0 ) const;
void GetSel( LONG& nStartChar, LONG& nEndChar ) const;
void GetSel( CHARRANGE &cr ) const;
int SetSel( LONG nStartChar, LONG nEndChar );
int SetSel( CHARRANGE &cr );
int SetSelAll();
int SetSelNone();
DWORD GetDefaultCharFormat( CHARFORMAT& cf ) const;
DWORD GetSelectionCharFormat( CHARFORMAT& cf ) const;
DWORD GetEventMask() const;
LONG GetLimitText() const;
DWORD GetParaFormat( PARAFORMAT& pf ) const;
#if ( _RICHEDIT_VER >= 0x0200 )
LONG GetSelText( LPTSTR lpstrBuff ) const;
#else
// RichEdit 1.0 EM_GETSELTEXT is ANSI only
LONG GetSelText( LPSTR lpstrBuff ) const;
#endif
#ifndef _ATL_NO_COM
BOOL GetSelTextBSTR( BSTR& bstrText ) const;
#endif
#if defined( _WTL_USE_CSTRING ) || defined( __ATLSTR_H__ )
LONG GetSelText( _CSTRING_NS::CString& strText ) const;
#endif
WORD GetSelectionType() const;
COLORREF SetBackgroundColor( COLORREF cr );
COLORREF SetBackgroundColor(); // sets to system background
BOOL SetCharFormat( CHARFORMAT& cf, WORD wFlags );
BOOL SetDefaultCharFormat( CHARFORMAT& cf );
BOOL SetSelectionCharFormat( CHARFORMAT& cf );
BOOL SetWordCharFormat( CHARFORMAT& cf );
DWORD SetEventMask( DWORD dwEventMask );
BOOL SetParaFormat( PARAFORMAT& pf );
BOOL SetTargetDevice( HDC hDC, int cxLineWidth );
int GetTextLength() const;
BOOL SetReadOnly( BOOL bReadOnly = TRUE );
int GetFirstVisibleLine() const;
EDITWORDBREAKPROCEX GetWordBreakProcEx() const;
EDITWORDBREAKPROCEX SetWordBreakProcEx( EDITWORDBREAKPROCEX pfnEditWordBreakProcEx );
int GetTextRange( TEXTRANGE* pTextRange ) const;
#if ( _RICHEDIT_VER >= 0x0200 )
int GetTextRange( LONG nStartChar, LONG nEndChar, LPTSTR lpstrText ) const;
#else
int GetTextRange( LONG nStartChar, LONG nEndChar, LPSTR lpstrText ) const;
#endif
#if ( _RICHEDIT_VER >= 0x0200 )
DWORD GetDefaultCharFormat( CHARFORMAT2& cf ) const;
BOOL SetCharFormat( CHARFORMAT2& cf, WORD wFlags );
BOOL SetDefaultCharFormat( CHARFORMAT2& cf );
DWORD GetSelectionCharFormat( CHARFORMAT2& cf ) const;
BOOL SetSelectionCharFormat( CHARFORMAT2& cf );
BOOL SetWordCharFormat( CHARFORMAT2& cf );
DWORD GetParaFormat( PARAFORMAT2& pf ) const;
BOOL SetParaFormat( PARAFORMAT2& pf );
TEXTMODE GetTextMode() const;
BOOL SetTextMode( TEXTMODE enumTextMode );
UNDONAMEID GetUndoName() const;
UNDONAMEID GetRedoName() const;
BOOL CanRedo() const;
BOOL GetAutoURLDetect() const;
BOOL SetAutoURLDetect( BOOL bAutoDetect = TRUE );
// this method is deprecated, please use SetAutoURLDetect
BOOL EnableAutoURLDetect( BOOL bEnable = TRUE );
UINT SetUndoLimit( UINT uUndoLimit );
void SetPalette( HPALETTE hPalette );
int GetTextEx( GETTEXTEX* pGetTextEx, LPTSTR lpstrText ) const;
int GetTextEx( LPTSTR lpstrText, int nTextLen, DWORD dwFlags = GT_DEFAULT, UINT uCodePage = CP_ACP, LPCSTR lpDefaultChar = NULL, LPBOOL lpUsedDefChar = NULL ) const;
int GetTextLengthEx( GETTEXTLENGTHEX* pGetTextLengthEx ) const;
int GetTextLengthEx( DWORD dwFlags = GTL_DEFAULT, UINT uCodePage = CP_ACP ) const;
#endif
#if ( _RICHEDIT_VER >= 0x0300 )
int SetTextEx( SETTEXTEX* pSetTextEx, LPCTSTR lpstrText );
int SetTextEx( LPCTSTR lpstrText, DWORD dwFlags = ST_DEFAULT, UINT uCodePage = CP_ACP );
int GetEditStyle() const;
int SetEditStyle( int nStyle, int nMask = -1 );
BOOL SetFontSize( int nFontSizeDelta );
void GetScrollPos( LPPOINT lpPoint ) const;
void SetScrollPos( LPPOINT lpPoint );
BOOL GetZoom( int& nNum, int& nDen ) const;
BOOL SetZoom( int nNum, int nDen );
BOOL SetZoomOff();
#endif
// Operations
void LimitText( LONG nChars = 0 );
int LineFromChar( LONG nIndex ) const;
POINT PosFromChar( LONG nChar ) const;
int CharFromPos( POINT pt ) const;
void EmptyUndoBuffer();
int LineIndex( int nLine = -1 ) const;
int LineLength( int nLine = -1 ) const;
BOOL LineScroll( int nLines, int nChars = 0 );
void ReplaceSel( LPCTSTR lpszNewText, BOOL bCanUndo = FALSE );
void SetRect( LPCRECT lpRect );
BOOL DisplayBand( LPRECT pDisplayRect );
LONG FindText( DWORD dwFlags, FINDTEXT& ft ) const;
LONG FindText( DWORD dwFlags, FINDTEXTEX& ft ) const;
LONG FormatRange( FORMATRANGE& fr, BOOL bDisplay = TRUE );
LONG FormatRange( FORMATRANGE* pFormatRange, BOOL bDisplay = TRUE );
void HideSelection( BOOL bHide = TRUE, BOOL bChangeStyle = FALSE );
void PasteSpecial( UINT uClipFormat, DWORD dwAspect = 0, HMETAFILE hMF = 0 );
void RequestResize();
LONG StreamIn( UINT uFormat, EDITSTREAM& es );
LONG StreamOut( UINT uFormat, EDITSTREAM& es );
DWORD FindWordBreak( int nCode, LONG nStartChar );
// Additional operations
void ScrollCaret();
int InsertText( long nInsertAfterChar, LPCTSTR lpstrText, BOOL bCanUndo = FALSE );
int AppendText( LPCTSTR lpstrText, BOOL bCanUndo = FALSE );
// Clipboard operations
BOOL Undo();
void Clear();
void Copy();
void Cut();
void Paste();
// OLE support
IRichEditOle* GetOleInterface() const;
BOOL SetOleCallback( IRichEditOleCallback* pCallback );
#if ( _RICHEDIT_VER >= 0x0200 )
BOOL Redo();
void StopGroupTyping();
void ShowScrollBar( int nBarType, BOOL bVisible = TRUE );
#endif
#if ( _RICHEDIT_VER >= 0x0300 )
BOOL SetTabStops( int nTabStops, LPINT rgTabStops );
BOOL SetTabStops();
BOOL SetTabStops( const int& cxEachStop ); // takes an 'int'
#endif
これで大体何ができるか分かった。
あとは、実際に使用しそうで使ったことがないメソッドについて詳しくみていくことにする。
GetLibraryName
リッチエディットコントロールを使用するには、最初にリッチエディットコントロールの DLL をロードしておかなければいけないらしい。
リッチエディットコントロールの DLL 名はバージョンによって異なるので(Ver1.0 は RICHED32.DLL で、Ver2.0 以降は RICHED20.DLL)、このメソッドを使うことでその違いを CRichEditCtrl がプリプロセス時点で解決してくれる。
// IniModifier.cpp
int WINAPI _tWinMain( HINSTANCE, HINSTANCE, LPTSTR, int )
{
HMODULE hRich = ::LoadLibrary( CRichEditCtrl::GetLibraryName() );
// snip
::FreeLibrary( hRich );
return nRet;
}
SetSelectionCharFormat
現在の選択のテキストの文字書式属性を設定する。
なお、選択範囲がない場合は、以降の入力についての設定となる。
// CRichEditCtrl m_rich;
// テキストを青色太字にして保護にする
CHARFORMAT cf;
cf.dwMask = CFM_PROTECTED | CFM_COLOR | CFM_BOLD;
cf.dwEffects = CFE_PROTECTED | CFE_BOLD;
cf.crTextColor = RGB( 0, 0, 255 );
m_rich.SetSelectionCharFormat( cf );
SetEventMask
親ウィンドウに送る通知メッセージを指定する。
- ENM_PROTECTED
- 保護領域を編集しようとした時に WM_NOTIFY メッセージで EN_PROTECTED が通知されるようにする。
0 を返すと変更許可、非0 を返すと変更禁止とする。
ENPROTECTED* pProtected = reinterpret_cast< ENPROTECTED* >( reinterpret_cast< LPNMHDR >( lParam ) );
としたとき、
pProtected->msg
に、この通知発生原因のメッセージ ID が入っている。
pProtected->chrg.cpMin
と pProtected->chrg.cpMax
に、この通知発生元のインデックス(リッチエディットコントロール先頭位置からのオフセット)が入っている。
- ENM_KEYEVENTS
- キーボードイベントが発生した時に WM_NOTIFY メッセージで EN_MSGFILTER が通知されるようにする。
0 を返すと通常のイベントを処理する。非0 を返すと以降のイベント処理を無視する。
MSGFILTER* pFilter = reinterpret_cast< MSGFILTER* >( reinterpret_cast< LPNMHDR >( lParam ) );
としたとき、
pFilter->msg
に、この通知発生原因のメッセージ ID が入っている。
- ENM_MOUSEEVENTS
- マウスイベントが発生した時に WM_NOTIFY メッセージで EN_MSGFILTER が通知されるようにする。
EN_MSGFILTER の動作については、ENM_KEYEVENTS と同じ。
m_rich.SetEventMask( ENM_PROTECTED | ENM_KEYEVENTS | ENM_MOUSEEVENTS );