?? scintillawin.cxx
字號:
// Scintilla source code edit control
/** @file ScintillaWin.cxx
** Windows specific subclass of ScintillaBase.
**/
// Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <ctype.h>
#include <assert.h>
#include <limits.h>
#define _WIN32_WINNT 0x0500
#include <windows.h>
#include <commctrl.h>
#include <richedit.h>
#include <windowsx.h>
#include "Platform.h"
#include "Scintilla.h"
#include "SString.h"
#ifdef SCI_LEXER
#include "SciLexer.h"
#include "PropSet.h"
#include "Accessor.h"
#include "KeyWords.h"
#endif
#include "ContractionState.h"
#include "SVector.h"
#include "SplitVector.h"
#include "Partitioning.h"
#include "CellBuffer.h"
#include "CallTip.h"
#include "KeyMap.h"
#include "Indicator.h"
#include "XPM.h"
#include "LineMarker.h"
#include "Style.h"
#include "AutoComplete.h"
#include "ViewStyle.h"
#include "CharClassify.h"
#include "Document.h"
#include "Editor.h"
#include "ScintillaBase.h"
#include "UniConversion.h"
#ifdef SCI_LEXER
#include "ExternalLexer.h"
#endif
#ifndef SPI_GETWHEELSCROLLLINES
#define SPI_GETWHEELSCROLLLINES 104
#endif
#ifndef WM_UNICHAR
#define WM_UNICHAR 0x0109
#endif
#ifndef UNICODE_NOCHAR
#define UNICODE_NOCHAR 0xFFFF
#endif
#ifndef WM_IME_STARTCOMPOSITION
#include <imm.h>
#endif
#include <commctrl.h>
#ifndef __BORLANDC__
#ifndef __DMC__
#include <zmouse.h>
#endif
#endif
#include <ole2.h>
#ifndef MK_ALT
#define MK_ALT 32
#endif
#define SC_WIN_IDLE 5001
// Functions imported from PlatWin
extern bool IsNT();
extern void Platform_Initialise(void *hInstance);
extern void Platform_Finalise();
/** TOTAL_CONTROL ifdef surrounds code that will only work when ScintillaWin
* is derived from ScintillaBase (all features) rather than directly from Editor
* (lightweight editor).
*/
#define TOTAL_CONTROL
// GCC has trouble with the standard COM ABI so do it the old C way with explicit vtables.
const TCHAR scintillaClassName[] = TEXT("Scintilla");
const TCHAR callClassName[] = TEXT("CallTip");
class ScintillaWin; // Forward declaration for COM interface subobjects
/**
*/
class FormatEnumerator {
public:
void **vtbl;
int ref;
int pos;
CLIPFORMAT formats[2];
int formatsLen;
FormatEnumerator(int pos_, CLIPFORMAT formats_[], int formatsLen_);
};
/**
*/
class DropSource {
public:
void **vtbl;
ScintillaWin *sci;
DropSource();
};
/**
*/
class DataObject {
public:
void **vtbl;
ScintillaWin *sci;
DataObject();
};
/**
*/
class DropTarget {
public:
void **vtbl;
ScintillaWin *sci;
DropTarget();
};
/**
*/
class ScintillaWin :
public ScintillaBase {
bool lastKeyDownConsumed;
bool capturedMouse;
unsigned int linesPerScroll; ///< Intellimouse support
int wheelDelta; ///< Wheel delta from roll
HRGN hRgnUpdate;
bool hasOKText;
CLIPFORMAT cfColumnSelect;
DropSource ds;
DataObject dob;
DropTarget dt;
static HINSTANCE hInstance;
ScintillaWin(HWND hwnd);
ScintillaWin(const ScintillaWin &) : ScintillaBase() {}
virtual ~ScintillaWin();
ScintillaWin &operator=(const ScintillaWin &) { return *this; }
virtual void Initialise();
virtual void Finalise();
HWND MainHWND();
static sptr_t DirectFunction(
ScintillaWin *sci, UINT iMessage, uptr_t wParam, sptr_t lParam);
static sptr_t PASCAL SWndProc(
HWND hWnd, UINT iMessage, WPARAM wParam, sptr_t lParam);
static sptr_t PASCAL CTWndProc(
HWND hWnd, UINT iMessage, WPARAM wParam, sptr_t lParam);
enum { invalidTimerID, standardTimerID, idleTimerID };
virtual void StartDrag();
sptr_t WndPaint(uptr_t wParam);
sptr_t HandleComposition(uptr_t wParam, sptr_t lParam);
virtual bool ValidCodePage(int codePage) const;
virtual sptr_t DefWndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam);
virtual bool SetIdle(bool on);
virtual void SetTicking(bool on);
virtual void SetMouseCapture(bool on);
virtual bool HaveMouseCapture();
virtual bool PaintContains(PRectangle rc);
virtual void ScrollText(int linesToMove);
virtual void UpdateSystemCaret();
virtual void SetVerticalScrollPos();
virtual void SetHorizontalScrollPos();
virtual bool ModifyScrollBars(int nMax, int nPage);
virtual void NotifyChange();
virtual void NotifyFocus(bool focus);
virtual int GetCtrlID();
virtual void NotifyParent(SCNotification scn);
virtual void NotifyDoubleClick(Point pt, bool shift);
virtual void Copy();
virtual bool CanPaste();
virtual void Paste();
virtual void CreateCallTipWindow(PRectangle rc);
virtual void AddToPopUp(const char *label, int cmd = 0, bool enabled = true);
virtual void ClaimSelection();
// DBCS
void ImeStartComposition();
void ImeEndComposition();
void AddCharBytes(char b0, char b1);
void GetIntelliMouseParameters();
virtual void CopyToClipboard(const SelectionText &selectedText);
void ScrollMessage(WPARAM wParam);
void HorizontalScrollMessage(WPARAM wParam);
void RealizeWindowPalette(bool inBackGround);
void FullPaint();
void FullPaintDC(HDC dc);
bool IsCompatibleDC(HDC dc);
virtual int SetScrollInfo(int nBar, LPCSCROLLINFO lpsi, BOOL bRedraw);
virtual bool GetScrollInfo(int nBar, LPSCROLLINFO lpsi);
void ChangeScrollPos(int barType, int pos);
void InsertPasteText(const char *text, int len, int selStart, bool isRectangular);
public:
// Public for benefit of Scintilla_DirectFunction
virtual sptr_t WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam);
/// Implement IUnknown
STDMETHODIMP QueryInterface(REFIID riid, PVOID *ppv);
STDMETHODIMP_(ULONG)AddRef();
STDMETHODIMP_(ULONG)Release();
/// Implement IDropTarget
STDMETHODIMP DragEnter(LPDATAOBJECT pIDataSource, DWORD grfKeyState,
POINTL pt, PDWORD pdwEffect);
STDMETHODIMP DragOver(DWORD grfKeyState, POINTL pt, PDWORD pdwEffect);
STDMETHODIMP DragLeave();
STDMETHODIMP Drop(LPDATAOBJECT pIDataSource, DWORD grfKeyState,
POINTL pt, PDWORD pdwEffect);
/// Implement important part of IDataObject
STDMETHODIMP GetData(FORMATETC *pFEIn, STGMEDIUM *pSTM);
// External Lexers
#ifdef SCI_LEXER
void SetLexerLanguage(const char *languageName);
void SetLexer(uptr_t wParam);
#endif
static bool Register(HINSTANCE hInstance_);
static bool Unregister();
friend class DropSource;
friend class DataObject;
friend class DropTarget;
bool DragIsRectangularOK(CLIPFORMAT fmt) {
return drag.rectangular && (fmt == cfColumnSelect);
}
private:
// For use in creating a system caret
bool HasCaretSizeChanged();
BOOL CreateSystemCaret();
BOOL DestroySystemCaret();
HBITMAP sysCaretBitmap;
int sysCaretWidth;
int sysCaretHeight;
};
HINSTANCE ScintillaWin::hInstance = 0;
ScintillaWin::ScintillaWin(HWND hwnd) {
lastKeyDownConsumed = false;
capturedMouse = false;
linesPerScroll = 0;
wheelDelta = 0; // Wheel delta from roll
hRgnUpdate = 0;
hasOKText = false;
// There does not seem to be a real standard for indicating that the clipboard
// contains a rectangular selection, so copy Developer Studio.
cfColumnSelect = static_cast<CLIPFORMAT>(
::RegisterClipboardFormat(TEXT("MSDEVColumnSelect")));
wMain = hwnd;
dob.sci = this;
ds.sci = this;
dt.sci = this;
sysCaretBitmap = 0;
sysCaretWidth = 0;
sysCaretHeight = 0;
Initialise();
}
ScintillaWin::~ScintillaWin() {}
void ScintillaWin::Initialise() {
// Initialize COM. If the app has already done this it will have
// no effect. If the app hasnt, we really shouldnt ask them to call
// it just so this internal feature works.
::OleInitialize(NULL);
}
void ScintillaWin::Finalise() {
ScintillaBase::Finalise();
SetTicking(false);
SetIdle(false);
DestroySystemCaret();
::RevokeDragDrop(MainHWND());
::OleUninitialize();
}
HWND ScintillaWin::MainHWND() {
return reinterpret_cast<HWND>(wMain.GetID());
}
void ScintillaWin::StartDrag() {
DWORD dwEffect = 0;
dropWentOutside = true;
IDataObject *pDataObject = reinterpret_cast<IDataObject *>(&dob);
IDropSource *pDropSource = reinterpret_cast<IDropSource *>(&ds);
//Platform::DebugPrintf("About to DoDragDrop %x %x\n", pDataObject, pDropSource);
HRESULT hr = ::DoDragDrop(
pDataObject,
pDropSource,
DROPEFFECT_COPY | DROPEFFECT_MOVE, &dwEffect);
//Platform::DebugPrintf("DoDragDrop = %x\n", hr);
if (SUCCEEDED(hr)) {
if ((hr == DRAGDROP_S_DROP) && (dwEffect == DROPEFFECT_MOVE) && dropWentOutside) {
// Remove dragged out text
ClearSelection();
}
}
inDragDrop = false;
SetDragPosition(invalidPosition);
}
// Avoid warnings everywhere for old style casts by concentrating them here
static WORD LoWord(DWORD l) {
return LOWORD(l);
}
static WORD HiWord(DWORD l) {
return HIWORD(l);
}
static int InputCodePage() {
HKL inputLocale = ::GetKeyboardLayout(0);
LANGID inputLang = LOWORD(inputLocale);
char sCodePage[10];
int res = ::GetLocaleInfo(MAKELCID(inputLang, SORT_DEFAULT),
LOCALE_IDEFAULTANSICODEPAGE, sCodePage, sizeof(sCodePage));
if (!res)
return 0;
return atoi(sCodePage);
}
#ifndef VK_OEM_2
static const int VK_OEM_2=0xbf;
static const int VK_OEM_3=0xc0;
static const int VK_OEM_4=0xdb;
static const int VK_OEM_5=0xdc;
static const int VK_OEM_6=0xdd;
#endif
/** Map the key codes to their equivalent SCK_ form. */
static int KeyTranslate(int keyIn) {
//PLATFORM_ASSERT(!keyIn);
switch (keyIn) {
case VK_DOWN: return SCK_DOWN;
case VK_UP: return SCK_UP;
case VK_LEFT: return SCK_LEFT;
case VK_RIGHT: return SCK_RIGHT;
case VK_HOME: return SCK_HOME;
case VK_END: return SCK_END;
case VK_PRIOR: return SCK_PRIOR;
case VK_NEXT: return SCK_NEXT;
case VK_DELETE: return SCK_DELETE;
case VK_INSERT: return SCK_INSERT;
case VK_ESCAPE: return SCK_ESCAPE;
case VK_BACK: return SCK_BACK;
case VK_TAB: return SCK_TAB;
case VK_RETURN: return SCK_RETURN;
case VK_ADD: return SCK_ADD;
case VK_SUBTRACT: return SCK_SUBTRACT;
case VK_DIVIDE: return SCK_DIVIDE;
case VK_LWIN: return SCK_WIN;
case VK_RWIN: return SCK_RWIN;
case VK_APPS: return SCK_MENU;
case VK_OEM_2: return '/';
case VK_OEM_3: return '`';
case VK_OEM_4: return '[';
case VK_OEM_5: return '\\';
case VK_OEM_6: return ']';
default: return keyIn;
}
}
LRESULT ScintillaWin::WndPaint(uptr_t wParam) {
//ElapsedTime et;
// Redirect assertions to debug output and save current state
bool assertsPopup = Platform::ShowAssertionPopUps(false);
paintState = painting;
PAINTSTRUCT ps;
PAINTSTRUCT *pps;
bool IsOcxCtrl = (wParam != 0); // if wParam != 0, it contains
// a PAINSTRUCT* from the OCX
// Removed since this interferes with reporting other assertions as it occurs repeatedly
//PLATFORM_ASSERT(hRgnUpdate == NULL);
hRgnUpdate = ::CreateRectRgn(0, 0, 0, 0);
if (IsOcxCtrl) {
pps = reinterpret_cast<PAINTSTRUCT*>(wParam);
} else {
::GetUpdateRgn(MainHWND(), hRgnUpdate, FALSE);
pps = &ps;
::BeginPaint(MainHWND(), pps);
}
AutoSurface surfaceWindow(pps->hdc, this);
if (surfaceWindow) {
rcPaint = PRectangle(pps->rcPaint.left, pps->rcPaint.top, pps->rcPaint.right, pps->rcPaint.bottom);
PRectangle rcClient = GetClientRectangle();
paintingAllText = rcPaint.Contains(rcClient);
if (paintingAllText) {
//Platform::DebugPrintf("Performing full text paint\n");
} else {
//Platform::DebugPrintf("Performing partial paint %d .. %d\n", rcPaint.top, rcPaint.bottom);
}
Paint(surfaceWindow, rcPaint);
surfaceWindow->Release();
}
if (hRgnUpdate) {
::DeleteRgn(hRgnUpdate);
hRgnUpdate = 0;
}
if(!IsOcxCtrl)
::EndPaint(MainHWND(), pps);
if (paintState == paintAbandoned) {
// Painting area was insufficient to cover new styling or brace highlight positions
FullPaint();
}
paintState = notPainting;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -