406 lines
11 KiB
C++
406 lines
11 KiB
C++
//////////////////////////////////////////////////////////////////////
|
|
//
|
|
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
|
|
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED
|
|
// TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
|
|
// PARTICULAR PURPOSE.
|
|
//
|
|
// Copyright (C) 2003 Microsoft Corporation. All rights reserved.
|
|
//
|
|
// ExtentVisual.cpp
|
|
//
|
|
// CRangeFromPointViewer
|
|
//
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
#include "Globals.h"
|
|
#include "TextService.h"
|
|
#include "RangeFromPoint.h"
|
|
#include "EditSession.h"
|
|
|
|
TCHAR CRangeFromPointViewer::_szWndClass[] = TEXT("RangeFromPointViewer");
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// CRangeFromPointViewer
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// ctor
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
CRangeFromPointViewer::CRangeFromPointViewer(CExtentMonitorTextService *pTextService, WCHAR *psz, COLORREF cr)
|
|
{
|
|
_hwnd = NULL;
|
|
StringCchCopy(_sz, ARRAYSIZE(_sz), psz);
|
|
_cr = cr;
|
|
_pTextService = pTextService;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// dtor
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
CRangeFromPointViewer::~CRangeFromPointViewer()
|
|
{
|
|
if (IsWindow(_hwnd))
|
|
DestroyWindow(_hwnd);
|
|
}
|
|
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// StaticInit
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
BOOL CRangeFromPointViewer::StaticInit()
|
|
{
|
|
|
|
WNDCLASSEX wcex;
|
|
|
|
memset(&wcex, 0, sizeof(wcex));
|
|
wcex.cbSize = sizeof(wcex);
|
|
wcex.style = CS_HREDRAW | CS_VREDRAW ;
|
|
wcex.hInstance = g_hInst;
|
|
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
|
|
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
|
|
|
|
wcex.lpfnWndProc = _WndProc;
|
|
wcex.lpszClassName = _szWndClass;
|
|
RegisterClassEx(&wcex);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// CreateWnd
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
HWND CRangeFromPointViewer::CreateWnd()
|
|
{
|
|
if (_hwnd)
|
|
return _hwnd;
|
|
|
|
_hwnd = CreateWindowEx(WS_EX_TOPMOST | WS_EX_LAYERED, _szWndClass, TEXT(""),
|
|
WS_POPUP | WS_DISABLED,
|
|
0, 0, 0, 0,
|
|
NULL, 0, g_hInst, this);
|
|
|
|
// SetLayeredWindowAttributes(_hwnd, _cr, 240, LWA_COLORKEY | LWA_ALPHA);
|
|
SetLayeredWindowAttributes(_hwnd, 0, 128, LWA_ALPHA);
|
|
|
|
return _hwnd;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// _OwnerWndProc
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
LRESULT CALLBACK CRangeFromPointViewer::_WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
CRangeFromPointViewer *_this;
|
|
HDC hdc;
|
|
PAINTSTRUCT ps;
|
|
|
|
_this = _GetThis(hwnd);
|
|
|
|
switch (uMsg)
|
|
{
|
|
case WM_CREATE:
|
|
_SetThis(hwnd, lParam);
|
|
return 0;
|
|
|
|
case WM_SETCURSOR:
|
|
if (_this)
|
|
_this->OnSetCursor(hwnd, wParam, lParam);
|
|
break;
|
|
|
|
case WM_PAINT:
|
|
hdc = BeginPaint(hwnd, &ps);
|
|
if (_this)
|
|
_this->OnPaint(hwnd, hdc);
|
|
EndPaint(hwnd, &ps);
|
|
break;
|
|
|
|
default:
|
|
return DefWindowProc(hwnd, uMsg, wParam, lParam);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Show
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
void CRangeFromPointViewer::Show(RECT *prc)
|
|
{
|
|
if (!IsWindow(_hwnd))
|
|
return;
|
|
|
|
InvalidateRect(_hwnd, NULL, TRUE);
|
|
SetWindowPos(_hwnd,
|
|
HWND_TOPMOST,
|
|
prc->left,
|
|
prc->top,
|
|
prc->right - prc->left > 2 ? prc->right - prc->left : 2,
|
|
prc->bottom - prc->top > 2 ? prc->bottom - prc->top : 2,
|
|
SWP_SHOWWINDOW | SWP_NOACTIVATE);
|
|
|
|
}
|
|
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Hide
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
void CRangeFromPointViewer::Hide()
|
|
{
|
|
if (!IsWindow(_hwnd))
|
|
return;
|
|
|
|
ShowWindow(_hwnd, SW_HIDE);
|
|
}
|
|
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// OnPaint
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
void CRangeFromPointViewer::OnPaint(HWND hwnd, HDC hdc)
|
|
{
|
|
HFONT hfont = (HFONT)GetStockObject(DEFAULT_GUI_FONT);
|
|
HFONT hfontOld = (HFONT)SelectObject(hdc, hfont);
|
|
|
|
RECT rc;
|
|
GetClientRect(hwnd, &rc);
|
|
SetBkColor(hdc, _cr);
|
|
// ExtTextOutW(hdc, 2, 2, ETO_OPAQUE, &rc, _sz, lstrlenW(_sz), NULL);
|
|
ExtTextOutW(hdc, 2, 2, ETO_OPAQUE, &rc, _sz, 0, NULL);
|
|
|
|
if (_fIsRectNearest)
|
|
FrameRect(hdc, &_rcNearest, (HBRUSH)GetStockObject(BLACK_BRUSH));
|
|
|
|
SelectObject(hdc, hfontOld);
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// OnSetCursor
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
void CRangeFromPointViewer::OnSetCursor(HWND hwnd, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
POINT pt;
|
|
|
|
switch (HIWORD(lParam))
|
|
{
|
|
case WM_LBUTTONDOWN:
|
|
_fIsRect = FALSE;
|
|
_fIsRectRoundNearest = FALSE;
|
|
_fIsRectNearest = FALSE;
|
|
GetCursorPos( &pt );
|
|
_pTextService->GetRectFromPointOnFocusDocument(pt);
|
|
break;
|
|
|
|
case WM_RBUTTONDOWN:
|
|
_fIsRect = FALSE;
|
|
_fIsRectRoundNearest = FALSE;
|
|
_fIsRectNearest = FALSE;
|
|
InvalidateRect(_hwnd, NULL, TRUE);
|
|
break;
|
|
}
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// _EnsurePopupWindow
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
void CExtentMonitorTextService::_EnsureRangeFromPointViewer()
|
|
{
|
|
if (!_pRangeFromPointViewer)
|
|
_pRangeFromPointViewer = new CRangeFromPointViewer(this, L"View", 0xD00000);
|
|
if (_pRangeFromPointViewer)
|
|
_pRangeFromPointViewer->CreateWnd();
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// _UpdatePopupWindow
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
void CExtentMonitorTextService::_UpdateRangeFromPointViewer()
|
|
{
|
|
if (_pRangeFromPointViewer)
|
|
{
|
|
_pRangeFromPointViewer->Show(&_rcView);
|
|
}
|
|
|
|
_fIsShownRangeFromPointViewer = TRUE;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// _HidePopupWindow
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
void CExtentMonitorTextService::_HideRangeFromPointViewer()
|
|
{
|
|
if (_pRangeFromPointViewer)
|
|
_pRangeFromPointViewer->Hide();
|
|
|
|
_fIsShownRangeFromPointViewer = FALSE;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// CGetRectFromPointEditSession
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
class CGetRectFromPointEditSession : public CEditSessionBase
|
|
{
|
|
public:
|
|
CGetRectFromPointEditSession(CExtentMonitorTextService *pTextService, ITfContext *pContext, POINT pt) : CEditSessionBase(pTextService, pContext)
|
|
{
|
|
_pt = pt;
|
|
}
|
|
|
|
// ITfEditSession
|
|
STDMETHODIMP DoEditSession(TfEditCookie ec);
|
|
|
|
POINT _pt;
|
|
|
|
};
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// DoEditSession
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
STDAPI CGetRectFromPointEditSession::DoEditSession(TfEditCookie ec)
|
|
{
|
|
_pTextService->_GetRectFromPoint(ec, _pContext, _pt);
|
|
return S_OK;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// GetRectFromPointOnFocusDocument
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
void CExtentMonitorTextService::GetRectFromPointOnFocusDocument(POINT pt)
|
|
{
|
|
ITfDocumentMgr *pDocMgrFocus;
|
|
if ((_pThreadMgr->GetFocus(&pDocMgrFocus) == S_OK) &&
|
|
(pDocMgrFocus != NULL))
|
|
{
|
|
ITfContext *pContext;
|
|
if (SUCCEEDED(pDocMgrFocus->GetBase(&pContext)))
|
|
{
|
|
CGetRectFromPointEditSession *pEditSession;
|
|
HRESULT hr = E_FAIL;
|
|
|
|
if ((pEditSession = new CGetRectFromPointEditSession(this, pContext, pt)) != NULL)
|
|
{
|
|
pContext->RequestEditSession(_tfClientId, pEditSession, TF_ES_ASYNCDONTCARE | TF_ES_READ, &hr);
|
|
pEditSession->Release();
|
|
}
|
|
|
|
pContext->Release();
|
|
}
|
|
pDocMgrFocus->Release();
|
|
}
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// _GetRectFromPoint
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
void CExtentMonitorTextService::_GetRectFromPoint(TfEditCookie ec, ITfContext *pContext, POINT pt)
|
|
{
|
|
ITfContextView *pContextView;
|
|
|
|
if (!_pRangeFromPointViewer)
|
|
return;
|
|
|
|
if (SUCCEEDED(pContext->GetActiveView(&pContextView)))
|
|
{
|
|
ITfRange *pRange;
|
|
ITfRange *pRangeRoundNearest;
|
|
ITfRange *pRangeNearest;
|
|
BOOL fClipped;
|
|
RECT rcScreen = {0};
|
|
|
|
if (SUCCEEDED(pContextView->GetScreenExt(&rcScreen)))
|
|
{
|
|
_pRangeFromPointViewer->_fIsRect = FALSE;
|
|
if (SUCCEEDED(pContextView->GetRangeFromPoint(ec, &pt, 0, &pRange)))
|
|
{
|
|
if (SUCCEEDED(pContextView->GetTextExt(ec, pRange, &_pRangeFromPointViewer->_rc, &fClipped)))
|
|
{
|
|
OffsetRect(&_pRangeFromPointViewer->_rc, 0 - rcScreen.left, 0 - rcScreen.top);
|
|
_pRangeFromPointViewer->_fIsRect = TRUE;
|
|
}
|
|
pRange->Release();
|
|
}
|
|
|
|
_pRangeFromPointViewer->_fIsRectRoundNearest = FALSE;
|
|
if (SUCCEEDED(pContextView->GetRangeFromPoint(ec, &pt, GXFPF_ROUND_NEAREST, &pRangeRoundNearest)))
|
|
{
|
|
if (SUCCEEDED(pContextView->GetTextExt(ec, pRangeRoundNearest, &_pRangeFromPointViewer->_rcRoundNearest, &fClipped)))
|
|
{
|
|
OffsetRect(&_pRangeFromPointViewer->_rcRoundNearest, 0 - rcScreen.left, 0 - rcScreen.top);
|
|
_pRangeFromPointViewer->_fIsRectRoundNearest = TRUE;
|
|
}
|
|
pRangeRoundNearest->Release();
|
|
}
|
|
|
|
_pRangeFromPointViewer->_fIsRectNearest = FALSE;
|
|
if (SUCCEEDED(pContextView->GetRangeFromPoint(ec, &pt, GXFPF_NEAREST, &pRangeNearest)))
|
|
{
|
|
if (SUCCEEDED(pContextView->GetTextExt(ec, pRangeNearest, &_pRangeFromPointViewer->_rcNearest, &fClipped)))
|
|
{
|
|
OffsetRect(&_pRangeFromPointViewer->_rcNearest, 0 - rcScreen.left, 0 - rcScreen.top);
|
|
_pRangeFromPointViewer->_fIsRectNearest = TRUE;
|
|
}
|
|
pRangeNearest->Release();
|
|
}
|
|
}
|
|
|
|
pContextView->Release();
|
|
}
|
|
|
|
|
|
if (IsShownRangeFromPointViewer())
|
|
_UpdateRangeFromPointViewer();
|
|
|
|
}
|
|
|
|
|