⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 scintillawin.cxx

📁 一个可以提供语法高亮显示的编辑器
💻 CXX
📖 第 1 页 / 共 4 页
字号:
			}
		}
		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 + -