자동 들여쓰기 구현
핵심 아이디어는 SCN_CHARADDED 고지를 이용하여 새줄 문자 이후에 들여쓰기를 추가하는 것이다.
고지의 lParam은 SCNotification 구조를 카리키는 포인터로서 그 안의 ch 멤버는 추가된 문자를 지정한다. 새줄문자 추가되면, 앞 줄을 열람하고 같은 들여쓰기 만큼 새줄에 추가할 수 있다.
다음은 SciTE에서 가져 온 관련 코드이다: (SciTE.cxx
SciTEWindow::CharAdded)
if
(ch
== '\r' || ch
== '\n') {
char linebuf[1000];
int curLine = GetCurrentLineNumber();
int lineLength =
SendEditor(SCI_LINELENGTH, curLine);
//Platform::DebugPrintf("[CR] %d len = %d\n", curLine, lineLength);
if (curLine > 0 && lineLength <=
2)
{
int prevLineLength = SendEditor(SCI_LINELENGTH, curLine -
1);
if (prevLineLength < sizeof(linebuf))
{
WORD buflen = sizeof(linebuf);
memcpy(linebuf,
&buflen, sizeof(buflen));
SendEditor(EM_GETLINE,
curLine - 1,
reinterpret_cast<LPARAM>(static_cast<char *>(linebuf)));
linebuf[prevLineLength] =
'\0';
for (int pos =
0;
linebuf[pos]; pos++) {
if (linebuf[pos] != ' ' && linebuf[pos] != '\t')
linebuf[pos] = '\0';
}
SendEditor(EM_REPLACESEL, 0, reinterpret_cast<LPARAM>(static_cast<char
*>(linebuf)));
}
}
물론, 더 멋지게 처리를 구현할 수 있다. 예를 들어, 앞 줄이 제어 구조의 시작이었다면, 다음 줄은 자동으로 한 탭 만큼 더 들여쓰기 할 수 있다. (그것이 여러분의 들여쓰기가 스타일이라고 가정하고서 말이다.)
구문 스타일링 구현
구문 스타일링은 SCN_STYLENEEDED 고지로 처리한다. 신틸라는 스타일 처리된 텍스트의 끝을 추적 관리한다 - 이것은 SCI_GETENDSTYLED으로 열람한다. SCN_STYLENEEDED 고지에 응대하여, 스타일을 ENDSTYLED로부터 고지에 지정한 위치까지에 있는 텍스트에 적용해야 한다.
다음은 관련 코드를 SciTE로부터 가져 왔다: (SciTE.cxx)
void SciTEWindow::Notify(SCNotification *notification) {
switch (notification->nmhdr.code)
{
case SCN_STYLENEEDED: {
if (notification->nmhdr.idFrom ==
IDM_SRCWIN) {
int endStyled = SendEditor(SCI_GETENDSTYLED);
int lineEndStyled = SendEditor(EM_LINEFROMCHAR, endStyled);
endStyled = SendEditor(EM_LINEINDEX, lineEndStyled);
Colourise(endStyled,
notification->position);
Colourize(start, end)는 지정한 범위의 텍스트를 열람하고 keywords.cxx에 있는 ColourizeDoc을 호출한다. 다음과 같이 호출하면서 프로세스를 시작한다:
SendMessage(hwnd, SCI_STARTSTYLING, startPos,
31);
다음으로 텍스트의 각 토큰에 대하여, 다음과 같이 호출한다:
SendMessage(hwnd, SCI_SETSTYLING, length,
style);
여기에서 style은 0부터 31까지 번호이다. 각 모양은 SCI_STYLESET... 메시지를 사용하여 정의되어 있다.
호출정보(Calltips) 구현
역시, SCN_CHARADDED 고지를 사용하여 여는 괄호가 추가되는 순간을 잡는다. 앞 단어는 현재 줄에서 열람할 수 있다:
char linebuf[1000];
int current =
SendEditor(SCI_GETCURLINE, sizeof(linebuf),
reinterpret_cast<LPARAM>(static_cast<char *>(linebuf)));
int pos =
SendEditor(SCI_GETCURRENTPOS);
int startword =
current - 1;
while (startword > 0 && isalpha(linebuf[startword - 1]))
startword--;
linebuf[current
- 1] = '\0';
char* word = linebuf +
startword;
그리고 호출정보를 사용할 수 있으면 화면에 보여줄 수 있다. 콜팁이 지정한 위치 아래에 즉시 보여진다. 콜팁은 새줄문자(\n)로 여러 줄로 가를 수 있다.
pos = SendMessage(hwnd, SCI_GETCURRENTPOS, 0, 0);
SendMessageText(hwnd, SCI_CALLTIPSHOW, pos
- wordLen - 1, calltip);
콜팁은 닫는 괄호가 입력될 때 제거할 수 있다:
if
(SendMessage(hwnd, SCI_CALLTIPACTIVE, 0, 0))
SendMessage(hwnd, SCI_CALLTIPCANCEL, 0, 0);
적절한 콜팁 텍스트가 공급된 후에는 어플리케이션이 책임진다.
SciTE는 한 발 더 나아가, 인자 사이의 쉼표 개수를 세서 호출정보에서 상응하는 부분을 강조한다. 이 코드는 ContinueCallTip에 있다.
Page contributed by Andrew McKinlay.