📄 guiconsole.c
字号:
RECT rc = GuiData->Selection;
rc.left *= GuiData->CharWidth;
rc.top *= GuiData->CharHeight;
rc.right *= GuiData->CharWidth;
rc.bottom *= GuiData->CharHeight;
/* invert the selection */
if (IntersectRect(&rc,
&ps.rcPaint,
&rc))
{
PatBlt(hDC,
rc.left,
rc.top,
rc.right - rc.left,
rc.bottom - rc.top,
DSTINVERT);
}
}
LeaveCriticalSection(&GuiData->Lock);
}
}
EndPaint(hWnd, &ps);
}
}
static VOID FASTCALL
GuiConsoleHandleKey(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
PCSRSS_CONSOLE Console;
PGUI_CONSOLE_DATA GuiData;
MSG Message;
GuiConsoleGetDataPointers(hWnd, &Console, &GuiData);
Message.hwnd = hWnd;
Message.message = msg;
Message.wParam = wParam;
Message.lParam = lParam;
if(msg == WM_CHAR || msg == WM_SYSKEYDOWN)
{
/* clear the selection */
GuiConsoleUpdateSelection(hWnd, NULL, GuiData);
}
ConioProcessKey(&Message, Console, FALSE);
}
static VOID FASTCALL
GuiIntDrawRegion(PGUI_CONSOLE_DATA GuiData, HWND Wnd, RECT *Region)
{
RECT RegionRect;
RegionRect.left = Region->left * GuiData->CharWidth;
RegionRect.top = Region->top * GuiData->CharHeight;
RegionRect.right = (Region->right + 1) * GuiData->CharWidth;
RegionRect.bottom = (Region->bottom + 1) * GuiData->CharHeight;
InvalidateRect(Wnd, &RegionRect, FALSE);
}
static VOID STDCALL
GuiDrawRegion(PCSRSS_CONSOLE Console, RECT *Region)
{
PGUI_CONSOLE_DATA GuiData = (PGUI_CONSOLE_DATA) Console->PrivateData;
if (NULL != Console->hWindow && NULL != GuiData)
{
GuiIntDrawRegion(GuiData, Console->hWindow, Region);
}
}
static VOID FASTCALL
GuiInvalidateCell(PGUI_CONSOLE_DATA GuiData, HWND Wnd, UINT x, UINT y)
{
RECT CellRect;
CellRect.left = x;
CellRect.top = y;
CellRect.right = x;
CellRect.bottom = y;
GuiIntDrawRegion(GuiData, Wnd, &CellRect);
}
static VOID STDCALL
GuiWriteStream(PCSRSS_CONSOLE Console, RECT *Region, LONG CursorStartX, LONG CursorStartY,
UINT ScrolledLines, CHAR *Buffer, UINT Length)
{
PGUI_CONSOLE_DATA GuiData = (PGUI_CONSOLE_DATA) Console->PrivateData;
PCSRSS_SCREEN_BUFFER Buff = Console->ActiveBuffer;
LONG CursorEndX, CursorEndY;
RECT ScrollRect;
if (NULL == Console->hWindow || NULL == GuiData)
{
return;
}
if (0 != ScrolledLines)
{
ScrollRect.left = 0;
ScrollRect.top = 0;
ScrollRect.right = Console->Size.X * GuiData->CharWidth;
ScrollRect.bottom = Region->top * GuiData->CharHeight;
if (GuiData->Selection.left != -1)
{
/* scroll the selection */
if (GuiData->Selection.top > ScrolledLines)
{
GuiData->Selection.top -= ScrolledLines;
GuiData->Selection.bottom -= ScrolledLines;
}
else if (GuiData->Selection.bottom < ScrolledLines)
{
GuiData->Selection.left = -1;
}
else
{
GuiData->Selection.top = 0;
GuiData->Selection.bottom -= ScrolledLines;
}
}
ScrollWindowEx(Console->hWindow,
0,
-(ScrolledLines * GuiData->CharHeight),
&ScrollRect,
NULL,
NULL,
NULL,
SW_INVALIDATE);
}
GuiIntDrawRegion(GuiData, Console->hWindow, Region);
if (CursorStartX < Region->left || Region->right < CursorStartX
|| CursorStartY < Region->top || Region->bottom < CursorStartY)
{
GuiInvalidateCell(GuiData, Console->hWindow, CursorStartX, CursorStartY);
}
ConioPhysicalToLogical(Buff, Buff->CurrentX, Buff->CurrentY,
&CursorEndX, &CursorEndY);
if ((CursorEndX < Region->left || Region->right < CursorEndX
|| CursorEndY < Region->top || Region->bottom < CursorEndY)
&& (CursorEndX != CursorStartX || CursorEndY != CursorStartY))
{
GuiInvalidateCell(GuiData, Console->hWindow, CursorEndX, CursorEndY);
}
}
static BOOL STDCALL
GuiSetCursorInfo(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER Buff)
{
RECT UpdateRect;
if (Console->ActiveBuffer == Buff)
{
ConioPhysicalToLogical(Buff, Buff->CurrentX, Buff->CurrentY,
&UpdateRect.left, &UpdateRect.top);
UpdateRect.right = UpdateRect.left;
UpdateRect.bottom = UpdateRect.top;
ConioDrawRegion(Console, &UpdateRect);
}
return TRUE;
}
static BOOL STDCALL
GuiSetScreenInfo(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER Buff, UINT OldCursorX, UINT OldCursorY)
{
RECT UpdateRect;
if (Console->ActiveBuffer == Buff)
{
/* Redraw char at old position (removes cursor) */
UpdateRect.left = OldCursorX;
UpdateRect.top = OldCursorY;
UpdateRect.right = OldCursorX;
UpdateRect.bottom = OldCursorY;
ConioDrawRegion(Console, &UpdateRect);
/* Redraw char at new position (shows cursor) */
ConioPhysicalToLogical(Buff, Buff->CurrentX, Buff->CurrentY,
&(UpdateRect.left), &(UpdateRect.top));
UpdateRect.right = UpdateRect.left;
UpdateRect.bottom = UpdateRect.top;
ConioDrawRegion(Console, &UpdateRect);
}
return TRUE;
}
static VOID FASTCALL
GuiConsoleHandleTimer(HWND hWnd)
{
PCSRSS_CONSOLE Console;
PGUI_CONSOLE_DATA GuiData;
RECT CursorRect;
ULONG CursorX, CursorY;
GuiConsoleGetDataPointers(hWnd, &Console, &GuiData);
GuiData->CursorBlinkOn = ! GuiData->CursorBlinkOn;
GuiConsoleGetLogicalCursorPos(Console->ActiveBuffer, &CursorX, &CursorY);
CursorRect.left = CursorX;
CursorRect.top = CursorY;
CursorRect.right = CursorX;
CursorRect.bottom = CursorY;
GuiDrawRegion(Console, &CursorRect);
}
static VOID FASTCALL
GuiConsoleHandleClose(HWND hWnd)
{
PCSRSS_CONSOLE Console;
PGUI_CONSOLE_DATA GuiData;
PLIST_ENTRY current_entry;
PCSRSS_PROCESS_DATA current;
GuiConsoleGetDataPointers(hWnd, &Console, &GuiData);
EnterCriticalSection(&Console->Header.Lock);
current_entry = Console->ProcessList.Flink;
while (current_entry != &Console->ProcessList)
{
current = CONTAINING_RECORD(current_entry, CSRSS_PROCESS_DATA, ProcessEntry);
current_entry = current_entry->Flink;
ConioConsoleCtrlEvent(CTRL_CLOSE_EVENT, current);
}
LeaveCriticalSection(&Console->Header.Lock);
}
static VOID FASTCALL
GuiConsoleHandleNcDestroy(HWND hWnd)
{
PCSRSS_CONSOLE Console;
PGUI_CONSOLE_DATA GuiData;
GuiConsoleGetDataPointers(hWnd, &Console, &GuiData);
KillTimer(hWnd, 1);
Console->PrivateData = NULL;
DeleteCriticalSection(&GuiData->Lock);
GetSystemMenu(hWnd, TRUE);
if (GuiData->ConsoleLibrary)
FreeLibrary(GuiData->ConsoleLibrary);
HeapFree(Win32CsrApiHeap, 0, GuiData);
}
static VOID FASTCALL
GuiConsoleLeftMouseDown(HWND hWnd, LPARAM lParam)
{
PCSRSS_CONSOLE Console;
PGUI_CONSOLE_DATA GuiData;
POINTS pt;
RECT rc;
GuiConsoleGetDataPointers(hWnd, &Console, &GuiData);
if (Console == NULL || GuiData == NULL) return;
pt = MAKEPOINTS(lParam);
rc.left = pt.x / GuiData->CharWidth;
rc.top = pt.y / GuiData->CharHeight;
rc.right = rc.left + 1;
rc.bottom = rc.top + 1;
GuiData->SelectionStart.x = rc.left;
GuiData->SelectionStart.y = rc.top;
SetCapture(hWnd);
GuiData->MouseDown = TRUE;
GuiConsoleUpdateSelection(hWnd, &rc, GuiData);
}
static VOID FASTCALL
GuiConsoleLeftMouseUp(HWND hWnd, LPARAM lParam)
{
PCSRSS_CONSOLE Console;
PGUI_CONSOLE_DATA GuiData;
RECT rc;
POINTS pt;
GuiConsoleGetDataPointers(hWnd, &Console, &GuiData);
if (Console == NULL || GuiData == NULL) return;
if (GuiData->Selection.left == -1 || !GuiData->MouseDown) return;
pt = MAKEPOINTS(lParam);
rc.left = GuiData->SelectionStart.x;
rc.top = GuiData->SelectionStart.y;
rc.right = (pt.x >= 0 ? (pt.x / GuiData->CharWidth) + 1 : 0);
rc.bottom = (pt.y >= 0 ? (pt.y / GuiData->CharHeight) + 1 : 0);
/* exchange left/top with right/bottom if required */
if(rc.left >= rc.right)
{
LONG tmp;
tmp = rc.left;
rc.left = max(rc.right - 1, 0);
rc.right = tmp + 1;
}
if(rc.top >= rc.bottom)
{
LONG tmp;
tmp = rc.top;
rc.top = max(rc.bottom - 1, 0);
rc.bottom = tmp + 1;
}
GuiData->MouseDown = FALSE;
GuiConsoleUpdateSelection(hWnd, &rc, GuiData);
ReleaseCapture();
}
static VOID FASTCALL
GuiConsoleMouseMove(HWND hWnd, WPARAM wParam, LPARAM lParam)
{
PCSRSS_CONSOLE Console;
PGUI_CONSOLE_DATA GuiData;
RECT rc;
POINTS pt;
if (!(wParam & MK_LBUTTON)) return;
GuiConsoleGetDataPointers(hWnd, &Console, &GuiData);
if (Console == NULL || GuiData == NULL || !GuiData->MouseDown) return;
pt = MAKEPOINTS(lParam);
rc.left = GuiData->SelectionStart.x;
rc.top = GuiData->SelectionStart.y;
rc.right = (pt.x >= 0 ? (pt.x / GuiData->CharWidth) + 1 : 0);
if (Console->Size.X < rc.right)
{
rc.right = Console->Size.X;
}
rc.bottom = (pt.y >= 0 ? (pt.y / GuiData->CharHeight) + 1 : 0);
if (Console->Size.Y < rc.bottom)
{
rc.bottom = Console->Size.Y;
}
/* exchange left/top with right/bottom if required */
if(rc.left >= rc.right)
{
LONG tmp;
tmp = rc.left;
rc.left = max(rc.right - 1, 0);
rc.right = tmp + 1;
}
if(rc.top >= rc.bottom)
{
LONG tmp;
tmp = rc.top;
rc.top = max(rc.bottom - 1, 0);
rc.bottom = tmp + 1;
}
GuiConsoleUpdateSelection(hWnd, &rc, GuiData);
}
static VOID FASTCALL
GuiConsoleRightMouseDown(HWND hWnd)
{
PCSRSS_CONSOLE Console;
PGUI_CONSOLE_DATA GuiData;
GuiConsoleGetDataPointers(hWnd, &Console, &GuiData);
if (Console == NULL || GuiData == NULL) return;
if (GuiData->Selection.left == -1)
{
/* FIXME - paste text from clipboard */
}
else
{
/* FIXME - copy selection to clipboard */
GuiConsoleUpdateSelection(hWnd, NULL, GuiData);
}
}
static VOID
GuiConsoleShowConsoleProperties(HWND hWnd, BOOL Defaults, PGUI_CONSOLE_DATA GuiData)
{
PCSRSS_CONSOLE Console;
APPLET_PROC CPLFunc;
TCHAR szBuffer[MAX_PATH];
ConsoleInfo SharedInfo;
DPRINT("GuiConsoleShowConsoleProperties entered\n");
GuiConsoleGetDataPointers(hWnd, &Console, &GuiData);
if (GuiData == NULL)
{
DPRINT("GuiConsoleGetDataPointers failed\n");
return;
}
if (GuiData->ConsoleLibrary == NULL)
{
GetWindowsDirectory(szBuffer,MAX_PATH);
_tcscat(szBuffer, _T("\\system32\\console.dll"));
GuiData->ConsoleLibrary = LoadLibrary(szBuffer);
if (GuiData->ConsoleLibrary == NULL)
{
DPRINT1("failed to load console.dll");
return;
}
}
CPLFunc = (APPLET_PROC) GetProcAddress(GuiData->ConsoleLibrary, _T("CPlApplet"));
if (!CPLFunc)
{
DPRINT("Error: Console.dll misses CPlApplet export\n");
return;
}
/* setup struct */
SharedInfo.InsertMode = GuiData->InsertMode;
SharedInfo.HistoryBufferSize = GuiData->HistoryBufferSize;
SharedInfo.NumberOfHistoryBuffers = GuiData->NumberOfHistoryBuffers;
SharedInfo.ScreenText = GuiData->ScreenText;
SharedInfo.ScreenBackground = GuiData->ScreenBackground;
SharedInfo.PopupText = GuiData->PopupText;
SharedInfo.PopupBackground = GuiData->PopupBackground;
SharedInfo.WindowSize = (DWORD)MAKELONG(Console->Size.X, Console->Size.Y);
SharedInfo.WindowPosition = GuiData->WindowPosition;
SharedInfo.ScreenBuffer = GuiData->ScreenBufferSize;
SharedInfo.UseRasterFonts = GuiData->UseRasterFonts;
SharedInfo.FontSize = (DWORD)GuiData->FontSize;
SharedInfo.FontWeight = GuiData->FontWeight;
SharedInfo.CursorSize = Console->ActiveBuffer->CursorInfo.dwSize;
SharedInfo.HistoryNoDup = GuiData->HistoryNoDup;
SharedInfo.FullScreen = GuiData->FullScreen;
SharedInfo.QuickEdit = GuiData->QuickEdit;
memcpy(&SharedInfo.Colors[0], GuiData->Colors, sizeof(s_Colors));
if (!CPLFunc(hWnd, CPL_INIT, 0, 0))
{
DPRINT("Error: failed to initialize console.dll\n");
return;
}
if (CPLFunc(hWnd, CPL_GETCOUNT, 0, 0) != 1)
{
DPRINT("Error: console.dll returned unexpected CPL count\n");
return;
}
CPLFunc(hWnd, CPL_DBLCLK, (LPARAM)&SharedInfo, Defaults);
}
static LRESULT FASTCALL
GuiConsoleHandleSysMenuCommand(HWND hWnd, WPARAM wParam, LPARAM lParam, PGUI_CONSOLE_DATA GuiData)
{
LRESULT Ret = TRUE;
switch(wParam)
{
case ID_SYSTEM_EDIT_MARK:
case ID_SYSTEM_EDIT_COPY:
case ID_SYSTEM_EDIT_PASTE:
case ID_SYSTEM_EDIT_SELECTALL:
case ID_SYSTEM_EDIT_SCROLL:
case ID_SYSTEM_EDIT_FIND:
break;
case ID_SYSTEM_DEFAULTS:
GuiConsoleShowConsoleProperties(hWnd, TRUE, GuiData);
break;
case ID_SYSTEM_PROPERTIES:
GuiConsoleShowConsoleProperties(hWnd, FALSE, GuiData);
break;
default:
Ret = DefWindowProcW(hWnd, WM_SYSCOMMAND, wParam, lParam);
break;
}
return Ret;
}
static VOID FASTCALL
GuiConsoleResize(HWND hWnd, WPARAM wParam, LPARAM lParam)
{
PCSRSS_CONSOLE Console;
PGUI_CONSOLE_DATA GuiData;
GuiConsoleGetDataPointers(hWnd, &Console, &GuiData);
if (wParam == SIZE_RESTORED || wParam == SIZE_MAXIMIZED || wParam == SIZE_MINIMIZED)
{
DPRINT1("GuiConsoleResize X %d Y %d\n", LOWORD(lParam), HIWORD(lParam));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -