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

📄 scintillawin.cxx

📁 一个可以提供语法高亮显示的编辑器
💻 CXX
📖 第 1 页 / 共 4 页
字号:
}

bool ScintillaWin::CanPaste() {
	if (!Editor::CanPaste())
		return false;
	if (::IsClipboardFormatAvailable(CF_TEXT))
		return true;
	if (IsUnicodeMode())
		return ::IsClipboardFormatAvailable(CF_UNICODETEXT) != 0;
	return false;
}

void ScintillaWin::Paste() {
	pdoc->BeginUndoAction();
	int selStart = SelectionStart();
	ClearSelection();
	::OpenClipboard(MainHWND());
	bool isRectangular = ::IsClipboardFormatAvailable(cfColumnSelect) != 0;
	HGLOBAL hmemUSelection = 0;
	if (IsUnicodeMode()) {
		hmemUSelection = ::GetClipboardData(CF_UNICODETEXT);
		if (hmemUSelection) {
			wchar_t *uptr = static_cast<wchar_t *>(::GlobalLock(hmemUSelection));
			if (uptr) {
				unsigned int bytes = ::GlobalSize(hmemUSelection);
				unsigned int len = UTF8Length(uptr, bytes/2);
				char *putf = new char[len+1];
				if (putf) {
					UTF8FromUCS2(uptr, bytes/2, putf, len);
					if (isRectangular) {
						PasteRectangular(selStart, putf, len);
					} else {
						if (pdoc->InsertString(currentPos, putf, len)) {
							SetEmptySelection(currentPos + len);
						}
					}
					delete []putf;
				}
			}
			::GlobalUnlock(hmemUSelection);
		}
	}
	if (!hmemUSelection) {
		HGLOBAL hmemSelection = ::GetClipboardData(CF_TEXT);
		if (hmemSelection) {
			char *ptr = static_cast<char *>(
				::GlobalLock(hmemSelection));
			if (ptr) {
				unsigned int bytes = ::GlobalSize(hmemSelection);
				unsigned int len = bytes;
				for (unsigned int i = 0; i < bytes; i++) {
					if ((len == bytes) && (0 == ptr[i]))
						len = i;
				}
				if (isRectangular) {
					PasteRectangular(selStart, ptr, len);
				} else {
					pdoc->InsertString(currentPos, ptr, len);
					SetEmptySelection(currentPos + len);
				}
			}
			::GlobalUnlock(hmemSelection);
		}
	}
	::CloseClipboard();
	pdoc->EndUndoAction();
	NotifyChange();
	Redraw();
}

void ScintillaWin::CreateCallTipWindow(PRectangle) {
#ifdef TOTAL_CONTROL
	if (!ct.wCallTip.Created()) {
		ct.wCallTip = ::CreateWindow(callClassName, "ACallTip",
					     WS_POPUP, 100, 100, 150, 20,
					     MainHWND(), 0,
					     GetWindowInstance(MainHWND()),
					     this);
		ct.wDraw = ct.wCallTip;
	}
#endif
}

void ScintillaWin::AddToPopUp(const char *label, int cmd, bool enabled) {
#ifdef TOTAL_CONTROL
	HMENU hmenuPopup = reinterpret_cast<HMENU>(popup.GetID());
	if (!label[0])
		::AppendMenu(hmenuPopup, MF_SEPARATOR, 0, "");
	else if (enabled)
		::AppendMenu(hmenuPopup, MF_STRING, cmd, label);
	else
		::AppendMenu(hmenuPopup, MF_STRING | MF_DISABLED | MF_GRAYED, cmd, label);
#endif
}

void ScintillaWin::ClaimSelection() {
	// Windows does not have a primary selection
}

#ifdef SCI_LEXER

/*

  Initial Windows-Only implementation of the external lexer
  system in ScintillaWin class. Intention is to create a LexerModule
  subclass (?) to have lex and fold methods which will call out to their
  relevant DLLs...

*/

void ScintillaWin::SetLexer(uptr_t wParam) {
	lexLanguage = wParam;
	lexCurrent = LexerModule::Find(lexLanguage);
	if (!lexCurrent)
		lexCurrent = LexerModule::Find(SCLEX_NULL);
}

void ScintillaWin::SetLexerLanguage(const char *languageName) {
	lexLanguage = SCLEX_CONTAINER;
	lexCurrent = LexerModule::Find(languageName);
	if (!lexCurrent)
		lexCurrent = LexerModule::Find(SCLEX_NULL);
	if (lexCurrent)
		lexLanguage = lexCurrent->GetLanguage();
}

#endif

/// Implement IUnknown

STDMETHODIMP_(ULONG)FormatEnumerator_AddRef(FormatEnumerator *fe);
STDMETHODIMP FormatEnumerator_QueryInterface(FormatEnumerator *fe, REFIID riid, PVOID *ppv) {
	//Platform::DebugPrintf("EFE QI");
	*ppv = NULL;
	if (riid == IID_IUnknown)
		*ppv = reinterpret_cast<IEnumFORMATETC *>(fe);
	if (riid == IID_IEnumFORMATETC)
		*ppv = reinterpret_cast<IEnumFORMATETC *>(fe);
	if (!*ppv)
		return E_NOINTERFACE;
	FormatEnumerator_AddRef(fe);
	return S_OK;
}
STDMETHODIMP_(ULONG)FormatEnumerator_AddRef(FormatEnumerator *fe) {
	return ++fe->ref;
}
STDMETHODIMP_(ULONG)FormatEnumerator_Release(FormatEnumerator *fe) {
	fe->ref--;
	if (fe->ref > 0)
		return fe->ref;
	delete fe;
	return 0;
}
/// Implement IEnumFORMATETC
STDMETHODIMP FormatEnumerator_Next(FormatEnumerator *fe, ULONG celt, FORMATETC *rgelt, ULONG *pceltFetched) {
	//Platform::DebugPrintf("EFE Next %d %d", fe->pos, celt);
	if (rgelt == NULL) return E_POINTER;
	// We only support one format, so this is simple.
	unsigned int putPos = 0;
	while ((fe->pos < fe->formatsLen) && (putPos < celt)) {
		rgelt->cfFormat = fe->formats[fe->pos];
		rgelt->ptd = 0;
		rgelt->dwAspect = DVASPECT_CONTENT;
		rgelt->lindex = -1;
		rgelt->tymed = TYMED_HGLOBAL;
		fe->pos++;
		putPos++;
	}
	if (pceltFetched)
		*pceltFetched = putPos;
	return putPos ? S_OK : S_FALSE;
}
STDMETHODIMP FormatEnumerator_Skip(FormatEnumerator *fe, ULONG celt) {
	fe->pos += celt;
	return S_OK;
}
STDMETHODIMP FormatEnumerator_Reset(FormatEnumerator *fe) {
	fe->pos = 0;
	return S_OK;
}
STDMETHODIMP FormatEnumerator_Clone(FormatEnumerator *fe, IEnumFORMATETC **ppenum) {
	FormatEnumerator *pfe = new FormatEnumerator(fe->pos, fe->formats, fe->formatsLen);
	return FormatEnumerator_QueryInterface(pfe, IID_IEnumFORMATETC,
	                                       reinterpret_cast<void **>(ppenum));
}

static void *vtFormatEnumerator[] = {
	(void *)(FormatEnumerator_QueryInterface),
	(void *)(FormatEnumerator_AddRef),
	(void *)(FormatEnumerator_Release),
	(void *)(FormatEnumerator_Next),
	(void *)(FormatEnumerator_Skip),
	(void *)(FormatEnumerator_Reset),
	(void *)(FormatEnumerator_Clone)
};

FormatEnumerator::FormatEnumerator(int pos_, CLIPFORMAT formats_[], int formatsLen_) {
	vtbl = vtFormatEnumerator;
	ref = 0;   // First QI adds first reference...
	pos = pos_;
	formatsLen = formatsLen_;
	for (int i=0;i<formatsLen;i++)
		formats[i] = formats_[i];
}

/// Implement IUnknown
STDMETHODIMP DropSource_QueryInterface(DropSource *ds, REFIID riid, PVOID *ppv) {
	return ds->sci->QueryInterface(riid, ppv);
}
STDMETHODIMP_(ULONG)DropSource_AddRef(DropSource *ds) {
	return ds->sci->AddRef();
}
STDMETHODIMP_(ULONG)DropSource_Release(DropSource *ds) {
	return ds->sci->Release();
}

/// Implement IDropSource
STDMETHODIMP DropSource_QueryContinueDrag(DropSource *, BOOL fEsc, DWORD grfKeyState) {
	if (fEsc)
		return DRAGDROP_S_CANCEL;
	if (!(grfKeyState & MK_LBUTTON))
		return DRAGDROP_S_DROP;
	return S_OK;
}

STDMETHODIMP DropSource_GiveFeedback(DropSource *, DWORD) {
	return DRAGDROP_S_USEDEFAULTCURSORS;
}

static void *vtDropSource[] = {
	(void *)(DropSource_QueryInterface),
	(void *)(DropSource_AddRef),
	(void *)(DropSource_Release),
	(void *)(DropSource_QueryContinueDrag),
	(void *)(DropSource_GiveFeedback)
};

DropSource::DropSource() {
	vtbl = vtDropSource;
	sci = 0;
}

/// Implement IUnkown
STDMETHODIMP DataObject_QueryInterface(DataObject *pd, REFIID riid, PVOID *ppv) {
	//Platform::DebugPrintf("DO QI %x\n", pd);
	return pd->sci->QueryInterface(riid, ppv);
}
STDMETHODIMP_(ULONG)DataObject_AddRef(DataObject *pd) {
	return pd->sci->AddRef();
}
STDMETHODIMP_(ULONG)DataObject_Release(DataObject *pd) {
	return pd->sci->Release();
}
/// Implement IDataObject
STDMETHODIMP DataObject_GetData(DataObject *pd, FORMATETC *pFEIn, STGMEDIUM *pSTM) {
	return pd->sci->GetData(pFEIn, pSTM);
}

STDMETHODIMP DataObject_GetDataHere(DataObject *, FORMATETC *, STGMEDIUM *) {
	//Platform::DebugPrintf("DOB GetDataHere\n");
	return E_NOTIMPL;
}

STDMETHODIMP DataObject_QueryGetData(DataObject *pd, FORMATETC *pFE) {
	if (pd->sci->DragIsRectangularOK(pFE->cfFormat) &&
	    pFE->ptd == 0 &&
	    (pFE->dwAspect & DVASPECT_CONTENT) != 0 &&
	    pFE->lindex == -1 &&
	    (pFE->tymed & TYMED_HGLOBAL) != 0
	) {
		return S_OK;
	}

	bool formatOK = (pFE->cfFormat == CF_TEXT) ||
		((pFE->cfFormat == CF_UNICODETEXT) && pd->sci->IsUnicodeMode()) ||
		(pFE->cfFormat == CF_HDROP);
	if (!formatOK ||
	    pFE->ptd != 0 ||
	    (pFE->dwAspect & DVASPECT_CONTENT) == 0 ||
	    pFE->lindex != -1 ||
	    (pFE->tymed & TYMED_HGLOBAL) == 0
	) {
		//Platform::DebugPrintf("DOB QueryGetData No %x\n",pFE->cfFormat);
		//return DATA_E_FORMATETC;
		return S_FALSE;
	}
	//Platform::DebugPrintf("DOB QueryGetData OK %x\n",pFE->cfFormat);
	return S_OK;
}

STDMETHODIMP DataObject_GetCanonicalFormatEtc(DataObject *pd, FORMATETC *, FORMATETC *pFEOut) {
	//Platform::DebugPrintf("DOB GetCanon\n");
	if (pd->sci->IsUnicodeMode())
		pFEOut->cfFormat = CF_UNICODETEXT;
	else
		pFEOut->cfFormat = CF_TEXT;
	pFEOut->ptd = 0;
	pFEOut->dwAspect = DVASPECT_CONTENT;
	pFEOut->lindex = -1;
	pFEOut->tymed = TYMED_HGLOBAL;
	return S_OK;
}

STDMETHODIMP DataObject_SetData(DataObject *, FORMATETC *, STGMEDIUM *, BOOL) {
	//Platform::DebugPrintf("DOB SetData\n");
	return E_FAIL;
}

STDMETHODIMP DataObject_EnumFormatEtc(DataObject *pd, DWORD dwDirection, IEnumFORMATETC **ppEnum) {
	//Platform::DebugPrintf("DOB EnumFormatEtc %d\n", dwDirection);
	if (dwDirection != DATADIR_GET) {
		*ppEnum = 0;
		return E_FAIL;
	}
	FormatEnumerator *pfe;
	if (pd->sci->IsUnicodeMode()) {
		CLIPFORMAT formats[] = {CF_UNICODETEXT, CF_TEXT};
		pfe = new FormatEnumerator(0, formats, 2);
	} else {
		CLIPFORMAT formats[] = {CF_TEXT};
		pfe = new FormatEnumerator(0, formats, 1);
	}
	return FormatEnumerator_QueryInterface(pfe, IID_IEnumFORMATETC,
	                                       reinterpret_cast<void **>(ppEnum));
}

STDMETHODIMP DataObject_DAdvise(DataObject *, FORMATETC *, DWORD, IAdviseSink *, PDWORD) {
	//Platform::DebugPrintf("DOB DAdvise\n");
	return E_FAIL;
}

STDMETHODIMP DataObject_DUnadvise(DataObject *, DWORD) {
	//Platform::DebugPrintf("DOB DUnadvise\n");
	return E_FAIL;
}

STDMETHODIMP DataObject_EnumDAdvise(DataObject *, IEnumSTATDATA **) {
	//Platform::DebugPrintf("DOB EnumDAdvise\n");
	return E_FAIL;
}

static void *vtDataObject[] = {
	(void *)(DataObject_QueryInterface),
	(void *)(DataObject_AddRef),
	(void *)(DataObject_Release),
	(void *)(DataObject_GetData),
	(void *)(DataObject_GetDataHere),
	(void *)(DataObject_QueryGetData),
	(void *)(DataObject_GetCanonicalFormatEtc),
	(void *)(DataObject_SetData),
	(void *)(DataObject_EnumFormatEtc),
	(void *)(DataObject_DAdvise),
	(void *)(DataObject_DUnadvise),
	(void *)(DataObject_EnumDAdvise)
};

DataObject::DataObject() {
	vtbl = vtDataObject;
	sci = 0;
}

/// Implement IUnknown
STDMETHODIMP DropTarget_QueryInterface(DropTarget *dt, REFIID riid, PVOID *ppv) {
	//Platform::DebugPrintf("DT QI %x\n", dt);
	return dt->sci->QueryInterface(riid, ppv);
}
STDMETHODIMP_(ULONG)DropTarget_AddRef(DropTarget *dt) {
	return dt->sci->AddRef();
}
STDMETHODIMP_(ULONG)DropTarget_Release(DropTarget *dt) {
	return dt->sci->Release();
}

/// Implement IDropTarget by forwarding to Scintilla
STDMETHODIMP DropTarget_DragEnter(DropTarget *dt, LPDATAOBJECT pIDataSource, DWORD grfKeyState,
                                  POINTL pt, PDWORD pdwEffect) {
	return dt->sci->DragEnter(pIDataSource, grfKeyState, pt, pdwEffect);
}
STDMETHODIMP DropTarget_DragOver(DropTarget *dt, DWORD grfKeyState, POINTL pt, PDWORD pdwEffect) {
	return dt->sci->DragOver(grfKeyState, pt, pdwEffect);
}
STDMETHODIMP DropTarget_DragLeave(DropTarget *dt) {
	return dt->sci->DragLeave();
}
STDMETHODIMP DropTarget_Drop(DropTarget *dt, LPDATAOBJECT pIDataSource, DWORD grfKeyState,
                             POINTL pt, PDWORD pdwEffect) {
	return dt->sci->Drop(pIDataSource, grfKeyState, pt, pdwEffect);
}

static void *vtDropTarget[] = {
	(void *)(DropTarget_QueryInterface),
	(void *)(DropTarget_AddRef),
	(void *)(DropTarget_Release),
	(void *)(DropTarget_DragEnter),
	(void *)(DropTarget_DragOver),
	(void *)(DropTarget_DragLeave),
	(void *)(DropTarget_Drop)
};

DropTarget::DropTarget() {
	vtbl = vtDropTarget;
	sci = 0;
}

/**
 * DBCS: support Input Method Editor (IME).
 * Called when IME Window opened.
 */
void ScintillaWin::ImeStartComposition() {
#ifndef __DMC__
	// Digital Mars compiler does not include Imm library
	if (caret.active) {
		// Move IME Window to current caret position
		HIMC hIMC = ::ImmGetContext(MainHWND());
		Point pos = LocationFromPosition(currentPos);
		COMPOSITIONFORM CompForm;
		CompForm.dwStyle = CFS_POINT;
		CompForm.ptCurrentPos.x = pos.x;
		CompForm.ptCurrentPos.y = pos.y;

		::ImmSetCompositionWindow(hIMC, &CompForm);

		// Set font of IME window to same as surrounded text.
		if (stylesValid) {
			// Since the style creation code has been made platform independent,
			// The logfont for the IME is recreated here.
			int styleHere = (pdoc->StyleAt(currentPos)) & 31;
			LOGFONT lf = {0,0,0,0,0,0,0,0,0,0,0,0,0,""};
			int sizeZoomed = vs.styles[styleHere].size + vs.zoomLevel;
			if (sizeZoomed <= 2)	// Hangs if sizeZoomed <= 1
				sizeZoomed = 2;
			AutoSurface surface(this);
			int deviceHeight = sizeZoomed;
			if (surface) {
				deviceHeight = (sizeZoomed * surface->LogPixelsY()) / 72;
			}
			// The negative is to allow for leading
			lf.lfHeight = -(abs(deviceHeight));
			lf.lfWeight = vs.styles[styleHere].bold ? FW_BOLD : FW_NORMAL;
			lf.lfItalic = static_cast<BYTE>(vs.styles[styleHere].italic ? 1 : 0);
			lf.lfCharSet = DEFAULT_CHARSET;
			lf.lfFaceName[0] = '\0';
			if (vs.styles[styleHere].fontName)
				strcpy(lf.lfFaceName, vs.styles[styleHere].fontName);

			::ImmSetCompositionFont(hIMC, &lf);
		}
		::ImmReleaseContext(MainHWND(), hIMC);
		// Caret is displayed in IME window. So, caret in Scintilla is useless.
		DropCaret();
	}
#endif
}

/** Called when IME Window closed. */
void ScintillaWin::ImeEndComposition() {
	ShowCaretAtCurrentPosition();
}

void ScintillaWin::AddCharBytes(char b0, char b1) {

	int inputCodePage = InputCodePage();
	if (inputCodePage && IsUnicodeMode()) {
		char utfval[4]="\0\0\0";
		char ansiChars[3];
		ansiChars[0] = b0;
		ansiChars[1] = b1;
		ansiChars[2] = '\0';
		wchar_t wcs[2];
		::MultiByteToWideChar(inputCodePage, 0, ansiChars, 2, wcs, 1);
		unsigned int len = UTF8Length(wcs, 1);
		UTF8FromUCS2(wcs, 1, utfval, len);
		utfval[len] = '\0';
		AddCharUTF(utfval,len);
	} else if (b1) {
		char dbcsChars[3];
		dbcsChars[0] = b0;
		dbcsChars[1] = b1;
		dbcsChars[2] = '\0';
		AddCharUTF(dbcsChars, 2, true);
	} else {
		AddChar(b0);
	}
}

void ScintillaWin::GetIntelliMouseParameters() {
	// This retrieves the number of lines per scroll as configured inthe Mouse Properties sheet in Control Panel
	::SystemParametersInfo(SPI_GETWHEELSCROLLLINES, 0, &linesPerScroll, 0);
}

void ScintillaWin::CopyToClipboard(const SelectionText &selectedText) {
	::OpenClipboard(MainHWND());
	::EmptyClipboard();

	HGLOBAL hand = ::GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT,
		selectedText.len + 1);
	if (hand) {
		char *ptr = static_cast<char *>(::GlobalLock(hand));
		memcpy(ptr, selectedText.s, selectedText.len);
		ptr[selectedText.len] = '\0';
		::GlobalUnlock(hand);
	}
	::SetClipboardData(CF_TEXT, hand);

	if (IsUnicodeMode()) {
		int uchars = UCS2Length(selectedText.s, selectedText.len);
		HGLOBAL uhand = ::GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT,
			2 * (uchars + 1));
		if (uhand) {
			wchar_t *uptr = static_cast<wchar_t *>(::GlobalLock(uhand));
			UCS2FromUTF8(selectedText.s, selectedText.len, uptr, uchars);
			uptr[uchars] = 0;
			::GlobalUnlock(uhand);
		}
		::SetClipboardData(CF_UNICODETEXT, uhand);
	}

	if (selectedText.rectangular) {
		::SetClipboardData(cfColumnSelect, 0);
	}

⌨️ 快捷键说明

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