自己写一个通用的MessageBox(SDK实现)

本文档介绍如何根据实际需求创建一个自定义的通用MessageBox,允许改变按钮文本,以适应不同场景的用户交互。通过提供的源码,可以看到作者如何处理各种按钮数量和布局,以及如何与系统MessageBox保持一致的美观性。
摘要由CSDN通过智能技术生成

系统提供的MessageBox各按钮上的文本不便改变,但是在我们开发过程中,需要各种各样的提示,如果一律用Yes/No之类的提示,界面不太友好。比如按关闭按钮,弹出一个MessageBox提示"退出还是最小化?",用"退出","最小化" 两个按钮供用户作选择,就比用"是",“否”友好.

我在网上看到很多人遇到这样需求的时候,是用对话框取代MessageBox,如果你的顶目够大,那需要这样提示的地方会很多,难道你就做N个对话框来解决?为什么不自己做一个MessageBox,来替代系统的MessageBox呢?

自己要做一个通用的MessageBox,你必须要考虑到MessageBox排版的问题,每次提示,提示文本,按钮个数,按钮文本都可能是不一样的。你能不能做出每次弹出的不同内容的MessageBox跟系统提供的MessageBox一样美观?如果做到了这一点,你的MessageBox就实现了.下面提供相关源码,供有需要的朋友参考.

//调用SA_MsgBox跟调用MessageBox一样方便.对于我而言,甚至更方便,因为是我自己写的,我为uType定义了一种SA_MB_RESOURCE,这样szText/szTitle还可以传递字符串资源进来,不用外面每处调用都分配内存了.最多可以支持5个按钮,按钮的文本由pBtnText传进来.MessageBox有的SA_MsgBox都有

sa_int SA_MsgBox( HWND hWnd, sa_char szText[], sa_char szTitle[], UINT uType,sa_int nBtnCnt,sa_char* pBtnText[])
{
 sa_int type=0;
 MsgBoxData_T * pMsgBoxData = NULL;
 sa_int i=0;
 sa_char szBuf[MAX_LOADSTRING];


 if (hWnd==NULL)
 {
  hWnd = ::GetActiveWindow();
  if (hWnd != NULL)
  {
   hWnd = ::GetLastActivePopup(hWnd);
  }
 }

//SA_MALLOC是被重定义的内存分配,在它里面随便用0把内存块初始化了一下

 pMsgBoxData = (MsgBoxData_T *)SA_MALLOC(sizeof(MsgBoxData_T));

 pMsgBoxData->uType = uType;
 if((uType&SA_MB_BTN_MASK) == SA_MB_CUSTOM) //自定义风格
 {

//对于自定义风格,SA_MsgBox将使用nBtnCnt/pBtnText[]定义的按钮个数和各按钮文本
  if (nBtnCnt>MSGBOX_BTN_MAXCNT)//MSGBOX_BTN_MAXCNT被定义成5,最多支持5个
  {
   pMsgBoxData->nBtnCnt  =MSGBOX_BTN_MAXCNT;
   DEG_ASSERT(pBtnText!=NULL);
  }
  else if (nBtnCnt>0)
  {
   DEG_ASSERT(pBtnText!=NULL);
   pMsgBoxData->nBtnCnt  =nBtnCnt;
  }

  for (i=0;i<pMsgBoxData->nBtnCnt;i++)
  {
   DEG_ASSERT(pBtnText[i]!=NULL);
   pMsgBoxData->pBtnText[i] = (sa_char*)SA_MALLOC(strlen(pBtnText[i])+1);
   strcpy(pMsgBoxData->pBtnText[i],pBtnText[i]);
  }
 }
 else if ((uType&SA_MB_BTN_MASK) == SA_MB_OK) //即MessageBox的MB_OK风格,我给它戴了个帽,后面类推
 {

  pMsgBoxData->nBtnCnt =1;
  LoadString(SA_Get_Instance(), IDS_CONFIRM, szBuf, sizeof(szBuf));
  pMsgBoxData->pBtnText[0]= (sa_char*)SA_MALLOC(strlen(szBuf)+1);
  strcpy(pMsgBoxData->pBtnText[0],szBuf);
 }
 else if ((uType&SA_MB_BTN_MASK) == SA_MB_OKCANCEL)
 {
  pMsgBoxData->nBtnCnt =2;
  LoadString(SA_Get_Instance(), IDS_CONFIRM, szBuf, sizeof(szBuf));
  pMsgBoxData->pBtnText[0]= (sa_char*)SA_MALLOC(strlen(szBuf)+1);
  strcpy(pMsgBoxData->pBtnText[0],szBuf);

  LoadString(SA_Get_Instance(), IDS_CANCEL, szBuf, sizeof(szBuf));
  pMsgBoxData->pBtnText[1]= (sa_char*)SA_MALLO

由于MessageBox是Windows Forms应用程序中的一部分,因此需要使用Windows Forms的线程安全技术来实现线程安全的MessageBox。以下是一个示例代码: ```csharp using System; using System.Threading; using System.Windows.Forms; namespace ThreadSafeMessageBox { public static class MessageBoxHelper { private static readonly object _lock = new object(); public static DialogResult Show(string message, string caption, MessageBoxButtons buttons, MessageBoxIcon icon) { DialogResult result = DialogResult.None; if (Application.OpenForms.Count > 0) { Form activeForm = Application.OpenForms[0]; if (activeForm.InvokeRequired) { activeForm.Invoke(new Action(() => { lock (_lock) { result = MessageBox.Show(activeForm, message, caption, buttons, icon); } })); } else { lock (_lock) { result = MessageBox.Show(activeForm, message, caption, buttons, icon); } } } return result; } } } ``` 这里使用了一个名为MessageBoxHelper的静态类来实现线程安全的MessageBox。其中,_lock是一个对象锁,用于保证在多线程环境下MessageBox的安全性。 Show方法接受与MessageBox.Show方法相同的参数,并返回DialogResult类型的结果。在Show方法中,首先检查当前应用程序是否有打开的窗体。如果有,则获取第一个窗体并检查它是否需要调用Invoke方法来跨线程调用。如果需要,则使用Invoke方法执行一个Lambda表达式来调用MessageBox.Show方法,并在Lambda表达式中使用_lock对象锁来保护MessageBox的安全。如果不需要调用Invoke方法,则直接使用_lock对象锁来调用MessageBox.Show方法。 这个MessageBoxHelper类可以在任何多线程应用程序中使用,以确保在多个线程同时调用MessageBox时不会出现问题。使用方法与普通的MessageBox.Show方法相同,只需要调用MessageBoxHelper.Show方法即可。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值