📄 scintillawin.cxx
字号:
}
}
Command(LoWord(wParam));
#endif
break;
case WM_PAINT:
return WndPaint(wParam);
case WM_VSCROLL:
ScrollMessage(wParam);
break;
case WM_HSCROLL:
HorizontalScrollMessage(wParam);
break;
case WM_SIZE: {
//Platform::DebugPrintf("Scintilla WM_SIZE %d %d\n", LoWord(lParam), HiWord(lParam));
ChangeSize();
}
break;
case WM_MOUSEWHEEL:
// Don't handle datazoom.
// (A good idea for datazoom would be to "fold" or "unfold" details.
// i.e. if datazoomed out only class structures are visible, when datazooming in the control
// structures appear, then eventually the individual statements...)
if (wParam & MK_SHIFT) {
return ::DefWindowProc(MainHWND(), iMessage, wParam, lParam);
}
// Either SCROLL or ZOOM. We handle the wheel steppings calculation
wheelDelta -= static_cast<short>(HiWord(wParam));
if (abs(wheelDelta) >= WHEEL_DELTA && linesPerScroll > 0) {
int linesToScroll = linesPerScroll;
if (linesPerScroll == WHEEL_PAGESCROLL)
linesToScroll = LinesOnScreen() - 1;
if (linesToScroll == 0) {
linesToScroll = 1;
}
linesToScroll *= (wheelDelta / WHEEL_DELTA);
if (wheelDelta >= 0)
wheelDelta = wheelDelta % WHEEL_DELTA;
else
wheelDelta = - (-wheelDelta % WHEEL_DELTA);
if (wParam & MK_CONTROL) {
// Zoom! We play with the font sizes in the styles.
// Number of steps/line is ignored, we just care if sizing up or down
if (linesToScroll < 0) {
KeyCommand(SCI_ZOOMIN);
} else {
KeyCommand(SCI_ZOOMOUT);
}
} else {
// Scroll
ScrollTo(topLine + linesToScroll);
}
}
return 0;
case WM_TIMER:
Tick();
break;
case WM_GETMINMAXINFO:
return ::DefWindowProc(MainHWND(), iMessage, wParam, lParam);
case WM_LBUTTONDOWN:
//Platform::DebugPrintf("Buttdown %d %x %x %x %x %x\n",iMessage, wParam, lParam,
// Platform::IsKeyDown(VK_SHIFT),
// Platform::IsKeyDown(VK_CONTROL),
// Platform::IsKeyDown(VK_MENU));
ButtonDown(Point::FromLong(lParam), ::GetMessageTime(),
(wParam & MK_SHIFT) != 0,
(wParam & MK_CONTROL) != 0,
Platform::IsKeyDown(VK_MENU));
::SetFocus(MainHWND());
break;
case WM_MOUSEMOVE:
ButtonMove(Point::FromLong(lParam));
break;
case WM_LBUTTONUP:
ButtonUp(Point::FromLong(lParam),
::GetMessageTime(),
(wParam & MK_CONTROL) != 0);
break;
case WM_SETCURSOR:
if (LoWord(lParam) == HTCLIENT) {
if (inDragDrop) {
DisplayCursor(Window::cursorUp);
} else {
// Display regular (drag) cursor over selection
POINT pt;
::GetCursorPos(&pt);
::ScreenToClient(MainHWND(), &pt);
if (PointInSelMargin(Point(pt.x, pt.y))) {
DisplayCursor(Window::cursorReverseArrow);
} else if (PointInSelection(Point(pt.x, pt.y))) {
DisplayCursor(Window::cursorArrow);
} else if (PointIsHotspot(Point(pt.x, pt.y))) {
DisplayCursor(Window::cursorHand);
} else {
DisplayCursor(Window::cursorText);
}
}
return TRUE;
} else {
return ::DefWindowProc(MainHWND(), iMessage, wParam, lParam);
}
case WM_CHAR:
if (!iscntrl(wParam&0xff) || !lastKeyDownConsumed) {
if (IsUnicodeMode()) {
// For a wide character version of the window:
//char utfval[4];
//wchar_t wcs[2] = {wParam, 0};
//unsigned int len = UTF8Length(wcs, 1);
//UTF8FromUCS2(wcs, 1, utfval, len);
//AddCharUTF(utfval, len);
AddCharBytes(static_cast<char>(wParam & 0xff));
} else {
AddChar(static_cast<char>(wParam & 0xff));
}
}
return 1;
case WM_UNICHAR:
if (wParam == UNICODE_NOCHAR) {
return 1;
} else if (lastKeyDownConsumed) {
return 1;
} else {
if (IsUnicodeMode()) {
char utfval[4];
wchar_t wcs[2] = {wParam, 0};
unsigned int len = UTF8Length(wcs, 1);
UTF8FromUCS2(wcs, 1, utfval, len);
AddCharUTF(utfval, len);
return 1;
} else {
return 0;
}
}
case WM_SYSKEYDOWN:
case WM_KEYDOWN: {
//Platform::DebugPrintf("S keydown %d %x %x %x %x\n",iMessage, wParam, lParam, ::IsKeyDown(VK_SHIFT), ::IsKeyDown(VK_CONTROL));
lastKeyDownConsumed = false;
int ret = KeyDown(KeyTranslate(wParam),
Platform::IsKeyDown(VK_SHIFT),
Platform::IsKeyDown(VK_CONTROL),
Platform::IsKeyDown(VK_MENU),
&lastKeyDownConsumed);
if (!ret && !lastKeyDownConsumed) {
return ::DefWindowProc(MainHWND(), iMessage, wParam, lParam);
}
break;
}
case WM_IME_KEYDOWN:
return ::DefWindowProc(MainHWND(), iMessage, wParam, lParam);
case WM_KEYUP:
//Platform::DebugPrintf("S keyup %d %x %x\n",iMessage, wParam, lParam);
return ::DefWindowProc(MainHWND(), iMessage, wParam, lParam);
case WM_SETTINGCHANGE:
//Platform::DebugPrintf("Setting Changed\n");
InvalidateStyleData();
// Get Intellimouse scroll line parameters
GetIntelliMouseParameters();
break;
case WM_GETDLGCODE:
return DLGC_HASSETSEL | DLGC_WANTALLKEYS;
case WM_KILLFOCUS: {
HWND wOther = reinterpret_cast<HWND>(wParam);
HWND wThis = reinterpret_cast<HWND>(wMain.GetID());
HWND wCT = reinterpret_cast<HWND>(ct.wCallTip.GetID());
if (!wParam ||
!(::IsChild(wThis,wOther) || (wOther == wCT))) {
SetFocusState(false);
}
}
//RealizeWindowPalette(true);
break;
case WM_SETFOCUS:
SetFocusState(true);
RealizeWindowPalette(false);
break;
case WM_SYSCOLORCHANGE:
//Platform::DebugPrintf("Setting Changed\n");
InvalidateStyleData();
break;
case WM_PALETTECHANGED:
if (wParam != reinterpret_cast<uptr_t>(MainHWND())) {
//Platform::DebugPrintf("** Palette Changed\n");
RealizeWindowPalette(true);
}
break;
case WM_QUERYNEWPALETTE:
//Platform::DebugPrintf("** Query palette\n");
RealizeWindowPalette(false);
break;
case WM_IME_STARTCOMPOSITION: // dbcs
ImeStartComposition();
return ::DefWindowProc(MainHWND(), iMessage, wParam, lParam);
case WM_IME_ENDCOMPOSITION: // dbcs
ImeEndComposition();
return ::DefWindowProc(MainHWND(), iMessage, wParam, lParam);
case WM_IME_COMPOSITION:
return HandleComposition(wParam, lParam);
case WM_IME_CHAR: {
if (HIBYTE(wParam) == '\0')
AddChar(LOBYTE(wParam));
else
AddCharBytes(HIBYTE(wParam), LOBYTE(wParam));
return 0;
}
case WM_CONTEXTMENU:
#ifdef TOTAL_CONTROL
if (displayPopupMenu) {
Point pt = Point::FromLong(lParam);
if ((pt.x == -1) && (pt.y == -1)) {
// Caused by keyboard so display menu near caret
pt = LocationFromPosition(currentPos);
POINT spt = {pt.x, pt.y};
::ClientToScreen(MainHWND(), &spt);
pt = Point(spt.x, spt.y);
}
ContextMenu(pt);
return 0;
}
#endif
return ::DefWindowProc(MainHWND(), iMessage, wParam, lParam);
case WM_INPUTLANGCHANGE:
//::SetThreadLocale(LOWORD(lParam));
return ::DefWindowProc(MainHWND(), iMessage, wParam, lParam);
case WM_INPUTLANGCHANGEREQUEST:
return ::DefWindowProc(MainHWND(), iMessage, wParam, lParam);
case WM_ERASEBKGND:
return 1; // Avoid any background erasure as whole window painted.
case WM_CAPTURECHANGED:
capturedMouse = false;
return 0;
// These are not handled in Scintilla and its faster to dispatch them here.
// Also moves time out to here so profile doesn't count lots of empty message calls.
case WM_MOVE:
case WM_MOUSEACTIVATE:
case WM_NCHITTEST:
case WM_NCCALCSIZE:
case WM_NCPAINT:
case WM_NCMOUSEMOVE:
case WM_NCLBUTTONDOWN:
case WM_IME_SETCONTEXT:
case WM_IME_NOTIFY:
case WM_SYSCOMMAND:
case WM_WINDOWPOSCHANGING:
case WM_WINDOWPOSCHANGED:
return ::DefWindowProc(MainHWND(), iMessage, wParam, lParam);
case EM_LINEFROMCHAR:
if (static_cast<int>(wParam) < 0) {
wParam = SelectionStart();
}
return pdoc->LineFromPosition(wParam);
case EM_EXLINEFROMCHAR:
return pdoc->LineFromPosition(lParam);
case EM_GETSEL:
if (wParam) {
*reinterpret_cast<int *>(wParam) = SelectionStart();
}
if (lParam) {
*reinterpret_cast<int *>(lParam) = SelectionEnd();
}
return MAKELONG(SelectionStart(), SelectionEnd());
case EM_EXGETSEL: {
if (lParam == 0) {
return 0;
}
CharacterRange *pCR = reinterpret_cast<CharacterRange *>(lParam);
pCR->cpMin = SelectionStart();
pCR->cpMax = SelectionEnd();
}
break;
case EM_SETSEL: {
int nStart = static_cast<int>(wParam);
int nEnd = static_cast<int>(lParam);
if (nStart == 0 && nEnd == -1) {
nEnd = pdoc->Length();
}
if (nStart == -1) {
nStart = nEnd; // Remove selection
}
if (nStart > nEnd) {
SetSelection(nEnd, nStart);
} else {
SetSelection(nStart, nEnd);
}
EnsureCaretVisible();
}
break;
case EM_EXSETSEL: {
if (lParam == 0) {
return 0;
}
CharacterRange *pCR = reinterpret_cast<CharacterRange *>(lParam);
selType = selStream;
if (pCR->cpMax == 0 && pCR->cpMax == -1) {
SetSelection(pCR->cpMin, pdoc->Length());
} else {
SetSelection(pCR->cpMin, pCR->cpMax);
}
EnsureCaretVisible();
return pdoc->LineFromPosition(SelectionStart());
}
case SCI_GETDIRECTFUNCTION:
return reinterpret_cast<sptr_t>(DirectFunction);
case SCI_GETDIRECTPOINTER:
return reinterpret_cast<sptr_t>(this);
case SCI_GRABFOCUS:
::SetFocus(MainHWND());
break;
#ifdef SCI_LEXER
case SCI_LOADLEXERLIBRARY:
LexerManager::GetInstance()->Load(reinterpret_cast<const char*>(lParam));
break;
#endif
default:
return ScintillaBase::WndProc(iMessage, wParam, lParam);
}
return 0l;
}
sptr_t ScintillaWin::DefWndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
return ::DefWindowProc(MainHWND(), iMessage, wParam, lParam);
}
void ScintillaWin::SetTicking(bool on) {
if (timer.ticking != on) {
timer.ticking = on;
if (timer.ticking) {
timer.tickerID = reinterpret_cast<TickerID>(::SetTimer(MainHWND(), 1, timer.tickSize, NULL));
} else {
::KillTimer(MainHWND(), reinterpret_cast<uptr_t>(timer.tickerID));
timer.tickerID = 0;
}
}
timer.ticksToWait = caret.period;
}
void ScintillaWin::SetMouseCapture(bool on) {
if (mouseDownCaptures) {
if (on) {
::SetCapture(MainHWND());
} else {
::ReleaseCapture();
}
}
capturedMouse = on;
}
bool ScintillaWin::HaveMouseCapture() {
// Cannot just see if GetCapture is this window as the scroll bar also sets capture for the window
return capturedMouse;
//return capturedMouse && (::GetCapture() == MainHWND());
}
void ScintillaWin::ScrollText(int linesToMove) {
//Platform::DebugPrintf("ScintillaWin::ScrollText %d\n", linesToMove);
::ScrollWindow(MainHWND(), 0,
vs.lineHeight * linesToMove, 0, 0);
::UpdateWindow(MainHWND());
}
// Change the scroll position but avoid repaint if changing to same value
static void ChangeScrollPos(HWND w, int barType, int pos) {
SCROLLINFO sci = {
sizeof(sci),0,0,0,0,0,0
};
sci.fMask = SIF_POS;
::GetScrollInfo(w, barType, &sci);
if (sci.nPos != pos) {
sci.nPos = pos;
::SetScrollInfo(w, barType, &sci, TRUE);
}
}
void ScintillaWin::SetVerticalScrollPos() {
ChangeScrollPos(MainHWND(), SB_VERT, topLine);
}
void ScintillaWin::SetHorizontalScrollPos() {
ChangeScrollPos(MainHWND(), SB_HORZ, xOffset);
}
bool ScintillaWin::ModifyScrollBars(int nMax, int nPage) {
bool modified = false;
SCROLLINFO sci = {
sizeof(sci),0,0,0,0,0,0
};
sci.fMask = SIF_PAGE | SIF_RANGE;
::GetScrollInfo(MainHWND(), SB_VERT, &sci);
int vertEndPreferred = nMax;
if (!verticalScrollBarVisible)
vertEndPreferred = 0;
if ((sci.nMin != 0) ||
(sci.nMax != vertEndPreferred) ||
(sci.nPage != static_cast<unsigned int>(nPage)) ||
(sci.nPos != 0)) {
//Platform::DebugPrintf("Scroll info changed %d %d %d %d %d\n",
// sci.nMin, sci.nMax, sci.nPage, sci.nPos, sci.nTrackPos);
sci.fMask = SIF_PAGE | SIF_RANGE;
sci.nMin = 0;
sci.nMax = vertEndPreferred;
sci.nPage = nPage;
sci.nPos = 0;
sci.nTrackPos = 1;
::SetScrollInfo(MainHWND(), SB_VERT, &sci, TRUE);
modified = true;
}
PRectangle rcText = GetTextRectangle();
int horizEndPreferred = scrollWidth;
if (horizEndPreferred < 0)
horizEndPreferred = 0;
if (!horizontalScrollBarVisible || (wrapState != eWrapNone))
horizEndPreferred = 0;
unsigned int pageWidth = rcText.Width();
sci.fMask = SIF_PAGE | SIF_RANGE;
::GetScrollInfo(MainHWND(), SB_HORZ, &sci);
if ((sci.nMin != 0) ||
(sci.nMax != horizEndPreferred) ||
(sci.nPage != pageWidth) ||
(sci.nPos != 0)) {
sci.fMask = SIF_PAGE | SIF_RANGE;
sci.nMin = 0;
sci.nMax = horizEndPreferred;
sci.nPage = pageWidth;
sci.nPos = 0;
sci.nTrackPos = 1;
::SetScrollInfo(MainHWND(), SB_HORZ, &sci, TRUE);
modified = true;
if (scrollWidth < static_cast<int>(pageWidth)) {
HorizontalScrollTo(0);
}
}
return modified;
}
void ScintillaWin::NotifyChange() {
::SendMessage(::GetParent(MainHWND()), WM_COMMAND,
MAKELONG(GetCtrlID(), SCEN_CHANGE),
reinterpret_cast<LPARAM>(MainHWND()));
}
void ScintillaWin::NotifyFocus(bool focus) {
::SendMessage(::GetParent(MainHWND()), WM_COMMAND,
MAKELONG(GetCtrlID(), focus ? SCEN_SETFOCUS : SCEN_KILLFOCUS),
reinterpret_cast<LPARAM>(MainHWND()));
}
int ScintillaWin::GetCtrlID() {
return ::GetDlgCtrlID(reinterpret_cast<HWND>(wMain.GetID()));
}
void ScintillaWin::NotifyParent(SCNotification scn) {
scn.nmhdr.hwndFrom = MainHWND();
scn.nmhdr.idFrom = GetCtrlID();
::SendMessage(::GetParent(MainHWND()), WM_NOTIFY,
GetCtrlID(), reinterpret_cast<LPARAM>(&scn));
}
void ScintillaWin::NotifyDoubleClick(Point pt, bool shift) {
//Platform::DebugPrintf("ScintillaWin Double click 0\n");
ScintillaBase::NotifyDoubleClick(pt, shift);
// Send myself a WM_LBUTTONDBLCLK, so the container can handle it too.
::SendMessage(MainHWND(),
WM_LBUTTONDBLCLK,
shift ? MK_SHIFT : 0,
MAKELPARAM(pt.x, pt.y));
}
void ScintillaWin::Copy() {
//Platform::DebugPrintf("Copy\n");
if (currentPos != anchor) {
SelectionText selectedText;
CopySelectionRange(&selectedText);
CopyToClipboard(selectedText);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -