=== sakura/sakura.vcproj ================================================================== --- sakura/sakura.vcproj (revision 69505) +++ sakura/sakura.vcproj (revision 69511) @@ -1,10 +1,11 @@ + + + + + + + + === sakura_core/Makefile ================================================================== --- sakura_core/Makefile (revision 69505) +++ sakura_core/Makefile (revision 69511) @@ -353,6 +353,7 @@ util/window.o \ view/CCaret.o \ view/CEditView.o \ +view/CEditView_AsWithHelpTooltip.o \ view/CEditView_Cmdgrep.o \ view/CEditView_CmdHokan.o \ view/CEditView_Cmdisrch.o \ === sakura_core/window/CTipWnd.h ================================================================== --- sakura_core/window/CTipWnd.h (revision 69505) +++ sakura_core/window/CTipWnd.h (revision 69511) @@ -22,63 +22,103 @@ #include "CWnd.h" #include "mem/CMemory.h" /*----------------------------------------------------------------------- -クラスの宣言 + クラスの宣言 -----------------------------------------------------------------------*/ -class CTipWnd : public CWnd +class CTipWnd : private CWnd { -public: - /* - || Constructors - */ - CTipWnd(); +public: // 初期化 + CTipWnd(); //!< デフォルトコンストラクタは意味のあるインスタンスを作らない。placement newで上書きして OK。 + CTipWnd( HINSTANCE, HWND ); //!< 意味のあるコンストラクタ。 ~CTipWnd(); - void Create( HINSTANCE, HWND ); /* 初期化 */ - /* - || Attributes & Operations - */ - void Show( int, int, const TCHAR*, RECT* pRect = NULL ); /* Tipを表示 */ - void Hide( void ); /* Tipを消す */ - void GetWindowSize(LPRECT pRect); // 2001/06/19 asa-o ウィンドウのサイズを得る +public: // プロパティ + void SetFont( const LOGFONT& lf ); + void SetText( const TCHAR* szText ); - void ChangeFont( LOGFONT* lf ){ - if ( m_hFont ){ - ::DeleteObject( m_hFont ); - } - m_hFont = ::CreateFontIndirect( lf ); - } + SIZE GetWindowSize() const; //cx = sz.cx; + out->cy = sz.cy; } - return; } +/* + class CTipWnd コンストラクタ +*/ -/* 初期化 */ -void CTipWnd::Create( HINSTANCE hInstance, HWND hwndParent ) +CTipWnd::CTipWnd() +: CWnd(_T("::CTipWnd")) +, m_hFont(NULL) +, m_Text() +, m_bShown( false ) +{} + +CTipWnd::CTipWnd( HINSTANCE hInstance, HWND hwndParent ) +: CWnd(_T("::CTipWnd")) +, m_hFont(NULL) +, m_Text() +, m_bShown( false ) { LPCTSTR pszClassName = _T("CTipWnd"); @@ -87,245 +131,27 @@ return; } -/*! CreateWindowの後 - - CWnd::AfterCreateWindowでウィンドウを表示するようになっているのを - 動かなくするための空関数 - - @date 2006.01.09 genta 新規作成 -*/ -void CTipWnd::AfterCreateWindow( void ) +// 2001/06/19 Start by asa-o: ウィンドウのサイズを得る +SIZE CTipWnd::GetWindowSize() const { + SIZE sz; + HDC hdc = GetDC( GetHwnd() ); + DrawTipText( hdc, m_hFont, m_Text.GetStringPtr(), &sz ); + ReleaseDC( GetHwnd(), hdc ); + sz.cx += 8; sz.cy += 8; + return sz; } -/* Tipを表示 */ -void CTipWnd::Show( int nX, int nY, const TCHAR* szText, RECT* pRect ) -{ - HDC hdc; - RECT rc; - - if( NULL != szText ){ - m_cInfo.SetString( szText ); - } - const TCHAR* pszInfo = m_cInfo.GetStringPtr(); - - hdc = ::GetDC( GetHwnd() ); - - // サイズを計算済み 2001/06/19 asa-o - if(pRect != NULL) - { - rc = *pRect; - } - else - { - /* ウィンドウのサイズを決める */ - ComputeWindowSize( hdc, m_hFont, pszInfo, &rc ); - } - - ::ReleaseDC( GetHwnd(), hdc ); - - if( m_bAlignLeft ){ - // 右側固定で表示(MiniMap) - ::MoveWindow( GetHwnd(), nX - rc.right, nY, rc.right + 8, rc.bottom + 8, TRUE ); - }else{ - // 左側固定で表示(通常) - ::MoveWindow( GetHwnd(), nX, nY, rc.right + 8, rc.bottom + 8/*nHeight*/, TRUE ); - } - ::InvalidateRect( GetHwnd(), NULL, TRUE ); - ::ShowWindow( GetHwnd(), SW_SHOWNA ); - return; - -} - -/* ウィンドウのサイズを決める */ -void CTipWnd::ComputeWindowSize( - HDC hdc, - HFONT hFont, - const TCHAR* pszText, - RECT* pRect -) -{ - int nTextLength; - int nCurMaxWidth; - int nCurHeight; - int nBgn; - RECT rc; - HFONT hFontOld; - int i; - int nCharChars; - - hFontOld = (HFONT)::SelectObject( hdc, hFont ); - - nCurMaxWidth = 0; - nCurHeight = 0; - nTextLength = _tcslen( pszText ); - nBgn = 0; - for( i = 0; i <= nTextLength; ++i ){ - // 2005-09-02 D.S.Koba GetSizeOfChar - nCharChars = CNativeT::GetSizeOfChar( pszText, nTextLength, i ); - if( ( 1 == nCharChars && _T('\\') == pszText[i] && _T('n') == pszText[i + 1]) || _T('\0') == pszText[i] ){ - if( 0 < i - nBgn ){ - TCHAR* pszWork = new TCHAR[i - nBgn + 1]; - auto_memcpy( pszWork, &pszText[nBgn], i - nBgn ); - pszWork[i - nBgn] = _T('\0'); - - rc.left = 0; - rc.top = 0; - rc.right = ::GetSystemMetrics( SM_CXSCREEN ); - rc.bottom = 0; - ::DrawText( hdc, pszWork, _tcslen(pszWork), &rc, - DT_CALCRECT | DT_EXTERNALLEADING | DT_EXPANDTABS | DT_WORDBREAK /*| DT_TABSTOP | (0x0000ff00 & ( 4 << 8 ))*/ - ); - delete [] pszWork; - if( nCurMaxWidth < rc.right ){ - nCurMaxWidth = rc.right; - } - }else{ - ::DrawText( hdc, _T(" "), 1, &rc, - DT_CALCRECT | DT_EXTERNALLEADING | DT_EXPANDTABS | DT_WORDBREAK /*| DT_TABSTOP | (0x0000ff00 & ( 4 << 8 ))*/ - ); - } - nCurHeight += rc.bottom; - - nBgn = i + 2; - } - if( 2 == nCharChars ){ - ++i; - } - } - - pRect->left = 0; - pRect->top = 0; - pRect->right = nCurMaxWidth + 4; - pRect->bottom = nCurHeight + 2; - - ::SelectObject( hdc, hFontOld ); - - return; - - -} - - -/* ウィンドウのテキストを表示 */ -void CTipWnd::DrawTipText( - HDC hdc, - HFONT hFont, - const TCHAR* pszText -) -{ - int nTextLength; - int nCurMaxWidth; - int nCurHeight; - int nBgn; - RECT rc; - HFONT hFontOld; - int i; - int nBkMode_Old; - COLORREF colText_Old; - int nCharChars; - - nBkMode_Old = ::SetBkMode( hdc, TRANSPARENT ); - hFontOld = (HFONT)::SelectObject( hdc, hFont ); - colText_Old = ::SetTextColor( hdc, ::GetSysColor( COLOR_INFOTEXT ) ); - - nCurMaxWidth = 0; - nCurHeight = 0; - nTextLength = _tcslen( pszText ); - nBgn = 0; - for( i = 0; i <= nTextLength; ++i ){ -// nCharChars = &pszText[i] - CMemory::MemCharPrev( pszText, nTextLength, &pszText[i] ); - // 2005-09-02 D.S.Koba GetSizeOfChar - nCharChars = CNativeT::GetSizeOfChar( pszText, nTextLength, i ); - if( ( 1 == nCharChars && _T('\\') == pszText[i] && _T('n') == pszText[i + 1]) || _T('\0') == pszText[i] ){ - if( 0 < i - nBgn ){ - TCHAR* pszWork; - pszWork = new TCHAR[i - nBgn + 1]; - auto_memcpy( pszWork, &pszText[nBgn], i - nBgn ); - pszWork[i - nBgn] = _T('\0'); - - rc.left = 4; - rc.top = 4 + nCurHeight; - rc.right = ::GetSystemMetrics( SM_CXSCREEN ); - rc.bottom = rc.top + 200; - nCurHeight += ::DrawText( hdc, pszWork, _tcslen(pszWork), &rc, - DT_EXTERNALLEADING | DT_EXPANDTABS | DT_WORDBREAK /*| DT_TABSTOP | (0x0000ff00 & ( 4 << 8 ))*/ - ); - delete [] pszWork; - if( nCurMaxWidth < rc.right ){ - nCurMaxWidth = rc.right; - } - }else{ - rc.left = 4; - rc.top = 4 + nCurHeight; - rc.right = ::GetSystemMetrics( SM_CXSCREEN ); - rc.bottom = rc.top + 200; - nCurHeight += ::DrawText( hdc, _T(" "), 1, &rc, - DT_EXTERNALLEADING | DT_EXPANDTABS | DT_WORDBREAK /*| DT_TABSTOP | (0x0000ff00 & ( 4 << 8 ))*/ - ); - } - - nBgn = i + 2; - } - if( 2 == nCharChars ){ - ++i; - } - } - - - ::SetTextColor( hdc, colText_Old ); - ::SelectObject( hdc, hFontOld ); - ::SetBkMode( hdc, nBkMode_Old ); - - return; - - -} - - - -/* Tipを消す */ -void CTipWnd::Hide( void ) -{ - ::ShowWindow( GetHwnd(), SW_HIDE ); -// ::DestroyWindow( GetHwnd() ); - return; -} - - - - -/* 描画処理 */ LRESULT CTipWnd::OnPaint( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM l_Param ) { - PAINTSTRUCT ps; - RECT rc; - HDC hdc = ::BeginPaint( hwnd, &ps ); - ::GetClientRect( hwnd, &rc ); - - /* ウィンドウのテキストを表示 */ - DrawTipText( hdc, m_hFont, m_cInfo.GetStringPtr() ); - - ::EndPaint( hwnd, &ps ); + PAINTSTRUCT ps; + HDC hdc = ::BeginPaint( hwnd, &ps ); + RECT rc; GetClientRect( hwnd, &rc ); + DrawTipText( hdc, m_hFont, m_Text.GetStringPtr() ); + EndPaint( hwnd, &ps ); return 0L; } - -// 2001/06/19 Start by asa-o: ウィンドウのサイズを得る -void CTipWnd::GetWindowSize(LPRECT pRect) -{ - const TCHAR* pszText; - - HDC hdc = ::GetDC( GetHwnd() ); - - pszText = m_cInfo.GetStringPtr(); - - // ウィンドウのサイズを得る - ComputeWindowSize( hdc, m_hFont, pszText , pRect ); - - ::ReleaseDC( GetHwnd(), hdc ); //2007.10.10 kobake ReleaseDCが抜けていたのを修正 -} - // 2001/06/19 End === sakura_core/view/CEditView_AsWithHelpTooltip.h ================================================================== --- sakura_core/view/CEditView_AsWithHelpTooltip.h (revision 69505) +++ sakura_core/view/CEditView_AsWithHelpTooltip.h (revision 69511) @@ -0,0 +1,197 @@ +#ifndef CEDITVIEW_ASWITHHELPTOOLTIP_H +#define CEDITVIEW_ASWITHHELPTOOLTIP_H + +#include "window/CTipWnd.h" + +/** AsXXX クラス群とは + * CEditViewの機能的一側面。 + * 1機能1クラス。 + * CEditViewに継承させて使用する。 + * CRTPパターン。 + * たくさんの AsXXXが CEditViewに継承されると名前が競合しや + すいので、パブリックメンバは説明的な名前にするのがいい。 +*/ + +template +class AsWithHelpTooltip +{ +public: // 型 + typedef struct KeywordHelpInfo { + int dicNo; //!< キーワードを含む辞書の番号。-1 でキーワードに該当するヘルプ辞書不在 + int dicLineNo; //!< 辞書内でキーワードを含む行の番号 + CNativeW content; //!< 辞書を元に組み立てたヘルプテキスト + + KeywordHelpInfo(): dicNo(-1), dicLineNo(-1), content(L"") {} + } KeywordHelpInfo; + typedef struct KeywordInfo { + KeywordHelpInfo help; //!< キーワードに関連するヘルプと辞書について + CNativeW keyword; //!< キーワード + POINT from, to; //!< キーワードの範囲。単位は CLayoutIntもしくは CLogicInt. + + KeywordInfo():help(), keyword(L""), from(), to() {} + } KeywordInfo; + typedef enum ShowTooltipFlags { + HIDE_ON_MOUSEMOVE = 1, //!< マウスが動いたときに自動的に隠すかどうか。falseなら ShowTooltipのあと HideTooltipを明示的に呼ぶ必要がある。 + TEXT_IS_KEYWORD = 2, //!< Textフィールドをキーワードとみなし、関連づけられたヘルプ(なければキーワードそのもの)を実際のツールチップテキストとする。 + DONT_SHOW_NONKEYWORD_TEXT = 4, //!< TEXT_IS_KEYWORDが指定されていたが Textが登録されたキーワードではなかったとき、キーワードそのものを内容とするツールチップは表示したくない。 + SHOW_LEFT = 8, //!< スペースに関わらず左に表示する。 + SHOW_RIGHT = 16, //!< スペースに関わらず右に表示する。 + SHOW_INVISIBLE = 32 //!< 他の全ての処理を行うが表示だけはしない。更新されたプロパティから情報を取得するためにある。 + } ShowTooltipFlags; + typedef struct ShowTooltipOptions { + int flags; //!< ShowTooltipFlagsの組み合わせ。 + POINT pos; //!< 表示位置。スクリーン座標系。 + CNativeW text; //!< ツールチップの内容。 + + ShowTooltipOptions(): flags(0), pos(), text(L"") {} + } ShowTooltipOptions; + +public: // イニシャライザ(CEditView::Create後)、デストラクタ + void Create(); + +public: // プロパティ + void SetTooltipFont( const LOGFONT& lf ); + + bool TooltipIsShown() const; //!< ツールチップを表示中かどうか。 + const TCHAR* GetTooltipText() const; //!< 最後のもしくは現在のツールチップの内容。ShowTooltipを呼び出す毎に更新される。 + SIZE GetTooltipSize() const; //!< 最後に表示した時点でのツールチップウィンドウのサイズ。ShowTooltipを呼び出す毎に更新される。 + int GetLastHitKeywordDictionary() const; //!< TEXT_IS_KEYWORDフラグが指定されていたときに使用した辞書のインデックス。使用しなかった場合キーワードが見つからなかったは -1. ShowTooltipを呼び出す毎に更新される。 + int GetLastHitKeywordLineNumber() const; //!< GetLastHitKeywordDictionary()の何行目がキーワードに該当するか。ShowTooltipを呼び出す毎に更新される。 + +public: // メソッド + KeywordHelpInfo BuildHelpAbout( const CNativeW& keyword ) const; + static CNativeW BuildLineHelpAbout( const View& view, CLayoutInt lineNo ); + KeywordInfo SearchKeywordAround( CLogicPoint pt ) const; + KeywordInfo SearchKeywordAround( CLayoutPoint pt ) const; + + ShowTooltipOptions BuildContextualHelp() const; //!< 今現在ツールチップとして表示するべき内容があればそれを得る。 + + bool ShowTooltip( const ShowTooltipOptions& options ); //!< ツールチップを表示する。 + void HideTooltip(); //!< 即座に隠す。表示してなくても隠す(嘘)。とりあえず呼んでおいて問題ない。 + +public: // コールバック +/* + 初期化中に適当なイベントに結びつけて呼ばれるようにできると + ツールチップを遅延表示したり、マウス移動・キャレット移動で + ツールチップを隠したりするのを自律的に行えるのだけど、 + さしあたっては CEditViewに呼んでもらうことでそれらを実現する。 +*/ + void OnTimer( DWORD dwTickCount ); + void OnMouseMove( int x, int y ); + +private: + CTipWnd m_cTipWnd; //!< キーワードヘルプ表示用ツールチップウィンドウ + ShowTooltipOptions m_LastOptions; //!< 最後の ShowTooltipの引数。 + POINT m_ptMouse0; //!< OnMouseMoveでマウス移動を検知するために位置を随時保存する。 + DWORD m_dwTime0; //!< 遅延表示のために OnTimerで経過時間を知るために随時保存する。 + CLayoutPoint m_ptCaretOnLastMouseMove; //!< ユーザーが最後に操作したときのキャレットの位置。マウスが最後に動いたときからキャレットが移動していたら、ユーザーの興味はマウスよりキーボードにあり、ツールチップを表示するのは適当でない。その判断材料。 + mutable struct { + int dicNo, dicLineNo; + CNativeW keyword; + } m_LastSearchCache; +}; + +template inline +void +AsWithHelpTooltip:: +SetTooltipFont( const LOGFONT& lf ) +{ + m_cTipWnd.SetFont( lf ); +} + +template inline +bool +AsWithHelpTooltip:: +TooltipIsShown() const +{ + return m_cTipWnd.IsShown(); +} + +template inline +const TCHAR* +AsWithHelpTooltip:: +GetTooltipText() const +{ + return m_cTipWnd.GetText(); +} + +template inline +SIZE +AsWithHelpTooltip:: +GetTooltipSize() const +{ + return m_cTipWnd.GetWindowSize(); +} + +template inline +int +AsWithHelpTooltip:: +GetLastHitKeywordDictionary() const +{ + return m_LastSearchCache.dicNo; +} + +template inline +int +AsWithHelpTooltip:: +GetLastHitKeywordLineNumber() const +{ + return m_LastSearchCache.dicLineNo; +} + +template inline +void +AsWithHelpTooltip:: +HideTooltip() +{ + m_cTipWnd.Hide(); + m_dwTime0 = GetTickCount(); +} + +template inline +void +AsWithHelpTooltip:: +OnTimer( DWORD dwTickCount ) +{ + if ( dwTickCount < m_dwTime0 + 300 ) { + return; // マウスが十分にじっとしていない。 + } + m_dwTime0 = GetTickCount(); // 遅延表示判定の起点をリセットして、しばらくは OnTimerを早抜けする。 + if ( TooltipIsShown() ) { + /* + マウスカーソルがビューの外に出ると OnMouseMoveが発生せず + ツールチップを消し損ねるので、外に移動したというイベント + を補完する。 + */ + POINT pt; GetCursorPos( &pt ); + RECT rc; GetWindowRect( static_cast(this)->GetHwnd(), &rc ); + if ( ! PtInRect( &rc, pt ) ) { + OnMouseMove( pt.x, pt.y ); + } + + return; // すでに表示されているので表示しない。 + } + ShowTooltip( BuildContextualHelp() ); +} + +template inline +void +AsWithHelpTooltip:: +OnMouseMove( int x, int y ) +{ + const bool moved = m_ptMouse0.x != x || m_ptMouse0.y != y; + if ( ! (m_LastOptions.flags & HIDE_ON_MOUSEMOVE) && TooltipIsShown() ) { + // 表示継続。 + } else if (moved) { + HideTooltip(); + // 表示してなくてもこれを呼ぶのは、dwTime0に現在の TickCountを記録して + // ツールチップの遅延表示に利用するため。細かく場合分けせずに + // HideTooltip()一本に任せてる。 + } + if ( moved ) { + m_ptCaretOnLastMouseMove = static_cast(this)->GetCaret().GetCaretLayoutPos(); + m_ptMouse0.x = x; m_ptMouse0.y = y; + } +} + +#endif CEDITVIEW_ASWITHHELPTOOLTIP_H === sakura_core/view/CEditView_AsWithHelpTooltip.cpp ================================================================== --- sakura_core/view/CEditView_AsWithHelpTooltip.cpp (revision 69505) +++ sakura_core/view/CEditView_AsWithHelpTooltip.cpp (revision 69511) @@ -0,0 +1,517 @@ +#include "StdAfx.h" +#include "CEditView_AsWithHelpTooltip.h" +#include "CEditView.h" +#include +#include "CSearchAgent.h" +#include "doc/CEditDoc.h" +#include "doc/layout/CLayoutMgr.h" +#include "parse/CWordParse.h" +#include "util/os.h" +#include "window/CEditWnd.h" +template AsWithHelpTooltip; // 他の .cppから呼んでもらえるように予め実体化しておく。 +template inline const V* asView( const AsWithHelpTooltip* this_ ) { return static_cast(this_); } // よく使う。 +const int STRNCMP_MAX = 100; //!< キーワード探索のために比較する文字列の最大長 + +template +void +AsWithHelpTooltip:: +Create() +{ + m_cTipWnd.~CTipWnd(); + new(&m_cTipWnd) CTipWnd( G_AppInstance(), asView(this)->GetHwnd() ); + // * メンバ毎に細々と new を使いたくない。 + // * CEditViewのウィンドウを作成してから遅延初期化したい。 + // * CTipWndに代入演算子を定義しようにも HINSTANCEや HWNDを保存していないので手間。 + // * 手間をかけてウィンドウを複製して、代入の右辺のウィンドウが適切に破棄されるだろうか。 + // * ムーブ代入演算子はまだちょっと…… + // * ムーブといえばお手軽に ==auto_ptr== unique_ptrだけど、ポインタだと暗黙的/必然的に + // Nullableだと受け取られかねないのが…… +} + +template +CNativeW +AsWithHelpTooltip:: +BuildLineHelpAbout( const View& view, CLayoutInt lineNo ) +{ + CNativeW out(L""); + const CLayout* pLayout = view.GetDocument()->m_cLayoutMgr.SearchLineByLayoutY( lineNo ); + for ( int i = 0; i < 4 && pLayout; ++i, pLayout = pLayout->GetNextLayout() ) { + CNativeW line; + { + CLogicInt nLineLen = pLayout->GetLengthWithoutEOL(); + const wchar_t* pszData = pLayout->GetPtr(); + int nLimitLength = 80; + int pre = 0; + int i = 0; + int k = 0; + int charSize = CNativeW::GetSizeOfChar( pszData, nLineLen, i ); + int charWidth = t_max(1, (int)(Int)CNativeW::GetKetaOfChar( pszData, nLineLen, i )); + int charType = 0; + // 連続する"\t", " " を " "1つにする + // 左からnLimitLengthまでの幅を切り取り + while( i + charSize <= (Int)nLineLen && k + charWidth <= nLimitLength ){ + if( pszData[i] == L'\t' || pszData[i] == L' ' ){ + if( charType == 0 ){ + line.AppendString( pszData + pre , i - pre ); + line.AppendString( L" " ); + charType = 1; + } + pre = i + charSize; + k++; + }else{ + k += charWidth; + charType = 0; + } + i += charSize; + charSize = CNativeW::GetSizeOfChar( pszData, nLineLen, i ); + charWidth = t_max(1, (int)(Int)CNativeW::GetKetaOfChar( pszData, nLineLen, i )); + } + line.AppendString( pszData + pre , i - pre ); + } + line.Replace( L"\\", L"\\\\" ); + out.AppendNativeData( line ); + out.AppendString( L"\n" ); + } + out.Chop(); // 末尾の\nを削る。空でも安全なのでとりあえず呼んどく。 + return out; +} + +template +typename AsWithHelpTooltip::KeywordHelpInfo +AsWithHelpTooltip:: +BuildHelpAbout( const CNativeW& keyword ) const +{ + KeywordHelpInfo result; + + if ( ! asView(this)->m_pTypeData->m_bUseKeyWordHelp ) { // キーワードヘルプを使用しない設定 + return result; + } + if ( -1 == m_LastSearchCache.dicNo + && CNativeW::IsEqual( m_LastSearchCache.keyword, keyword ) + ) { + /* + 内容は覚えていないので本処理をスキップできないけど、 + 辞書にキーワードが見つからなかったという結果は再利用できる。 + */ + return result; + } + + /* 1行目にキーワードを表示する場合 */ + if( asView(this)->m_pTypeData->m_bUseKeyHelpKeyDisp ) { + result.content.AppendString( L"[ " ); + result.content.AppendNativeData( keyword ); + result.content.AppendString( L" ]" ); + result.content.AppendString( L"\n--------------------\n" ); + } + + //! 文字列比較最大長。設定によりSTRNCMP_MAXサイズまでの完全一致かキーワードの接頭辞になっているか、どちらかを確かめるのに必要十分な長さ。 + const int CmpLen = asView(this)->m_pTypeData->m_bUseKeyHelpPrefix ? wcslen(keyword.GetStringPtr()) : STRNCMP_MAX; + TCHAR szFile[MAX_PATH]; + for ( int i = 0; i < asView(this)->m_pTypeData->m_nKeyHelpNum; i++ ) { //最大数:MAX_KEYHELP_FILE + const KeyHelpInfo& d = asView(this)->m_pTypeData->m_KeyHelpArr[i]; + if ( ! d.m_bUse ) { + continue; + } + + CNativeW *pK = NULL, *pV = NULL; + int nLine = 0; + BOOL found = CDicMgr::Search ( + keyword.GetStringPtr(), CmpLen, + &pK, &pV, + d.m_szPath, + &nLine + ); + std::auto_ptr pKey(pK), pVal(pV); // deleteを任せる。 + pK = pV = NULL; // 生ポインタはもう使わない。 + if ( ! found ) { + continue; + } + + /* 該当するキーがある */ + + /* 有効になっている辞書を全部なめて、ヒットの都度説明を継ぎ足す */ + if ( asView(this)->m_pTypeData->m_bUseKeyHelpAllSearch ) { + + // ■ + result.content.AppendString( L"■" ); + + // 辞書のファイル名(拡張子なし) + szFile[0] = TEXT('\0'); + _tsplitpath( d.m_szPath, NULL, NULL, szFile, NULL ); + result.content.AppendString( szFile ); + result.content.AppendString( L"\n" ); + + // 選択範囲で前方一致検索してヒットした単語 + if( asView(this)->m_pTypeData->m_bUseKeyHelpPrefix ) { + result.content.AppendNativeData( *pKey ); + result.content.AppendString( L" >>\n" ); + } + + // 調査した「意味」を挿入 + result.content.AppendNativeData( *pVal ); + + // タグジャンプ用に最初にヒットした辞書の情報を残す + if ( result.dicNo == -1 ) { + result.dicNo = i; + result.dicLineNo = nLine; + } + } else { + /* 最初のヒット項目のみ返す場合 */ + + // 選択範囲で前方一致検索してヒットした単語 + if( asView(this)->m_pTypeData->m_bUseKeyHelpPrefix ) { + result.content.AppendNativeData( *pKey ); + result.content.AppendString( L" >>\n" ); + } + + // 調査した「意味」を挿入 + result.content.AppendNativeData( *pVal ); + + // タグジャンプ用に情報を残す + result.dicNo = i; + result.dicLineNo = nLine; + + break; + } + } + if ( result.dicNo == -1 ) { + result.content.SetString(L""); // 「1行目にキーワード」が入ってる場合があるので + } + m_LastSearchCache.keyword = keyword; + m_LastSearchCache.dicNo = result.dicNo; + m_LastSearchCache.dicLineNo = result.dicLineNo; + return result; +} + +static bool +SearchKeywordAround( const CEditView& view, CLogicPoint ptInLogic, CNativeW* outKeyword, CLogicInt* outFrom, CLogicInt* outTo ) +{ + if ( outKeyword ) { *outKeyword = L""; } + if ( outFrom ) { *outFrom = ptInLogic.x; } + if ( outTo ) { *outTo = ptInLogic.x; } + CLogicInt from, to; CNativeW keyword; + if ( ! CSearchAgent( &(view.m_pcEditDoc->m_cDocLineMgr) ).WhereCurrentWord( + ptInLogic.y, ptInLogic.x, &from, &to, &keyword, NULL + ) ) { + return false; // なかったよ。 + } + if ( outKeyword ) { *outKeyword = keyword; } + if ( outFrom ) { *outFrom = from; } + if ( outTo ) { *outTo = to; } + return true; +} + +static bool +SearchKeywordAround( const CEditView& view, CLayoutPoint ptInLayout, CNativeW* outKeyword, CLayoutPoint* outFrom, CLayoutPoint* outTo ) +{ + if ( outKeyword ) { *outKeyword = L""; } + if ( outFrom ) { *outFrom = ptInLayout; } + if ( outTo ) { *outTo = ptInLayout; } + CLogicPoint ptInLogic; view.m_pcEditDoc->m_cLayoutMgr.LayoutToLogic( ptInLayout, &ptInLogic ); + CLogicInt from, to; + if ( ! SearchKeywordAround( view, ptInLogic, outKeyword, &from, &to ) ) { + return false; // なかったよ。 + } + if ( outFrom ) { + ptInLogic.x = from; + view.m_pcEditDoc->m_cLayoutMgr.LogicToLayout( ptInLogic, outFrom, ptInLayout.y ); + } + if ( outTo ) { + ptInLogic.x = to; + view.m_pcEditDoc->m_cLayoutMgr.LogicToLayout( ptInLogic, outTo, ptInLayout.y ); + } + return true; +} + +template +typename AsWithHelpTooltip::KeywordInfo +AsWithHelpTooltip:: +SearchKeywordAround( CLogicPoint pt ) const +{ + KeywordInfo ki; + CNativeW word; CLogicInt fromX, toX; + if ( ! ::SearchKeywordAround( *asView(this), pt, &word, &fromX, &toX ) ) { + return ki; + } + KeywordHelpInfo khi = BuildHelpAbout( word ); + if ( khi.dicNo == -1 ) { + return ki; + } + ki.keyword = word; + ki.help = khi; + ki.from.x = Int( fromX ); ki.to.x = Int( toX ); + ki.from.y = Int( pt.y ); ki.to.y = Int( pt.y ); + return ki; +} + +template +typename AsWithHelpTooltip::KeywordInfo +AsWithHelpTooltip:: +SearchKeywordAround( CLayoutPoint pt ) const +{ + KeywordInfo ki; + CNativeW word; CLayoutPoint ptFrom, ptTo; + if ( ! ::SearchKeywordAround( *asView(this), pt, &word, &ptFrom, &ptTo ) ) { + return ki; + } + if ( pt.y == ptFrom.y && pt.x < ptFrom.x ) { + return ki; // たぶん行番号領域をポイントしてる。SearchKeywordAround(が呼び出す関数)はそれでも失敗しない。 + } + KeywordHelpInfo khi = BuildHelpAbout( word ); + if ( khi.dicNo == -1 ) { + return ki; + } + ki.keyword = word; + ki.help = khi; + ki.from.x = Int( ptFrom.x ); ki.to.x = Int( ptTo.x ); + ki.from.y = Int( ptFrom.y ); ki.to.y = Int( ptTo.y ); + return ki; +} + +static inline bool +MinimapTooltipOptions( const CEditView& view, AsWithHelpTooltip::ShowTooltipOptions* out ) +{ + POINT pt; GetCursorPos( &pt ); + RECT rc; GetWindowRect( view.GetHwnd(), &rc ); rc.right -= GetSystemMetrics(SM_CXVSCROLL); + if ( ! PtInRect( &rc, pt ) ) { // ビュー(=ミニマップ)の上にマウスカーソルがなければ + *out = AsWithHelpTooltip::ShowTooltipOptions(); + return true; + } + //if ( WindowFromPoint( pt ) != view.GetHwnd() ) { // とりあえずコピペしてきたが上との違いがわからない + // return false; + //} +/* + ポインタの下のテキストをツールチップの内容にします。 +*/ + CMyPoint ptInClient = pt; ScreenToClient( view.GetHwnd(), &ptInClient ); + CLayoutPoint ptInLayout; view.GetTextArea().ClientToLayout( ptInClient, &ptInLayout ); + + out->flags = AsWithHelpTooltip::HIDE_ON_MOUSEMOVE | AsWithHelpTooltip::SHOW_LEFT; + GetCursorPos( &(out->pos) ); out->pos.y += view.m_pcEditWnd->GetActiveView().GetTextMetrics().GetHankakuHeight(); + out->text = AsWithHelpTooltip::BuildLineHelpAbout( view, ptInLayout.y ); + return true; +} + +static inline bool +PointedKeywordTooltipOptions( const CEditView& view, AsWithHelpTooltip::ShowTooltipOptions* out ) +{ + POINT pt; GetCursorPos( &pt ); + ScreenToClient( view.GetHwnd(), &pt ); + CLayoutPoint ptInLayout; view.GetTextArea().ClientToLayout( pt, &ptInLayout ); + + AsWithHelpTooltip::KeywordInfo ki = view.SearchKeywordAround( ptInLayout ); + if ( ki.help.dicNo == -1 ) { + *out = AsWithHelpTooltip::ShowTooltipOptions(); + return true; + } +/* + 表示位置の調整。 + X座標を単語の開始位置に、Y座標をポインタ(ptInLayout)の1行と半分下に。 + X座標の移動で折り返しをまたいだときは…… +*/ + ptInLayout.x = CLayoutInt( ki.from.x ); + CMyPoint mpt; view.GetTextArea().LayoutToClient( ptInLayout, &mpt ); + out->pos.x = mpt.x; out->pos.y = mpt.y + 3 * view.m_pcEditWnd->GetActiveView().GetTextMetrics().GetHankakuHeight() / 2; + ClientToScreen( view.GetHwnd(), &(out->pos) ); + + out->flags = AsWithHelpTooltip::HIDE_ON_MOUSEMOVE | AsWithHelpTooltip::SHOW_RIGHT; + out->text = ki.help.content; + return true; +} + +static inline bool +SelectedKeywordTooltipOptions( const CEditView& view, AsWithHelpTooltip::ShowTooltipOptions* out ) +{ + CNativeW keyword; + if ( ! view.GetSelectedDataOne( keyword, STRNCMP_MAX ) ) { + *out = AsWithHelpTooltip::ShowTooltipOptions(); + return true; + } + if ( keyword.GetStringLength() == 0 ) { + *out = AsWithHelpTooltip::ShowTooltipOptions(); + return true; + } + out->flags = AsWithHelpTooltip::HIDE_ON_MOUSEMOVE | AsWithHelpTooltip::TEXT_IS_KEYWORD | AsWithHelpTooltip::DONT_SHOW_NONKEYWORD_TEXT; + GetCursorPos( &(out->pos) ); out->pos.y += view.GetTextMetrics().GetHankakuHeight(); + out->text = keyword; + return true; +} + +static inline bool +KeywordAroundCaretTooltipOptions( const CEditView& view, AsWithHelpTooltip::ShowTooltipOptions* out ) +{ + CLogicPoint ptInLogic = view.GetCaret().GetCaretLogicPos(); + AsWithHelpTooltip::KeywordInfo ki = view.SearchKeywordAround( ptInLogic ); + if ( ki.help.dicNo == -1 ) { + *out = AsWithHelpTooltip::ShowTooltipOptions(); + return true; + } +/* + 表示位置の調整。 + X座標を単語の開始位置に、Y座標をキャレット(ptInLogic)の1行と半分下に。 + X座標の移動で折り返しをまたいだときは…… +*/ + if ("obey legacy") { + GetCursorPos( &(out->pos) ); out->pos.y += view.GetTextMetrics().GetHankakuHeight(); + } else { + CLayoutPoint ptInLayout; ptInLogic.x = CLogicInt( ki.from.x ); view.m_pcEditDoc->m_cLayoutMgr.LogicToLayout( ptInLogic, &ptInLayout ); + CMyPoint mpt; view.GetTextArea().LayoutToClient( ptInLayout, &mpt ); + out->pos.x = mpt.x; out->pos.y = mpt.y + 3 * view.m_pcEditWnd->GetActiveView().GetTextMetrics().GetHankakuHeight() / 2; + ClientToScreen( view.GetHwnd(), &(out->pos) ); + } + + out->flags = AsWithHelpTooltip::HIDE_ON_MOUSEMOVE | AsWithHelpTooltip::SHOW_RIGHT; + out->text = ki.help.content; + return true; +} + +template +typename AsWithHelpTooltip::ShowTooltipOptions +AsWithHelpTooltip:: +BuildContextualHelp() const +{ + if ( asView(this)->GetSelectionInfo().IsMouseSelecting() ) { + return ShowTooltipOptions(); // マウス選択中はツールチップ無効。 + } + if ( asView(this)->m_bInMenuLoop ) { + return ShowTooltipOptions(); // メニュー モーダル ループに入っているときはツールチップ無効。 + // ただし、m_bMiniMap == true のビューでは m_bInMenuLoop == true になることがないみたいなので + // メニュー表示中でもツールチップが出ます。 + } +/* + コンテキスト(flags)を組み立てる +*/ + enum { + FOCUS_MOUSE = 1, //!< 最後にマウスを触ってからキーボードでキャレットを移動していない。 + KEYBOARD_FOCUS = 2, //!< ビューがフォーカスを持っている。 + KWDHLP_ENABLED = 4, //!< キーワードヘルプ機能を使用する設定。 + MOUSE_OVER_VIEW = 8, //!< ビュー・ミニマップの上にマウスカーソルがある。 + SENSITIVE_HELP = 16, //!< 範囲選択無しでキーワードヘルプを表示する設定。キーワードヘルプが有効かどうかとは独立していることに注意(センシティブでも表示しない設定がある)。 + VIEW_IS_MINIMAP = 32, + TEXT_SELECTED = 64 + }; + int flags = 0; + CLayoutPoint ptCaret = asView(this)->GetCaret().GetCaretLayoutPos(); + if ( ptCaret.x == m_ptCaretOnLastMouseMove.x && ptCaret.y == m_ptCaretOnLastMouseMove.y ) { + flags += FOCUS_MOUSE; + } + if ( asView(this)->GetCaret().ExistCaretFocus() ) { + flags += KEYBOARD_FOCUS; + } + if ( asView(this)->m_pTypeData->m_bUseKeyWordHelp ) { + flags += KWDHLP_ENABLED; + } + POINT pt; GetCursorPos( &pt ); + RECT rc; GetWindowRect( asView(this)->GetHwnd(), &rc ); + if ( !! PtInRect( &rc, pt ) ) { + flags += MOUSE_OVER_VIEW; + } + if ( !! GetDllShareData().m_Common.m_sSearch.m_bUseCaretKeyWord ) { + flags += SENSITIVE_HELP; + } + if ( asView(this)->m_bMiniMap ) { + flags += VIEW_IS_MINIMAP; + } + if ( asView(this)->GetSelectionInfo().IsTextSelected() ) { + flags += TEXT_SELECTED; + } + struct Must1_t { int flags; Must1_t(int flags):flags(flags){} + bool operator()( int cond ) { return ( flags & cond ^ cond ) == 0; } + } Must1( flags ); + struct Must0_t { int flags; Must0_t(int flags):flags(flags){} + bool operator()( int cond ) { return ( flags & cond ) == 0; } + } Must0( flags ); +/* + コンテキスト(flags)に適合するヘルプ(ShowTooltipOptions)を組み立てる +*/ + ShowTooltipOptions opt; + if ( Must1( FOCUS_MOUSE|MOUSE_OVER_VIEW|VIEW_IS_MINIMAP ) ) { + if ( MinimapTooltipOptions( *asView(this), &opt ) ) { + return opt; + } + } + if ( Must1( FOCUS_MOUSE|MOUSE_OVER_VIEW|KWDHLP_ENABLED|SENSITIVE_HELP ) && Must0( VIEW_IS_MINIMAP ) ) { + if ( PointedKeywordTooltipOptions( *asView(this), &opt ) ) { + return opt; + } + } + if ( Must1( KEYBOARD_FOCUS|MOUSE_OVER_VIEW|KWDHLP_ENABLED|TEXT_SELECTED ) && Must0( VIEW_IS_MINIMAP ) ) { + if ( SelectedKeywordTooltipOptions( *asView(this), &opt ) ) { + return opt; + } + } + if ( Must1( KEYBOARD_FOCUS|MOUSE_OVER_VIEW|KWDHLP_ENABLED|SENSITIVE_HELP ) && Must0( VIEW_IS_MINIMAP ) ) { + if ( KeywordAroundCaretTooltipOptions( *asView(this), &opt ) ) { + return opt; + } + } + return ShowTooltipOptions(); +} + +template +bool +AsWithHelpTooltip:: +ShowTooltip( const ShowTooltipOptions& opt ) +{ + if ( opt.text.GetStringLength() == 0 ) { + return false; // textが空の時は特別扱い。ShowTooltipは呼ばれなかったものとする。デフォルトコンストラクトされた ShowTooltipOptionsが主にこの条件に該当する。 + } +/* + リセット +*/ + HideTooltip(); + m_LastOptions = opt; + // m_LastHelpInfoのリセットは再利用を試みてから。 +/* + 引数処理: キーワード展開。ツールチップチップテキスト設定 +*/ + if ( opt.flags & TEXT_IS_KEYWORD ) { + if ( CNativeW::IsEqual( m_LastSearchCache.keyword, opt.text ) ) { + /* + m_LastSearchCacheとツールチップの内容(m_cTipWnd.GetText())を再利用する。 + */ + } else { + KeywordHelpInfo khi = BuildHelpAbout( opt.text ); + m_cTipWnd.SetText( 0 <= khi.dicNo ? khi.content.GetStringT() : opt.text.GetStringT() ); + } + } else { + //m_LastSearchCache.dicNo = -1; + //m_LastSearchCache.dicLineNo = -1; + //m_LastSearchCache.keyword.SetString( L"" ); + m_cTipWnd.SetText( opt.text.GetStringT() ); + } +/* + 表示位置決め。 +*/ + int LR = 0; + if ( (opt.flags & (SHOW_LEFT|SHOW_RIGHT)) == SHOW_LEFT ) { // SHOW_LEFT単独指定 + LR = SHOW_LEFT; + } + if ( (opt.flags & (SHOW_LEFT|SHOW_RIGHT)) == SHOW_RIGHT ) { // SHOW_RIGHT単独指定 + LR = SHOW_RIGHT; + } + if ( LR == 0 ) { + SIZE tipWin = m_cTipWnd.GetWindowSize(); + RECT rcDesktop; GetMonitorWorkRect( asView(this)->GetHwnd(), &rcDesktop ); + LR = ( opt.pos.x + tipWin.cx < rcDesktop.right ) ? SHOW_RIGHT: // 右に入る + ( rcDesktop.left < opt.pos.x - tipWin.cx ) ? SHOW_LEFT: // 左に入る + ( rcDesktop.right - opt.pos.x > opt.pos.x ) ? SHOW_RIGHT: // 入らないが右の方が広い + SHOW_LEFT; // 入らないが左の方が広い + } +/* + 表示 +*/ + const int MAYBE_INVISIBLE = ( TEXT_IS_KEYWORD | DONT_SHOW_NONKEYWORD_TEXT ); + if ( (opt.flags & MAYBE_INVISIBLE) == MAYBE_INVISIBLE && m_LastSearchCache.dicNo == -1 ) { + return false; // キーワード検索が不調に終わったため表示しなかった。 + } + if ( opt.flags & SHOW_INVISIBLE ) { + return true; // 状態の更新はするが表示はしないが表示したつもりで true。他のフラグ(すぐ上のifを見る)次第では falseが返ることもあるので、いつでも表示したつもりというわけではない。 + } + if ( LR == SHOW_RIGHT ) { + m_cTipWnd.ShowRight( opt.pos.x, opt.pos.y ); + } else { + m_cTipWnd.ShowLeft( opt.pos.x, opt.pos.y ); + } + return true; +} === sakura_core/view/CEditView.h ================================================================== --- sakura_core/view/CEditView.h (revision 69505) +++ sakura_core/view/CEditView.h (revision 69511) @@ -44,6 +44,7 @@ #include #include // LPDATAOBJECT #include // HDROP +#include "view/CEditView_AsWithHelpTooltip.h" #include "CTextMetrics.h" #include "CTextDrawer.h" #include "CTextArea.h" @@ -54,7 +55,6 @@ #include "CViewSelect.h" #include "CSearchAgent.h" #include "view/colors/EColorIndexType.h" -#include "window/CTipWnd.h" #include "window/CAutoScrollWnd.h" #include "CDicMgr.h" // Jun. 26, 2001 genta 正規表現ライブラリの差し替え @@ -110,9 +110,6 @@ const int CMD_FROM_MOUSE = 2; -/*----------------------------------------------------------------------- -クラスの宣言 ------------------------------------------------------------------------*/ /*! @brief 文書ウィンドウの管理 @@ -131,6 +128,7 @@ , public CEditView_Paint , public CMyWnd , public CDocListenerEx +, public AsWithHelpTooltip { public: const CEditDoc* GetDocument() const @@ -338,7 +336,7 @@ public: // 2002/01/19 novice public属性に変更 bool GetSelectedDataSimple( CNativeW& );// 選択範囲のデータを取得 - bool GetSelectedDataOne( CNativeW& cmemBuf, int nMaxLen ); + bool GetSelectedDataOne( CNativeW& cmemBuf, int nMaxLen ) const; bool GetSelectedData( CNativeW*, BOOL, const wchar_t*, BOOL, bool bAddCRLFWhenCopy, EEolType neweol = EOL_UNKNOWN);/* 選択範囲のデータを取得 */ int IsCurrentPositionSelected( CLayoutPoint ptCaretPos ); /* 指定カーソル位置が選択エリア内にあるか */ int IsCurrentPositionSelectedTEST( const CLayoutPoint& ptCaretPos, const CLayoutRange& sSelect ) const;/* 指定カーソル位置が選択エリア内にあるか */ @@ -457,18 +455,6 @@ // Jan. 10, 2005 インクリメンタルサーチ bool IsISearchEnabled(int nCommand) const; - BOOL KeySearchCore( const CNativeW* pcmemCurText ); // 2006.04.10 fon - bool MiniMapCursorLineTip( POINT* po, RECT* rc, bool* pbHide ); - - /*! CEditView::KeyWordHelpSearchDictのコール元指定用ローカルID - @date 2006.04.10 fon 新規作成 - */ - enum LID_SKH { - LID_SKH_ONTIMER = 1, /*!< CEditView::OnTimer */ - LID_SKH_POPUPMENU_R = 2, /*!< CEditView::CreatePopUpMenu_R */ - }; - BOOL KeyWordHelpSearchDict( LID_SKH nID, POINT* po, RECT* rc ); // 2006.04.10 fon - int IsSearchString( const CStringRef& cStr, CLogicInt, CLogicInt*, CLogicInt* ) const; /* 現在位置が検索文字列に該当するか */ //2002.02.08 hor 引数追加 void GetCurrentTextForSearch( CNativeW&, bool bStripMaxPath = true, bool bTrimSpaceTab = false ); /* 現在カーソル位置単語または選択範囲より検索等のキーを取得 */ @@ -570,7 +556,6 @@ void SplitBoxOnOff( BOOL, BOOL, BOOL ); /* 縦・横の分割ボックス・サイズボックスのON/OFF */ // 2001/06/18 asa-o - bool ShowKeywordHelp( POINT po, LPCWSTR pszHelp, LPRECT prcHokanWin); // 補完ウィンドウ用のキーワードヘルプ表示 void SetUndoBuffer( bool bPaintLineNumber = false ); // アンドゥバッファの処理 HWND StartProgress(); @@ -720,11 +705,7 @@ bool m_bDoing_UndoRedo; /* アンドゥ・リドゥの実行中か */ // 辞書Tip関連 - DWORD m_dwTipTimer; /* Tip起動タイマー */ - CTipWnd m_cTipWnd; /* Tip表示ウィンドウ */ - POINT m_poTipCurPos; /* Tip起動時のマウスカーソル位置 */ BOOL m_bInMenuLoop; /* メニュー モーダル ループに入っています */ - CDicMgr m_cDicMgr; /* 辞書マネージャ */ TCHAR m_szComposition[512]; // IMR_DOCUMENTFEED用入力中文字列データ @@ -758,8 +739,6 @@ DISALLOW_COPY_AND_ASSIGN(CEditView); }; - - class COutputAdapter { public: @@ -773,7 +752,3 @@ }; /////////////////////////////////////////////////////////////////////// #endif /* _CEDITVIEW_H_ */ - - - - === sakura_core/view/CEditView.cpp ================================================================== --- sakura_core/view/CEditView.cpp (revision 69505) +++ sakura_core/view/CEditView.cpp (revision 69511) @@ -247,7 +247,6 @@ m_CurRegexp.InitDll(GetDllShareData().m_Common.m_sSearch.m_szRegexpLib ); // 2004.02.08 m_hFont_ZENは未使用により削除 - m_dwTipTimer = ::GetTickCount(); /* 辞書Tip起動タイマー */ m_bInMenuLoop = FALSE; /* メニュー モーダル ループに入っています */ // MYTRACE( _T("CEditView::CEditView()おわり\n") ); m_bHokan = FALSE; @@ -358,8 +357,7 @@ m_pcDropTarget->Register_DropTarget( GetHwnd() ); } - /* 辞書Tip表示ウィンドウ作成 */ - m_cTipWnd.Create( G_AppInstance(), GetHwnd()/*GetDllShareData().m_sHandles.m_hwndTray*/ ); + AsWithHelpTooltip::Create(); /* 再描画用コンパチブルDC */ // 2007.09.09 Moca 互換BMPによる画面バッファ @@ -770,12 +768,8 @@ case WM_ENTERMENULOOP: m_bInMenuLoop = TRUE; /* メニュー モーダル ループに入っています */ - /* 辞書Tipが起動されている */ - if( 0 == m_dwTipTimer ){ - /* 辞書Tipを消す */ - m_cTipWnd.Hide(); - m_dwTipTimer = ::GetTickCount(); /* 辞書Tip起動タイマー */ - } + this->HideTooltip(); // 辞書Tipを消す + if( m_bHokan ){ m_pcEditWnd->m_cHokanMgr.Hide(); m_bHokan = FALSE; @@ -1145,12 +1139,7 @@ GetRuler().DispRuler( hdc ); ::ReleaseDC( GetHwnd(), hdc ); - /* 辞書Tipが起動されている */ - if( 0 == m_dwTipTimer ){ - /* 辞書Tipを消す */ - m_cTipWnd.Hide(); - m_dwTipTimer = ::GetTickCount(); /* 辞書Tip起動タイマー */ - } + this->HideTooltip(); // 辞書Tipを消す if( m_bHokan ){ m_pcEditWnd->m_cHokanMgr.Hide(); @@ -1357,42 +1346,24 @@ UINT uMsg, // WM_TIMER message UINT_PTR idEvent, // timer identifier DWORD dwTime // current system time - ) +) { - POINT po; - RECT rc; - if( GetDllShareData().m_Common.m_sEdit.m_bUseOLE_DragDrop ){ /* OLEによるドラッグ & ドロップを使う */ if( IsDragSource() ){ return; } } - /* 範囲選択中でない場合 */ - if(!GetSelectionInfo().IsMouseSelecting()){ - if( m_bMiniMap ){ - bool bHide; - if( MiniMapCursorLineTip( &po, &rc, &bHide ) ){ - m_cTipWnd.m_bAlignLeft = true; - m_cTipWnd.Show( po.x, po.y + m_pcEditWnd->GetActiveView().GetTextMetrics().GetHankakuHeight(), NULL ); - }else{ - if( bHide && 0 == m_dwTipTimer ){ - m_cTipWnd.Hide(); - } - } - }else{ - if( FALSE != KeyWordHelpSearchDict( LID_SKH_ONTIMER, &po, &rc ) ){ // 2006.04.10 fon - /* 辞書Tipを表示 */ - m_cTipWnd.Show( po.x, po.y + GetTextMetrics().GetHankakuHeight(), NULL ); - } - } - } - else{ - ::GetCursorPos( &po ); - ::GetWindowRect(GetHwnd(), &rc ); - if( !PtInRect( &rc, po ) ){ + + if( GetSelectionInfo().IsMouseSelecting() ) { + POINT pt; GetCursorPos( &pt ); + RECT rc; GetWindowRect( GetHwnd(), &rc ); + if( ! PtInRect( &rc, pt ) ){ OnMOUSEMOVE( 0, GetSelectionInfo().m_ptMouseRollPosOld.x, GetSelectionInfo().m_ptMouseRollPosOld.y ); - } + } } + + // ツールチップ + AsWithHelpTooltip::OnTimer( dwTime ); } // -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- // @@ -1592,10 +1563,10 @@ { CMenuDrawer& cMenuDrawer = m_pcEditWnd->GetMenuDrawer(); // 2010.07.24 Moca オーナードロー対応のために前に移動してCMenuDrawer経由で追加する - if( !GetSelectionInfo().IsMouseSelecting() && eRmenuType != KEYHELP_RMENU_NONE ){ - POINT po; - RECT rc; - if( FALSE != KeyWordHelpSearchDict( LID_SKH_POPUPMENU_R, &po, &rc ) ){ // 2006.04.10 fon + if( !GetSelectionInfo().IsMouseSelecting() && eRmenuType != KEYHELP_RMENU_NONE ) { + ShowTooltipOptions opt = BuildContextualHelp(); + opt.flags |= SHOW_INVISIBLE; + if( ShowTooltip( opt ) ) { // 2006.04.10 fon if( eRmenuType == KEYHELP_RMENU_BOTTOM ){ cMenuDrawer.MyAppendMenuSep( hMenu, MF_SEPARATOR, F_0, _T("") ); } @@ -1796,7 +1767,7 @@ OnSize( rc.right, rc.bottom ); /* フォントが変わった */ - m_cTipWnd.ChangeFont( &(GetDllShareData().m_Common.m_sHelper.m_lf) ); + this->SetTooltipFont( GetDllShareData().m_Common.m_sHelper.m_lf ); /* 再描画 */ @@ -2147,7 +2118,7 @@ 通常選択ならロジック行、矩形なら選択範囲内のレイアウト行1行を選択 2010.09.04 Moca 新規作成 */ -bool CEditView::GetSelectedDataOne( CNativeW& cmemBuf, int nMaxLen ) +bool CEditView::GetSelectedDataOne( CNativeW& cmemBuf, int nMaxLen ) const { const wchar_t* pLine; CLogicInt nLineLen; @@ -2760,68 +2731,6 @@ m_cHistory->Add( m ); } - -// 2001/06/18 Start by asa-o: 補完ウィンドウ用のキーワードヘルプ表示 -bool CEditView::ShowKeywordHelp( POINT po, LPCWSTR pszHelp, LPRECT prcHokanWin) -{ - CNativeW cmemCurText; - RECT rcTipWin, - rcDesktop; - - if( m_pTypeData->m_bUseKeyWordHelp ){ /* キーワードヘルプを使用する */ - if( m_bInMenuLoop == FALSE && /* メニュー モーダル ループに入っていない */ - 0 != m_dwTipTimer /* 辞書Tipを表示していない */ - ){ - cmemCurText.SetString( pszHelp ); - - /* 既に検索済みか */ - if( CNativeW::IsEqual( cmemCurText, m_cTipWnd.m_cKey ) ){ - /* 該当するキーがなかった */ - if( !m_cTipWnd.m_KeyWasHit ){ - return false; - } - }else{ - m_cTipWnd.m_cKey = cmemCurText; - /* 検索実行 */ - if(!KeySearchCore(&m_cTipWnd.m_cKey)) // 2006.04.10 fon - return FALSE; - } - m_dwTipTimer = 0; /* 辞書Tipを表示している */ - - // 2001/06/19 Start by asa-o: 辞書Tipの表示位置調整 - // 辞書Tipのサイズを取得 - m_cTipWnd.GetWindowSize(&rcTipWin); - - // May 01, 2004 genta マルチモニタ対応 - ::GetMonitorWorkRect( m_cTipWnd.GetHwnd(), &rcDesktop ); - - // 右に入る - if(prcHokanWin->right + rcTipWin.right < rcDesktop.right){ - // そのまま - }else - // 左に入る - if(rcDesktop.left < prcHokanWin->left - rcTipWin.right ){ - // 左に表示 - po.x = prcHokanWin->left - (rcTipWin.right + 8); - }else - // どちらもスペースが無いとき広いほうに表示 - if(rcDesktop.right - prcHokanWin->right > prcHokanWin->left ){ - // 右に表示 そのまま - }else{ - // 左に表示 - po.x = prcHokanWin->left - (rcTipWin.right + 8); - } - // 2001/06/19 End - - /* 辞書Tipを表示 */ - m_cTipWnd.Show( po.x, po.y , NULL , &rcTipWin); - return true; - } - } - return false; -} -// 2001/06/18 End - /*! @brief 指定位置または指定範囲がテキストの存在しないエリアかチェックする === sakura_core/view/CEditView_Search.cpp ================================================================== --- sakura_core/view/CEditView_Search.cpp (revision 69505) +++ sakura_core/view/CEditView_Search.cpp (revision 69511) @@ -29,265 +29,10 @@ #include "parse/CWordParse.h" #include "util/string_ex2.h" -const int STRNCMP_MAX = 100; /* MAXキーワード長:strnicmp文字列比較最大値(CEditView::KeySearchCore) */ // 2006.04.10 fon - // -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- // // 検索 // // -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- // -/*! キーワード辞書検索の前提条件チェックと、検索 - - @date 2006.04.10 fon OnTimer, CreatePopUpMenu_Rから分離 -*/ -BOOL CEditView::KeyWordHelpSearchDict( LID_SKH nID, POINT* po, RECT* rc ) -{ - CNativeW cmemCurText; - - /* キーワードヘルプを使用するか? */ - if( !m_pTypeData->m_bUseKeyWordHelp ) /* キーワードヘルプ機能を使用する */ // 2006.04.10 fon - goto end_of_search; - /* フォーカスがあるか? */ - if( !GetCaret().ExistCaretFocus() ) - goto end_of_search; - /* ウィンドウ内にマウスカーソルがあるか? */ - GetCursorPos( po ); - GetWindowRect( GetHwnd(), rc ); - if( !PtInRect( rc, *po ) ) - goto end_of_search; - switch(nID){ - case LID_SKH_ONTIMER: - /* 右コメントの1〜3でない場合 */ - if(!( m_bInMenuLoop == FALSE && /* 1.メニュー モーダル ループに入っていない */ - 0 != m_dwTipTimer && /* 2.辞書Tipを表示していない */ - 300 < ::GetTickCount() - m_dwTipTimer /* 3.一定時間以上、マウスが固定されている */ - ) ) goto end_of_search; - break; - case LID_SKH_POPUPMENU_R: - if(!( m_bInMenuLoop == FALSE //&& /* 1.メニュー モーダル ループに入っていない */ - // 0 != m_dwTipTimer && /* 2.辞書Tipを表示していない */ - // 1000 < ::GetTickCount() - m_dwTipTimer /* 3.一定時間以上、マウスが固定されている */ - ) ) goto end_of_search; - break; - default: - PleaseReportToAuthor( NULL, _T("CEditView::KeyWordHelpSearchDict\nnID=%d"), (int)nID ); - } - /* 選択範囲のデータを取得(複数行選択の場合は先頭の行のみ) */ - if( GetSelectedDataOne( cmemCurText, STRNCMP_MAX + 1 ) ){ - } - /* キャレット位置の単語を取得する処理 */ // 2006.03.24 fon - else if(GetDllShareData().m_Common.m_sSearch.m_bUseCaretKeyWord){ - if(!GetParser().GetCurrentWord(&cmemCurText)) - goto end_of_search; - } - else - goto end_of_search; - - if( CNativeW::IsEqual( cmemCurText, m_cTipWnd.m_cKey ) && /* 既に検索済みか */ - (!m_cTipWnd.m_KeyWasHit) ) /* 該当するキーがなかった */ - goto end_of_search; - m_cTipWnd.m_cKey = cmemCurText; - - /* 検索実行 */ - if( !KeySearchCore(&m_cTipWnd.m_cKey) ) - goto end_of_search; - m_dwTipTimer = 0; /* 辞書Tipを表示している */ - m_poTipCurPos = *po; /* 現在のマウスカーソル位置 */ - return TRUE; /* ここまで来ていればヒット・ワード */ - - /* キーワードヘルプ表示処理終了 */ - end_of_search: - return FALSE; -} - -/*! キーワード辞書検索処理メイン - - @date 2006.04.10 fon KeyWordHelpSearchDictから分離 -*/ -BOOL CEditView::KeySearchCore( const CNativeW* pcmemCurText ) -{ - CNativeW* pcmemRefKey; - int nCmpLen = STRNCMP_MAX; // 2006.04.10 fon - int nLine; // 2006.04.10 fon - - - m_cTipWnd.m_cInfo.SetString( _T("") ); /* tooltipバッファ初期化 */ - /* 1行目にキーワード表示の場合 */ - if(m_pTypeData->m_bUseKeyHelpKeyDisp){ /* キーワードも表示する */ // 2006.04.10 fon - m_cTipWnd.m_cInfo.AppendString( _T("[ ") ); - m_cTipWnd.m_cInfo.AppendString( pcmemCurText->GetStringT() ); - m_cTipWnd.m_cInfo.AppendString( _T(" ]") ); - } - /* 途中まで一致を使う場合 */ - if(m_pTypeData->m_bUseKeyHelpPrefix) - nCmpLen = wcslen( pcmemCurText->GetStringPtr() ); // 2006.04.10 fon - m_cTipWnd.m_KeyWasHit = FALSE; - for(int i =0 ; i < m_pTypeData->m_nKeyHelpNum; i++){ //最大数:MAX_KEYHELP_FILE - if( m_pTypeData->m_KeyHelpArr[i].m_bUse ){ - // 2006.04.10 fon (nCmpLen,pcmemRefKey,nSearchLine)引数を追加 - CNativeW* pcmemRefText; - int nSearchResult=m_cDicMgr.CDicMgr::Search( - pcmemCurText->GetStringPtr(), - nCmpLen, - &pcmemRefKey, - &pcmemRefText, - m_pTypeData->m_KeyHelpArr[i].m_szPath, - &nLine - ); - if(nSearchResult){ - /* 該当するキーがある */ - LPWSTR pszWork; - pszWork = pcmemRefText->GetStringPtr(); - /* 有効になっている辞書を全部なめて、ヒットの都度説明の継ぎ増し */ - if(m_pTypeData->m_bUseKeyHelpAllSearch){ /* ヒットした次の辞書も検索 */ // 2006.04.10 fon - /* バッファに前のデータが詰まっていたらseparator挿入 */ - if(m_cTipWnd.m_cInfo.GetStringLength() != 0) - m_cTipWnd.m_cInfo.AppendString( LS(STR_ERR_DLGEDITVW5) ); - else - m_cTipWnd.m_cInfo.AppendString( LS(STR_ERR_DLGEDITVW6) ); /* 先頭の場合 */ - /* 辞書のパス挿入 */ - { - TCHAR szFile[MAX_PATH]; - // 2013.05.08 表示するのはファイル名(拡張子なし)のみにする - _tsplitpath( m_pTypeData->m_KeyHelpArr[i].m_szPath, NULL, NULL, szFile, NULL ); - m_cTipWnd.m_cInfo.AppendString( szFile ); - } - m_cTipWnd.m_cInfo.AppendString( _T("\n") ); - /* 前方一致でヒットした単語を挿入 */ - if(m_pTypeData->m_bUseKeyHelpPrefix){ /* 選択範囲で前方一致検索 */ - m_cTipWnd.m_cInfo.AppendString( pcmemRefKey->GetStringT() ); - m_cTipWnd.m_cInfo.AppendString( _T(" >>\n") ); - }/* 調査した「意味」を挿入 */ - m_cTipWnd.m_cInfo.AppendStringW( pszWork ); - delete pcmemRefText; - delete pcmemRefKey; // 2006.07.02 genta - /* タグジャンプ用の情報を残す */ - if(!m_cTipWnd.m_KeyWasHit){ - m_cTipWnd.m_nSearchDict=i; /* 辞書を開くとき最初にヒットした辞書を開く */ - m_cTipWnd.m_nSearchLine=nLine; - m_cTipWnd.m_KeyWasHit = TRUE; - } - } - else{ /* 最初のヒット項目のみ返す場合 */ - /* キーワードが入っていたらseparator挿入 */ - if(m_cTipWnd.m_cInfo.GetStringLength() != 0) - m_cTipWnd.m_cInfo.AppendString( _T("\n--------------------\n") ); - - /* 前方一致でヒットした単語を挿入 */ - if(m_pTypeData->m_bUseKeyHelpPrefix){ /* 選択範囲で前方一致検索 */ - m_cTipWnd.m_cInfo.AppendString( pcmemRefKey->GetStringT() ); - m_cTipWnd.m_cInfo.AppendString( _T(" >>\n") ); - } - - /* 調査した「意味」を挿入 */ - m_cTipWnd.m_cInfo.AppendStringW( pszWork ); - delete pcmemRefText; - delete pcmemRefKey; // 2006.07.02 genta - /* タグジャンプ用の情報を残す */ - m_cTipWnd.m_nSearchDict=i; - m_cTipWnd.m_nSearchLine=nLine; - m_cTipWnd.m_KeyWasHit = TRUE; - return TRUE; - } - } - } - } - if( m_cTipWnd.m_KeyWasHit != FALSE ){ - return TRUE; - } - /* 該当するキーがなかった場合 */ - return FALSE; -} - -bool CEditView::MiniMapCursorLineTip( POINT* po, RECT* rc, bool* pbHide ) -{ - *pbHide = true; - if( !m_bMiniMap ){ - return false; - } - // ウィンドウ内にマウスカーソルがあるか? - GetCursorPos( po ); - GetWindowRect( GetHwnd(), rc ); - rc->right -= ::GetSystemMetrics(SM_CXVSCROLL); - if( !PtInRect( rc, *po ) ){ - return false; - } - if(!( m_bInMenuLoop == FALSE && /* 1.メニュー モーダル ループに入っていない */ - 300 < ::GetTickCount() - m_dwTipTimer /* 2.一定時間以上、マウスが固定されている */ - ) ){ - return false; - } - if( WindowFromPoint( *po ) != GetHwnd() ){ - return false; - } - - CMyPoint ptClient(*po); - ScreenToClient( GetHwnd(), &ptClient ); - CLayoutPoint ptNew; - GetTextArea().ClientToLayout( ptClient, &ptNew ); - // 同じ行ならなにもしない - if( 0 == m_dwTipTimer && m_cTipWnd.m_nSearchLine == (Int)ptNew.y ){ - *pbHide = false; // 表示継続 - return false; - } - CNativeW cmemCurText; - CLayoutYInt nTipBeginLine = ptNew.y; - CLayoutYInt nTipEndLine = ptNew.y + CLayoutYInt(4); - for( CLayoutYInt nCurLine = nTipBeginLine; nCurLine < nTipEndLine; nCurLine++ ){ - const CLayout* pcLayout = NULL; - if( 0 <= nCurLine ){ - pcLayout = GetDocument()->m_cLayoutMgr.SearchLineByLayoutY( nCurLine ); - } - if( pcLayout ){ - CNativeW cmemCurLine; - { - CLogicInt nLineLen = pcLayout->GetLengthWithoutEOL(); - const wchar_t* pszData = pcLayout->GetPtr(); - int nLimitLength = 80; - int pre = 0; - int i = 0; - int k = 0; - int charSize = CNativeW::GetSizeOfChar( pszData, nLineLen, i ); - int charWidth = t_max(1, (int)(Int)CNativeW::GetKetaOfChar( pszData, nLineLen, i )); - int charType = 0; - // 連続する"\t" " " を " "1つにする - // 左からnLimitLengthまでの幅を切り取り - while( i + charSize <= (Int)nLineLen && k + charWidth <= nLimitLength ){ - if( pszData[i] == L'\t' || pszData[i] == L' ' ){ - if( charType == 0 ){ - cmemCurLine.AppendString( pszData + pre , i - pre ); - cmemCurLine.AppendString( L" " ); - charType = 1; - } - pre = i + charSize; - k++; - }else{ - k += charWidth; - charType = 0; - } - i += charSize; - charSize = CNativeW::GetSizeOfChar( pszData, nLineLen, i ); - charWidth = t_max(1, (int)(Int)CNativeW::GetKetaOfChar( pszData, nLineLen, i )); - } - cmemCurLine.AppendString( pszData + pre , i - pre ); - } - if( nTipBeginLine != nCurLine ){ - cmemCurText.AppendString( L"\n" ); - } - cmemCurLine.Replace( L"\\", L"\\\\" ); - cmemCurText.AppendNativeData( cmemCurLine ); - } - } - if( cmemCurText.GetStringLength() <= 0 ){ - return false; - } - m_cTipWnd.m_cKey = cmemCurText; - m_cTipWnd.m_cInfo = cmemCurText.GetStringT(); - m_cTipWnd.m_nSearchLine = (Int)ptNew.y; - m_dwTipTimer = 0; // 辞書Tipを表示している */ - m_poTipCurPos = *po; // 現在のマウスカーソル位置 */ - return true; // ここまで来ていればヒット・ワード -} - /* 現在カーソル位置単語または選択範囲より検索等のキーを取得 */ void CEditView::GetCurrentTextForSearch( CNativeW& cmemCurText, bool bStripMaxPath /* = true */, bool bTrimSpaceTab /* = false */ ) { === sakura_core/view/CEditView_Mouse.cpp ================================================================== --- sakura_core/view/CEditView_Mouse.cpp (revision 69505) +++ sakura_core/view/CEditView_Mouse.cpp (revision 69511) @@ -86,15 +86,7 @@ return; } - /* 辞書Tipが起動されている */ - if( 0 == m_dwTipTimer ){ - /* 辞書Tipを消す */ - m_cTipWnd.Hide(); - m_dwTipTimer = ::GetTickCount(); /* 辞書Tip起動タイマー */ - } - else{ - m_dwTipTimer = ::GetTickCount(); /* 辞書Tip起動タイマー */ - } + this->HideTooltip(); // 辞書Tipを消す // 2007.12.02 nasukoji トリプルクリックをチェック tripleClickMode = CheckTripleClick(ptMouse); @@ -968,18 +960,10 @@ return; } + // ツールチップ + AsWithHelpTooltip::OnMouseMove( xPos_, yPos_ ); + if( m_bMiniMap ){ - POINT po; - ::GetCursorPos( &po ); - // 辞書Tipが起動されている - if( 0 == m_dwTipTimer ){ - if( (m_poTipCurPos.x != po.x || m_poTipCurPos.y != po.y ) ){ - m_cTipWnd.Hide(); - m_dwTipTimer = ::GetTickCount(); - } - }else{ - m_dwTipTimer = ::GetTickCount(); - } if( m_bMiniMapMouseDown ){ CLayoutPoint ptNew; CTextArea& area = GetTextArea(); @@ -1041,20 +1025,7 @@ // マウスによる範囲選択中でない場合 POINT po; ::GetCursorPos( &po ); - // 2001/06/18 asa-o: 補完ウィンドウが表示されていない - if(!m_bHokan){ - /* 辞書Tipが起動されている */ - if( 0 == m_dwTipTimer ){ - if( (m_poTipCurPos.x != po.x || m_poTipCurPos.y != po.y ) ){ - /* 辞書Tipを消す */ - m_cTipWnd.Hide(); - m_dwTipTimer = ::GetTickCount(); /* 辞書Tip起動タイマー */ - } - }else{ - m_dwTipTimer = ::GetTickCount(); /* 辞書Tip起動タイマー */ - } - } - /* 現在のマウスカーソル位置→レイアウト位置 */ + CLayoutPoint ptNew; GetTextArea().ClientToLayout(ptMouse, &ptNew); @@ -1281,9 +1252,7 @@ } return; } -//m_dwTipTimerm_dwTipTimerm_dwTipTimer - #ifndef SPI_GETWHEELSCROLLCHARS #define SPI_GETWHEELSCROLLCHARS 0x006C #endif === sakura_core/cmd/CViewCommander.cpp ================================================================== --- sakura_core/cmd/CViewCommander.cpp (revision 69505) +++ sakura_core/cmd/CViewCommander.cpp (revision 69511) @@ -87,11 +87,9 @@ } ++GetDocument()->m_nCommandExecNum; /* コマンド実行回数 */ -// if( nCommand != F_COPY ){ - /* 辞書Tipを消す */ - m_pCommanderView->m_cTipWnd.Hide(); - m_pCommanderView->m_dwTipTimer = ::GetTickCount(); /* 辞書Tip起動タイマー */ -// } + + m_pCommanderView->HideTooltip(); // 辞書Tipを消す + /* 印刷プレビューモードか */ //@@@ 2002.01.14 YAZAKI 印刷プレビューをCPrintPreviewに独立させたことによる変更 if( GetEditWindow()->m_pPrintPreview && F_PRINT_PREVIEW != nCommand ){ === sakura_core/cmd/CViewCommander_CustMenu.cpp ================================================================== --- sakura_core/cmd/CViewCommander_CustMenu.cpp (revision 69505) +++ sakura_core/cmd/CViewCommander_CustMenu.cpp (revision 69511) @@ -24,20 +24,15 @@ /* 右クリックメニュー */ void CViewCommander::Command_MENU_RBUTTON( void ) { - int nId; - int nLength; -// HGLOBAL hgClip; -// char* pszClip; - int i; /* ポップアップメニュー(右クリック) */ - nId = m_pCommanderView->CreatePopUpMenu_R(); - if( 0 == nId ){ + switch( int nId = m_pCommanderView->CreatePopUpMenu_R() ){ + case 0: return; - } - switch( nId ){ + case IDM_COPYDICINFO: - const TCHAR* pszStr; - pszStr = m_pCommanderView->m_cTipWnd.m_cInfo.GetStringPtr( &nLength ); + { + const TCHAR* pszStr = m_pCommanderView->GetTooltipText(); + const int nLength = _tcslen( pszStr ); TCHAR* pszWork; pszWork = new TCHAR[nLength + 1]; @@ -45,7 +40,7 @@ pszWork[nLength] = _T('\0'); // 見た目と同じように、\n を CR+LFへ変換する - for( i = 0; i < nLength ; ++i){ + for( int i = 0; i < nLength ; ++i ) { if( pszWork[i] == _T('\\') && pszWork[i + 1] == _T('n')){ pszWork[i] = WCODE::CR; pszWork[i + 1] = WCODE::LF; @@ -56,14 +51,16 @@ delete[] pszWork; break; - + } case IDM_JUMPDICT: /* キーワード辞書ファイルを開く */ - if(m_pCommanderView->m_pTypeData->m_bUseKeyWordHelp){ /* キーワード辞書セレクトを使用する */ // 2006.04.10 fon + if( m_pCommanderView->m_pTypeData->m_bUseKeyWordHelp + && -1 != m_pCommanderView->GetLastHitKeywordDictionary() + ) { /* キーワード辞書セレクトを使用する */ // 2006.04.10 fon // Feb. 17, 2007 genta 相対パスを実行ファイル基準で開くように m_pCommanderView->TagJumpSub( - m_pCommanderView->m_pTypeData->m_KeyHelpArr[m_pCommanderView->m_cTipWnd.m_nSearchDict].m_szPath, - CMyPoint(1, m_pCommanderView->m_cTipWnd.m_nSearchLine), + m_pCommanderView->m_pTypeData->m_KeyHelpArr[m_pCommanderView->GetLastHitKeywordDictionary()].m_szPath, + CMyPoint(1, m_pCommanderView->GetLastHitKeywordLineNumber()), 0, true ); === sakura_core/CHokanMgr.cpp ================================================================== --- sakura_core/CHokanMgr.cpp (revision 69505) +++ sakura_core/CHokanMgr.cpp (revision 69511) @@ -677,10 +677,8 @@ INT nItem, nTopItem, nItemHeight; - POINT point; CEditView* pcEditView; HWND hwndCtrl; - RECT rcHokanWin; hwndCtrl = ::GetDlgItem( GetHwnd(), IDC_LIST_WORDS ); @@ -693,26 +691,62 @@ pcEditView = reinterpret_cast(m_lParam); - // すでに辞書Tipが表示されていたら - if( pcEditView->m_dwTipTimer == 0 ) - { - // 辞書Tipを消す - pcEditView -> m_cTipWnd.Hide(); - pcEditView -> m_dwTipTimer = ::GetTickCount(); - } + // 辞書Tipを消す + pcEditView->HideTooltip(); - // 表示する位置を決定 +/* + 2001/06/19 asa-o 選択中の単語が補完ウィンドウに表示されているなら辞書Tipを表示 +*/ nTopItem = List_GetTopIndex( hwndCtrl ); nItemHeight = List_GetItemHeight( hwndCtrl, 0 ); - point.x = m_poWin.x + m_nWidth; - point.y = m_poWin.y + 4 + (nItem - nTopItem) * nItemHeight; - // 2001/06/19 asa-o 選択中の単語が補完ウィンドウに表示されているなら辞書Tipを表示 - if( point.y > m_poWin.y && point.y < m_poWin.y + m_nHeight ) - { - ::SetRect( &rcHokanWin , m_poWin.x, m_poWin.y, m_poWin.x + m_nWidth, m_poWin.y + m_nHeight ); - if( !pcEditView -> ShowKeywordHelp( point, &szLabel[0], &rcHokanWin ) ) - pcEditView -> m_dwTipTimer = ::GetTickCount(); // 表示するべきキーワードヘルプが無い + POINT ptItem = { + m_poWin.x + m_nWidth, + m_poWin.y + 4 + (nItem - nTopItem) * nItemHeight + }; + RECT rcHokanWin = { + m_poWin.x, + m_poWin.y, + m_poWin.x + m_nWidth, + m_poWin.y + m_nHeight + }; + if( ptItem.y <= rcHokanWin.top || rcHokanWin.bottom <= ptItem.y ) { + return; } + + CEditView::KeywordHelpInfo khi = pcEditView->BuildHelpAbout( &szLabel[0] ); + if ( khi.dicNo == -1 ) { + return; + } + + CEditView::ShowTooltipOptions opt; + opt.text = khi.content; + opt.flags = CEditView::SHOW_INVISIBLE; + pcEditView->ShowTooltip( opt ); // SHOW_INVISIBLEなので表示はされないが情報は更新される。 + opt.flags ^= CEditView::SHOW_INVISIBLE; +/* + 辞書の表示位置決め +*/ + SIZE tipWin = pcEditView->GetTooltipSize(); + RECT rcDesktop; GetMonitorWorkRect( pcEditView->GetHwnd(), &rcDesktop ); + enum { + UNDECIDED = 0, SHOW_RIGHT, SHOW_LEFT + } LR = ( rcHokanWin.right + tipWin.cx < rcDesktop.right ) ? SHOW_RIGHT: // 右に入る + ( rcDesktop.left < rcHokanWin.left - tipWin.cx ) ? SHOW_LEFT: // 左に入る + ( rcDesktop.right - rcHokanWin.right > rcHokanWin.left ) ? SHOW_RIGHT: // 入らないが右の方が広い + SHOW_LEFT; // 入らないが左の方が広い +/* + 辞書Tipを表示 +*/ + if ( LR == SHOW_RIGHT ) { + opt.flags |= CEditView::SHOW_RIGHT; + opt.pos.x = rcHokanWin.right; + opt.pos.y = ptItem.y; + } else { + opt.flags |= CEditView::SHOW_LEFT; + opt.pos.x = rcHokanWin.left; + opt.pos.y = ptItem.y; + } + pcEditView->ShowTooltip( opt ); } // 2001/06/18 End === sakura_core/view/CTextArea.h ================================================================== --- sakura_core/view/CTextArea.h (revision 69505) +++ sakura_core/view/CTextArea.h (revision 69511) @@ -170,6 +170,7 @@ //計算 //! クライアント座標からレイアウト位置に変換する void ClientToLayout(CMyPoint ptClient, CLayoutPoint* pptLayout) const; + void LayoutToClient(CLayoutPoint ptLayout, CMyPoint* pptClient) const; // -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- // // 設定 // === sakura_core/view/CTextArea.cpp ================================================================== --- sakura_core/view/CTextArea.cpp (revision 69505) +++ sakura_core/view/CTextArea.cpp (revision 69511) @@ -295,6 +295,14 @@ ); } +void CTextArea::LayoutToClient(CLayoutPoint ptLayout, CMyPoint* pptClient) const +{ + const CEditView* pView=m_pEditView; + pptClient->Set( + Int( ptLayout.x - GetViewLeftCol() ) * pView->GetTextMetricsW().GetCharPxWidth() + GetAreaLeft(), + Int( ptLayout.y - GetViewTopLine() ) * pView->GetTextMetrics().GetHankakuDy() + GetAreaTop() + ); +} //! 行番号エリアも含む範囲 void CTextArea::GenerateTopRect (RECT* rc, CLayoutInt nLineCount) const