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

📄 scintillawin.cxx

📁 最强源代码编辑控件
💻 CXX
📖 第 1 页 / 共 5 页
字号:
			ansiText.SetClip(CF_TEXT);
		}
	}

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

	::CloseClipboard();
}

void ScintillaWin::ScrollMessage(WPARAM wParam) {
	//DWORD dwStart = timeGetTime();
	//Platform::DebugPrintf("Scroll %x %d\n", wParam, lParam);

	SCROLLINFO sci;
	memset(&sci, 0, sizeof(sci));
	sci.cbSize = sizeof(sci);
	sci.fMask = SIF_ALL;

	GetScrollInfo(SB_VERT, &sci);

	//Platform::DebugPrintf("ScrollInfo %d mask=%x min=%d max=%d page=%d pos=%d track=%d\n", b,sci.fMask,
	//sci.nMin, sci.nMax, sci.nPage, sci.nPos, sci.nTrackPos);

	int topLineNew = topLine;
	switch (LoWord(wParam)) {
	case SB_LINEUP:
		topLineNew -= 1;
		break;
	case SB_LINEDOWN:
		topLineNew += 1;
		break;
	case SB_PAGEUP:
		topLineNew -= LinesToScroll(); break;
	case SB_PAGEDOWN: topLineNew += LinesToScroll(); break;
	case SB_TOP: topLineNew = 0; break;
	case SB_BOTTOM: topLineNew = MaxScrollPos(); break;
	case SB_THUMBPOSITION: topLineNew = sci.nTrackPos; break;
	case SB_THUMBTRACK: topLineNew = sci.nTrackPos; break;
	}
	ScrollTo(topLineNew);
}

void ScintillaWin::HorizontalScrollMessage(WPARAM wParam) {
	int xPos = xOffset;
	PRectangle rcText = GetTextRectangle();
	int pageWidth = rcText.Width() * 2 / 3;
	switch (LoWord(wParam)) {
	case SB_LINEUP:
		xPos -= 20;
		break;
	case SB_LINEDOWN:	// May move past the logical end
		xPos += 20;
		break;
	case SB_PAGEUP:
		xPos -= pageWidth;
		break;
	case SB_PAGEDOWN:
		xPos += pageWidth;
		if (xPos > scrollWidth - rcText.Width()) {	// Hit the end exactly
			xPos = scrollWidth - rcText.Width();
		}
		break;
	case SB_TOP:
		xPos = 0;
		break;
	case SB_BOTTOM:
		xPos = scrollWidth;
		break;
	case SB_THUMBPOSITION:
		xPos = HiWord(wParam);
		break;
	case SB_THUMBTRACK:
		xPos = HiWord(wParam);
		break;
	}
	HorizontalScrollTo(xPos);
}

void ScintillaWin::RealizeWindowPalette(bool inBackGround) {
	RefreshStyleData();
	HDC hdc = ::GetDC(MainHWND());
	// Select a stock font to prevent warnings from BoundsChecker
	::SelectObject(hdc, GetStockFont(DEFAULT_GUI_FONT));
	AutoSurface surfaceWindow(hdc, this);
	if (surfaceWindow) {
		int changes = surfaceWindow->SetPalette(&palette, inBackGround);
		if (changes > 0)
			Redraw();
		surfaceWindow->Release();
	}
	::ReleaseDC(MainHWND(), hdc);
}

/**
 * Redraw all of text area.
 * This paint will not be abandoned.
 */
void ScintillaWin::FullPaint() {
	HDC hdc = ::GetDC(MainHWND());
	FullPaintDC(hdc);
	::ReleaseDC(MainHWND(), hdc);
}

/**
 * Redraw all of text area on the specified DC.
 * This paint will not be abandoned.
 */
void ScintillaWin::FullPaintDC(HDC hdc) {
	paintState = painting;
	rcPaint = GetClientRectangle();
	paintingAllText = true;
	AutoSurface surfaceWindow(hdc, this);
	if (surfaceWindow) {
		Paint(surfaceWindow, rcPaint);
		surfaceWindow->Release();
	}
	paintState = notPainting;
}

static bool CompareDevCap(HDC hdc, HDC hOtherDC, int nIndex) {
	return ::GetDeviceCaps(hdc, nIndex) == ::GetDeviceCaps(hOtherDC, nIndex);
}

bool ScintillaWin::IsCompatibleDC(HDC hOtherDC) {
	HDC hdc = ::GetDC(MainHWND());
	bool isCompatible =
		CompareDevCap(hdc, hOtherDC, TECHNOLOGY) &&
		CompareDevCap(hdc, hOtherDC, LOGPIXELSY) &&
		CompareDevCap(hdc, hOtherDC, LOGPIXELSX) &&
		CompareDevCap(hdc, hOtherDC, BITSPIXEL) &&
		CompareDevCap(hdc, hOtherDC, PLANES);
	::ReleaseDC(MainHWND(), hdc);
	return isCompatible;
}

/// Implement IUnknown
STDMETHODIMP ScintillaWin::QueryInterface(REFIID riid, PVOID *ppv) {
	*ppv = NULL;
	if (riid == IID_IUnknown)
		*ppv = reinterpret_cast<IDropTarget *>(&dt);
	if (riid == IID_IDropSource)
		*ppv = reinterpret_cast<IDropSource *>(&ds);
	if (riid == IID_IDropTarget)
		*ppv = reinterpret_cast<IDropTarget *>(&dt);
	if (riid == IID_IDataObject)
		*ppv = reinterpret_cast<IDataObject *>(&dob);
	if (!*ppv)
		return E_NOINTERFACE;
	return S_OK;
}

STDMETHODIMP_(ULONG) ScintillaWin::AddRef() {
	return 1;
}

STDMETHODIMP_(ULONG) ScintillaWin::Release() {
	return 1;
}

/// Implement IDropTarget
STDMETHODIMP ScintillaWin::DragEnter(LPDATAOBJECT pIDataSource, DWORD grfKeyState,
                                     POINTL, PDWORD pdwEffect) {
	if (pIDataSource == NULL)
		return E_POINTER;
	if (IsUnicodeMode()) {
		FORMATETC fmtu = {CF_UNICODETEXT, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
		HRESULT hrHasUText = pIDataSource->QueryGetData(&fmtu);
		hasOKText = (hrHasUText == S_OK);
	}
	if (!hasOKText) {
		FORMATETC fmte = {CF_TEXT, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
		HRESULT hrHasText = pIDataSource->QueryGetData(&fmte);
		hasOKText = (hrHasText == S_OK);
	}
	if (!hasOKText) {
		*pdwEffect = DROPEFFECT_NONE;
		return S_OK;
	}

	if (inDragDrop)	// Internal defaults to move
		*pdwEffect = DROPEFFECT_MOVE;
	else
		*pdwEffect = DROPEFFECT_COPY;
	if (grfKeyState & MK_ALT)
		*pdwEffect = DROPEFFECT_MOVE;
	if (grfKeyState & MK_CONTROL)
		*pdwEffect = DROPEFFECT_COPY;
	return S_OK;
}

STDMETHODIMP ScintillaWin::DragOver(DWORD grfKeyState, POINTL pt, PDWORD pdwEffect) {
	if (!hasOKText || pdoc->IsReadOnly()) {
		*pdwEffect = DROPEFFECT_NONE;
		return S_OK;
	}

	// These are the Wordpad semantics.
	if (inDragDrop)	// Internal defaults to move
		*pdwEffect = DROPEFFECT_MOVE;
	else
		*pdwEffect = DROPEFFECT_COPY;
	if (grfKeyState & MK_ALT)
		*pdwEffect = DROPEFFECT_MOVE;
	if (grfKeyState & MK_CONTROL)
		*pdwEffect = DROPEFFECT_COPY;
	// Update the cursor.
	POINT rpt = {pt.x, pt.y};
	::ScreenToClient(MainHWND(), &rpt);
	SetDragPosition(PositionFromLocation(Point(rpt.x, rpt.y)));

	return S_OK;
}

STDMETHODIMP ScintillaWin::DragLeave() {
	SetDragPosition(invalidPosition);
	return S_OK;
}

STDMETHODIMP ScintillaWin::Drop(LPDATAOBJECT pIDataSource, DWORD grfKeyState,
                                POINTL pt, PDWORD pdwEffect) {
	if (inDragDrop)	// Internal defaults to move
		*pdwEffect = DROPEFFECT_MOVE;
	else
		*pdwEffect = DROPEFFECT_COPY;
	if (grfKeyState & MK_ALT)
		*pdwEffect = DROPEFFECT_MOVE;
	if (grfKeyState & MK_CONTROL)
		*pdwEffect = DROPEFFECT_COPY;

	if (pIDataSource == NULL)
		return E_POINTER;

	SetDragPosition(invalidPosition);

	STGMEDIUM medium={0,{0},0};
	HRESULT hr = S_OK;

	char *data = 0;
	bool dataAllocated = false;

	if (IsUnicodeMode()) {
		FORMATETC fmtu = {CF_UNICODETEXT, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
		hr = pIDataSource->GetData(&fmtu, &medium);
		if (SUCCEEDED(hr) && medium.hGlobal) {
			wchar_t *udata = static_cast<wchar_t *>(::GlobalLock(medium.hGlobal));
			int tlen = ::GlobalSize(medium.hGlobal);
			// Convert UCS-2 to UTF-8
			int dataLen = UTF8Length(udata, tlen/2);
			data = new char[dataLen+1];
			if (data) {
				UTF8FromUCS2(udata, tlen/2, data, dataLen);
				dataAllocated = true;
			}
		}
	}

	if (!data) {
		FORMATETC fmte = {CF_TEXT, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
		hr = pIDataSource->GetData(&fmte, &medium);
		if (SUCCEEDED(hr) && medium.hGlobal) {
			data = static_cast<char *>(::GlobalLock(medium.hGlobal));
		}
	}

	if (!data) {
		//Platform::DebugPrintf("Bad data format: 0x%x\n", hres);
		return hr;
	}

	FORMATETC fmtr = {cfColumnSelect, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
	HRESULT hrRectangular = pIDataSource->QueryGetData(&fmtr);

	POINT rpt = {pt.x, pt.y};
	::ScreenToClient(MainHWND(), &rpt);
	int movePos = PositionFromLocation(Point(rpt.x, rpt.y));

	DropAt(movePos, data, *pdwEffect == DROPEFFECT_MOVE, hrRectangular == S_OK);

	::GlobalUnlock(medium.hGlobal);

	// Free data
	if (medium.pUnkForRelease != NULL)
		medium.pUnkForRelease->Release();
	else
		::GlobalFree(medium.hGlobal);

	if (dataAllocated)
		delete []data;

	return S_OK;
}

/// Implement important part of IDataObject
STDMETHODIMP ScintillaWin::GetData(FORMATETC *pFEIn, STGMEDIUM *pSTM) {
	bool formatOK = (pFEIn->cfFormat == CF_TEXT) ||
		((pFEIn->cfFormat == CF_UNICODETEXT) && IsUnicodeMode());
	if (!formatOK ||
	    pFEIn->ptd != 0 ||
	    (pFEIn->dwAspect & DVASPECT_CONTENT) == 0 ||
	    pFEIn->lindex != -1 ||
	    (pFEIn->tymed & TYMED_HGLOBAL) == 0
	) {
		//Platform::DebugPrintf("DOB GetData No %d %x %x fmt=%x\n", lenDrag, pFEIn, pSTM, pFEIn->cfFormat);
		return DATA_E_FORMATETC;
	}
	pSTM->tymed = TYMED_HGLOBAL;
	//Platform::DebugPrintf("DOB GetData OK %d %x %x\n", lenDrag, pFEIn, pSTM);

	GlobalMemory text;
	if (pFEIn->cfFormat == CF_UNICODETEXT) {
		int uchars = UCS2Length(drag.s, drag.len);
		text.Allocate(2 * uchars);
		if (text) {
			UCS2FromUTF8(drag.s, drag.len, static_cast<wchar_t *>(text.ptr), uchars);
		}
	} else {
		text.Allocate(drag.len);
		if (text) {
			memcpy(static_cast<char *>(text.ptr), drag.s, drag.len);
		}
	}
	pSTM->hGlobal = text ? text.Unlock() : 0;
	pSTM->pUnkForRelease = 0;
	return S_OK;
}

bool ScintillaWin::Register(HINSTANCE hInstance_) {

	hInstance = hInstance_;
	bool result;
#if 0
	// Register the Scintilla class
	if (IsNT()) {
	//if (0) {
		// Register Scintilla as a wide character window
		WNDCLASSEXW wndclass;
		wndclass.cbSize = sizeof(wndclass);
		wndclass.style = CS_GLOBALCLASS | CS_HREDRAW | CS_VREDRAW;
		wndclass.lpfnWndProc = ::ScintillaWin::SWndProc;
		wndclass.cbClsExtra = 0;
		wndclass.cbWndExtra = sizeof(ScintillaWin *);
		wndclass.hInstance = hInstance;
		wndclass.hIcon = NULL;
		wndclass.hCursor = NULL;
		wndclass.hbrBackground = NULL;
		wndclass.lpszMenuName = NULL;
		wndclass.lpszClassName = L"Scintilla";
		wndclass.hIconSm = 0;
		result = ::RegisterClassExW(&wndclass);
	} else {
#endif
		// Register Scintilla as a normal character window
		WNDCLASSEX wndclass;
		wndclass.cbSize = sizeof(wndclass);
		wndclass.style = CS_GLOBALCLASS | CS_HREDRAW | CS_VREDRAW;
		wndclass.lpfnWndProc = ::ScintillaWin::SWndProc;
		wndclass.cbClsExtra = 0;
		wndclass.cbWndExtra = sizeof(ScintillaWin *);
		wndclass.hInstance = hInstance;
		wndclass.hIcon = NULL;
		wndclass.hCursor = NULL;
		wndclass.hbrBackground = NULL;
		wndclass.lpszMenuName = NULL;
		wndclass.lpszClassName = scintillaClassName;
		wndclass.hIconSm = 0;
		result = ::RegisterClassEx(&wndclass) != 0;
	//}

	if (result) {
		// Register the CallTip class
		WNDCLASSEX wndclassc;
		wndclassc.cbSize = sizeof(wndclassc);
		wndclassc.style = CS_GLOBALCLASS | CS_HREDRAW | CS_VREDRAW;
		wndclassc.cbClsExtra = 0;
		wndclassc.cbWndExtra = sizeof(ScintillaWin *);
		wndclassc.hInstance = hInstance;
		wndclassc.hIcon = NULL;
		wndclassc.hbrBackground = NULL;
		wndclassc.lpszMenuName = NULL;
		wndclassc.lpfnWndProc = ScintillaWin::CTWndProc;
		wndclassc.hCursor = ::LoadCursor(NULL, IDC_ARROW);
		wndclassc.lpszClassName = callClassName;
		wndclassc.hIconSm = 0;

		result = ::RegisterClassEx(&wndclassc) != 0;
	}

	return result;
}

bool ScintillaWin::Unregister() {
	bool result = ::UnregisterClass(scintillaClassName, hInstance) != 0;
	if (::UnregisterClass(callClassName, hInstance) == 0)
		result = false;
	return result;
}

bool ScintillaWin::HasCaretSizeChanged() {
	if (
		( (0 != vs.caretWidth) && (sysCaretWidth != vs.caretWidth) )
		|| (0 != vs.lineHeight) && (sysCaretHeight != vs.lineHeight)
		) {
		return true;
	}
	return false;
}

BOOL ScintillaWin::CreateSystemCaret() {
	sysCaretWidth = vs.caretWidth;
	if (0 == sysCaretWidth) {
		sysCaretWidth = 1;
	}
	sysCaretHeight = vs.lineHeight;
	int bitmapSize = (((sysCaretWidth + 15) & ~15) >> 3) *
		sysCaretHeight;
	char *bits = new char[bitmapSize];
	memset(bits, 0, bitmapSize);
	sysCaretBitmap = ::CreateBitmap(sysCaretWidth, sysCaretHeight, 1,
		1, reinterpret_cast<BYTE *>(bits));
	delete []bits;
	BOOL retval = ::CreateCaret(
		MainHWND(), sysCaretBitmap,
		sysCaretWidth, sysCaretHeight);
	::ShowCaret(MainHWND());
	return retval;
}

BOOL ScintillaWin::DestroySystemCaret() {
	::HideCaret(MainHWND());
	BOOL retval = ::DestroyCaret();
	if (sysCaretBitmap) {
		::DeleteObject(sysCaretBitmap);
		sysCaretBitmap = 0;
	}
	return retval;
}

// Take care of 32/64 bit pointers
#ifdef GetWindowLongPtr
static void *PointerFromWindow(HWND hWnd) {
	return reinterpret_cast<void *>(::GetWindowLongPtr(hWnd, 0));
}
static void SetWindowPointer(HWND hWnd, void *ptr) {
	::SetWindowLongPtr(hWnd, 0, reinterpret_cast<LONG_PTR>(ptr));
}
#else
static void *PointerFromWindow(HWND hWnd) {
	return reinterpret_cast<void *>(::GetWindowLong(hWnd, 0));
}
static void SetWindowPointer(HWND hWnd, void *ptr) {
	::SetWindowLong(hWnd, 0, reinterpret_cast<LONG>(ptr));
}
#endif

sptr_t PASCAL ScintillaWin::CTWndProc(
 

⌨️ 快捷键说明

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