Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

msgbox.c

Go to the documentation of this file.
00001 /* $Id: msgbox.c,v 1.6 2001/11/14 18:33:03 sandervl Exp $ */
00002 /*
00003  * Message boxes (based on Wine code)
00004  *
00005  * Copyright 1995 Bernd Schmidt
00006  *
00007  * Corel WINE version: 20000317
00008  *
00009  */
00010 #include <win\winbase.h>
00011 #include <win\winuser.h>
00012 #include <string.h>
00013 #include <dlgs.h>
00014 #include <misc.h>
00015 #include <heapstring.h>
00016 
00017 #define DBG_LOCALLOG    DBG_msgbox
00018 #include "dbglocal.h"
00019 
00020 #define MSGBOX_IDICON 1088
00021 #define MSGBOX_IDTEXT 100
00022 
00023 static HFONT MSGBOX_OnInit(HWND hwnd, LPMSGBOXPARAMSA lpmb)
00024 {
00025     static HFONT hFont = 0, hPrevFont = 0;
00026     RECT rect;
00027     HWND hItem;
00028     HDC hdc;
00029     int i, buttons;
00030     int bspace, bw, bh, theight, tleft, wwidth, wheight, bpos;
00031     int borheight, borwidth, iheight, ileft, iwidth, twidth, tiheight;
00032     LPCSTR lpszText;
00033     char buf[256];
00034     NONCLIENTMETRICSA nclm;
00035     BOOL hasIcon = TRUE;
00036 
00037     nclm.cbSize = sizeof(NONCLIENTMETRICSA);
00038     SystemParametersInfoA (SPI_GETNONCLIENTMETRICS, 0, &nclm, 0);
00039     hFont = CreateFontIndirectA (&nclm.lfMessageFont);
00040     /* set button font */
00041     for (i=1; i < 8; i++)
00042         SendDlgItemMessageA (hwnd, i, WM_SETFONT, (WPARAM)hFont, 0);
00043     /* set text font */
00044     SendDlgItemMessageA (hwnd, MSGBOX_IDTEXT, WM_SETFONT, (WPARAM)hFont, 0);
00045 
00046     if (HIWORD(lpmb->lpszCaption)) {
00047        SetWindowTextA(hwnd, lpmb->lpszCaption);
00048     } else {
00049        if (LoadStringA(lpmb->hInstance, LOWORD(lpmb->lpszCaption), buf, sizeof(buf)))
00050           SetWindowTextA(hwnd, buf);
00051     }
00052     if (HIWORD(lpmb->lpszText)) {
00053        lpszText = lpmb->lpszText;
00054     } else {
00055        lpszText = buf;
00056        if (!LoadStringA(lpmb->hInstance, LOWORD(lpmb->lpszText), buf, sizeof(buf)))
00057           *buf = 0;     /* FIXME ?? */
00058     }
00059     SetWindowTextA(GetDlgItem(hwnd, MSGBOX_IDTEXT), lpszText);
00060 
00061     /* Hide not selected buttons */
00062     switch(lpmb->dwStyle & MB_TYPEMASK) {
00063     case MB_OK:
00064         ShowWindow(GetDlgItem(hwnd, IDCANCEL), SW_HIDE);
00065         /* fall through */
00066     case MB_OKCANCEL:
00067         ShowWindow(GetDlgItem(hwnd, IDABORT), SW_HIDE);
00068         ShowWindow(GetDlgItem(hwnd, IDRETRY), SW_HIDE);
00069         ShowWindow(GetDlgItem(hwnd, IDIGNORE), SW_HIDE);
00070         ShowWindow(GetDlgItem(hwnd, IDYES), SW_HIDE);
00071         ShowWindow(GetDlgItem(hwnd, IDNO), SW_HIDE);
00072         break;
00073     case MB_ABORTRETRYIGNORE:
00074         ShowWindow(GetDlgItem(hwnd, IDOK), SW_HIDE);
00075         ShowWindow(GetDlgItem(hwnd, IDCANCEL), SW_HIDE);
00076         ShowWindow(GetDlgItem(hwnd, IDYES), SW_HIDE);
00077         ShowWindow(GetDlgItem(hwnd, IDNO), SW_HIDE);
00078         break;
00079     case MB_YESNO:
00080         ShowWindow(GetDlgItem(hwnd, IDCANCEL), SW_HIDE);
00081         /* fall through */
00082     case MB_YESNOCANCEL:
00083         ShowWindow(GetDlgItem(hwnd, IDOK), SW_HIDE);
00084         ShowWindow(GetDlgItem(hwnd, IDABORT), SW_HIDE);
00085         ShowWindow(GetDlgItem(hwnd, IDRETRY), SW_HIDE);
00086         ShowWindow(GetDlgItem(hwnd, IDIGNORE), SW_HIDE);
00087         break;
00088     case MB_RETRYCANCEL:
00089         ShowWindow(GetDlgItem(hwnd, IDOK), SW_HIDE);
00090         ShowWindow(GetDlgItem(hwnd, IDABORT), SW_HIDE);
00091         ShowWindow(GetDlgItem(hwnd, IDIGNORE), SW_HIDE);
00092         ShowWindow(GetDlgItem(hwnd, IDYES), SW_HIDE);
00093         ShowWindow(GetDlgItem(hwnd, IDNO), SW_HIDE);
00094         break;
00095     }
00096     /* Set the icon */
00097     switch(lpmb->dwStyle & MB_ICONMASK) {
00098     case MB_ICONEXCLAMATION:
00099         SendDlgItemMessageA(hwnd, stc1, STM_SETICON,
00100                            (WPARAM)LoadIconA(0, IDI_EXCLAMATIONA), 0);
00101         break;
00102     case MB_ICONQUESTION:
00103         SendDlgItemMessageA(hwnd, stc1, STM_SETICON,
00104                              (WPARAM)LoadIconA(0, IDI_QUESTIONA), 0);
00105         break;
00106     case MB_ICONASTERISK:
00107         SendDlgItemMessageA(hwnd, stc1, STM_SETICON,
00108                              (WPARAM)LoadIconA(0, IDI_ASTERISKA), 0);
00109         break;
00110     case MB_ICONHAND:
00111         SendDlgItemMessageA(hwnd, stc1, STM_SETICON,
00112                              (WPARAM)LoadIconA(0, IDI_HANDA), 0);
00113         break;
00114     default:
00115       /* By default, Windows 95/98/NT do not associate an icon to message boxes.
00116        * So wine should do the same.
00117        */
00118         hasIcon = FALSE;
00119         ShowWindow(GetDlgItem(hwnd,stc1),SW_HIDE);
00120         break;
00121     }
00122 
00123     /* Position everything */
00124     GetWindowRect(hwnd, &rect);
00125     borheight = rect.bottom - rect.top;
00126     borwidth  = rect.right - rect.left;
00127     GetClientRect(hwnd, &rect);
00128     borheight -= rect.bottom - rect.top;
00129     borwidth  -= rect.right - rect.left;
00130 
00131     /* Get the icon height */
00132     if (hasIcon)
00133     {
00134       GetWindowRect(GetDlgItem(hwnd, MSGBOX_IDICON), &rect);
00135       MapWindowPoints(0, hwnd, (LPPOINT)&rect, 2);
00136       iheight = rect.bottom - rect.top;
00137       ileft = rect.left;
00138       iwidth = rect.right - ileft;
00139     } else
00140     {
00141       iheight = 0;
00142       ileft = 0;
00143       iwidth = 0;
00144     }
00145 
00146     hdc = GetDC(hwnd);
00147     if (hFont)
00148         hPrevFont = SelectObject(hdc, hFont);
00149 
00150     /* Get the number of visible buttons and their size */
00151     bh = bw = 1; /* Minimum button sizes */
00152     for (buttons = 0, i = 1; i < 8; i++)
00153     {
00154         hItem = GetDlgItem(hwnd, i);
00155         if (GetWindowLongA(hItem, GWL_STYLE) & WS_VISIBLE)
00156         {
00157             char buttonText[1024];
00158             int w, h;
00159             buttons++;
00160             if (GetWindowTextA(hItem, buttonText, sizeof buttonText))
00161             {
00162                 DrawTextA( hdc, buttonText, -1, &rect, DT_LEFT | DT_EXPANDTABS | DT_CALCRECT);
00163                 h = rect.bottom - rect.top;
00164                 w = rect.right - rect.left;
00165                 if (h > bh) bh = h;
00166                 if (w > bw)  bw = w ;
00167             }
00168         }
00169     }
00170     bw = MAX(bw, bh * 2);
00171     /* Button white space */
00172     bh = bh * 2;
00173     bw = bw * 2;
00174     bspace = bw/3; /* Space between buttons */
00175 
00176     /* Get the text size */
00177     GetClientRect(GetDlgItem(hwnd, MSGBOX_IDTEXT), &rect);
00178     rect.top = rect.left = rect.bottom = 0;
00179     DrawTextA( hdc, lpszText, -1, &rect,
00180                DT_LEFT | DT_EXPANDTABS | DT_WORDBREAK | DT_CALCRECT);
00181     /* Min text width corresponds to space for the buttons */
00182     tleft = 2 * ileft + iwidth;
00183     twidth = MAX((bw + bspace) * buttons + bspace - tleft, rect.right);
00184     theight = rect.bottom;
00185 
00186     if (hFont)
00187         SelectObject(hdc, hPrevFont);
00188     ReleaseDC(hItem, hdc);
00189 
00190     tiheight = 16 + MAX(iheight, theight);
00191     wwidth  = tleft + twidth + ileft + borwidth;
00192     wheight = 8 + tiheight + bh + borheight;
00193 
00194     /* Resize the window */
00195     SetWindowPos(hwnd, 0, 0, 0, wwidth, wheight,
00196                  SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOREDRAW);
00197 
00198     /* Position the icon */
00199     SetWindowPos(GetDlgItem(hwnd, MSGBOX_IDICON), 0, ileft, (tiheight - iheight) / 2, 0, 0,
00200                  SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOREDRAW);
00201 
00202     /* Position the text */
00203     SetWindowPos(GetDlgItem(hwnd, MSGBOX_IDTEXT), 0, tleft, (tiheight - theight) / 2, twidth, theight,
00204                  SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOREDRAW);
00205 
00206     /* Position the buttons */
00207     bpos = (wwidth - (bw + bspace) * buttons + bspace) / 2;
00208     for (buttons = i = 0; i < 7; i++) {
00209         /* some arithmetic to get the right order for YesNoCancel windows */
00210         hItem = GetDlgItem(hwnd, (i + 5) % 7 + 1);
00211         if (GetWindowLongA(hItem, GWL_STYLE) & WS_VISIBLE) {
00212             if (buttons++ == ((lpmb->dwStyle & MB_DEFMASK) >> 8)) {
00213                 SetFocus(hItem);
00214                 SendMessageA( hItem, BM_SETSTYLE, BS_DEFPUSHBUTTON, TRUE );
00215             }
00216             SetWindowPos(hItem, 0, bpos, tiheight, bw, bh,
00217                          SWP_NOZORDER|SWP_NOACTIVATE|SWP_NOREDRAW);
00218             bpos += bw + bspace;
00219         }
00220     }
00221     return hFont;
00222 }
00223 
00224 
00225 /**************************************************************************
00226  *           MSGBOX_DlgProc
00227  *
00228  * Dialog procedure for message boxes.
00229  */
00230 static LRESULT CALLBACK MSGBOX_DlgProc( HWND hwnd, UINT message,
00231                                         WPARAM wParam, LPARAM lParam )
00232 {
00233   static HFONT hFont;
00234   switch(message) {
00235    case WM_INITDIALOG:
00236     hFont = MSGBOX_OnInit(hwnd, (LPMSGBOXPARAMSA)lParam);
00237     return 0;
00238 
00239    case WM_COMMAND:
00240     switch (wParam)
00241     {
00242      case IDOK:
00243      case IDCANCEL:
00244      case IDABORT:
00245      case IDRETRY:
00246      case IDIGNORE:
00247      case IDYES:
00248      case IDNO:
00249       EndDialog(hwnd, wParam);
00250       if (hFont)
00251           DeleteObject(hFont);
00252       break;
00253     }
00254 
00255    default:
00256      /* Ok. Ignore all the other messages */
00257      //TRACE("Message number %i is being ignored.\n", message);
00258     break;
00259   }
00260   return 0;
00261 }
00262 
00263 /**************************************************************************
00264  *           MessageBox32A   (USER32.391)
00265  *
00266  * NOTES
00267  *   The WARN is here to help debug erroneous MessageBoxes
00268  *   Use: -debugmsg warn+dialog,+relay
00269  */
00270 INT WINAPI MessageBoxA(HWND hWnd, LPCSTR text, LPCSTR title, UINT type)
00271 {
00272     LPVOID lpTemplate;
00273     HRSRC hRes;
00274     MSGBOXPARAMSA mbox;
00275 
00276     dprintf(("MessageBoxA %x %s %s %x", hWnd, text, title, type));
00277 
00278     if(!(hRes = FindResourceA(GetModuleHandleA("USER32"), "MSGBOX", RT_DIALOGA)))
00279         return 0;
00280     if(!(lpTemplate = (LPVOID)LoadResource(GetModuleHandleA("USER32"), hRes)))
00281         return 0;
00282 
00283     if (!text) text="<ODIN-NULL>";
00284     if (!title)
00285       title="Error";
00286     mbox.lpszCaption = title;
00287     mbox.lpszText  = text;
00288     mbox.dwStyle  = type;
00289     return DialogBoxIndirectParamA( GetWindowLongA(hWnd,GWL_HINSTANCE), lpTemplate,
00290                                       hWnd, (DLGPROC)MSGBOX_DlgProc, (LPARAM)&mbox );
00291 }
00292 
00293 
00294 /**************************************************************************
00295  *           MessageBox32W   (USER32.396)
00296  */
00297 INT WINAPI MessageBoxW( HWND hwnd, LPCWSTR text, LPCWSTR title,
00298                             UINT type )
00299 {
00300     LPSTR titleA = HEAP_strdupWtoA( GetProcessHeap(), 0, title );
00301     LPSTR textA  = HEAP_strdupWtoA( GetProcessHeap(), 0, text );
00302     INT ret;
00303 
00304     ret = MessageBoxA( hwnd, textA, titleA, type );
00305     HeapFree( GetProcessHeap(), 0, titleA );
00306     HeapFree( GetProcessHeap(), 0, textA );
00307     return ret;
00308 }
00309 
00310 
00311 /**************************************************************************
00312  *           MessageBoxEx32A   (USER32.392)
00313  */
00314 INT WINAPI MessageBoxExA( HWND hWnd, LPCSTR text, LPCSTR title,
00315                               UINT type, WORD langid )
00316 {
00317     /* ignore language id for now */
00318     return MessageBoxA(hWnd,text,title,type);
00319 }
00320 
00321 /**************************************************************************
00322  *           MessageBoxEx32W   (USER32.393)
00323  */
00324 INT WINAPI MessageBoxExW( HWND hWnd, LPCWSTR text, LPCWSTR title,
00325                               UINT type, WORD langid )
00326 {
00327     /* ignore language id for now */
00328     return MessageBoxW(hWnd,text,title,type);
00329 }
00330 
00331 
00332 /**************************************************************************
00333  *           MessageBoxIndirect32A   (USER32.394)
00334  */
00335 INT WINAPI MessageBoxIndirectA( LPMSGBOXPARAMSA msgbox )
00336 {
00337     LPVOID lpTemplate;
00338     HRSRC hRes;
00339 
00340     dprintf(("MessageBoxIndirectA %x", msgbox));
00341 
00342     if(!(hRes = FindResourceA(GetModuleHandleA("USER32"), "MSGBOX", RT_DIALOGA)))
00343         return 0;
00344     if(!(lpTemplate = (LPVOID)LoadResource(GetModuleHandleA("USER32"), hRes)))
00345         return 0;
00346 
00347     return DialogBoxIndirectParamA( msgbox->hInstance, lpTemplate,
00348                                       msgbox->hwndOwner, (DLGPROC)MSGBOX_DlgProc,
00349                                       (LPARAM)msgbox );
00350 }
00351 
00352 /**************************************************************************
00353  *           MessageBoxIndirect32W   (USER32.395)
00354  */
00355 INT WINAPI MessageBoxIndirectW( LPMSGBOXPARAMSW msgbox )
00356 {
00357     MSGBOXPARAMSA       msgboxa;
00358 
00359     memcpy(&msgboxa,msgbox,sizeof(msgboxa));
00360     if (msgbox->lpszCaption)
00361       lstrcpyWtoA((LPSTR)msgboxa.lpszCaption,msgbox->lpszCaption);
00362     if (msgbox->lpszText)
00363       lstrcpyWtoA((LPSTR)msgboxa.lpszText,msgbox->lpszText);
00364 
00365     return MessageBoxIndirectA(&msgboxa);
00366 }
00367 
00368 #ifndef __WIN32OS2__
00369 /**************************************************************************
00370  *           FatalAppExit32A   (KERNEL32.108)
00371  */
00372 void WINAPI FatalAppExitA( UINT action, LPCSTR str )
00373 {
00374     //WARN("AppExit\n");
00375     MessageBoxA( 0, str, NULL, MB_SYSTEMMODAL | MB_OK );
00376     ExitProcess(0);
00377 }
00378 
00379 
00380 /**************************************************************************
00381  *           FatalAppExit32W   (KERNEL32.109)
00382  */
00383 void WINAPI FatalAppExitW( UINT action, LPCWSTR str )
00384 {
00385     //WARN("AppExit\n");
00386     MessageBoxW( 0, str, NULL, MB_SYSTEMMODAL | MB_OK );
00387     ExitProcess(0);
00388 }
00389 #endif
00390 
00391 /*****************************************************************************
00392  * Name      : BOOL WIN32API SysErrorBox
00393  * Purpose   : Unknown
00394  * Parameters: Unknown
00395  * Variables :
00396  * Result    :
00397  * Remark    : HARDERR like ?
00398  * Status    : UNTESTED UNKNOWN STUB
00399  *
00400  * Author    : Patrick Haller [Wed, 1998/06/16 11:55]
00401  *****************************************************************************/
00402 
00403 BOOL WIN32API SysErrorBox(DWORD x1,
00404                              DWORD x2,
00405                              DWORD x3)
00406 {
00407   dprintf(("USER32: SysErrorBox(%08xh,%08xh,%08xh) not implemented.\n",
00408            x1,
00409            x2,
00410            x3));
00411 
00412   return (FALSE); /* default */
00413 }

Generated on Wed Jan 23 23:17:38 2002 for ODIN-user32 by doxygen1.2.11.1 written by Dimitri van Heesch, © 1997-2001