控制台的底层输入函数获取鼠标信息

看到了一个底层的控制台输入函数。
ReadConsoleInput

非常强大,于是在控制台下也可以玩鼠标了。

读入的INPUT_RECORD定义如下:

typedef struct _INPUT_RECORD { // ir
    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;

EventType可以判断出事件类型。
下面Event是个联合,
不同的EventType时,应该用不同的结构体去对应其中的信息。

跟鼠标有关的是这个:
typedef struct _MOUSE_EVENT_RECORD { // mer
    COORD dwMousePosition;
    DWORD dwButtonState;
    DWORD dwControlKeyState;
    DWORD dwEventFlags;
} MOUSE_EVENT_RECORD;

其中要取得坐标和按键状态都很容易了,在MSDN上很清楚。
要注意的是,x坐标是向右,y坐标是向下。
并且控制台的尺寸是80*25。
但当输出内容过多的时候,会向下滚动,
于是得到的(x,y)坐标的行值可能会一直增大。
最大的时候也就是299,因为只支持300行。

一个演示程序:

输出鼠标的位置,并且用'0'画上一个跟随鼠标走的十字标记。


#include <stdio.h>
#include <windows.h>

const int ROW = 25 ;
const int COL = 80 ;

char buffer[ROW][COL] ;

HANDLE ih ;
HANDLE oh ;

void back_to_00(){
    COORD cp ;
    int ret ;
    cp.X = 0 ;
    cp.Y = 0 ;
    ret = SetConsoleCursorPosition(oh , cp) ;
}

void draw_heart(int x , int y){
    int i , j ;
    for ( i = 0 ; i < ROW ; i ++ ){
        buffer[i][x] = '0' ;
    }
    for ( j = 0 ; j < COL ; j += 2 ){
        buffer[y][j] = '0' ;
    }
    sprintf(buffer[0] , "(%d,%d)" , x , y) ;
}

void flush_buffer(){
    int i , j ;
    back_to_00() ;
    for ( i = 0 ; i < ROW ; i ++ ){
        for ( j = 0 ; j < COL ; j ++ ){
            putchar(buffer[i][j]) ;
        }
    }
    back_to_00() ;
    memset(buffer , ' ' , sizeof(buffer)) ;
}

int main(){
    INPUT_RECORD irc ;
    DWORD n ;
    ih = GetStdHandle(STD_INPUT_HANDLE) ;
    oh = GetStdHandle(STD_OUTPUT_HANDLE) ;
    flush_buffer() ;
    while(1){
        ReadConsoleInput(ih , &irc , 1 , &n) ;
        if ( n == 1 ){
            if ( irc.EventType == MOUSE_EVENT ) {
                MOUSE_EVENT_RECORD mrc = irc.Event.MouseEvent ;
                //flush_buffer() ;
                //printf("%d,%d/n" , mrc.dwMousePosition.X , mrc.dwMousePosition.Y ) ;
                //puts("mouse") ;
                draw_heart(mrc.dwMousePosition.X , mrc.dwMousePosition.Y) ;
                flush_buffer() ;
            }
        }
    }
    return 0 ;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值