社区
图形处理/算法
帖子详情
我想用VC做一个DOS下的简单界面
windnet
2002-10-24 10:23:17
画一个条筐,然后移动光标到线筐内等待用户输入。其实很简单。但是VC好象不支持显存缓冲区的控制。请帮忙提供几个可以在VC下使用的画图函数和移动光标函数。。。感激~!
...全文
64
5
打赏
收藏
我想用VC做一个DOS下的简单界面
画一个条筐,然后移动光标到线筐内等待用户输入。其实很简单。但是VC好象不支持显存缓冲区的控制。请帮忙提供几个可以在VC下使用的画图函数和移动光标函数。。。感激~!
复制链接
扫一扫
分享
转发到动态
举报
写回复
配置赞助广告
用AI写文章
5 条
回复
切换为时间正序
请发表友善的回复…
发表回复
打赏红包
用户 昵称
2002-11-06
打赏
举报
回复
#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);
}
用户 昵称
2002-11-06
打赏
举报
回复
控制台窗口中的光标反映了文本插入的当前位置,通过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键时,在控制台窗口的最后一行显示这些键的状态。
voohoo2000
2002-10-24
打赏
举报
回复
www.yesky.com的VC学习里,刚刚好有
Console编程,去看看,很不错
sans
2002-10-24
打赏
举报
回复
在MSDN中有个例子,你找找看:
ConGui: Sample for Console I/O with GUI I/O
用户 昵称
2002-10-24
打赏
举报
回复
#include <windows.h>
#include <stdio.h>
#include <iostream.h>
class MyPosition;
class MyScreen
{
public:
void PrintMyPosition(MyPosition* pMyPosition);
};
class MyPosition
{
public:
int x,y;
void DisplayMyPosition(MyScreen* pMyScreen);
};
void MyScreen::PrintMyPosition(MyPosition* pMyPosition)
{
HANDLE hConsoleOutput=GetStdHandle(STD_OUTPUT_HANDLE);
COORD dwCursorPosition={0, 24};
char sz[80];
sprintf(sz, "My position is (%d,%d).", pMyPosition->x, pMyPosition->y);
DWORD cWritten;
WriteConsoleOutputCharacter(hConsoleOutput, sz, lstrlen(sz),
dwCursorPosition, &cWritten);
dwCursorPosition.X=pMyPosition->x;
dwCursorPosition.Y=pMyPosition->y;
SetConsoleCursorPosition(hConsoleOutput,dwCursorPosition);
}
void MyPosition::DisplayMyPosition(MyScreen* pMyScreen)
{
pMyScreen->PrintMyPosition(this);
}
void main()
{
MyPosition mypos;
MyScreen mysrn;
cout<<"Enter a position (e.g. 4 10): ";
int x,y;
cin>>x>>y;
mypos.x=x;
mypos.y=y;
mypos.DisplayMyPosition(&mysrn);
}
用
VC
#.NET+OpenGL开发交互式CAD系统
本课程用
VC
#.NET结合OpenGL,从无到有开发
一个
功能较完整的小型交互式CAD系统。 作者有交互式CAD系统、动态几何系统开发经验。出版过交互式CAD系统开发方面的图书。 课程先讲准备知识,然后讲整个系统的开发思路和...
用
VC
#.NET开发交互式CAD系统
用
VC
#.NET开发交互式CAD系统,包括结合GDI+和OPENGL两种方案。 联系平台客服可开发票。
VC
#.NET+GDI+开发交互式CAD系统
本课程用
VC
#.NET结合GDI+,从无到有开发
一个
功能较完整的小型交互式CAD系统。 作者有交互式CAD系统、动态几何系统开发经验。出版过交互式CAD系统开发方面的图书。 课程先讲准备知识,然后讲整个系统的开发思路和主要...
Linux开发入门:使用gdb调试C/C++入门教程
GDB(GNU symbolic debugger)
简单
地说就是
一个
调试工具。它是
一个
受通用公共许可证即GPL保护的自由软件。 像所有的调试器一样,GDB可以让你调试
一个
程序,包括让程序在你希望的地方停下,此时你可以查看变量、...
【C++程序员必修第一课】C++基础课程
课程目标: 学会搭建
VC
2019 开发环境 全面系统学习 C++ 语法和开发基础 学会用代码思维解决实际工作中的问题 最终拥有一定的程序设计能力,能够独立开发
一个
完整软件 适用人群: 【零基础,
想
入行 C++ 开发程序员...
图形处理/算法
19,468
社区成员
50,700
社区内容
发帖
与我相关
我的任务
图形处理/算法
VC/MFC 图形处理/算法
复制链接
扫一扫
分享
社区描述
VC/MFC 图形处理/算法
社区管理员
加入社区
获取链接或二维码
近7日
近30日
至今
加载中
查看更多榜单
社区公告
暂无公告
试试用AI创作助手写篇文章吧
+ 用AI写文章