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

📄 guiconsole.c

📁 这是一个开放源代码的与WINNT/WIN2K/WIN2003兼容的操作系统
💻 C
📖 第 1 页 / 共 4 页
字号:
                    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 + -