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

2016-02-19 13:58 7 1 收藏

今天天气好晴朗处处好风光,好天气好开始,图老师又来和大家分享啦。下面给大家推荐让你的控制台程序也支持自动补齐,希望大家看完后也有个好心情,快快行动吧!

【 tulaoshi.com - 编程语言 】

 对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

(本文来源于图老师网站,更多请访问https://www.tulaoshi.com/bianchengyuyan/)

  LPVOID lpReserved // reserved

  );

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

  该参数不为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对应^B,bit3对应^C,以此类推。当用户输入时,输入了dwWakeMask中指定的任何一个Ctrl按键,ReadConsole将返回。

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

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

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

  #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 (¶m, 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 ("$");

  param.dwInitLen = 0;

  param.dwUnknown = 0;

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

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

  | (1 Ctrl ('D'));

  again:

  if (ReadConsoleW (hInput, buf, 0x100, &read, ¶m))

  {

  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",

(本文来源于图老师网站,更多请访问https://www.tulaoshi.com/bianchengyuyan/)

  // 然后继续等待输入

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

  WriteConsoleW (hOutput, L"ddd", 3,

&written, NULL);

  param.dwInitLen = read-1+3;

  goto again;

  };

  // 去掉回车换行
 
  if (buf [read-1] == '')

  --read;

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

  --read;

  buf [read] = 0;

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

  }

  else

  {

  printf ("ReadConsole failed with error %d",

  GetLastError ());

  break;

  };

  };

  };

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

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

来源:https://www.tulaoshi.com/n/20160219/1605850.html

延伸阅读
《辐射3》控制台-瞬移代码 控制台-瞬移代码   格式: coc LocationID 将您传送到LocationID位址   QUOTE: LocationID Location ID                Location Name --------------------------------------------------------------------- AgathasHou...
《辐射:新维加斯》控制台代码 0.打开控制台的方法:在游戏里按"~"开启控制台,输入完后按回车,再按"~"关闭即可 1.实用控制台代码和作用解析:【不区分大小写】 注意:之前如果输入过某个代码,并按回车启动后,再次使用只需按~,再按方向键的【↑】即可调出。下文大量运用此技巧! 小发现:刚才不小心加了一个【食...
《求生之路2》控制台命令 打开控制台输入Sv_Cheats 1 下面就是命令代码: god 1 无敌 noclip 穿墙 sv_infinite_ammo 1 无限弹药不换弹夹 give health 加满血 give ammo 加满弹夹 melee_range 70 (预设为70)近战武器的伤害范围数值越高能砍得越远 sb_dont_bash 1 强制电脑队友不用手推 sb_dont_shoot 1 强制电脑队友不开枪 sb_takecontrol * 游...
《骨色争霸》控制台命令 按【 SHIFT+~ 】开启控制台 金钱100W=vegasbaby(gamechar); 无限生命=godlike(gamechar); 增加弹药=goodtimes(gamechar); 完成使命正常=beatThisShit(gamechar); 开启所有的小鸡选择性别店=unlockChicks(gamechar); 未成年人慎入!《骨色争霸》情色游戏将于秋季面市 国外游戏开发商D.Hub今日宣布这款成人级的...
《上古卷轴5:天际》让你知道什么叫Mod和控制台的用法 诶丫丫!不写下不行,稍微写下上古Mod的小白补习教程,仅供新手学习,文笔不是很好!能看懂就好! 补习篇 先认识下什么叫Mod,游戏模组(MOD)是英文单词modification(意为修改)的缩写,它是游戏的一种修改或增强程序。就是将电脑游戏中的道具、武器、角色、敌人、事物、模式、故事...

经验教程

933

收藏

90
微博分享 QQ分享 QQ空间 手机页面 收藏网站 回到头部