296 lines
9.2 KiB
C
296 lines
9.2 KiB
C
/*
|
|
* SHLWAPI message box functions
|
|
*
|
|
* Copyright 2004 Jon Griffiths
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
* License as published by the Free Software Foundation; either
|
|
* version 2.1 of the License, or (at your option) any later version.
|
|
*
|
|
* This library is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with this library; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
|
*/
|
|
|
|
#include "config.h"
|
|
#include "wine/port.h"
|
|
|
|
#include <stdarg.h>
|
|
#include <string.h>
|
|
|
|
#define NONAMELESSUNION
|
|
#define NONAMELESSSTRUCT
|
|
#include "windef.h"
|
|
#include "winbase.h"
|
|
#include "winuser.h"
|
|
#include "winreg.h"
|
|
#include "shlwapi.h"
|
|
#include "wine/unicode.h"
|
|
#include "wine/debug.h"
|
|
#include "resource.h"
|
|
|
|
|
|
WINE_DEFAULT_DEBUG_CHANNEL(shell);
|
|
|
|
extern HINSTANCE shlwapi_hInstance; /* in shlwapi_main.c */
|
|
|
|
static const WCHAR szDontShowKey[] = { 'S','o','f','t','w','a','r','e','\\',
|
|
'M','i','c','r','o','s','o','f','t','\\','W','i','n','d','o','w','s','\\',
|
|
'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
|
|
'E','x','p','l','o','r','e','r','\\','D','o','n','t','S','h','o','w',
|
|
'M','e','T','h','i','s','D','i','a','l','o','g','A','g','a','i','n','\0'
|
|
};
|
|
|
|
INT_PTR WINAPI SHMessageBoxCheckExW(HWND,HINSTANCE,LPCWSTR,DLGPROC,LPARAM,INT_PTR,LPCWSTR);
|
|
INT_PTR WINAPI SHMessageBoxCheckW(HWND,LPCWSTR,LPCWSTR,DWORD,INT_PTR,LPCWSTR);
|
|
|
|
/* Data held by each general message boxes */
|
|
typedef struct tagDLGDATAEX
|
|
{
|
|
DLGPROC dlgProc; /* User supplied DlgProc */
|
|
LPARAM lParam; /* User supplied LPARAM for dlgProc */
|
|
LPCWSTR lpszId; /* Name of reg key holding whether to skip */
|
|
} DLGDATAEX;
|
|
|
|
/* Dialogue procedure for general message boxes */
|
|
static INT_PTR CALLBACK SHDlgProcEx(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
DLGDATAEX *d = (DLGDATAEX *)GetWindowLongPtrW(hDlg, DWLP_USER);
|
|
|
|
TRACE("(%p,%u,%ld,%ld) data %p\n", hDlg, uMsg, wParam, lParam, d);
|
|
|
|
switch (uMsg)
|
|
{
|
|
case WM_INITDIALOG:
|
|
{
|
|
/* FIXME: Not sure where native stores its lParam */
|
|
SetWindowLongPtrW(hDlg, DWLP_USER, lParam);
|
|
d = (DLGDATAEX *)lParam;
|
|
TRACE("WM_INITDIALOG: %p, %s,%p,%p\n", hDlg, debugstr_w(d->lpszId),
|
|
d->dlgProc, (void*)d->lParam);
|
|
if (d->dlgProc)
|
|
return d->dlgProc(hDlg, uMsg, wParam, d->lParam);
|
|
return TRUE;
|
|
}
|
|
|
|
case WM_COMMAND:
|
|
switch (LOWORD(wParam))
|
|
{
|
|
case IDYES:
|
|
wParam = MAKELONG(IDOK, HIWORD(wParam));
|
|
/* Fall through ... */
|
|
case IDNO:
|
|
if (LOWORD(wParam) == IDNO)
|
|
wParam = MAKELONG(IDCANCEL, HIWORD(wParam));
|
|
/* Fall through ... */
|
|
case IDOK:
|
|
case IDCANCEL:
|
|
|
|
TRACE("WM_COMMAND: id=%s data=%p\n",
|
|
LOWORD(wParam) == IDOK ? "IDOK" : "IDCANCEL", d);
|
|
|
|
if (SendMessageW(GetDlgItem(hDlg, IDC_ERR_DONT_SHOW), BM_GETCHECK, 0L, 0L))
|
|
{
|
|
DWORD dwZero = 0;
|
|
|
|
/* The user clicked 'don't show again', so set the key */
|
|
SHRegSetUSValueW(szDontShowKey, d->lpszId, REG_DWORD, &dwZero,
|
|
sizeof(dwZero), SHREGSET_DEFAULT);
|
|
}
|
|
if (!d->dlgProc || !d->dlgProc(hDlg, uMsg, wParam, lParam))
|
|
EndDialog(hDlg, wParam);
|
|
return TRUE;
|
|
}
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
if (d && d->dlgProc)
|
|
return d->dlgProc(hDlg, uMsg, wParam, lParam);
|
|
return FALSE;
|
|
}
|
|
|
|
/*************************************************************************
|
|
* @ [SHLWAPI.291]
|
|
*
|
|
* Pop up a 'Don't show this message again' dialogue box.
|
|
*
|
|
* PARAMS
|
|
* hWnd [I] Window to be the dialogues' parent
|
|
* hInst [I] Instance of the module holding the dialogue resource
|
|
* lpszName [I] Resource Id of the dialogue resource
|
|
* dlgProc [I] Dialog procedure, or NULL for default handling
|
|
* lParam [I] LPARAM to pass to dlgProc
|
|
* iRet [I] Value to return if dialogue is not shown
|
|
* lpszId [I] Name of registry subkey which determines whether to show the dialog
|
|
*
|
|
* RETURNS
|
|
* Success: The value returned from the dialogue procedure.
|
|
* Failure: iRet, if the dialogue resource could not be loaded or the dialogue
|
|
* should not be shown.
|
|
*
|
|
* NOTES
|
|
* Both lpszName and lpszId must be less than MAX_PATH in length.
|
|
*/
|
|
INT_PTR WINAPI SHMessageBoxCheckExA(HWND hWnd, HINSTANCE hInst, LPCSTR lpszName,
|
|
DLGPROC dlgProc, LPARAM lParam, INT_PTR iRet,
|
|
LPCSTR lpszId)
|
|
{
|
|
WCHAR szNameBuff[MAX_PATH], szIdBuff[MAX_PATH];
|
|
LPCWSTR szName = szNameBuff;
|
|
|
|
if (HIWORD(lpszName))
|
|
MultiByteToWideChar(CP_ACP, 0, lpszName, -1, szNameBuff, MAX_PATH);
|
|
else
|
|
szName = (LPCWSTR)lpszName; /* Resource Id or NULL */
|
|
|
|
MultiByteToWideChar(CP_ACP, 0, lpszId, -1, szIdBuff, MAX_PATH);
|
|
|
|
return SHMessageBoxCheckExW(hWnd, hInst, szName, dlgProc, lParam, iRet, szIdBuff);
|
|
}
|
|
|
|
/*************************************************************************
|
|
* @ [SHLWAPI.292]
|
|
*
|
|
* Unicode version of SHMessageBoxCheckExW.
|
|
*/
|
|
INT_PTR WINAPI SHMessageBoxCheckExW(HWND hWnd, HINSTANCE hInst, LPCWSTR lpszName,
|
|
DLGPROC dlgProc, LPARAM lParam, INT_PTR iRet, LPCWSTR lpszId)
|
|
{
|
|
DLGDATAEX d;
|
|
|
|
if (!SHRegGetBoolUSValueW(szDontShowKey, lpszId, FALSE, TRUE))
|
|
return iRet;
|
|
|
|
d.dlgProc = dlgProc;
|
|
d.lParam = lParam;
|
|
d.lpszId = lpszId;
|
|
return DialogBoxParamW(hInst, (LPCWSTR)lpszName, hWnd, SHDlgProcEx, (LPARAM)&d);
|
|
}
|
|
|
|
/* Data held by each shlwapi message box */
|
|
typedef struct tagDLGDATA
|
|
{
|
|
LPCWSTR lpszTitle; /* User supplied message title */
|
|
LPCWSTR lpszText; /* User supplied message text */
|
|
DWORD dwType; /* Message box type */
|
|
} DLGDATA;
|
|
|
|
/* Dialogue procedure for shlwapi message boxes */
|
|
static INT_PTR CALLBACK SHDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
TRACE("(%p,%u,%ld,%ld)\n", hDlg, uMsg, wParam, lParam);
|
|
|
|
switch (uMsg)
|
|
{
|
|
case WM_INITDIALOG:
|
|
{
|
|
DLGDATA *d = (DLGDATA *)lParam;
|
|
TRACE("WM_INITDIALOG: %p, %s,%s,%d\n", hDlg, debugstr_w(d->lpszTitle),
|
|
debugstr_w(d->lpszText), d->dwType);
|
|
|
|
SetWindowTextW(hDlg, d->lpszTitle);
|
|
SetWindowTextW(GetDlgItem(hDlg, IDS_ERR_USER_MSG), d->lpszText);
|
|
|
|
/* Set buttons according to dwType */
|
|
switch (d->dwType)
|
|
{
|
|
case 0:
|
|
ShowWindow(GetDlgItem(hDlg, IDCANCEL), SW_HIDE);
|
|
/* FIXME: Move OK button to position of the Cancel button (cosmetic) */
|
|
case 1:
|
|
ShowWindow(GetDlgItem(hDlg, IDYES), SW_HIDE);
|
|
ShowWindow(GetDlgItem(hDlg, IDNO), SW_HIDE);
|
|
break;
|
|
default:
|
|
ShowWindow(GetDlgItem(hDlg, IDOK), SW_HIDE);
|
|
ShowWindow(GetDlgItem(hDlg, IDCANCEL), SW_HIDE);
|
|
break;
|
|
}
|
|
return TRUE;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
/*************************************************************************
|
|
* @ [SHLWAPI.185]
|
|
*
|
|
* Pop up a 'Don't show this message again' dialogue box.
|
|
*
|
|
* PARAMS
|
|
* hWnd [I] Window to be the dialogues' parent
|
|
* lpszText [I] Text of the message to show
|
|
* lpszTitle [I] Title of the dialogue box
|
|
* dwType [I] Type of dialogue buttons (See below)
|
|
* iRet [I] Value to return if dialogue is not shown
|
|
* lpszId [I] Name of registry subkey which determines whether to show the dialog
|
|
*
|
|
* RETURNS
|
|
* Success: The value returned from the dialogue procedure (e.g. IDOK).
|
|
* Failure: iRet, if the default dialogue resource could not be loaded or the
|
|
* dialogue should not be shown.
|
|
*
|
|
* NOTES
|
|
* - Both lpszTitle and lpszId must be less than MAX_PATH in length.
|
|
* - Possible values for dwType are:
|
|
*| Value Buttons
|
|
*| ----- -------
|
|
*| 0 OK
|
|
*| 1 OK/Cancel
|
|
*| 2 Yes/No
|
|
*/
|
|
INT_PTR WINAPI SHMessageBoxCheckA(HWND hWnd, LPCSTR lpszText, LPCSTR lpszTitle,
|
|
DWORD dwType, INT_PTR iRet, LPCSTR lpszId)
|
|
{
|
|
WCHAR szTitleBuff[MAX_PATH], szIdBuff[MAX_PATH];
|
|
WCHAR *szTextBuff = NULL;
|
|
int iLen;
|
|
INT_PTR iRetVal;
|
|
|
|
if (lpszTitle)
|
|
MultiByteToWideChar(CP_ACP, 0, lpszTitle, -1, szTitleBuff, MAX_PATH);
|
|
|
|
if (lpszText)
|
|
{
|
|
iLen = MultiByteToWideChar(CP_ACP, 0, lpszText, -1, NULL, 0);
|
|
szTextBuff = HeapAlloc(GetProcessHeap(), 0, iLen * sizeof(WCHAR));
|
|
MultiByteToWideChar(CP_ACP, 0, lpszText, -1, szTextBuff, iLen);
|
|
}
|
|
|
|
MultiByteToWideChar(CP_ACP, 0, lpszId, -1, szIdBuff, MAX_PATH);
|
|
|
|
iRetVal = SHMessageBoxCheckW(hWnd, szTextBuff, lpszTitle ? szTitleBuff : NULL,
|
|
dwType, iRet, szIdBuff);
|
|
HeapFree(GetProcessHeap(), 0, szTextBuff);
|
|
return iRetVal;
|
|
}
|
|
|
|
/*************************************************************************
|
|
* @ [SHLWAPI.191]
|
|
*
|
|
* Unicode version of SHMessageBoxCheckA.
|
|
*/
|
|
INT_PTR WINAPI SHMessageBoxCheckW(HWND hWnd, LPCWSTR lpszText, LPCWSTR lpszTitle,
|
|
DWORD dwType, INT_PTR iRet, LPCWSTR lpszId)
|
|
{
|
|
DLGDATA d;
|
|
|
|
d.lpszTitle = lpszTitle;
|
|
d.lpszText = lpszText;
|
|
d.dwType = dwType;
|
|
|
|
return SHMessageBoxCheckExW(hWnd, shlwapi_hInstance, (LPCWSTR)IDD_ERR_DIALOG,
|
|
SHDlgProc, (LPARAM)&d, iRet, lpszId);
|
|
}
|