]> git.kernelconcepts.de Git - karo-tx-redboot.git/blob - tools/src/tools/configtool/common/win32/messagebox.cpp
Initial revision
[karo-tx-redboot.git] / tools / src / tools / configtool / common / win32 / messagebox.cpp
1 //####COPYRIGHTBEGIN####
2 //                                                                          
3 // ----------------------------------------------------------------------------
4 // Copyright (C) 1998, 1999, 2000 Red Hat, Inc.
5 //
6 // This program is part of the eCos host tools.
7 //
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) 
11 // any later version.
12 // 
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 
16 // more details.
17 // 
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.
21 //
22 // ----------------------------------------------------------------------------
23 //                                                                          
24 //####COPYRIGHTEND####
25 // MessageBox.cpp : implementation file
26 //
27 //
28 //===========================================================================
29 //#####DESCRIPTIONBEGIN####
30 //
31 // Author(s):   sdf
32 // Contact(s):  sdf
33 // Date:                1998/10/06
34 // Version:             0.01
35 // Purpose:     
36 // Description: This is the implementation of the messagebox class
37 // Requires:    
38 // Provides:    
39 // See also:    
40 // Known bugs:  
41 // Usage:       
42 //
43 //####DESCRIPTIONEND####
44 //
45 //===========================================================================
46
47 //
48
49 #include "stdafx.h"
50 #include "MessageBox.h"
51
52 #ifdef _DEBUG
53 #define new DEBUG_NEW
54 #undef THIS_FILE
55 static char THIS_FILE[] = __FILE__;
56 #endif
57
58 /////////////////////////////////////////////////////////////////////////////
59 // CMessageBox dialog
60
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,
64                 0,                // No controls yet
65                 0,0,0,0}, // Fix up size and position later
66                 0,0,0};   // Default menu, class and title
67
68 void CMessageBox::Init()
69 {
70         m_pFont=CFont::FromHandle(HFONT(GetStockObject(DEFAULT_GUI_FONT)));
71         m_nFocusButton=-1;
72         m_nEscapeButton=-1;
73         m_nJustify=SS_LEFT;
74         m_nDefaultButton=0;
75         m_hIcon=NULL;
76         m_pStaticText=NULL;
77         m_pStaticIcon=NULL;
78         m_bTopMost=false;
79         m_bModeless=false;
80         m_bDialogCreated=false;
81         m_pParentNotify=NULL;
82         m_crText=GetSysColor(COLOR_BTNTEXT);
83         InitModalIndirect (&DlgData.tmpl,NULL); 
84 }
85
86 CMessageBox::CMessageBox()
87         : CDialog()
88 {
89         Init();
90         m_strCaption=_T("Error");
91 }
92
93 CMessageBox::CMessageBox(const CString &strText,const CString &strCaption/*=_T("Error")*/,UINT Flag/*=MB_OK*/)
94         : CDialog()
95 {
96         Init();
97
98         m_strText=strText;
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
103         // to select icon.
104
105         switch(Flag&MB_TYPEMASK){
106                 case MB_OK:
107                         AddButton(_T("OK"),IDOK);
108                         break;
109                 case MB_OKCANCEL:
110                         AddButton(_T("OK"),IDOK);
111                         AddButton(_T("Cancel"),IDCANCEL);
112                         break;
113                 case MB_ABORTRETRYIGNORE:
114                         AddButton(_T("&Abort"),IDABORT);
115                         AddButton(_T("&Retry"),IDRETRY);
116                         AddButton(_T("&Ignore"),IDIGNORE);
117                         break;
118                 case MB_YESNOCANCEL:
119                         AddButton(_T("&Yes"),IDYES);
120                         AddButton(_T("&No"),IDNO);
121                         AddButton(_T("Cancel"),IDCANCEL);
122                         break;
123                 case MB_YESNO:
124                         AddButton(_T("&Yes"),IDYES);
125                         AddButton(_T("&No"),IDNO);
126                         break;
127                 case MB_RETRYCANCEL:
128                         AddButton(_T("&Retry"),IDRETRY);
129                         AddButton(_T("Cancel"),IDCANCEL);
130                         break;
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);
136                         break;
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);
143                         break;
144                 default:
145                         ASSERT(FALSE);
146         }
147         
148         if(Flag&MB_HELP){
149                 AddButton(_T("&Help"),IDHELP);
150         }
151
152         switch(Flag&MB_ICONMASK){
153                 case MB_ICONHAND:
154                         m_hIcon=AfxGetApp()->LoadStandardIcon(IDI_HAND);
155                         break;
156                 case MB_ICONQUESTION:
157                         m_hIcon=AfxGetApp()->LoadStandardIcon(IDI_QUESTION);
158                         break;
159                 case MB_ICONEXCLAMATION:
160                         m_hIcon=AfxGetApp()->LoadStandardIcon(IDI_EXCLAMATION);
161                         break;
162                 case MB_ICONASTERISK:
163                         m_hIcon=AfxGetApp()->LoadStandardIcon(IDI_ASTERISK);
164                         break;
165                 case 0:
166                         break;
167                 default:
168                         ASSERT(FALSE);
169                         break;
170         }
171 }
172
173 BEGIN_MESSAGE_MAP(CMessageBox, CDialog)
174         //{{AFX_MSG_MAP(CMessageBox)
175         ON_WM_FONTCHANGE()
176         ON_WM_CTLCOLOR()
177         ON_WM_CLOSE()
178         //}}AFX_MSG_MAP
179         ON_CONTROL_RANGE(BN_CLICKED, 1, 0xFFFF, OnButton)
180 END_MESSAGE_MAP()
181
182 /////////////////////////////////////////////////////////////////////////////
183 // CMessageBox message handlers
184
185 BOOL CMessageBox::OnInitDialog() 
186 {
187         // Create buttons as required
188         ASSERT(ButtonCount()>0);
189
190         SetWindowText(m_strCaption);
191
192         if(-1==m_nEscapeButton||IDCANCEL!=m_arBInfo[m_nEscapeButton].m_id){
193                 // No cancel button
194                 CMenu *pMenu=GetSystemMenu(FALSE);
195                 pMenu->RemoveMenu(SC_CLOSE,MF_BYCOMMAND);
196         }
197
198         CDialog::OnInitDialog();
199         CDC *pDC=GetDC();
200         CFont *pOldFont=pDC->SelectObject(m_pFont);
201         TEXTMETRIC tm;
202         pDC->GetTextMetrics(&tm);
203         
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));
217         int cyText=0;
218
219         // Size the text control according to the maximum line length
220         LPCTSTR c=m_strText;
221         while(*c){
222                 PTCHAR d=_tcsstr(c,_T("\r\n"));
223                 int nCount;
224                 if(d){
225                         *d=_TCHAR('\0');
226                         nCount=d-c;
227                 } else {\
228                         nCount=_tcslen(c);
229                 }
230                 cxText=max(cxText,pDC->GetTextExtent(c,nCount).cx);
231                 cyText+=tm.tmHeight;
232                 if(d){
233                         *d=_TCHAR('\r');
234                         c=d+2;
235                 } else {
236                         break;
237                 }
238         }
239         
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;
242
243         pDC->SelectObject(pOldFont);
244         ReleaseDC(pDC); 
245
246         // Set dialog box size
247         {
248                 int cx=(2*cxBorder)+cxText+cxButtonSep+2*GetSystemMetrics(SM_CXDLGFRAME);
249                 if(m_hIcon){
250                         cx+=cxIcon+cxTextButtonSep;
251                 }
252                 int cy=(2*cyBorder)+cyText+cyTextExtra+cyTextButtonSep+nButtonHeight+
253                         GetSystemMetrics(SM_CYCAPTION)+2*GetSystemMetrics(SM_CYDLGFRAME);
254                 UINT flags=SWP_NOMOVE;
255                 if(!m_bTopMost){
256                         flags|=SWP_NOZORDER;
257                 }
258                 SetWindowPos(&wndTopMost,0,0,cx,cy,flags);
259         }
260
261         // Create a static control for the icon
262         if(m_hIcon){
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);
267         }
268
269         // Create a static control for the text
270         {
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);
276         }
277
278         // Create the buttons
279         CRect rcClient;
280         GetClientRect(rcClient);
281         CRect rect;
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;
286
287         ASSERT(m_nDefaultButton<ButtonCount());
288
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){
295                         style|=WS_DISABLED;
296                 }
297                 if(0==i){
298                         style|=WS_GROUP;
299                 }
300                 style|=(m_nDefaultButton==i)?BS_DEFPUSHBUTTON:BS_PUSHBUTTON;
301                         
302                 pWnd->Create(m_arBInfo[i].m_strCaption,style,rect,this,id);
303                 pWnd->SetFont(m_pFont);
304                 if(m_nDefaultButton==i){
305                         pWnd->SetFocus();
306                 }
307                 rect.left+=nButtonWidth+cxButtonSep;
308                 rect.right+=nButtonWidth+cxButtonSep;
309         }
310
311         m_nFocusButton=m_nDefaultButton;
312         m_bDialogCreated=true;
313         return FALSE;
314 }
315
316 void CMessageBox::OnButton(UINT id)
317 {
318         if(-1!=IndexOf(id)){
319                 if(m_bModeless){
320                         if(NULL!=m_pParentNotify){
321                                 m_pParentNotify->PostMessage(m_nParentNotifcationMessage,MAKEWPARAM(id,m_nParentNotifcationwParamHigh),0);
322                                 DestroyWindow();
323                         }
324                 } else {
325                         EndDialog(id);
326                 }
327         }
328 }
329
330 BOOL CMessageBox::PreTranslateMessage(MSG* pMsg) 
331 {
332         if(pMsg->message==WM_KEYDOWN){
333                 switch(pMsg->wParam){
334                         case VK_ESCAPE:
335                                 if(-1!=m_nEscapeButton){
336                                         OnButton(m_arBInfo[m_nEscapeButton].m_id);
337                                 }
338                                 return TRUE;
339                         default:
340                                 break;
341                 }
342         }
343     if( IsDialogMessage( pMsg ) )        
344                 return TRUE;    
345         else
346         return CDialog::PreTranslateMessage( pMsg );
347 }
348
349 void CMessageBox::AddButton(const CString & strCaption, UINT id, bool bEnabled/*=true*/)
350 {
351 #ifdef _DEBUG
352         ASSERT(-1==IndexOf(id));
353         for(unsigned int i=0;i<ButtonCount();i++){
354                 if(0==m_arBInfo[i].m_strCaption.Compare(strCaption)){
355                         ASSERT(FALSE);
356                 }
357         }
358 #endif
359         if(bEnabled){
360                 if(IDCANCEL==id || (IDOK==id && -1==m_nEscapeButton)){
361                         m_nEscapeButton=ButtonCount();
362                 } 
363         }
364         CButtonInfo info(id,bEnabled,strCaption);
365         m_arBInfo.Add(info);
366 }
367
368 CMessageBox::~CMessageBox()
369 {
370         for(unsigned int i=0;i<ButtonCount();i++){
371                 deleteZ(m_arBInfo[i].m_pWnd);
372         }
373         deleteZ(m_pStaticText);
374         deleteZ(m_pStaticIcon);
375 }
376
377 void CMessageBox::SetDefaultButton(UINT nIndex)
378 {
379         ASSERT(nIndex<ButtonCount());
380         m_nDefaultButton=nIndex; 
381 }
382
383 void CMessageBox::OnFontChange() 
384 {
385         CDialog::OnFontChange();
386         
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);
390         }
391         m_pStaticText->SetFont(m_pFont);
392 }
393
394
395
396 HBRUSH CMessageBox::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) 
397 {
398         HBRUSH hbr=CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
399         switch(nCtlColor){
400                 case CTLCOLOR_STATIC:
401                         pDC->SetTextColor(m_crText);
402                         break;
403                 default:
404                         break;
405         }
406         return hbr;
407 }
408
409
410 BOOL CMessageBox::Create(CWnd *pWnd,UINT msg,WORD wParamHigh)
411 {
412         m_bModeless=true;
413         if(0!=msg){
414                 ASSERT(NULL!=pWnd);
415                 m_pParentNotify=pWnd;
416                 m_nParentNotifcationMessage=msg;
417                 m_nParentNotifcationwParamHigh=wParamHigh;
418         }
419         return CreateIndirect (&DlgData.tmpl,pWnd); 
420 }
421
422 int CMessageBox::IndexOf(UINT id)
423 {
424         for(unsigned int i=0;i<ButtonCount();i++){
425                 if(m_arBInfo[i].m_id==id){
426                         return (signed)i;
427                 }
428         }
429         return -1;
430 }
431
432 void CMessageBox::PostNcDestroy() 
433 {
434         if(m_bModeless){
435                 delete this;
436         } else {
437                 CDialog::PostNcDestroy();
438         }
439 }
440
441 void CMessageBox::OnClose() 
442 {
443         OnButton(IDCANCEL);
444 }
445
446 void CMessageBox::SetCaption (const CString &strCaption) 
447 {
448         m_strCaption=strCaption;
449         if(m_bDialogCreated){
450                 SetWindowText(strCaption);
451         }
452 }