#include "WinMergeShell.h"
#include "UnicodeString.h"
#include "RegKey.h"
-#include "coretools.h"
#include <sys/types.h>
#include <sys/stat.h>
{
EXT_ENABLED = 0x01, /**< ShellExtension enabled/disabled. */
EXT_ADVANCED = 0x02, /**< Advanced menuitems enabled/disabled. */
- EXT_SUBFOLDERS = 0x04, /**< Subfolders included by default? */
};
/// Max. filecount to select
#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.
static const TCHAR f_RegValuePriPath[] = _T("PriExecutable");
/** LanguageId */
static const TCHAR f_LanguageId[] = _T("LanguageId");
+/** Recurse */
+static const TCHAR f_Recurse[] = _T("Recurse");
/*@}*/
/**
m_lcidOld = GetThreadLocale();
- int iLangId = reg.ReadDword(f_LanguageId, (DWORD) - 1);
+ int iLangId = reg.ReadDword(f_LanguageId, (DWORD)-1);
if (iLangId != -1)
+ {
SetThreadLocale(MAKELCID(iLangId, SORT_DEFAULT));
+ SetThreadUILanguage(iLangId);
+ }
}
~CWinMergeTempLocale()
{
SetThreadLocale(m_lcidOld);
+ SetThreadUILanguage(LANGIDFROMLCID(m_lcidOld));
}
};
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;
+ 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
- m_MergeBmp = (HBITMAP)LoadImage(_Module.GetModuleInstance(), MAKEINTRESOURCE(IDB_WINMERGE), IMAGE_BITMAP,
- GetSystemMetrics(SM_CXMENUCHECK), GetSystemMetrics(SM_CYMENUCHECK), LR_DEFAULTCOLOR);
+ 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);
}
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;
}
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)
return TRUE;
}
-/// Checks if given file exists and is executable
-BOOL CWinMergeShell::CheckExecutable(String path)
-{
- String sExt;
- SplitFilename(path.c_str(), NULL, NULL, &sExt);
-
- // Check extension
- if (_tcsicmp(sExt.c_str(), _T("exe")) == 0 ||
- _tcsicmp(sExt.c_str(), _T("cmd")) == 0 ||
- _tcsicmp(sExt.c_str(), _T("bat")) == 0)
- {
- // Check if file exists
- struct _stati64 statBuffer;
- int nRetVal = _tstati64(path.c_str(), &statBuffer);
- if (nRetVal > -1)
- return TRUE;
- }
- return FALSE;
-}
-
/// Create menu for simple mode
int CWinMergeShell::DrawSimpleMenu(HMENU hmenu, UINT uMenuIndex,
UINT uidFirstCmd)
InsertMenu(hmenu, uMenuIndex, MF_BYPOSITION, uidFirstCmd, strMenu.c_str());
// Add bitmap
- if (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)
}
// Add bitmap
- if (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
String CWinMergeShell::FormatCmdLine(const String &winmergePath,
const String &path1, const String &path2, BOOL bAlterSubFolders)
{
- String 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");