📄 edit.cpp
字号:
HRESULT result = S_OK;
switch (idTimer)
{
case RETID_BGND_RECALC:
{
_pdp->StepBackgroundRecalc();
break;
}
#if !defined(NOMAGELLAN)
case RETID_MAGELLANTRACK:
{
mouse.TrackUpdateMagellanMButtonDown( *this, _mousePt );
break;
}
#endif
case RETID_AUTOSCROLL: // Continuous scrolling.
{
// Do a select drag scroll.
OnTxMouseMove( _mousePt.x, _mousePt.y, 0, NULL );
break;
}
#if !defined(NOMAGELLAN)
case RETID_SMOOTHSCROLL: // Smooth scrolling
{
if ( _fMButtonCapture ) // HACK, only 1 timer!
{ // delivered on Win95
// when things get busy.
mouse.TrackUpdateMagellanMButtonDown( *this, _mousePt );
}
if ( _pdp->IsSmoothVScolling() ) // Test only because of
{ // above HACK!!
_pdp->SmoothVScrollUpdate();
}
}
break;
#endif
case RETID_DRAGDROP:
{
TxKillTimer(RETID_DRAGDROP);
if(_fWantDrag
&& _fDragged
&& !_fUsePassword
&& !IsProtected(_fReadOnly ? WM_COPY : WM_CUT,
_dwFkeys,
MAKELONG(_mousePt.x,_mousePt.y)) )
{
CGenUndoBuilder undobldr(this, UB_AUTOCOMMIT);
_ldte.StartDrag(GetSel(), &undobldr);
_fWantDrag = FALSE;
_fDragged = FALSE;
TxSetCapture(FALSE);
_fCapture = FALSE;
}
break;
}
default:
{
result = S_FALSE;
break;
}
}
return result;
}
const TCHAR c_pszRTF[] = __TEXT("Rich Text Format");
UINT GetBestClipFormat()
{
// This is copied from PWord.c. We need to make sure we are using the same clipboard format
static UINT cfRTF = 0xFFFF;
if (0xFFFF == cfRTF)
{
cfRTF = RegisterClipboardFormat(c_pszRTF);
}
UINT cf=0;
if (IsClipboardFormatAvailable(CF_DIB)) {
cf = CF_DIB;
}
if (IsClipboardFormatAvailable(CF_TEXT)) {
cf = CF_TEXT;
}
if (IsClipboardFormatAvailable(CF_UNICODETEXT)) {
cf = CF_UNICODETEXT;
}
if (IsClipboardFormatAvailable(cfRTF)) {
cf = cfRTF;
}
return cf;
}
/////////////////////////// Keyboard Commands ////////////////////////////////
/*
* CTxtEdit::OnTxKeyDown(vkey, dwFlags, publdr)
*
* @mfunc
* Handle WM_KEYDOWN message
*
* @rdesc
* HRESULT with the following values:
*
* S_OK if key was understood and consumed
* S_MSG_KEY_IGNORED if key was understood, but not consumed
* S_FALSE if key was not understood (and not consumed)
*/
HRESULT CTxtEdit::OnTxKeyDown(
WORD vkey, //@parm Virtual key code
DWORD dwFlags, //@parm lparam of WM_KEYDOWN msg
IUndoBuilder *publdr) //@parm Undobuilder to receive antievents
{
TRACEBEGIN(TRCSUBSYSEDIT, TRCSCOPEINTERN, "CTxtEdit::OnTxKeyDown");
BOOL fRet = FALSE; // Converted to HRESULT on return
BOOL fCtrl = FALSE;
BOOL fShift;
LONG nDeadKey = 0;
// If dragging or Alt key down, just look for ESCAPE. Note: if Alt key is
// down, we should never come here (would generate WM_SYSKEYDOWN message).
if(_fMouseDown)
{
if (vkey == VK_ESCAPE)
{
POINT pt;
// Cancel drag select or drag & drop
GetCursorPos(&pt);
OnTxLButtonUp(pt.x, pt.y, 0, TRUE);
return S_OK;
}
return OnTxSpecialKeyDown(vkey, dwFlags, publdr);
}
CTxtSelection * const psel = GetSel();
AssertSz(psel,"CTxtEdit::OnKeyDown() - No selection object !");
fShift = (GetKeyState(VK_SHIFT) & 0x8000) != 0;
if(GetKeyState(VK_CONTROL) & 0x8000)
{
fCtrl = TRUE;
if (OnTxSpecialKeyDown(vkey, dwFlags, publdr) == S_OK)
return S_OK;
if (IsIMEComposition())
{
// During IME Composition, there are some key events we should
// not handle. Also, there are other key events we need to handle by
// terminating the IME composition first.
BOOL bDontHandle = FALSE;
switch(vkey)
{
case VK_TAB:
case VK_CLEAR:
case VK_NUMPAD5:
case 'A': // Ctrl-A => pselect all
case 'C': // Ctrl-C => copy
case 'X': // Ctrl-X => cut
case 'Y': // Ctrl-Y => redo
bDontHandle = TRUE;
break;
case 'V': // Ctrl-V => paste
case 'Z': // Ctrl-Z => undo
_ime->TerminateIMEComposition(*this, CIme::TERMINATE_NORMAL );
// early exist for undo case
if (vkey == 'Z')
bDontHandle = TRUE;
break;
default:
// we can goto cont since we have handled all the cases
// for the below switch block.
goto cont;
}
if (bDontHandle)
return S_OK;
}
switch(vkey)
{
case VK_TAB:
return OnTxChar(VK_TAB, dwFlags, publdr);
case VK_CLEAR:
case VK_NUMPAD5:
case 'A': // Ctrl-A => pselect all
psel->SelectAll();
break;
case 'C': // Ctrl-C => copy
CtrlC: CutOrCopySelection(WM_COPY, 0, 0, NULL);
break;
case 'V': // Ctrl-V => paste
CtrlV: if( IsntProtectedOrReadOnly( WM_PASTE, 0, 0) )
{
PasteDataObjectToRange(NULL, (CTxtRange *)psel, (CLIPFORMAT) GetBestClipFormat(), NULL, publdr, PDOR_NONE);
// to match the Word UI, better go ahead and update the window
TxUpdateWindow();
}
break;
case 'X': // Ctrl-X => cut
CtrlX: CutOrCopySelection(WM_CUT, 0, 0, publdr);
break;
case 'Z': // Ctrl-Z => undo
if (_pundo && !_fReadOnly )
{
PopAndExecuteAntiEvent(_pundo, 0);
}
break;
case 'Y': // Ctrl-Y => redo
if( _predo && !_fReadOnly )
{
PopAndExecuteAntiEvent(_predo, 0);
}
break;
case VK_CONTROL:
goto cont;
#define VK_APOSTROPHE 0xDE
#define VK_GRAVE 0xC0
#define VK_SEMICOLON 0xBA
#define VK_COMMA 0xBC
case VK_APOSTROPHE:
if(fShift)
g_wFlags ^= KF_SMARTQUOTES;
else
nDeadKey = ACCENT_ACUTE;
break;
case VK_GRAVE:
nDeadKey = fShift ? ACCENT_TILDE : ACCENT_GRAVE;
break;
case VK_SEMICOLON:
nDeadKey = ACCENT_UMLAUT;
break;
case '6':
if(!fShift)
goto cont;
nDeadKey = ACCENT_CARET;
break;
case VK_COMMA:
nDeadKey = ACCENT_CEDILLA;
break;
default:
goto cont;
}
// Since these choices vary a bit according to keyboard, we only
// enable them for English. French, German, Italian, and Spanish
// keyboard already have a fair amount of accent capability.
if(PRIMARYLANGID(GetKeyboardLayout(0)) == LANG_ENGLISH)
_bDeadKey = nDeadKey;
return S_OK;
}
cont:
if (IsIMEComposition())
{
// During IME Composition, there are some key events we should
// not handle. Also, there are other key events we need to handle by
// terminating the IME composition first.
BOOL bDontHandle = FALSE;
switch(vkey)
{
case VK_BACK:
case VK_F16:
bDontHandle = TRUE;
break;
case VK_INSERT: // Ins
if(fShift) // Shift-Ins --> paste
_ime->TerminateIMEComposition(*this, CIme::TERMINATE_NORMAL );
else
bDontHandle = TRUE;
break;
#ifndef PWD_JUPITER
// GuyBark JupiterJ 49220:
// These are all legitamate things to do with undetermined ime now,
// and so we DON'T want it to be determined with these key presses.
case VK_LEFT: // Left arrow
case VK_RIGHT: // Right arrow
case VK_UP: // Up arrow
case VK_DOWN: // Down arrow
case VK_HOME: // Home
case VK_END: // End
case VK_PRIOR: // PgUp
case VK_NEXT: // PgDn
#endif // !PWD_JUPITER
case VK_DELETE: // Del
// Ctrl-Return generates Ctrl-J (LF), treat it as an ordinary return
case CTRL('J'):
case VK_RETURN:
_ime->TerminateIMEComposition(*this, CIme::TERMINATE_NORMAL);
break;
}
if (bDontHandle)
return S_MSG_KEY_IGNORED;
}
psel->SetExtend(fShift);
switch(vkey)
{
case VK_BACK:
case VK_F16:
if(_fReadOnly)
{
Sound();
fRet = TRUE;
}
else if(IsntProtectedOrReadOnly(WM_KEYDOWN, VK_BACK, dwFlags))
{
fRet = psel->Backspace(fCtrl, publdr);
}
break;
case VK_INSERT: // Ins
if(fShift) // Shift-Ins
goto CtrlV; // Alias for Ctrl-V
if(fCtrl) // Ctrl-Ins
goto CtrlC; // Alias for Ctrl-C
if(!_fReadOnly) // Ins
_fOverstrike = !_fOverstrike; // Toggle Ins/Ovr
fRet = TRUE;
break;
case VK_LEFT: // Left arrow
if(!IsIMEComposition() || !fCtrl){
fRet = psel->Left(fCtrl);
} else {
fRet = TRUE;
}
break;
case VK_RIGHT: // Right arrow
if(!IsIMEComposition() || !fCtrl){
fRet = psel->Right(fCtrl);
} else {
fRet = TRUE;
}
break;
case VK_UP: // Up arrow
if(!IsIMEComposition() || !fCtrl){
fRet = psel->Up(fCtrl);
} else {
fRet = TRUE;
}
break;
case VK_DOWN: // Down arrow
if(!IsIMEComposition() || !fCtrl){
fRet = psel->Down(fCtrl);
} else {
fRet = TRUE;
}
break;
case VK_HOME: // Home
fRet = psel->Home(fCtrl);
break;
case VK_END: // End
fRet = psel->End(fCtrl);
break;
case VK_PRIOR: // PgUp
fRet = psel->PageUp(fCtrl);
break;
case VK_NEXT: // PgDn
fRet = psel->PageDown(fCtrl);
break;
case VK_DELETE: // Del
if(fShift) // Shift-Del
goto CtrlX; // Alias for Ctrl-X
if(IsntProtectedOrReadOnly(WM_KEYDOWN, VK_DELETE, dwFlags))
psel->Delete(fCtrl, publdr);
fRet = TRUE;
break;
case CTRL('J'): // Ctrl-Return gives Ctrl-J
case VK_RETURN: // (LF), treat it as return
if(!TxGetMultiLine())
{
Sound();
return S_FALSE;
}
SetCursor(0);
if(IsntProtectedOrReadOnly(WM_CHAR, VK_RETURN, dwFlags))
psel->InsertEOP(publdr);
fRet = TRUE;
break;
case VK_PROCESSKEY:
// We will receive this case when handling
// IME input only. Check to see if protected is on
// If so, we will ingore IME input
if(!IsntProtectedOrReadOnly(WM_CHAR, VK_RETURN, dwFlags))
{
HWND hwnd;
TxGetWindow( &hwnd );
return ( IgnoreIMEInput( hwnd, *this, dwFlags ) );
}
return S_FALSE;
case VK_KANA:
// for Japanese, this virtual key indicates Kana mode.
// Check the toggle bit to see if it is on or offf.
// If on, Kana characters (single byte Japanese char) are coming in via WM_CHAR.
_fKANAMode = (GetKeyState(VK_KANA) & 0x1) != 0;
return S_OK;
case VK_KANJI:
// for Korean, need to convert the next Korean Hangeul character to Hanja
if(_KOREAN_CP == GetKeyboardCodePage() &&
IsntProtectedOrReadOnly(WM_KEYDOWN, VK_KANJI, dwFlags))
fRet = IMEHangeulToHanja ( *this, *publdr );
break;
default:
return S_FALSE;
}
return fRet ? S_OK : S_MSG_KEY_IGNORED;
}
/*
* CTxtEdit::CutOrCopySelection(msg, wparam, lparam, publdr)
*
* @mfunc
* Handle WM_COPY message and its keyboard hotkey aliases
*
* @rdesc
* HRESULT
*/
HRESULT CTxtEdit::CutOrCopySelection(
UINT msg, //@parm Message (WM_CUT or WM_COPY)
WPARAM wparam, //@parm Message wparam for protection check
LPARAM lparam, //@parm Message lparam for protection check
IUndoBuilder *publdr) //@parm Undobuilder to receive antievents
{
Assert(msg == WM_CUT || msg == WM_COPY);
if(!_fUsePassword && IsntProtectedOrReadOnly(msg, wparam, lparam))
{
CTxtSelection *psel = GetSel();
if(!psel)
{
return E_OUTOFMEMORY;
}
psel->CheckTableSelection();
return msg == WM_COPY
? _ldte.CopyRangeToClipboard((CTxtRange *)psel)
: _ldte.CutRangeToClipboard((CTxtRange *)psel, publdr);
}
return NOERROR;
}
/*
* CTxtEdit::OnTxSpecialKeyDown(vkey, dwFlags, publdr)
*
* @mfunc
* Handle WM_KEYDOWN message for outline mode
*
* @rdesc
* HRESULT with the following values:
*
* S_OK if key was understood and consumed
* S_MSG_KEY_IGNORED if key was understood, but not consumed
* S_FALSE if key was not understood (and not consumed)
*/
HRESULT CTxtEdit::OnTxSpecialKeyDown(
WORD vkey, //@parm Virtual key code
DWORD dwFlags, //@parm lparam of WM_KEYDOWN msg
IUndoBuilder *publdr) //@parm Undobuilder to receive antievents
{
TRACEBEGIN(TRCSUBSYSEDIT, TRCSCOPEINTERN, "CTxtEdit::OnTxOutlineKeyDown");
if (IsIMEComposition())
return S_FALSE;
HRESULT hr = S_OK;
int level = 0;
BOOL fWholeDoc = TRUE;
if(!TxGetMultiLine() || !IsRich()) // Control must be rich,
return S_FALSE; // multiline and active
int const SHFT_ON = 1;
int const ALT_ON = 2;
int const CTL_ON = 4;
int iKeyState = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -