栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

c++ 控制台鼠标化操作

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

c++ 控制台鼠标化操作

一个学习c++的人,难免会做亿些小游戏来消遣时间,在这里,我讲解一下如何让你的控制台游戏完全鼠标化.

首先,先给大家看一下执行鼠标操作的必备头文件

#include
#define KEY_DOWN(VK_NONAME) ((GetAsyncKeyState(VK_NONAME) & 0x8000) ? 1:0)
CONSOLE_FONT_INFO consoleCurrentFont;

然后进入正题

首先我们需要解除控制台的快速编译功能,并且隐藏控制台光标(就是程序运行时那个一闪一闪的东西),下面是对应代码

HANDLE hStdin = GetStdHandle(STD_INPUT_HANDLE);  
    DWORD mode;  
    GetConsoleMode(hStdin, &mode);  
    mode &= ~ENABLE_QUICK_EDIT_MODE;  //移除快速编辑模式
    mode &= ~ENABLE_INSERT_MODE;      //移除插入模式
    mode &= ~ENABLE_MOUSE_INPUT;
    SetConsoleMode(hStdin, mode);  
    CONSOLE_CURSOR_INFO cursor_info={1,0};
    SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE),&cursor_info);

到这里,你的开始准备工作还没有做完!

你需要进行一下鼠标矫正

struct
{
    LONG x=-1,y=-1,lest_x=-1,lest_y=-1;
    double real_x,real_y;
    POINT pt= {0,0}; 

    void check_mouse() 
    {  
        pt.y=pt.y/real_y,pt.x=(pt.x/real_x);
        if(pt.y<0)pt.y=0;
        if(pt.x<0)pt.x=0;
    }
    void mouse()
    {
        SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),15);
        GetCursorPos(&pt);    //获取鼠标当前位置 
        ScreenToClient(FindWindow("ConsoleWindowClass", NULL), &pt); 
        check_mouse();
        lest_y=y,lest_x=x;
        x=pt.x,y=pt.y;
        SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),7);
    } 
    void get_real_mouse()
    {
        basic.cls();printf("鼠标校正,请用鼠标点击右下角的"Hi"");
        int x=rand()%10+35,y=rand()%10+75;
        basic.gt(x,y);printf("Hi");
        while(1)
        {
            GetCursorPos(&pt);    //获取鼠标当前位置
            ScreenToClient(FindWindow("ConsoleWindowClass", NULL), &pt); 
            if(KEY_DOWN(VK_LBUTTON)&&MessageBox(0,"您确定您点击了"Hi"吗?n如果您没有点击此点可能会导致程序错乱.","鼠标校正",4)==IDYES)
            {
                real_x=pt.x/y,real_y=pt.y/x;
                break;
            }
        }
        basic.wait(500); basic.cls();
    }
}mouse;

里面的" void get_real_mouse() "就是上述的鼠标定位.

然而你把它拷贝到编译器中,编译器会提示你 缺少一些东西

是的,的确缺少.所以我补一下那些缺少的部分

struct
{ 
    void color(int all){SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),all);}
    void wait(int all){Sleep(all);}
    void cls(){system("cls");}
    void b(short hz,double time){Beep(hz,time);}
    void gt(int x,int y) 
    {
        COORD coord;
        coord.X=y;//Here, the order is reversed, otherwise, the output pointer is moved to Y row and X column
        coord.Y=x;
        HANDLE a=GetStdHandle(STD_OUTPUT_HANDLE);
        SetConsoleCursorPosition(a,coord);
    }
}basic; 

好了准备工作完毕!

接下来进入到最主要的环节

如何使用?

我给大家写了一个如何使用它例子

int choose(void) 
    {
        string whats[10]={},title="",about_things="null";
        short how_long=0,wait_=1;
        for(int i=1;i<=9;i++)
        {
            if(whats[i]!="")how_long++;
            else break;
        }
        int choose; 
        while(1) 
        {
            choose=-1; 
            basic.gt(1,0);
            mouse.mouse();
            if(mouse.y==1)choose=1;
            printf("%s",title.c_str()); 
            if(choose==1){basic.color(16+7);printf("(?)n");} 
            else {basic.color(7);printf("     n");} 
            short x=1;
            for(int i=1;i<=how_long;i++)
            {
                x++;
                if(mouse.y==x)choose=x;
                if(choose==i+1)basic.color(16*15);
                else basic.color(7);
                printf("%sn",whats[i].c_str()); 
            }
            basic.color(0);printf("n---"); 
            if(wait_==1){basic.wait(500);wait_=0;}
            if(KEY_DOWN(VK_LBUTTON)&&choose>1)break;
            else if(KEY_DOWN(VK_LBUTTON)&&choose==1)
            {
                string about="关于"+title;
                MessageBox(0,about_things.c_str(),about.c_str(),MB_OK);
            } 
        }
        for(int i=1;i<=9;i++)whats[i]="";
        title="",about_things="null";
        basic.color(7);
        basic.cls();
        return choose-1; 
    }

我讲解一下这个代码的用途 string whats[10]={},title="",about_things="null";

这个是按键内容(string whats[10]),选择界面的标题(string tittle),和关于标题的介绍(string about_things)

其余的就是基础代码了大家可以自行理解 其实我懒得打字

这个大体的运行效果就是显示一排按键,然后当你点击其中任意一个按键后会返回一个对应按键的值

最后

我把这些代码连接在一起,方便大家白嫖学习

#include
#include
#include
#include
#include
#include
#include
#include
#define KEY_DOWN(VK_NONAME) ((GetAsyncKeyState(VK_NONAME) & 0x8000) ? 1:0)
CONSOLE_FONT_INFO consoleCurrentFont;
using namespace std;
string user_name;
struct
{
    void color(int all){SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),all);}
    void wait(int all){Sleep(all);}
    void cls(){system("cls");}
    void b(short hz,double time){Beep(hz,time);}
    void gt(int x,int y)
    {
        COORD coord;
        coord.X=y;//Here, the order is reversed, otherwise, the output pointer is moved to Y row and X column
        coord.Y=x;
        HANDLE a=GetStdHandle(STD_OUTPUT_HANDLE);
        SetConsoleCursorPosition(a,coord);
    }
}basic;
struct
{
    LONG x=-1,y=-1,lest_x=-1,lest_y=-1;
    double real_x,real_y;
    HANDLE hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
    POINT pt= {0,0};

    void check_mouse()
    {
        //GetCurrentConsoleFont(hOutput, FALSE, &consoleCurrentFont); //获取字体信息
        //pt.y=((pt.y/=consoleCurrentFont.dwFontSize.Y)/1.2)+1;
        //pt.x=(pt.x/=consoleCurrentFont.dwFontSize.X)/1.25;
        pt.y=pt.y/real_y,pt.x=(pt.x/real_x);
        if(pt.y<0)pt.y=0;
        if(pt.x<0)pt.x=0;
    }
    void mouse()
    {
        SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),15);
        GetCursorPos(&pt);    //获取鼠标当前位置
        ScreenToClient(FindWindow("ConsoleWindowClass", NULL), &pt);
        check_mouse();
        lest_y=y,lest_x=x;
        x=pt.x,y=pt.y;
        SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),7);
    }
    void get_real_mouse()
    {
        basic.cls();printf("鼠标校正,请用鼠标点击右下角的"Hi"");
        int x=rand()%10+35,y=rand()%10+75;
        basic.gt(x,y);printf("Hi");
        while(1)
        {
            GetCursorPos(&pt);    //获取鼠标当前位置
            ScreenToClient(FindWindow("ConsoleWindowClass", NULL), &pt);
            if(KEY_DOWN(VK_LBUTTON)&&MessageBox(0,"您确定您点击了"Hi"吗?n如果您没有点击此点可能会导致程序错乱.","鼠标校正",4)==IDYES)
            {
                real_x=pt.x/y,real_y=pt.y/x;
                break;
            }
        }
        basic.wait(500); basic.cls();
    }
}mouse;
struct
{//移动库
    int num_get()
    {
        int num=0,ans=1,fu=0;
        int life[10]={};
        short now_key,key,lk;
        for(int i=1;i<=5;i++)
        {
            now_key=(int)getch()-48;
            key=now_key+48;
            if(key==13)break;
            else if(now_key==-40)
            {
                if(lk!=49)
                {
                    i=0,ans=0,num=0,fu=0;
                    for(int q=0;q<=9;q++)life[q]=0;
                    printf("(重新输入)");
                }
            }
            else if(key==45){ fu=1,i--;printf("(此数已经设定为负数)");}
            else if(now_key>9||now_key<0)i--;
            else printf("%i",now_key);
            lk=now_key;
            life[i]=now_key,ans++;
        }
        int d=1;
        //for(int i=1;i<=ans;i++)d=d*10;
        for(int i=ans;i>=1;i--)
        {
            num=num+life[i]*d;
            d=d*10;
        }
        if(fu==1)num=num*-1;
        return num/10;
    }
    string whats[10]={},title="",about_things="null";
    int ai_choose(void)
    {
        basic.cls();
        short how_long=0,wait_=1;
        for(int i=1;i<=9;i++)
        {
            if(whats[i]!="")how_long++;
            else break;
        }
        int choose;
        while(1)
        {
            choose=-1;
            basic.gt(1,0);
            mouse.mouse();
            if(mouse.y==1)choose=1;
            printf("%s",title.c_str());
            if(choose==1){basic.color(16+7);printf("(?)n");}
            else {basic.color(7);printf("     n");}
            short x=1;
            for(int i=1;i<=how_long;i++)
            {
                x++;
                if(mouse.y==x)choose=x;
                if(choose==i+1)basic.color(16*15);
                else basic.color(7);
                printf("%sn",whats[i].c_str());
            }
            if(wait_==1){basic.wait(500);wait_=0;}
            if(KEY_DOWN(VK_LBUTTON)&&choose>1)break;
            else if(KEY_DOWN(VK_LBUTTON)&&choose==1)
            {
                string about="关于"+title;
                if(about!="null")MessageBox(0,about_things.c_str(),about.c_str(),MB_OK);
            }
        }
        for(int i=1;i<=9;i++)whats[i]="";
        title="",about_things="null";
        basic.cls();
        return choose-1;
    }
}choose;
int main()
{
    system("mode con cols=150 lines=40");
    HANDLE hStdin = GetStdHandle(STD_INPUT_HANDLE);
    DWORD mode;
    GetConsoleMode(hStdin, &mode);
    mode &= ~ENABLE_QUICK_EDIT_MODE;  //移除快速编辑模式
    mode &= ~ENABLE_INSERT_MODE;      //移除插入模式
    mode &= ~ENABLE_MOUSE_INPUT;
    SetConsoleMode(hStdin, mode);
    CONSOLE_CURSOR_INFO cursor_info={1,0};
    SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE),&cursor_info);
    mouse.get_real_mouse();
    while(1)
    {
        choose.about_things="开始界面选择",choose.title="有什么好看的?",choose.whats[1]="开始游戏", choose.whats[2]="打开Pearl Harbor War官网", choose.whats[3]="关闭游戏";
        short a=choose.ai_choose();
        cout<

小结: 此鼠标操作有一个缺点:当你完成鼠标定位后不能修改控制台字体大小,一旦修改鼠标定位将失灵


大家拿走前请标明出处,感谢大家的配合!


文章来源:关于c++控制台鼠标化操作 - bailiwen/heveral(白.)的博客 - 洛谷博客

------

注:洛谷用户 bailiwen ,CDSN中的heveral ,NOI中的heveral(白.)均属于同一人

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/443717.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号