wchar_t* Console::ReadStdOut(int nb, const CONSOLE_SCREEN_BUFFER_INFO &gCSI, const SMALL_RECT &gSelectRect) { COORD size = { (short)CSI_WndCols(&gCSI), (short)1 }; std::vector<CHAR_INFO> work(size.X); COORD pos = { 0,0 }; SMALL_RECT sr = { gCSI.srWindow.Left, 0, gCSI.srWindow.Right, 0 }; wchar_t* buffer = new wchar_t[ nb +32 ]; wchar_t* wp = buffer; *wp = 0; if(gSelectRect.Top == gSelectRect.Bottom) { sr.Top = sr.Bottom = gSelectRect.Top; ReadConsoleOutput_Unicode(&work[0], size, pos, &sr); copyChar(wp, &work[0], gSelectRect.Left, gSelectRect.Right-1, false); } else { sr.Top = sr.Bottom = gSelectRect.Top; ReadConsoleOutput_Unicode(&work[0], size, pos, &sr); copyChar(wp, &work[0], gSelectRect.Left, gCSI.srWindow.Right); for(int y = gSelectRect.Top+1 ; y <= gSelectRect.Bottom-1 ; y++) { sr.Top = sr.Bottom = y; ReadConsoleOutput_Unicode(&work[0], size, pos, &sr); copyChar(wp, &work[0], gCSI.srWindow.Left, gCSI.srWindow.Right); } sr.Top = sr.Bottom = gSelectRect.Bottom; ReadConsoleOutput_Unicode(&work[0], size, pos, &sr); copyChar(wp, &work[0], gCSI.srWindow.Left, gSelectRect.Right-1, false); } return (buffer); }
/* (craftware) */ wchar_t * getAllString() { int nb; nb = gCSI->dwSize.X * gCSI->dwSize.Y; COORD size = { gCSI->dwSize.X, 1 }; CHAR_INFO* work = new CHAR_INFO[ gCSI->dwSize.X ]; wchar_t* buffer = new wchar_t[ nb ]; wchar_t* wp = buffer; COORD pos = { 0,0 }; SMALL_RECT sr = { 0, 0, gCSI->dwSize.X-1, 0 }; *wp = 0; for( int y=0 ; y<gCSI->dwSize.Y ; ++y ) { sr.Top = sr.Bottom = y; ReadConsoleOutput_Unicode(gStdOut, work, size, pos, &sr); copyChar( wp, work, 0, gCSI->dwSize.X-1 ); } delete [] work; return(buffer); }
// window resizeが必要な場合にtrueを返す bool Console::onTimer(HWND hWnd, bool gVScrollHide, int *w, int *h) { if(WaitForSingleObject(gChild, 0) != WAIT_TIMEOUT) { ::PostMessage(hWnd, WM_CLOSE, 0,0); return false; } // refresh handle if(gStdOut) CloseHandle(gStdOut); gStdOut = CreateFile(L"CONOUT$", GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); CONSOLE_SCREEN_BUFFER_INFO csi=GetConsoleScreenBufferInfo(); COORD size; size.X = CSI_WndCols(&csi); size.Y = CSI_WndRows(&csi); /* copy screen buffer */ DWORD nb = size.X * size.Y; CHAR_INFO* buffer = new CHAR_INFO[nb]; CHAR_INFO* ptr = buffer; SMALL_RECT sr; COORD pos = { 0, 0 }; /* ReadConsoleOuput - maximum read size 64kByte?? */ size.Y = 0x8000 / sizeof(CHAR_INFO) / size.X; sr.Left = csi.srWindow.Left; sr.Right = csi.srWindow.Right; sr.Top = csi.srWindow.Top; do { sr.Bottom = sr.Top + size.Y -1; if(sr.Bottom > csi.srWindow.Bottom) { sr.Bottom = csi.srWindow.Bottom; size.Y = sr.Bottom - sr.Top +1; } ReadConsoleOutput_Unicode(ptr, size, pos, &sr); ptr += size.X * size.Y; sr.Top = sr.Bottom +1; } while(sr.Top <= csi.srWindow.Bottom); /* compare */ if(gScreen && !memcmp(&csi, &gCSI, sizeof(CONSOLE_SCREEN_BUFFER_INFO)) && !memcmp(buffer, gScreen, sizeof(CHAR_INFO) * nb)) { /* no modified */ delete [] buffer; return false; } /* swap buffer */ if(gScreen) delete [] gScreen; gScreen = buffer; gCSI = csi; /* redraw request */ InvalidateRect(hWnd, NULL, TRUE); /* set vertical scrollbar status */ if(!gVScrollHide) { SCROLLINFO si; si.cbSize = sizeof(si); si.fMask = SIF_DISABLENOSCROLL | SIF_POS | SIF_PAGE | SIF_RANGE; si.nPos = gCSI.srWindow.Top; si.nPage = CSI_WndRows(&gCSI); si.nMin = 0; si.nMax = gCSI.dwSize.Y-1; SetScrollInfo(hWnd, SB_VERT, &si, TRUE); } *w = CSI_WndCols(&gCSI); *h = CSI_WndRows(&gCSI); return gWinW != *w || gWinH != *h; }