为Cocos2d-x增加带Button回调的系统级消息框(MessageBox)

来源:互联网 发布:it服务管理体系认证 编辑:程序博客网 时间:2024/04/28 14:05


目标: 当点击系统消息框中的 "ok" 按钮时, 可执行一段我们自己任意指定的c++代码...

实现: 修改(或添加)代码如下,


----------------------------------------------
platform/CCCommon.h

#include <functional>// 回调类型typedef std::function<void()> MessageBox_Callback;// 带回调的消息框void CC_DLL MessageBox(const char * msg, const char * title, const MessageBox_Callback & callback);


----------------------------------------------
platform/ios/CCCommon.mm

// 消息框代理@interface MessageBox_Delegate : NSObject <UIAlertViewDelegate>{    MessageBox_Callback mCallback;}- (id)initWithCallback:(const MessageBox_Callback &)callback;@end@implementation MessageBox_Delegate- (id)initWithCallback:(const MessageBox_Callback &)callback;{    if (self = [super init])    {        mCallback = callback; // 备份对象    }        return(self);}- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex{    [alertView setDelegate: nil];    [self autorelease];        mCallback(); // 回调}@endvoid MessageBox(const char * msg, const char * title, const MessageBox_Callback & callback){    MessageBox_Delegate * modalDelegate = [[MessageBox_Delegate alloc] initWithCallback: callback];        NSString * tmpTitle = (title) ? [NSString stringWithUTF8String : title] : nil;    NSString * tmpMsg = (msg) ? [NSString stringWithUTF8String : msg] : nil;    UIAlertView * messageBox = [[UIAlertView alloc] initWithTitle: tmpTitle                                                          message: tmpMsg                                                         delegate: modalDelegate                                                cancelButtonTitle: @"OK"                                                otherButtonTitles: nil];    [messageBox autorelease];    [messageBox show];}


----------------------------------------------

platform/android/CCCommon.cpp

void MessageBox(const char * msg, const char * title){    showDialogJNI(msg, title, 0); // 回调地址为0 则不回调}void MessageBox(const char * msg, const char * title, const MessageBox_Callback & callback){    MessageBox_Callback * Callback = new MessageBox_Callback(); // 待回调后 delete    *Callback = callback;                                       // 备份对象        showDialogJNI(msg, title, (long long)Callback); // 将地址作为64位整型传给Java(防止日后将c++代码编译为64位版本)}extern "C"{    // 供Java回调    JNIEXPORT void JNICALL Java_org_cocos2dx_lib_Cocos2dxHandler_onDialogButtonClicked(JNIEnv* env, jobject thiz, jlong callback)    {        if (0 != callback)        {            MessageBox_Callback * Callback = (MessageBox_Callback *)callback;            (*Callback)(); // 回调之                        delete Callback; // 删除对象        }    }}


----------------------------------------------

Java_org_cocos2dx_lib_Cocos2dxHelper.h

extern void showDialogJNI(const char * pszMsg, const char * pszTitle, long long pCallback);


----------------------------------------------
Java_org_cocos2dx_lib_Cocos2dxHelper.cpp

void showDialogJNI(const char * pszMsg, const char * pszTitle, long long pCallback){    if (!pszMsg)    {        return;    }    JniMethodInfo t;    if (JniHelper::getStaticMethodInfo(t, CLASS_NAME, "showDialog", "(Ljava/lang/String;Ljava/lang/String;J)V")) // **    {        jstring stringArg1;        if (!pszTitle)        {            stringArg1 = t.env->NewStringUTF("");        }        else        {            stringArg1 = t.env->NewStringUTF(pszTitle);        }        jstring stringArg2 = t.env->NewStringUTF(pszMsg);        t.env->CallStaticVoidMethod(t.classID, t.methodID, stringArg1, stringArg2, pCallback); // 调用Java        t.env->DeleteLocalRef(stringArg1);        t.env->DeleteLocalRef(stringArg2);        t.env->DeleteLocalRef(t.classID);    }}


----------------------------------------------

Cocos2dxHelper.java

public class Cocos2dxHelper{private static void showDialog(final String pTitle, final String pMessage, final long pCallback) // 供c++调用{Cocos2dxHelper.sCocos2dxHelperListener.showDialog(pTitle, pMessage, pCallback);}public static interface Cocos2dxHelperListener // 此接口由Cocos2dxActivity实现{public void showDialog(final String pTitle, final String pMessage, final long pCallback);}}


----------------------------------------------
Cocos2dxActivity.java

public abstract class Cocos2dxActivity extends Activity implements Cocos2dxHelperListener {@Overridepublic void showDialog(final String pTitle, final String pMessage, final long pCallback){Message msg = new Message();msg.what = Cocos2dxHandler.HANDLER_SHOW_DIALOG;msg.obj = new Cocos2dxHandler.DialogMessage(pTitle, pMessage, pCallback);this.mHandler.sendMessage(msg);}}


----------------------------------------------
Cocos2dxHandler.java

public class Cocos2dxHandler extends Handler {private static LinkedList<DialogData> sDialogDataList = null;// c++ 回调public static native void onDialogButtonClicked(long callback);private void showDialog(Message msg) {Cocos2dxActivity theActivity = this.mActivity.get();DialogMessage dialogMessage = (DialogMessage)msg.obj;AlertDialog alertDialog = new AlertDialog.Builder(theActivity).setCancelable(false).setTitle(dialogMessage.titile).setMessage(dialogMessage.message).setPositiveButton("Ok",new DialogInterface.OnClickListener() {@Overridepublic void onClick(DialogInterface dialog, int which) {if (null != sDialogDataList){Iterator<DialogData> listItr = sDialogDataList.iterator();while (listItr.hasNext()) // 遍历list找dialog{DialogData dialogData = listItr.next();if (dialogData.dialog == dialog){onDialogButtonClicked(dialogData.callback); // 回调c++listItr.remove(); // 移除break;}}}}}).create();if (null == sDialogDataList) // 初始化list{sDialogDataList = new LinkedList<DialogData>();}DialogData dialogData = new DialogData(alertDialog, dialogMessage.callback); // Dialog与callback绑定sDialogDataList.addFirst(dialogData); // 存入list (后弹出的对话框 会先被点击 所以放在list头部 便于查询)alertDialog.show();}private static class DialogData // dialog及对应的callback{public DialogInterface dialog;public long callback;public DialogData(DialogInterface dialog, long callback) {this.dialog = dialog;this.callback = callback;}}public static class DialogMessage {public String titile;public String message;public long callback;public DialogMessage(String title, String message, long callback) {this.titile = title;this.message = message;this.callback = callback;}}}


----------------------------------------------
调用实例

cocos2d::MessageBox("连接服务器失败", "通知",    [this]()    {        if (GGlobal::GLoginSocket->ConnectLoginServer()) // 重新请求连接        {            this->mTimeUsed = 0.0f;        }    });


----------------------------------------------

以上源代码文件在不同版本的cocos2d-x中可能路径略微有差别, 可自行搜索定位, 目前只实现了Android和iOS版, 仅供参考.


1 0
原创粉丝点击