紧急!!!控制台如何向屏幕输出流???(100分)

  • 主题发起人 主题发起人 pitts
  • 开始时间 开始时间
P

pitts

Unregistered / Unconfirmed
GUEST, unregistred user!
一个控制台程序,读一个二进制文件,处理后,向屏幕输出。。。<br>关键的问题就是:如何向控制台输出流???<br>搞不定啊:(((
 
cout &lt;&lt; "haha just kidding" &lt;&lt; endl;<br><br>我想 write 和 writeln 应该可以的吧
 
是 Delphi 的 {$APPTYPE CONSOLE} 控制台程序...<br>用 Write 不能写流,错误为:illegal type in Write/Writeln statement ...<br>想用 WriteConsole 试一试可是不会用:(<br><br>
 
BOOL WriteConsole(<br>&nbsp; HANDLE hConsoleOutput, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // handle to screen buffer<br>&nbsp; CONST VOID *lpBuffer, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// write buffer<br>&nbsp; DWORD nNumberOfCharsToWrite, &nbsp; &nbsp; // number of characters to write<br>&nbsp; LPDWORD lpNumberOfCharsWritten, &nbsp;// number of characters written<br>&nbsp; LPVOID lpReserved &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// reserved<br>);<br>这个API函数可以高定!注意是控制台程序,不是简单的C/c++程序<br>下面这个小程序在至于MSDN<br>#include &lt;windows.h&gt; <br>&nbsp;<br>void NewLine(void); <br>void ScrollScreenBuffer(HANDLE, INT); <br>&nbsp;<br>HANDLE hStdout, hStdin; <br>CONSOLE_SCREEN_BUFFER_INFO csbiInfo; <br>&nbsp;<br>void main(void) <br>{ <br>&nbsp; &nbsp; LPSTR lpszPrompt1 = "Type something and press Enter:/n"; <br>&nbsp; &nbsp; LPSTR lpszPrompt2 = "Type any key: "; <br>&nbsp; &nbsp; CHAR chBuffer[256]; <br>&nbsp; &nbsp; DWORD cRead, cWritten, fdwMode, fdwOldMode; <br>&nbsp; &nbsp; WORD wOldColorAttrs; <br><br>&nbsp; &nbsp; // Get handles to STDIN and STDOUT. <br><br>&nbsp; &nbsp; hStdin = GetStdHandle(STD_INPUT_HANDLE); <br>&nbsp; &nbsp; hStdout = GetStdHandle(STD_OUTPUT_HANDLE); <br>&nbsp; &nbsp; if (hStdin == INVALID_HANDLE_VALUE || <br>&nbsp; &nbsp; &nbsp; &nbsp; hStdout == INVALID_HANDLE_VALUE) <br>&nbsp; &nbsp; {<br>&nbsp; &nbsp; &nbsp; &nbsp; MyErrorExit("GetStdHandle"); <br>&nbsp; &nbsp; }<br><br>&nbsp; &nbsp; // Save the current text colors. <br><br>&nbsp; &nbsp; if (! GetConsoleScreenBufferInfo(hStdout, &amp;csbiInfo)) <br>&nbsp; &nbsp; &nbsp; &nbsp; MyErrorExit("GetConsoleScreenBufferInfo"); <br><br>&nbsp; &nbsp; wOldColorAttrs = csbiInfo.wAttributes; <br><br>&nbsp; &nbsp; // Set the text attr. to draw red text on black background. <br><br>&nbsp; &nbsp; if (! SetConsoleTextAttribute(hStdout, FOREGROUND_RED)) <br>&nbsp; &nbsp; &nbsp; &nbsp; MyErrorExit("SetConsoleTextAttribute"); <br><br>&nbsp; &nbsp; // Write to STDOUT and read from STDIN by using the default <br>&nbsp; &nbsp; // modes. Input is echoed automatically, and ReadFile <br>&nbsp; &nbsp; // does not return until a carriage return is typed. <br>&nbsp; &nbsp; // <br>&nbsp; &nbsp; // The default input modes are line, processed, and echo. <br>&nbsp; &nbsp; // The default output modes are processed and wrap at EOL. <br><br>&nbsp; &nbsp; while (1) <br>&nbsp; &nbsp; { <br>&nbsp; &nbsp; &nbsp; &nbsp; if (! WriteFile( <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; hStdout, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// output handle <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; lpszPrompt1, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// prompt string <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; lstrlen(lpszPrompt1), // string length <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &amp;cWritten, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// bytes written <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; NULL) ) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // not overlapped <br>&nbsp; &nbsp; &nbsp; &nbsp; break; <br>&nbsp; &nbsp; &nbsp; &nbsp; if (! ReadFile( <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; hStdin, &nbsp; &nbsp;// input handle <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; chBuffer, &nbsp;// buffer to read into <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 255, &nbsp; &nbsp; &nbsp; // size of buffer <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &amp;cRead, &nbsp; &nbsp;// actual bytes read <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; NULL) ) &nbsp; &nbsp;// not overlapped <br>&nbsp; &nbsp; &nbsp; &nbsp; break; <br>&nbsp; &nbsp; &nbsp; &nbsp; if (chBuffer[0] == 'q') break; <br>&nbsp; &nbsp; } <br><br>&nbsp; &nbsp; // Turn off the line input mode, and echo the input mode. <br><br>&nbsp; &nbsp; if (! GetConsoleMode(hStdin, &amp;fdwOldMode)) <br>&nbsp; &nbsp; &nbsp; &nbsp; MyErrorExit("GetConsoleMode"); <br><br>&nbsp; &nbsp; fdwMode = fdwOldMode &amp; <br>&nbsp; &nbsp; &nbsp; &nbsp; ~(ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT); <br>&nbsp; &nbsp; if (! SetConsoleMode(hStdin, fdwMode)) <br>&nbsp; &nbsp; &nbsp; &nbsp; MyErrorExit("SetConsoleMode"); <br><br>&nbsp; &nbsp; // Prompt for input. <br><br>&nbsp; &nbsp; if (! WriteFile( <br>&nbsp; &nbsp; &nbsp; &nbsp; hStdout, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// output handle <br>&nbsp; &nbsp; &nbsp; &nbsp; lpszPrompt2, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// prompt string <br>&nbsp; &nbsp; &nbsp; &nbsp; lstrlen(lpszPrompt2), // string length <br>&nbsp; &nbsp; &nbsp; &nbsp; &amp;cWritten, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// bytes written <br>&nbsp; &nbsp; &nbsp; &nbsp; NULL) ) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // not overlapped <br>&nbsp; &nbsp; MyErrorExit("WriteFile"); <br><br>&nbsp; &nbsp; // Without line and echo input modes, ReadFile returns <br>&nbsp; &nbsp; // when any input is available. Carriage returns must <br>&nbsp; &nbsp; // be handled, and WriteFile is used to echo input. <br><br>&nbsp; &nbsp; while (1) <br>&nbsp; &nbsp; { <br>&nbsp; &nbsp; &nbsp; &nbsp; if (! ReadFile(hStdin, chBuffer, 1, &amp;cRead, NULL)) <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break; <br>&nbsp; &nbsp; &nbsp; &nbsp; if (chBuffer[0] == '/r') <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; NewLine(); <br>&nbsp; &nbsp; &nbsp; &nbsp; else if (! WriteFile(hStdout, chBuffer, cRead, <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &amp;cWritten, NULL)) break; <br>&nbsp; &nbsp; &nbsp; &nbsp; if (chBuffer[0] == 'q') break; <br>&nbsp; &nbsp; } <br><br>&nbsp; &nbsp; // Restore the original console mode. <br><br>&nbsp; &nbsp; if (! SetConsoleMode(hStdin, fdwOldMode)) <br>&nbsp; &nbsp; &nbsp; &nbsp; MyErrorExit("SetConsoleMode"); <br><br>&nbsp; &nbsp; // Restore the original text colors. <br><br>&nbsp; &nbsp; if (! SetConsoleTextAttribute(hStdout, wOldColorAttrs)) <br>&nbsp; &nbsp; &nbsp; &nbsp; MyErrorExit("SetConsoleTextAttribute"); <br>}<br><br>// The NewLine function handles carriage returns when the processed <br>// input mode is disabled. It gets the current cursor position <br>// and resets it to the first cell of the next row. <br>&nbsp;<br>void NewLine(void) <br>{ <br>&nbsp; &nbsp; if (! GetConsoleScreenBufferInfo(hStdout, &amp;csbiInfo)) <br>&nbsp; &nbsp; &nbsp; &nbsp; MyErrorExit("GetConsoleScreenBufferInfo"); <br>&nbsp; &nbsp; csbiInfo.dwCursorPosition.X = 0; <br><br>&nbsp; &nbsp; // If it is the last line in the screen buffer, scroll <br>&nbsp; &nbsp; // the buffer up. <br><br>&nbsp; &nbsp; if ((csbiInfo.dwSize.Y-1) == csbiInfo.dwCursorPosition.Y) <br>&nbsp; &nbsp; { <br>&nbsp; &nbsp; &nbsp; &nbsp; ScrollScreenBuffer(hStdout, 1); <br>&nbsp; &nbsp; } <br><br>&nbsp; &nbsp; // Otherwise, advance the cursor to the next line. <br><br>&nbsp; &nbsp; else csbiInfo.dwCursorPosition.Y += 1; <br>&nbsp;<br>&nbsp; &nbsp; if (! SetConsoleCursorPosition(hStdout, <br>&nbsp; &nbsp; &nbsp; &nbsp; csbiInfo.dwCursorPosition)) <br>&nbsp; &nbsp; {<br>&nbsp; &nbsp; &nbsp; &nbsp; MyErrorExit("SetConsoleCursorPosition"); <br>&nbsp; &nbsp; }<br>} <br>
 
再简单说一下问题吧:<br><br>Delphi 写控制台程序,已知一个 TMemoryStream ,如何将其输出到控制台窗口(Dos)?<br><br>有 API WriteConsole 可以利用,但是不会用啊,好笨啊偶:((((<br><br>The WriteConsole function writes a character string to a console screen buffer beginning at the current cursor location. <br><br>BOOL WriteConsole(<br><br>&nbsp; &nbsp; HANDLE hConsoleOutput, // handle to a console screen buffer <br>&nbsp; &nbsp; CONST VOID *lpBuffer, // pointer to buffer to write from <br>&nbsp; &nbsp; DWORD nNumberOfCharsToWrite, // number of characters to write <br>&nbsp; &nbsp; LPDWORD lpNumberOfCharsWritten, // pointer to number of characters written <br>&nbsp; &nbsp; LPVOID lpReserved // reserved <br>&nbsp; &nbsp;); <br>&nbsp;<br><br>Parameters<br><br>hConsoleOutput<br><br>Identifies the console screen buffer to be written to. The handle must have GENERIC_WRITE access. <br><br>lpBuffer<br><br>Points to a buffer that contains characters to be written to the screen buffer. <br><br>nNumberOfCharsToWrite<br><br>Specifies the number of characters to write. <br><br>lpNumberOfCharsWritten<br><br>Points to a 32-bit variable that receives the number of characters actually written. <br><br>lpReserved<br><br>Reserved; must be NULL. <br><br>&nbsp;<br><br>Return Values<br><br>If the function succeeds, the return value is nonzero.<br>If the function fails, the return value is zero. To get extended error information, call GetLastError. <br><br>Remarks<br><br>WriteConsole writes characters to a console screen buffer. It behaves like the WriteFile function, except it can write in either Unicode (wide-character) or ANSI mode. To create an application that maintains a single set of sources compatible with both modes, use WriteConsole rather than WriteFile. Although WriteConsole can be used only with a console screen buffer handle, WriteFile can be used with other handles (such as files or pipes). WriteConsole fails if used with a standard handle that has been redirected to be something other than a console handle.
 
后来有人很简单就搞定了。。。<br><br>program ShowStream;<br>{$APPTYPE CONSOLE}<br>uses<br>&nbsp; Windows,<br>&nbsp; SysUtils,<br>&nbsp; Classes;<br>var<br>&nbsp; sIn: TFileStream;<br>&nbsp; sOut: THandleStream;<br>begin<br>&nbsp; sIn := TFileStream.Create('f:/music1.gif', fmOpenRead);<br>&nbsp; try<br>&nbsp; &nbsp; sOut := THandleStream.Create(GetStdHandle(STD_OUTPUT_HANDLE));<br>&nbsp; &nbsp; try<br>&nbsp; &nbsp; &nbsp; sOut.CopyFrom(sIn, sIn.Size);<br>&nbsp; &nbsp; finally<br>&nbsp; &nbsp; &nbsp; sOut.Free;<br>&nbsp; &nbsp; end;<br>&nbsp; finally<br>&nbsp; &nbsp; sIn.Free;<br>&nbsp; end;<br>end.<br>
 
多人接受答案了。
 
后退
顶部