1 //####COPYRIGHTBEGIN####
3 // ----------------------------------------------------------------------------
4 // Copyright (C) 1998, 1999, 2000 Red Hat, Inc.
6 // This program is part of the eCos host tools.
8 // This program is free software; you can redistribute it and/or modify it
9 // under the terms of the GNU General Public License as published by the Free
10 // Software Foundation; either version 2 of the License, or (at your option)
13 // This program is distributed in the hope that it will be useful, but WITHOUT
14 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
18 // You should have received a copy of the GNU General Public License along with
19 // this program; if not, write to the Free Software Foundation, Inc.,
20 // 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 // ----------------------------------------------------------------------------
24 //####COPYRIGHTEND####
25 // MessageBox.cpp : implementation file
28 //===========================================================================
29 //#####DESCRIPTIONBEGIN####
36 // Description: This is the implementation of the messagebox class
43 //####DESCRIPTIONEND####
45 //===========================================================================
50 #include "MessageBox.h"
55 static char THIS_FILE[] = __FILE__;
58 /////////////////////////////////////////////////////////////////////////////
61 // Must be global because InitModalIndirect saves the pointer
62 CMessageBox::DLGDATA CMessageBox::DlgData = {
63 { DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU,
65 0,0,0,0}, // Fix up size and position later
66 0,0,0}; // Default menu, class and title
68 void CMessageBox::Init()
70 m_pFont=CFont::FromHandle(HFONT(GetStockObject(DEFAULT_GUI_FONT)));
80 m_bDialogCreated=false;
82 m_crText=GetSysColor(COLOR_BTNTEXT);
83 InitModalIndirect (&DlgData.tmpl,NULL);
86 CMessageBox::CMessageBox()
90 m_strCaption=_T("Error");
93 CMessageBox::CMessageBox(const CString &strText,const CString &strCaption/*=_T("Error")*/,UINT Flag/*=MB_OK*/)
99 m_strCaption=strCaption;
100 m_nDefaultButton=((Flag&MB_DEFMASK)>>8);
101 m_bTopMost=(0!=(Flag&MB_SYSTEMMODAL));
102 // Use flag to select from amongst standard combinations and
105 switch(Flag&MB_TYPEMASK){
107 AddButton(_T("OK"),IDOK);
110 AddButton(_T("OK"),IDOK);
111 AddButton(_T("Cancel"),IDCANCEL);
113 case MB_ABORTRETRYIGNORE:
114 AddButton(_T("&Abort"),IDABORT);
115 AddButton(_T("&Retry"),IDRETRY);
116 AddButton(_T("&Ignore"),IDIGNORE);
119 AddButton(_T("&Yes"),IDYES);
120 AddButton(_T("&No"),IDNO);
121 AddButton(_T("Cancel"),IDCANCEL);
124 AddButton(_T("&Yes"),IDYES);
125 AddButton(_T("&No"),IDNO);
128 AddButton(_T("&Retry"),IDRETRY);
129 AddButton(_T("Cancel"),IDCANCEL);
131 case MB_YESNOALL: //13
132 AddButton(_T("&Yes"),IDYES);
133 AddButton(_T("&No"),IDNO);
134 AddButton(_T("Yes &All"),IDYESALL);
135 AddButton(_T("No A&ll"),IDNOALL);
137 case MB_YESNOALLCANCEL: //14
138 AddButton(_T("&Yes"),IDYES);
139 AddButton(_T("&No"),IDNO);
140 AddButton(_T("Yes &All"),IDYESALL);
141 AddButton(_T("No A&ll"),IDNOALL);
142 AddButton(_T("Cancel"),IDCANCEL);
149 AddButton(_T("&Help"),IDHELP);
152 switch(Flag&MB_ICONMASK){
154 m_hIcon=AfxGetApp()->LoadStandardIcon(IDI_HAND);
156 case MB_ICONQUESTION:
157 m_hIcon=AfxGetApp()->LoadStandardIcon(IDI_QUESTION);
159 case MB_ICONEXCLAMATION:
160 m_hIcon=AfxGetApp()->LoadStandardIcon(IDI_EXCLAMATION);
162 case MB_ICONASTERISK:
163 m_hIcon=AfxGetApp()->LoadStandardIcon(IDI_ASTERISK);
173 BEGIN_MESSAGE_MAP(CMessageBox, CDialog)
174 //{{AFX_MSG_MAP(CMessageBox)
179 ON_CONTROL_RANGE(BN_CLICKED, 1, 0xFFFF, OnButton)
182 /////////////////////////////////////////////////////////////////////////////
183 // CMessageBox message handlers
185 BOOL CMessageBox::OnInitDialog()
187 // Create buttons as required
188 ASSERT(ButtonCount()>0);
190 SetWindowText(m_strCaption);
192 if(-1==m_nEscapeButton||IDCANCEL!=m_arBInfo[m_nEscapeButton].m_id){
194 CMenu *pMenu=GetSystemMenu(FALSE);
195 pMenu->RemoveMenu(SC_CLOSE,MF_BYCOMMAND);
198 CDialog::OnInitDialog();
200 CFont *pOldFont=pDC->SelectObject(m_pFont);
202 pDC->GetTextMetrics(&tm);
204 int cxDLU=tm.tmAveCharWidth;
205 int cyDLU=tm.tmHeight;
206 int nButtonWidth= (60*cxDLU)/4; // width of a button
207 int nButtonHeight=(14*cyDLU)/8; // height of a button
208 int cxButtonSep= (4*cxDLU)/4; // horizontal button separation
209 int cxTextButtonSep=(10*cxDLU)/4; // horizontal separation between text and icon
210 int cyTextButtonSep=(10*cyDLU)/8; // vertical separation between text and buttons
211 int cxBorder= (7*cxDLU)/4; // horizontal separation between buttons and border
212 int cyBorder= (7*cyDLU)/8; // vertical separation between buttons and border
213 int cxIcon=GetSystemMetrics(SM_CXICON); // width of an icon
214 int cyIcon=GetSystemMetrics(SM_CYICON); // height of an icon
215 int nTotalButtonWidth=(ButtonCount()*nButtonWidth)+(ButtonCount()-1)*cxButtonSep;
216 int cxText=max(50,nTotalButtonWidth-(m_hIcon?(cxIcon+cxTextButtonSep):0));
219 // Size the text control according to the maximum line length
222 PTCHAR d=_tcsstr(c,_T("\r\n"));
230 cxText=max(cxText,pDC->GetTextExtent(c,nCount).cx);
240 // If vertical extent of text is less than that of the icon, difference between the two
241 int cyTextExtra= (m_hIcon && cyText<cyIcon)?cyIcon-cyText:0;
243 pDC->SelectObject(pOldFont);
246 // Set dialog box size
248 int cx=(2*cxBorder)+cxText+cxButtonSep+2*GetSystemMetrics(SM_CXDLGFRAME);
250 cx+=cxIcon+cxTextButtonSep;
252 int cy=(2*cyBorder)+cyText+cyTextExtra+cyTextButtonSep+nButtonHeight+
253 GetSystemMetrics(SM_CYCAPTION)+2*GetSystemMetrics(SM_CYDLGFRAME);
254 UINT flags=SWP_NOMOVE;
258 SetWindowPos(&wndTopMost,0,0,cx,cy,flags);
261 // Create a static control for the icon
263 m_pStaticIcon=new CStatic;
264 m_pStaticIcon->Create(NULL,WS_CHILD|WS_VISIBLE|SS_ICON,
265 CRect(cxBorder,cyBorder,cxBorder+cxIcon,cyBorder+cyIcon), this);
266 m_pStaticIcon->SetIcon(m_hIcon);
269 // Create a static control for the text
271 int cx=m_hIcon?cxIcon+cxTextButtonSep:0;
272 m_pStaticText=new CStatic;
273 m_pStaticText->Create(m_strText,WS_CHILD|WS_VISIBLE|m_nJustify|SS_NOPREFIX,
274 CRect(cxBorder+cx,cyBorder+cyTextExtra/2,cxBorder+cx+cxText,cyBorder+cyText+cyTextExtra/2), this);
275 m_pStaticText->SetFont(m_pFont);
278 // Create the buttons
280 GetClientRect(rcClient);
282 rect.left=(rcClient.Width()-nTotalButtonWidth)/2;
283 rect.right=rect.left+nButtonWidth;
284 rect.bottom=rcClient.bottom-cyBorder;
285 rect.top=rect.bottom-nButtonHeight;
287 ASSERT(m_nDefaultButton<ButtonCount());
289 for(unsigned i=0;i<ButtonCount();i++){
290 CButton *pWnd=new CButton;
291 m_arBInfo[i].m_pWnd=pWnd;
292 UINT id=m_arBInfo[i].m_id;
293 UINT style=WS_CHILD|WS_VISIBLE|WS_TABSTOP;
294 if(!m_arBInfo[i].m_bEnabled){
300 style|=(m_nDefaultButton==i)?BS_DEFPUSHBUTTON:BS_PUSHBUTTON;
302 pWnd->Create(m_arBInfo[i].m_strCaption,style,rect,this,id);
303 pWnd->SetFont(m_pFont);
304 if(m_nDefaultButton==i){
307 rect.left+=nButtonWidth+cxButtonSep;
308 rect.right+=nButtonWidth+cxButtonSep;
311 m_nFocusButton=m_nDefaultButton;
312 m_bDialogCreated=true;
316 void CMessageBox::OnButton(UINT id)
320 if(NULL!=m_pParentNotify){
321 m_pParentNotify->PostMessage(m_nParentNotifcationMessage,MAKEWPARAM(id,m_nParentNotifcationwParamHigh),0);
330 BOOL CMessageBox::PreTranslateMessage(MSG* pMsg)
332 if(pMsg->message==WM_KEYDOWN){
333 switch(pMsg->wParam){
335 if(-1!=m_nEscapeButton){
336 OnButton(m_arBInfo[m_nEscapeButton].m_id);
343 if( IsDialogMessage( pMsg ) )
346 return CDialog::PreTranslateMessage( pMsg );
349 void CMessageBox::AddButton(const CString & strCaption, UINT id, bool bEnabled/*=true*/)
352 ASSERT(-1==IndexOf(id));
353 for(unsigned int i=0;i<ButtonCount();i++){
354 if(0==m_arBInfo[i].m_strCaption.Compare(strCaption)){
360 if(IDCANCEL==id || (IDOK==id && -1==m_nEscapeButton)){
361 m_nEscapeButton=ButtonCount();
364 CButtonInfo info(id,bEnabled,strCaption);
368 CMessageBox::~CMessageBox()
370 for(unsigned int i=0;i<ButtonCount();i++){
371 deleteZ(m_arBInfo[i].m_pWnd);
373 deleteZ(m_pStaticText);
374 deleteZ(m_pStaticIcon);
377 void CMessageBox::SetDefaultButton(UINT nIndex)
379 ASSERT(nIndex<ButtonCount());
380 m_nDefaultButton=nIndex;
383 void CMessageBox::OnFontChange()
385 CDialog::OnFontChange();
387 m_pFont=CFont::FromHandle(HFONT(GetStockObject(DEFAULT_GUI_FONT)));
388 for(unsigned int i=0;i<ButtonCount();i++){
389 Button(i).SetFont(m_pFont);
391 m_pStaticText->SetFont(m_pFont);
396 HBRUSH CMessageBox::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
398 HBRUSH hbr=CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
400 case CTLCOLOR_STATIC:
401 pDC->SetTextColor(m_crText);
410 BOOL CMessageBox::Create(CWnd *pWnd,UINT msg,WORD wParamHigh)
415 m_pParentNotify=pWnd;
416 m_nParentNotifcationMessage=msg;
417 m_nParentNotifcationwParamHigh=wParamHigh;
419 return CreateIndirect (&DlgData.tmpl,pWnd);
422 int CMessageBox::IndexOf(UINT id)
424 for(unsigned int i=0;i<ButtonCount();i++){
425 if(m_arBInfo[i].m_id==id){
432 void CMessageBox::PostNcDestroy()
437 CDialog::PostNcDestroy();
441 void CMessageBox::OnClose()
446 void CMessageBox::SetCaption (const CString &strCaption)
448 m_strCaption=strCaption;
449 if(m_bDialogCreated){
450 SetWindowText(strCaption);