mirror of
https://github.com/reactos/reactos.git
synced 2025-04-18 19:47:14 +00:00
Rolf Kalbermatter <rolf.kalbermatter@citeng.com>
- Added SHFreeNameMappings implementation. - Modify ANSI functions to allocate intermediate Unicode strings on the heap instead of stack. Mike McCormack <mike@codeweavers.com> - Convert the shellmenu code to use unicode. svn path=/trunk/; revision=11328
This commit is contained in:
parent
b373e014a9
commit
b35df7844e
3 changed files with 197 additions and 140 deletions
|
@ -383,7 +383,7 @@
|
|||
@ stdcall SHFileOperationA(ptr)
|
||||
@ stdcall SHFileOperationW(ptr)
|
||||
@ stub SHFormatDrive
|
||||
@ stub SHFreeNameMappings
|
||||
@ stdcall SHFreeNameMappings(ptr)
|
||||
@ stdcall SHGetDesktopFolder(ptr)
|
||||
@ stdcall SHGetFileInfo(ptr long ptr long long)SHGetFileInfoAW
|
||||
@ stdcall SHGetFileInfoA(ptr long ptr long long)
|
||||
|
|
|
@ -45,18 +45,18 @@
|
|||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(shell);
|
||||
|
||||
#define IsAttribFile(x) (!(x == -1) && !(x & FILE_ATTRIBUTE_DIRECTORY))
|
||||
#define IsAttribDir(x) (!(x == -1) && (x & FILE_ATTRIBUTE_DIRECTORY))
|
||||
|
||||
#define IsAttrib(x, y) ((INVALID_FILE_ATTRIBUTES != (x)) && ((x) & (y)))
|
||||
#define IsAttribFile(x) (!((x) & FILE_ATTRIBUTE_DIRECTORY))
|
||||
#define IsAttribDir(x) IsAttrib(x, FILE_ATTRIBUTE_DIRECTORY)
|
||||
#define IsDotDir(x) ((x[0] == '.') && ((x[1] == 0) || ((x[1] == '.') && (x[2] == 0))))
|
||||
|
||||
#define FO_MASK 0xF
|
||||
|
||||
static const CHAR aWildcardFile[] = {'*','.','*',0};
|
||||
static const WCHAR wWildcardFile[] = {'*','.','*',0};
|
||||
static const WCHAR wWildcardFile[] = {'*',0};
|
||||
static const WCHAR wWildcardChars[] = {'*','?',0};
|
||||
static const WCHAR wBackslash[] = {'\\',0};
|
||||
|
||||
static BOOL SHELL_DeleteDirectoryW(LPCWSTR pszDir, BOOL bShowUI);
|
||||
static DWORD SHNotifyCreateDirectoryA(LPCSTR path, LPSECURITY_ATTRIBUTES sec);
|
||||
static DWORD SHNotifyCreateDirectoryW(LPCWSTR path, LPSECURITY_ATTRIBUTES sec);
|
||||
static DWORD SHNotifyRemoveDirectoryA(LPCSTR path);
|
||||
|
@ -130,6 +130,27 @@ BOOL SHELL_ConfirmDialogW(int nKindOfDialog, LPCWSTR szDir)
|
|||
return (IDOK == MessageBoxW(GetActiveWindow(), szBuffer, szCaption, MB_OKCANCEL | MB_ICONEXCLAMATION));
|
||||
}
|
||||
|
||||
static DWORD SHELL32_AnsiToUnicodeBuf(LPCSTR aPath, LPWSTR *wPath, DWORD minlen)
|
||||
{
|
||||
DWORD len = MultiByteToWideChar(CP_ACP, 0, aPath, -1, NULL, 0);
|
||||
|
||||
if (len < minlen)
|
||||
len = minlen;
|
||||
|
||||
*wPath = HeapAlloc(GetProcessHeap(), 0, len);
|
||||
if (*wPath)
|
||||
{
|
||||
MultiByteToWideChar(CP_ACP, 0, aPath, -1, *wPath, len);
|
||||
return NO_ERROR;
|
||||
}
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
static void SHELL32_FreeUnicodeBuf(LPWSTR wPath)
|
||||
{
|
||||
HeapFree(GetProcessHeap(), 0, wPath);
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* SHELL_DeleteDirectoryA() [internal]
|
||||
*
|
||||
|
@ -137,40 +158,18 @@ BOOL SHELL_ConfirmDialogW(int nKindOfDialog, LPCWSTR szDir)
|
|||
*/
|
||||
BOOL SHELL_DeleteDirectoryA(LPCSTR pszDir, BOOL bShowUI)
|
||||
{
|
||||
BOOL ret = TRUE;
|
||||
HANDLE hFind;
|
||||
WIN32_FIND_DATAA wfd;
|
||||
char szTemp[MAX_PATH];
|
||||
LPWSTR wPath;
|
||||
BOOL ret = FALSE;
|
||||
|
||||
/* Make sure the directory exists before eventually prompting the user */
|
||||
PathCombineA(szTemp, pszDir, aWildcardFile);
|
||||
hFind = FindFirstFileA(szTemp, &wfd);
|
||||
if (hFind == INVALID_HANDLE_VALUE)
|
||||
return FALSE;
|
||||
|
||||
if (!bShowUI || (ret = SHELL_ConfirmDialog(ASK_DELETE_FOLDER, pszDir)))
|
||||
if (!SHELL32_AnsiToUnicodeBuf(pszDir, &wPath, 0))
|
||||
{
|
||||
do
|
||||
{
|
||||
LPSTR lp = wfd.cAlternateFileName;
|
||||
if (!lp[0])
|
||||
lp = wfd.cFileName;
|
||||
if (IsDotDir(lp))
|
||||
continue;
|
||||
PathCombineA(szTemp, pszDir, lp);
|
||||
if (FILE_ATTRIBUTE_DIRECTORY & wfd.dwFileAttributes)
|
||||
ret = SHELL_DeleteDirectoryA(szTemp, FALSE);
|
||||
else
|
||||
ret = (SHNotifyDeleteFileA(szTemp) == ERROR_SUCCESS);
|
||||
} while (ret && FindNextFileA(hFind, &wfd));
|
||||
ret = SHELL_DeleteDirectoryW(wPath, bShowUI);
|
||||
SHELL32_FreeUnicodeBuf(wPath);
|
||||
}
|
||||
FindClose(hFind);
|
||||
if (ret)
|
||||
ret = (SHNotifyRemoveDirectoryA(pszDir) == ERROR_SUCCESS);
|
||||
return ret;
|
||||
}
|
||||
|
||||
BOOL SHELL_DeleteDirectoryW(LPCWSTR pszDir, BOOL bShowUI)
|
||||
static BOOL SHELL_DeleteDirectoryW(LPCWSTR pszDir, BOOL bShowUI)
|
||||
{
|
||||
BOOL ret = TRUE;
|
||||
HANDLE hFind;
|
||||
|
@ -241,11 +240,18 @@ BOOL SHELL_DeleteFileW(LPCWSTR pszFile, BOOL bShowUI)
|
|||
*/
|
||||
static DWORD SHNotifyCreateDirectoryA(LPCSTR path, LPSECURITY_ATTRIBUTES sec)
|
||||
{
|
||||
WCHAR wPath[MAX_PATH];
|
||||
LPWSTR wPath;
|
||||
DWORD retCode;
|
||||
|
||||
TRACE("(%s, %p)\n", debugstr_a(path), sec);
|
||||
|
||||
MultiByteToWideChar(CP_ACP, 0, path, -1, wPath, MAX_PATH);
|
||||
return SHNotifyCreateDirectoryW(wPath, sec);
|
||||
retCode = SHELL32_AnsiToUnicodeBuf(path, &wPath, 0);
|
||||
if (!retCode)
|
||||
{
|
||||
retCode = SHNotifyCreateDirectoryW(wPath, sec);
|
||||
SHELL32_FreeUnicodeBuf(wPath);
|
||||
}
|
||||
return retCode;
|
||||
}
|
||||
|
||||
/**********************************************************************/
|
||||
|
@ -254,19 +260,6 @@ static DWORD SHNotifyCreateDirectoryW(LPCWSTR path, LPSECURITY_ATTRIBUTES sec)
|
|||
{
|
||||
TRACE("(%s, %p)\n", debugstr_w(path), sec);
|
||||
|
||||
if (StrPBrkW(path, wWildcardChars))
|
||||
{
|
||||
/* FIXME: This test is currently necessary since our CreateDirectory
|
||||
implementation does create directories with wildcard characters
|
||||
without objection!! Once this is fixed, this here can go away. */
|
||||
SetLastError(ERROR_INVALID_NAME);
|
||||
#ifdef W98_FO_FUNCTION /* W98 */
|
||||
return ERROR_FILE_NOT_FOUND;
|
||||
#else
|
||||
return ERROR_INVALID_NAME;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (CreateDirectoryW(path, sec))
|
||||
{
|
||||
SHChangeNotify(SHCNE_MKDIR, SHCNF_PATHW, path, NULL);
|
||||
|
@ -302,11 +295,18 @@ BOOL WINAPI Win32CreateDirectoryAW(LPCVOID path, LPSECURITY_ATTRIBUTES sec)
|
|||
|
||||
static DWORD SHNotifyRemoveDirectoryA(LPCSTR path)
|
||||
{
|
||||
WCHAR wPath[MAX_PATH];
|
||||
LPWSTR wPath;
|
||||
DWORD retCode;
|
||||
|
||||
TRACE("(%s)\n", debugstr_a(path));
|
||||
|
||||
MultiByteToWideChar(CP_ACP, 0, path, -1, wPath, MAX_PATH);
|
||||
return SHNotifyRemoveDirectoryW(wPath);
|
||||
retCode = SHELL32_AnsiToUnicodeBuf(path, &wPath, 0);
|
||||
if (!retCode)
|
||||
{
|
||||
retCode = SHNotifyRemoveDirectoryW(wPath);
|
||||
SHELL32_FreeUnicodeBuf(wPath);
|
||||
}
|
||||
return retCode;
|
||||
}
|
||||
|
||||
/***********************************************************************/
|
||||
|
@ -321,7 +321,7 @@ static DWORD SHNotifyRemoveDirectoryW(LPCWSTR path)
|
|||
{
|
||||
/* Directory may be write protected */
|
||||
DWORD dwAttr = GetFileAttributesW(path);
|
||||
if (dwAttr != -1 && dwAttr & FILE_ATTRIBUTE_READONLY)
|
||||
if (IsAttrib(dwAttr, FILE_ATTRIBUTE_READONLY))
|
||||
if (SetFileAttributesW(path, dwAttr & ~FILE_ATTRIBUTE_READONLY))
|
||||
ret = RemoveDirectoryW(path);
|
||||
}
|
||||
|
@ -360,11 +360,18 @@ BOOL WINAPI Win32RemoveDirectoryAW(LPCVOID path)
|
|||
|
||||
static DWORD SHNotifyDeleteFileA(LPCSTR path)
|
||||
{
|
||||
WCHAR wPath[MAX_PATH];
|
||||
LPWSTR wPath;
|
||||
DWORD retCode;
|
||||
|
||||
TRACE("(%s)\n", debugstr_a(path));
|
||||
|
||||
MultiByteToWideChar(CP_ACP, 0, path, -1, wPath, MAX_PATH);
|
||||
return SHNotifyDeleteFileW(wPath);
|
||||
retCode = SHELL32_AnsiToUnicodeBuf(path, &wPath, 0);
|
||||
if (!retCode)
|
||||
{
|
||||
retCode = SHNotifyDeleteFileW(wPath);
|
||||
SHELL32_FreeUnicodeBuf(wPath);
|
||||
}
|
||||
return retCode;
|
||||
}
|
||||
|
||||
/***********************************************************************/
|
||||
|
@ -380,7 +387,7 @@ static DWORD SHNotifyDeleteFileW(LPCWSTR path)
|
|||
{
|
||||
/* File may be write protected or a system file */
|
||||
DWORD dwAttr = GetFileAttributesW(path);
|
||||
if ((dwAttr != -1) && (dwAttr & (FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_SYSTEM)))
|
||||
if (IsAttrib(dwAttr, FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_SYSTEM))
|
||||
if (SetFileAttributesW(path, dwAttr & ~(FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_SYSTEM)))
|
||||
ret = DeleteFileW(path);
|
||||
}
|
||||
|
@ -421,25 +428,12 @@ static DWORD SHNotifyMoveFileW(LPCWSTR src, LPCWSTR dest, BOOL bRename)
|
|||
|
||||
TRACE("(%s %s %s)\n", debugstr_w(src), debugstr_w(dest), bRename ? "renameIfExists" : "");
|
||||
|
||||
if (StrPBrkW(dest, wWildcardChars))
|
||||
{
|
||||
/* FIXME: This test is currently necessary since our MoveFile
|
||||
implementation does create files with wildcard characters
|
||||
without objection!! Once this is fixed, this here can go away. */
|
||||
SetLastError(ERROR_INVALID_NAME);
|
||||
#ifdef W98_FO_FUNCTION /* W98 */
|
||||
return ERROR_FILE_NOT_FOUND;
|
||||
#else
|
||||
return ERROR_INVALID_NAME;
|
||||
#endif
|
||||
}
|
||||
|
||||
ret = MoveFileW(src, dest);
|
||||
if (!ret)
|
||||
{
|
||||
/* Source file may be write protected or a system file */
|
||||
DWORD dwAttr = GetFileAttributesW(src);
|
||||
if ((dwAttr != -1) && (dwAttr & (FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_SYSTEM)))
|
||||
if (IsAttrib(dwAttr, FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_SYSTEM))
|
||||
if (SetFileAttributesW(src, dwAttr & ~(FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_SYSTEM)))
|
||||
ret = MoveFileW(src, dest);
|
||||
|
||||
|
@ -447,7 +441,7 @@ static DWORD SHNotifyMoveFileW(LPCWSTR src, LPCWSTR dest, BOOL bRename)
|
|||
{
|
||||
/* Destination file probably exists */
|
||||
dwAttr = GetFileAttributesW(dest);
|
||||
if (dwAttr != -1)
|
||||
if (dwAttr != INVALID_FILE_ATTRIBUTES)
|
||||
{
|
||||
FIXME("Rename on move to existing file not implemented!\n");
|
||||
}
|
||||
|
@ -486,7 +480,7 @@ static DWORD SHNotifyCopyFileW(LPCWSTR src, LPCWSTR dest, BOOL bRename)
|
|||
{
|
||||
/* Destination file probably exists */
|
||||
DWORD dwAttr = GetFileAttributesW(dest);
|
||||
if (dwAttr != -1)
|
||||
if (dwAttr != INVALID_FILE_ATTRIBUTES)
|
||||
{
|
||||
FIXME("Rename on copy to existing file not implemented!\n");
|
||||
}
|
||||
|
@ -502,7 +496,9 @@ static DWORD SHNotifyCopyFileW(LPCWSTR src, LPCWSTR dest, BOOL bRename)
|
|||
/*************************************************************************
|
||||
* SHCreateDirectory [SHELL32.165]
|
||||
*
|
||||
* Create a directory at the specified location
|
||||
* This function creates a file system folder whose fully qualified path is
|
||||
* given by path. If one or more of the intermediate folders do not exist,
|
||||
* they will be created as well.
|
||||
*
|
||||
* PARAMS
|
||||
* hWnd [I]
|
||||
|
@ -512,6 +508,8 @@ static DWORD SHNotifyCopyFileW(LPCWSTR src, LPCWSTR dest, BOOL bRename)
|
|||
* ERRROR_SUCCESS or one of the following values:
|
||||
* ERROR_BAD_PATHNAME if the path is relative
|
||||
* ERROR_FILE_EXISTS when a file with that name exists
|
||||
* ERROR_PATH_NOT_FOUND can't find the path, probably invalid
|
||||
* ERROR_INVLID_NAME if the path contains invalid chars
|
||||
* ERROR_ALREADY_EXISTS when the directory already exists
|
||||
* ERROR_FILENAME_EXCED_RANGE if the filename was to long to process
|
||||
*
|
||||
|
@ -530,28 +528,47 @@ DWORD WINAPI SHCreateDirectory(HWND hWnd, LPCVOID path)
|
|||
/*************************************************************************
|
||||
* SHCreateDirectoryExA [SHELL32.@]
|
||||
*
|
||||
* Create a directory at the specified location
|
||||
* This function creates a file system folder whose fully qualified path is
|
||||
* given by path. If one or more of the intermediate folders do not exist,
|
||||
* they will be created as well.
|
||||
*
|
||||
* PARAMS
|
||||
* hWnd [I]
|
||||
* path [I] path of directory to create
|
||||
* hWnd [I]
|
||||
* path [I] path of directory to create
|
||||
* sec [I] security attributes to use or NULL
|
||||
*
|
||||
* RETURNS
|
||||
* ERRROR_SUCCESS or one of the following values:
|
||||
* ERROR_BAD_PATHNAME if the path is relative
|
||||
* ERORO_INVALID_NAME if the path contains invalid chars
|
||||
* ERROR_BAD_PATHNAME or ERROR_PATH_NOT_FOUND if the path is relative
|
||||
* ERROR_INVLID_NAME if the path contains invalid chars
|
||||
* ERROR_FILE_EXISTS when a file with that name exists
|
||||
* ERROR_ALREADY_EXISTS when the directory already exists
|
||||
* ERROR_FILENAME_EXCED_RANGE if the filename was to long to process
|
||||
*
|
||||
* FIXME: Not implemented yet;
|
||||
* SHCreateDirectoryEx also verifies that the files will be visible. If not:
|
||||
*
|
||||
* If hWnd is set to a valid window handle, a message box is displayed warning
|
||||
* the user that the files may not be accessible. If the user chooses not to
|
||||
* proceed, the function returns ERROR_CANCELLED.
|
||||
*
|
||||
* If hWnd is set to NULL, no user interface is displayed and the function
|
||||
* returns ERROR_CANCELLED.
|
||||
*/
|
||||
int WINAPI SHCreateDirectoryExA(HWND hWnd, LPCSTR path, LPSECURITY_ATTRIBUTES sec)
|
||||
{
|
||||
WCHAR wPath[MAX_PATH];
|
||||
TRACE("(%p, %s, %p)\n",hWnd, debugstr_a(path), sec);
|
||||
LPWSTR wPath;
|
||||
DWORD retCode;
|
||||
|
||||
MultiByteToWideChar(CP_ACP, 0, path, -1, wPath, MAX_PATH);
|
||||
return SHCreateDirectoryExW(hWnd, wPath, sec);
|
||||
TRACE("(%s, %p)\n", debugstr_a(path), sec);
|
||||
|
||||
retCode = SHELL32_AnsiToUnicodeBuf(path, &wPath, 0);
|
||||
if (!retCode)
|
||||
{
|
||||
retCode = SHCreateDirectoryExW(hWnd, wPath, sec);
|
||||
SHELL32_FreeUnicodeBuf(wPath);
|
||||
}
|
||||
return retCode;
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
|
@ -560,7 +577,7 @@ int WINAPI SHCreateDirectoryExA(HWND hWnd, LPCSTR path, LPSECURITY_ATTRIBUTES se
|
|||
int WINAPI SHCreateDirectoryExW(HWND hWnd, LPCWSTR path, LPSECURITY_ATTRIBUTES sec)
|
||||
{
|
||||
int ret = ERROR_BAD_PATHNAME;
|
||||
TRACE("(%p, %s, %p)\n",hWnd, debugstr_w(path), sec);
|
||||
TRACE("(%p, %s, %p)\n", hWnd, debugstr_w(path), sec);
|
||||
|
||||
if (PathIsRelativeW(path))
|
||||
{
|
||||
|
@ -569,6 +586,7 @@ int WINAPI SHCreateDirectoryExW(HWND hWnd, LPCWSTR path, LPSECURITY_ATTRIBUTES s
|
|||
else
|
||||
{
|
||||
ret = SHNotifyCreateDirectoryW(path, sec);
|
||||
/* Refuse to work on certain error codes before trying to create directories recursively */
|
||||
if (ret != ERROR_FILE_EXISTS &&
|
||||
ret != ERROR_ALREADY_EXISTS &&
|
||||
ret != ERROR_FILENAME_EXCED_RANGE)
|
||||
|
@ -1293,6 +1311,35 @@ DWORD WINAPI SHFileOperationAW(LPVOID lpFileOp)
|
|||
return SHFileOperationA(lpFileOp);
|
||||
}
|
||||
|
||||
#define SHDSA_GetItemCount(hdsa) (*(int*)(hdsa))
|
||||
|
||||
/*************************************************************************
|
||||
* SHFreeNameMappings [shell32.246]
|
||||
*
|
||||
* Free the mapping handle returned by SHFileoperation if FOF_WANTSMAPPINGHANDLE
|
||||
* was specified.
|
||||
*
|
||||
* PARAMS
|
||||
* hNameMapping [I] handle to the name mappings used during renaming of files
|
||||
*
|
||||
*/
|
||||
void WINAPI SHFreeNameMappings(HANDLE hNameMapping)
|
||||
{
|
||||
if (hNameMapping)
|
||||
{
|
||||
int i = SHDSA_GetItemCount((HDSA)hNameMapping) - 1;
|
||||
|
||||
for (; i>= 0; i--)
|
||||
{
|
||||
LPSHNAMEMAPPINGW lp = DSA_GetItemPtr((HDSA)hNameMapping, i);
|
||||
|
||||
SHFree(lp->pszOldPath);
|
||||
SHFree(lp->pszNewPath);
|
||||
}
|
||||
DSA_Destroy((HDSA)hNameMapping);
|
||||
}
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
* SheGetDirW [SHELL32.281]
|
||||
*
|
||||
|
|
|
@ -31,14 +31,18 @@
|
|||
#include "shlobj.h"
|
||||
#include "undocshell.h"
|
||||
#include "shlwapi.h"
|
||||
#include "heap.h"
|
||||
#include "shell32_main.h"
|
||||
#include "shlguid.h"
|
||||
|
||||
#include "pidl.h"
|
||||
#include "wine/debug.h"
|
||||
|
||||
static BOOL FileMenu_AppendItemA(HMENU hMenu, LPCSTR lpText, UINT uID, int icon,
|
||||
#ifdef FM_SEPARATOR
|
||||
#undef FM_SEPARATOR
|
||||
#endif
|
||||
#define FM_SEPARATOR (LPCWSTR)1
|
||||
|
||||
static BOOL FileMenu_AppendItemW(HMENU hMenu, LPCWSTR lpText, UINT uID, int icon,
|
||||
HMENU hMenuPopup, int nItemHeight);
|
||||
|
||||
typedef struct
|
||||
|
@ -62,7 +66,7 @@ typedef struct
|
|||
{ int cchItemText;
|
||||
int iIconIndex;
|
||||
HMENU hMenu;
|
||||
char szItemText[1];
|
||||
WCHAR szItemText[1];
|
||||
} FMITEM, * LPFMITEM;
|
||||
|
||||
static BOOL bAbortInit;
|
||||
|
@ -133,7 +137,7 @@ static int FM_InitMenuPopup(HMENU hmenu, LPCITEMIDLIST pAlternatePidl)
|
|||
UINT uID, uFlags, uEnumFlags;
|
||||
LPFNFMCALLBACK lpfnCallback;
|
||||
LPCITEMIDLIST pidl;
|
||||
char sTemp[MAX_PATH];
|
||||
WCHAR sTemp[MAX_PATH];
|
||||
int NumberOfItems = 0, iIcon;
|
||||
MENUINFO MenuInfo;
|
||||
LPFMINFO menudata;
|
||||
|
@ -185,7 +189,7 @@ static int FM_InitMenuPopup(HMENU hmenu, LPCITEMIDLIST pAlternatePidl)
|
|||
{
|
||||
if (SUCCEEDED (IShellFolder_GetAttributesOf(lpsf, 1, (LPCITEMIDLIST*)&pidlTemp, &ulItemAttr)))
|
||||
{
|
||||
ILGetDisplayNameExA(NULL, pidlTemp, sTemp, ILGDN_FORPARSING);
|
||||
ILGetDisplayNameExW(NULL, pidlTemp, sTemp, ILGDN_FORPARSING);
|
||||
if (! (PidlToSicIndex(lpsf, pidlTemp, FALSE, 0, &iIcon)))
|
||||
iIcon = FM_BLANK_ICON;
|
||||
if ( SFGAO_FOLDER & ulItemAttr)
|
||||
|
@ -204,12 +208,14 @@ static int FM_InitMenuPopup(HMENU hmenu, LPCITEMIDLIST pAlternatePidl)
|
|||
MenuInfo.dwMenuData = (DWORD) lpFmMi;
|
||||
SetMenuInfo (hMenuPopup, &MenuInfo);
|
||||
|
||||
FileMenu_AppendItemA (hmenu, sTemp, uID, iIcon, hMenuPopup, FM_DEFAULT_HEIGHT);
|
||||
FileMenu_AppendItemW (hmenu, sTemp, uID, iIcon, hMenuPopup, FM_DEFAULT_HEIGHT);
|
||||
}
|
||||
else
|
||||
{
|
||||
((LPSTR)PathFindExtensionA(sTemp))[0] = 0x00;
|
||||
FileMenu_AppendItemA (hmenu, sTemp, uID, iIcon, 0, FM_DEFAULT_HEIGHT);
|
||||
LPWSTR pExt = PathFindExtensionW(sTemp);
|
||||
if (pExt)
|
||||
*pExt = 0;
|
||||
FileMenu_AppendItemW (hmenu, sTemp, uID, iIcon, 0, FM_DEFAULT_HEIGHT);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -230,7 +236,9 @@ static int FM_InitMenuPopup(HMENU hmenu, LPCITEMIDLIST pAlternatePidl)
|
|||
}
|
||||
|
||||
if ( GetMenuItemCount (hmenu) == 0 )
|
||||
{ FileMenu_AppendItemA (hmenu, "(empty)", uID, FM_BLANK_ICON, 0, FM_DEFAULT_HEIGHT);
|
||||
{
|
||||
static const WCHAR szEmpty[] = { '(','e','m','p','t','y',')',0 };
|
||||
FileMenu_AppendItemW (hmenu, szEmpty, uID, FM_BLANK_ICON, 0, FM_DEFAULT_HEIGHT);
|
||||
NumberOfItems++;
|
||||
}
|
||||
|
||||
|
@ -302,33 +310,33 @@ void WINAPI FileMenu_Destroy (HMENU hmenu)
|
|||
* FileMenu_AppendItem [SHELL32.115]
|
||||
*
|
||||
*/
|
||||
static BOOL FileMenu_AppendItemA(
|
||||
static BOOL FileMenu_AppendItemW(
|
||||
HMENU hMenu,
|
||||
LPCSTR lpText,
|
||||
LPCWSTR lpText,
|
||||
UINT uID,
|
||||
int icon,
|
||||
HMENU hMenuPopup,
|
||||
int nItemHeight)
|
||||
{
|
||||
LPSTR lpszText = (LPSTR)lpText;
|
||||
MENUITEMINFOA mii;
|
||||
MENUITEMINFOW mii;
|
||||
LPFMITEM myItem;
|
||||
LPFMINFO menudata;
|
||||
MENUINFO MenuInfo;
|
||||
|
||||
|
||||
TRACE("%p %s 0x%08x 0x%08x %p 0x%08x\n",
|
||||
hMenu, (lpszText!=FM_SEPARATOR) ? lpText: NULL,
|
||||
uID, icon, hMenuPopup, nItemHeight);
|
||||
hMenu, (lpText!=FM_SEPARATOR) ? debugstr_w(lpText) : NULL,
|
||||
uID, icon, hMenuPopup, nItemHeight);
|
||||
|
||||
ZeroMemory (&mii, sizeof(MENUITEMINFOA));
|
||||
ZeroMemory (&mii, sizeof(MENUITEMINFOW));
|
||||
|
||||
mii.cbSize = sizeof(MENUITEMINFOA);
|
||||
mii.cbSize = sizeof(MENUITEMINFOW);
|
||||
|
||||
if (lpText != FM_SEPARATOR)
|
||||
{ int len = strlen (lpText);
|
||||
myItem = (LPFMITEM) SHAlloc( sizeof(FMITEM) + len);
|
||||
strcpy (myItem->szItemText, lpText);
|
||||
{
|
||||
int len = strlenW (lpText);
|
||||
myItem = (LPFMITEM) SHAlloc( sizeof(FMITEM) + len*sizeof(WCHAR));
|
||||
strcpyW (myItem->szItemText, lpText);
|
||||
myItem->cchItemText = len;
|
||||
myItem->iIconIndex = icon;
|
||||
myItem->hMenu = hMenu;
|
||||
|
@ -354,7 +362,7 @@ static BOOL FileMenu_AppendItemA(
|
|||
}
|
||||
mii.wID = uID;
|
||||
|
||||
InsertMenuItemA (hMenu, (UINT)-1, TRUE, &mii);
|
||||
InsertMenuItemW (hMenu, (UINT)-1, TRUE, &mii);
|
||||
|
||||
/* set bFixedItems to true */
|
||||
MenuInfo.cbSize = sizeof(MENUINFO);
|
||||
|
@ -388,15 +396,17 @@ BOOL WINAPI FileMenu_AppendItemAW(
|
|||
int nItemHeight)
|
||||
{
|
||||
BOOL ret;
|
||||
LPSTR lpszText=NULL;
|
||||
|
||||
if (SHELL_OsIsUnicode() && (lpText!=FM_SEPARATOR))
|
||||
lpszText = HEAP_strdupWtoA ( GetProcessHeap(),0, lpText);
|
||||
|
||||
ret = FileMenu_AppendItemA(hMenu, (lpszText) ? lpszText : lpText, uID, icon, hMenuPopup, nItemHeight);
|
||||
|
||||
if (lpszText)
|
||||
if ((SHELL_OsIsUnicode() && (lpText!=FM_SEPARATOR)) || (lpText == NULL))
|
||||
ret = FileMenu_AppendItemW(hMenu, lpText, uID, icon, hMenuPopup, nItemHeight);
|
||||
else
|
||||
{
|
||||
DWORD len = MultiByteToWideChar( CP_ACP, 0, lpText, -1, NULL, 0 );
|
||||
LPWSTR lpszText = HeapAlloc ( GetProcessHeap(), 0, len*sizeof(WCHAR) );
|
||||
MultiByteToWideChar( CP_ACP, 0, lpText, -1, lpszText, len );
|
||||
ret = FileMenu_AppendItemW(hMenu, lpszText, uID, icon, hMenuPopup, nItemHeight);
|
||||
HeapFree( GetProcessHeap(), 0, lpszText );
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -484,7 +494,7 @@ int WINAPI FileMenu_AppendFilesForPidl(
|
|||
FM_InitMenuPopup(hmenu, pidl);
|
||||
|
||||
if (bAddSeperator)
|
||||
FileMenu_AppendItemA (hmenu, FM_SEPARATOR, 0, 0, 0, FM_DEFAULT_HEIGHT);
|
||||
FileMenu_AppendItemW (hmenu, FM_SEPARATOR, 0, 0, 0, FM_DEFAULT_HEIGHT);
|
||||
|
||||
TRACE("%p %p 0x%08x\n",hmenu, pidl,bAddSeperator);
|
||||
|
||||
|
@ -559,9 +569,9 @@ LRESULT WINAPI FileMenu_MeasureItem(
|
|||
SIZE size;
|
||||
LPFMINFO menuinfo;
|
||||
|
||||
TRACE("%p %p %s\n", hWnd, lpmis, pMyItem->szItemText);
|
||||
TRACE("%p %p %s\n", hWnd, lpmis, debugstr_w(pMyItem->szItemText));
|
||||
|
||||
GetTextExtentPoint32A(hdc, pMyItem->szItemText, pMyItem->cchItemText, &size);
|
||||
GetTextExtentPoint32W(hdc, pMyItem->szItemText, pMyItem->cchItemText, &size);
|
||||
|
||||
lpmis->itemWidth = size.cx + FM_LEFTBORDER + FM_ICON_SIZE + FM_SPACE1 + FM_SPACE2 + FM_RIGHTBORDER;
|
||||
lpmis->itemHeight = (size.cy > (FM_ICON_SIZE + FM_Y_SPACE)) ? size.cy : (FM_ICON_SIZE + FM_Y_SPACE);
|
||||
|
@ -589,7 +599,7 @@ LRESULT WINAPI FileMenu_DrawItem(
|
|||
RECT TextRect, BorderRect;
|
||||
LPFMINFO menuinfo;
|
||||
|
||||
TRACE("%p %p %s\n", hWnd, lpdis, pMyItem->szItemText);
|
||||
TRACE("%p %p %s\n", hWnd, lpdis, debugstr_w(pMyItem->szItemText));
|
||||
|
||||
if (lpdis->itemState & ODS_SELECTED)
|
||||
{
|
||||
|
@ -620,7 +630,7 @@ LRESULT WINAPI FileMenu_DrawItem(
|
|||
xt = xi + FM_ICON_SIZE + FM_SPACE2;
|
||||
yt = yi;
|
||||
|
||||
ExtTextOutA (lpdis->hDC, xt , yt, ETO_OPAQUE, &TextRect, pMyItem->szItemText, pMyItem->cchItemText, NULL);
|
||||
ExtTextOutW (lpdis->hDC, xt , yt, ETO_OPAQUE, &TextRect, pMyItem->szItemText, pMyItem->cchItemText, NULL);
|
||||
|
||||
Shell_GetImageList(0, &hImageList);
|
||||
ImageList_Draw(hImageList, pMyItem->iIconIndex, lpdis->hDC, xi, yi, ILD_NORMAL);
|
||||
|
@ -666,19 +676,19 @@ LRESULT WINAPI FileMenu_HandleMenuChar(
|
|||
*/
|
||||
BOOL WINAPI FileMenu_DeleteAllItems (HMENU hmenu)
|
||||
{
|
||||
MENUITEMINFOA mii;
|
||||
MENUITEMINFOW mii;
|
||||
LPFMINFO menudata;
|
||||
|
||||
int i;
|
||||
|
||||
TRACE("%p\n", hmenu);
|
||||
|
||||
ZeroMemory ( &mii, sizeof(MENUITEMINFOA));
|
||||
mii.cbSize = sizeof(MENUITEMINFOA);
|
||||
ZeroMemory ( &mii, sizeof(MENUITEMINFOW));
|
||||
mii.cbSize = sizeof(MENUITEMINFOW);
|
||||
mii.fMask = MIIM_SUBMENU|MIIM_DATA;
|
||||
|
||||
for (i = 0; i < GetMenuItemCount( hmenu ); i++)
|
||||
{ GetMenuItemInfoA(hmenu, i, TRUE, &mii );
|
||||
{ GetMenuItemInfoW(hmenu, i, TRUE, &mii );
|
||||
|
||||
if (mii.dwItemData)
|
||||
SHFree((LPFMINFO)mii.dwItemData);
|
||||
|
@ -702,15 +712,15 @@ BOOL WINAPI FileMenu_DeleteAllItems (HMENU hmenu)
|
|||
*/
|
||||
BOOL WINAPI FileMenu_DeleteItemByCmd (HMENU hMenu, UINT uID)
|
||||
{
|
||||
MENUITEMINFOA mii;
|
||||
MENUITEMINFOW mii;
|
||||
|
||||
TRACE("%p 0x%08x\n", hMenu, uID);
|
||||
|
||||
ZeroMemory ( &mii, sizeof(MENUITEMINFOA));
|
||||
mii.cbSize = sizeof(MENUITEMINFOA);
|
||||
ZeroMemory ( &mii, sizeof(MENUITEMINFOW));
|
||||
mii.cbSize = sizeof(MENUITEMINFOW);
|
||||
mii.fMask = MIIM_SUBMENU;
|
||||
|
||||
GetMenuItemInfoA(hMenu, uID, FALSE, &mii );
|
||||
GetMenuItemInfoW(hMenu, uID, FALSE, &mii );
|
||||
if ( mii.hSubMenu )
|
||||
{
|
||||
/* FIXME: Do what? */
|
||||
|
@ -725,15 +735,15 @@ BOOL WINAPI FileMenu_DeleteItemByCmd (HMENU hMenu, UINT uID)
|
|||
*/
|
||||
BOOL WINAPI FileMenu_DeleteItemByIndex ( HMENU hMenu, UINT uPos)
|
||||
{
|
||||
MENUITEMINFOA mii;
|
||||
MENUITEMINFOW mii;
|
||||
|
||||
TRACE("%p 0x%08x\n", hMenu, uPos);
|
||||
|
||||
ZeroMemory ( &mii, sizeof(MENUITEMINFOA));
|
||||
mii.cbSize = sizeof(MENUITEMINFOA);
|
||||
ZeroMemory ( &mii, sizeof(MENUITEMINFOW));
|
||||
mii.cbSize = sizeof(MENUITEMINFOW);
|
||||
mii.fMask = MIIM_SUBMENU;
|
||||
|
||||
GetMenuItemInfoA(hMenu, uPos, TRUE, &mii );
|
||||
GetMenuItemInfoW(hMenu, uPos, TRUE, &mii );
|
||||
if ( mii.hSubMenu )
|
||||
{
|
||||
/* FIXME: Do what? */
|
||||
|
@ -829,12 +839,12 @@ LPVOID WINAPI SHFind_InitMenuPopup (HMENU hMenu, HWND hWndParent, DWORD w, DWORD
|
|||
*/
|
||||
BOOL _SHIsMenuSeparator(HMENU hm, int i)
|
||||
{
|
||||
MENUITEMINFOA mii;
|
||||
MENUITEMINFOW mii;
|
||||
|
||||
mii.cbSize = sizeof(MENUITEMINFOA);
|
||||
mii.cbSize = sizeof(MENUITEMINFOW);
|
||||
mii.fMask = MIIM_TYPE;
|
||||
mii.cch = 0; /* WARNING: We MUST initialize it to 0*/
|
||||
if (!GetMenuItemInfoA(hm, i, TRUE, &mii))
|
||||
if (!GetMenuItemInfoW(hm, i, TRUE, &mii))
|
||||
{
|
||||
return(FALSE);
|
||||
}
|
||||
|
@ -853,8 +863,8 @@ HRESULT WINAPI Shell_MergeMenus (HMENU hmDst, HMENU hmSrc, UINT uInsert, UINT uI
|
|||
{ int nItem;
|
||||
HMENU hmSubMenu;
|
||||
BOOL bAlreadySeparated;
|
||||
MENUITEMINFOA miiSrc;
|
||||
char szName[256];
|
||||
MENUITEMINFOW miiSrc;
|
||||
WCHAR szName[256];
|
||||
UINT uTemp, uIDMax = uIDAdjust;
|
||||
|
||||
TRACE("hmenu1=%p hmenu2=%p 0x%04x 0x%04x 0x%04x 0x%04lx\n",
|
||||
|
@ -887,16 +897,16 @@ HRESULT WINAPI Shell_MergeMenus (HMENU hmDst, HMENU hmSrc, UINT uInsert, UINT uI
|
|||
/* Go through the menu items and clone them*/
|
||||
for (nItem = GetMenuItemCount(hmSrc) - 1; nItem >= 0; nItem--)
|
||||
{
|
||||
miiSrc.cbSize = sizeof(MENUITEMINFOA);
|
||||
miiSrc.cbSize = sizeof(MENUITEMINFOW);
|
||||
miiSrc.fMask = MIIM_STATE | MIIM_ID | MIIM_SUBMENU | MIIM_CHECKMARKS | MIIM_TYPE | MIIM_DATA;
|
||||
|
||||
/* We need to reset this every time through the loop in case menus DON'T have IDs*/
|
||||
miiSrc.fType = MFT_STRING;
|
||||
miiSrc.dwTypeData = szName;
|
||||
miiSrc.dwItemData = 0;
|
||||
miiSrc.cch = sizeof(szName);
|
||||
miiSrc.cch = sizeof(szName)/sizeof(WCHAR);
|
||||
|
||||
if (!GetMenuItemInfoA(hmSrc, nItem, TRUE, &miiSrc))
|
||||
if (!GetMenuItemInfoW(hmSrc, nItem, TRUE, &miiSrc))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
@ -955,7 +965,7 @@ HRESULT WINAPI Shell_MergeMenus (HMENU hmDst, HMENU hmSrc, UINT uInsert, UINT uI
|
|||
|
||||
/* TRACE("inserting menu=0x%04x %s id=0x%04x mask=0x%08x smenu=0x%04x\n", hmDst, debugstr_a(miiSrc.dwTypeData), miiSrc.wID, miiSrc.fMask, miiSrc.hSubMenu);
|
||||
*/
|
||||
if (!InsertMenuItemA(hmDst, uInsert, TRUE, &miiSrc))
|
||||
if (!InsertMenuItemW(hmDst, uInsert, TRUE, &miiSrc))
|
||||
{
|
||||
return(uIDMax);
|
||||
}
|
||||
|
@ -984,7 +994,7 @@ HRESULT WINAPI Shell_MergeMenus (HMENU hmDst, HMENU hmSrc, UINT uInsert, UINT uI
|
|||
if ((uFlags & MM_ADDSEPARATOR) && !bAlreadySeparated)
|
||||
{
|
||||
/* Add a separator between the menus*/
|
||||
InsertMenuA(hmDst, uInsert, MF_BYPOSITION | MF_SEPARATOR, 0, NULL);
|
||||
InsertMenuW(hmDst, uInsert, MF_BYPOSITION | MF_SEPARATOR, 0, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue