2674 lines
75 KiB
C++
2674 lines
75 KiB
C++
/******************************************************************************/
|
|
/* Tedit.CPP: IMPLEMENTATION OF THE CTedit CLASS */
|
|
/* */
|
|
/* */
|
|
/******************************************************************************/
|
|
/* */
|
|
/* Methods in this file */
|
|
/* */
|
|
/* Edit Control Object */
|
|
/* CAttrEdit::OnPaint */
|
|
/* CAttrEdit::OnEraseBkgnd */
|
|
/* CAttrEdit::OnRButtonDown */
|
|
/* CAttrEdit::OnChar */
|
|
/* CAttrEdit::OnMouseMove */
|
|
/* */
|
|
/******************************************************************************/
|
|
/* */
|
|
/* Text Edit Control Parent Window (Parent of Edit Control) */
|
|
/* CTedit::CTedit */
|
|
/* CTedit::CTedit */
|
|
/* CTedit::~CTedit */
|
|
/* */
|
|
/* Miscellaneous Methods */
|
|
/* CTedit::RefreshWindow */
|
|
/* CTedit::SetTextColor */
|
|
/* CTedit::SetBackColor */
|
|
/* CTedit::SetTransparentMode */
|
|
/* CTedit::Undo */
|
|
/* CTedit::ShowFontPalette */
|
|
/* CTedit::IsFontPaletteVisible */
|
|
/* CTedit::GetBitmap */
|
|
/* CTedit::PostNcDestroy */
|
|
/* CTedit::GetDefaultMinSize */
|
|
/* */
|
|
/* Edit Control Notification and processing methods */
|
|
/* CTedit::OnAttrEditEnChange */
|
|
/* CTedit::OnAttrEditFontChange */
|
|
/* */
|
|
/* Control Notification/Window Messages */
|
|
/* CTedit::OnEraseBkgnd */
|
|
/* CTedit::OnSize */
|
|
/* CTedit::OnMove */
|
|
/* CTedit::OnCtlColor */
|
|
/* CTedit::OnNcCalcSize */
|
|
/* CTedit::OnNcPaint */
|
|
/* CTedit::OnNcHitTest */
|
|
/* CTedit::OnRButtonDown */
|
|
/* */
|
|
/* Popup Menu Control Notification/Window Messages */
|
|
/* CTedit::OnTextPlain */
|
|
/* CTedit::OnTextBold */
|
|
/* CTedit::OnTextItalic */
|
|
/* CTedit::OnTextUnderline */
|
|
/* CTedit::OnTextSelectfont */
|
|
/* CTedit::OnTextSelectpointsize */
|
|
/* CTedit::OnEditCut */
|
|
/* CTedit::OnEditCopy */
|
|
/* CTedit::OnEditPaste */
|
|
/* CTedit::OnTextDelete */
|
|
/* CTedit::OnTextSelectall */
|
|
/* CTedit::OnTextPlace */
|
|
/* CTedit::OnTextTexttool */
|
|
/* */
|
|
/* CTedit::OnUpdateTextPlain */
|
|
/* CTedit::OnUpdateTextBold */
|
|
/* CTedit::OnUpdateTextItalic */
|
|
/* CTedit::OnUpdateTextUnderline */
|
|
/* CTedit::OnUpdateTextTexttool */
|
|
/* */
|
|
/******************************************************************************/
|
|
|
|
// TEDIT.CPP: IMPLEMENTATION OF THE CTEDIT CLASS
|
|
//
|
|
#include "stdafx.h"
|
|
#include "global.h"
|
|
#include "pbrush.h"
|
|
#include "pbrusvw.h"
|
|
#include "pbrusfrm.h"
|
|
#include "imgwnd.h"
|
|
#include "pictures.h"
|
|
#include "minifwnd.h"
|
|
#include "tfont.h"
|
|
#include "tedit.h"
|
|
#include "tracker.h"
|
|
|
|
#include <imm.h>
|
|
|
|
#include "imgsuprt.h"
|
|
|
|
#ifndef WM_SYSTIMER
|
|
#define WM_SYSTIMER 0x118
|
|
#endif //WM_SYSTIMER
|
|
|
|
|
|
#ifdef _DEBUG
|
|
#undef THIS_FILE
|
|
static CHAR BASED_CODE THIS_FILE[] = __FILE__;
|
|
#endif
|
|
|
|
IMPLEMENT_DYNCREATE( CAttrEdit, CEdit )
|
|
IMPLEMENT_DYNCREATE( CTedit, CWnd )
|
|
|
|
#include "memtrace.h"
|
|
|
|
|
|
|
|
|
|
/******************************************************************************/
|
|
// CAttrEdit
|
|
|
|
BEGIN_MESSAGE_MAP( CAttrEdit, CEdit )
|
|
//{{AFX_MSG_MAP(CAttrEdit)
|
|
ON_WM_PAINT()
|
|
ON_WM_ERASEBKGND()
|
|
ON_WM_RBUTTONDOWN()
|
|
ON_WM_CHAR()
|
|
|
|
ON_MESSAGE(WM_IME_CHAR, OnImeChar)
|
|
ON_MESSAGE(WM_IME_COMPOSITION, OnImeComposition)
|
|
ON_MESSAGE(WM_INPUTLANGCHANGE, OnInputLangChange)
|
|
ON_WM_KILLFOCUS()
|
|
|
|
|
|
ON_WM_NCHITTEST()
|
|
ON_WM_SETFOCUS()
|
|
ON_WM_SIZE()
|
|
ON_WM_LBUTTONDBLCLK()
|
|
ON_WM_LBUTTONDOWN()
|
|
ON_WM_MOUSEMOVE()
|
|
ON_WM_LBUTTONUP()
|
|
ON_WM_KEYDOWN()
|
|
ON_MESSAGE(WM_SYSTIMER, OnSysTimer)
|
|
|
|
//}}AFX_MSG_MAP
|
|
END_MESSAGE_MAP()
|
|
|
|
/******************************************************************************/
|
|
|
|
CAttrEdit::CAttrEdit()
|
|
{
|
|
m_bBackgroundTransparent = TRUE;
|
|
m_pParentWnd = NULL;
|
|
m_uiLastChar[0] = 32;
|
|
m_uiLastChar[1] = 32;
|
|
|
|
m_rectUpdate.SetRectEmpty();
|
|
|
|
|
|
m_strResult.Empty();
|
|
m_bMouseDown = FALSE;
|
|
m_hHCursor = theApp.LoadStandardCursor( IDC_IBEAM );
|
|
m_hVCursor = theApp.LoadCursor( IDCUR_HIBEAM );
|
|
m_hOldCursor = NULL;
|
|
m_rectFmt.SetRectEmpty();
|
|
m_iPrevStart = -1;
|
|
m_bResizeOnly = FALSE;
|
|
|
|
}
|
|
|
|
/******************************************************************************/
|
|
|
|
void CAttrEdit::OnPaint()
|
|
{
|
|
GetUpdateRect( &m_rectUpdate );
|
|
|
|
|
|
if ( !m_pParentWnd->m_bVertEdit )
|
|
{
|
|
Default();
|
|
return;
|
|
}
|
|
else
|
|
{
|
|
CFont* pFont;
|
|
CFont* pOldFont = NULL;
|
|
CPalette* ppalOld = NULL;
|
|
int OldBkMode;
|
|
COLORREF OldTxtColor;
|
|
CRect rc = m_rectFmt;
|
|
int cnt = 0;
|
|
int i = 0, h = 0;
|
|
int nLen;
|
|
CString cStr;
|
|
LPTSTR lpStr;
|
|
int nStart, nEnd;
|
|
CDC* pDC = NULL;
|
|
PAINTSTRUCT ps;
|
|
|
|
const MSG *pCurrentMessage = GetCurrentMessage();
|
|
//wParam is DC
|
|
if ( pCurrentMessage->wParam )
|
|
{
|
|
HDC hDC = (HDC) pCurrentMessage->wParam;
|
|
pDC = CDC::FromHandle( hDC );
|
|
}
|
|
else
|
|
pDC = BeginPaint( &ps );
|
|
|
|
if (pDC == NULL || pDC->m_hDC == NULL)
|
|
{
|
|
theApp.SetGdiEmergency();
|
|
return;
|
|
}
|
|
|
|
OldBkMode = pDC->GetBkMode();
|
|
OldTxtColor = pDC->GetTextColor();
|
|
ppalOld = PBSelectPalette(pDC, theApp.m_pPalette, FALSE);
|
|
|
|
m_pParentWnd->SendMessage( WM_CTLCOLOREDIT, (WPARAM)pDC->m_hDC,
|
|
(LPARAM) m_hWnd );
|
|
|
|
pFont = GetFont();
|
|
pOldFont = pDC->SelectObject( pFont );
|
|
|
|
h = m_pParentWnd->m_iLineHeight;
|
|
|
|
cnt = GetLineCount();
|
|
|
|
GetSel( nStart, nEnd );
|
|
if ( nStart == nEnd )
|
|
{
|
|
for ( i = 0; i < cnt; i++ )
|
|
{
|
|
nLen = LineLength( LineIndex( i ) );
|
|
lpStr = cStr.GetBufferSetLength( nLen );
|
|
GetLine( i, lpStr, nLen );
|
|
TabTextOut( pDC, LineIndex( i ), rc.right - h * i, 0,
|
|
(LPTSTR)lpStr, nLen, FALSE );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
int nStartLn, nEndLn;
|
|
int nMaxText = GetWindowTextLength();
|
|
int nChar = 0;
|
|
|
|
nStartLn = LineFromChar( nStart );
|
|
nEndLn = LineFromChar( nEnd );
|
|
|
|
//Before Start
|
|
for ( i = 0; i < nStartLn; i++ )
|
|
{
|
|
nLen = LineLength( LineIndex( i ) );
|
|
lpStr = cStr.GetBufferSetLength( nLen );
|
|
GetLine( i, lpStr, nLen );
|
|
TabTextOut( pDC, LineIndex( i ), rc.right - h * i, 0,
|
|
(LPTSTR)lpStr, nLen, FALSE );
|
|
nChar = LineIndex( i + 1 );
|
|
}
|
|
nLen = LineLength( LineIndex( i ) );
|
|
lpStr = cStr.GetBufferSetLength( nLen );
|
|
GetLine( i, lpStr, nLen );
|
|
TabTextOut( pDC, LineIndex( i ), rc.right - h * i, 0,
|
|
(LPTSTR)lpStr, nStart - nChar, FALSE );
|
|
|
|
//Selected Text
|
|
COLORREF bkColor = pDC->SetBkColor( GetSysColor(COLOR_HIGHLIGHT) );
|
|
COLORREF txtColor = pDC->SetTextColor( GetSysColor(COLOR_HIGHLIGHTTEXT) );
|
|
int bkMode = pDC->SetBkMode( OPAQUE );
|
|
|
|
CPoint ptStart( (DWORD)SendMessage( EM_POSFROMCHAR, nStart ) );
|
|
if ( nStartLn == nEndLn )
|
|
{
|
|
TabTextOut( pDC, nStart, rc.right - h * i, ptStart.x,
|
|
(LPTSTR)lpStr + (nStart - nChar), nEnd - nStart, TRUE );
|
|
}
|
|
else
|
|
{
|
|
TabTextOut( pDC, nStart, rc.right - h * i, ptStart.x,
|
|
(LPTSTR)lpStr + (nStart - nChar), nLen + nChar - nStart, TRUE );
|
|
nChar = LineIndex( i + 1 );
|
|
|
|
for ( i++; i < nEndLn; i++ )
|
|
{
|
|
nLen = LineLength( LineIndex( i ) );
|
|
lpStr = cStr.GetBufferSetLength( nLen );
|
|
GetLine( i, lpStr, nLen );
|
|
TabTextOut( pDC, nChar, rc.right - h * i, 0,
|
|
(LPTSTR)lpStr, nLen, TRUE );
|
|
nChar = LineIndex( i + 1 );
|
|
}
|
|
|
|
nLen = LineLength( LineIndex( i ) );
|
|
lpStr = cStr.GetBufferSetLength( nLen );
|
|
GetLine( i, lpStr, nLen );
|
|
TabTextOut( pDC, nChar, rc.right - h * i, 0,
|
|
(LPTSTR)lpStr, nEnd - nChar, TRUE );
|
|
}
|
|
|
|
pDC->SetBkColor( bkColor );
|
|
pDC->SetTextColor( txtColor );
|
|
pDC->SetBkMode( bkMode );
|
|
|
|
//After End
|
|
if ( nEnd < nMaxText )
|
|
{
|
|
CPoint ptEnd( (DWORD)SendMessage( EM_POSFROMCHAR, nEnd ) );
|
|
TabTextOut( pDC, nEnd, rc.right - h * i, ptEnd.x,
|
|
(LPTSTR)lpStr + (nEnd - nChar), nChar + nLen - nEnd, FALSE );
|
|
for ( i++; i < cnt; i++ )
|
|
{
|
|
nLen = LineLength( LineIndex( i ) );
|
|
lpStr = cStr.GetBufferSetLength( nLen );
|
|
GetLine( i, lpStr, nLen );
|
|
TabTextOut( pDC, LineIndex( i ), rc.right - h * i, 0,
|
|
(LPTSTR)lpStr, nLen, FALSE );
|
|
}
|
|
}
|
|
}
|
|
|
|
cStr.Empty();
|
|
|
|
if (pOldFont) pDC->SelectObject( pOldFont );
|
|
if (ppalOld) pDC->SelectPalette( ppalOld, FALSE );
|
|
pDC->SetBkMode( OldBkMode );
|
|
pDC->SetTextColor( OldTxtColor );
|
|
|
|
if ( !pCurrentMessage->wParam )
|
|
EndPaint( &ps );
|
|
}
|
|
}
|
|
|
|
/******************************************************************************/
|
|
|
|
BOOL CAttrEdit::OnEraseBkgnd( CDC* pDC )
|
|
{
|
|
if (m_pParentWnd == NULL)
|
|
return CEdit::OnEraseBkgnd( pDC );
|
|
|
|
ASSERT( m_pParentWnd->m_pImgWnd->m_pImg != NULL );
|
|
ASSERT( m_pParentWnd->m_pImgWnd->m_pImg->hDC != NULL );
|
|
|
|
CPalette* ppalOld = NULL;
|
|
|
|
if (m_rectUpdate.IsRectEmpty())
|
|
{
|
|
if (! GetUpdateRect( &m_rectUpdate, FALSE ))
|
|
GetClientRect( &m_rectUpdate );
|
|
|
|
ValidateRect( &m_rectUpdate );
|
|
}
|
|
CRect destRect = m_rectUpdate;
|
|
|
|
ClientToScreen( &m_rectUpdate );
|
|
|
|
m_pParentWnd->m_pImgWnd->ScreenToClient( &m_rectUpdate );
|
|
|
|
ppalOld = PBSelectPalette(pDC, theApp.m_pPalette, FALSE);
|
|
|
|
if (m_bBackgroundTransparent)
|
|
m_pParentWnd->m_pImgWnd->DrawImage( pDC, &m_rectUpdate, &destRect );
|
|
else
|
|
pDC->FillRect( &destRect, &m_pParentWnd->m_hbrBkColor );
|
|
|
|
if (ppalOld)
|
|
pDC->SelectPalette( ppalOld, FALSE );
|
|
|
|
m_rectUpdate.SetRectEmpty();
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
/******************************************************************************/
|
|
|
|
void CAttrEdit::OnRButtonDown(UINT nFlags, CPoint point)
|
|
{
|
|
const MSG *pCurrentMessage = GetCurrentMessage();
|
|
|
|
m_pParentWnd->SendMessage( pCurrentMessage->message,
|
|
pCurrentMessage->wParam,
|
|
pCurrentMessage->lParam);
|
|
}
|
|
|
|
/******************************************************************************/
|
|
|
|
void CAttrEdit::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)
|
|
{
|
|
|
|
m_uiLastChar[0] = m_uiLastChar[1];
|
|
|
|
#ifndef UNICODE
|
|
//
|
|
// For DBCS we have to peek for the trail byte if the current
|
|
// byte is a lead byte
|
|
//
|
|
if (IsDBCSLeadByte((BYTE)nChar))
|
|
{
|
|
MSG msg;
|
|
ZeroMemory (&msg, sizeof(msg));
|
|
::PeekMessage (&msg, m_hWnd, WM_CHAR, WM_CHAR, PM_NOREMOVE);
|
|
m_uiLastChar[1] = (UINT)MAKEWORD((BYTE)msg.wParam, (BYTE)nChar);
|
|
}
|
|
else
|
|
#endif // UNICODE
|
|
m_uiLastChar[1] = nChar;
|
|
|
|
|
|
if ( m_pParentWnd->m_bVertEdit )
|
|
{
|
|
SetCaretPosition( TRUE, NULL, -1 );
|
|
UpdateInput();
|
|
HideCaret();
|
|
}
|
|
|
|
CEdit::OnChar( nChar, nRepCnt, nFlags );
|
|
|
|
if ( m_pParentWnd->m_bVertEdit )
|
|
{
|
|
SetCaretShape();
|
|
UpdateInput();
|
|
ShowCaret();
|
|
}
|
|
|
|
|
|
BOOL bRefresh = FALSE;
|
|
|
|
switch (nChar)
|
|
{
|
|
case VK_BACK:
|
|
case VK_DELETE:
|
|
case VK_INSERT:
|
|
bRefresh = TRUE;
|
|
|
|
break;
|
|
}
|
|
|
|
if (bRefresh)
|
|
m_pParentWnd->RefreshWindow(); /* enhance to do only the character involved */
|
|
|
|
|
|
//
|
|
// The edit control may have to resize
|
|
//
|
|
m_bResizeOnly = TRUE;
|
|
m_pParentWnd->OnEnMaxText ();
|
|
m_bResizeOnly = FALSE;
|
|
|
|
}
|
|
|
|
|
|
/******************************************************************************/
|
|
|
|
LRESULT CAttrEdit::OnInputLangChange( WPARAM wParam, LPARAM lParam )
|
|
{
|
|
LRESULT lRet = Default();
|
|
|
|
if ( m_pParentWnd->m_bVertEdit )
|
|
{
|
|
SetCaretPosition( TRUE, NULL, -1 );
|
|
}
|
|
return lRet;
|
|
}
|
|
|
|
/******************************************************************************/
|
|
|
|
LRESULT CAttrEdit::OnImeChar( WPARAM wParam, LPARAM lParam )
|
|
{
|
|
|
|
|
|
|
|
if ( m_pParentWnd->m_bVertEdit )
|
|
{
|
|
SetCaretPosition( TRUE, NULL, -1 );
|
|
UpdateInput();
|
|
HideCaret();
|
|
}
|
|
|
|
|
|
return Default();
|
|
|
|
}
|
|
|
|
/******************************************************************************/
|
|
|
|
LRESULT CAttrEdit::OnImeComposition( WPARAM wParam, LPARAM lParam )
|
|
{
|
|
// Use Faster Way undr Japanese Keyboard Layout (Japanese IME)
|
|
// Japanese IME may generate lots of chars at one time.
|
|
// This way is better than waiting WM_CHAR.
|
|
|
|
DWORD dwKeyboardLayout = PRIMARYLANGID(LOWORD(GetKeyboardLayout(0)));
|
|
|
|
if ( dwKeyboardLayout == LANG_JAPANESE)
|
|
{
|
|
if (lParam & GCS_RESULTSTR)
|
|
{
|
|
HIMC hIMC = ImmGetContext(m_hWnd);
|
|
|
|
DWORD dwSize;
|
|
if (hIMC &&
|
|
(dwSize = ImmGetCompositionString(hIMC,GCS_RESULTSTR,NULL,0L)))
|
|
{
|
|
// ImmGetCompositionString returns the buffer size, IN BYTES.
|
|
// even if Unicode version.
|
|
LPTSTR lp = m_strResult.GetBufferSetLength(dwSize);
|
|
ImmGetCompositionString(hIMC,GCS_RESULTSTR,lp,dwSize+sizeof(TCHAR));
|
|
*(lp + dwSize/sizeof(TCHAR)) = TEXT('\0');
|
|
ReplaceSel(lp);
|
|
m_strResult.Empty();
|
|
}
|
|
|
|
ImmReleaseContext(m_hWnd, hIMC);
|
|
|
|
lParam &= ~( GCS_RESULTREADSTR | GCS_RESULTREADCLAUSE | GCS_RESULTSTR | GCS_RESULTCLAUSE);
|
|
if (lParam)
|
|
DefWindowProc(WM_IME_COMPOSITION,wParam,lParam);
|
|
|
|
// We'are not sure, how IME hide its composiiton window.
|
|
m_pParentWnd->RefreshWindow();
|
|
return 0;
|
|
}
|
|
}
|
|
else if ( dwKeyboardLayout == LANG_KOREAN)
|
|
{
|
|
if ( m_pParentWnd->m_bVertEdit ) {
|
|
|
|
Default();
|
|
|
|
SetCaretPosition( FALSE, NULL, -2);
|
|
|
|
// We should update current composition string.
|
|
UpdateInput();
|
|
return 0;
|
|
}
|
|
else {
|
|
// We should update current composition string.
|
|
UpdateInput();
|
|
return Default();
|
|
}
|
|
}
|
|
|
|
return Default();
|
|
}
|
|
|
|
/******************************************************************************/
|
|
|
|
void CAttrEdit::OnKillFocus(CWnd* pNewWnd)
|
|
{
|
|
HIMC hIMC = ImmGetContext(m_hWnd);
|
|
ImmNotifyIME(hIMC, NI_COMPOSITIONSTR, CPS_COMPLETE, 0L);
|
|
ImmReleaseContext(m_hWnd, hIMC);
|
|
|
|
CEdit::OnKillFocus(pNewWnd);
|
|
|
|
|
|
if ( m_pParentWnd->m_bVertEdit )
|
|
{
|
|
SetFmtRect();
|
|
Repaint();
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
/******************************************************************************/
|
|
|
|
UINT CAttrEdit::OnNcHitTest( CPoint point )
|
|
{
|
|
const MSG *pCurrentMessage = GetCurrentMessage();
|
|
UINT uiHitTestCode = (UINT)DefWindowProc( pCurrentMessage->message,
|
|
pCurrentMessage->wParam,
|
|
pCurrentMessage->lParam);
|
|
|
|
if ( (uiHitTestCode == HTCLIENT) )
|
|
{
|
|
if ( (m_pParentWnd->m_bVertEdit) ) SetVCursorShape();
|
|
else SetHCursorShape();
|
|
}
|
|
|
|
return uiHitTestCode;
|
|
}
|
|
|
|
/******************************************************************************/
|
|
|
|
void CAttrEdit::OnSetFocus( CWnd* pOldWnd )
|
|
{
|
|
Default();
|
|
|
|
if ( m_pParentWnd->m_bVertEdit )
|
|
{
|
|
SetCaretShape();
|
|
SetCaretPosition( FALSE, NULL, -1 );
|
|
Repaint();
|
|
}
|
|
}
|
|
|
|
/******************************************************************************/
|
|
|
|
void CAttrEdit::OnSize( UINT nType, int cx, int cy )
|
|
{
|
|
Default();
|
|
|
|
m_rectFmt.left = m_rectFmt.top = 0;
|
|
m_rectFmt.right = cx;
|
|
m_rectFmt.bottom = cy;
|
|
|
|
SetFmtRect();
|
|
}
|
|
|
|
|
|
/******************************************************************************/
|
|
|
|
void CAttrEdit::OnLButtonDblClk(UINT nFlags, CPoint point)
|
|
{
|
|
|
|
if ( !m_pParentWnd->m_bVertEdit )
|
|
{
|
|
Default();
|
|
return;
|
|
}
|
|
|
|
HideCaret();
|
|
UpdateSel();
|
|
SetStartSelect();
|
|
|
|
int tt = point.y;
|
|
point.y = m_rectFmt.right - point.x;
|
|
point.x = tt;
|
|
|
|
const MSG *pCurrentMessage = GetCurrentMessage();
|
|
DefWindowProc( pCurrentMessage->message,
|
|
pCurrentMessage->wParam,
|
|
MAKELPARAM( point.x, point.y ));
|
|
|
|
SetCaretPosition( TRUE, &point, -1 );
|
|
ShowCaret();
|
|
UpdateSel();
|
|
UpdateWindow();
|
|
}
|
|
|
|
/******************************************************************************/
|
|
|
|
void CAttrEdit::OnLButtonDown(UINT nFlags, CPoint point)
|
|
{
|
|
|
|
if ( !m_pParentWnd->m_bVertEdit )
|
|
{
|
|
Default();
|
|
return;
|
|
}
|
|
|
|
HideCaret();
|
|
UpdateSel();
|
|
SetStartSelect();
|
|
|
|
int iPrevEnd;
|
|
GetSel( m_iPrevStart, iPrevEnd );
|
|
|
|
int tt = point.y;
|
|
point.y = m_rectFmt.right - point.x;
|
|
point.x = tt;
|
|
|
|
//reset caret position to get correct caret position
|
|
CPoint pt( -20000, -20000 );
|
|
SetCaretPos( pt );
|
|
|
|
const MSG *pCurrentMessage = GetCurrentMessage();
|
|
DefWindowProc( pCurrentMessage->message,
|
|
pCurrentMessage->wParam,
|
|
MAKELPARAM( point.x, point.y ));
|
|
|
|
SetCaretPosition( TRUE, &point, m_iPrevStart );
|
|
if ( GetKeyState(VK_SHIFT) >= 0 ) //not extend selection
|
|
GetSel( m_iPrevStart, iPrevEnd );
|
|
ShowCaret();
|
|
UpdateSel();
|
|
UpdateWindow();
|
|
|
|
m_bMouseDown = TRUE;
|
|
|
|
}
|
|
|
|
/******************************************************************************/
|
|
|
|
void CAttrEdit::OnLButtonUp(UINT nFlags, CPoint point)
|
|
{
|
|
|
|
if ( !m_pParentWnd->m_bVertEdit )
|
|
{
|
|
Default();
|
|
return;
|
|
}
|
|
|
|
m_bMouseDown = FALSE;
|
|
|
|
HideCaret();
|
|
UpdateSel();
|
|
SetStartSelect();
|
|
|
|
int tt = point.y;
|
|
point.y = m_rectFmt.right - point.x;
|
|
point.x = tt;
|
|
|
|
const MSG *pCurrentMessage = GetCurrentMessage();
|
|
DefWindowProc( pCurrentMessage->message,
|
|
pCurrentMessage->wParam,
|
|
MAKELPARAM( point.x, point.y ));
|
|
|
|
SetCaretPosition( TRUE, &point, m_iPrevStart );
|
|
ShowCaret();
|
|
UpdateSel();
|
|
UpdateWindow();
|
|
}
|
|
|
|
|
|
/******************************************************************************/
|
|
|
|
void CAttrEdit::OnMouseMove(UINT nFlags, CPoint point)
|
|
{
|
|
|
|
if ( !m_pParentWnd->m_bVertEdit )
|
|
{
|
|
Default();
|
|
return;
|
|
}
|
|
|
|
if ( m_bMouseDown )
|
|
{
|
|
HideCaret();
|
|
UpdateSel();
|
|
SetStartSelect();
|
|
|
|
int tt = point.y;
|
|
point.y = m_rectFmt.right - point.x;
|
|
point.x = tt;
|
|
|
|
const MSG *pCurrentMessage = GetCurrentMessage();
|
|
DefWindowProc( pCurrentMessage->message,
|
|
pCurrentMessage->wParam,
|
|
MAKELPARAM( point.x, point.y ));
|
|
|
|
SetCaretPosition( TRUE, &point, m_iPrevStart );
|
|
ShowCaret();
|
|
UpdateSel();
|
|
UpdateWindow();
|
|
}
|
|
else CEdit::OnMouseMove( nFlags, point );
|
|
|
|
}
|
|
|
|
/******************************************************************************/
|
|
|
|
void CAttrEdit::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
|
|
{
|
|
|
|
if ( !m_pParentWnd->m_bVertEdit )
|
|
{
|
|
CEdit::OnKeyDown(nChar, nRepCnt, nFlags);
|
|
return;
|
|
}
|
|
|
|
BOOL bPrev = FALSE;
|
|
|
|
HideCaret();
|
|
|
|
switch (nChar)
|
|
{
|
|
case VK_LEFT:
|
|
case VK_RIGHT:
|
|
case VK_UP:
|
|
case VK_DOWN:
|
|
case VK_HOME:
|
|
case VK_END:
|
|
{
|
|
UpdateSel();
|
|
|
|
CPoint ptCaretPos = GetCaretPos();
|
|
if ( ptCaretPos.y != 0 ) bPrev = TRUE;
|
|
|
|
int iPrevEnd;
|
|
GetSel( m_iPrevStart, iPrevEnd );
|
|
|
|
SetStartSelect(); //for VK_RETURN
|
|
|
|
//reset caret position to get correct caret position
|
|
CPoint pt( -20000, -20000 );
|
|
SetCaretPos( pt );
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
switch (nChar)
|
|
{
|
|
case VK_LEFT: nChar = VK_DOWN; break;
|
|
case VK_RIGHT: nChar = VK_UP; break;
|
|
case VK_UP: nChar = VK_LEFT; bPrev = FALSE; break;
|
|
case VK_DOWN: nChar = VK_RIGHT; bPrev = FALSE; break;
|
|
case VK_HOME: bPrev = FALSE; break;
|
|
case VK_END: bPrev = TRUE; break;
|
|
}
|
|
|
|
const MSG *pCurrentMessage = GetCurrentMessage();
|
|
DefWindowProc( pCurrentMessage->message,
|
|
nChar,
|
|
pCurrentMessage->lParam);
|
|
|
|
switch (nChar)
|
|
{
|
|
case VK_LEFT:
|
|
case VK_RIGHT:
|
|
case VK_UP:
|
|
case VK_DOWN:
|
|
case VK_HOME:
|
|
case VK_END:
|
|
{
|
|
SetCaretPosition( bPrev, NULL, m_iPrevStart );
|
|
UpdateSel();
|
|
UpdateWindow();
|
|
break;
|
|
}
|
|
case VK_HANJA:
|
|
// For Korea hanja conversion.
|
|
SetCaretPosition( FALSE, NULL, -2);
|
|
break;
|
|
|
|
}
|
|
|
|
ShowCaret();
|
|
}
|
|
|
|
/******************************************************************************/
|
|
void CAttrEdit::SetStartSelect( void )
|
|
{
|
|
int nStart, nEnd;
|
|
|
|
CPoint ptCaretPos = GetCaretPos();
|
|
|
|
if ( ptCaretPos.y == 0 )
|
|
{
|
|
GetSel( nStart, nEnd );
|
|
if ( nStart == nEnd ) SetSel( nStart, nEnd );
|
|
}
|
|
}
|
|
|
|
/******************************************************************************/
|
|
void CAttrEdit::SetCaretPosition( BOOL bPrev, CPoint* ptMouse, int iPrevStart )
|
|
{
|
|
|
|
HideCaret();
|
|
|
|
// Get Caret Position
|
|
CPoint ptCaretPos;
|
|
|
|
// Get End Selected Position to be Caret Position
|
|
int nStart, nEnd;
|
|
|
|
GetSel( nStart, nEnd );
|
|
|
|
if ( iPrevStart != -1 && nStart < iPrevStart )
|
|
nEnd = nStart;
|
|
#ifdef UNICODE
|
|
// When NT bug 116057 is fixed, remove this code
|
|
|
|
|
|
// For composition string support
|
|
if ( m_pParentWnd->m_bVertEdit && iPrevStart == -2)
|
|
nEnd -= 1 * sizeof(WCHAR)/sizeof(TCHAR);
|
|
#endif //UNICODE
|
|
CPoint ptPos( (DWORD)SendMessage( EM_POSFROMCHAR, nEnd ) );
|
|
|
|
if ( nEnd >= GetWindowTextLength() ||
|
|
( ptPos.x == 0 && (bPrev) && (ptMouse == NULL ||
|
|
ptMouse->y < ptPos.y ) ) )
|
|
{
|
|
CString cStr;
|
|
CDC* pDC = GetDC();
|
|
CFont* pFont = GetFont();
|
|
CFont* pOldFont;
|
|
int nLine = ( (ptPos.x < 0) ? GetLineCount() : LineFromChar( nEnd ) ) - 1;
|
|
int nChar = LineIndex( nLine );
|
|
int nLen = LineLength( nChar );
|
|
LPTSTR lpStr = cStr.GetBufferSetLength( nLen );
|
|
TEXTMETRIC tm;
|
|
|
|
pOldFont = pDC->SelectObject( pFont );
|
|
GetLine( nLine, lpStr, nLen );
|
|
|
|
pDC->GetTextMetrics( &tm );
|
|
|
|
if ( !(tm.tmPitchAndFamily & TMPF_FIXED_PITCH) )
|
|
m_iTabPos = tm.tmAveCharWidth;
|
|
else
|
|
{
|
|
CPoint len( pDC->GetTextExtent( TEXT("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"), 52) );
|
|
m_iTabPos = (len.x / 26 + 1) / 2;
|
|
if ( m_iTabPos <= 0 ) m_iTabPos = tm.tmAveCharWidth;
|
|
}
|
|
|
|
m_iTabPos *= 8;
|
|
if ( m_iTabPos <= 0 ) m_iTabPos = 1;
|
|
|
|
CPoint tt( 0, 0 );
|
|
if ( nLen > 0 )
|
|
{
|
|
if ( *(lpStr + nLen - 1) == TEXT('\t') )
|
|
{
|
|
tt = (CPoint) (DWORD)SendMessage( EM_POSFROMCHAR, nChar + nLen - 1 );
|
|
tt.x = min( (tt.x / m_iTabPos + 1) * m_iTabPos, m_rectFmt.bottom - 1 );
|
|
}
|
|
else
|
|
{
|
|
LPTSTR lpChar = lpStr + nLen - 1;
|
|
int nCnt;
|
|
|
|
for ( nCnt = 0; nCnt < nLen && *lpChar != TEXT('\t'); nCnt++, lpChar-- );
|
|
lpChar++;
|
|
tt = (CPoint) (DWORD)SendMessage( EM_POSFROMCHAR, nChar + nLen - nCnt );
|
|
tt.Offset( pDC->GetTextExtent( lpChar, nCnt ) );
|
|
}
|
|
}
|
|
cStr.Empty();
|
|
ptCaretPos.x = tt.x;
|
|
ptCaretPos.y = m_pParentWnd->m_iLineHeight * nLine;
|
|
pDC->SelectObject( pOldFont );
|
|
|
|
ReleaseDC( pDC );
|
|
}
|
|
else
|
|
{
|
|
ptCaretPos.x = ptPos.x;
|
|
ptCaretPos.y = ptPos.y;
|
|
}
|
|
|
|
// H -> V
|
|
CPoint pt( m_rectFmt.right - ptCaretPos.y - m_pParentWnd->m_iLineHeight,
|
|
ptCaretPos.x );
|
|
//
|
|
// for some reason, typing spaces pushes the caret beyond the bottom of the rect.
|
|
// Cover that case by forcing the caret to be at the bottom of the rect.
|
|
//
|
|
if (pt.y > m_rectFmt.bottom)
|
|
{
|
|
pt.y = m_rectFmt.bottom-2;
|
|
}
|
|
SetCaretPos( pt );
|
|
|
|
//Set IME composition window position
|
|
HIMC himc;
|
|
|
|
if (himc=ImmGetContext(m_hWnd))
|
|
{
|
|
COMPOSITIONFORM cf;
|
|
RECT rcClient;
|
|
|
|
cf.dwStyle = CFS_RECT;
|
|
cf.ptCurrentPos.x = m_rectFmt.right - ptCaretPos.y - 1;
|
|
cf.ptCurrentPos.y = pt.y;
|
|
GetClientRect( &rcClient );
|
|
cf.rcArea = rcClient;
|
|
|
|
ImmSetCompositionWindow(himc,&cf);
|
|
ImmReleaseContext(m_hWnd, himc);
|
|
}
|
|
|
|
#ifndef WINNT // don't call ImmSetCompositionWindow at this time.
|
|
SetFmtRect(); //it should be called after set IME position
|
|
#endif
|
|
|
|
ShowCaret();
|
|
}
|
|
|
|
/******************************************************************************/
|
|
void CAttrEdit::SetCaretShape( void )
|
|
{
|
|
HideCaret();
|
|
::DestroyCaret();
|
|
::CreateCaret( m_hWnd, NULL, m_pParentWnd->m_iLineHeight, 2 );
|
|
ShowCaret();
|
|
}
|
|
|
|
/******************************************************************************/
|
|
void CAttrEdit::SetFmtRect()
|
|
{
|
|
RECT rc;
|
|
|
|
rc.left = rc.top = 0;
|
|
if ( m_pParentWnd->m_bVertEdit )
|
|
{
|
|
rc.right = m_rectFmt.bottom;
|
|
rc.bottom = m_rectFmt.right;
|
|
}
|
|
else
|
|
{
|
|
rc.right = m_rectFmt.right;
|
|
rc.bottom = m_rectFmt.bottom;
|
|
}
|
|
|
|
HIMC himc;
|
|
COMPOSITIONFORM cf;
|
|
BOOL bResult = FALSE;
|
|
|
|
if (himc=ImmGetContext(m_hWnd)) {
|
|
bResult = ImmGetCompositionWindow(himc,&cf);
|
|
}
|
|
|
|
SetRectNP( &rc );
|
|
|
|
if (himc && bResult) {
|
|
ImmSetCompositionWindow(himc,&cf);
|
|
}
|
|
|
|
}
|
|
|
|
/******************************************************************************/
|
|
void CAttrEdit::Repaint(void)
|
|
{
|
|
InvalidateRect( NULL, TRUE );
|
|
UpdateWindow();
|
|
}
|
|
|
|
/******************************************************************************/
|
|
void CAttrEdit::UpdateSel(void)
|
|
{
|
|
int nStart, nEnd;
|
|
|
|
GetSel( nStart, nEnd );
|
|
|
|
if (nStart != nEnd )
|
|
{
|
|
RECT rc = m_rectFmt;
|
|
|
|
if ( nStart > nEnd )
|
|
{
|
|
int tt = nStart;
|
|
nStart = nEnd;
|
|
nEnd = tt;
|
|
}
|
|
|
|
CPoint ptStart( (DWORD)SendMessage( EM_POSFROMCHAR, nStart ) );
|
|
rc.right -= ptStart.y;
|
|
|
|
if ( nEnd < GetWindowTextLength() )
|
|
{
|
|
CPoint ptEnd( (DWORD)SendMessage( EM_POSFROMCHAR, nEnd ) );
|
|
rc.left = m_rectFmt.right - ptEnd.y - m_pParentWnd->m_iLineHeight;
|
|
}
|
|
|
|
InvalidateRect( &rc );
|
|
}
|
|
}
|
|
|
|
/******************************************************************************/
|
|
void CAttrEdit::UpdateInput(void)
|
|
{
|
|
RECT rc = m_rectFmt;
|
|
|
|
CPoint pt( GetCaretPos() );
|
|
rc.right = pt.x + m_pParentWnd->m_iLineHeight;
|
|
|
|
InvalidateRect( &rc );
|
|
}
|
|
|
|
/******************************************************************************/
|
|
|
|
LRESULT CAttrEdit::OnSysTimer( WPARAM wParam, LPARAM lParam )
|
|
{
|
|
|
|
if ( !m_pParentWnd->m_bVertEdit )
|
|
{
|
|
Default();
|
|
return 1L;
|
|
}
|
|
|
|
return 1L;
|
|
}
|
|
|
|
/******************************************************************************/
|
|
void CAttrEdit::SetHCursorShape(void)
|
|
{
|
|
if ( GetSafeHwnd() )
|
|
{
|
|
ShowCursor( FALSE );
|
|
SetClassLongPtr( m_hWnd, GCLP_HCURSOR, (LONG_PTR) m_hHCursor );
|
|
ShowCursor( TRUE );
|
|
}
|
|
}
|
|
|
|
/******************************************************************************/
|
|
void CAttrEdit::SetVCursorShape(void)
|
|
{
|
|
if ( GetSafeHwnd() )
|
|
{
|
|
ShowCursor( FALSE );
|
|
SetClassLongPtr( m_hWnd, GCLP_HCURSOR, (LONG_PTR) m_hVCursor );
|
|
ShowCursor( TRUE );
|
|
}
|
|
}
|
|
|
|
/******************************************************************************/
|
|
void CAttrEdit::TabTextOut( CDC* pDC, int nCharIndex, int x, int y, LPCTSTR lpStr, int nCount, BOOL bSelect )
|
|
{
|
|
int i, nCnt;
|
|
LPCTSTR lpChar = lpStr;
|
|
CPoint pt;
|
|
CPoint ptEnd;
|
|
RECT rc;
|
|
BOOL bReverse;
|
|
|
|
CSize s1 = pDC->GetTextExtent( TEXT("a"), 1 );
|
|
CSize s2 = pDC->GetTextExtent( TEXT("aa"), 2 );
|
|
bReverse = (s1.cx == s2.cx);
|
|
|
|
rc.left = x - m_pParentWnd->m_iLineHeight;
|
|
rc.right = x;
|
|
|
|
for ( i = 0, nCnt = 0; i < nCount; i++, nCnt++, lpStr++ )
|
|
{
|
|
if ( *lpStr == TEXT('\t') )
|
|
{
|
|
pt = (CPoint)(DWORD)SendMessage( EM_POSFROMCHAR, nCharIndex );
|
|
if ( nCnt > 0 )
|
|
{
|
|
pDC->TextOut( x, pt.x, lpChar, nCnt );
|
|
}
|
|
|
|
nCharIndex += nCnt + 1;
|
|
nCnt = -1;
|
|
lpChar = lpStr + 1;
|
|
if ( bSelect )
|
|
{
|
|
pt = (CPoint)(DWORD)SendMessage( EM_POSFROMCHAR, nCharIndex - 1 );
|
|
rc.top = pt.x;
|
|
|
|
if ( i < (nCount - 1) )
|
|
{
|
|
pt = (CPoint)(DWORD)SendMessage( EM_POSFROMCHAR, nCharIndex );
|
|
rc.bottom = pt.x;
|
|
}
|
|
else
|
|
{
|
|
rc.bottom = min( (pt.x / m_iTabPos + 1) * m_iTabPos,
|
|
m_rectFmt.bottom - 1 );
|
|
}
|
|
|
|
pDC->ExtTextOut( x, rc.top, 0 /*ETO_OPAQUE*/, &rc, NULL, 0, NULL );
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( nCnt > 0 )
|
|
{
|
|
pt = (CPoint)(DWORD)SendMessage( EM_POSFROMCHAR, nCharIndex );
|
|
pDC->TextOut( x, pt.x, lpChar, nCnt );
|
|
}
|
|
}
|
|
|
|
|
|
/******************************************************************************/
|
|
/******************************************************************************/
|
|
// CTedit
|
|
|
|
BEGIN_MESSAGE_MAP( CTedit, CWnd )
|
|
//{{AFX_MSG_MAP(CTedit)
|
|
ON_WM_SIZE()
|
|
ON_WM_MOVE()
|
|
ON_WM_CTLCOLOR()
|
|
ON_WM_NCCALCSIZE()
|
|
ON_WM_NCPAINT()
|
|
ON_WM_NCHITTEST()
|
|
ON_WM_RBUTTONDOWN()
|
|
ON_COMMAND(ID_TEXT_PLAIN, OnTextPlain)
|
|
ON_COMMAND(ID_TEXT_BOLD, OnTextBold)
|
|
ON_COMMAND(ID_TEXT_ITALIC, OnTextItalic)
|
|
ON_COMMAND(ID_TEXT_UNDERLINE, OnTextUnderline)
|
|
ON_COMMAND(ID_TEXT_SELECTFONT, OnTextSelectfont)
|
|
ON_COMMAND(ID_TEXT_SELECTPOINTSIZE, OnTextSelectpointsize)
|
|
ON_COMMAND(ID_EDIT_CUT, OnEditCut)
|
|
ON_COMMAND(ID_EDIT_COPY, OnEditCopy)
|
|
ON_COMMAND(ID_EDIT_PASTE, OnEditPaste)
|
|
ON_COMMAND(ID_EDIT_CLEAR, OnTextDelete)
|
|
ON_COMMAND(ID_EDIT_SELECT_ALL, OnTextSelectall)
|
|
ON_COMMAND(ID_EDIT_UNDO, OnTextUndo)
|
|
ON_COMMAND(ID_TEXT_PLACE, OnTextPlace)
|
|
ON_COMMAND(ID_VIEW_TEXT_TOOLBAR, OnTextTexttool)
|
|
ON_WM_LBUTTONDOWN()
|
|
//}}AFX_MSG_MAP
|
|
ON_WM_GETMINMAXINFO()
|
|
ON_MESSAGE(WM_MOVING, OnMoving)
|
|
ON_EN_CHANGE(IDC_ATTREDIT, OnAttrEditEnChange)
|
|
ON_EN_MAXTEXT(IDC_ATTREDIT, OnEnMaxText)
|
|
ON_EN_UPDATE(IDC_ATTREDIT, OnEnUpdate)
|
|
|
|
ON_WM_DESTROY()
|
|
|
|
END_MESSAGE_MAP()
|
|
|
|
/******************************************************************************/
|
|
// CTedit construction/destruction
|
|
|
|
CTedit::CTedit()
|
|
{
|
|
m_eLastAction = eNO_CHANGE;
|
|
m_bCleanupBKBrush = FALSE;
|
|
m_bStarting = TRUE;
|
|
m_bPasting = FALSE;
|
|
m_bExpand = FALSE;
|
|
m_bChanged = FALSE;
|
|
m_uiHitArea = HTNOWHERE;
|
|
m_crFGColor = ::GetSysColor( COLOR_WINDOWTEXT );
|
|
m_crBKColor = ::GetSysColor( COLOR_WINDOW );
|
|
|
|
// Need to be initialized during first GETMINMAXINFO call
|
|
m_SizeMinimum.cx = 1;
|
|
m_SizeMinimum.cy = 1;
|
|
|
|
m_bBackgroundTransparent = TRUE;
|
|
|
|
m_cRectOldPos.SetRectEmpty();
|
|
m_cRectWindow.SetRectEmpty();
|
|
|
|
|
|
m_bVertEdit = FALSE;
|
|
m_bAssocIMC = FALSE;
|
|
m_hIMCEdit = NULL;
|
|
m_hIMCFace = NULL;
|
|
m_hIMCSize = NULL;
|
|
m_hWndFace = NULL;
|
|
m_hWndSize = NULL;
|
|
|
|
}
|
|
|
|
/******************************************************************************/
|
|
|
|
CTedit::~CTedit()
|
|
{
|
|
if (m_bCleanupBKBrush)
|
|
{
|
|
m_hbrBkColor.DeleteObject(); //Set in SetTransparentMode
|
|
m_bCleanupBKBrush = FALSE;
|
|
}
|
|
}
|
|
|
|
/******************************************************************************/
|
|
|
|
BOOL CTedit::Create( CImgWnd* pParentWnd,
|
|
COLORREF crefForeground,
|
|
COLORREF crefBackground,
|
|
CRect& rectPos,
|
|
BOOL bBackTransparent )
|
|
{
|
|
if (! m_bStarting)
|
|
return FALSE;
|
|
|
|
// Initialize member variables
|
|
m_pImgWnd = pParentWnd;
|
|
m_crBKColor = crefBackground;
|
|
m_crFGColor = crefForeground;
|
|
m_bBackgroundTransparent = bBackTransparent; // Do this or else
|
|
|
|
SetTransparentMode( bBackTransparent );
|
|
|
|
CRect rectText = rectPos;
|
|
|
|
rectText.InflateRect( CTracker::HANDLE_SIZE, CTracker::HANDLE_SIZE );
|
|
rectText.right += CTracker::HANDLE_SIZE * 2;
|
|
rectText.bottom += CTracker::HANDLE_SIZE * 2;
|
|
|
|
if (! CWnd::Create( NULL, TEXT(""), WS_CHILD | WS_THICKFRAME, rectText, pParentWnd, IDC_ATTREDIT + 1 ))
|
|
return FALSE;
|
|
|
|
CRect rectEditArea;
|
|
|
|
GetClientRect( &rectEditArea );
|
|
|
|
m_cEdit.m_pParentWnd = this;
|
|
|
|
if (! m_cEdit.Create( WS_CHILD | ES_LEFT | ES_MULTILINE | ES_NOHIDESEL | ES_WANTRETURN, rectEditArea, this, IDC_ATTREDIT ))
|
|
{
|
|
theApp.SetMemoryEmergency();
|
|
|
|
DestroyWindow();
|
|
return FALSE;
|
|
}
|
|
|
|
ClientToScreen( &rectEditArea ); // use this to let the font tool where not to cover
|
|
|
|
m_pcTfont = new CTfont( this ); // this is the class Text Font Pallette
|
|
// it is derived from cframewnd and will
|
|
ASSERT( m_pcTfont != NULL ); // auto destruct when this window
|
|
// 'CTedit' is Destroyed
|
|
if (m_pcTfont == NULL || ! m_pcTfont->Create( rectEditArea ))
|
|
{
|
|
theApp.SetMemoryEmergency();
|
|
|
|
DestroyWindow();
|
|
|
|
m_pcTfont = NULL;
|
|
return FALSE;
|
|
}
|
|
|
|
// reset the width and height to the minimum if nessesary
|
|
CSize size = GetDefaultMinSize(); // must call after ctfont object created (it sets our font).
|
|
m_cRectWindow = CRect( rectText.TopLeft(), size );
|
|
SetWindowPos( &wndTop, 0, 0, size.cx, size.cy, SWP_NOACTIVATE | SWP_NOMOVE );
|
|
|
|
ShowWindow( SW_SHOWNOACTIVATE );
|
|
|
|
GetClientRect( &rectEditArea );
|
|
|
|
m_cEdit.SetWindowPos( &wndTopMost, 0, 0, rectEditArea.Width(),
|
|
rectEditArea.Height(), 0 );
|
|
m_cEdit.ShowWindow( SW_SHOWNOACTIVATE );
|
|
|
|
m_bStarting = FALSE;
|
|
|
|
|
|
//get all control windows on ToolBar for controling IME
|
|
CWnd* pcWndFace = m_pcTfont->GetFontFaceControl();
|
|
if ( (pcWndFace != NULL) && (pcWndFace->GetSafeHwnd() != NULL) )
|
|
m_hWndFace = pcWndFace->m_hWnd; //static
|
|
|
|
CWnd* pcWndSize = m_pcTfont->GetFontSizeControl();
|
|
if ( (pcWndSize != NULL) && (
|
|
pcWndSize->GetSafeHwnd() != NULL) )
|
|
{
|
|
CWnd* pcWndEditSize = pcWndSize->GetWindow( GW_CHILD ); //edit
|
|
if ( (pcWndEditSize != NULL) && (
|
|
pcWndEditSize->GetSafeHwnd() != NULL) )
|
|
m_hWndSize = pcWndEditSize->m_hWnd; //edit
|
|
}
|
|
|
|
//save original Edit control
|
|
if ( m_cEdit.GetSafeHwnd() )
|
|
m_cEdit.m_hOldCursor = (HCURSOR) SetClassLongPtr( m_cEdit.m_hWnd, GCLP_HCURSOR, (LONG_PTR) m_cEdit.m_hHCursor );
|
|
|
|
|
|
//only DBCS font would enable IME
|
|
CFont* pcFont = m_cEdit.GetFont();
|
|
LOGFONT lf;
|
|
pcFont->GetObject( sizeof( LOGFONT ), &lf );
|
|
if ( !IS_DBCS_CHARSET( lf.lfCharSet ) )
|
|
{
|
|
m_bAssocIMC = TRUE;
|
|
if (!IsCUAS())
|
|
m_hIMCEdit = DisableIme( m_cEdit.m_hWnd );
|
|
m_hIMCFace = DisableIme( m_hWndFace );
|
|
m_hIMCSize = DisableIme( m_hWndSize );
|
|
}
|
|
|
|
|
|
//initial Caret Position
|
|
if ( m_bVertEdit )
|
|
{
|
|
CPoint pt( 0, 0 );
|
|
m_cEdit.SetCaretPos( pt );
|
|
m_cEdit.SetCaretPosition( FALSE, NULL, -1 );
|
|
}
|
|
|
|
m_cEdit.SetFocus();
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
/******************************************************************************/
|
|
|
|
BOOL CTedit::PreCreateWindow( CREATESTRUCT& cs )
|
|
{
|
|
cs.dwExStyle |= WS_EX_TRANSPARENT;
|
|
|
|
return CWnd::PreCreateWindow( cs );
|
|
}
|
|
|
|
/******************************************************************************/
|
|
|
|
void CTedit::RefreshWindow( CRect* prect, BOOL bErase )
|
|
{
|
|
if (! m_bStarting)
|
|
{
|
|
UINT flags = RDW_INVALIDATE;
|
|
|
|
if (bErase)
|
|
flags |= RDW_ERASE;
|
|
|
|
if ( m_bVertEdit )
|
|
{
|
|
m_cEdit.SetFmtRect();
|
|
m_cEdit.Repaint();
|
|
}
|
|
|
|
else
|
|
m_cEdit.RedrawWindow( prect, NULL, flags );
|
|
}
|
|
}
|
|
|
|
/******************************************************************************/
|
|
|
|
void CTedit::SetTextColor( COLORREF crColor )
|
|
{
|
|
m_crFGColor = crColor;
|
|
RefreshWindow( NULL, FALSE );
|
|
}
|
|
|
|
/******************************************************************************/
|
|
|
|
void CTedit::SetBackColor( COLORREF crColor )
|
|
{
|
|
m_crBKColor = crColor;
|
|
|
|
if (! m_bBackgroundTransparent)
|
|
{
|
|
m_bBackgroundTransparent = TRUE; // just fake it out
|
|
SetTransparentMode( FALSE ); // to setup the background brush when in opaque mode
|
|
}
|
|
}
|
|
|
|
/******************************************************************************/
|
|
|
|
void CTedit::SetTransparentMode( BOOL bTransparent )
|
|
{
|
|
BOOL bRefresh = ((! m_bBackgroundTransparent && bTransparent)
|
|
|| ( m_bBackgroundTransparent && ! bTransparent));
|
|
|
|
m_cEdit.m_bBackgroundTransparent = bTransparent;
|
|
m_bBackgroundTransparent = bTransparent;
|
|
|
|
if (m_bCleanupBKBrush)
|
|
{
|
|
m_hbrBkColor.DeleteObject();
|
|
m_bCleanupBKBrush = FALSE;
|
|
}
|
|
|
|
if (! m_bBackgroundTransparent)
|
|
{
|
|
m_hbrBkColor.CreateSolidBrush( m_crBKColor );
|
|
m_bCleanupBKBrush = TRUE;
|
|
}
|
|
|
|
if (bRefresh)
|
|
{
|
|
InvalidateRect( NULL );
|
|
UpdateWindow();
|
|
|
|
RefreshWindow();
|
|
}
|
|
}
|
|
|
|
/******************************************************************************/
|
|
|
|
void CTedit::Undo()
|
|
{
|
|
|
|
if ( m_bVertEdit )
|
|
m_cEdit.HideCaret();
|
|
|
|
switch(m_eLastAction)
|
|
{
|
|
case eEBOX_CHANGE:
|
|
m_cEdit.Undo();
|
|
break;
|
|
|
|
case eFONT_CHANGE:
|
|
ASSERT(m_pcTfont != NULL);
|
|
|
|
if (m_pcTfont != NULL)
|
|
{
|
|
m_pcTfont->Undo();
|
|
}
|
|
break;
|
|
|
|
case eSIZE_MOVE_CHANGE:
|
|
if (! m_cRectOldPos.IsRectEmpty())
|
|
MoveWindow( m_cRectOldPos );
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
|
|
if ( m_bVertEdit )
|
|
{
|
|
m_cEdit.SetCaretShape();
|
|
m_cEdit.SetCaretPosition( TRUE, NULL, -1 );
|
|
m_cEdit.ShowCaret();
|
|
}
|
|
|
|
}
|
|
|
|
/******************************************************************************/
|
|
|
|
void CTedit::ShowFontPalette(int nCmdShow)
|
|
{
|
|
ASSERT(m_pcTfont != NULL);
|
|
|
|
if (m_pcTfont != NULL)
|
|
{
|
|
theApp.m_bShowTextToolbar = ! theApp.m_bShowTextToolbar;
|
|
|
|
m_pcTfont->ShowWindow(nCmdShow);
|
|
}
|
|
}
|
|
|
|
/******************************************************************************/
|
|
|
|
BOOL CTedit::IsFontPaletteVisible(void)
|
|
{
|
|
BOOL bWindowVisible = FALSE;
|
|
|
|
ASSERT(m_pcTfont != NULL);
|
|
|
|
if (m_pcTfont != NULL)
|
|
{
|
|
bWindowVisible = m_pcTfont->IsWindowVisible();
|
|
}
|
|
|
|
return bWindowVisible;
|
|
}
|
|
|
|
/******************************************************************************/
|
|
|
|
void CTedit::ShowFontToolbar(BOOL bActivate)
|
|
{
|
|
// FEATURE: Remove ShowFontPalette after RTM
|
|
|
|
if (m_pcTfont == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
m_pcTfont->ShowWindow(bActivate ? SW_SHOW : SW_SHOWNOACTIVATE);
|
|
}
|
|
|
|
/******************************************************************************/
|
|
|
|
void CTedit::HideFontToolbar(void)
|
|
{
|
|
if (m_pcTfont == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
m_pcTfont->ShowWindow(SW_HIDE);
|
|
}
|
|
|
|
/******************************************************************************/
|
|
// Returns a Ptr to a discardable bitmap (CBitmap object) or NULL on error
|
|
|
|
void CTedit::GetBitmap( CDC* pDC, CRect* prectImg )
|
|
{
|
|
if (! m_bBackgroundTransparent)
|
|
pDC->FillRect( prectImg, &m_hbrBkColor );
|
|
|
|
m_cEdit.SetSel( -1, 0 );
|
|
|
|
|
|
if ( m_bVertEdit )
|
|
{
|
|
m_cEdit.SetFmtRect();
|
|
m_cEdit.UpdateWindow();
|
|
}
|
|
|
|
|
|
CPoint ptViewOrgOld = pDC->SetViewportOrg( prectImg->left, prectImg->top );
|
|
|
|
m_cEdit.SendMessage( WM_PAINT, (WPARAM)(pDC->m_hDC) );
|
|
|
|
pDC->SetViewportOrg( ptViewOrgOld );
|
|
pDC->SelectClipRgn( NULL );
|
|
}
|
|
|
|
/******************************************************************************/
|
|
|
|
void CTedit::PostNcDestroy()
|
|
{
|
|
|
|
// If m_pcTfont is destroyed by shutdown before CTedit,
|
|
// m_pcTfont will be null
|
|
if (m_pcTfont != NULL)
|
|
{
|
|
m_pcTfont->DestroyWindow();
|
|
m_pcTfont = NULL;
|
|
}
|
|
|
|
delete this;
|
|
}
|
|
|
|
/******************************************************************************/
|
|
|
|
CSize CTedit::GetDefaultMinSize( void )
|
|
{
|
|
CRect cRectClient;
|
|
int iWidth;
|
|
int iHeight;
|
|
|
|
// edit control takes up the whole client area of the ctedit
|
|
// object/window, so width of client of ctedit is same as widht of edit
|
|
// control window. Edit control window has no border.
|
|
GetClientRect( &cRectClient );
|
|
|
|
iWidth = cRectClient.Width();
|
|
iHeight = cRectClient.Height();
|
|
|
|
CDC* pDC = m_cEdit.GetDC();
|
|
CFont* pcFont = m_cEdit.GetFont();
|
|
|
|
if (pDC != NULL
|
|
&& pcFont != NULL)
|
|
{
|
|
TEXTMETRIC tm;
|
|
CFont* pcFontOld = NULL;
|
|
|
|
pcFontOld = pDC->SelectObject( pcFont );
|
|
|
|
pDC->GetTextMetrics( &tm );
|
|
|
|
BOOL bUpdateSize = FALSE;
|
|
|
|
m_SizeMinimum.cx = tm.tmAveCharWidth * MIN_CHARS_DISPLAY_SIZE + CTracker::HANDLE_SIZE * 2;
|
|
m_SizeMinimum.cy = tm.tmHeight + CTracker::HANDLE_SIZE * 2;
|
|
|
|
if (m_SizeMinimum.cx > iWidth) // must be able to at least display MIN_CHARS_DISPLAY_SIZE
|
|
{
|
|
iWidth = m_SizeMinimum.cx;
|
|
bUpdateSize = TRUE;
|
|
}
|
|
|
|
if (m_SizeMinimum.cy > iHeight) // must be able to at least 1 char high
|
|
{
|
|
iHeight = m_SizeMinimum.cy;
|
|
bUpdateSize = TRUE;
|
|
}
|
|
|
|
if (bUpdateSize)
|
|
m_eLastAction = eNO_CHANGE; // don't want user to be able to undo this
|
|
|
|
if (pcFontOld != NULL)
|
|
{
|
|
pDC->SelectObject( pcFontOld );
|
|
}
|
|
}
|
|
if (pDC != NULL)
|
|
m_cEdit.ReleaseDC( pDC );
|
|
|
|
cRectClient.SetRect( 0, 0, iWidth - 1, iHeight - 1 );
|
|
|
|
ClientToScreen( &cRectClient );
|
|
m_pImgWnd->ScreenToClient( &cRectClient );
|
|
|
|
CRect rectDrawing = m_pImgWnd->GetDrawingRect();
|
|
|
|
if (cRectClient.right > rectDrawing.right)
|
|
iWidth -= (cRectClient.right - rectDrawing.right) - CTracker::HANDLE_SIZE;
|
|
|
|
if (cRectClient.bottom > rectDrawing.bottom)
|
|
iHeight -= (cRectClient.bottom - rectDrawing.bottom) - CTracker::HANDLE_SIZE;
|
|
|
|
m_SizeMinimum.cx = iWidth;
|
|
m_SizeMinimum.cy = iHeight;
|
|
|
|
return CSize( iWidth, iHeight );
|
|
}
|
|
|
|
/******************************************************************************/
|
|
|
|
void CTedit::OnAttrEditEnChange(void)
|
|
{
|
|
m_eLastAction = eEBOX_CHANGE;
|
|
|
|
if (m_bRefresh)
|
|
m_cEdit.UpdateWindow();
|
|
|
|
|
|
if ( m_bVertEdit )
|
|
{
|
|
m_cEdit.SetCaretPosition( TRUE, NULL, -1 );
|
|
m_cEdit.UpdateWindow();
|
|
}
|
|
|
|
}
|
|
|
|
/******************************************************************************/
|
|
|
|
void CTedit::OnEnUpdate()
|
|
{
|
|
CPoint ptCaretPos = m_cEdit.GetCaretPos();
|
|
CPoint ptLastChar( (DWORD)m_cEdit.SendMessage( EM_POSFROMCHAR,
|
|
(WPARAM)(m_cEdit.GetWindowTextLength() - 1) ) );
|
|
CRect rect;
|
|
m_cEdit.GetClientRect( &rect );
|
|
rect.top = ptCaretPos.y;
|
|
rect.bottom = ptLastChar.y + m_iLineHeight;
|
|
m_cEdit.InvalidateRect( &rect, TRUE );
|
|
|
|
m_bChanged = TRUE;
|
|
}
|
|
|
|
/******************************************************************************/
|
|
|
|
void CTedit::OnEnMaxText()
|
|
{
|
|
|
|
if (m_bPasting)
|
|
{
|
|
if (!m_cEdit.m_bResizeOnly)
|
|
{
|
|
AfxMessageBox( IDS_UNABLE_TO_PASTE, MB_OK | MB_ICONEXCLAMATION );
|
|
}
|
|
return;
|
|
}
|
|
|
|
CFont* pfntEdit = m_cEdit.GetFont();
|
|
|
|
if (pfntEdit == NULL)
|
|
return;
|
|
|
|
CClientDC dc( &m_cEdit );
|
|
|
|
CFont* pfntOld = dc.SelectObject( pfntEdit );
|
|
|
|
TEXTMETRIC tm;
|
|
|
|
dc.GetTextMetrics( &tm );
|
|
|
|
CRect rectText;
|
|
CRect rectImg;
|
|
|
|
GetWindowRect( &rectText );
|
|
|
|
m_pImgWnd->ScreenToClient( &rectText );
|
|
|
|
POINT pt;
|
|
::GetCaretPos (&pt);
|
|
//
|
|
// If the next character would extend past the end of the
|
|
// edit window, grow the window
|
|
|
|
|
|
if (!m_bVertEdit && m_cEdit.m_bResizeOnly &&
|
|
((rectText.left + pt.x + 2*tm.tmMaxCharWidth < rectText.right)
|
|
|| (rectText.top + pt.y + 2*tm.tmHeight < rectText.bottom)) )
|
|
{
|
|
return;
|
|
}
|
|
else if (m_bVertEdit && m_cEdit.m_bResizeOnly &&
|
|
((pt.x - tm.tmMaxCharWidth > 0)
|
|
|| (rectText.top + pt.y + 2*tm.tmHeight < rectText.bottom)) )
|
|
{
|
|
return;
|
|
}
|
|
m_pImgWnd->GetClientRect ( &rectImg );
|
|
|
|
|
|
if (m_cEdit.m_strResult.IsEmpty())
|
|
{
|
|
|
|
if (m_bVertEdit)
|
|
rectText.left -= tm.tmHeight;
|
|
else
|
|
rectText.bottom += tm.tmHeight;
|
|
}
|
|
else
|
|
{
|
|
CRect rectTmp = rectText;
|
|
int nLen = m_cEdit.m_strResult.GetLength();
|
|
|
|
|
|
if (m_bVertEdit)
|
|
rectText.left -= dc.DrawText(m_cEdit.m_strResult.GetBuffer(nLen),
|
|
nLen,&rectTmp,
|
|
DT_CALCRECT | DT_LEFT | DT_WORDBREAK);
|
|
else
|
|
rectText.bottom += dc.DrawText(m_cEdit.m_strResult.GetBuffer(nLen),
|
|
nLen,&rectTmp,
|
|
DT_CALCRECT | DT_LEFT | DT_WORDBREAK);
|
|
}
|
|
|
|
CRect rectDrawing = m_pImgWnd->GetDrawingRect();
|
|
|
|
if ( ((m_bVertEdit) && rectText.left>=rectDrawing.left && rectText.left >= rectImg.left) ||
|
|
((!m_bVertEdit) && rectText.bottom<=rectDrawing.bottom && rectText.bottom<=rectImg.bottom) )
|
|
{
|
|
MoveWindow( &rectText );
|
|
m_cEdit.UpdateWindow();
|
|
|
|
if ( m_bVertEdit )
|
|
m_cEdit.UpdateInput();
|
|
|
|
if (!m_cEdit.m_bResizeOnly)
|
|
{
|
|
if (m_cEdit.m_strResult.IsEmpty())
|
|
{
|
|
#ifdef UNICODE
|
|
WCHAR ch[3];
|
|
|
|
ch[0] = (WCHAR)m_cEdit.m_uiLastChar[0];
|
|
ch[1] = L'\0';
|
|
#else
|
|
BYTE ch[3];
|
|
//
|
|
// Put lead and trail bytes in proper place for DBCS characters.
|
|
//
|
|
if (IsDBCSLeadByte (HIBYTE(LOWORD(m_cEdit.m_uiLastChar[0]))))
|
|
{
|
|
ch[0] = HIBYTE(LOWORD(m_cEdit.m_uiLastChar[0]));
|
|
ch[1] = LOBYTE(LOWORD(m_cEdit.m_uiLastChar[0]));
|
|
ch[2] = '\0';
|
|
}
|
|
else
|
|
{
|
|
ch[0] = LOBYTE(LOWORD(m_cEdit.m_uiLastChar[0]));
|
|
ch[1] = '\0';
|
|
}
|
|
#endif // UNICODE
|
|
if (ch[0] == VK_RETURN)
|
|
{
|
|
lstrcpy((LPTSTR)ch, TEXT("\r\n"));
|
|
}
|
|
|
|
m_cEdit.ReplaceSel((LPCTSTR) ch );
|
|
}
|
|
else
|
|
{
|
|
int nLen = m_cEdit.m_strResult.GetLength();
|
|
|
|
m_cEdit.ReplaceSel( m_cEdit.m_strResult.GetBuffer(nLen));
|
|
}
|
|
}
|
|
}
|
|
|
|
if (pfntOld)
|
|
dc.SelectObject( pfntOld );
|
|
}
|
|
|
|
/******************************************************************************/
|
|
|
|
void CTedit::OnAttrEditFontChange(void)
|
|
{
|
|
CClientDC editDC( &m_cEdit );
|
|
CFont* pcFont = m_cEdit.GetFont();
|
|
if (!pcFont)
|
|
{
|
|
return; // this happens when you "escape" from the font
|
|
// selection listbox
|
|
}
|
|
CFont* pFontOld = editDC.SelectObject( pcFont);
|
|
|
|
TEXTMETRIC tm;
|
|
|
|
editDC.GetTextMetrics( &tm );
|
|
|
|
m_iLineHeight = tm.tmHeight;
|
|
|
|
|
|
#ifdef _DEBUG
|
|
TRACE1( "New font line height %d.\n", m_iLineHeight );
|
|
#endif
|
|
|
|
|
|
//only DBCS associated font would enable IME
|
|
if ( !m_bStarting )
|
|
{
|
|
|
|
LOGFONT lf;
|
|
|
|
pcFont->GetObject( sizeof( LOGFONT ), &lf );
|
|
if ( IS_DBCS_CHARSET( lf.lfCharSet ) )
|
|
|
|
{
|
|
|
|
if (m_bAssocIMC)
|
|
{
|
|
|
|
m_bAssocIMC = FALSE;
|
|
if (!IsCUAS())
|
|
{
|
|
EnableIme( m_cEdit.m_hWnd, m_hIMCEdit );
|
|
m_hIMCEdit = NULL;
|
|
}
|
|
EnableIme( m_hWndFace, m_hIMCFace );
|
|
EnableIme( m_hWndSize, m_hIMCSize );
|
|
m_hIMCFace = NULL;
|
|
m_hIMCSize = NULL;
|
|
m_pcTfont->SetFocus();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
|
|
if (!m_bAssocIMC)
|
|
{
|
|
|
|
m_bAssocIMC = TRUE;
|
|
if (!IsCUAS())
|
|
m_hIMCEdit = DisableIme( m_cEdit.m_hWnd );
|
|
m_hIMCFace = DisableIme( m_hWndFace );
|
|
m_hIMCSize = DisableIme( m_hWndSize );
|
|
m_pcTfont->SetFocus();
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
if (pFontOld != NULL)
|
|
editDC.SelectObject( pFontOld );
|
|
|
|
m_eLastAction = eFONT_CHANGE;
|
|
}
|
|
|
|
/******************************************************************************/
|
|
|
|
void CTedit::OnSize( UINT nType, int cx, int cy )
|
|
{
|
|
if (! m_bStarting)
|
|
ShowWindow( SW_HIDE );
|
|
|
|
// need to do this if transparent to force see through
|
|
m_cRectOldPos = m_cRectWindow;
|
|
GetWindowRect( &m_cRectWindow );
|
|
m_pImgWnd->ScreenToClient( m_cRectWindow );
|
|
|
|
m_eLastAction = eSIZE_MOVE_CHANGE;
|
|
|
|
// could be NULL when main window is created and child edit window
|
|
// has not been created yet.
|
|
if (m_cEdit.GetSafeHwnd() != NULL)
|
|
{
|
|
m_cEdit.MoveWindow( 0, 0, cx, cy );
|
|
m_cEdit.SetWindowPos( &wndTopMost, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE );
|
|
}
|
|
InvalidateRect( NULL );
|
|
UpdateWindow();
|
|
|
|
if (m_bBackgroundTransparent)
|
|
{
|
|
RefreshWindow();
|
|
}
|
|
if (! m_bStarting)
|
|
ShowWindow( SW_SHOW );
|
|
|
|
|
|
if ( m_bVertEdit )
|
|
{
|
|
m_cEdit.SetFmtRect();
|
|
CPoint pt( -20000, -20000 );
|
|
m_cEdit.SetCaretPos( pt );
|
|
m_cEdit.SetCaretPosition( FALSE, NULL, -1 );
|
|
m_cEdit.Repaint();
|
|
}
|
|
|
|
|
|
}
|
|
|
|
/******************************************************************************/
|
|
|
|
void CTedit::OnMove( int x, int y )
|
|
{
|
|
// need to do this if transparent to force see through
|
|
m_cRectOldPos = m_cRectWindow;
|
|
GetWindowRect( &m_cRectWindow );
|
|
m_pImgWnd->ScreenToClient( m_cRectWindow );
|
|
|
|
if (m_cRectOldPos.Width() != m_cRectWindow.Width()
|
|
|| m_cRectOldPos.Height() != m_cRectWindow.Height())
|
|
{
|
|
//reset back to previous, since new will be updated in onsize, due to
|
|
// size and move happening both (e.g. sizing either left or top side
|
|
// causes an onmove then an onsize
|
|
m_cRectWindow = m_cRectOldPos;
|
|
}
|
|
m_eLastAction = eSIZE_MOVE_CHANGE;
|
|
|
|
if (m_cEdit.GetSafeHwnd() != NULL)
|
|
{
|
|
m_cEdit.SetWindowPos( &wndTopMost, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE );
|
|
}
|
|
|
|
InvalidateRect( NULL );
|
|
UpdateWindow();
|
|
|
|
if (m_bBackgroundTransparent)
|
|
{
|
|
RefreshWindow();
|
|
}
|
|
}
|
|
|
|
/******************************************************************************/
|
|
|
|
LRESULT CTedit::OnMoving( WPARAM, LPARAM lprc )
|
|
{
|
|
LRESULT lResult = 0;
|
|
CRect rectEdit = *((LPRECT)lprc);
|
|
CRect rectImage = m_pImgWnd->GetDrawingRect();
|
|
|
|
m_pImgWnd->ClientToScreen( &rectImage );
|
|
|
|
int iX = 0;
|
|
int iY = 0;
|
|
|
|
if (rectEdit.left < rectImage.left)
|
|
iX = rectImage.left - rectEdit.left;
|
|
else
|
|
if (rectEdit.right > rectImage.right)
|
|
iX = -(rectEdit.right - rectImage.right);
|
|
|
|
if (rectEdit.top < rectImage.top)
|
|
iY = rectImage.top - rectEdit.top;
|
|
else
|
|
if (rectEdit.bottom > rectImage.bottom)
|
|
iY = -(rectEdit.bottom - rectImage.bottom);
|
|
|
|
if (iX || iY)
|
|
{
|
|
rectEdit.OffsetRect( iX, iY );
|
|
*((LPRECT)lprc) = rectEdit;
|
|
lResult = 1;
|
|
}
|
|
return lResult;
|
|
}
|
|
|
|
/******************************************************************************/
|
|
|
|
void CTedit::OnGetMinMaxInfo( MINMAXINFO FAR* lpMMI )
|
|
{
|
|
CRect rectImage = m_pImgWnd->GetDrawingRect();
|
|
CSize Size = rectImage.Size();
|
|
|
|
lpMMI->ptMaxSize.x = Size.cx;
|
|
lpMMI->ptMaxSize.y = Size.cy;
|
|
lpMMI->ptMaxPosition = rectImage.TopLeft();
|
|
lpMMI->ptMinTrackSize.x = m_SizeMinimum.cx;
|
|
lpMMI->ptMinTrackSize.y = m_SizeMinimum.cy;
|
|
|
|
CRect rectClient;
|
|
|
|
GetWindowRect( &rectClient );
|
|
m_pImgWnd->ScreenToClient( &rectClient );
|
|
|
|
switch (m_uiHitArea)
|
|
{
|
|
case HTTOP:
|
|
case HTLEFT:
|
|
case HTTOPLEFT:
|
|
break;
|
|
|
|
case HTRIGHT:
|
|
case HTTOPRIGHT:
|
|
case HTBOTTOMRIGHT:
|
|
lpMMI->ptMaxSize.x -= (rectClient.left - rectImage.left);
|
|
|
|
if (m_uiHitArea == HTBOTTOMRIGHT)
|
|
; // fall thru and do the bottom
|
|
else
|
|
break;
|
|
|
|
case HTBOTTOMLEFT:
|
|
case HTBOTTOM:
|
|
lpMMI->ptMaxSize.y -= (rectClient.top - rectImage.top);
|
|
break;
|
|
}
|
|
|
|
lpMMI->ptMaxTrackSize = lpMMI->ptMaxSize;
|
|
}
|
|
|
|
/******************************************************************************/
|
|
|
|
HBRUSH CTedit::OnCtlColor (CDC* pDC, CWnd* pWnd, UINT nCtlColor )
|
|
{
|
|
HBRUSH hbrBack = NULL;
|
|
|
|
if (pWnd == &m_cEdit)
|
|
{
|
|
PBSelectPalette( pDC, theApp.m_pPalette, FALSE );
|
|
pDC->SetTextColor( m_crFGColor );
|
|
|
|
//set the background color and transparent mode
|
|
// if (m_bBackgroundTransparent)
|
|
// {
|
|
pDC->SetBkMode( TRANSPARENT );
|
|
|
|
hbrBack = (HBRUSH)::GetStockObject( NULL_BRUSH );
|
|
// }
|
|
// else
|
|
// {
|
|
// pDC->SetBkMode( OPAQUE );
|
|
// pDC->SetBkColor( m_crBKColor );
|
|
|
|
// hbrBack = (HBRUSH)m_hbrBkColor.GetSafeHandle();
|
|
// }
|
|
}
|
|
if (hbrBack == NULL)
|
|
return (HBRUSH)Default();
|
|
|
|
return hbrBack;
|
|
}
|
|
|
|
/******************************************************************************/
|
|
//void CTedit::OnLButtonDown(UINT nFlags, CPoint point )
|
|
// {
|
|
// SendMessage(WM_NCLBUTTONDOWN, HTCAPTION, MAKELPARAM(point.x, point.y));
|
|
// SetFocus();
|
|
// CEdit::OnLButtonDown(nFlags, point);
|
|
// }
|
|
|
|
/******************************************************************************/
|
|
|
|
void CTedit::OnNcCalcSize( BOOL bCalcValidRects, NCCALCSIZE_PARAMS FAR* lpncsp )
|
|
{
|
|
/* Increase by an extra width height of the border*/
|
|
lpncsp->rgrc[0].left += CTracker::HANDLE_SIZE;
|
|
lpncsp->rgrc[0].top += CTracker::HANDLE_SIZE;
|
|
lpncsp->rgrc[0].right -= CTracker::HANDLE_SIZE;
|
|
lpncsp->rgrc[0].bottom -= CTracker::HANDLE_SIZE;
|
|
}
|
|
|
|
/******************************************************************************/
|
|
|
|
void CTedit::OnNcPaint()
|
|
{
|
|
CDC *pdcWindow = GetWindowDC();
|
|
|
|
ASSERT(pdcWindow != NULL);
|
|
|
|
if (pdcWindow != NULL)
|
|
{
|
|
CRgn rgnClipping;
|
|
CRect cWinRect;
|
|
int iWindowWidth;
|
|
int iWindowHeight;
|
|
|
|
GetWindowRect( &cWinRect );
|
|
|
|
iWindowWidth = cWinRect.Width();
|
|
iWindowHeight = cWinRect.Height();
|
|
|
|
CRect cBorderRect( 0, 0, iWindowWidth, iWindowHeight );
|
|
|
|
CTracker::DrawBorder ( pdcWindow, cBorderRect, CTracker::all );
|
|
CTracker::DrawHandles( pdcWindow, cBorderRect, CTracker::all );
|
|
|
|
ReleaseDC( pdcWindow );
|
|
}
|
|
}
|
|
|
|
/******************************************************************************/
|
|
|
|
UINT CTedit::OnNcHitTest( CPoint point )
|
|
{
|
|
CRect cClientRect;
|
|
UINT uiHitTestCode = HTCAPTION;
|
|
|
|
ScreenToClient( &point );
|
|
|
|
GetClientRect(&cClientRect);
|
|
|
|
//Test to see if the pt is in THE CLIENT AREA
|
|
if (cClientRect.PtInRect(point))
|
|
{
|
|
uiHitTestCode = HTCLIENT;
|
|
}
|
|
|
|
m_uiHitArea = HTNOWHERE;
|
|
|
|
switch (CTracker::HitTest( cClientRect, point, CTracker::nil ))
|
|
{
|
|
case CTracker::resizingTop:
|
|
m_uiHitArea = HTTOP;
|
|
break;
|
|
|
|
case CTracker::resizingLeft:
|
|
m_uiHitArea = HTLEFT;
|
|
break;
|
|
|
|
case CTracker::resizingRight:
|
|
m_uiHitArea = HTRIGHT;
|
|
break;
|
|
|
|
case CTracker::resizingBottom:
|
|
m_uiHitArea = HTBOTTOM;
|
|
break;
|
|
|
|
case CTracker::resizingTopLeft:
|
|
m_uiHitArea = HTTOPLEFT;
|
|
break;
|
|
|
|
case CTracker::resizingTopRight:
|
|
m_uiHitArea = HTTOPRIGHT;
|
|
break;
|
|
|
|
case CTracker::resizingBottomLeft:
|
|
m_uiHitArea = HTBOTTOMLEFT;
|
|
break;
|
|
|
|
case CTracker::resizingBottomRight:
|
|
m_uiHitArea = HTBOTTOMRIGHT;
|
|
break;
|
|
}
|
|
|
|
if (m_uiHitArea != HTNOWHERE)
|
|
uiHitTestCode = m_uiHitArea;
|
|
|
|
|
|
m_cEdit.SetHCursorShape();
|
|
|
|
|
|
return uiHitTestCode;
|
|
}
|
|
|
|
/******************************************************************************/
|
|
|
|
void CTedit::OnRButtonDown(UINT nFlags, CPoint point)
|
|
{
|
|
CMenu cMenuPopup;
|
|
CMenu *pcContextMenu;
|
|
CRect cRectClient;
|
|
BOOL bRC = cMenuPopup.LoadMenu( IDR_TEXT_POPUP );
|
|
|
|
ASSERT( bRC );
|
|
|
|
if (bRC)
|
|
{
|
|
GetClientRect( &cRectClient );
|
|
|
|
pcContextMenu = cMenuPopup.GetSubMenu( ID_EBOX_POPUPMENU_POS );
|
|
|
|
ASSERT( pcContextMenu != NULL );
|
|
|
|
if (pcContextMenu != NULL)
|
|
{
|
|
// update the check marks
|
|
OnUpdateTextPlain ( pcContextMenu );
|
|
OnUpdateTextBold ( pcContextMenu );
|
|
OnUpdateTextItalic ( pcContextMenu );
|
|
OnUpdateTextUnderline( pcContextMenu );
|
|
OnUpdateTextTexttool ( pcContextMenu );
|
|
|
|
ClientToScreen( &point );
|
|
ClientToScreen( &cRectClient );
|
|
|
|
// the frame actually has a clue about what items to enable...
|
|
CWnd *notify = GetParentFrame();
|
|
|
|
if( !notify )
|
|
notify = this; // oh well...
|
|
|
|
pcContextMenu->TrackPopupMenu( TPM_LEFTALIGN | TPM_RIGHTBUTTON,
|
|
point.x, point.y, notify, &cRectClient );
|
|
}
|
|
}
|
|
}
|
|
|
|
/******************************************************************************/
|
|
|
|
void CTedit::OnTextPlain()
|
|
{
|
|
ASSERT( m_pcTfont != NULL );
|
|
|
|
if (m_pcTfont != NULL)
|
|
{
|
|
if (m_pcTfont->IsBoldOn())
|
|
{
|
|
m_pcTfont->OnBold();
|
|
}
|
|
|
|
if (m_pcTfont->IsItalicOn())
|
|
{
|
|
m_pcTfont->OnItalic();
|
|
}
|
|
|
|
if (m_pcTfont->IsUnderlineOn())
|
|
{
|
|
m_pcTfont->OnUnderline();
|
|
}
|
|
|
|
if (m_pcTfont->IsShadowOn())
|
|
{
|
|
m_pcTfont->OnShadow();
|
|
}
|
|
|
|
m_pcTfont->RefreshToolBar();
|
|
|
|
RefreshWindow();
|
|
}
|
|
}
|
|
|
|
/******************************************************************************/
|
|
|
|
void CTedit::OnTextBold()
|
|
{
|
|
ASSERT(m_pcTfont != NULL);
|
|
|
|
if (m_pcTfont != NULL)
|
|
{
|
|
m_pcTfont->OnBold();
|
|
m_pcTfont->RefreshToolBar();
|
|
|
|
RefreshWindow();
|
|
}
|
|
}
|
|
|
|
/******************************************************************************/
|
|
|
|
void CTedit::OnTextItalic()
|
|
{
|
|
ASSERT(m_pcTfont != NULL);
|
|
|
|
if (m_pcTfont != NULL)
|
|
{
|
|
m_pcTfont->OnItalic();
|
|
m_pcTfont->RefreshToolBar();
|
|
|
|
RefreshWindow();
|
|
}
|
|
}
|
|
|
|
/******************************************************************************/
|
|
|
|
void CTedit::OnTextUnderline()
|
|
{
|
|
ASSERT(m_pcTfont != NULL);
|
|
|
|
if (m_pcTfont != NULL)
|
|
{
|
|
m_pcTfont->OnUnderline();
|
|
m_pcTfont->RefreshToolBar();
|
|
|
|
RefreshWindow();
|
|
}
|
|
}
|
|
|
|
/******************************************************************************/
|
|
|
|
void CTedit::OnTextSelectfont()
|
|
{
|
|
if (m_pcTfont != NULL)
|
|
{
|
|
if (! IsFontPaletteVisible())
|
|
ShowFontPalette( SW_SHOW );
|
|
else
|
|
m_pcTfont->SetFocus();
|
|
}
|
|
}
|
|
|
|
/******************************************************************************/
|
|
|
|
void CTedit::OnTextSelectpointsize()
|
|
{
|
|
if (m_pcTfont != NULL)
|
|
{
|
|
if (! IsFontPaletteVisible())
|
|
ShowFontPalette( SW_SHOW );
|
|
else
|
|
m_pcTfont->SetFocus();
|
|
|
|
CWnd* pWnd = m_pcTfont->GetFontSizeControl();
|
|
|
|
if (pWnd != NULL)
|
|
{
|
|
pWnd->SetFocus();
|
|
}
|
|
}
|
|
}
|
|
|
|
/******************************************************************************/
|
|
|
|
void CTedit::OnEditCut()
|
|
{
|
|
|
|
if ( m_bVertEdit ) HideCaret();
|
|
|
|
|
|
m_cEdit.Cut();
|
|
RefreshWindow();
|
|
|
|
|
|
if ( m_bVertEdit )
|
|
{
|
|
m_cEdit.SetCaretShape();
|
|
ShowCaret();
|
|
}
|
|
|
|
}
|
|
|
|
/******************************************************************************/
|
|
|
|
void CTedit::OnEditCopy()
|
|
{
|
|
m_cEdit.Copy();
|
|
}
|
|
|
|
/******************************************************************************/
|
|
|
|
void CTedit::OnEditPaste()
|
|
{
|
|
m_bPasting = TRUE;
|
|
|
|
#ifdef _DEBUG
|
|
TRACE0( "OnEditPaste Start\n" );
|
|
#endif
|
|
|
|
m_cEdit.Paste();
|
|
|
|
#ifdef _DEBUG
|
|
TRACE0( "OnEditPaste End\n" );
|
|
#endif
|
|
|
|
m_bPasting = FALSE;
|
|
|
|
RefreshWindow();
|
|
}
|
|
|
|
/******************************************************************************/
|
|
|
|
void CTedit::OnTextDelete()
|
|
{
|
|
int iLength = m_cEdit.GetWindowTextLength();
|
|
int iStart = iLength;
|
|
int iEnd = iLength;
|
|
|
|
|
|
if ( m_bVertEdit ) m_cEdit.HideCaret();
|
|
|
|
|
|
m_cEdit.GetSel( iStart, iEnd );
|
|
|
|
if (iStart == iEnd)
|
|
{
|
|
if (iLength == iStart)
|
|
return;
|
|
|
|
CString strText;
|
|
m_cEdit.GetWindowText(strText);
|
|
if (!strText.IsEmpty() && (IsDBCSLeadByte((CHAR)strText[iStart])
|
|
|| strText[iStart]==TEXT('\r')))
|
|
iEnd += 2;
|
|
else
|
|
iEnd += 1;
|
|
|
|
m_cEdit.SetSel( iStart, iEnd, TRUE );
|
|
}
|
|
m_cEdit.Clear();
|
|
|
|
|
|
if ( m_bVertEdit )
|
|
{
|
|
m_cEdit.SetCaretShape();
|
|
m_cEdit.SetCaretPosition( TRUE, NULL, -1 );
|
|
m_cEdit.ShowCaret();
|
|
m_cEdit.Repaint();
|
|
}
|
|
else
|
|
{
|
|
|
|
|
|
UpdateWindow();
|
|
RefreshWindow();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
/******************************************************************************/
|
|
|
|
void CTedit::OnTextSelectall()
|
|
{
|
|
m_cEdit.SetSel( 0, -1, TRUE );
|
|
|
|
RefreshWindow();
|
|
}
|
|
|
|
/******************************************************************************/
|
|
|
|
void CTedit::OnTextUndo()
|
|
{
|
|
Undo();
|
|
|
|
RefreshWindow();
|
|
}
|
|
|
|
/******************************************************************************/
|
|
|
|
void CTedit::OnTextPlace()
|
|
{
|
|
CWnd* cwndParent = GetParent();
|
|
|
|
cwndParent->PostMessage( WM_LBUTTONDOWN, MK_LBUTTON, MAKELPARAM( CTracker::HANDLE_SIZE + 1, CTracker::HANDLE_SIZE + 1 ) );
|
|
cwndParent->PostMessage( WM_LBUTTONUP, MK_LBUTTON, MAKELPARAM( CTracker::HANDLE_SIZE + 1, CTracker::HANDLE_SIZE + 1 ) );
|
|
}
|
|
|
|
/******************************************************************************/
|
|
|
|
void CTedit::OnTextTexttool()
|
|
{
|
|
if (IsFontPaletteVisible())
|
|
{
|
|
ShowFontPalette( SW_HIDE );
|
|
}
|
|
else
|
|
{
|
|
ShowFontPalette( SW_SHOWNOACTIVATE );
|
|
}
|
|
}
|
|
|
|
/******************************************************************************/
|
|
|
|
void CTedit::OnUpdateTextPlain( CMenu *pcMenu )
|
|
{
|
|
ASSERT( m_pcTfont != NULL );
|
|
|
|
if (m_pcTfont != NULL)
|
|
{
|
|
if (! m_pcTfont->IsBoldOn()
|
|
&& ! m_pcTfont->IsItalicOn()
|
|
&& ! m_pcTfont->IsUnderlineOn()
|
|
&& ! m_pcTfont->IsShadowOn())
|
|
{
|
|
pcMenu->CheckMenuItem(ID_TEXT_PLAIN, MF_BYCOMMAND | MF_CHECKED);
|
|
}
|
|
else
|
|
{
|
|
pcMenu->CheckMenuItem(ID_TEXT_PLAIN, MF_BYCOMMAND | MF_UNCHECKED);
|
|
}
|
|
}
|
|
}
|
|
|
|
/******************************************************************************/
|
|
|
|
void CTedit::OnUpdateTextBold(CMenu *pcMenu)
|
|
{
|
|
ASSERT(m_pcTfont != NULL);
|
|
|
|
if (m_pcTfont != NULL)
|
|
{
|
|
if (m_pcTfont->IsBoldOn())
|
|
{
|
|
pcMenu->CheckMenuItem(ID_TEXT_BOLD, MF_BYCOMMAND | MF_CHECKED);
|
|
}
|
|
else
|
|
{
|
|
pcMenu->CheckMenuItem(ID_TEXT_BOLD, MF_BYCOMMAND | MF_UNCHECKED);
|
|
}
|
|
}
|
|
}
|
|
|
|
/******************************************************************************/
|
|
|
|
void CTedit::OnUpdateTextItalic(CMenu *pcMenu)
|
|
{
|
|
ASSERT(m_pcTfont != NULL);
|
|
|
|
if (m_pcTfont != NULL)
|
|
{
|
|
if (m_pcTfont->IsItalicOn())
|
|
{
|
|
pcMenu->CheckMenuItem(ID_TEXT_ITALIC, MF_BYCOMMAND | MF_CHECKED);
|
|
}
|
|
else
|
|
{
|
|
pcMenu->CheckMenuItem(ID_TEXT_ITALIC, MF_BYCOMMAND | MF_UNCHECKED);
|
|
}
|
|
}
|
|
}
|
|
|
|
/******************************************************************************/
|
|
|
|
void CTedit::OnUpdateTextUnderline(CMenu *pcMenu)
|
|
{
|
|
ASSERT(m_pcTfont != NULL);
|
|
|
|
if (m_pcTfont != NULL)
|
|
{
|
|
if (m_pcTfont->IsUnderlineOn())
|
|
{
|
|
pcMenu->CheckMenuItem(ID_TEXT_UNDERLINE, MF_BYCOMMAND | MF_CHECKED);
|
|
}
|
|
else
|
|
{
|
|
pcMenu->CheckMenuItem(ID_TEXT_UNDERLINE, MF_BYCOMMAND | MF_UNCHECKED);
|
|
}
|
|
}
|
|
}
|
|
|
|
/******************************************************************************/
|
|
|
|
void CTedit::OnUpdateTextTexttool(CMenu *pcMenu)
|
|
{
|
|
if (IsFontPaletteVisible())
|
|
{
|
|
pcMenu->CheckMenuItem(ID_VIEW_TEXT_TOOLBAR, MF_BYCOMMAND | MF_CHECKED);
|
|
}
|
|
else
|
|
{
|
|
pcMenu->CheckMenuItem(ID_VIEW_TEXT_TOOLBAR, MF_BYCOMMAND | MF_UNCHECKED);
|
|
}
|
|
}
|
|
|
|
/******************************************************************************/
|
|
|
|
|
|
|
|
/******************************************************************************/
|
|
|
|
void CTedit::OnDestroy(void)
|
|
{
|
|
if ( m_cEdit.GetSafeHwnd() )
|
|
{
|
|
if ( m_cEdit.m_hOldCursor )
|
|
SetClassLongPtr( m_cEdit.m_hWnd, GCLP_HCURSOR, (LONG_PTR) m_cEdit.m_hOldCursor );
|
|
|
|
//restore original edit IMC
|
|
if (m_bAssocIMC)
|
|
{
|
|
m_bAssocIMC = FALSE;
|
|
EnableIme( m_cEdit.m_hWnd, m_hIMCEdit );
|
|
EnableIme( m_hWndFace, m_hIMCFace );
|
|
EnableIme( m_hWndSize, m_hIMCSize );
|
|
m_hIMCEdit = NULL;
|
|
m_hIMCFace = NULL;
|
|
m_hIMCSize = NULL;
|
|
}
|
|
}
|
|
|
|
Default();
|
|
return;
|
|
}
|
|
|
|
/******************************************************************************/
|
|
|
|
HIMC CTedit::DisableIme( HWND hWnd )
|
|
{
|
|
HIMC hIMC = NULL;
|
|
|
|
if ( (hWnd) && (::IsWindow( hWnd )) )
|
|
hIMC = ImmAssociateContext( hWnd, NULL );
|
|
|
|
return hIMC;
|
|
}
|
|
|
|
/******************************************************************************/
|
|
|
|
void CTedit::EnableIme( HWND hWnd, HIMC hIMC )
|
|
{
|
|
if ( (hWnd) && (::IsWindow( hWnd )) )
|
|
ImmAssociateContext( hWnd, hIMC );
|
|
}
|
|
|
|
/******************************************************************************/
|
|
|
|
//
|
|
// Tablet PC.
|
|
//
|
|
// Is CUAS (Cicero Unaware App Support) is on, we need to use hIMC even on
|
|
// Ansi Font. The string from English HW/Speech TIPs will be delivered
|
|
// through hIMC.
|
|
//
|
|
BOOL CTedit::IsCUAS()
|
|
{
|
|
BOOL bRet = FALSE;
|
|
|
|
typedef BOOL (*PFNCTFIMMISCICEROENABLED)(void);
|
|
|
|
static PFNCTFIMMISCICEROENABLED pfn = NULL;
|
|
|
|
if (!pfn)
|
|
{
|
|
HMODULE hMod = LoadLibrary(TEXT("imm32.dll"));
|
|
if (hMod)
|
|
{
|
|
pfn = (PFNCTFIMMISCICEROENABLED)GetProcAddress(hMod,
|
|
"CtfImmIsCiceroEnabled");
|
|
|
|
}
|
|
}
|
|
if (pfn)
|
|
bRet = pfn();
|
|
return bRet;
|
|
}
|
|
|
|
/******************************************************************************/
|