📄 kedit.cpp
字号:
/*
Copyright (c) 1999, kSet Lab
Author: Konstantin Bukreev
E-mail: konstantin@mail.primorye.ru
kEdit.cpp : Implementation of _kEdit
*/
#include "stdafx.h"
#include "KSetEditor.h"
#include "kEdit.h"
#include "GdiHelper.h"
#include "HSVModel.h"
#include "About.h"
void _kEdit::CreateMenu()
{
m_hMenu = LoadMenu(_Module.GetResourceInstance(), MAKEINTRESOURCE(IDR_MENU1));
}
void _kEdit::ExecuteMenu (int id)
{
switch (id)
{
case IDM_UNDO: m_pedit->undo(); break;
case IDM_REDO: m_pedit->redo(); break;
case IDM_CUT: m_pedit->cut(); break;
case IDM_COPY: m_pedit->copy(); break;
case IDM_PASTE: m_pedit->paste(); break;
case IDM_DELETE: m_pedit->del(); break;
case IDM_SELALL:
m_pedit->caret(0);
m_pedit->select(m_pedit->length());
break;
default:
return;
}
SetTextCoordSize();
ShowCaretHelper();
FireViewChange();
}
void _kEdit::UpdateColors()
{
if (m_clrContainerColor != (0x80000000 | COLOR_BTNFACE))
{
//change color thru hsl model
COLORREF clr;
OleTranslateColor(m_clrContainerColor, m_hPalette, &clr);
Get3DColors(clr, m_clrShadowColor, m_clrHighlightColor);
}
else
{
m_clrShadowColor = 0x80000000 | COLOR_3DSHADOW;
m_clrHighlightColor = 0x80000000 | COLOR_3DHILIGHT;
}
}
bool _kEdit::SetTextCoordSize(bool bCycleYes)
{
unsigned int m_uiPrevScroll = m_uiScroll;
if (m_pedit->caret() < m_uiScroll)
m_uiScroll = m_pedit->caret();
_kAutoDC<_kEdit> hdc(this);
_kAutoSelect<HFONT> _auto(hdc, m_hFont);
TCHAR* pStr; int len;
cycle:
pStr = (TCHAR*)&m_pedit->text()[m_uiScroll];
len = m_pedit->length() - m_uiScroll;
m_szTxt.cx = 0;
GetTextExtentExPoint(hdc, pStr, len, m_uiWidthBox, (int*)&m_uiLength, 0, &m_szTxt);
if (m_eAlignment && bCycleYes)
while (m_uiScroll && (m_szTxt.cx < m_uiWidthBox))
{
m_uiScroll--; pStr--; len++;
GetTextExtentExPoint(hdc, pStr, len, m_uiWidthBox, (int*)&m_uiLength, 0, &m_szTxt);
}
if (len != m_uiLength)
GetTextExtentPoint32(hdc, pStr, m_uiLength, &m_szTxt);
switch (m_eAlignment)
{
case 0: m_pTxt.x = INDENT_LEFT; break; //left
case 1: m_pTxt.x = max(INDENT_LEFT, (INDENT_LEFT + (((int)m_uiWidthBox - m_szTxt.cx) >> 1))); break; //central
case 2: m_pTxt.x = max(INDENT_LEFT, (INDENT_LEFT + ((int)m_uiWidthBox - m_szTxt.cx))); break; //right
default:
ATLTRACE("Invalid value for m_eAlignment: %u\n", m_eAlignment);
ATLASSERT(0);
};
if (m_pedit->caret() > (m_uiScroll + m_uiLength))
{
m_uiScroll += m_pedit->caret() - m_uiScroll - m_uiLength;
bCycleYes = false;
goto cycle; //Ooops!
}
return (m_uiPrevScroll != m_uiScroll);
}
void _kEdit::SetCaretByMouseClick(POINT& p, bool bshift)
{
_kAutoDC<_kEdit> hdc(this);
DPtoLP(hdc, &p, 1);
if (bshift)
if (p.x < m_pTxt.x)
{
if (m_pedit->left(bshift))
MoveCaretLeft();
return;
}
else if (p.x > (m_pTxt.x + m_uiWidthBox))
{
if(m_pedit->right(bshift))
MoveCaretRight();
return;
}
_kAutoSelect<HFONT> _auto(hdc, m_hFont);
TCHAR* pStr = (TCHAR*)&m_pedit->text()[m_uiScroll];
int position = 0;
int x_mouse = p.x - m_pTxt.x;
SIZE sz;
GetTextExtentExPoint(hdc, pStr, m_uiLength, x_mouse, &position, 0, &sz);
try{m_pedit->caret(m_uiScroll + position, bshift);}
catch(...) {ATLASSERT(0);}
GetTextExtentPoint32(hdc, pStr, m_pedit->caret() - m_uiScroll, &sz);
SetCaretPosition(sz.cx + m_pTxt.x);
}
bool _kEdit::MoveCaretLeft()
{
if (m_uiScroll > m_pedit->caret())
{
SetTextCoordSize(false);
ShowCaretHelper();
return true;
}
else
{
TCHAR ch = m_pedit->text()[m_pedit->caret()];
SetCaretPosition(m_pCaret.x - GetExtentChar(ch));
return false;
}
}
bool _kEdit::MoveCaretRight()
{
if (m_pedit->caret() > (m_uiScroll + m_uiLength))
{
SetTextCoordSize(false);
ShowCaretHelper();
return true;
}
else
{
TCHAR ch = m_pedit->text()[m_pedit->caret() - 1];
SetCaretPosition(m_pCaret.x + GetExtentChar(ch));
return false;
}
}
void _kEdit::SetMousePointer()
{
if (m_eMousePointer == kCustom)
{
OLE_HANDLE hOle = 0;
CComQIPtr<IPicture> pPic(m_pMouseIcon);
if (pPic)
{
if (SUCCEEDED(pPic->get_Handle(&hOle)) && hOle)
m_hCursor = (HCURSOR)hOle;
}
}
else
{
m_hCursor = LoadCursor(0, m_eMousePointer == kArrow ? IDC_ARROW : IDC_IBEAM);
}
}
void _kEdit::CalcCoordSizeCaret()
{
m_pCaret.y = max(0, ((m_szControl.cy - m_yChar) / 2));
if (m_eCaretView == kCaretHorz)
{
m_uiWidthCaret = m_xChar;
m_pCaret.y += m_baseline;
}
else
{
m_uiWidthCaret = 1;
}
}
HRESULT _kEdit::FireOnRequestEdit(DISPID dispID)
{
if (dispID == DISPID_FONT)
{
if (m_pFont && m_hFont.isOk())
{
CComQIPtr<IFont> pF(m_pFont);
if (pF)
pF->ReleaseHfont(m_hFont);
m_hFont = 0;
}
}
return CComControl<_kEdit>::FireOnRequestEdit(dispID);
}
HRESULT _kEdit::FireOnChanged (DISPID dispID)
{
ATLTRACE("FireOnChanged property %i\n", dispID);
switch (dispID)
{
case DISPID_ENABLED:
m_pedit->enabled(m_bEnabled != 0);
break;
case dispidContainerColor:
UpdateColors();
break;
case DISPID_FONT:
{
CComQIPtr<IFont> pF(m_pFont);
ATLASSERT(pF.p != 0);
ATLASSERT(m_hFont == 0);
if (SUCCEEDED(pF->get_hFont(&m_hFont)) && m_hFont.isOk())
pF->AddRefHfont(m_hFont);
TEXTMETRICOLE tm;
pF->QueryTextMetrics(&tm);
m_yChar = tm.tmHeight;
m_xChar = tm.tmAveCharWidth;
m_tmOverhang = tm.tmOverhang;
m_tmPitchAndFamily = tm.tmPitchAndFamily;
m_baseline = tm.tmAscent + tm.tmExternalLeading;
CalcCoordY();
CalcCoordSizeCaret();
if (IsWindow())
SetTextCoordSize();
}
break;
case DISPID_TEXT:
m_pedit->reset_undo();
m_pedit->caret(0);
if (IsWindow())
SetTextCoordSize();
break;
case dispidStackSize:
m_pedit->set_stack_size(m_lUndoStackSize); break;
case dispidCaret:
CalcCoordSizeCaret();
break;
case dispidAlignment:
if (IsWindow())
SetTextCoordSize();
break;
case DISPID_MOUSEICON:
case DISPID_MOUSEPOINTER:
SetMousePointer();
break;
default:
break;
};
Prepare(dispID);
return CComControl<_kEdit>::FireOnChanged(dispID);
}
STDMETHODIMP _kEdit::put_Text(BSTR pText)
{
USES_CONVERSION;
ATLTRACE2(atlTraceControls,2,_T("_kEdit::put_Text\n"));
if (FireOnRequestEdit(DISPID_TEXT) == S_FALSE)
return S_FALSE;
m_pedit->text(W2T(pText));
m_bRequiresSave = TRUE;
FireOnChanged(DISPID_TEXT);
FireViewChange();
SendOnDataChange(0);
return S_OK;
}
STDMETHODIMP _kEdit::get_Text(BSTR* ppText)
{
USES_CONVERSION;
ATLTRACE2(atlTraceControls,2,_T("_kEdit::get_Text\n"));
*ppText = SysAllocString(T2W(m_pedit->text()));
return S_OK;
}
STDMETHODIMP _kEdit::AboutBox()
{
_About about;
about.DoModal();
return S_OK;
}
STDMETHODIMP _kEdit::InitNew()
{
if (FAILED(GetAmbientPalette(m_hPalette)))
m_hPalette = 0;
if (FAILED(GetAmbientBackColor(m_clrContainerColor)))
m_clrContainerColor = 0x80000000 | COLOR_BTNFACE;
if (FAILED(GetAmbientForeColor(m_clrForeColor)))
m_clrForeColor = 0x80000000 | COLOR_BTNTEXT;
m_clrBorderColor = m_clrForeColor;
m_clrBackColor = 0x80000000 | COLOR_WINDOW;
static FONTDESC _fontdesc = {sizeof(FONTDESC), L"MS Sans Serif", FONTSIZE(9), FW_NORMAL, ANSI_CHARSET, FALSE, FALSE, FALSE};
{
CComPtr<IFontDisp> pF;
if (OleCreateFontIndirect(&_fontdesc, __uuidof(IFontDisp), (void**)&pF) == S_OK && pF)
putref_Font(pF);
}
m_pedit->text((TCHAR*)EDIT_DEFAULT_STR);
m_lUndoStackSize = kDefaultUndoStackSize;
m_pedit->set_stack_size(m_lUndoStackSize);
m_nAppearance = k3dHigh;
m_bEnabled = TRUE;
m_eCaretView = kCaretHorz;
m_uiScroll = 0;
m_IsFocused = false;
m_bMousePressed = false;
m_bHideSelection = FALSE;
m_eFontEffect = kNoEffect;
m_eAlignment = kLeftJustify;
m_eMousePointer = kBeam;
FireOnChanged(dispidCaret);
FireOnChanged(DISPID_TEXT);
FireOnChanged(DISPID_MOUSEPOINTER);
FireOnChanged(dispidContainerColor);
FireOnChanged(DISPID_BACKCOLOR);
FireOnChanged(DISPID_BORDERCOLOR);
FireOnChanged(DISPID_ENABLED);
// FireOnChanged(DISPID_FORECOLOR);
// FireOnChanged(dispidFontEffect);
return IPersistStreamInitImpl<_kEdit>::InitNew();
}
STDMETHODIMP _kEdit::DoVerb(LONG iVerb, LPMSG lpmsg, IOleClientSite *pActiveSite, LONG lindex, HWND hwndParent, LPCRECT lprcPosRect)
{
if (iVerb == 1)
iVerb = OLEIVERB_PROPERTIES;
else if (iVerb == 2)
AboutBox();
return IOleObjectImpl<_kEdit>::DoVerb(iVerb, lpmsg, pActiveSite, lindex, hwndParent, lprcPosRect);
}
//window message handlers
LRESULT _kEdit::OnRButtonUp(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
if (m_hMenu)
{
POINT p = {LOWORD(lParam), HIWORD(lParam)};
ClientToScreen(&p);
EnableMenuItem(m_hMenu, IDM_UNDO, MF_BYCOMMAND | (m_pedit->canundo() ? MF_ENABLED : MF_GRAYED));
EnableMenuItem(m_hMenu, IDM_REDO, MF_BYCOMMAND | (m_pedit->canredo() ? MF_ENABLED : MF_GRAYED));
EnableMenuItem(m_hMenu, IDM_CUT, MF_BYCOMMAND | (m_bEnabled && m_pedit->isselect() ? MF_ENABLED : MF_GRAYED));
EnableMenuItem(m_hMenu, IDM_COPY, MF_BYCOMMAND | (m_pedit->isselect() ? MF_ENABLED : MF_GRAYED));
EnableMenuItem(m_hMenu, IDM_DELETE, MF_BYCOMMAND | (m_bEnabled && m_pedit->isselect() ? MF_ENABLED : MF_GRAYED));
EnableMenuItem(m_hMenu, IDM_PASTE, MF_BYCOMMAND | (m_bEnabled && IsClipboardFormatAvailable(_CF_TEXT) ? MF_ENABLED : MF_GRAYED));
ExecuteMenu(TrackPopupMenu(GetSubMenu(m_hMenu, 0),
TPM_LEFTALIGN | TPM_NONOTIFY | TPM_RETURNCMD, p.x, p.y, 0, m_hWnd, 0));
}
return 0;
}
LRESULT _kEdit::OnRButtonDown(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
return 0;
}
LRESULT _kEdit::OnLButtonUp(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
m_bMousePressed = false;
ReleaseCapture();
FireMouseUp(CrackButton(wParam | MK_LBUTTON), CrackShift(wParam), LOWORD(lParam), HIWORD(lParam));
POINT p = {LOWORD(lParam), HIWORD(lParam)};
RECT rc = {0, 0, m_szControl.cx, m_szControl.cy};
if (PtInRect(&rc, p))
FireClick();
return 0;
}
LRESULT _kEdit::OnLButtonDown(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
if (!m_IsFocused)
SetControlFocus(TRUE);
POINT p = {LOWORD(lParam), HIWORD(lParam)};
SetCapture();
bool bshift = GetKeyState(VK_SHIFT) < 0;
bool bselect = m_pedit->isselect();
SetCaretByMouseClick(p, bshift);
if (bshift || bselect)
FireViewChange();
m_bMousePressed = true;
FireMouseDown(CrackButton(wParam), CrackShift(wParam), LOWORD(lParam), HIWORD(lParam));
return 0;
}
LRESULT _kEdit::OnLButtonDbl(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
POINT p = {LOWORD(lParam), HIWORD(lParam)};
SetCaretByMouseClick(p, GetKeyState(VK_SHIFT) < 0);
m_pedit->select_word();
ShowCaretHelper();
m_bMousePressed = false;
if (m_pedit->isselect())
FireViewChange();
FireDblClick();
return 0;
}
LRESULT _kEdit::OnKeyUp(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
FireKeyUp(wParam,
GetKeyState(VK_SHIFT) < 0 ? 1 : 0 +
GetKeyState(VK_CONTROL) < 0 ? 2 : 0);
return 0;
}
LRESULT _kEdit::OnKeyDown(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
bool bControl = GetKeyState(VK_CONTROL) < 0;
bool bShift = GetKeyState(VK_SHIFT) < 0;
bool bDrawNeed = (bShift || m_pedit->isselect());
switch (wParam)
{
case 57: // 9
if (bShift)
{
//for fix very strange bug !
BOOL bln;
OnChar(0, 40, 0, bln);
}
break;
case VK_HOME:
m_pedit->caret(0, bShift);
bDrawNeed = bDrawNeed || SetTextCoordSize();
SetCaretPosition(m_pTxt.x);
break;
case VK_END:
m_pedit->caret(m_pedit->length(), bShift);
bDrawNeed = bDrawNeed || SetTextCoordSize();
ShowCaretHelper();
break;
case VK_DELETE:
m_pedit->del();
SetTextCoordSize();
ShowCaretHelper();
bDrawNeed = true;
break;
case VK_BACK:
if (m_pedit->isselect() || m_pedit->left(true))
{
m_pedit->del();
SetTextCoordSize();
ShowCaretHelper();
bDrawNeed = true;
}
break;
case VK_RIGHT: case VK_DOWN:
{
bool bNext;
do
{
bNext = m_pedit->right(bShift);
if (bNext && MoveCaretRight())
bDrawNeed = true;
} while (bNext && bControl
&& m_pedit->text()[m_pedit->caret()] != TCHAR(' '));
break;
}
case VK_LEFT: case VK_UP:
{
bool bNext;
do
{
bNext = m_pedit->left(bShift);
if (bNext && MoveCaretLeft())
bDrawNeed = true;
} while (bNext && bControl
&& m_pedit->text()[m_pedit->caret()] != TCHAR(' '));
break;
}
default:
if (bControl)
{
switch (wParam)
{
case 65: ExecuteMenu(IDM_SELALL); break;
case 67: ExecuteMenu(IDM_COPY); break;
case 86: ExecuteMenu(IDM_PASTE); break;
case 88: ExecuteMenu(IDM_CUT); break;
case 89: ExecuteMenu(IDM_REDO); break;
case 90: ExecuteMenu(IDM_UNDO); break;
default: break;
}
}
break;
};
if (bDrawNeed)
FireViewChange();
FireKeyDown(wParam, bShift + ((int)bControl << 1));
return 0;
}
LRESULT _kEdit::OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
CreateMenu();
return 0;
}
LRESULT _kEdit::OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
m_szControl.cx = LOWORD(lParam);
m_szControl.cy = HIWORD(lParam);
if (m_hCacheBitmap)
{
DeleteObject(m_hCacheBitmap);
m_hCacheBitmap = 0;
}
SetWidthIndentValue();
SetTextCoordSize();
CalcCoordY();
CalcCoordSizeCaret();
return 0;
}
LRESULT _kEdit::OnSetFocus(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
m_IsFocused = true;
CreateCaretHelper();
ShowCaret();
ShowCaretHelper();
FireViewChange();
FireSetFocus();
bHandled = FALSE;
return 0;
}
LRESULT _kEdit::OnKillFocus(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
m_IsFocused = false;
HideCaret();
DestroyCaret();
FireViewChange();
FireKillFocus();
bHandled = FALSE;
return 0;
}
LRESULT _kEdit::OnDestroy(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
m_pUnkMouseMove.Release();
if (m_pFont && (bool)m_hFont)
{
CComQIPtr<IFont> pF(m_pFont);
if (pF)
pF->ReleaseHfont(m_hFont);
}
if(m_hMenu)
{
DestroyMenu(m_hMenu);
}
if (m_hCacheBitmap)
{
DeleteObject(m_hCacheBitmap);
}
try{delete m_pedit;}
catch(...){ATLASSERT(0);}
return 0;
}
void _kEdit::Get3DColors (COLORREF clr, COLORREF& clrShadow, COLORREF& clrHighlight)
{
_HSLModel hsl(clr);
_HSLModel _hs1 = hsl;
BYTE lum = hsl.luminance();
hsl.luminance (lum / 3 * 2);
_hs1.luminance (lum + ((240 - lum) / 2));
clrShadow = hsl.rgb();
clrHighlight = _hs1.rgb();
}
void _kEdit::DetectTrackMouse()
{
m_pfTrackMouseEvent = (PTRF_TrackMouseEvent)GetProcAddress (GetModuleHandle(_T("user32")), _T("TrackMouseEvent"));
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -