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

📄 guiconsole.c

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