⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 guiconsole.c

📁 这是一个开放源代码的与WINNT/WIN2K/WIN2003兼容的操作系统
💻 C
📖 第 1 页 / 共 4 页
字号:
  }
}

VOID FASTCALL
GuiConsoleCreateScrollBar(PCSRSS_CONSOLE Console, PGUI_CONSOLE_DATA GuiData, HWND NewWindow)
{
  HMENU hMenu;
  HWND hVScrollBar;
  HWND hHScrollBar;
  SCROLLINFO sInfo;

  hMenu = CreatePopupMenu();
  if (hMenu == NULL)
    {
      DPRINT("CreatePopupMenu failed\n");
      return;
    }

  //InsertItem(hMenu, MIIM_STRING, MIIM_ID | MIIM_FTYPE | MIIM_STRING, 0, NULL, IDS_SCROLLHERE);
  //InsertItem(hMenu, MFT_SEPARATOR, MIIM_FTYPE, 0, NULL, -1);
  //InsertItem(hMenu, MIIM_STRING, MIIM_ID | MIIM_FTYPE | MIIM_STRING, 0, NULL, IDS_SCROLLTOP);
  //InsertItem(hMenu, MIIM_STRING, MIIM_ID | MIIM_FTYPE | MIIM_STRING, 0, NULL, IDS_SCROLLBOTTOM);
  //InsertItem(hMenu, MFT_SEPARATOR, MIIM_FTYPE, 0, NULL, -1);
  //InsertItem(hMenu, MIIM_STRING, MIIM_ID | MIIM_FTYPE | MIIM_STRING, 0, NULL, IDS_SCROLLPAGE_UP);
  //InsertItem(hMenu, MIIM_STRING, MIIM_ID | MIIM_FTYPE | MIIM_STRING, 0, NULL, IDS_SCROLLPAGE_DOWN);
  //InsertItem(hMenu, MFT_SEPARATOR, MIIM_FTYPE, 0, NULL, -1);
  //InsertItem(hMenu, MIIM_STRING, MIIM_ID | MIIM_FTYPE | MIIM_STRING, 0, NULL, IDS_SCROLLUP);
  //InsertItem(hMenu, MIIM_STRING, MIIM_ID | MIIM_FTYPE | MIIM_STRING, 0, NULL, IDS_SCROLLDOWN);
  
  hVScrollBar = CreateWindowExW(0L,
                                L"ScrollBar",
                                (LPWSTR)NULL,
                                WS_CHILD | WS_VSCROLL,
                                0,
                                0,
                                200,
                                50,
                                NewWindow,
                                NULL, //hMenu,
                                GetModuleHandleW(NULL),
                                (LPVOID)GuiData);

  if (hVScrollBar)
    {

      /* set scrollbar sizes */
      sInfo.cbSize = sizeof(SCROLLINFO);
      sInfo.fMask = SIF_RANGE | SIF_POS;
      sInfo.nMin = 0;
      sInfo.nMax = Console->ActiveBuffer->MaxY;
	  sInfo.nPos = 0;
      SetScrollInfo(hVScrollBar, SB_CTL, &sInfo, TRUE);
      ShowScrollBar(NewWindow, SB_CTL, TRUE);
	  GuiData->hVScrollBar = hVScrollBar;
    }
 
  if (Console->ActiveBuffer->MaxX > Console->Size.X)
    {
      hHScrollBar = CreateWindowExW(0L,
                                    L"ScrollBar",
                                    (LPWSTR)NULL,
                                    WS_CHILD | WS_HSCROLL,
                                    0,
                                    0,
                                    200,
                                    CW_USEDEFAULT,
                                    NewWindow,
                                    hMenu,
                                    GetModuleHandleW(NULL),
                                   (LPVOID)GuiData);
      if (hHScrollBar)
        {
          sInfo.nMax = Console->ActiveBuffer->MaxX;
          SetScrollInfo(hHScrollBar, SB_CTL, &sInfo, TRUE);
          GuiData->hHScrollBar = hHScrollBar;
        }
    }
}

static VOID FASTCALL
GuiApplyUserSettings(PCSRSS_CONSOLE Console, PGUI_CONSOLE_DATA GuiData, PConsoleInfo pConInfo)
{
  DWORD windx, windy;
  RECT rect;
    
  /* apply text / background color */
  GuiData->ScreenText = pConInfo->ScreenText;
  GuiData->ScreenBackground = pConInfo->ScreenBackground;

  /* apply cursor size */
  Console->ActiveBuffer->CursorInfo.dwSize = max(min(pConInfo->CursorSize, 1), 100);

  windx = LOWORD(pConInfo->ScreenBuffer);
  windy = HIWORD(pConInfo->ScreenBuffer);

  if (windx != Console->ActiveBuffer->MaxX || windy != Console->ActiveBuffer->MaxY)
  {
    //
    // TODO
    // resize screen buffer


    // Console->ActiveBuffer->MaxX = windx;
    // Console->ActiveBuffer->MaxY = windy;
  }

  windx = LOWORD(pConInfo->WindowSize);
  windy = HIWORD(pConInfo->WindowSize);

  if (windx != Console->Size.X || windy != Console->Size.Y)
  {
      /* resize window */
      Console->Size.X = windx;
      Console->Size.Y = windy;

      GetWindowRect(pConInfo->hConsoleWindow, &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(pConInfo->hConsoleWindow, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, FALSE);

      if (Console->Size.X < Console->ActiveBuffer->MaxX)
      {
          /* show scrollbar when window becomes smaller than active screen buffer */
          //ShowScrollBar(GuiData->hHScrollBar, SB_CTL, TRUE);
      }
      else
      {
          /* hide scrollbar */
          //ShowScrollBar(GuiData->hHScrollBar, SB_CTL, FALSE);
      }
  }
  /* repaint window */
  InvalidateRect(pConInfo->hConsoleWindow, NULL, TRUE);
}

static LRESULT CALLBACK
GuiConsoleWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
  LRESULT Result = 0;
  PGUI_CONSOLE_DATA GuiData = NULL;
  PCSRSS_CONSOLE Console = NULL;

  GuiConsoleGetDataPointers(hWnd, &Console, &GuiData);

  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;
      case WM_SYSCOMMAND:
          Result = GuiConsoleHandleSysMenuCommand(hWnd, wParam, lParam, GuiData);
          break;
      case WM_SIZE:
          GuiConsoleResize(hWnd, wParam, lParam);
          break;
      case PM_APPLY_CONSOLE_INFO:
          GuiApplyUserSettings(Console, GuiData, (PConsoleInfo)wParam);
          if (lParam)
            {
              GuiConsoleWriteUserSettings(Console, GuiData);
            }
          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, //WS_OVERLAPPEDWINDOW
                                  CW_USEDEFAULT,
                                  CW_USEDEFAULT,
                                  CW_USEDEFAULT,
                                  CW_USEDEFAULT,
                                  NULL,
                                  NULL,
                                  (HINSTANCE) GetModuleHandleW(NULL),
                                  (PVOID) Console);
        if (NULL != Buffer)
          {
            HeapFree(Win32CsrApiHeap, 0, Buffer);
          }
        if (NULL != NewWindow)
          {
            // scrollbar support
            //GuiConsoleCreateScrollBar(Console, (PGUI_CONSOLE_DATA)Console->PrivateData, 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, (LPCWSTR) 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 = DEFAULT_ATTRIB;
}

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;
  PGUI_CONSOLE_DATA GuiData;

  if (! ConsInitialized)
    {
      ConsInitialized = TRUE;
      if (! GuiInit())
        {
          ConsInitialized = FALSE;
          return STATUS_UNSUCCESSFUL;
        }
    }

  Console->Vtbl = &GuiVtbl;
  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;
        }
    }
    GuiData = HeapAlloc(Win32CsrApiHeap, HEAP_ZERO_MEMORY,
                        sizeof(GUI_CONSOLE_DATA));
    if (!GuiData)
      {
        DPRINT1("Win32Csr: Failed to create GUI_CONSOLE_DATA\n");
        return STATUS_UNSUCCESSFUL;
      }

    Console->PrivateData = (PVOID) GuiData;
    /*
     * we need to wait untill the GUI has been fully initialized
     * to retrieve custom settings i.e. WindowSize etc..
     * Ideally we could use SendNotifyMessage for this but its not
     * yet implemented.
     *
     */
    GuiData->hGuiInitEvent = CreateEventW(NULL, FALSE, FALSE, NULL);
    /* create console */
    PostMessageW(NotifyWnd, PM_CREATE_CONSOLE, 0, (LPARAM) Console);

    /* wait untill initialization has finished */
    WaitForSingleObject(GuiData->hGuiInitEvent, INFINITE);
    DPRINT1("received event Console %p GuiData %p X %d Y %d\n", Console, Console->PrivateData, Console->Size.X, Console->Size.Y);
    CloseHandle(GuiData->hGuiInitEvent);
    GuiData->hGuiInitEvent = NULL;

  return STATUS_SUCCESS;
}

/* EOF */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -