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

📄 scintillawin.cxx

📁 最强源代码编辑控件
💻 CXX
📖 第 1 页 / 共 5 页
字号:
	// Restore debug output state
	Platform::ShowAssertionPopUps(assertsPopup);

	//Platform::DebugPrintf("Paint took %g\n", et.Duration());
	return 0l;
}

sptr_t ScintillaWin::HandleComposition(uptr_t wParam, sptr_t lParam) {
#ifdef __DMC__
	// Digital Mars compiler does not include Imm library
	return 0;
#else
	if (lParam & GCS_RESULTSTR) {
		HIMC hIMC = ::ImmGetContext(MainHWND());
		if (hIMC) {
			const int maxLenInputIME = 200;
			wchar_t wcs[maxLenInputIME];
			LONG bytes = ::ImmGetCompositionStringW(hIMC,
				GCS_RESULTSTR, wcs, (maxLenInputIME-1)*2);
			int wides = bytes / 2;
			if (IsUnicodeMode()) {
				char utfval[maxLenInputIME * 3];
				unsigned int len = UTF8Length(wcs, wides);
				UTF8FromUCS2(wcs, wides, utfval, len);
				utfval[len] = '\0';
				AddCharUTF(utfval, len);
			} else {
				char dbcsval[maxLenInputIME * 2];
				int size = ::WideCharToMultiByte(InputCodePage(),
					0, wcs, wides, dbcsval, sizeof(dbcsval) - 1, 0, 0);
				for (int i=0; i<size; i++) {
					AddChar(dbcsval[i]);
				}
			}
			// Set new position after converted
			Point pos = LocationFromPosition(currentPos);
			COMPOSITIONFORM CompForm;
			CompForm.dwStyle = CFS_POINT;
			CompForm.ptCurrentPos.x = pos.x;
			CompForm.ptCurrentPos.y = pos.y;
			::ImmSetCompositionWindow(hIMC, &CompForm);
			::ImmReleaseContext(MainHWND(), hIMC);
		}
		return 0;
	}
	return ::DefWindowProc(MainHWND(), WM_IME_COMPOSITION, wParam, lParam);
#endif
}

// Translate message IDs from WM_* and EM_* to SCI_* so can partly emulate Windows Edit control
static unsigned int SciMessageFromEM(unsigned int iMessage) {
	switch (iMessage) {
	case EM_CANPASTE: return SCI_CANPASTE;
	case EM_CANUNDO: return SCI_CANUNDO;
	case EM_EMPTYUNDOBUFFER: return SCI_EMPTYUNDOBUFFER;
	case EM_FINDTEXTEX: return SCI_FINDTEXT;
	case EM_FORMATRANGE: return SCI_FORMATRANGE;
	case EM_GETFIRSTVISIBLELINE: return SCI_GETFIRSTVISIBLELINE;
	case EM_GETLINECOUNT: return SCI_GETLINECOUNT;
	case EM_GETSELTEXT: return SCI_GETSELTEXT;
	case EM_GETTEXTRANGE: return SCI_GETTEXTRANGE;
	case EM_HIDESELECTION: return SCI_HIDESELECTION;
	case EM_LINEINDEX: return SCI_POSITIONFROMLINE;
	case EM_LINESCROLL: return SCI_LINESCROLL;
	case EM_REPLACESEL: return SCI_REPLACESEL;
	case EM_SCROLLCARET: return SCI_SCROLLCARET;
	case EM_SETREADONLY: return SCI_SETREADONLY;
	case WM_CLEAR: return SCI_CLEAR;
	case WM_COPY: return SCI_COPY;
	case WM_CUT: return SCI_CUT;
	case WM_GETTEXT: return SCI_GETTEXT;
	case WM_SETTEXT: return SCI_SETTEXT;
	case WM_GETTEXTLENGTH: return SCI_GETTEXTLENGTH;
	case WM_PASTE: return SCI_PASTE;
	case WM_UNDO: return SCI_UNDO;
	}
	return iMessage;
}

sptr_t ScintillaWin::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
	//Platform::DebugPrintf("S M:%x WP:%x L:%x\n", iMessage, wParam, lParam);
	iMessage = SciMessageFromEM(iMessage);
	switch (iMessage) {

	case WM_CREATE:
		ctrlID = ::GetDlgCtrlID(reinterpret_cast<HWND>(wMain.GetID()));
		// Get Intellimouse scroll line parameters
		GetIntelliMouseParameters();
		::RegisterDragDrop(MainHWND(), reinterpret_cast<IDropTarget *>(&dt));
		break;

	case WM_COMMAND:
#ifdef TOTAL_CONTROL
		Command(LoWord(wParam));
#endif
		break;

	case WM_PAINT:
		return WndPaint(wParam);

	case WM_PRINTCLIENT: {
			HDC hdc = reinterpret_cast<HDC>(wParam);
			if (!IsCompatibleDC(hdc)) {
				return ::DefWindowProc(MainHWND(), iMessage, wParam, lParam);
			}
			FullPaintDC(hdc);
		}
		break;

	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:
		if (wParam == standardTimerID && timer.ticking) {
			Tick();
		} else if (wParam == idleTimerID && idler.state) {
			SendMessage(MainHWND(), SC_WIN_IDLE, 0, 1);
		} else {
			return 1;
		}
		break;

	case SC_WIN_IDLE:
		// wParam=dwTickCountInitial, or 0 to initialize.  lParam=bSkipUserInputTest
		if (idler.state) {
			if (lParam || (WAIT_TIMEOUT==MsgWaitForMultipleObjects(0,0,0,0, QS_INPUT|QS_HOTKEY))) {
				if (Idle()) {
					// User input was given priority above, but all events do get a turn.  Other
					// messages, notifications, etc. will get interleaved with the idle messages.

					// However, some things like WM_PAINT are a lower priority, and will not fire
					// when there's a message posted.  So, several times a second, we stop and let
					// the low priority events have a turn (after which the timer will fire again).

					DWORD dwCurrent = GetTickCount();
					DWORD dwStart = wParam ? wParam : dwCurrent;

					if (dwCurrent >= dwStart && dwCurrent > 200 && dwCurrent - 200 < dwStart)
						PostMessage(MainHWND(), SC_WIN_IDLE, dwStart, 0);
				} else {
					SetIdle(false);
				}
			}
		}
		break;

	case WM_GETMINMAXINFO:
		return ::DefWindowProc(MainHWND(), iMessage, wParam, lParam);

	case WM_LBUTTONDOWN: {
#ifndef __DMC__
		// Digital Mars compiler does not include Imm library
		// For IME, set the composition string as the result string.
		HIMC hIMC = ::ImmGetContext(MainHWND());
		::ImmNotifyIME(hIMC, NI_COMPOSITIONSTR, CPS_COMPLETE, 0);
		::ImmReleaseContext(MainHWND(), hIMC);
#endif
		//
		//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)) && !SelectionEmpty()) {
					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('\0', LOBYTE(wParam));
			} else {
				AddChar(LOBYTE(wParam));
			}
		}
		return 0;

	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 = MainHWND();
			HWND wCT = reinterpret_cast<HWND>(ct.wCallTip.GetID());
			if (!wParam ||
				!(::IsChild(wThis,wOther) || (wOther == wCT))) {
				SetFocusState(false);
				DestroySystemCaret();
			}
		}
		//RealizeWindowPalette(true);
		break;

	case WM_SETFOCUS:
		SetFocusState(true);
		RealizeWindowPalette(false);
		DestroySystemCaret();
		CreateSystemCaret();
		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: {
			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) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -