微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

适用于Linux的SDL跨平台消息框

我正在开发一个跨平台的游戏引擎 – 这很好(我正在使用SDL)。 不过,我想要一个简单的方法显示消息框给用户,而不必依靠SDL或OpenGL(渲染到屏幕)例如,如果窗口被销毁或尚未创build,所以我不能渲染消息屏幕?

我已经为每个平台实现了多个实现的消息框函数:Windows实现使用MessageBox,Mac OS X实现使用来自Cocoa的NSAlert,我不知道我可以用于Linux实现。 我在想X11,因为这是SDL用于在Linux上进行窗口化的东西。

我已经尝试了其他的答案,但他们要么太模糊,要么用X11或者其他东西重新调整我的整个游戏引擎。 我试图find一个独立于应用程序的解决scheme(如可以在控制台应用程序中使用的Windows MessageBox函数)。

注意:Mac和Windows实现的所有代码工作正常,这只是我需要帮助的Linux实现。

如何获得与程序和function相同的已安装程序列表?

是PathIsRelative函数的WinAPI错误吗?

在linux上执行一个exec()进程所花费的时间

/ dev / random总是返回相同的序列

ShowDialog问题,同时打开表单

哦,当我在Mac OS XI上编译时,可以利用Objective-C ++,所以我可以将Cocoa(Objective-C)与我的C ++ msgBox()函数混合使用。

这是我迄今为止的Windows&Mac实现的代码

msgBox.h

#ifndef MSGBox_H #define MSGBox_H //Cross-platform message Box method. #include "platform.h" #include "string.h" //This is my own cross platform enum for message Boxes. //This enumeration 'overlaps' with some declarations in windows.h but that is fine. enum //Message Box values. { MB_OK,//For OK message Box and return value. MB_OKCANCEL,MB_YESNO,MB_RETRYCANCEL,MB_YESNOCANCEL,MB_ABORTRETRYIGnorE,MB_CANCELTRYCONTINUE,MB_CANCEL,MB_YES,MB_NO,MB_RETRY,MB_IGnorE,MB_TRYAGAIN,MB_CONTINUE,MB_ABORT,}; //The message Box function (multiple implementations for each platform). int msgBox(string msg,string title,int buttons); #endif // MSGBox_H

msgBox.cpp

#include "msgBox.h" #if CURRENT_PLATFORM == PLATFORM_WINDOWS //We can use the windows API for our messageBox. #include <windows.h> //For the message Box function. #define IDTRYAGAIN 10 //Some fixes to help this application compile. #define IDCONTINUE 11 int msgBox(string msg,int buttons) { //display the mesageBox. int retval = MessageBox(NULL,msg.c_str(),title.c_str(),buttons | MB_ICONEXCLAMATION | MB_SYstemMODAL); //Map the windows return value to ours. switch(retval) { case IDOK: return MB_OK; case IDCANCEL: return MB_CANCEL; case IDYES: return MB_YES; case IDNO: return MB_NO; case IDRETRY: return MB_RETRY; case IDIGnorE: return MB_IGnorE; case IDTRYAGAIN:return MB_TRYAGAIN; case IDCONTINUE:return MB_CONTINUE; } } #elif CURRENT_PLATFORM == PLATFORM_MACOSX //Use Cocoa to display the message Box. int msgBox(string msg,int buttons) { Nsstring* defbutton = nil; Nsstring* altbutton = nil; Nsstring* otherbutton = nil; switch(buttons) { default: case MB_OK: defbutton = @"Ok"; break; case MB_OKCANCEL: defbutton = @"Ok"; altbutton = @"Cancel"; break; case MB_RETRYCANCEL: defbutton = @"Retry"; altbutton = @"Cancel"; break; case MB_YESNO: defbutton = @"Yes"; altbutton = @"No"; break; case MB_YESNOCANCEL: defbutton = @"Yes"; altbutton = @"No"; otherbutton = @"Cancel"; break; case MB_ABORTRETRYIGnorE: defbutton = @"Abort"; altbutton = @"Retry"; otherbutton = @"Ignore"; break; case MB_CANCELTRYCONTINUE: defbutton = @"Cancel"; altbutton = @"Try Again"; otherbutton = @"Continue"; break; } NSAlert* alert = [NSAlert alertWithMessageText:[Nsstring stringWithCString:title.c_str() encoding:[Nsstring defaultCStringEncoding]] defaultButton:defbutton alternateButton:altbutton otherButton:otherbutton @R_636_4045@iveTextWithFormat:@"%s",msg.c_str()]; //brings this 'application' to the front. [[NSRunningApplication currentApplication] activateWithOptions:NSApplicationActivateIgnoringOtherApps]; NSInteger retval = [alert runModal]; //Convert the NSAlert return values into my MB_* return values. if(retval == NSAlertDefaultReturn) { switch(buttons) { case MB_OK: case MB_OKCANCEL: return MB_OK; case MB_YESNO: case MB_YESNOCANCEL: return MB_YES; case MB_ABORTRETRYIGnorE: return MB_ABORT; case MB_CANCELTRYCONTINUE: return MB_CANCEL; case MB_RETRYCANCEL: return MB_RETRY; } } else if(retval == NSAlertAlternateReturn) { switch(buttons) { case MB_OKCANCEL: case MB_RETRYCANCEL: return MB_CANCEL; case MB_YESNO: case MB_YESNOCANCEL: return MB_NO; case MB_ABORTRETRYIGnorE: return MB_RETRY; case MB_CANCELTRYCONTINUE: return MB_TRYAGAIN; } } else if(retval == NSAlertOtherReturn) { switch(buttons) { case MB_YESNOCANCEL: return MB_CANCEL; case MB_ABORTRETRYIGnorE: return MB_IGnorE; case MB_CANCELTRYCONTINUE: return MB_CONTINUE; } } return NULL; } #else int msgBox(string msg,int buttons) { //WHAT DO I DO?????? return 0; } //#error No implementation of message Boxes on current platform! #endif // CURRENT_PLATFORM

编辑:我不想使用Qt的原因有几个:它太重了,它不能在我的主计算机上工作,它不能给我足够的程序控制权。 无论如何,我正在尝试从零开始将这个游戏引擎作为一个业余爱好项目,而不依赖于其他库(我将最终用我自己的代码取代SDL)。

如何使用mingw头文件/ libs来使用windows的clang

C文件读取到char数组

在login到Windows之前,如何启动WPF应用程序?

调用posix_spawn时closures所有文件句柄

有时通过UDP套接字发送缓冲区时延迟

我创建了一个简单的包装函数,它使用SDL 2.0中的SDL_ShowMessageBox,它替换了我提交的以前的代码,它可以在Linux,Mac和Windows上运行。

SDL 2.0可以在( http://www.libsdl.org/tmp/download-2.0.PHP )找到。

您必须在Linux上自己构建SDL 2 – 只需在提供的页面中下载源代码,然后解压缩存档,然后按照INSTALL.txt中的安装说明进行操作(构建SDL 2之后,将这些库放在/ usr / local / lib文件夹 – 您可能需要移动它们或告诉您的链接器它们在哪里(包含文件在包含目录中)。

这里是代码

示例(使用我的功能):

int i = showMessageBox(mySDLWindow,"Message","Title",3,MB_BUTTONS("BUTTON 1","BUTTON 2","BUTTON 3"),0); printf("Button %i was pressed",i + 1);

messageBox.h:

//Cross-platform message Box method. #include <string> #include <SDL/SDL.h> //SDL 2.0 header file //Helper macro #define MB_BUTTONS(...) ((char*[]) {__VA_ARGS__}) //Flexible message Box function. //Returns the index of button pressed on success or a negative value on a failure. //The parent argument can be set to NULL if not available. int showMessageBox(SDL_Window *parent,std::string msg,std::string title,int count,char* buttons[],int defbutton = 0);

messageBox.cpp:

//Complex function int showMessageBox(SDL_Window *parent,string msg,int defbutton) { //Variables. int resultButton = 0; SDL_MessageBoxData mbdata; //Set the message Box @R_636_4045@ion. mbdata.flags = SDL_MESSAGEBox_@R_636_4045@ION; mbdata.message = msg.c_str(); mbdata.title = title.c_str(); mbdata.colorScheme = NULL; mbdata.window = parent; mbdata.numbuttons = count; //Allocate buttons. SDL_MessageBoxButtonData *butarray = new SDL_MessageBoxButtonData[mbdata.numbuttons]; //Set the button values. for(unsigned char i = 0; i < mbdata.numbuttons; i++) { //Is this button the default button? if(i == defbutton) { butarray[i].flags = SDL_MESSAGEBox_BUTTON_RETURNKEY_DEFAULT; } else { butarray[i].flags = 0; } //Set button text. if(buttons[i] != NULL) { butarray[i].text = buttons[i]; } //Set button ID. butarray[i].buttonid = i; } //Set the message Box data's button array. mbdata.buttons = butarray; //display the message Box. int retval = SDL_ShowMessageBox(&mbdata,&resultButton); //Deallocate the buttons array to prevent memory leaks. delete[] butarray; //Return the result (-1 on failure or if the dialog was closed). return retval < 0 ? -1 : resultButton; }

我使用gdialog / kdialog并在命令行上传递消息。 代码如下:

#include <cstdlib> #include <string> const char * getDialogCommand() { if (::system(NULL)) { if (::system("which gdialog") == 0) return "gdialog"; else if (::system("which kdialog") == 0) return "kdialog"; } return NULL; } void showWarning(const std::string & warning) { const char * dialogCommand = getDialogCommand(); if (dialogCommand) { std::string command = dialogCommand; command += " --title "Message Box Title" --msgBox "" + warning + """; int result = ::system(command.c_str()); if (result == 0) return; // success } // fail-safe method here,using stdio perhaps,depends on your application }

这不是世界上最强大的代码,但至少在我们的游戏中,我从来没有见过它失败。 在代码方面,它是无依赖的,但是你必须确保你不会在字符串中使用字符串,例如,<,>,&!!和所有非ASCII字符的转义字符。

还请注意,SDL 2.0具有SDL_ShowMessageBox

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐