让你的控制台程序也支持自动补齐

原创 2004年03月24日 10:07:00

让你的控制台程序也支持自动补齐

关键字:控制台(Console), 自动补齐, 命令提示符(cmd.exe)<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

作者:xstring@csdn/peach@smth

时间:2004/3/23

 

Windows 2000, Windows XP, Windows Server 2003操作系统下的“命令提示符程序 cmd.exe)”了解稍多的人都会知道“命令提示符”有几个很好用的功能。一、支持命令历史记录,可以用上下键来切换以前输入的命令;二、支持快捷键功能(F1~F9)[具体每个键的功能请读者自己试吧];三、支持目录/文件名的自动补齐,这样可以快速输入目录/文件名。

 

这些功能对于用户来讲是非常友好的,可以让用户更方便的输入和编辑命令。我也相信任何一个写控制台程序的人都希望在自己的程序当中能够实现这样的功能。

 

那么如何让自己的程序有如上的功能呢?

 

对于上面提到前两个功能,操作系统本身已经提供了,你只需要简单的调用ReadConsole这个API就可以了。这个API会跟据你输入时的按键来执行这些功能。

对于第三个功能,MSDN中未曾提及,ReadConsole API的说明中任何一点都和此功能无关。实际上自动补齐功能要用到ReadConsole的一个公开的功能,而且只有Unicode版本的ReadConsoleW提供了该功能,ANSI版本的ReadConsoleA并不支持。

 

我们先看看ReadConsole这个API的原型(from MSDN

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

);

 

MSDN中提到参数lpReserved这个参数必须为NULL值,当然MSDN中是这么提的,但对于ReadConsoleW来讲就不是了,因为自动补齐这个功能要靠ReadConsoleWlpReserved参数了。

 

该参数不为NULL时,可以指向一个如下的结构体

 

struct read_console_param

{

DWORD cbSize;

DWORD dwInitLen;

DWORD dwWakeMask;

DWORD dwUnknown;
};

 

其中每个成员变量的意义如下

²        cbSize - 该结构体的长度,16字节

²        dwInitLen – 指出lpBuffer中已有字符的数目,这样ReadConsole在等待用户输入时,也会把lpBuffer中已有的内容算进去。

²        dwWakeMask – 指出ReadConsole在接收到哪些Ctrl序列后返回,其中bit0对应^@, bit1对应^A, bit2对应^Bbit3对应^C,以此类推。当用户输入时,输入了dwWakeMask中指定的任何一个Ctrl按键,ReadConsole将返回。

²        dwUnknown具体什么意义暂不清楚,最初设为0即可

 

了解了ReadConsoleW的这个新功能后(其实该功能早就有了,只不过很多人不知道),那么就可以很容易地实现自动补齐了。

以下是我给的一个简单例子:

 

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <locale.h>

#include <windows.h>

 

#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;

      //  我们使用^F^D来进行自动补齐

      param.dwWakeMask  = (1 << Ctrl ('F'))

         | (1 << Ctrl ('D'));

again:

      if (ReadConsoleW (hInput, buf, 0x100, &read, &param))

      {

         if (buf [read-1] == Ctrl ('F'))

         {    //     用户按下了^F, 自动补齐字符串"fff"

            //     然后继续等待输入

            wcscpy (buf+read-1, L"fff");

            WriteConsoleW (hOutput, L"fff", 3,

               &written, NULL);

            param.dwInitLen = read - 1 + 3;

            goto again;

         }

         else if (buf [read-1] == Ctrl ('D'))

         {    //     用户按下了^D, 自动补齐字符串"ddd"

            //     然后继续等待输入

            wcscpy (buf+read-1, L"ddd");

            WriteConsoleW (hOutput, L"ddd", 3,

               &written, NULL);

            param.dwInitLen = read-1+3;

            goto again;

         };

 

         //  去掉回车换行

         if (buf [read-1] == '/n')

            --read;

         if (buf [read-1] == '/r')

            --read;

         buf [read] = 0;

         printf ("you inputed: [%S]/n", buf);

      }

      else

      {

         printf ("ReadConsole failed with error %d/n",

            GetLastError ());

         break;

      };

   };

};

 

       这个例子是个最简单的例子,目前只支持在输入字符串的末尾进行自动补齐,无法在输入字符串的中间进行自动补齐;如果要写出cmd.exe那样的效果,还需要加很多的代码。

最后祝所有的程序员都能在Windows下写出支持自动补齐的控制台程序!

 

linux下控制台程序界面的自动补齐和历史记录功能cli

  一 目的 为了使linux下的程序在运行中的命令行界面输入命令时具有自动补齐和历史记录功能,比如像asterisk的控制台界面。 二 实现方法 实现方法相对于在远端实现(为在telnet自...
  • ren911
  • ren911
  • 2010年07月10日 23:39
  • 1514

激活kail-linux系统控制台自动补全功能

新安装的kali-linux 操作系统的终端控制台没有自动补全功能, 这个非常讨厌, 通过研究发现这个本质的问题是创建用户时候默认指定的shell 是 /bin/sh 需要将他调整为 /bin/bas...
  • zhyh1435589631
  • zhyh1435589631
  • 2017年01月07日 12:15
  • 893

让你的控制台程序也支持自动补齐

让你的控制台程序也支持自动补齐关键字:控制台(Console), 自动补齐, 命令提示符(cmd.exe)作者:xstring@csdn/peach@smth 时间:2004/3/23 对Window...
  • xstring
  • xstring
  • 2004年03月24日 10:07
  • 645

[vc]让你的控制台程序也支持自动补齐

让你的控制台程序也支持自动补齐对Windows 2000, Windows XP, Windows Server 2003操作系统下的“命令提示符程序(cmd.exe)”了解稍多的人都会知道“命令提示...
  • zerokkqq
  • zerokkqq
  • 2011年03月20日 16:06
  • 765

经营,归根结底,就是理解游戏规则,有哪些参与者、他们有什么优势、他们有什么弱势,你要如何将对手将死、压倒他们、让他们出局,你总是处在这样一个竞争性博弈之中,你需要不断的创新,不断跳跃式前进,尝试超越他

http://open.163.com/movie/2014/4/2/V/M9OI1SF08_M9OIE9N2V.html 经营,归根结底,就是理解游戏规则,有哪些参与者、他们有什么优势、他们有什...
  • stableboy
  • stableboy
  • 2015年08月28日 21:20
  • 486

linux帮助命令及命令补全功能

前一篇讲解了linux下的计算器命令bc,这一篇我们讲解linux下至关重要的帮助命令以及命令自动补全。 1.你是否在学习linux时觉得各个linux命令语法参数太多,根本不可能完全背下来?从鸟哥的...
  • u010921701
  • u010921701
  • 2016年05月13日 21:24
  • 4222

配置NotePad++ 的java 开发环境

http://blog.sina.com.cn/s/blog_a1fe9256010153sd.html 1. 安装NotePad++  Notepad++是运行在Wind...
  • caizi001
  • caizi001
  • 2015年05月27日 15:37
  • 560

让你的站点也支持MarkDown

Markdown是一种可以使用普通文本编辑器编写的标记语言,通过类似HTML的标记语法,它可以使普通文本内容具有一定的格式。Markdown的语法简洁明了、学习容易,而且功能比纯文本更强,因此有很多人...
  • zerokkqq
  • zerokkqq
  • 2017年05月03日 21:08
  • 826

控制台程序实现拖曳运行支持

TCHAR *acDataFile = new TCHAR[MAX_PATH];TCHAR *acTmp = new TCHAR[MAX_PATH];TCHAR *acSourceF...
  • garfieldking
  • garfieldking
  • 2009年12月07日 23:44
  • 412

linux下模拟控制台经典函数

#define COMM_KEY1 '1' #define COMM_KEY2 '2' #define COMM_KEY3 '3' #define COMM_KEY4 '4' #defin...
  • wwwtovvv
  • wwwtovvv
  • 2014年04月02日 12:01
  • 517
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:让你的控制台程序也支持自动补齐
举报原因:
原因补充:

(最多只允许输入30个字)