// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or (at
// your option) any later version.
-//
+//
// This program 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
/////////////////////////////////////////////////////////////////////////////
// Look at http://www.codeproject.com/shell/ for excellent guide
// to Windows Shell programming by Michael Dunn.
-//
+//
// This extension needs two registry values to be defined:
// HKEY_CURRENT_USER\Software\Thingamahoochie\WinMerge\ContextMenuEnabled
// defines if context menu is shown (extension enabled) and if
// overwrites 'Executable' if defined. Useful to overwrite
// option set from UI when debugging/testing.
/////////////////////////////////////////////////////////////////////////////
-/**
+/**
* @file WinMergeShell.cpp
*
* @brief Implementation of the ShellExtension class
*/
// ID line follows -- this is updated by SVN
-// $Id$
+// $Id: WinMergeShell.cpp 6933 2009-07-26 14:07:03Z kimmov $
#include "stdafx.h"
#include "ShellExtension.h"
#include "WinMergeShell.h"
#include "UnicodeString.h"
#include "RegKey.h"
-#include "coretools.h"
#include <sys/types.h>
#include <sys/stat.h>
-/**
+/**
* @brief Flags for enabling and other settings of context menu.
*/
enum ExtensionFlags
{
EXT_ENABLED = 0x01, /**< ShellExtension enabled/disabled. */
EXT_ADVANCED = 0x02, /**< Advanced menuitems enabled/disabled. */
- EXT_SUBFOLDERS = 0x04, /**< Subfolders included by default? */
};
/// Max. filecount to select
-static const int MaxFileCount = 2;
-/// Registry path to WinMerge
+static const int MaxFileCount = 3;
+/// Registry path to WinMerge
#define REGDIR _T("Software\\Thingamahoochie\\WinMerge")
static const TCHAR f_RegDir[] = REGDIR;
static const TCHAR f_RegLocaleDir[] = REGDIR _T("\\Locale");
+static const TCHAR f_RegSettingsDir[] = REGDIR _T("\\Settings");
/**
* @name Registry valuenames.
*/
-/*@{*/
+/*@{*/
/** Shell context menuitem enabled/disabled */
static const TCHAR f_RegValueEnabled[] = _T("ContextMenuEnabled");
/** 'Saved' path in advanced mode */
static const TCHAR f_RegValuePriPath[] = _T("PriExecutable");
/** LanguageId */
static const TCHAR f_LanguageId[] = _T("LanguageId");
+/** Recurse */
+static const TCHAR f_Recurse[] = _T("Recurse");
/*@}*/
-/// Shown menustate
+/**
+ * @brief The states in which the menu can be.
+ * These states define what items are added to the menu and how those
+ * items work.
+ */
enum
{
- MENU_SIMPLE = 0,
- MENU_ONESEL_NOPREV,
- MENU_ONESEL_PREV,
- MENU_TWOSEL,
+ MENU_SIMPLE = 0, /**< Simple menu, only "Compare item" is shown. */
+ MENU_ONESEL_NOPREV, /**< One item selected, no previous selections. */
+ MENU_ONESEL_PREV, /**< One item selected, previous selection exists. */
+ MENU_TWOSEL, /**< Two items are selected. */
+ MENU_THREESEL
};
#define USES_WINMERGELOCALE CWinMergeTempLocale __wmtl__
+static String GetResourceString(UINT resourceID);
+
class CWinMergeTempLocale
{
private:
LCID m_lcidOld;
public:
- CWinMergeTempLocale() {
+ CWinMergeTempLocale()
+ {
CRegKeyEx reg;
if (reg.Open(HKEY_CURRENT_USER, f_RegLocaleDir) != ERROR_SUCCESS)
return;
int iLangId = reg.ReadDword(f_LanguageId, (DWORD)-1);
if (iLangId != -1)
+ {
SetThreadLocale(MAKELCID(iLangId, SORT_DEFAULT));
+ SetThreadUILanguage(iLangId);
+ }
}
- ~CWinMergeTempLocale() {
+ ~CWinMergeTempLocale()
+ {
SetThreadLocale(m_lcidOld);
+ SetThreadUILanguage(LANGIDFROMLCID(m_lcidOld));
}
};
+/**
+ * @brief Load a string from resource.
+ * @param [in] Resource string ID.
+ * @return String loaded from resource.
+ */
+static String GetResourceString(UINT resourceID)
+{
+ TCHAR resStr[1024] = {0};
+ int res = LoadString(_Module.GetModuleInstance(), resourceID, resStr, 1024);
+ ATLASSERT(res != 0);
+ String strResource = resStr;
+ return strResource;
+}
+
+static HBITMAP MakeBitmapBackColorTransparent(HBITMAP hbmSrc)
+{
+ HDC hdcSrc = CreateCompatibleDC(NULL);
+ BITMAP bm;
+ GetObject(hbmSrc, sizeof(bm), &bm);
+ HBITMAP hbmSrcOld = (HBITMAP)SelectObject(hdcSrc, hbmSrc);
+ BITMAPINFO bi = {0};
+ bi.bmiHeader.biSize = sizeof BITMAPINFOHEADER;
+ bi.bmiHeader.biPlanes = 1;
+ bi.bmiHeader.biBitCount = 32;
+ bi.bmiHeader.biCompression = BI_RGB;
+ bi.bmiHeader.biWidth = bm.bmWidth;
+ bi.bmiHeader.biHeight = -bm.bmHeight;
+ DWORD *pBits = NULL;
+ HBITMAP hbmNew = CreateDIBSection(NULL, &bi, DIB_RGB_COLORS, (void **)&pBits, NULL, 0);
+ if (pBits)
+ {
+ COLORREF clrTP = GetPixel(hdcSrc, 0, 0);
+ int bR = GetRValue(clrTP), bG = GetGValue(clrTP), bB = GetBValue(clrTP);
+
+ for (int y = 0; y < bm.bmHeight; ++y)
+ {
+ for (int x = 0; x < bm.bmWidth; ++x)
+ {
+ COLORREF clrCur = GetPixel(hdcSrc, x, y);
+ int cR = GetRValue(clrCur), cG = GetGValue(clrCur), cB = GetBValue(clrCur);
+ if (!(abs(cR - bR) <= 1 && abs(cG - bG) <= 1 && abs(cB - bB) <= 1))
+ {
+ pBits[y * bm.bmWidth + x] = cB | (cG << 8) | (cR << 16) | 0xFF000000;
+ }
+ }
+ }
+ }
+
+ SelectObject(hdcSrc, hbmSrcOld);
+ DeleteDC(hdcSrc);
+
+ return hbmNew;
+}
+
+
/////////////////////////////////////////////////////////////////////////////
// CWinMergeShell
CWinMergeShell::CWinMergeShell()
{
m_dwMenuState = 0;
- HBITMAP hMergeBmp = LoadBitmap(_Module.GetModuleInstance(),
- MAKEINTRESOURCE(IDB_WINMERGE));
- m_MergeBmp.Attach(hMergeBmp);
+ int cx = GetSystemMetrics(SM_CXMENUCHECK);
+ int cy = GetSystemMetrics(SM_CYMENUCHECK);
+ int id_fileicon = cx > 16 ? IDB_WINMERGE32 : IDB_WINMERGE;
+ int id_diricon = cx > 16 ? IDB_WINMERGEDIR32 : IDB_WINMERGEDIR;
+
+ // compress or stretch icon bitmap according to menu item height
+ HBITMAP hMergeBmp = (HBITMAP)LoadImage(_Module.GetModuleInstance(), MAKEINTRESOURCE(id_fileicon), IMAGE_BITMAP,
+ cx, cy, LR_DEFAULTCOLOR);
+ HBITMAP hMergeDirBmp = (HBITMAP)LoadImage(_Module.GetModuleInstance(), MAKEINTRESOURCE(id_diricon), IMAGE_BITMAP,
+ cx, cy, LR_DEFAULTCOLOR);
+
+ OSVERSIONINFO osvi;
+ osvi.dwOSVersionInfoSize = sizeof OSVERSIONINFO;
+ GetVersionEx(&osvi);
+ if (osvi.dwMajorVersion >= 6)
+ {
+ m_MergeBmp = MakeBitmapBackColorTransparent(hMergeBmp);
+ DeleteObject(hMergeBmp);
+
+ m_MergeDirBmp = MakeBitmapBackColorTransparent(hMergeDirBmp);
+ DeleteObject(hMergeDirBmp);
+ }
+ else
+ {
+ m_MergeBmp = hMergeBmp;
+ m_MergeDirBmp = hMergeDirBmp;
+ }
+}
+
+/// Default destructor, unloads bitmap
+CWinMergeShell::~CWinMergeShell()
+{
+ DeleteObject(m_MergeDirBmp);
+ DeleteObject(m_MergeBmp);
}
/// Reads selected paths
return E_INVALIDARG;
// Sanity check & make sure there is at least one filename.
- UINT uNumFilesDropped = DragQueryFile (hDropInfo, 0xFFFFFFFF, NULL, 0);
+ UINT uNumFilesDropped = DragQueryFile(hDropInfo, 0xFFFFFFFF, NULL, 0);
m_nSelectedItems = uNumFilesDropped;
if (uNumFilesDropped == 0)
GlobalUnlock(stg.hGlobal);
ReleaseStgMedium(&stg);
}
+ else
+ {
+ m_nSelectedItems = 0;
+ }
- // No item selected - selection is the folder background
+ // No item selected - selection is the folder background
if (pidlFolder)
{
TCHAR szPath[MAX_PATH] = {0};
if (SHGetPathFromIDList(pidlFolder, szPath))
{
- m_strPaths[0] = szPath;
- m_nSelectedItems = 1;
+ if (m_nSelectedItems < MaxFileCount)
+ m_strPaths[m_nSelectedItems++] = szPath;
hr = S_OK;
}
else
+ {
hr = E_INVALIDARG;
+ }
}
return hr;
}
HRESULT CWinMergeShell::QueryContextMenu(HMENU hmenu, UINT uMenuIndex,
UINT uidFirstCmd, UINT uidLastCmd, UINT uFlags)
{
- AFX_MANAGE_STATE(AfxGetStaticModuleState())
int nItemsAdded = 0;
USES_WINMERGELOCALE;
}
else
{
- if (m_nSelectedItems == 1 && m_strPreviousPath.IsEmpty())
+ if (m_nSelectedItems == 1 && m_strPreviousPath.empty())
m_dwMenuState = MENU_ONESEL_NOPREV;
- else if (m_nSelectedItems == 1 && !m_strPreviousPath.IsEmpty())
+ else if (m_nSelectedItems == 1 && !m_strPreviousPath.empty())
m_dwMenuState = MENU_ONESEL_PREV;
else if (m_nSelectedItems == 2)
m_dwMenuState = MENU_TWOSEL;
+ else if (m_nSelectedItems == 3)
+ m_dwMenuState = MENU_THREESEL;
nItemsAdded = DrawAdvancedMenu(hmenu, uMenuIndex, uidFirstCmd);
}
HRESULT CWinMergeShell::GetCommandString(UINT_PTR idCmd, UINT uFlags,
UINT* pwReserved, LPSTR pszName, UINT cchMax)
{
- AFX_MANAGE_STATE(AfxGetStaticModuleState())
USES_CONVERSION;
USES_WINMERGELOCALE;
}
else
{
- if (idCmd > 1)
+ if (idCmd > 2)
return E_INVALIDARG;
}
// supplied buffer.
if (uFlags & GCS_HELPTEXT)
{
- CString strHelp;
+ String strHelp;
strHelp = GetHelpText(idCmd);
if (uFlags & GCS_UNICODE)
// We need to cast pszName to a Unicode string, and then use the
// Unicode string copy API.
- lstrcpynW((LPWSTR) pszName, T2CW(strHelp), cchMax);
+ lstrcpynW((LPWSTR) pszName, T2CW(strHelp.c_str()), cchMax);
else
// Use the ANSI string copy API to return the help string.
- lstrcpynA(pszName, T2CA(strHelp), cchMax);
+ lstrcpynA(pszName, T2CA(strHelp.c_str()), cchMax);
return S_OK;
}
/// Runs WinMerge with given paths
HRESULT CWinMergeShell::InvokeCommand(LPCMINVOKECOMMANDINFO pCmdInfo)
{
- AFX_MANAGE_STATE(AfxGetStaticModuleState())
CRegKeyEx reg;
- CString strWinMergePath;
+ String strWinMergePath;
BOOL bCompare = FALSE;
BOOL bAlterSubFolders = FALSE;
USES_WINMERGELOCALE;
if (!GetWinMergeDir(strWinMergePath))
return S_FALSE;
- // Check that file we are trying to execute exists and is executable
- if (!CheckExecutable(strWinMergePath))
+ // Check that file we are trying to execute exists
+ if (!PathFileExists(strWinMergePath.c_str()))
return S_FALSE;
if (LOWORD(pCmdInfo->lpVerb) == 0)
case MENU_ONESEL_NOPREV:
m_strPreviousPath = m_strPaths[0];
if (reg.Open(HKEY_CURRENT_USER, f_RegDir) == ERROR_SUCCESS)
- reg.WriteString(f_FirstSelection, m_strPreviousPath);
+ reg.WriteString(f_FirstSelection, m_strPreviousPath.c_str());
break;
case MENU_ONESEL_PREV:
m_strPaths[1] = m_strPaths[0];
m_strPaths[0] = m_strPreviousPath;
bCompare = TRUE;
-
+
// Forget previous selection
if (reg.Open(HKEY_CURRENT_USER, f_RegDir) == ERROR_SUCCESS)
reg.WriteString(f_FirstSelection, _T(""));
break;
case MENU_TWOSEL:
+ case MENU_THREESEL:
// "Compare" - compare paths
bCompare = TRUE;
- m_strPreviousPath.Empty();
+ m_strPreviousPath.erase();
break;
}
}
case MENU_ONESEL_PREV:
m_strPreviousPath = m_strPaths[0];
if (reg.Open(HKEY_CURRENT_USER, f_RegDir) == ERROR_SUCCESS)
- reg.WriteString(f_FirstSelection, m_strPreviousPath);
+ reg.WriteString(f_FirstSelection, m_strPreviousPath.c_str());
bCompare = FALSE;
break;
default:
// "Compare..." - user wants to compare this single item and open WinMerge
- m_strPaths[1].Empty();
+ m_strPaths[1].erase();
bCompare = TRUE;
break;
}
if ((GetAsyncKeyState(VK_CONTROL) & 0x8000) != 0)
bAlterSubFolders = TRUE;
- CString strCommandLine = FormatCmdLine(strWinMergePath, m_strPaths[0],
- m_strPaths[1], bAlterSubFolders);
+ String strCommandLine = FormatCmdLine(strWinMergePath, m_strPaths[0],
+ m_strPaths[1], bAlterSubFolders);
+
+ if (!m_strPaths[2].empty())
+ strCommandLine += _T(" \"") + m_strPaths[2] + _T("\"");
// Finally start a new WinMerge process
BOOL retVal = FALSE;
STARTUPINFO stInfo = {0};
stInfo.cb = sizeof(STARTUPINFO);
PROCESS_INFORMATION processInfo = {0};
-
- retVal = CreateProcess(NULL, (LPTSTR)(LPCTSTR)strCommandLine,
- NULL, NULL, FALSE, CREATE_DEFAULT_ERROR_MODE, NULL, NULL,
- &stInfo, &processInfo);
+
+ retVal = CreateProcess(NULL, (LPTSTR)strCommandLine.c_str(),
+ NULL, NULL, FALSE, CREATE_DEFAULT_ERROR_MODE, NULL, NULL,
+ &stInfo, &processInfo);
if (!retVal)
return S_FALSE;
}
/// Reads WinMerge path from registry
-BOOL CWinMergeShell::GetWinMergeDir(CString &strDir)
+BOOL CWinMergeShell::GetWinMergeDir(String &strDir)
{
CRegKeyEx reg;
if (!reg.QueryRegUser(f_RegDir))
return FALSE;
-
+
// Try first reading debug/test value
- strDir = reg.ReadString(f_RegValuePriPath, _T("")).c_str();
- if (strDir.IsEmpty())
+ strDir = reg.ReadString(f_RegValuePriPath, _T(""));
+ if (strDir.empty())
{
- strDir = reg.ReadString(f_RegValuePath, _T("")).c_str();
- if (strDir.IsEmpty())
+ strDir = reg.ReadString(f_RegValuePath, _T(""));
+ if (strDir.empty())
return FALSE;
- }
+ }
return TRUE;
}
-/// Checks if given file exists and is executable
-BOOL CWinMergeShell::CheckExecutable(CString path)
-{
- String sExt;
- SplitFilename(path, NULL, NULL, &sExt);
- CString ext(sExt.c_str());
-
- // Check extension
- ext.MakeLower();
- if (ext == _T("exe") || ext == _T("cmd") || ext == ("bat"))
- {
- // Check if file exists
- struct _stati64 statBuffer;
- int nRetVal = _tstati64(path, &statBuffer);
- if (nRetVal > -1)
- return TRUE;
- }
- return FALSE;
-}
-
/// Create menu for simple mode
int CWinMergeShell::DrawSimpleMenu(HMENU hmenu, UINT uMenuIndex,
UINT uidFirstCmd)
{
- CString strMenu;
- VERIFY(strMenu.LoadString(IDS_CONTEXT_MENU));
+ String strMenu = GetResourceString(IDS_CONTEXT_MENU);
+ InsertMenu(hmenu, uMenuIndex, MF_BYPOSITION, uidFirstCmd, strMenu.c_str());
- InsertMenu(hmenu, uMenuIndex, MF_BYPOSITION, uidFirstCmd, strMenu);
-
// Add bitmap
- if ((HBITMAP)m_MergeBmp != NULL)
- SetMenuItemBitmaps(hmenu, uMenuIndex, MF_BYPOSITION, m_MergeBmp, NULL);
-
+ HBITMAP hBitmap = PathIsDirectory(m_strPaths[0].c_str()) ? m_MergeDirBmp : m_MergeBmp;
+ if (hBitmap != NULL)
+ SetMenuItemBitmaps(hmenu, uMenuIndex, MF_BYPOSITION, hBitmap, NULL);
+
// Show menu item as grayed if more than two items selected
if (m_nSelectedItems > MaxFileCount)
EnableMenuItem(hmenu, uMenuIndex, MF_BYPOSITION | MF_GRAYED);
-
+
return 1;
}
int CWinMergeShell::DrawAdvancedMenu(HMENU hmenu, UINT uMenuIndex,
UINT uidFirstCmd)
{
- CString strCompare;
- CString strCompareEllipsis;
- CString strCompareTo;
- CString strReselect;
+ String strCompare = GetResourceString(IDS_COMPARE);
+ String strCompareEllipsis = GetResourceString(IDS_COMPARE_ELLIPSIS);
+ String strCompareTo = GetResourceString(IDS_COMPARE_TO);
+ String strReselect = GetResourceString(IDS_RESELECT_FIRST);
int nItemsAdded = 0;
- VERIFY(strCompare.LoadString(IDS_COMPARE));
- VERIFY(strCompareEllipsis.LoadString(IDS_COMPARE_ELLIPSIS));
- VERIFY(strCompareTo.LoadString(IDS_COMPARE_TO));
- VERIFY(strReselect.LoadString(IDS_RESELECT_FIRST));
-
switch (m_dwMenuState)
{
- // No items selected earlier
- // Select item as first item to compare
+ // No items selected earlier
+ // Select item as first item to compare
case MENU_ONESEL_NOPREV:
- InsertMenu(hmenu, uMenuIndex, MF_BYPOSITION, uidFirstCmd, strCompareTo);
+ InsertMenu(hmenu, uMenuIndex, MF_BYPOSITION, uidFirstCmd,
+ strCompareTo.c_str());
uMenuIndex++;
uidFirstCmd++;
- InsertMenu(hmenu, uMenuIndex, MF_BYPOSITION, uidFirstCmd, strCompareEllipsis);
+ InsertMenu(hmenu, uMenuIndex, MF_BYPOSITION, uidFirstCmd,
+ strCompareEllipsis.c_str());
nItemsAdded = 2;
break;
- // One item selected earlier:
- // Allow re-selecting first item or selecting second item
+ // One item selected earlier:
+ // Allow re-selecting first item or selecting second item
case MENU_ONESEL_PREV:
- InsertMenu(hmenu, uMenuIndex, MF_BYPOSITION, uidFirstCmd, strCompare);
+ InsertMenu(hmenu, uMenuIndex, MF_BYPOSITION, uidFirstCmd,
+ strCompare.c_str());
uMenuIndex++;
uidFirstCmd++;
- InsertMenu(hmenu, uMenuIndex, MF_BYPOSITION, uidFirstCmd, strReselect);
+ InsertMenu(hmenu, uMenuIndex, MF_BYPOSITION, uidFirstCmd,
+ strReselect.c_str());
nItemsAdded = 2;
break;
- // Two items selected
- // Select both items for compare
+ // Two items selected
+ // Select both items for compare
case MENU_TWOSEL:
- InsertMenu(hmenu, uMenuIndex, MF_BYPOSITION, uidFirstCmd, strCompare);
+ case MENU_THREESEL:
+ InsertMenu(hmenu, uMenuIndex, MF_BYPOSITION, uidFirstCmd,
+ strCompare.c_str());
nItemsAdded = 1;
break;
default:
- InsertMenu(hmenu, uMenuIndex, MF_BYPOSITION, uidFirstCmd, strCompare);
+ InsertMenu(hmenu, uMenuIndex, MF_BYPOSITION, uidFirstCmd,
+ strCompare.c_str());
nItemsAdded = 1;
break;
}
-
+
// Add bitmap
- if ((HBITMAP)m_MergeBmp != NULL)
+ HBITMAP hBitmap = PathIsDirectory(m_strPaths[0].c_str()) ? m_MergeDirBmp : m_MergeBmp;
+ if (hBitmap != NULL)
{
if (nItemsAdded == 2)
- SetMenuItemBitmaps(hmenu, uMenuIndex - 1, MF_BYPOSITION, m_MergeBmp, NULL);
- SetMenuItemBitmaps(hmenu, uMenuIndex, MF_BYPOSITION, m_MergeBmp, NULL);
+ SetMenuItemBitmaps(hmenu, uMenuIndex - 1, MF_BYPOSITION, hBitmap, NULL);
+ SetMenuItemBitmaps(hmenu, uMenuIndex, MF_BYPOSITION, hBitmap, NULL);
}
-
+
// Show menu item as grayed if more than two items selected
if (m_nSelectedItems > MaxFileCount)
{
}
/// Determine help text shown in explorer's statusbar
-CString CWinMergeShell::GetHelpText(UINT_PTR idCmd)
+String CWinMergeShell::GetHelpText(UINT_PTR idCmd)
{
- CString strHelp;
+ String strHelp;
// More than two items selected, advice user
if (m_nSelectedItems > MaxFileCount)
{
- VERIFY(strHelp.LoadString(IDS_CONTEXT_HELP_MANYITEMS));
+ strHelp = GetResourceString(IDS_CONTEXT_HELP_MANYITEMS);
return strHelp;
}
switch (m_dwMenuState)
{
case MENU_SIMPLE:
- VERIFY(strHelp.LoadString(IDS_CONTEXT_HELP));
+ strHelp = GetResourceString(IDS_CONTEXT_HELP);;
break;
case MENU_ONESEL_NOPREV:
- VERIFY(strHelp.LoadString(IDS_HELP_SAVETHIS));
+ strHelp = GetResourceString(IDS_HELP_SAVETHIS);
break;
-
+
case MENU_ONESEL_PREV:
- AfxFormatString1(strHelp, IDS_HELP_COMPARESAVED, m_strPreviousPath);
+ strHelp = GetResourceString(IDS_HELP_COMPARESAVED);
+ string_replace(strHelp, _T("%1"), m_strPreviousPath);
break;
-
+
case MENU_TWOSEL:
- VERIFY(strHelp.LoadString(IDS_CONTEXT_HELP));
+ case MENU_THREESEL:
+ strHelp = GetResourceString(IDS_CONTEXT_HELP);
break;
}
}
switch (m_dwMenuState)
{
case MENU_ONESEL_PREV:
- VERIFY(strHelp.LoadString(IDS_HELP_SAVETHIS));
+ strHelp = GetResourceString(IDS_HELP_SAVETHIS);
break;
default:
- VERIFY(strHelp.LoadString(IDS_CONTEXT_HELP));
+ strHelp = GetResourceString(IDS_CONTEXT_HELP);
break;
}
}
}
/// Format commandline used to start WinMerge
-CString CWinMergeShell::FormatCmdLine(const CString &winmergePath,
- const CString &path1, const CString &path2, BOOL bAlterSubFolders)
+String CWinMergeShell::FormatCmdLine(const String &winmergePath,
+ const String &path1, const String &path2, BOOL bAlterSubFolders)
{
- CString strCommandline = winmergePath;
+ String strCommandline = _T("\"") + winmergePath + _T("\"");
// Check if user wants to use context menu
BOOL bSubfoldersByDefault = FALSE;
- if (m_dwContextMenuEnabled & EXT_SUBFOLDERS) // User wants subfolders by def
- bSubfoldersByDefault = TRUE;
+ CRegKeyEx reg;
+ if (reg.Open(HKEY_CURRENT_USER, f_RegSettingsDir) == ERROR_SUCCESS)
+ bSubfoldersByDefault = reg.ReadBool(f_Recurse, FALSE);
if (bAlterSubFolders && !bSubfoldersByDefault)
strCommandline += _T(" /r");
else if (!bAlterSubFolders && bSubfoldersByDefault)
strCommandline += _T(" /r");
-
+
strCommandline += _T(" \"") + path1 + _T("\"");
-
- if (!m_strPaths[1].IsEmpty())
+
+ if (!m_strPaths[1].empty())
strCommandline += _T(" \"") + path2 + _T("\"");
return strCommandline;