📄 guiconsole.c
字号:
return;
}
DPRINT("GuiConsoleReadUserSettings entered dwNumSubKeys %d\n", dwNumSubKeys);
for (dwIndex = 0; dwIndex < dwNumSubKeys; dwIndex++)
{
dwValue = sizeof(Value);
dwValueName = MAX_PATH;
if (RegEnumValueW(hKey, dwIndex, szValueName, &dwValueName, NULL, &dwType, (BYTE*)&Value, &dwValue) != ERROR_SUCCESS)
{
if (dwType == REG_SZ)
{
/*
* retry in case of string value
*/
dwValue = sizeof(szValue);
dwValueName = MAX_PATH;
if (RegEnumValueW(hKey, dwIndex, szValueName, &dwValueName, NULL, NULL, (BYTE*)szValue, &dwValue) != ERROR_SUCCESS)
break;
}
else
break;
}
if (!wcscmp(szValueName, L"CursorSize"))
{
if (Value == 0x32)
{
Buffer->CursorInfo.dwSize = Value;
}
else if (Value == 0x64)
{
Buffer->CursorInfo.dwSize = Value;
}
}
else if (!wcscmp(szValueName, L"ScreenText"))
{
GuiData->ScreenText = Value;
}
else if (!wcscmp(szValueName, L"ScreenBackground"))
{
GuiData->ScreenBackground = Value;
}
else if (!wcscmp(szValueName, L"FaceName"))
{
wcscpy(GuiData->FontName, szValue);
}
else if (!wcscmp(szValueName, L"FontSize"))
{
GuiData->FontSize = Value;
}
else if (!wcscmp(szValueName, L"FontWeight"))
{
GuiData->FontWeight = Value;
}
else if (!wcscmp(szValueName, L"HistoryNoDup"))
{
GuiData->HistoryNoDup = Value;
}
else if (!wcscmp(szValueName, L"WindowSize"))
{
Console->Size.X = LOWORD(Value);
Console->Size.Y = HIWORD(Value);
}
else if (!wcscmp(szValueName, L"ScreenBufferSize"))
{
if(Buffer)
{
Buffer->MaxX = LOWORD(Value);
Buffer->MaxY = HIWORD(Value);
}
}
else if (!wcscmp(szValueName, L"FullScreen"))
{
GuiData->FullScreen = Value;
}
else if (!wcscmp(szValueName, L"QuickEdit"))
{
GuiData->QuickEdit = Value;
}
else if (!wcscmp(szValueName, L"InsertMode"))
{
GuiData->InsertMode = Value;
}
}
}
static VOID FASTCALL
GuiConsoleUseDefaults(PCSRSS_CONSOLE Console, PGUI_CONSOLE_DATA GuiData, PCSRSS_SCREEN_BUFFER Buffer)
{
/*
* init guidata with default properties
*/
wcscpy(GuiData->FontName, L"DejaVu Sans Mono");
GuiData->FontSize = 0x0008000C; // font is 8x12
GuiData->FontWeight = FW_NORMAL;
GuiData->HistoryNoDup = FALSE;
GuiData->FullScreen = FALSE;
GuiData->QuickEdit = FALSE;
GuiData->InsertMode = TRUE;
GuiData->HistoryBufferSize = 50;
GuiData->NumberOfHistoryBuffers = 5;
GuiData->ScreenText = RGB(192, 192, 192);
GuiData->ScreenBackground = RGB(0, 0, 0);
GuiData->PopupText = RGB(128, 0, 128);
GuiData->PopupBackground = RGB(255, 255, 255);
GuiData->WindowPosition = UINT_MAX;
GuiData->ScreenBufferSize = MAKELONG(80, 300); //FIXME
GuiData->UseRasterFonts = TRUE;
memcpy(GuiData->Colors, s_Colors, sizeof(s_Colors));
Console->Size.X = 80;
Console->Size.Y = 25;
if (Buffer)
{
Buffer->MaxX = 80;
Buffer->MaxY = 25;
Buffer->CursorInfo.bVisible = TRUE;
Buffer->CursorInfo.dwSize = 5;
}
}
static BOOL FASTCALL
GuiConsoleHandleNcCreate(HWND hWnd, CREATESTRUCTW *Create)
{
RECT Rect;
PCSRSS_CONSOLE Console = (PCSRSS_CONSOLE) Create->lpCreateParams;
PGUI_CONSOLE_DATA GuiData = (PGUI_CONSOLE_DATA)Console->PrivateData;
HDC Dc;
HFONT OldFont;
TEXTMETRICW Metrics;
PCSRSS_PROCESS_DATA ProcessData;
HKEY hKey;
Console->hWindow = hWnd;
if (NULL == GuiData)
{
DPRINT1("GuiConsoleNcCreate: HeapAlloc failed\n");
return FALSE;
}
GuiConsoleUseDefaults(Console, GuiData, Console->ActiveBuffer);
if (Console->ProcessList.Flink != &Console->ProcessList)
{
ProcessData = CONTAINING_RECORD(Console->ProcessList.Flink, CSRSS_PROCESS_DATA, ProcessEntry);
if (GuiConsoleOpenUserSettings(GuiData, PtrToUlong(ProcessData->ProcessId), &hKey, KEY_READ, FALSE))
{
GuiConsoleReadUserSettings(hKey, Console, GuiData, Console->ActiveBuffer);
RegCloseKey(hKey);
}
}
InitializeCriticalSection(&GuiData->Lock);
GuiData->LineBuffer = (PWCHAR)HeapAlloc(Win32CsrApiHeap, HEAP_ZERO_MEMORY,
Console->Size.X * sizeof(WCHAR));
GuiData->Font = CreateFontW(LOWORD(GuiData->FontSize),
0, //HIWORD(GuiData->FontSize),
0,
TA_BASELINE,
GuiData->FontWeight,
FALSE,
FALSE,
FALSE,
OEM_CHARSET,
OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
NONANTIALIASED_QUALITY, FIXED_PITCH | FF_DONTCARE,
GuiData->FontName);
if (NULL == GuiData->Font)
{
DPRINT1("GuiConsoleNcCreate: CreateFont failed\n");
DeleteCriticalSection(&GuiData->Lock);
HeapFree(Win32CsrApiHeap, 0, GuiData);
return FALSE;
}
Dc = GetDC(hWnd);
if (NULL == Dc)
{
DPRINT1("GuiConsoleNcCreate: GetDC failed\n");
DeleteObject(GuiData->Font);
DeleteCriticalSection(&GuiData->Lock);
HeapFree(Win32CsrApiHeap, 0, GuiData);
return FALSE;
}
OldFont = SelectObject(Dc, GuiData->Font);
if (NULL == OldFont)
{
DPRINT1("GuiConsoleNcCreate: SelectObject failed\n");
ReleaseDC(hWnd, Dc);
DeleteObject(GuiData->Font);
DeleteCriticalSection(&GuiData->Lock);
HeapFree(Win32CsrApiHeap, 0, GuiData);
return FALSE;
}
if (! GetTextMetricsW(Dc, &Metrics))
{
DPRINT1("GuiConsoleNcCreate: GetTextMetrics failed\n");
SelectObject(Dc, OldFont);
ReleaseDC(hWnd, Dc);
DeleteObject(GuiData->Font);
DeleteCriticalSection(&GuiData->Lock);
HeapFree(Win32CsrApiHeap, 0, GuiData);
return FALSE;
}
GuiData->CharWidth = Metrics.tmMaxCharWidth;
GuiData->CharHeight = Metrics.tmHeight + Metrics.tmExternalLeading;
SelectObject(Dc, OldFont);
ReleaseDC(hWnd, Dc);
GuiData->CursorBlinkOn = TRUE;
GuiData->ForceCursorOff = FALSE;
GuiData->Selection.left = -1;
DPRINT("Console %p GuiData %p\n", Console, GuiData);
Console->PrivateData = GuiData;
SetWindowLongPtrW(hWnd, GWL_USERDATA, (DWORD_PTR) Console);
GetWindowRect(hWnd, &Rect);
Rect.right = Rect.left + Console->Size.X * GuiData->CharWidth +
2 * GetSystemMetrics(SM_CXFIXEDFRAME);
Rect.bottom = Rect.top + Console->Size.Y * GuiData->CharHeight +
2 * GetSystemMetrics(SM_CYFIXEDFRAME) + GetSystemMetrics(SM_CYCAPTION);
MoveWindow(hWnd, Rect.left, Rect.top, Rect.right - Rect.left,
Rect.bottom - Rect.top, FALSE);
SetTimer(hWnd, 1, CURSOR_BLINK_TIME, NULL);
GuiConsoleCreateSysMenu(Console);
SetEvent(GuiData->hGuiInitEvent);
return (BOOL) DefWindowProcW(hWnd, WM_NCCREATE, 0, (LPARAM) Create);
}
static COLORREF FASTCALL
GuiConsoleRGBFromAttribute(BYTE Attribute)
{
int Red = (Attribute & 0x04 ? (Attribute & 0x08 ? 0xff : 0x80) : 0x00);
int Green = (Attribute & 0x02 ? (Attribute & 0x08 ? 0xff : 0x80) : 0x00);
int Blue = (Attribute & 0x01 ? (Attribute & 0x08 ? 0xff : 0x80) : 0x00);
return RGB(Red, Green, Blue);
}
static VOID FASTCALL
GuiConsoleSetTextColors(HDC Dc, BYTE Attribute, PCSRSS_SCREEN_BUFFER Buff, COLORREF TextColor, COLORREF BkColor)
{
if (Attribute != Buff->DefaultAttrib)
{
SetTextColor(Dc, GuiConsoleRGBFromAttribute(Attribute & 0x0f));
SetBkColor(Dc, GuiConsoleRGBFromAttribute((Attribute & 0xf0) >> 4));
}
else
{
SetTextColor(Dc, TextColor);
SetBkColor(Dc, BkColor);
}
}
static VOID FASTCALL
GuiConsoleGetLogicalCursorPos(PCSRSS_SCREEN_BUFFER Buff, ULONG *CursorX, ULONG *CursorY)
{
*CursorX = Buff->CurrentX;
if (Buff->CurrentY < Buff->ShowY)
{
*CursorY = Buff->MaxY - Buff->ShowY + Buff->CurrentY;
}
else
{
*CursorY = Buff->CurrentY - Buff->ShowY;
}
}
static VOID FASTCALL
GuiConsoleUpdateSelection(HWND hWnd, PRECT rc, PGUI_CONSOLE_DATA GuiData)
{
RECT oldRect = GuiData->Selection;
if(rc != NULL)
{
RECT changeRect = *rc;
GuiData->Selection = *rc;
changeRect.left *= GuiData->CharWidth;
changeRect.top *= GuiData->CharHeight;
changeRect.right *= GuiData->CharWidth;
changeRect.bottom *= GuiData->CharHeight;
if(rc->left != oldRect.left ||
rc->top != oldRect.top ||
rc->right != oldRect.right ||
rc->bottom != oldRect.bottom)
{
if(oldRect.left != -1)
{
HRGN rgn1, rgn2;
oldRect.left *= GuiData->CharWidth;
oldRect.top *= GuiData->CharHeight;
oldRect.right *= GuiData->CharWidth;
oldRect.bottom *= GuiData->CharHeight;
/* calculate the region that needs to be updated */
if((rgn1 = CreateRectRgnIndirect(&oldRect)))
{
if((rgn2 = CreateRectRgnIndirect(&changeRect)))
{
if(CombineRgn(rgn1, rgn2, rgn1, RGN_XOR) != ERROR)
{
InvalidateRgn(hWnd, rgn1, FALSE);
}
DeleteObject(rgn2);
}
DeleteObject(rgn1);
}
}
else
{
InvalidateRect(hWnd, &changeRect, FALSE);
}
}
}
else if(oldRect.left != -1)
{
/* clear the selection */
GuiData->Selection.left = -1;
oldRect.left *= GuiData->CharWidth;
oldRect.top *= GuiData->CharHeight;
oldRect.right *= GuiData->CharWidth;
oldRect.bottom *= GuiData->CharHeight;
InvalidateRect(hWnd, &oldRect, FALSE);
}
}
static VOID FASTCALL
GuiConsolePaint(PCSRSS_CONSOLE Console,
PGUI_CONSOLE_DATA GuiData,
HDC hDC,
PRECT rc)
{
PCSRSS_SCREEN_BUFFER Buff;
ULONG TopLine, BottomLine, LeftChar, RightChar;
ULONG Line, Char, Start;
PBYTE From;
PWCHAR To;
BYTE LastAttribute, Attribute;
ULONG CursorX, CursorY, CursorHeight;
HBRUSH CursorBrush, OldBrush, BackgroundBrush;
HFONT OldFont;
Buff = Console->ActiveBuffer;
TopLine = rc->top / GuiData->CharHeight;
BottomLine = (rc->bottom + (GuiData->CharHeight - 1)) / GuiData->CharHeight - 1;
LeftChar = rc->left / GuiData->CharWidth;
RightChar = (rc->right + (GuiData->CharWidth - 1)) / GuiData->CharWidth - 1;
LastAttribute = Buff->Buffer[(TopLine * Buff->MaxX + LeftChar) * 2 + 1];
GuiConsoleSetTextColors(hDC,
LastAttribute,
Buff,
GuiData->ScreenText,
GuiData->ScreenBackground);
EnterCriticalSection(&Buff->Header.Lock);
OldFont = SelectObject(hDC,
GuiData->Font);
BackgroundBrush = CreateSolidBrush(GuiData->ScreenBackground);
FillRect(hDC, rc, BackgroundBrush);
DeleteObject(BackgroundBrush);
for (Line = TopLine; Line <= BottomLine; Line++)
{
if (Line + Buff->ShowY < Buff->MaxY)
{
From = Buff->Buffer + ((Line + Buff->ShowY) * Buff->MaxX + LeftChar) * 2;
}
else
{
From = Buff->Buffer +
((Line - (Buff->MaxY - Buff->ShowY)) * Buff->MaxX + LeftChar) * 2;
}
Start = LeftChar;
To = GuiData->LineBuffer;
for (Char = LeftChar; Char <= RightChar; Char++)
{
if (*(From + 1) != LastAttribute)
{
TextOutW(hDC,
Start * GuiData->CharWidth,
Line * GuiData->CharHeight,
GuiData->LineBuffer,
Char - Start);
Start = Char;
To = GuiData->LineBuffer;
Attribute = *(From + 1);
if (Attribute != LastAttribute)
{
GuiConsoleSetTextColors(hDC,
Attribute,
Buff,
GuiData->ScreenText,
GuiData->ScreenBackground);
LastAttribute = Attribute;
}
}
MultiByteToWideChar(Console->OutputCodePage,
0,
(PCHAR)From,
1,
To,
1);
To++;
From += 2;
}
TextOutW(hDC,
Start * GuiData->CharWidth,
Line * GuiData->CharHeight,
GuiData->LineBuffer,
RightChar - Start + 1);
}
if (Buff->CursorInfo.bVisible && GuiData->CursorBlinkOn &&
!GuiData->ForceCursorOff)
{
GuiConsoleGetLogicalCursorPos(Buff,
&CursorX,
&CursorY);
if (LeftChar <= CursorX && CursorX <= RightChar &&
TopLine <= CursorY && CursorY <= BottomLine)
{
CursorHeight = (GuiData->CharHeight * Buff->CursorInfo.dwSize) / 100;
if (CursorHeight < 1)
{
CursorHeight = 1;
}
From = Buff->Buffer + (Buff->CurrentY * Buff->MaxX + Buff->CurrentX) * 2 + 1;
if (*From != DEFAULT_ATTRIB)
{
CursorBrush = CreateSolidBrush(GuiConsoleRGBFromAttribute(*From));
}
else
{
CursorBrush = CreateSolidBrush(GuiData->ScreenText);
}
OldBrush = SelectObject(hDC,
CursorBrush);
PatBlt(hDC,
CursorX * GuiData->CharWidth,
CursorY * GuiData->CharHeight + (GuiData->CharHeight - CursorHeight),
GuiData->CharWidth,
CursorHeight,
PATCOPY);
SelectObject(hDC,
OldBrush);
DeleteObject(CursorBrush);
}
}
LeaveCriticalSection(&Buff->Header.Lock);
SelectObject(hDC,
OldFont);
}
static VOID FASTCALL
GuiConsoleHandlePaint(HWND hWnd, HDC hDCPaint)
{
HDC hDC;
PAINTSTRUCT ps;
PCSRSS_CONSOLE Console;
PGUI_CONSOLE_DATA GuiData;
hDC = BeginPaint(hWnd, &ps);
if (hDC != NULL &&
ps.rcPaint.left < ps.rcPaint.right &&
ps.rcPaint.top < ps.rcPaint.bottom)
{
GuiConsoleGetDataPointers(hWnd,
&Console,
&GuiData);
if (Console != NULL && GuiData != NULL &&
Console->ActiveBuffer != NULL)
{
if (Console->ActiveBuffer->Buffer != NULL)
{
EnterCriticalSection(&GuiData->Lock);
GuiConsolePaint(Console,
GuiData,
hDC,
&ps.rcPaint);
if (GuiData->Selection.left != -1)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -