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

来源:互联网 发布:养生网站源码 编辑:程序博客网 时间:2024/06/11 08:07

系统提供的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_MALLOC(strlen(szBuf)+1);
  strcpy(pMsgBoxData->pBtnText[1],szBuf);
 }
 else if ((uType&SA_MB_BTN_MASK) == SA_MB_ABORTRETRYIGNORE)
 {
  pMsgBoxData->nBtnCnt =3;
  LoadString(SA_Get_Instance(), IDS_ABORT, szBuf, sizeof(szBuf));
  pMsgBoxData->pBtnText[0]= (sa_char*)SA_MALLOC(strlen(szBuf)+1);
  strcpy(pMsgBoxData->pBtnText[0],szBuf);

  LoadString(SA_Get_Instance(), IDS_RETRY, szBuf, sizeof(szBuf));
  pMsgBoxData->pBtnText[1]= (sa_char*)SA_MALLOC(strlen(szBuf)+1);
  strcpy(pMsgBoxData->pBtnText[1],szBuf);

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

  LoadString(SA_Get_Instance(), IDS_NO, szBuf, sizeof(szBuf));
  pMsgBoxData->pBtnText[1]= (sa_char*)SA_MALLOC(strlen(szBuf)+1);
  strcpy(pMsgBoxData->pBtnText[1],szBuf);

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

  LoadString(SA_Get_Instance(), IDS_NO, szBuf, sizeof(szBuf));
  pMsgBoxData->pBtnText[1]= (sa_char*)SA_MALLOC(strlen(szBuf)+1);
  strcpy(pMsgBoxData->pBtnText[1],szBuf);
 }
 else if ((uType&SA_MB_BTN_MASK) == SA_MB_RETRYCANCEL)
 {
  pMsgBoxData->nBtnCnt =2;
  LoadString(SA_Get_Instance(), IDS_RETRY, 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_MALLOC(strlen(szBuf)+1);
  strcpy(pMsgBoxData->pBtnText[1],szBuf);
 }

 if((uType & SA_MB_OTHER_MASK) ==SA_MB_RESOURCE)//为自己设计的,解释szText/szTitle传入的资源ID
 {
  sa_int resource_id ;

  if(szText!=NULL)
  {
   resource_id = (sa_int)szText;
   LoadString(SA_Get_Instance(), resource_id, szBuf, sizeof(szBuf));
   pMsgBoxData->pszInfo = (sa_char*)SA_MALLOC(strlen(szBuf)+1);
   strcpy(pMsgBoxData->pszInfo,szBuf);

  }

  if(szTitle!=NULL)
  {
   resource_id = (sa_int)szTitle;
   LoadString(SA_Get_Instance(), resource_id, szBuf, sizeof(szBuf));
   pMsgBoxData->pszTitle = (sa_char*)SA_MALLOC(strlen(szBuf)+1);
   strcpy(pMsgBoxData->pszTitle,szBuf);

  }
  
 }
 else
 {
  if(szText!=NULL)
  {
   pMsgBoxData->pszInfo = (sa_char*)SA_MALLOC(strlen(szText)+1);
   strcpy(pMsgBoxData->pszInfo,szText);
  }
  
  if(szTitle!=NULL)
  {
   pMsgBoxData->pszTitle = (sa_char*)SA_MALLOC(strlen(szTitle)+1);
   strcpy(pMsgBoxData->pszTitle,szTitle);
  }
 }
  

//挂起,等待用户按相应按钮后返回


 type = DialogBoxParam(SA_Get_Instance(), (LPCTSTR)IDD_DLG_MSGBOX, hWnd, (DLGPROC)SA_MsgBoxProc,(LPARAM)pMsgBoxData);

 SA_Safe_Free(pMsgBoxData->pszInfo);
 SA_Safe_Free(pMsgBoxData->pszTitle);
 for(i=0;i<pMsgBoxData->nBtnCnt;i++)
 {
  SA_Safe_Free(pMsgBoxData->pBtnText[i]);
 }
 
 SA_Safe_Free(pMsgBoxData->userdata);
 SA_Safe_Free(pMsgBoxData);

 return type;
}

 SA_MsgBoxOnInitdialog

static LRESULT SA_MsgBoxOnInitdialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
 SIZE tStaticSize;
 SIZE tBtnSize[MSGBOX_BTN_MAXCNT];
 SIZE tDlgSize;
 HICON hIcon=NULL;
 MsgBoxData_T *pUserData=NULL;
 HWND hchild=NULL;
 //HWND hStatic = NULL;
 sa_int x=0;//基于客户区
 sa_int y=0;//基于客户区
 sa_int i=0;
 sa_int total_btn_width=0;
 sa_int btn_max_height=0;
 sa_int btn_space=MSGBOX_BTN_HSPACE_MIN;
 RECT rtDlgClient;
 RECT rtDlg;
 sa_int nBtnId[MSGBOX_BTN_MAXCNT] ={IDC_BTN1,IDC_BTN2,IDC_BTN3,IDC_BTN4,IDC_BTN5};

//DisableWndData_T结构是我在WS_DISABLE风格窗口中使用的, 我把SA_MsgBox建成了WS_DISABLE风格,

//但你不必这么做
 DisableWndData_T *pUserData2 ;

sa_char szTitle[MAX_LOADSTRING]={0};

 


 DEG_ASSERT(lParam!=0);
 pUserData = (MsgBoxData_T *)lParam;
 
 pUserData2 = (DisableWndData_T*)SA_MALLOC(sizeof(DisableWndData_T));
 DEG_ASSERT(pUserData2!=NULL);
 
 pUserData->userdata = pUserData2;
 SetWindowLong(hDlg,GWL_USERDATA,(LONG)pUserData);

 memset(&tStaticSize,0,sizeof(tStaticSize));
 memset(tBtnSize,0,sizeof(tBtnSize));
 //memset(&tPicSize,0,sizeof(tPicSize));
 memset(&tDlgSize,0,sizeof(tDlgSize));

 if (pUserData->pszTitle == NULL)
 {
  LoadString(SA_Get_Instance(), IDS_NOTITLE, szTitle, sizeof(szTitle));
 }

 if((pUserData->uType & SA_MB_ICON_MASK) == SA_MB_ICONWARNING)
 {

  hIcon = LoadIcon(NULL,IDI_WARNING);

  if (pUserData->pszTitle == NULL)
  {
   LoadString(SA_Get_Instance(), IDS_WARN, szTitle, sizeof(szTitle));
  }
  
 }
 else if ((pUserData->uType & SA_MB_ICON_MASK) == SA_MB_ICONERROR)
 {
  hIcon = LoadIcon(NULL,IDI_ERROR);
  if (pUserData->pszTitle == NULL)
  {
   LoadString(SA_Get_Instance(), IDS_ERROR, szTitle, sizeof(szTitle));
  }
 }
 else if ((pUserData->uType & SA_MB_ICON_MASK) == SA_MB_ICONQUESTION)
 {
  hIcon = LoadIcon(NULL,IDI_QUESTION);
  if (pUserData->pszTitle == NULL)
  {
   LoadString(SA_Get_Instance(), IDS_QUESTION, szTitle, sizeof(szTitle));
  }
 }
 else if ((pUserData->uType & SA_MB_ICON_MASK) == SA_MB_ICONINFORMATION)
 {
  hIcon = LoadIcon(NULL,IDI_INFORMATION);
  if (pUserData->pszTitle == NULL)
  {
   LoadString(SA_Get_Instance(), IDS_PROMPT, szTitle, sizeof(szTitle));
  }
 }

 if ((pUserData->uType & SA_MB_DEFBTN_MASK)==SA_MB_DEFBUTTON2)
 {
  if (pUserData->nBtnCnt>1)
  {
   pUserData2->nFocusId = nBtnId[1];
  }
 }
 else if ((pUserData->uType & SA_MB_DEFBTN_MASK)==SA_MB_DEFBUTTON3)
 {
  if (pUserData->nBtnCnt>2)
  {
   pUserData2->nFocusId = nBtnId[2];
  }
 }
 else if ((pUserData->uType & SA_MB_DEFBTN_MASK)==SA_MB_DEFBUTTON4)
 {
  if (pUserData->nBtnCnt>3)
  {
   pUserData2->nFocusId = nBtnId[3];
  }
 }
 else if ((pUserData->uType & SA_MB_DEFBTN_MASK)==SA_MB_DEFBUTTON5)
 {
  if (pUserData->nBtnCnt>4)
  {
   pUserData2->nFocusId = nBtnId[4];
  }
 }
 else
 {
  if (pUserData->nBtnCnt>0)
  {
   pUserData2->nFocusId = nBtnId[0];
  }
 }

 if(pUserData->pszTitle)
 {
  SetWindowText(hDlg,pUserData->pszTitle);
 }
 else
 {
  SetWindowText(hDlg,szTitle);
 }
  

 if(pUserData->pszInfo)
 {

//SA_Get_Text_Proper_Rect是我封装的一个通用函数,求得按当前窗口字体要输出某个字符串要多大一个矩形
  SA_Get_Text_Proper_Rect(GetDlgItem(hDlg,IDC_STATIC_TEXT),&tStaticSize,pUserData->pszInfo);
 }

 for (i=0;i<pUserData->nBtnCnt;i++)
 {
  SA_Get_Text_Proper_Rect(GetDlgItem(hDlg,nBtnId[i]),&(tBtnSize[i]),pUserData->pBtnText[i]);
  
  if(tBtnSize[i].cx<MSGBOX_BTN_WIDTH_MIN)
  {
   tBtnSize[i].cx =MSGBOX_BTN_WIDTH_MIN;
  }

  if (tBtnSize[i].cy <MSGBOX_BTN_HEIGHT_MIN )
  {
   tBtnSize[i].cy =MSGBOX_BTN_HEIGHT_MIN;
  }
  
  total_btn_width+=tBtnSize[i].cx;
  if(tBtnSize[i].cy>btn_max_height)
  {
   btn_max_height = tBtnSize[i].cy;
  }
 }
 
 if (pUserData->nBtnCnt>0)
 {
  total_btn_width+=btn_space*(pUserData->nBtnCnt-1);
 }
 

//MSGBOX_STATIC_HSPACE之类是一些宏定义,

//MSGBOX_STATIC_HSPACE是提示内容的STATIC控件和图片控件的横向间距,以此类推
 if ((tStaticSize.cx+MSGBOX_PIC_WIDTH+MSGBOX_STATIC_HSPACE) > total_btn_width)
 {
  tDlgSize.cx = tStaticSize.cx+MSGBOX_PIC_WIDTH+MSGBOX_STATIC_HSPACE;
  if(pUserData->nBtnCnt>1)
  {
   btn_space = (tStaticSize.cx+MSGBOX_PIC_WIDTH+MSGBOX_STATIC_HSPACE-total_btn_width)/(pUserData->nBtnCnt-1);
   if (btn_space>MSGBOX_BTN_HSPACE_MAX)
   {
    btn_space = MSGBOX_BTN_HSPACE_MAX;
   }
   total_btn_width+=(btn_space-MSGBOX_BTN_HSPACE_MIN)*(pUserData->nBtnCnt-1);
  }
 }
 else
 {
  tDlgSize.cx = total_btn_width;
 }

 tDlgSize.cx+=MSGBOX_LEFT_MARGIN+MSGBOX_RIGHT_MARGIN;

 if(tStaticSize.cy > MSGBOX_PIC_HEIGHT)
 {
  tDlgSize.cy = tStaticSize.cy+ btn_max_height + MSGBOX_TOP_MARGIN+MSGBOX_BOTTOM_MARGIN+MSGBOX_PART_VSPACE;
 }
 else
 {
  tDlgSize.cy = MSGBOX_PIC_HEIGHT+ btn_max_height + MSGBOX_TOP_MARGIN+MSGBOX_BOTTOM_MARGIN+MSGBOX_PART_VSPACE;
 }

 GetWindowRect(hDlg,&rtDlg);//对话框屏幕坐标
 SA_Get_Client_Rect(hDlg,&rtDlgClient);
 tDlgSize.cx += SA_RECT_WIDTH(rtDlg)-SA_RECT_WIDTH(rtDlgClient);
 tDlgSize.cy+=SA_RECT_HEIGHT(rtDlg) -SA_RECT_HEIGHT(rtDlgClient);
 
 MoveWindow(hDlg,rtDlg.left-(tDlgSize.cx-SA_RECT_WIDTH(rtDlg))/2,
  rtDlg.top - (tDlgSize.cy-SA_RECT_HEIGHT(rtDlg))/2,
  tDlgSize.cx ,tDlgSize.cy,FALSE);

 x= MSGBOX_LEFT_MARGIN;
 
 y= MSGBOX_TOP_MARGIN;
 if (tStaticSize.cy > MSGBOX_PIC_HEIGHT)
 {
  y += (tStaticSize.cy - MSGBOX_PIC_HEIGHT)/2;
 }
 
 
 if(hIcon!=NULL)
 {
 //没有使用动态创建窗口,借助资源管理器创建了个对话框,然后在此调整它的位置
  hchild  = GetDlgItem(hDlg,IDC_STATIC_PIC);
  SendMessage(hchild,STM_SETICON,(WPARAM)hIcon,0);
  MoveWindow(hchild,x,y,MSGBOX_PIC_WIDTH,MSGBOX_PIC_HEIGHT,FALSE);
 }
 
 if ((tStaticSize.cx+MSGBOX_PIC_WIDTH+MSGBOX_STATIC_HSPACE) < total_btn_width)
 {
  x+=MSGBOX_PIC_WIDTH+(total_btn_width-MSGBOX_PIC_WIDTH - tStaticSize.cx)/2;
 }
 else
 {
  x+=MSGBOX_PIC_WIDTH+MSGBOX_STATIC_HSPACE;
 }

 if (tStaticSize.cy >= MSGBOX_PIC_HEIGHT)
 {
  y = MSGBOX_TOP_MARGIN;
 }
 else
 {
  y = MSGBOX_TOP_MARGIN+ (MSGBOX_PIC_HEIGHT-tStaticSize.cy)/2;
 }

 if(pUserData->pszInfo)
 {
   hchild = GetDlgItem(hDlg,IDC_STATIC_TEXT);
  SetWindowText(hchild,pUserData->pszInfo);
  MoveWindow(hchild,x,y,tStaticSize.cx,tStaticSize.cy,FALSE);
 }

 
 SA_Get_Client_Rect(hDlg,&rtDlgClient);

 x = (SA_RECT_WIDTH(rtDlgClient) - total_btn_width)/2;
 DEG_ASSERT(x>0);

 if (tStaticSize.cy >= MSGBOX_PIC_HEIGHT)
 {
  y = MSGBOX_TOP_MARGIN+tStaticSize.cy;
 }
 else
 {
  y = MSGBOX_TOP_MARGIN+MSGBOX_PIC_HEIGHT;
 }
 y+=MSGBOX_PART_VSPACE;

 for (i=0;i<pUserData->nBtnCnt;i++)
 {
     hchild = GetDlgItem(hDlg,nBtnId[i]);
  SetWindowText(hchild,pUserData->pBtnText[i]);
  MoveWindow(hchild,x,y,tBtnSize[i].cx,tBtnSize[i].cy,FALSE);
  ShowWindow(hchild,SW_SHOW);
  EnableWindow(hchild,TRUE);
  x+=tBtnSize[i].cx+btn_space;
 }


 return FALSE;
}

原创粉丝点击