Let your console program also support automatic complement
Keywords: Console, automatic complement, command prompt (cmd.exe)
Author: xstring @ 9cbs / peach @ smth
Time: 2004/3/23
For Windows 2000, Windows XP, Windows Server 2003 operating system, "CMD.exe", knows a few more people know that "command prompt" has several features. First, support the command history, you can use the upper and lower keys to switch the previously entered command; Second, support shortcut keys (F1 ~ F9) [Specific Each key to please readers yourself] ;. Third, support directory / file name Automatic replenishment, so you can quickly enter the directory / file name.
These features are very friendly for users to make users more convenient input and editing commands. I also believe that anyone who write console programs want to achieve such functions in their own procedure.
So how do you make your own procedure as the above features?
For the first two functions mentioned above, the operating system itself is already provided, you only need to simply call the ReadConsole this API. This API will perform these features with the button you enter.
For the third function, there is no mention in the MSDN that any point in the ReadConsole API is not related to this function. In fact, automatic replenishing features is used to use an open function of ReadConsole, and only the Unicode version of ReadConsoleW provides this feature, and the ANSI version of ReadConsolea is not supported.
Let's take a look at the prototype of the API of Readconsole.
Bool Readconsole
Handle HconsoleInput, // Handle To Console Input Buffer
LPVOID LPBUFFER, // Data Buffer
DWord nnumberofcharstoread, // Number of Characters to read
LPDWORD LPNUMBEROFCHARSREAD, // Number of Characters Read
LPVOID LPRESERVED / / RESERVED
);
In MSDN, the parameter lpreserved parameter must be null values, of course, this is this in MSDN, but it is not for ReadConsolew, because the automatic complement of this feature depends on ReadConsolew's LPRESERVED parameters.
When this parameter is not NULL, you can point to a structural body.
Struct Read_Console_Param
{
DWORD CBSIZE;
DWORD dwinitlen;
DWORD dwWakemask;
DWORD DWUNKNOWN;
The significance of each member variable is as follows
2 CBSIZE - the length, 16 bytes of the structure
2 DWINITLEN - indicates the number of characters in lpbuffer, so that readconsole is waiting for the contents of LPBuffer when waiting for user input.
2 DWWAKEMASK - Indicates that Retconsole returns after receiving which Ctrl sequences, where bit0 corresponds to ^ @, bit1 corresponds to ^ B, Bit3 corresponds to ^ C, and push it. When the user is input, enter any CTRL button specified in dwWWakeMask, ReadConsole will return.
2 DWUNKNOWN What is the significance of the meaning is not clear, it is initially set to 0
After learning this new feature of ReadConsole (in fact, this function has long been there, but many people don't know), then it can be easily replenished. The following is a simple example I gave:
#include
#include
#include
#include
#include
#define ctrl (x) ((x) & 0x37)
Struct Read_Console_Param
{
DWord NLENGTH;
DWORD dwinitlen;
DWORD dwWakemask;
DWORD dwunknown;
}
Int main (void)
{
HANDLE HINPUT, HOUTPUT
Wchar BUF [0x100];
Read_console_param param;
SetLocale (lc_all, ".acp");
MEMSET (& param, 0, Sizeof (param);
Param.nlength = Sizeof (param);
Hinput = getstdhandle (STD_INPUT_HANDLE);
Houtput = getstdhandle (std_output_handle);
BUF [0] = 0;
While (WCSCMP (BUF, L "quit")! = 0)
{
DWord Read, Written;
Printf ("/ n $");
Param.dwinitlen = 0;
PARAM.DWUNKNOWN = 0;
// We use ^ f and ^ D to automate
Param.dwwkemask = (1 << Ctrl ('f'))
(1 << Ctrl ('D'));
Again:
IF (readconsolew (Hinput, Buf, 0x100, & Read, & param))
{
IF (BUF [ied-1] == Ctrl ('f'))
{// The user presses the ^ F button, automatically supplies the string "FFF",
/ / Then continue to wait for input
WCSCPY (BUF READ-1, L "FFF");
Writeconsolew (Houtput, L "FFF", 3,
& written, NULL;
Param.dwinitlen = Read - 1 3;
Goto Again;
}
Else IF (buf [ied-1] == Ctrl ('d'))
{// Users pressed the ^ D key, automatically replenish the string "DDD",
/ / Then continue to wait for input
WCSCPY (BUF READ-1, L "DDD");
Writeconsolew (Houtput, L "DDD", 3,
& written, NULL;
Param.dwinitlen = read-1 3;
Goto Again;
}
// remove the carriage return
IF (BUF [ied-1] == '/ n')
- READ;
IF (buf [ied-1] == '/ r')
- READ;
BUF [Read] = 0; Printf ("You INPUTED: [% S] / N", BUF);
}
Else
{
Printf ("Readconsole Failed with Error% D / N",
GetLastError ());
Break;
}
}
}
This example is the simplest example, which is currently only supported at the end of the input string, which cannot be automatically completed in the middle of the input string; if you want to write cmd.exe, you need to add a lot. Code.
Finally, I wish all the programmers can write a console program that supports automatic complement in Windows!