基于easyx和C++实现的鼠标交互界面(点击按钮)| 系统设计

实现效果一览:

当鼠标放上去后效果:

代码实现及详解:

#include<iostream>
using namespace std;
#include <graphics.h>
#include <windows.h>
#include <conio.h>
#include<string.h>
/*
* 使用easyx 制作的菜单界面
*/

// 定义菜单按钮的宽度和高度
const int BUTTON_WIDTH = 200;
const int BUTTON_HEIGHT = 50;

//总的操作数再加上1
#define operations 11

// 定义按钮的坐标和状态
struct Button {
    int x, y; // 按钮的左上角坐标
    bool isHovered; // 是否被鼠标悬停
};

void Clear_() {
    system("cls");
}

//函数声明
wchar_t* multiByteToWideChar(const string& pKey);
char* wideCharToMultiByte(wchar_t* pWCStrKey);
bool isInButtonArea(Button button, int x, int y);
void drawButton(Button button, string str);
void Show_str_to_PC(int x, int y, string str, int size);

int main() {
    //初始化窗口
    initgraph(640, 660);

    //载入背景图片
    IMAGE bg_image;
    loadimage(&bg_image, _T("schoolmap.jpg"), 640, 660); // 加载背景图片

    //绘制背景图
    putimage(0, 0, &bg_image);

    //操作数组
    string texts[operations - 1] = { "显示景点信息\0","查找景点\0","查找两个景点间的简单路径\0","查找所有路径\0","退出系统\0","添加景点\0","删除景点\0","修改景点信息\0","添加两个景点间的路径\0","删除两个景点间的路径\0" };
  
    //用来指定显示范围的变量
    RECT r;


    // 创建按钮数组
    Button* buttons = new Button[operations - 1];

    //初始化按钮
    for (int i = 0; i < operations - 1; i++) {
        buttons[i].isHovered = false;
        buttons[i].x = 220;
        buttons[i].y = 150 + i * 50;
    }

    //绘制背景图
    putimage(0, 0, &bg_image);

    
    // 循环处理消息
    while (true) {

        // 绘制界面      
        setbkmode(TRANSPARENT);
        settextstyle(45, 0, _T("宋体"), 0, 0, FW_BOLD, 0, 0, 0);
        settextcolor(WHITE);
        r = { 0,60, 639,120 };
        drawtext(_T("校园导游系统"), &r, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
        r = { 0,100,639,160 };
        settextstyle(20, 0, _T("宋体"), 0, 0, FW_BOLD, 0, 0, 0);
        drawtext(_T("欢迎来到XXXX大学"), &r, DT_CENTER | DT_VCENTER | DT_SINGLELINE);

        //遍历 画出按钮
        for (int i = 0; i < operations - 1; i++) {
            drawButton(buttons[i], texts[i]);
        }

        // 循环处理鼠标消息
        if (MouseHit()) {
            MOUSEMSG m = GetMouseMsg();
            switch (m.uMsg) {
            case WM_MOUSEMOVE:
                // 鼠标移动时判断是否在按钮区域内
                for (int i = 0; i < operations - 1; i++) {
                    buttons[i].isHovered = isInButtonArea(buttons[i], m.x, m.y);
                }
                break;
            case WM_LBUTTONUP:
                // 左键抬起时判断是否在按钮区域内
                for (int i = 0; i < operations - 1; i++) {
                    if (isInButtonArea(buttons[i], m.x, m.y)) {
                        switch (i) {//可以在各个case中添加对应的处理函数  
                        case 0:
                            Clear_();
                            cleardevice();//清理屏幕
                            cout << "显示景点信息" << endl;//这里可以用对应的函数绘制二级界面
                            break;
                        case 1:
                            Clear_();
                            cleardevice();
                            cout << "查找景点" << endl;
                            break;
                        case 2:
                            Clear_();
                            cleardevice();
                            cout << "查找两个景点间的简单路径" << endl;
                            break;
                        case 3:
                            Clear_();
                            cleardevice();
                            cout << "查找所有路径" << endl;
                            break;
                        case 4:
                            Clear_();
                            cleardevice();
                            cout << "退出系统" << endl;
                            break;
                        case 5:
                            Clear_();
                            cleardevice();
                            cout << "添加景点" << endl;
                            break;
                        case 6:
                            Clear_();
                            cleardevice();
                            cout << "删除景点" << endl;
                            break;
                        case 7:
                            Clear_();
                            cleardevice();
                            cout << "修改景点" << endl;
                            break;
                        case 8:
                            Clear_();
                            cleardevice();
                            cout << "添加景点路径" << endl;
                            break;
                        case 9:
                            Clear_();
                            cleardevice();
                            cout << "删除景点路径" << endl;
                            break;

                        }
                        putimage(0, 0, &bg_image);//重绘背景图
                    }

                }


            }
        }

        Sleep(10);//刷新频率
    }

    closegraph();
    return 0;
}


//作此界面可能需要的函数

/*wchart 转string 函数*/
char* wideCharToMultiByte(wchar_t* pWCStrKey)
{
    //第一次调用确认转换后单字节字符串的长度,用于开辟空间
    int pSize = WideCharToMultiByte(CP_OEMCP, 0, pWCStrKey, wcslen(pWCStrKey), NULL, 0, NULL, NULL);
    char* pCStrKey = new char[pSize + 1];
    //第二次调用将双字节字符串转换成单字节字符串
    WideCharToMultiByte(CP_OEMCP, 0, pWCStrKey, wcslen(pWCStrKey), pCStrKey, pSize, NULL, NULL);
    pCStrKey[pSize] = '\0';
    return pCStrKey;
}

/*string 转 wchar 函数*/
wchar_t* multiByteToWideChar(const string& pKey)
{
    const char* pCStrKey = pKey.c_str();
    //第一次调用返回转换后的字符串长度,用于确认为wchar_t*开辟多大的内存空间
    int pSize = MultiByteToWideChar(CP_OEMCP, 0, pCStrKey, strlen(pCStrKey) + 1, NULL, 0);
    wchar_t* pWCStrKey = new wchar_t[pSize];
    //第二次调用将单字节字符串转换成双字节字符串
    MultiByteToWideChar(CP_OEMCP, 0, pCStrKey, strlen(pCStrKey) + 1, pWCStrKey, pSize);
    return pWCStrKey;
}

// 判断是否在按钮区域内
bool isInButtonArea(Button button, int x, int y) {
    return (x >= button.x && x <= button.x + BUTTON_WIDTH
        && y >= button.y && y <= button.y + BUTTON_HEIGHT);
}

// 绘制按钮
void drawButton(Button button, string str) {
    if (button.isHovered) {
        setfillcolor(WHITE); settextcolor(RGB(59, 90, 166));
    }
    else {
        setfillcolor(RGB(59, 90, 166));
        settextcolor(WHITE);
    }
    fillroundrect(button.x, button.y, button.x + BUTTON_WIDTH, button.y + BUTTON_HEIGHT, 10, 10);
    RECT r = { button.x, button.y, button.x + BUTTON_WIDTH, button.y - 1 + BUTTON_HEIGHT - 1 };
    setbkmode(TRANSPARENT);
    settextstyle(20, 0, _T("微软雅黑"), 0, 0, FW_BOLD, 0, 0, 0);
    drawtext(multiByteToWideChar(str), &r, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
}

//输出指定字符串到屏幕指定位置
void Show_str_to_PC(int x, int y, string str, int size) {
    setbkmode(TRANSPARENT);
    settextstyle(size, 0, _T("宋体"), 0, 0, FW_BOLD, 0, 0, 0);
    settextcolor(WHITE);
    outtextxy(x, y, multiByteToWideChar(str));
}


欢迎讨论!

  • 18
    点赞
  • 47
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,以下是基于EasyX和C++实现创建一个窗口当点特定区域时再创建一个新窗口当点新窗口特定区域时关闭新窗口的示例代码: ``` #include <graphics.h> int main() { initgraph(640, 480); // 创建640x480的窗口 // 绘制主窗口 rectangle(100, 100, 200, 200); outtextxy(120, 140, "Click me!"); // 等待鼠标主窗口 while (true) { if (MouseHit()) // 如果有鼠标消息 { MOUSEMSG msg = GetMouseMsg(); // 获取鼠标消息 if (msg.uMsg == WM_LBUTTONDOWN && // 如果是鼠标左键按下消息 msg.x >= 100 && msg.x <= 200 && msg.y >= 100 && msg.y <= 200) // 如果鼠标在主窗口内 { // 创建新窗口 HWND hwnd = initwindow(320, 240, "New Window"); // 绘制新窗口 rectangle(50, 50, 150, 150); outtextxy(70, 90, "Click me!"); // 等待鼠标新窗口 while (true) { if (MouseHit()) // 如果有鼠标消息 { MOUSEMSG msg = GetMouseMsg(); // 获取鼠标消息 if (msg.uMsg == WM_LBUTTONDOWN && // 如果是鼠标左键按下消息 msg.x >= 50 && msg.x <= 150 && msg.y >= 50 && msg.y <= 150) // 如果鼠标在新窗口内 { closegraph(hwnd); // 关闭新窗口 break; // 退出等待鼠标新窗口的循环 } } } } } } closegraph(); // 关闭主窗口 return 0; } ``` 在上面的示例代码中,我们首先创建了一个大小为640x480的窗口,并在窗口中绘制了一个大小为100x100的矩形和一个文本“Click me!”。然后,我们进入一个无限循环,等待鼠标主窗口。如果鼠标在主窗口内被点,我们就创建一个大小为320x240的新窗口,并在新窗口中绘制一个大小为100x100的矩形和一个文本“Click me!”。然后,我们再次进入一个无限循环,等待鼠标新窗口。如果鼠标在新窗口内被点,我们就关闭新窗口。最后,我们关闭主窗口并退出程序。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值