自己写一个通用的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;
}
- 自己写一个通用的MessageBox(SDK实现)
- 自己写的一个通用链表
- 自己写的一个通用Makefile
- 自己写一个简单通用的Makefile
- 自己写一个简单通用的Makefile
- Win32 SDK函数MessageBox的模拟实现(C语言版)
- 撸起袖子自己写一个通用的刷新控件
- 自己写的一个哈希表的实现
- 自己写的一个hibernate简单实现
- 自己写的一个单例实现
- 2010年10月20日 [原]自己实现的一个MessageBox()
- 自己写的ajax通用 脚本
- 自己写的通用文本验证
- 自己写的一个php基于phpQuery的通用采集类
- 用SDK获得IP地址(纯代码,好想是2004CSDN杂志上的自己写了一个)
- 自己写的一个用函数实现的日历
- 自己写的一个用AJAX实现的留言系统
- 自己写的一个二分查找的c++实现
- RFC868--时间协议客户机与服务器的实现
- velocity+struts+spring+ibatis
- 垃圾收集
- shell 编程
- CSS控制的文字段落左右对齐的样式
- 自己写一个通用的MessageBox(SDK实现)
- 住在我隔壁储藏室的大学刚毕业的小夫妻
- 框架制作之MVC
- 提高Excel VBA的执行效率
- 委托及事件的链表模型(从使用角度对其实现方式进行推测,不一定准确,但可以帮助理解)
- TCP和UDP协议简介
- JAVA电子书下载
- 2分法-通用存储过程分页(not in版本)
- [VS.NET 问题] 错误:源文件与模块生成时的文件不同! ,VS不能编译