guiconsole.c
来自「一个类似windows」· C语言 代码 · 共 1,107 行 · 第 1/3 页
C
1,107 行
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 LRESULT CALLBACK
GuiConsoleWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
LRESULT Result = 0;
switch(msg)
{
case WM_NCCREATE:
Result = (LRESULT) GuiConsoleHandleNcCreate(hWnd, (CREATESTRUCTW *) lParam);
break;
case WM_PAINT:
GuiConsoleHandlePaint(hWnd, (HDC)wParam);
break;
case WM_KEYDOWN:
case WM_KEYUP:
case WM_SYSKEYDOWN:
case WM_SYSKEYUP:
case WM_CHAR:
GuiConsoleHandleKey(hWnd, msg, wParam, lParam);
break;
case WM_TIMER:
GuiConsoleHandleTimer(hWnd);
break;
case WM_CLOSE:
GuiConsoleHandleClose(hWnd);
break;
case WM_NCDESTROY:
GuiConsoleHandleNcDestroy(hWnd);
break;
case WM_LBUTTONDOWN:
GuiConsoleLeftMouseDown(hWnd, lParam);
break;
case WM_LBUTTONUP:
GuiConsoleLeftMouseUp(hWnd, lParam);
break;
case WM_RBUTTONDOWN:
GuiConsoleRightMouseDown(hWnd);
break;
case WM_MOUSEMOVE:
GuiConsoleMouseMove(hWnd, wParam, lParam);
break;
default:
Result = DefWindowProcW(hWnd, msg, wParam, lParam);
break;
}
return Result;
}
static LRESULT CALLBACK
GuiConsoleNotifyWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
HWND NewWindow;
LONG WindowCount;
MSG Msg;
PWCHAR Buffer, Title;
PCSRSS_CONSOLE Console = (PCSRSS_CONSOLE) lParam;
switch(msg)
{
case WM_CREATE:
SetWindowLongW(hWnd, GWL_USERDATA, 0);
return 0;
case PM_CREATE_CONSOLE:
Buffer = HeapAlloc(Win32CsrApiHeap, 0,
Console->Title.Length + sizeof(WCHAR));
if (NULL != Buffer)
{
memcpy(Buffer, Console->Title.Buffer, Console->Title.Length);
Buffer[Console->Title.Length / sizeof(WCHAR)] = L'\0';
Title = Buffer;
}
else
{
Title = L"";
}
NewWindow = CreateWindowW(L"ConsoleWindowClass",
Title,
WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL,
NULL,
(HINSTANCE) GetModuleHandleW(NULL),
(PVOID) Console);
if (NULL != Buffer)
{
HeapFree(Win32CsrApiHeap, 0, Buffer);
}
Console->hWindow = NewWindow;
if (NULL != NewWindow)
{
SetWindowLongW(hWnd, GWL_USERDATA, GetWindowLongW(hWnd, GWL_USERDATA) + 1);
ShowWindow(NewWindow, SW_SHOW);
}
return (LRESULT) NewWindow;
case PM_DESTROY_CONSOLE:
/* Window creation is done using a PostMessage(), so it's possible that the
* window that we want to destroy doesn't exist yet. So first empty the message
* queue */
while(PeekMessageW(&Msg, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage(&Msg);
DispatchMessageW(&Msg);
}
DestroyWindow(Console->hWindow);
Console->hWindow = NULL;
WindowCount = GetWindowLongW(hWnd, GWL_USERDATA);
WindowCount--;
SetWindowLongW(hWnd, GWL_USERDATA, WindowCount);
if (0 == WindowCount)
{
NotifyWnd = NULL;
DestroyWindow(hWnd);
PrivateCsrssManualGuiCheck(-1);
PostQuitMessage(0);
}
return 0;
default:
return DefWindowProcW(hWnd, msg, wParam, lParam);
}
}
static DWORD STDCALL
GuiConsoleGuiThread(PVOID Data)
{
MSG msg;
PHANDLE GraphicsStartupEvent = (PHANDLE) Data;
NotifyWnd = CreateWindowW(L"Win32CsrCreateNotify",
L"",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL,
NULL,
(HINSTANCE) GetModuleHandleW(NULL),
NULL);
if (NULL == NotifyWnd)
{
PrivateCsrssManualGuiCheck(-1);
SetEvent(*GraphicsStartupEvent);
return 1;
}
SetEvent(*GraphicsStartupEvent);
while(GetMessageW(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessageW(&msg);
}
return 1;
}
static BOOL FASTCALL
GuiInit(VOID)
{
WNDCLASSEXW wc;
if (NULL == NotifyWnd)
{
PrivateCsrssManualGuiCheck(+1);
}
wc.cbSize = sizeof(WNDCLASSEXW);
wc.lpszClassName = L"Win32CsrCreateNotify";
wc.lpfnWndProc = GuiConsoleNotifyWndProc;
wc.style = 0;
wc.hInstance = (HINSTANCE) GetModuleHandleW(NULL);
wc.hIcon = NULL;
wc.hCursor = NULL;
wc.hbrBackground = NULL;
wc.lpszMenuName = NULL;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hIconSm = NULL;
if (RegisterClassExW(&wc) == 0)
{
DPRINT1("Failed to register notify wndproc\n");
return FALSE;
}
wc.cbSize = sizeof(WNDCLASSEXW);
wc.lpszClassName = L"ConsoleWindowClass";
wc.lpfnWndProc = GuiConsoleWndProc;
wc.style = 0;
wc.hInstance = (HINSTANCE) GetModuleHandleW(NULL);
wc.hIcon = LoadIconW(Win32CsrDllHandle, MAKEINTRESOURCEW(1));
wc.hCursor = LoadCursorW(NULL, MAKEINTRESOURCEW(IDC_ARROW));
wc.hbrBackground = NULL;
wc.lpszMenuName = NULL;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hIconSm = LoadImageW(Win32CsrDllHandle, MAKEINTRESOURCEW(1), IMAGE_ICON,
GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON),
LR_SHARED);
if (RegisterClassExW(&wc) == 0)
{
DPRINT1("Failed to register console wndproc\n");
return FALSE;
}
return TRUE;
}
static VOID STDCALL
GuiInitScreenBuffer(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER Buffer)
{
Buffer->DefaultAttrib = 0x0f;
}
static BOOL STDCALL
GuiChangeTitle(PCSRSS_CONSOLE Console)
{
PWCHAR Buffer, Title;
Buffer = HeapAlloc(Win32CsrApiHeap, 0,
Console->Title.Length + sizeof(WCHAR));
if (NULL != Buffer)
{
memcpy(Buffer, Console->Title.Buffer, Console->Title.Length);
Buffer[Console->Title.Length / sizeof(WCHAR)] = L'\0';
Title = Buffer;
}
else
{
Title = L"";
}
SendMessageW(Console->hWindow, WM_SETTEXT, 0, (LPARAM) Title);
if (NULL != Buffer)
{
HeapFree(Win32CsrApiHeap, 0, Buffer);
}
return TRUE;
}
static BOOL STDCALL
GuiChangeIcon(PCSRSS_CONSOLE Console)
{
SendMessageW(Console->hWindow, WM_SETICON, ICON_BIG, (LPARAM)Console->hWindowIcon);
SendMessageW(Console->hWindow, WM_SETICON, ICON_SMALL, (LPARAM)Console->hWindowIcon);
return TRUE;
}
static VOID STDCALL
GuiCleanupConsole(PCSRSS_CONSOLE Console)
{
SendMessageW(NotifyWnd, PM_DESTROY_CONSOLE, 0, (LPARAM) Console);
}
static CSRSS_CONSOLE_VTBL GuiVtbl =
{
GuiInitScreenBuffer,
GuiWriteStream,
GuiDrawRegion,
GuiSetCursorInfo,
GuiSetScreenInfo,
GuiChangeTitle,
GuiCleanupConsole,
GuiChangeIcon
};
NTSTATUS FASTCALL
GuiInitConsole(PCSRSS_CONSOLE Console)
{
HANDLE GraphicsStartupEvent;
HANDLE ThreadHandle;
if (! ConsInitialized)
{
ConsInitialized = TRUE;
if (! GuiInit())
{
ConsInitialized = FALSE;
return STATUS_UNSUCCESSFUL;
}
}
Console->Vtbl = &GuiVtbl;
Console->Size.X = 80;
Console->Size.Y = 25;
if (NULL == NotifyWnd)
{
GraphicsStartupEvent = CreateEventW(NULL, FALSE, FALSE, NULL);
if (NULL == GraphicsStartupEvent)
{
return STATUS_UNSUCCESSFUL;
}
ThreadHandle = CreateThread(NULL,
0,
GuiConsoleGuiThread,
(PVOID) &GraphicsStartupEvent,
0,
NULL);
if (NULL == ThreadHandle)
{
NtClose(GraphicsStartupEvent);
DPRINT1("Win32Csr: Failed to create graphics console thread. Expect problems\n");
return STATUS_UNSUCCESSFUL;
}
SetThreadPriority(ThreadHandle, THREAD_PRIORITY_HIGHEST);
CloseHandle(ThreadHandle);
WaitForSingleObject(GraphicsStartupEvent, INFINITE);
CloseHandle(GraphicsStartupEvent);
if (NULL == NotifyWnd)
{
DPRINT1("Win32Csr: Failed to create notification window.\n");
return STATUS_UNSUCCESSFUL;
}
}
PostMessageW(NotifyWnd, PM_CREATE_CONSOLE, 0, (LPARAM) Console);
return STATUS_SUCCESS;
}
/* EOF */
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?