标题:C++检测鼠标在程序中的位置问题
只看楼主
汪泊洋程序员
Rank: 1
来 自:安徽省淮北市相山区
等 级:新手上路
帖 子:5
专家分:0
注 册:2020-8-24
结帖率:0
 问题点数:0 回复次数:1 
C++检测鼠标在程序中的位置问题
最近编了许多C++程序,但发现其中没有涉及到鼠标。大家有没有什么侦测鼠标点击点的代码?最好有鼠标版扫雷、贪吃蛇代码!!
搜索更多相关主题的帖子: 代码 C++ 检测 位置 鼠标 
2020-08-25 21:29
rjsp
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:507
帖 子:8890
专家分:53117
注 册:2011-1-18
得分:0 
你说 控制台 还是 GUI?
C++肯定不包含这些,你得使用(无论是直接还是间接)系统提供的APIs。

下面是上次为此bbs某人写的代码,适用于windows系统
程序代码:
#include <windows.h>
#include <string_view>
#include <sstream>
#include <vector>

class Console
{
public:
    Console()
    {
        hinput_ = GetStdHandle( STD_INPUT_HANDLE );
        houtput_ = GetStdHandle( STD_OUTPUT_HANDLE );
        GetConsoleMode( hinput_, &mode_ );
        COORD curpos = GetCursorPosition();
        lefttop_ = COORD{ 0, SHORT(curpos.Y+(curpos.X>0)) };
    }
    ~Console()
    {
        SetConsoleMode( hinput_, mode_ );
        ShowCursor( true );
    }

    void ShowCursor( bool bShow )
    {
        CONSOLE_CURSOR_INFO cursor;
        GetConsoleCursorInfo( houtput_, &cursor );
        cursor.bVisible = bShow;
        SetConsoleCursorInfo( houtput_, &cursor );
    }

    void EnableQuickEditMode( bool bEnabled )
    {
        DWORD mode;
        GetConsoleMode( hinput_, &mode );
        if( bEnabled && (mode&ENABLE_QUICK_EDIT_MODE)==0 )
            SetConsoleMode( hinput_, mode|ENABLE_QUICK_EDIT_MODE );
        else if( !bEnabled && (mode&ENABLE_QUICK_EDIT_MODE)!=0 )
            SetConsoleMode( hinput_, mode&~ENABLE_QUICK_EDIT_MODE );
    }
    void EnableMouseInput( bool bEnabled )
    {
        DWORD mode;
        GetConsoleMode( hinput_, &mode );
        if( bEnabled && (mode&ENABLE_MOUSE_INPUT)==0 )
            SetConsoleMode( hinput_, mode|ENABLE_MOUSE_INPUT );
        else if( !bEnabled && (mode&ENABLE_MOUSE_INPUT)!=0 )
            SetConsoleMode( hinput_, mode&~ENABLE_MOUSE_INPUT );
    }
    bool GetInputEvent( INPUT_RECORD& record )
    {
        DWORD n;
        if( ReadConsoleInput(hinput_,&record,1,&n) && n==1 )
        {
            if( record.EventType == MOUSE_EVENT )
            {
                record.Event.MouseEvent.dwMousePosition.X -= lefttop_.X;
                record.Event.MouseEvent.dwMousePosition.Y -= lefttop_.Y;
            }
            return true;
        }
        return false;
    }

    COORD GetCursorPosition( void ) const
    {
        CONSOLE_SCREEN_BUFFER_INFO ScreenBufferInfo;
        GetConsoleScreenBufferInfo( houtput_, &ScreenBufferInfo );
        return ScreenBufferInfo.dwCursorPosition;
    }
    void SetCursorPosition( SHORT rx, SHORT ry )
    {
        SetConsoleCursorPosition( houtput_, COORD{SHORT(lefttop_.X+rx),SHORT(lefttop_.Y+ry)} );
    }

    template<typename T> void Output( SHORT rx, SHORT ry, const T& t, WORD wAttribute=FOREGROUND_BLUE|FOREGROUND_GREEN|FOREGROUND_RED )
    {
        std::ostringstream os;
        os << t;
        Output( rx, ry, std::string_view(os.str()), wAttribute );
    }
    void Output( SHORT rx, SHORT ry, const std::string_view& sv, WORD wAttribute=FOREGROUND_BLUE|FOREGROUND_GREEN|FOREGROUND_RED )
    {
        COORD coord = {SHORT(lefttop_.X+rx),SHORT(lefttop_.Y+ry)};
        DWORD n;
        WriteConsoleOutputCharacterA( houtput_, sv.data(), (DWORD)sv.size(), coord, &n );
        FillConsoleOutputAttribute( houtput_, wAttribute, n, coord, &n );
    }
    void Output( SHORT rx, SHORT ry, char ch, WORD wAttribute=FOREGROUND_BLUE|FOREGROUND_GREEN|FOREGROUND_RED )
    {
        Output( rx, ry, std::string_view{&ch,1}, wAttribute );
    }

private:
    HANDLE hinput_;
    HANDLE houtput_;
    DWORD mode_;
    COORD lefttop_;
};

class Chess
{
public:
    Chess( SHORT row, SHORT col ) : row(row), col(col), buf(row*col,EMPTY)
    {
        csl.ShowCursor( false );
        csl.EnableMouseInput( true );
        csl.EnableQuickEditMode( false );
        csl.SetCursorPosition(0,row+1+2);
    }
    ~Chess()
    {
    }
    void PrintBoard()
    {
        for( SHORT c=0; c!=col; ++c )
            csl.Output( 2*c+0, 0, c+1 );
        for( SHORT r=0; r!=row; ++r )
            csl.Output( 2*col+0, r+1, r+1 );
        for( SHORT i=0; i!=row*col; ++i )
            PrintSingle( i%col, i/col );
        csl.Output( 0, row+2, "X", FOREGROUND_RED|FOREGROUND_INTENSITY );
        csl.Output( 1, row+2, " --- quit" );
    }
    void PrintSingle( SHORT x, SHORT y )
    {
        const char* p;
        switch( buf[y*col+x] )
        {
        default:     p="·"; break;
        case USER_A: p="●"; break;
        case USER_B: p="○"; break;
        }
        csl.Output( x*2, y+1, p );
    }
    void Run()
    {
        PrintBoard();
        State user = USER_B;
        for( INPUT_RECORD record; csl.GetInputEvent(record); )
        {
            if( record.EventType ==  MOUSE_EVENT )
            {
                if( record.Event.MouseEvent.dwEventFlags==0 && record.Event.MouseEvent.dwButtonState == FROM_LEFT_1ST_BUTTON_PRESSED ) // 鼠标不移动 且 左键下压
                {
                    COORD pos = record.Event.MouseEvent.dwMousePosition;
                    if( pos.X>=0 && pos.X<2*col && pos.Y>=1 && pos.Y<1+row )
                    {
                        SHORT r = pos.Y-1;
                        SHORT c = pos.X/2;
                        if( buf[r*col+c] == EMPTY )
                        {
                            user = user==USER_A ? USER_B : USER_A;
                            buf[r*col+c] = user;
                            PrintSingle( c, r );
                        }
                    }
                    else if( pos.X==0 && pos.Y==row+2 ) // quit
                        break;
                }
            }
        }
    }

private:
    Console csl;
    SHORT row, col;
    enum State { EMPTY=0, USER_A, USER_B };
    std::vector<State> buf;
};

int main( void )
{
    Chess a( 20, 20 );
    a.Run();

    return 0;
}
2020-08-26 08:32



参与讨论请移步原网站贴子:https://bbs.bccn.net/thread-502957-1-1.html




关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.016863 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved