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

📄 scintillawin.cxx

📁 一个可以提供语法高亮显示的编辑器
💻 CXX
📖 第 1 页 / 共 4 页
字号:
	::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(MainHWND(), 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());
	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() {
	paintState = painting;
	rcPaint = GetClientRectangle();
	paintingAllText = true;
	HDC hdc = ::GetDC(MainHWND());
	AutoSurface surfaceWindow(hdc, this);
	if (surfaceWindow) {
		Paint(surfaceWindow, rcPaint);
		surfaceWindow->Release();
	}
	::ReleaseDC(MainHWND(), hdc);
	paintState = notPainting;
}

/// 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()) ||
		(pFEIn->cfFormat == CF_HDROP);
	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;
	if (pFEIn->cfFormat == CF_HDROP) {
		pSTM->hGlobal = 0;
		pSTM->pUnkForRelease = 0;
		return S_OK;
	}
	//Platform::DebugPrintf("DOB GetData OK %d %x %x\n", lenDrag, pFEIn, pSTM);

	HGLOBAL hand;
	if (pFEIn->cfFormat == CF_UNICODETEXT) {
		int uchars = UCS2Length(drag.s, drag.len);
		hand = ::GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, 2 * (uchars + 1));
		if (hand) {
			wchar_t *uptr = static_cast<wchar_t *>(::GlobalLock(hand));
			UCS2FromUTF8(drag.s, drag.len, uptr, uchars);
			uptr[uchars] = 0;
		}
	} else {
		hand = ::GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, drag.len + 1);
		if (hand) {
			char *ptr = static_cast<char *>(::GlobalLock(hand));
			for (int i = 0; i < drag.len; i++) {
				ptr[i] = drag.s[i];
			}
			ptr[drag.len] = '\0';
		}
	}
	::GlobalUnlock(hand);
	pSTM->hGlobal = hand;
	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;
}

// 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(
    HWND hWnd, UINT iMessage, WPARAM wParam, sptr_t lParam) {

	// Find C++ object associated with window.
	ScintillaWin *sciThis = reinterpret_cast<ScintillaWin *>(PointerFromWindow(hWnd));
	// ctp will be zero if WM_CREATE not seen yet
	if (sciThis == 0) {
		if (iMessage == WM_CREATE) {
			// Associate CallTip object with window
			CREATESTRUCT *pCreate = reinterpret_cast<CREATESTRUCT *>(lParam);
			SetWindowPointer(hWnd, pCreate->lpCreateParams);
			return 0;
		} else {
			return ::DefWindowProc(hWnd, iMessage, wParam, lParam);
		}
	} else {
		if (iMessage == WM_DESTROY) {
			::SetWindowLong(hWnd, 0, 0);
			return ::DefWindowProc(hWnd, iMessage, wParam, lParam);
		} else if (iMessage == WM_PAINT) {
			PAINTSTRUCT ps;
			::BeginPaint(hWnd, &ps);
			Surface *surfaceWindow = Surface::Allocate();
			if (surfaceWindow) {
				surfaceWindow->Init(ps.hdc, hWnd);
				surfaceWindow->SetUnicodeMode(SC_CP_UTF8 == sciThis->ct.codePage);
				surfaceWindow->SetDBCSMode(sciThis->ct.codePage);
				sciThis->ct.PaintCT(surfaceWindow);
				surfaceWindow->Release();
				delete surfaceWindow;
			}
			::EndPaint(hWnd, &ps);
			return 0;
		} else if ((iMessage == WM_NCLBUTTONDOWN) || (iMessage == WM_NCLBUTTONDBLCLK)) {
			POINT pt;
			pt.x = static_cast<short>(LOWORD(lParam));
			pt.y = static_cast<short>(HIWORD(lParam));
			ScreenToClient(hWnd, &pt);
			sciThis->ct.MouseClick(Point(pt.x, pt.y));
			sciThis->CallTipClick();
			return 0;
		} else if (iMessage == WM_LBUTTONDOWN) {
			// This does not fire due to the hit test code
			sciThis->ct.MouseClick(Point::FromLong(lParam));
			sciThis->CallTipClick();
			return 0;
		} else if (iMessage == WM_SETCURSOR) {
			::SetCursor(::LoadCursor(NULL,IDC_ARROW));
			return 0;
		} else if (iMessage == WM_NCHITTEST) {
			return HTCAPTION;
		} else {
			return ::DefWindowProc(hWnd, iMessage, wParam, lParam);
		}
	}
}

sptr_t ScintillaWin::DirectFunction(
    ScintillaWin *sci, UINT iMessage, uptr_t wParam, sptr_t lParam) {
	return sci->WndProc(iMessage, wParam, lParam);
}

extern "C" __declspec(dllexport) sptr_t __stdcall Scintilla_DirectFunction(
    ScintillaWin *sci, UINT iMessage, uptr_t wParam, sptr_t lParam) {
	return sci->WndProc(iMessage, wParam, lParam);
}

sptr_t PASCAL ScintillaWin::SWndProc(
    HWND hWnd, UINT iMessage, WPARAM wParam, sptr_t lParam) {
	//Platform::DebugPrintf("S W:%x M:%x WP:%x L:%x\n", hWnd, iMessage, wParam, lParam);

	// Find C++ object associated with window.
	ScintillaWin *sci = reinterpret_cast<ScintillaWin *>(PointerFromWindow(hWnd));
	// sci will be zero if WM_CREATE not seen yet
	if (sci == 0) {
		if (iMessage == WM_CREATE) {
			// Create C++ object associated with window
			sci = new ScintillaWin(hWnd);
			SetWindowPointer(hWnd, sci);
			return sci->WndProc(iMessage, wParam, lParam);
		} else {
			return ::DefWindowProc(hWnd, iMessage, wParam, lParam);
		}
	} else {
		if (iMessage == WM_DESTROY) {
			sci->Finalise();
			delete sci;
			::SetWindowLong(hWnd, 0, 0);
			return ::DefWindowProc(hWnd, iMessage, wParam, lParam);
		} else {
			return sci->WndProc(iMessage, wParam, lParam);
		}
	}
}

// This function is externally visible so it can be called from container when building statically.
// Must be called once only.
bool Scintilla_RegisterClasses(void *hInstance) {
	Platform_Initialise(hInstance);
	bool result = ScintillaWin::Register(reinterpret_cast<HINSTANCE>(hInstance));
#ifdef SCI_LEXER
	Scintilla_LinkLexers();
#endif
	return result;
}

// This function is externally visible so it can be called from container when building statically.
bool Scintilla_ReleaseResources() {
	bool result = ScintillaWin::Unregister();
	Platform_Finalise();
	return result;
}

#ifndef STATIC_BUILD
extern "C" int APIENTRY DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID) {
	//Platform::DebugPrintf("Scintilla::DllMain %d %d\n", hInstance, dwReason);
	if (dwReason == DLL_PROCESS_ATTACH) {
		if (!Scintilla_RegisterClasses(hInstance))
			return FALSE;
	} else if (dwReason == DLL_PROCESS_DETACH) {
		Scintilla_ReleaseResources();
	}
	return TRUE;
}
#endif

⌨️ 快捷键说明

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