Replace GetModuleHandle("user32.dll") with User32Instance.
[reactos.git] / reactos / lib / user32 / windows / messagebox.c
index 4b2e4a5..54795ff 100644 (file)
@@ -16,7 +16,7 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-/* $Id: messagebox.c,v 1.26 2004/07/22 02:32:53 navaraf Exp $
+/* $Id$
  *
  * PROJECT:         ReactOS user32.dll
  * FILE:            lib/user32/windows/messagebox.c
 
 /* INCLUDES ******************************************************************/
 
-#include <windows.h>
-#include <messages.h>
 #include <user32.h>
-#include <string.h>
-#define NTOS_MODE_USER
-#include <ntos.h>
-#include <stdio.h>
-#include <stdlib.h>
+#define NDEBUG
 #include <debug.h>
-#include "resource.h"
-
-//typedef UINT *LPUINT;
-#include <mmsystem.h>
 
 /* DEFINES *******************************************************************/
 
@@ -94,13 +84,6 @@ typedef struct _MSGBOXINFO {
 
 /* INTERNAL FUNCTIONS ********************************************************/
 
-static inline unsigned int strlenW( const WCHAR *str )
-{
-    const WCHAR *s = str;
-    while (*s) s++;
-    return s - str;
-}
-
 static INT_PTR CALLBACK MessageBoxProc( HWND hwnd, UINT message,
                                         WPARAM wParam, LPARAM lParam )
 {
@@ -108,7 +91,7 @@ static INT_PTR CALLBACK MessageBoxProc( HWND hwnd, UINT message,
   PMSGBOXINFO mbi;
   HELPINFO hi;
   HWND owner;
-  
+
   switch(message) {
     case WM_INITDIALOG:
       mbi = (PMSGBOXINFO)lParam;
@@ -118,7 +101,7 @@ static INT_PTR CALLBACK MessageBoxProc( HWND hwnd, UINT message,
         if(mbi->Icon)
           SendDlgItemMessageW(hwnd, MSGBOX_IDICON, STM_SETICON, (WPARAM)mbi->Icon, 0);
         SetWindowContextHelpId(hwnd, mbi->ContextHelpId);
-        
+
         /* set control fonts */
         SendDlgItemMessageW(hwnd, MSGBOX_IDTEXT, WM_SETFONT, (WPARAM)mbi->Font, 0);
         for(i = 0; i < mbi->nButtons; i++)
@@ -137,7 +120,7 @@ static INT_PTR CALLBACK MessageBoxProc( HWND hwnd, UINT message,
           SetTimer(hwnd, 0, mbi->Timeout, NULL);
       }
       return 0;
-    
+
     case WM_COMMAND:
       switch (LOWORD(wParam))
       {
@@ -164,7 +147,7 @@ static INT_PTR CALLBACK MessageBoxProc( HWND hwnd, UINT message,
           return 0;
       }
       return 0;
-    
+
     case WM_HELP:
       mbi = (PMSGBOXINFO)GetPropW(hwnd, L"ROS_MSGBOX");
       if(!mbi)
@@ -181,7 +164,7 @@ static INT_PTR CALLBACK MessageBoxProc( HWND hwnd, UINT message,
           SendMessageW(GetWindow(hwnd, GW_OWNER), WM_HELP, 0, (LPARAM)&hi);
       }
       return 0;
-    
+
     case WM_CLOSE:
       mbi = (PMSGBOXINFO)GetPropW(hwnd, L"ROS_MSGBOX");
       if(!mbi)
@@ -194,7 +177,7 @@ static INT_PTR CALLBACK MessageBoxProc( HWND hwnd, UINT message,
       }
       EndDialog(hwnd, IDCANCEL);
       return 1;
-    
+
     case WM_TIMER:
       if(wParam == 0)
       {
@@ -205,19 +188,17 @@ static INT_PTR CALLBACK MessageBoxProc( HWND hwnd, UINT message,
   return 0;
 }
 
-#define SAFETY_MARGIN 32 /* Extra number of bytes to allocate in case we counted wrong */
 static int
 MessageBoxTimeoutIndirectW(
-  CONST MSGBOXPARAMS *lpMsgBoxParams, UINT Timeout)
+  CONST MSGBOXPARAMSW *lpMsgBoxParams, UINT Timeout)
 {
     DLGTEMPLATE *tpl;
     DLGITEMTEMPLATE *iico, *itxt;
     NONCLIENTMETRICSW nclm;
     WCHAR capbuf[32];
-    HMODULE hUser32;
     LPVOID buf;
     BYTE *dest;
-    LPWSTR caption, text;
+    LPCWSTR caption, text;
     HFONT hFont;
     HICON Icon;
     HDC hDC;
@@ -230,25 +211,23 @@ MessageBoxTimeoutIndirectW(
     MSGBOXINFO mbi;
     BOOL defbtn = FALSE;
     DWORD units = GetDialogBaseUnits();
-    
-    hUser32 = GetModuleHandleW(L"USER32");
-    
+
     if(!lpMsgBoxParams->lpszCaption || !HIWORD((LPWSTR)lpMsgBoxParams->lpszCaption))
     {
-      LoadStringW(hUser32, IDS_ERROR, &capbuf[0], 32);
+      LoadStringW(User32Instance, IDS_ERROR, &capbuf[0], 32);
       caption = &capbuf[0];
     }
     else
       caption = (LPWSTR)lpMsgBoxParams->lpszCaption;
-      
-    if(!lpMsgBoxParams->lpszText || !HIWORD((LPWSTR)lpMsgBoxParams->lpszText))
+
+    if(!lpMsgBoxParams->lpszText || !HIWORD(lpMsgBoxParams->lpszText))
       text = L"";
     else
-      text = (LPWSTR)lpMsgBoxParams->lpszText;
-    
+      text = lpMsgBoxParams->lpszText;
+
     caplen = strlenW(caption);
     textlen = strlenW(text);
-    
+
     /* Create selected buttons */
     switch(lpMsgBoxParams->dwStyle & MB_TYPEMASK)
     {
@@ -295,7 +274,7 @@ MessageBoxTimeoutIndirectW(
     /* Create Help button */
     if(lpMsgBoxParams->dwStyle & MB_HELP)
       Buttons[nButtons++] = IDHELP;
-    
+
     switch(lpMsgBoxParams->dwStyle & MB_ICONMASK)
     {
       case MB_ICONEXCLAMATION:
@@ -315,7 +294,7 @@ MessageBoxTimeoutIndirectW(
         MessageBeep(MB_ICONHAND);
         break;
       case MB_USERICON:
-        Icon = LoadIconW(lpMsgBoxParams->hInstance, (LPCWSTR)lpMsgBoxParams->lpszIcon);
+        Icon = LoadIconW(lpMsgBoxParams->hInstance, lpMsgBoxParams->lpszIcon);
         MessageBeep(MB_OK);
         break;
       default:
@@ -328,7 +307,7 @@ MessageBoxTimeoutIndirectW(
     }
 
     /* Basic space */
-    bufsize = sizeof(DLGTEMPLATE) + 
+    bufsize = sizeof(DLGTEMPLATE) +
               2 * sizeof(WORD) +                         /* menu and class */
               (caplen + 1) * sizeof(WCHAR);              /* title */
 
@@ -347,40 +326,40 @@ MessageBoxTimeoutIndirectW(
                3 * sizeof(WORD) +
                (textlen + 1) * sizeof(WCHAR);
 
-    
+
     for(i = 0; i < nButtons; i++)
     {
       switch(Buttons[i])
       {
         case IDOK:
-          LoadStringW(hUser32, IDS_OK, ButtonText[i], MSGBOXEX_MAXBTNSTR - 1);
+          LoadStringW(User32Instance, IDS_OK, ButtonText[i], MSGBOXEX_MAXBTNSTR - 1);
           break;
         case IDCANCEL:
-          LoadStringW(hUser32, IDS_CANCEL, ButtonText[i], MSGBOXEX_MAXBTNSTR - 1);
+          LoadStringW(User32Instance, IDS_CANCEL, ButtonText[i], MSGBOXEX_MAXBTNSTR - 1);
           break;
         case IDYES:
-          LoadStringW(hUser32, IDS_YES, ButtonText[i], MSGBOXEX_MAXBTNSTR - 1);
+          LoadStringW(User32Instance, IDS_YES, ButtonText[i], MSGBOXEX_MAXBTNSTR - 1);
           break;
         case IDNO:
-          LoadStringW(hUser32, IDS_NO, ButtonText[i], MSGBOXEX_MAXBTNSTR - 1);
+          LoadStringW(User32Instance, IDS_NO, ButtonText[i], MSGBOXEX_MAXBTNSTR - 1);
           break;
         case IDTRYAGAIN:
-          LoadStringW(hUser32, IDS_TRYAGAIN, ButtonText[i], MSGBOXEX_MAXBTNSTR - 1);
+          LoadStringW(User32Instance, IDS_TRYAGAIN, ButtonText[i], MSGBOXEX_MAXBTNSTR - 1);
           break;
         case IDCONTINUE:
-          LoadStringW(hUser32, IDS_CONTINUE, ButtonText[i], MSGBOXEX_MAXBTNSTR - 1);
+          LoadStringW(User32Instance, IDS_CONTINUE, ButtonText[i], MSGBOXEX_MAXBTNSTR - 1);
           break;
         case IDABORT:
-          LoadStringW(hUser32, IDS_ABORT, ButtonText[i], MSGBOXEX_MAXBTNSTR - 1);
+          LoadStringW(User32Instance, IDS_ABORT, ButtonText[i], MSGBOXEX_MAXBTNSTR - 1);
           break;
         case IDRETRY:
-          LoadStringW(hUser32, IDS_RETRY, ButtonText[i], MSGBOXEX_MAXBTNSTR - 1);
+          LoadStringW(User32Instance, IDS_RETRY, ButtonText[i], MSGBOXEX_MAXBTNSTR - 1);
           break;
         case IDIGNORE:
-          LoadStringW(hUser32, IDS_IGNORE, ButtonText[i], MSGBOXEX_MAXBTNSTR - 1);
+          LoadStringW(User32Instance, IDS_IGNORE, ButtonText[i], MSGBOXEX_MAXBTNSTR - 1);
           break;
         case IDHELP:
-          LoadStringW(hUser32, IDS_HELP, ButtonText[i], MSGBOXEX_MAXBTNSTR - 1);
+          LoadStringW(User32Instance, IDS_HELP, ButtonText[i], MSGBOXEX_MAXBTNSTR - 1);
           break;
         default:
           ButtonText[i][0] = (WCHAR)0;
@@ -393,23 +372,22 @@ MessageBoxTimeoutIndirectW(
                  3 * sizeof(WORD) +
                  (wcslen(ButtonText[i]) + 1) * sizeof(WCHAR);
     }
-    
-    buf = RtlAllocateHeap(GetProcessHeap(), 0, bufsize + SAFETY_MARGIN);
-        /* Just to be safe.... */
+
+    buf = RtlAllocateHeap(GetProcessHeap(), 0, bufsize);
     if(!buf)
     {
       return 0;
     }
     iico = itxt = NULL;
-    
+
     hDC = CreateCompatibleDC(0);
-    
+
     nclm.cbSize = sizeof(nclm);
     SystemParametersInfoW (SPI_GETNONCLIENTMETRICS, sizeof(nclm), &nclm, 0);
     hFont = CreateFontIndirectW (&nclm.lfMessageFont);
-    
+
     tpl = (DLGTEMPLATE *)buf;
-    
+
     tpl->style = WS_CAPTION | WS_POPUP | WS_VISIBLE | WS_CLIPSIBLINGS | WS_SYSMENU | DS_CENTER | DS_MODALFRAME | DS_NOIDLEMSG;
     tpl->dwExtendedStyle = WS_EX_DLGMODALFRAME | WS_EX_WINDOWEDGE | WS_EX_CONTROLPARENT;
     if(lpMsgBoxParams->dwStyle & MB_TOPMOST)
@@ -418,10 +396,10 @@ MessageBoxTimeoutIndirectW(
       tpl->dwExtendedStyle |= WS_EX_RIGHT;
     tpl->x = 100;
     tpl->y = 100;
-    tpl->cdit = nButtons + (Icon != (HICON)0) + 1;
-    
+    tpl->cdit = nButtons + ((Icon != (HICON)0) ? 1 : 0) + 1;
+
     dest = (BYTE *)(tpl + 1);
-    
+
     *(WORD*)dest = 0; /* no menu */
     *(((WORD*)dest) + 1) = 0; /* use default window class */
     dest += 2 * sizeof(WORD);
@@ -429,7 +407,7 @@ MessageBoxTimeoutIndirectW(
     dest += caplen * sizeof(WCHAR);
     *(WCHAR*)dest = L'\0';
     dest += sizeof(WCHAR);
-    
+
     /* Create icon */
     if(Icon)
     {
@@ -438,7 +416,7 @@ MessageBoxTimeoutIndirectW(
       iico->style = WS_CHILD | WS_VISIBLE | SS_ICON;
       iico->dwExtendedStyle = 0;
       iico->id = MSGBOX_IDICON;
-      
+
       dest += sizeof(DLGITEMTEMPLATE);
       *(WORD*)dest = 0xFFFF;
       dest += sizeof(WORD);
@@ -451,7 +429,7 @@ MessageBoxTimeoutIndirectW(
       *(WORD*)dest = 0;
       dest += sizeof(WORD);
     }
-    
+
     /* create static for text */
     dest = (BYTE*)(((DWORD)dest + 3) & ~3);
     itxt = (DLGITEMTEMPLATE *)dest;
@@ -473,7 +451,7 @@ MessageBoxTimeoutIndirectW(
     dest += sizeof(WCHAR);
     *(WORD*)dest = 0;
     dest += sizeof(WORD);
-    
+
     /* create buttons */
     btnsize.cx = BTN_CX;
     btnsize.cy = BTN_CY;
@@ -511,11 +489,6 @@ MessageBoxTimeoutIndirectW(
       btnsize.cy = max(btnsize.cy, btnrect.bottom);
     }
 
-    if ((ULONG_PTR) dest != ((ULONG_PTR) buf + (ULONG_PTR) bufsize))
-    {
-      DbgPrint("Tell GvG he can't count: bufsize is %lu, but should be %lu\n", bufsize, (ULONG_PTR) dest - (ULONG_PTR) buf);
-    }
-    
     /* make first button the default button if no other is */
     if(!defbtn)
     {
@@ -523,7 +496,7 @@ MessageBoxTimeoutIndirectW(
       ibtn[0]->style |= BS_DEFPUSHBUTTON;
       mbi.DefBtn = Buttons[0];
     }
-    
+
     /* calculate position and size of controls */
     txtrect.right = GetSystemMetrics(SM_CXSCREEN) / 5 * 4;
     if(Icon)
@@ -532,11 +505,11 @@ MessageBoxTimeoutIndirectW(
     SelectObject(hDC, hFont);
     DrawTextW(hDC, text, textlen, &txtrect, DT_LEFT | DT_NOPREFIX | DT_WORDBREAK | DT_CALCRECT);
     txtrect.right++;
-    
+
     /* calculate position and size of the icon */
     rc.left = rc.bottom = rc.right = 0;
     btntop = 0;
-    
+
     if(iico)
     {
       rc.right = GetSystemMetrics(SM_CXICON);
@@ -603,7 +576,7 @@ MessageBoxTimeoutIndirectW(
       btnleft += btnsize.cx + MSGBOXEX_BUTTONSPACING;
     }
     /* calculate size and position of the messagebox window */
-    btnleft = max(btnleft - MSGBOXEX_BUTTONSPACING, rc.left + txtrect.right); 
+    btnleft = max(btnleft - MSGBOXEX_BUTTONSPACING, rc.left + txtrect.right);
     btnleft += MSGBOXEX_MARGIN;
     btntop +=  btnsize.cy + MSGBOXEX_MARGIN;
     /* set size and position of the message static */
@@ -614,7 +587,7 @@ MessageBoxTimeoutIndirectW(
     /* set size of the window */
     tpl->cx = (btnleft * 4) / LOWORD(units);
     tpl->cy = (btntop * 8) / HIWORD(units);
-    
+
     /* finally show the messagebox */
     mbi.Icon = Icon;
     mbi.Font = hFont;
@@ -624,16 +597,16 @@ MessageBoxTimeoutIndirectW(
     mbi.nButtons = nButtons;
     mbi.Btns = &Buttons[0];
     mbi.Timeout = Timeout;
-    
+
     if(hDC)
       DeleteDC(hDC);
-    
+
     ret =  DialogBoxIndirectParamW(lpMsgBoxParams->hInstance, tpl, lpMsgBoxParams->hwndOwner,
                                    MessageBoxProc, (LPARAM)&mbi);
 
     if(hFont)
       DeleteObject(hFont);
-    
+
     RtlFreeHeap(GetProcessHeap(), 0, buf);
     return ret;
 }
@@ -750,17 +723,22 @@ MessageBoxIndirectA(
     else
         captionW.Buffer = (LPWSTR)lpMsgBoxParams->lpszCaption;
 
-    if (HIWORD((UINT)lpMsgBoxParams->lpszIcon))
+    if(lpMsgBoxParams->dwStyle & MB_USERICON)
     {
-        RtlCreateUnicodeStringFromAsciiz(&iconW, (PCSZ)lpMsgBoxParams->lpszIcon);
-        /*
-         * UNICODE_STRING objects are always allocated with an extra byte so you
-         * can null-term if you want
-         */
-        iconW.Buffer[iconW.Length / sizeof(WCHAR)] = L'\0';
+        if (HIWORD((UINT)lpMsgBoxParams->lpszIcon))
+        {
+            RtlCreateUnicodeStringFromAsciiz(&iconW, (PCSZ)lpMsgBoxParams->lpszIcon);
+            /*
+             * UNICODE_STRING objects are always allocated with an extra byte so you
+             * can null-term if you want
+             */
+            iconW.Buffer[iconW.Length / sizeof(WCHAR)] = L'\0';
+        }
+        else
+            iconW.Buffer = (LPWSTR)lpMsgBoxParams->lpszIcon;
     }
     else
-        iconW.Buffer = (LPWSTR)lpMsgBoxParams->lpszIcon;
+        iconW.Buffer = NULL;
 
     msgboxW.cbSize = sizeof(msgboxW);
     msgboxW.hwndOwner = lpMsgBoxParams->hwndOwner;
@@ -781,7 +759,7 @@ MessageBoxIndirectA(
     if (HIWORD((UINT)lpMsgBoxParams->lpszCaption))
         RtlFreeUnicodeString(&captionW);
 
-    if (HIWORD((UINT)lpMsgBoxParams->lpszIcon))
+    if ((lpMsgBoxParams->dwStyle & MB_USERICON) && HIWORD((UINT)iconW.Buffer))
         RtlFreeUnicodeString(&iconW);
 
     return ret;
@@ -921,7 +899,7 @@ MessageBeep(UINT uType)
       if(waveOutGetNumDevs() == 0)
         return Beep(500, 100);    // Beep through speaker
       /* fall through */
-    case MB_OK: 
+    case MB_OK:
       EventName = L"SystemDefault";
       break;
     case MB_ICONASTERISK: