论坛登陆 用户: 密码:
联系我们
设为首页
加入收藏
业界新闻 网络编程 程序开发 网页图象 聊天通讯 软件应用 网络安全 硬件学堂 教育频道 站长club
  ·推荐新闻
 
·美前任官员认为amd告倒英特
·搜索引擎关键字排行简介
·网站优化教程(一)
·msn近期遭受木马病毒骚扰 用
·用qq管理你的系统^_^ 
·测评中心金山毒霸联合发布7
·qq群聊实名 普通用户不受影
·雅虎思科联手推数字邮件签名
·这18条背下来没人敢和你忽悠
·自己动手,拯救丢失的硬盘数
  ·资料搜索
 
  ·相关文章
·深度探索c++对象模型(完结篇)
·深度探索c++对象模型(10)
·深度探索c++对象模型(9)
·深度探索c++对象模型(8)
·深度探索c++对象模型(7)
·深度探索c++对象模型(6)
·深度探索c++对象模型(5)
·深度探索c++对象模型(4)
·深度探索c++对象模型(3)
·深度探索c++对象模型(2)
  ·热门新闻
首页>>程序开发>>c/c++区>>文章正文

控制台窗口界面的编程控制(五)


 日期:2005-7-18 9:13:51     来源:易特网络技术   编辑:黑鹰  点击:

  八、光标操作

  控制台窗口中的光标反映了文本插入的当前位置,通过setconsolecursorposition函数可以改变这个“当前”位置,这样就能控制字符(串)输出。事实上,光标本身的大小和显示或隐藏也可以通过相应的api函数进行设定。例如:

bool setconsolecursorinfo( // 设置光标信息
 handle hconsoleoutput, // 句柄
 const console_cursor_info *lpconsolecursorinfo // 光标信息
);

bool getconsolecursorinfo( // 获取光标信息
 handle hconsoleoutput, // 句柄
 pconsole_cursor_info lpconsolecursorinfo // 返回光标信息
);

  这两个函数都与console_cursor_info结构体类型有关,其定义如下:

typedef struct _console_cursor_info {
 dword dwsize; // 光标百分比大小
 bool bvisible; // 是否可见
} console_cursor_info, *pconsole_cursor_info;

  需要说明的是,dwsize值反映了光标的大小,它的值范围为1-100;当为1时,光标最小,仅是一条最靠下的水平细线,当为100,光标最大,为一个字符大小的方块。

  九、读取键盘信息

  键盘事件通常有字符事件和按键事件,这些事件所附带的信息构成了键盘信息。它是通过api函数readconsoleinput来获取的,其原型如下:

bool readconsoleinput(
 handle hconsoleinput, // 输入设备句柄
 pinput_record lpbuffer, // 返回数据记录
 dword nlength, // 要读取的记录数
 lpdword lpnumberofeventsread // 返回已读取的记录数
);

  其中,input_record定义如下:

typedef struct _input_record {
 word eventtype; // 事件类型
 union {
  key_event_record keyevent;
  mouse_event_record mouseevent;
  window_buffer_size_record windowbuffersizeevent;
  menu_event_record menuevent;
  focus_event_record focusevent;
 } event;
} input_record;

  与键盘事件相关的记录结构key_event_record定义如下:

typedef struct _key_event_record {
 bool bkeydown; // true表示键按下,false表示键释放
 word wrepeatcount; // 按键次数
 word wvirtualkeycode; // 虚拟键代码
 word wvirtualscancode; // 虚拟键扫描码
 union {
  wchar unicodechar; // 宽字符
  char asciichar; // ascii字符
 } uchar; // 字符
 dword dwcontrolkeystate; // 控制键状态
} key_event_record;

  我们知道,键盘上每一个有意义的键都对应着一个唯一的扫描码,虽然扫描码可以作为键的标识,但它依赖于具体设备的。因此,在应用程序中,使用的往往是与具体设备无关的虚拟键代码。这种虚拟键代码是与设备无关的键盘编码。在visual c++中,最常用的虚拟键代码已被定义在winuser.h中,例如:vk_shift表示shift键,vk_f1表示功能键f1等。

  上述结构定义中,dwcontrolkeystate用来表示控制键状态,它可以是capslock_on(caps lock灯亮)、enhanced_key(按下扩展键)、left_alt_pressed(按下左alt键)、left_ctrl_pressed(按下左ctrl键)、numlock_on (num lock灯亮)、right_alt_pressed(按下右alt键)、right_ctrl_pressed(按下右ctrl键)、scrolllock_on(scroll lock灯亮)和shift_pressed(按下shift键)中的一个或多个值的组合。

  下面的程序是将用户按键的字符输入到一个控制台窗口的某个区域中,并当按下num lock、caps lock和scroll lock键时,在控制台窗口的最后一行显示这些键的状态。

#include
handle hout;
handle hin;
void drawbox(bool bsingle, small_rect rc);
void clearscreen(void);
void charwindow(char ch, small_rect rc); // 将ch输入到指定的窗口中
void controlstatus(dword state); // 在最后一行显示控制键的状态
void deletetopline(small_rect rc); // 删除指定窗口中最上面的行并滚动
void main()
{
 hout = getstdhandle(std_output_handle); // 获取标准输出设备句柄
 hin = getstdhandle(std_input_handle); // 获取标准输入设备句柄
 word att = foreground_red | foreground_green | foreground_intensity |  
       background_blue ;
 // 背景是蓝色,文本颜色是黄色
 setconsoletextattribute(hout, att);
 clearscreen(); // 清屏
 input_record keyrec;
 dword state = 0, res;
 char ch;
 small_rect rc = {20, 2, 40, 12};
 drawbox(true, rc);
 coord pos = {rc.left+1, rc.top+1};
 setconsolecursorposition(hout, pos); // 设置光标位置
 for(;;) // 循环
 {
  readconsoleinput(hin, &keyrec, 1, &res);
  if (state != keyrec.event.keyevent.dwcontrolkeystate) {
   state = keyrec.event.keyevent.dwcontrolkeystate;
   controlstatus(state);
  }
  if (keyrec.eventtype == key_event){
   if (keyrec.event.keyevent.wvirtualkeycode == vk_escape) break;
   // 按esc键退出循环
   if (keyrec.event.keyevent.bkeydown) {
    ch = keyrec.event.keyevent.uchar.asciichar;
    charwindow(ch, rc);
   }
  }
 }
 pos.x = 0; pos.y = 0;
 setconsolecursorposition(hout, pos); // 设置光标位置
 closehandle(hout); // 关闭标准输出设备句柄
 closehandle(hin); // 关闭标准输入设备句柄
}

void charwindow(char ch, small_rect rc) // 将ch输入到指定的窗口中
{
 static coord chpos = {rc.left+1, rc.top+1};
 setconsolecursorposition(hout, chpos); // 设置光标位置
 if ((ch<0x20)||(ch>0x7e)) return;
 writeconsoleoutputcharacter(hout, &ch, 1, chpos, null);
 if (chpos.x>=(rc.right-1))
 {
  chpos.x = rc.left;
  chpos.y++;
 }
 if (chpos.y>(rc.bottom-1))
 {
  deletetopline(rc);
  chpos.y = rc.bottom-1;
 }
 chpos.x++;
 setconsolecursorposition(hout, chpos); // 设置光标位置
}

void controlstatus(dword state) // 在最后一行显示控制键的状态
{
 console_screen_buffer_info binfo;
 getconsolescreenbufferinfo( hout, &binfo );
 coord home = {0, binfo.dwsize.y-1};
 word att0 = background_intensity ;
 word att1 = foreground_green | foreground_intensity | background_red;
 fillconsoleoutputattribute(hout, att0, binfo.dwsize.x, home, null);
 fillconsoleoutputcharacter(hout, ' ', binfo.dwsize.x, home, null);
 setconsoletextattribute(hout, att1);
 coord stapos = {binfo.dwsize.x-16,binfo.dwsize.y-1};
 setconsolecursorposition(hout, stapos);
 if (state & numlock_on)
 writeconsole(hout, "num", 3, null, null);
 stapos.x += 4;
 setconsolecursorposition(hout, stapos);
 if (state & capslock_on)
 writeconsole(hout, "caps", 4, null, null);
 stapos.x += 5;
 setconsolecursorposition(hout, stapos);
 if (state & scrolllock_on)
 writeconsole(hout, "scroll", 6, null, null);
 setconsoletextattribute(hout, binfo.wattributes); // 恢复原来的属性
 setconsolecursorposition(hout, binfo.dwcursorposition); // 恢复原来的光标位置
}

void deletetopline(small_rect rc)
{
 coord crdest;
 char_info chfill;
 small_rect rcclip = rc;
 rcclip.left++; rcclip.right--;
 rcclip.top++; rcclip.bottom--;
 crdest.x = rcclip.left;
 crdest.y = rcclip.top - 1;
 console_screen_buffer_info binfo;
 getconsolescreenbufferinfo( hout, &binfo );
 chfill.attributes = binfo.wattributes;
 chfill.char.asciichar = ' ';
 scrollconsolescreenbuffer(hout, &rcclip, &rcclip, crdest, &chfill);
}

  程序运行结果如下图所示:
  




 
上一篇:控制台窗口界面的编程控制(四)
下一篇:控制台窗口界面的编程控制(六)
[发送给好友] [打印本页] [关闭窗口] [返回顶部转载请注明来源:http://www.iyit.net
特别声明: 本站除部分特别声明禁止转载的专稿外的其他文章可以自由转载,但请务必注明出处和原始作者。文章版权归文章原始作者所有。对于被本站转载文章的个人和网站,我们表示深深的谢意。如果本站转载的文章有版权问题请联系编辑人员,我们尽快予以更正。
责任编辑: 黑鹰 投稿作者: 易特网络
信息来源: 易特网络技术 录入时间: 2005-7-18 9:13:51
浏览次数: 投稿信箱: shtghy@163.com
设置首页 - 版权声明 - 广告服务 - 关于我们 - 联系我们 - 友情连接
copyrights ©2004-2005 iyit.net all rights reserved. 网站合作、广告联系qq:147007642、466949678
易特网络技术 点击这里给我发消息