简体   繁体   中英

Windows Console API Functions reattach to the console

I am wanting to implement functionality for

dir | editor

This requires that the text be read from GetStdHandle( STD_INPUT_HANDLE )

and then that the standard input be closed and standard input be attached to the keyboard.

I have found no way to attach the current window to the keyboard but I can create a new window and then use that.

Unfortunately I have not been able to control the size of that window.

The code I am using is below but currently I get

SCSBerr 87.

The app runs but initially it looks like this

Window initially

When the window is resized it looks like this

Window Resized

The Environment is Visual Studio 6.0 on Windows 10 and Visual Studio 2019 on Windows 10 (same result).

{ BOOL rc;
  RECT rect;
  SMALL_RECT sr;
  CONSOLE_SCREEN_BUFFER_INFO sbi;
  COORD sz;
  char buf[80];

  if (term.t_nrowm1 >= csbiInfoO.dwSize.Y)
    term.t_nrowm1 = csbiInfoO.dwSize.Y - 1;
  if (term.t_ncol > csbiInfoO.dwSize.X)
    term.t_ncol = csbiInfoO.dwSize.X;
//if (term.t_ncol > 80)
//  term.t_ncol = 80;
   
  sr.Left = 0+0;
  sr.Top = 0+3;
  sr.Right = 0+term.t_ncol-1;
  sr.Bottom = 0+term.t_nrowm1-3/* say */;
  sz.X = term.t_ncol;
  sz.Y = term.t_nrowm1+1;

//sprintf(buf, "RowM1 %d Col %d", term.t_nrowm1, term.t_ncol);
//mbwrite(buf);

  origwin = GetForegroundWindow();
 
  GetWindowRect(origwin, &rect); 

  g_ConsoleOut = GetStdHandle( STD_OUTPUT_HANDLE );
  if (GetConsoleScreenBufferInfo(g_ConsoleOut, &sbi) == 0)
    flagerr("SCGCSBIErr %d");
#if 1
  FreeConsole();
//if (AttachConsole((DWORD)-1) == 0)
//   flagerr("SCAC%d");

  if (AllocConsole() == 0)
    flagerr("SCAllocErr %d");
#endif
  g_ConsoleIn = GetStdHandle( STD_INPUT_HANDLE );
  if (g_ConsoleIn < 0)                                      /* INVALID_HANDLE_VALUE */
    flagerr("Piperr %d");
  g_ConsoleOut = GetStdHandle( STD_OUTPUT_HANDLE );

//flagerr("HConsoleOut %d", g_ConsoleOut);

  if (SetConsoleScreenBufferSize(g_ConsoleOut, sbi.dwMaximumWindowSize) == 0)
    flagerr("SCSBerr %d");
  if (SetConsoleWindowInfo(g_ConsoleOut, true, &sr) == 0)
    flagerr("SCWIEerr %d");

  //SetConsoleTitle("Debug Window");

  SetConsoleCtrlHandler(MyHandlerRoutine, true);

{ HWND mwh = GetForegroundWindow();
  if (mwh == NULL)
    flagerr("MwHerr %d");

{ Cc cc = SetWindowPos(mwh, HWND_TOP, 10,10,
//           ((GetSystemMetrics(SM_CXSCREEN) - (rc.right - rc.left)) / 2),
//           ((GetSystemMetrics(SM_CYSCREEN) - (rc.bottom - rc.top)) / 2), 
                                 0, 0, SWP_NOSIZE /*| SWP_NOACTIVATE*/); 
  if (cc == 0)
    flagerr("SwPerr %d");
}}}

I have found no way to attach the current window to the keyboard

The interactive console's buffer is available as CONIN$ , even when the standard handle is redirected. The following snippet waits until the standard input stream ends (via Ctrl-Z, or end of piped input), then repoints stdin to CONIN$ .

#include <windows.h>
#include <io.h>
#include <fcntl.h>
#include <stdio.h>

int main()
{
    char sz[256];

    while(fgets(sz, sizeof(sz), stdin))
        fputs(sz, stdout);
    printf("finished stdin\nstarting conin$\n\n");

    SECURITY_ATTRIBUTES sa = { sizeof(SECURITY_ATTRIBUTES), NULL, TRUE };
    HANDLE h = CreateFile("CONIN$",
                          GENERIC_READ | GENERIC_WRITE,
                          FILE_SHARE_READ | FILE_SHARE_WRITE,
                          &sa,
                          OPEN_EXISTING,
                          0, NULL); // ignored
    if(h == INVALID_HANDLE_VALUE || !SetStdHandle(STD_INPUT_HANDLE, h))
        return GetLastError();

    int n = _open_osfhandle((intptr_t)h, _O_RDONLY | _O_TEXT);
    if(n == -1 || _dup2(n, _fileno(stdin)))
        return errno;

    printf("type a short string\n");
    if(scanf("%s", sz) == 1)
        printf("read '%s' ...done\n", sz);

    // todo: cleanup
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM