#c++#如何制作一个**基于easyx**的按钮函数

我希望制作一个基于easyx的按钮函数,可以获取鼠标位置,当鼠标按下时执行函数
我是这样写的

//按钮函数,要传进的消息,按钮坐标,按钮图片指针和后续操作函数
void button(ExMessage& msg, int posX, int posY, IMAGE* img ,void(*run)() ){
    int x = msg.x, y = msg.y, t1 = img->getwidth(), t2 = img->getheight();
    while (true) {
        if (peekmessage(&msg, EX_MOUSE)) {
            if (x >= posX && x <= posX + t1 &&
                y >= posY && y <= posY + t2) {
                switch (msg.message) {
                case WM_LBUTTONDOWN://鼠标按键动作                    
                    run();
                    break;
                case WM_MOUSEMOVE://鼠标移动和鼠标悬停
                    // 设置鼠标形状为手,但是好像没什么用
                    SetCursor(LoadCursor(NULL, IDC_HAND));
                    break;
                default:
                    break;
                }
            }
        }    
    }
    return;
}

但是这样会导致我的背景图片消失,本身的按钮图片也没加载

除此之外,我有时候可能需要run函数是某一个类中的函数(需要调用类中的某些数据)时我应该怎么改

该回答通过自己思路及引用到GPTᴼᴾᴱᴺᴬᴵ搜索,得到内容具体如下:
您的按钮函数需要在绘制按钮的同时,不断监听鼠标动作,因此需要在函数中使用循环。然而,在循环过程中,如果没有退出循环,那么程序就会一直在循环中运行,无法继续执行后续代码,从而导致程序卡死。因此,您需要在循环中添加一个退出条件,例如在鼠标按下时退出循环。

另外,为了让按钮能够显示在界面上,您需要在绘制按钮时将按钮图片绘制到屏幕上。具体来说,可以使用 EasyX 提供的 putimage 函数将按钮图片绘制到指定位置。

下面是基于 EasyX 的按钮函数的一个示例:

#include <graphics.h>

// 定义按钮结构体
struct Button {
    int x;              // 按钮左上角的 x 坐标
    int y;              // 按钮左上角的 y 坐标
    IMAGE* normal;      // 普通状态下的按钮图片
    IMAGE* hover;       // 鼠标悬停时的按钮图片
    IMAGE* down;        // 鼠标按下时的按钮图片
};

// 绘制按钮
void draw_button(Button& btn) {
    // 获取鼠标位置
    int x = mousex(), y = mousey();
    // 判断鼠标是否在按钮范围内
    bool in_range = (x >= btn.x && x <= btn.x + btn.normal->getwidth() &&
                     y >= btn.y && y <= btn.y + btn.normal->getheight());
    // 根据鼠标状态选择绘制的图片
    IMAGE* img = in_range ? (is_mouse_down(MOUSE_LEFTBUTTON) ? btn.down : btn.hover) : btn.normal;
    // 绘制按钮图片
    putimage(btn.x, btn.y, img);
}

// 监听按钮事件
bool handle_button(Button& btn) {
    // 获取鼠标位置
    int x = mousex(), y = mousey();
    // 判断鼠标是否在按钮范围内
    bool in_range = (x >= btn.x && x <= btn.x + btn.normal->getwidth() &&
                     y >= btn.y && y <= btn.y + btn.normal->getheight());
    // 处理鼠标事件
    if (is_mouse_down(MOUSE_LEFTBUTTON) && in_range) {
        // 如果鼠标按下并且在按钮范围内,则执行后续操作
        return true;
    }
    return false;
}

// 使用按钮
void use_button(Button& btn) {
    // 在这里执行按钮操作
    // ...
}

int main() {
    // 初始化 EasyX
    initgraph(640, 480);
    // 创建按钮
    Button btn = { 100, 100, new IMAGE("normal.png"), new IMAGE("hover.png"), new IMAGE("down.png") };
    // 循环绘制并监听按钮事件
    while (!kbhit()) {
        // 绘制按钮
        draw_button(btn);
        // 监听按钮事件
        if (handle_button(btn)) {
            // 如果按钮事件被触发,则执行后续操作
            use_button(btn);
        }
    }
    // 关闭 EasyX
    closegraph();
    return 0;
}

在这个示例中,按钮结构体包含了按钮坐标和三种不同状态下的按钮图片。draw_button 函数根据鼠标的状态选择需要绘制的按钮图片,并将其绘制到屏幕上。handle_button 函数则监听鼠标动作,并根据鼠标的状态和位置判断是否触发了按钮事件。如果按钮事件被触发,则执行后续操作。在主函数中,我们循环调用 draw_buttonhandle_button 函数,从而实现了按钮的绘制和监听。


如果以上回答对您有所帮助,点击一下采纳该答案~谢谢