[Winmerge-svn] SF.net SVN: winmerge: [5074] trunk
Windows visual diff and merge for files and directories
Brought to you by:
christianlist,
grimmdp
From: <sdo...@us...> - 2008-02-23 23:59:14
|
Revision: 5074 http://winmerge.svn.sourceforge.net/winmerge/?rev=5074&view=rev Author: sdottaka Date: 2008-02-23 14:55:41 -0800 (Sat, 23 Feb 2008) Log Message: ----------- BUG: [ 1886580 ] sintance.h / sintance.cpp license not compatible? Modified Paths: -------------- trunk/Docs/Users/ChangeLog.txt trunk/Src/MainFrm.cpp trunk/Src/MainFrm.h trunk/Src/Merge.cpp trunk/Src/Merge.dsp Removed Paths: ------------- trunk/Src/Common/sinstance.cpp trunk/Src/Common/sinstance.h Modified: trunk/Docs/Users/ChangeLog.txt =================================================================== --- trunk/Docs/Users/ChangeLog.txt 2008-02-23 11:42:46 UTC (rev 5073) +++ trunk/Docs/Users/ChangeLog.txt 2008-02-23 22:55:41 UTC (rev 5074) @@ -2,6 +2,9 @@ Numbers in parentheses refer to SourceForge.net tracker item numbers (#XXXXX) or to Subversion revision numbers (rXXXXX). +WinMerge 2.7.7.6 + Remove sintance.h/sintance.cpp as not compatible with GPL (#1886580) + WinMerge 2.7.7.5 - 2008-02-22 (r5069) Cleaning up Help-menu (#1875111) Right-align tab size number in editor options (r5037) Deleted: trunk/Src/Common/sinstance.cpp =================================================================== --- trunk/Src/Common/sinstance.cpp 2008-02-23 11:42:46 UTC (rev 5073) +++ trunk/Src/Common/sinstance.cpp 2008-02-23 22:55:41 UTC (rev 5074) @@ -1,297 +0,0 @@ -/* -Module : SINSTANCE.CPP -Purpose: Defines the implementation for an MFC wrapper classe - to do instance checking -Created: PJN / 29-07-1998 -History: PJN / 25-03-2000 Neville Franks made the following changes. Contact ne...@ge..., www.getsoft.com - 1. Changed #pragma error to #pragma message. Former wouldn't compile under VC6 - 2. Replaced above #pragma with #include - 3. Added TrackFirstInstanceRunning(), MakeMMFFilename() - PJN / 27-03-2000 1. Fixed a potential handle leak where the file handle m_hPrevInstance was not being - closed under certain circumstances. - Neville Franks made the following changes. Contact ne...@ge..., www.getsoft.com - 2. Split PreviousInstanceRunning() up into separate functions so we - can call it without needing the MainFrame window. - 3. Changed ActivatePreviousInstance() to return hWnd. - PJN / 15-05-2000 1. Serialized access to all of the CSingleInstance class to prevent race conditions - which can occur when you app is programatically spawned. - PJN / 17-05-2000 1. Updated sample to show how the code can be used for dialog based apps. - PJN / 01-01-2001 1. Added a number of asserts to CInstanceChecker::ActivatePreviousInstance - 2. Now includes copyright message in the source code and documentation. - PJN / 15-01-2001 1. Now allows multiple calls to PreviousInstanceRunning without ASSERTing - 2. Removed some unnecessary VERIFY's from ActivatePreviousInstance - 3. Made the MMF filename used modifiable via a virtual function GetMMFFilename - 4. Made the window to track modifiable via a virtual function GetWindowToTrack - 5. Made destructor virtual since the introduction of other virtual functions in the class - 6. Removed a number of unnecessary verifies - 7. Changed the meaning of the return value from TrackFirstInstanceRunning - PJN / 17-06-2001 1. Moved most of the code from CInstanceChecker::CInstanceChecker to - CInstanceChecker::ActivateChecker. This allows client code to turn on or off the instance - checking code easily. Thanks to Anders Rundegren for this addition. - PJN / 31-08-2001 1. made the name of the mutex which the class uses to serialize access to itself a paramter - to the constructor. That way multiple independent apps do not block each other while - they are calling into the CSingleInstance class. Thanks to Eugene Shmelyov for spotting - this problem. - PJN / 23-03-2002 1. Provided a QuitPreviousInstance method. Thanks to Jon Bennett for providing this. - PJN / 30-10-2002 1. The name of the internal memory mapped file is now based on the Mutex name rather than - the application name. An example: a client was writing a webcam application and wanted it to - run with multiple configuration for multiple camera support. So the app can run multiple times - as long as a special configuration is given on the command line. But for that configuration - only one instance is allowed. Using the application name for the memory mapped file was tying - the single instance to the app rather than the unique mutex name. Thanks to Frank Fesevur for - this nice update. - PJN / 06-02-2003 1. Was missing a call to ReleaseLock in CInstanceChecker::ActivatePreviousInstance. Thanks to - Pierrick Ingels for reporting this problem. - - - -Copyright (c) 1996 - 2003 by PJ Naughter. (Web: www.naughter.com, Email: pj...@na...) - -All rights reserved. - -Copyright / Usage Details: - -You are allowed to include the source code in any product (commercial, shareware, freeware or otherwise) -when your product is released in binary form. You are allowed to modify the source code in any way you want -except you cannot modify the copyright details at the top of each module. If you want to distribute source -code with your application, then you are only allowed to distribute versions released by the author. This is -to maintain a single distribution point for the source code. - -*/ - - -///////////////////////////////// Includes ////////////////////////////////// - -#include "stdafx.h" -#include "sinstance.h" - - - -/////////////////////////////// Defines / Macros ////////////////////////////// - -#ifdef _DEBUG -#undef THIS_FILE -static char BASED_CODE THIS_FILE[] = __FILE__; -#define new DEBUG_NEW -#endif - - - -///////////////////////////////// Implementation ////////////////////////////// - -//struct which is put into shared memory -struct CWindowInstance -{ - HWND hMainWnd; -}; - -//Class which be used as a static to ensure that we -//only close the file mapping at the very last chance -class _INSTANCE_DATA -{ -public: - _INSTANCE_DATA(); - ~_INSTANCE_DATA(); - -protected: - HANDLE hInstanceData; - friend class CInstanceChecker; -}; - -_INSTANCE_DATA::_INSTANCE_DATA() -{ - hInstanceData = NULL; -} - -_INSTANCE_DATA::~_INSTANCE_DATA() -{ - if (hInstanceData != NULL) - { - ::CloseHandle(hInstanceData); - hInstanceData = NULL; - } -} - -static _INSTANCE_DATA instanceData; - - -CInstanceChecker::CInstanceChecker(const CString& sMutexName) : m_executeMutex(FALSE, sMutexName) -{ - //Hive away the unique name as we will also be using it for the name of the memory mapped file - m_sName = sMutexName; - - // Only one object of type CInstanceChecker should be created - ASSERT(instanceData.hInstanceData == NULL); - m_pExecuteLock = NULL; -} - -void CInstanceChecker::ActivateChecker() -{ - ASSERT(m_pExecuteLock == NULL); - - //Ensure there is only ever one CInstanceChecker instance - //active at any one time throughout the system - m_pExecuteLock = new CSingleLock(&m_executeMutex, TRUE); -} - -CInstanceChecker::~CInstanceChecker() -{ - //Free up the instance lock - ReleaseLock(); -} - -void CInstanceChecker::ReleaseLock() -{ - if (m_pExecuteLock) - { - delete m_pExecuteLock; - m_pExecuteLock = NULL; - } -} - -// Track the first instance of our App. -// return TRUE on success, else FALSE -BOOL CInstanceChecker::TrackFirstInstanceRunning() -{ - //If a previous instance is running, just return prematurely - if (PreviousInstanceRunning()) - return FALSE; - - //If this is the first instance then copy in our info into the shared memory - - //First create the MMF - int nMMFSize = sizeof(CWindowInstance); - instanceData.hInstanceData = ::CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, nMMFSize, GetMMFFilename()); - if (instanceData.hInstanceData == NULL) - { - TRACE(_T("Failed to create the MMF even though this is the first instance, you might want to consider overriding GetMMFFilename()\n")); - return FALSE; - } - - //Open the MMF - CWindowInstance* pInstanceData = (CWindowInstance*) ::MapViewOfFile(instanceData.hInstanceData, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, nMMFSize); - ASSERT(pInstanceData != NULL); //Opening the MMF should work - - // Lock the data prior to updating it - CSingleLock dataLock(&m_instanceDataMutex, TRUE); - pInstanceData->hMainWnd = GetWindowToTrack(); - ::UnmapViewOfFile(pInstanceData); - - //Since this will be the last function that will be called - //when this is the first instance we can release the lock - ReleaseLock(); - - return TRUE; -} - -// Returns TRUE if a previous instance of the App is running. -BOOL CInstanceChecker::PreviousInstanceRunning() -{ - //Try to open the MMF first to see if we are the second instance - HANDLE hPrevInstance = ::OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, GetMMFFilename()); - BOOL bPreviousInstance = (hPrevInstance != NULL); - if (hPrevInstance) - CloseHandle(hPrevInstance); - - return bPreviousInstance; -} - -CString CInstanceChecker::GetMMFFilename() -{ - CString sMMF(_T("CInstanceChecker_MMF_")); - sMMF += m_sName; - return sMMF; -} - -HWND CInstanceChecker::GetWindowToTrack() -{ - //By default the window tracked will be the standard AfxGetMainWnd() - ASSERT(AfxGetMainWnd() != NULL); //Did you forget to set up the mainfrm in InitInstance ? - return AfxGetMainWnd()->GetSafeHwnd(); -} - -// Activate the Previous Instance of our Application. -HWND CInstanceChecker::ActivatePreviousInstance() -{ - //Try to open the previous instances MMF - HANDLE hPrevInstance = ::OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, GetMMFFilename()); - if (hPrevInstance) - { - // Open up the MMF - int nMMFSize = sizeof(CWindowInstance); - CWindowInstance* pInstanceData = (CWindowInstance*) ::MapViewOfFile(hPrevInstance, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, nMMFSize); - if (pInstanceData != NULL) //Opening the MMF should work - { - //Lock the data prior to reading from it - CSingleLock dataLock(&m_instanceDataMutex, TRUE); - - //activate the old window - ASSERT(pInstanceData->hMainWnd); //Something gone wrong with the MMF - HWND hWindow = pInstanceData->hMainWnd; - - if (::IsWindow(hWindow)) - { - CWnd wndPrev; - wndPrev.Attach(hWindow); - CWnd* pWndChild = wndPrev.GetLastActivePopup(); - - // Restore the focus to the previous instance and bring it to the foreground - if (wndPrev.IsIconic()) - wndPrev.ShowWindow(SW_RESTORE); - pWndChild->SetForegroundWindow(); - - //Detach the CWnd we were using - wndPrev.Detach(); - } - - //Unmap the MMF we were using - ::UnmapViewOfFile(pInstanceData); - - //Close the file handle now that we - ::CloseHandle(hPrevInstance); - - //When we have activate the previous instance, we can release the lock - ReleaseLock(); - - //return the Window handle of the previous instance - return hWindow; - } - - //Close the file handle now that we - ::CloseHandle(hPrevInstance); - - //When we have activate the previous instance, we can release the lock - ReleaseLock(); - } - - return NULL; -} - -void CInstanceChecker::QuitPreviousInstance(int nExitCode) -{ - //Try to open the previous instances MMF - HANDLE hPrevInstance = ::OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, GetMMFFilename()); - if (hPrevInstance) - { - // Open up the MMF - int nMMFSize = sizeof(CWindowInstance); - CWindowInstance* pInstanceData = (CWindowInstance*) ::MapViewOfFile(hPrevInstance, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, nMMFSize); - if (pInstanceData != NULL) //Opening the MMF should work - { - // Lock the data prior to reading from it - CSingleLock dataLock(&m_instanceDataMutex, TRUE); - - //activate the old window - ASSERT(pInstanceData->hMainWnd); //Something gone wrong with the MMF - HWND hWindow = pInstanceData->hMainWnd; - - //Ask it to exit - if (hWindow) - PostMessage(hWindow, WM_QUIT, nExitCode, 0); - } - - //Close the file handle now that we - ::CloseHandle(hPrevInstance); - } -} - Deleted: trunk/Src/Common/sinstance.h =================================================================== --- trunk/Src/Common/sinstance.h 2008-02-23 11:42:46 UTC (rev 5073) +++ trunk/Src/Common/sinstance.h 2008-02-23 22:55:41 UTC (rev 5074) @@ -1,58 +0,0 @@ -/* -Module : SINSTANCE.H -Purpose: Defines the interface for an MFC wrapper class to do instance checking -Created: PJN / 29-07-1998 - -Copyright (c) 1998 - 2003 by PJ Naughter. - -All rights reserved. - -Copyright / Usage Details: - -You are allowed to include the source code in any product (commercial, shareware, freeware or otherwise) -when your product is released in binary form. You are allowed to modify the source code in any way you want -except you cannot modify the copyright details at the top of each module. If you want to distribute source -code with your application, then you are only allowed to distribute versions released by the author. This is -to maintain a single distribution point for the source code. - -*/ - - -#ifndef __SINSTANCE_H__ -#define __SINSTANCE_H__ - -#ifndef __AFXMT_H__ -#pragma message("to avoid this message, you should put afxmt.h in your PCH (normally stdafx.h)") -#include <afxmt.h> -#endif - -class CInstanceChecker : public CObject -{ -public: -//Constructors / Destructors - CInstanceChecker(const CString& sMutexName); - virtual ~CInstanceChecker(); - -//General functions - void ActivateChecker(); - BOOL TrackFirstInstanceRunning(); - BOOL PreviousInstanceRunning(); - HWND ActivatePreviousInstance(); - void QuitPreviousInstance(int nExitCode = 0); - -protected: -//Virtual methods - virtual CString GetMMFFilename(); - virtual HWND GetWindowToTrack(); - -//Standard non-virtual methods - void ReleaseLock(); - -//Data - CMutex m_instanceDataMutex; - CMutex m_executeMutex; - CSingleLock* m_pExecuteLock; - CString m_sName; -}; - -#endif //__SINSTANCE_H__ Modified: trunk/Src/MainFrm.cpp =================================================================== --- trunk/Src/MainFrm.cpp 2008-02-23 11:42:46 UTC (rev 5073) +++ trunk/Src/MainFrm.cpp 2008-02-23 22:55:41 UTC (rev 5074) @@ -347,6 +347,30 @@ static StatusDisplay myStatusDisplay; +/** + * @brief Change MainFrame window class name + * see http://support.microsoft.com/kb/403825/ja + */ +BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs) +{ + LPCTSTR lpzsNewName = _T("WinMergeWindowClass"); + WNDCLASS wndcls; + BOOL bRes = CMDIFrameWnd::PreCreateWindow(cs); + HINSTANCE hInst = AfxGetInstanceHandle(); + // see if the class already exists + if (!::GetClassInfo(hInst, lpzsNewName, &wndcls)) + { + // get default stuff + ::GetClassInfo(hInst, cs.lpszClass, &wndcls); + // register a new class + wndcls.lpszClassName = lpzsNewName; + wndcls.hIcon = ::LoadIcon(hInst, MAKEINTRESOURCE(IDR_MAINFRAME)); + ::RegisterClass(&wndcls); + } + cs.lpszClass = lpzsNewName; + return bRes; +} + int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (CMDIFrameWnd::OnCreate(lpCreateStruct) == -1) Modified: trunk/Src/MainFrm.h =================================================================== --- trunk/Src/MainFrm.h 2008-02-23 11:42:46 UTC (rev 5073) +++ trunk/Src/MainFrm.h 2008-02-23 22:55:41 UTC (rev 5074) @@ -145,6 +145,7 @@ virtual void ActivateFrame(int nCmdShow = -1); virtual BOOL PreTranslateMessage(MSG* pMsg); virtual void OnUpdateFrameTitle(BOOL bAddToTitle); + virtual BOOL PreCreateWindow(CREATESTRUCT& cs); //}}AFX_VIRTUAL // Implementation methods Modified: trunk/Src/Merge.cpp =================================================================== --- trunk/Src/Merge.cpp 2008-02-23 11:42:46 UTC (rev 5073) +++ trunk/Src/Merge.cpp 2008-02-23 22:55:41 UTC (rev 5074) @@ -42,7 +42,6 @@ #include "logfile.h" #include "coretools.h" #include "paths.h" -#include "sinstance.h" #include "FileFilterHelper.h" #include "Plugins.h" #include "DirScan.h" // for DirScan_InitializeDefaultCodepage @@ -246,22 +245,29 @@ BOOL bSingleInstance = GetOptionsMgr()->GetBool(OPT_SINGLE_INSTANCE) || (true == cmdInfo.m_bSingleInstance); - HANDLE hMutex = NULL; - if (bSingleInstance) + // Create exclusion mutex name + TCHAR szDesktopName[_MAX_PATH] = _T("Win9xDesktop"); + DWORD dwLengthNeeded; + GetUserObjectInformation(GetThreadDesktop(GetCurrentThreadId()), UOI_NAME, + szDesktopName, sizeof(szDesktopName), &dwLengthNeeded); + String mutexName = + String(_T("WinMerge{05963771-8B2E-11d8-B3B9-000000000000}-")) + + szDesktopName; + + HANDLE hMutex = CreateMutex(NULL, FALSE, mutexName.c_str()); + if (hMutex) + WaitForSingleObject(hMutex, INFINITE); + if (bSingleInstance && GetLastError() == ERROR_ALREADY_EXISTS) { - hMutex = CreateMutex(NULL, FALSE, _T("WinMerge{05963771-8B2E-11d8-B3B9-000000000000}")); - WaitForSingleObject(hMutex, INFINITE); - } + USES_CONVERSION; - CInstanceChecker instanceChecker(_T("{05963771-8B2E-11d8-B3B9-000000000000}")); - if (bSingleInstance) - { - if (instanceChecker.PreviousInstanceRunning()) + // Activate previous instance and send commandline to it + HWND hWnd = FindWindow(_T("WinMergeWindowClass"), NULL); + if (hWnd) { - USES_CONVERSION; - - // Activate previous instance and send commandline to it - HWND hWnd = instanceChecker.ActivatePreviousInstance(); + if (IsIconic(hWnd)) + ShowWindow(hWnd, SW_RESTORE); + SetForegroundWindow(GetLastActivePopup(hWnd)); WCHAR *pszArgs = new WCHAR[_tcslen(__targv[0]) + _tcslen(m_lpCmdLine) + 3]; WCHAR *p = pszArgs; @@ -275,13 +281,15 @@ data.cbData = (DWORD)(p - pszArgs) * sizeof(WCHAR); data.lpData = pszArgs; data.dwData = __argc; + SetLastError(ERROR_SUCCESS); SendMessage(hWnd, WM_COPYDATA, NULL, (LPARAM)&data); delete[] pszArgs; - - ReleaseMutex(hMutex); - CloseHandle(hMutex); - - return FALSE; + if (GetLastError() == ERROR_SUCCESS) + { + ReleaseMutex(hMutex); + CloseHandle(hMutex); + return FALSE; + } } } @@ -356,9 +364,6 @@ CMenu * pNewMenu = CMenu::FromHandle(pMainFrame->m_hMenuDefault); pMainFrame->MDISetMenu(pNewMenu, NULL); - //Track it so any other instances can find it. - instanceChecker.TrackFirstInstanceRunning(); - // The main window has been initialized, so activate and update it. pMainFrame->ActivateFrame(cmdInfo.m_nCmdShow); pMainFrame->UpdateWindow(); @@ -370,10 +375,7 @@ bContinue = FALSE; if (hMutex) - { ReleaseMutex(hMutex); - CloseHandle(hMutex); - } if (m_bNonInteractive) { Modified: trunk/Src/Merge.dsp =================================================================== --- trunk/Src/Merge.dsp 2008-02-23 11:42:46 UTC (rev 5073) +++ trunk/Src/Merge.dsp 2008-02-23 22:55:41 UTC (rev 5074) @@ -848,10 +848,6 @@ # End Source File # Begin Source File -SOURCE=.\Common\sinstance.cpp -# End Source File -# Begin Source File - SOURCE=.\Common\sizecbar.cpp # End Source File # Begin Source File @@ -1551,10 +1547,6 @@ # End Source File # Begin Source File -SOURCE=.\Common\sinstance.h -# End Source File -# Begin Source File - SOURCE=.\Common\sizecbar.h # End Source File # Begin Source File This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |