فهرست منبع

moved processing (filling list, added clip to db, tcp sending clicp) into threads

git-svn-id: svn://svn.code.sf.net/p/ditto-cp/code/trunk@479 595ec19a-5cb4-439b-94a8-42fb3063c22c
sabrogden 16 سال پیش
والد
کامیت
a87883f9e9
30فایلهای تغییر یافته به همراه4149 افزوده شده و 5261 حذف شده
  1. 74 157
      CP_Main.cpp
  2. 5 53
      CP_Main.h
  3. 52 61
      CP_Main.rc
  4. 8 0
      CP_Main.vcxproj
  5. 0 84
      Client.cpp
  6. 9 24
      Clip.cpp
  7. 2 1
      Clip.h
  8. 15 61
      CopyThread.cpp
  9. 9 40
      CopyThread.h
  10. 38 6
      EventThread.cpp
  11. 1 0
      EventThread.h
  12. 1 0
      HTMLFormatAggregator.cpp
  13. 627 1037
      MainFrm.cpp
  14. 112 147
      MainFrm.h
  15. 1 0
      MainTableFunctions.cpp
  16. 877 1273
      Misc.cpp
  17. 3 146
      Misc.h
  18. 6 0
      OleClipSource.cpp
  19. 0 16
      OptionsGeneral.cpp
  20. 5 7
      OptionsGeneral.h
  21. 0 18
      OptionsKeyBoard.cpp
  22. 0 2
      OptionsKeyBoard.h
  23. 8 6
      ProcessPaste.cpp
  24. 0 1
      QListCtrl.cpp
  25. 1 0
      QListCtrl.h
  26. 1503 1335
      QPasteWnd.cpp
  27. 235 264
      QPasteWnd.h
  28. 2 0
      Server.cpp
  29. 1 0
      Theme.cpp
  30. 554 522
      ToolTipEx.cpp

+ 74 - 157
CP_Main.cpp

@@ -1,8 +1,4 @@
-// CP_Main.cpp : Defines the class behaviors for the application.
-//
-
 #include "stdafx.h"
-//#include "vld.h"
 #include "CP_Main.h"
 #include "MainFrm.h"
 #include "Misc.h"
@@ -24,9 +20,6 @@
 static char THIS_FILE[] = __FILE__;
 #endif
 
-/////////////////////////////////////////////////////////////////////////////
-// The one and only CCP_MainApp object
-
 class DittoCommandLineInfo : public CCommandLineInfo
 {
 public:
@@ -77,9 +70,6 @@ public:
 
 CCP_MainApp theApp;
 
-/////////////////////////////////////////////////////////////////////////////
-// CCP_MainApp
-
 BEGIN_MESSAGE_MAP(CCP_MainApp, CWinApp)
 	//{{AFX_MSG_MAP(CCP_MainApp)
 		// NOTE - the ClassWizard will add and remove mapping macros here.
@@ -87,10 +77,6 @@ BEGIN_MESSAGE_MAP(CCP_MainApp, CWinApp)
 	//}}AFX_MSG_MAP
 END_MESSAGE_MAP()
 
-/////////////////////////////////////////////////////////////////////////////
-// CCP_MainApp construction
-
-
 CCP_MainApp::CCP_MainApp()
 {
 	m_bAppRunning = false;
@@ -125,9 +111,6 @@ CCP_MainApp::CCP_MainApp()
 	m_cfIgnoreClipboard = ::RegisterClipboardFormat(_T("Clipboard Viewer Ignore"));
 	m_cfDelaySavingData = ::RegisterClipboardFormat(_T("Ditto Delay Saving Data"));
 	m_RemoteCF_HDROP = ::RegisterClipboardFormat(_T("Ditto Remote CF_HDROP"));
-
-	m_QuickPasteMode = NONE_QUICK_PASTE;
-	m_pQuickPasteClip = NULL;
 }
 
 CCP_MainApp::~CCP_MainApp()
@@ -135,9 +118,6 @@ CCP_MainApp::~CCP_MainApp()
 	
 }
 
-/////////////////////////////////////////////////////////////////////////////
-// CCP_MainApp initialization
-
 BOOL CCP_MainApp::InitInstance()
 {
 	AfxEnableControlContainer();
@@ -288,13 +268,6 @@ void CCP_MainApp::AfterMainCreate()
 	// create hotkeys here.  They are automatically deleted on exit
 	m_pDittoHotKey = new CHotKey(CString("DittoHotKey"), 704); //704 is ctrl-tilda
 
-	//A U3 device is unable to use the keyboard hooks, so named paste and copy 
-	//can't be used
-	if(!g_Opt.m_bU3)
-	{
-		m_pNamedCopy = new CHotKey("CopyHotKey");
-		m_pNamedPaste = new CHotKey("NamedPaste");
-	}
 	m_pPosOne = new CHotKey("Position1", 0, true);
 	m_pPosTwo = new CHotKey("Position2", 0, true);
 	m_pPosThree = new CHotKey("Position3", 0, true);
@@ -346,12 +319,12 @@ void CCP_MainApp::StopServerThread()
 
 void CCP_MainApp::BeforeMainClose()
 {
-	/*ASSERT( m_bAppRunning && !m_bAppExiting );
+	ASSERT( m_bAppRunning && !m_bAppExiting );
 	m_bAppRunning = false;
 	m_bAppExiting = true;
 	g_HotKeys.UnregisterAll();
 	StopServerThread();
-	StopCopyThread();*/
+	StopCopyThread();
 }
 
 void CCP_MainApp::StartCopyThread()
@@ -363,9 +336,9 @@ void CCP_MainApp::StartCopyThread()
 	// - true = use Asynchronous communication (PostMessage)
 	// - true = enable copying on clipboard changes
 	// - pTypes = the supported types to use
-	m_CopyThread.Init( CCopyConfig( m_MainhWnd, true, true, pTypes ) );
+	m_CopyThread.Init(CCopyConfig(m_MainhWnd, true, true, pTypes));
 
-	VERIFY( m_CopyThread.CreateThread(CREATE_SUSPENDED) );
+	VERIFY(m_CopyThread.CreateThread(CREATE_SUSPENDED));
 	m_CopyThread.ResumeThread();
 	
 	if(m_bStartupDisconnected)
@@ -380,7 +353,6 @@ void CCP_MainApp::StopCopyThread()
 {
 	EnableCbCopy(false);
 	m_CopyThread.Quit();
-	SaveCopyClips();
 }
 
 // returns the current Clipboard Viewer Connect state (though it might not yet
@@ -399,8 +371,6 @@ bool CCP_MainApp::ToggleConnectCV()
 //   lose that connection, "Disconnect from Clipboard" will have a check next to it.
 void CCP_MainApp::UpdateMenuConnectCV(CMenu* pMenu, UINT nMenuID)
 {
-	//CString b=_T("Scott");
-	//pMenu->ModifyMenu(nMenuID, MF_BYCOMMAND, nMenuID, b);
 	if(pMenu == NULL)
 		return;
 
@@ -457,96 +427,10 @@ void CCP_MainApp::ReloadTypes()
 {
 	CClipTypes* pTypes = LoadTypesFromDB();
 
-	if( pTypes )
-		m_CopyThread.SetSupportedTypes( pTypes );
-}
-
-long CCP_MainApp::SaveCopyClips()
-{
-	Log(_T("Start of function SaveCopyClips"));
-
-	long lID = 0;
-	int count;
-
-	CClipList* pClips = m_CopyThread.GetClips(); // we now own pClips
-	if(!pClips)
+	if(pTypes)
 	{
-		Log(_T("End of function SaveCopyClips, no clips to save"));
-		return 0;
-	}
-
-	CClipList* pCopyOfClips = NULL;
-	if(g_Opt.m_lAutoSendClientCount > 0)
-	{
-		//The thread will free these
-		pCopyOfClips = new CClipList;
-		if(pCopyOfClips != NULL)
-		{
-			*pCopyOfClips = *pClips;
-		}
+		m_CopyThread.SetSupportedTypes(pTypes);
 	}
-
-	bool bEnteredThread = false;
-	bool bDeletepClips = true;
-
-	if(m_QuickPasteMode == ADDING_QUICK_PASTE)
-	{
-		Log(_T("SaveCopyclips from Quick Paste - Start"));
-
-		//this will be added when they are done entering the quick paste text
-		m_pQuickPasteClip = pClips;
-		
-		bDeletepClips = false;
-
-		//go ahead and send the clips out even though it won't be added for a bit
-		count = 1;
-
-		Log(_T("SaveCopyclips from Quick Paste - End"));
-	}
-	else
-	{
-		Log(_T("SaveCopyClips Before AddToDb")); 
-
-		count = pClips->AddToDB(true);
-
-		Log(StrF(_T("SaveCopyclips After AddToDb, Count: %d"), count));
-
-		if(count > 0)
-		{
-			lID = pClips->GetTail()->m_ID;
-
-			Log(StrF(_T("SaveCopyclips After AddToDb, Id: %d Before OnCopyCopyCompleted"), lID));
-
-			OnCopyCompleted(lID, count);
-
-			Log(StrF(_T("SaveCopyclips After AddToDb, Id: %d After OnCopyCopyCompleted"), lID));
-
-			if(m_CopyBuffer.Active())
-			{
-				m_CopyBuffer.EndCopy(lID);
-			}
-		}
-	}
-
-	if(count > 0)
-	{
-		if(g_Opt.m_lAutoSendClientCount > 0)
-		{
-			Log(_T("Starting thread to send clip to friends"));
-			AfxBeginThread(SendClientThread, pCopyOfClips);
-			bEnteredThread = true;
-		}
-	}
-	
-	if(bEnteredThread == false)
-		delete pCopyOfClips;
-
-	if(bDeletepClips)
-		delete pClips;
-
-	Log(_T("Start of function SaveCopyClips"));
-
-	return lID;
 }
 
 void CCP_MainApp::RefreshView()
@@ -555,9 +439,13 @@ void CCP_MainApp::RefreshView()
 	if(pWnd)
 	{
 		if(m_bAsynchronousRefreshView)
+		{
 			pWnd->PostMessage(WM_REFRESH_VIEW);
+		}
 		else
+		{
 			pWnd->SendMessage(WM_REFRESH_VIEW);
+		}
 	}
 }
 
@@ -565,18 +453,27 @@ void CCP_MainApp::OnPasteCompleted()
 {
 	// the list only changes if UpdateTimeOnPaste is true (updated time)
 	if(g_Opt.m_bUpdateTimeOnPaste)
+	{
 		RefreshView();
+	}
 }
 
 void CCP_MainApp::OnCopyCompleted(long lLastID, int count)
 {
 	if(count <= 0)
+	{
 		return;
+	}
 
 	// update copy statistics
 	CGetSetOptions::SetTripCopyCount(-count);
 	CGetSetOptions::SetTotalCopyCount(-count);
 
+	if(m_CopyBuffer.Active())
+	{
+		m_CopyBuffer.EndCopy(lLastID);
+	}
+
 	RefreshView();
 }
 
@@ -585,20 +482,28 @@ void CCP_MainApp::OnCopyCompleted(long lLastID, int count)
 // if NULL, this uses the current QPaste selection
 void CCP_MainApp::IC_Cut(ARRAY* pIDs)
 {
-	if( pIDs == NULL )
+	if(pIDs == NULL)
 	{
-		if( QPasteWnd() )
-			QPasteWnd()->m_lstHeader.GetSelectionItemData( m_IC_IDs );
+		if(QPasteWnd())
+		{
+			QPasteWnd()->m_lstHeader.GetSelectionItemData(m_IC_IDs);
+		}
 		else
+		{
 			m_IC_IDs.SetSize(0);
+		}
 	}
 	else
-		m_IC_IDs.Copy( *pIDs );
+	{
+		m_IC_IDs.Copy(*pIDs);
+	}
 
 	m_IC_bCopy = false;
 
-	if( QPasteWnd() )
+	if(QPasteWnd())
+	{
 		QPasteWnd()->UpdateStatus();
+	}
 }
 
 // if NULL, this uses the current QPaste selection
@@ -607,28 +512,39 @@ void CCP_MainApp::IC_Copy(ARRAY* pIDs)
 	if(pIDs == NULL)
 	{
 		if(QPasteWnd())
+		{
 			QPasteWnd()->m_lstHeader.GetSelectionItemData(m_IC_IDs);
+		}
 		else
+		{
 			m_IC_IDs.SetSize(0);
+		}
 	}
 	else
+	{
 		m_IC_IDs.Copy(*pIDs);
+	}
 
 	m_IC_bCopy = true;
 
-	if(QPasteWnd())
-		QPasteWnd()->UpdateStatus();
+	RefreshView();
 }
 
 void CCP_MainApp::IC_Paste()
 {
 	if(m_IC_IDs.GetSize() <= 0)
+	{
 		return;
+	}
 
 	if(m_IC_bCopy)
+	{
 		m_IC_IDs.CopyTo(GetValidGroupID());
+	}
 	else // Move
+	{
 		m_IC_IDs.MoveTo(GetValidGroupID());
+	}
 
 	// don't process the same items twice.
 	m_IC_IDs.SetSize(0);
@@ -667,8 +583,6 @@ BOOL CCP_MainApp::EnterGroupID(long lID)
 				{
 					m_GroupID = lID;
 					m_GroupParentID = q.getIntField(_T("lParentID"));
-//					if( m_GroupParentID == 0 )
-//				      m_GroupParentID = -1; // back out into "all top-level groups" list.
 					m_GroupText = q.getStringField(_T("mText"));
 					bResult = TRUE;
 				}
@@ -695,36 +609,45 @@ long CCP_MainApp::GetValidGroupID()
 }
 
 // sets a valid id
-void CCP_MainApp::SetGroupDefaultID( long lID )
+void CCP_MainApp::SetGroupDefaultID(long lID)
 {
-	if( m_GroupDefaultID == lID )
+	if(m_GroupDefaultID == lID)
+	{
 		return;
+	}
 
-	if( lID <= 0 )
+	if(lID <= 0)
+	{
 		m_GroupDefaultID = 0;
+	}
 	else
+	{
 		m_GroupDefaultID = lID;
+	}
 
-	if( QPasteWnd() )
+	if(QPasteWnd())
+	{
 		QPasteWnd()->UpdateStatus();
+	}
 }
 
-// Window States
-
-void CCP_MainApp::SetStatus( const TCHAR* status, bool bRepaintImmediately )
+void CCP_MainApp::SetStatus(const TCHAR* status, bool bRepaintImmediately)
 {
 	m_Status = status;
-	if( QPasteWnd() )
-		QPasteWnd()->UpdateStatus( bRepaintImmediately );
+	if(QPasteWnd())
+	{
+		QPasteWnd()->UpdateStatus(bRepaintImmediately);
+	}
 }
 
-void CCP_MainApp::ShowPersistent( bool bVal )
+void CCP_MainApp::ShowPersistent(bool bVal)
 {
-	g_Opt.SetShowPersistent( bVal );
+	g_Opt.SetShowPersistent(bVal);
+
 	// give some visual indication
-	if( m_bShowingQuickPaste )
+	if(m_bShowingQuickPaste)
 	{
-		ASSERT( QPasteWnd() );
+		ASSERT(QPasteWnd());
 		QPasteWnd()->SetCaptionColorActive(g_Opt.m_bShowPersistent, theApp.GetConnectCV());
 		QPasteWnd()->RefreshNc();
 	}
@@ -739,18 +662,6 @@ int CCP_MainApp::ExitInstance()
 
 	m_db.close();
 
-//	if(g_Opt.m_bU3)
-//	{
-//		if(g_Opt.IsU3DeviceAvailable())
-//		{
-//			CopyUpDatabase();
-//		}
-//		else
-//		{
-//			Log(_T("Needed to copy up database but device was not available to copy to"));
-//		}
-//	}
-
 	return CWinApp::ExitInstance();
 }
 
@@ -758,7 +669,7 @@ int CCP_MainApp::ExitInstance()
 BOOL CCP_MainApp::OnIdle(LONG lCount)
 {
 	// let winapp handle its idle processing
-	if( CWinApp::OnIdle(lCount) )
+	if(CWinApp::OnIdle(lCount))
 		return TRUE;
 
 	return FALSE;
@@ -769,9 +680,13 @@ void CCP_MainApp::SetConnectCV(bool bConnect)
 	m_CopyThread.SetConnectCV(bConnect); 
 	
 	if(bConnect)
+	{
 		m_pMainFrame->m_TrayIcon.SetIcon(IDR_MAINFRAME);
+	}
 	else
+	{
 		m_pMainFrame->m_TrayIcon.SetIcon(IDI_DITTO_NOCOPYCB);
+	}
 
 	if(QPasteWnd())
 	{
@@ -811,7 +726,9 @@ bool CCP_MainApp::ImportClips(HWND hWnd)
 	FileName.lpstrDefExt = _T("dto");
 
 	if(GetOpenFileName(&FileName) == 0)
+	{
 		return false;
+	}
 
 	using namespace nsPath;
 	CPath path(FileName.lpstrFile);

+ 5 - 53
CP_Main.h

@@ -1,12 +1,4 @@
-// CP_Main.h : main header file for the CP_MAIN application
-//
-
-#if !defined(AFX_CP_MAIN_H__DAB2F753_2CC1_4FED_8095_763987961026__INCLUDED_)
-#define AFX_CP_MAIN_H__DAB2F753_2CC1_4FED_8095_763987961026__INCLUDED_
-
-#if _MSC_VER > 1000
 #pragma once
-#endif // _MSC_VER > 1000
 
 #ifndef __AFXWIN_H__
 	#error include 'stdafx.h' before including this file for PCH
@@ -27,14 +19,10 @@
 #include "sqlite\CppSQLite3.h"
 #include "DittoAddins.h"
 #include "externalwindowtracker.h"
+#include "HotKeys.h"
 
-//#define GET_APP ((CMainWnd*)theApp)
 extern class CCP_MainApp theApp;
 
-/////////////////////////////////////////////////////////////////////////////
-// CCP_MainApp:
-// See CP_Main.cpp for the implementation of this class
-//
 class CCP_MainApp : public CWinApp
 {
 public:
@@ -59,9 +47,7 @@ public:
 
 // System-wide HotKeys
 	CHotKey*	m_pDittoHotKey; // activate ditto's qpaste window
-	CHotKey*	m_pNamedPaste;
-	CHotKey*	m_pNamedCopy;
-
+	
 	CHotKey*	m_pPosOne;
 	CHotKey*	m_pPosTwo;
 	CHotKey*	m_pPosThree;
@@ -91,10 +77,8 @@ public:
 	void StopCopyThread();
 	// for posting messages
 	HWND GetClipboardViewer()			{ return m_CopyThread.m_pClipboardViewer->m_hWnd; }
-	// enables or disables copying the clipboard when it changes
 	bool EnableCbCopy(bool bState)		{ return m_CopyThread.SetCopyOnChange(bState); }
 	bool IsClipboardViewerConnected()	{ return m_CopyThread.IsClipboardViewerConnected(); }
-	// user control over being in the clipboard viewer chain.
 	bool GetConnectCV()					{ return m_CopyThread.GetConnectCV(); }
 	void SetConnectCV(bool bConnect);
 	bool ToggleConnectCV();
@@ -103,15 +87,8 @@ public:
 	int ShowOptionsDlg();
 
 	void OnDeleteID(long lID);
-
 	BOOL GetClipData(long lID, CClipFormat &Clip);
-
-	bool EditItems(CClipIDs &Ids, bool bShowError);
-
-//	CClipList	m_SaveClipQueue; 
-	// Retrieves all clips from CopyThread and Saves them.
-	// returns the ID of the last Clip saved (or 0 if none)
-	long SaveCopyClips(); 
+	bool EditItems(CClipIDs &Ids, bool bShowError); 
 
 	CClipTypes* LoadTypesFromDB(); // returns a "new" allocated object
 	void ReloadTypes();
@@ -171,46 +148,21 @@ public:
 
 	COleDateTime m_oldtStartUp;
 
-	//Mulitlange Support
 	CMultiLanguage m_Language;
 
-	enum eQuickPasteMode{NONE_QUICK_PASTE, ADDING_QUICK_PASTE, PASTING_QUICK_PASTE, DITTO_BUFFER_QUICK_PASTE};
-
-	eQuickPasteMode m_QuickPasteMode;
-	CClipList* m_pQuickPasteClip;
-
 	CDittoCopyBuffer m_CopyBuffer;
 	void PumpMessageEx(HWND hWnd = NULL);
 
 	CDittoAddins m_Addins;
 
-protected:
-// Overrides
-	// ClassWizard generated virtual function overrides
-	//{{AFX_VIRTUAL(CCP_MainApp)
-	public:
+public:
 	virtual BOOL InitInstance();
 	virtual int ExitInstance();
-	//}}AFX_VIRTUAL
 	
-
-// Implementation
-	//{{AFX_MSG(CCP_MainApp)
 	afx_msg void OnAppAbout();
-		// NOTE - the ClassWizard will add and remove member functions here.
-		//    DO NOT EDIT what you see in these blocks of generated code !
-	//}}AFX_MSG
 	DECLARE_MESSAGE_MAP()
 	virtual BOOL OnIdle(LONG lCount);
 
 protected:
 	void ShowCommandLineError(CString csTitle, CString csMessage);
-};
-
-
-/////////////////////////////////////////////////////////////////////////////
-
-//{{AFX_INSERT_LOCATION}}
-// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
-
-#endif // !defined(AFX_CP_MAIN_H__DAB2F753_2CC1_4FED_8095_763987961026__INCLUDED_)
+};

+ 52 - 61
CP_Main.rc

@@ -414,47 +414,41 @@ FONT 8, "MS Shell Dlg", 0, 0, 0x1
 BEGIN
     CONTROL         "HotKey1",IDC_HOTKEY,"msctls_hotkey32",WS_BORDER | WS_TABSTOP,91,13,80,14
     CONTROL         "Win",IDC_CHECK_WIN_DITTO,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,174,13,33,14
-    CONTROL         "HotKey1",IDC_NAMED_COPY,"msctls_hotkey32",WS_BORDER | WS_TABSTOP,91,29,80,14
-    CONTROL         "Win",IDC_CHECK_WIN_NAMED_COPY,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,174,29,33,14
-    CONTROL         "HotKey1",IDC_HOTKEY1,"msctls_hotkey32",WS_BORDER | WS_TABSTOP,66,88,80,14
-    CONTROL         "Win",IDC_CHECK_WIN1,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,146,88,33,14
-    CONTROL         "HotKey1",IDC_HOTKEY2,"msctls_hotkey32",WS_BORDER | WS_TABSTOP,66,103,80,14
-    CONTROL         "Win",IDC_CHECK_WIN2,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,146,103,33,14
-    CONTROL         "HotKey1",IDC_HOTKEY3,"msctls_hotkey32",WS_BORDER | WS_TABSTOP,66,118,80,14
-    CONTROL         "Win",IDC_CHECK_WIN3,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,147,118,33,14
-    CONTROL         "HotKey1",IDC_HOTKEY4,"msctls_hotkey32",WS_BORDER | WS_TABSTOP,66,133,80,14
-    CONTROL         "Win",IDC_CHECK_WIN4,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,146,133,33,14
-    CONTROL         "HotKey1",IDC_HOTKEY5,"msctls_hotkey32",WS_BORDER | WS_TABSTOP,66,148,80,14
-    CONTROL         "Win",IDC_CHECK_WIN5,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,146,148,33,14
-    CONTROL         "HotKey1",IDC_HOTKEY6,"msctls_hotkey32",WS_BORDER | WS_TABSTOP,229,88,80,14
-    CONTROL         "Win",IDC_CHECK_WIN6,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,309,88,27,14
-    CONTROL         "HotKey1",IDC_HOTKEY7,"msctls_hotkey32",WS_BORDER | WS_TABSTOP,229,103,80,14
-    CONTROL         "Win",IDC_CHECK_WIN7,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,309,103,26,14
-    CONTROL         "HotKey1",IDC_HOTKEY8,"msctls_hotkey32",WS_BORDER | WS_TABSTOP,229,118,80,14
-    CONTROL         "Win",IDC_CHECK_WIN8,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,310,118,26,14
-    CONTROL         "HotKey1",IDC_HOTKEY9,"msctls_hotkey32",WS_BORDER | WS_TABSTOP,229,133,80,14
-    CONTROL         "Win",IDC_CHECK_WIN9,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,309,133,27,14
-    CONTROL         "HotKey1",IDC_HOTKEY10,"msctls_hotkey32",WS_BORDER | WS_TABSTOP,229,148,80,14
-    CONTROL         "Win",IDC_CHECK_WIN10,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,309,148,27,14
-    GROUPBOX        "Global Hot Keys for Last Ten Items Copied",IDC_STATIC_GROUP,7,64,336,105
+    CONTROL         "HotKey1",IDC_HOTKEY1,"msctls_hotkey32",WS_BORDER | WS_TABSTOP,66,64,80,14
+    CONTROL         "Win",IDC_CHECK_WIN1,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,146,64,33,14
+    CONTROL         "HotKey1",IDC_HOTKEY2,"msctls_hotkey32",WS_BORDER | WS_TABSTOP,66,79,80,14
+    CONTROL         "Win",IDC_CHECK_WIN2,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,146,79,33,14
+    CONTROL         "HotKey1",IDC_HOTKEY3,"msctls_hotkey32",WS_BORDER | WS_TABSTOP,66,94,80,14
+    CONTROL         "Win",IDC_CHECK_WIN3,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,147,94,33,14
+    CONTROL         "HotKey1",IDC_HOTKEY4,"msctls_hotkey32",WS_BORDER | WS_TABSTOP,66,109,80,14
+    CONTROL         "Win",IDC_CHECK_WIN4,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,146,109,33,14
+    CONTROL         "HotKey1",IDC_HOTKEY5,"msctls_hotkey32",WS_BORDER | WS_TABSTOP,66,124,80,14
+    CONTROL         "Win",IDC_CHECK_WIN5,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,146,124,33,14
+    CONTROL         "HotKey1",IDC_HOTKEY6,"msctls_hotkey32",WS_BORDER | WS_TABSTOP,229,64,80,14
+    CONTROL         "Win",IDC_CHECK_WIN6,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,309,64,27,14
+    CONTROL         "HotKey1",IDC_HOTKEY7,"msctls_hotkey32",WS_BORDER | WS_TABSTOP,229,79,80,14
+    CONTROL         "Win",IDC_CHECK_WIN7,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,309,79,26,14
+    CONTROL         "HotKey1",IDC_HOTKEY8,"msctls_hotkey32",WS_BORDER | WS_TABSTOP,229,94,80,14
+    CONTROL         "Win",IDC_CHECK_WIN8,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,310,94,26,14
+    CONTROL         "HotKey1",IDC_HOTKEY9,"msctls_hotkey32",WS_BORDER | WS_TABSTOP,229,109,80,14
+    CONTROL         "Win",IDC_CHECK_WIN9,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,309,109,27,14
+    CONTROL         "HotKey1",IDC_HOTKEY10,"msctls_hotkey32",WS_BORDER | WS_TABSTOP,229,124,80,14
+    CONTROL         "Win",IDC_CHECK_WIN10,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,309,124,27,14
+    GROUPBOX        "Global Hot Keys for Last Ten Items Copied",IDC_STATIC_GROUP,7,40,336,105
     CONTROL         "Send Paste (Otherwise it will just load the item on the clipboard)",IDC_CHECK_SEND_PASTE,
-                    "Button",BS_AUTOCHECKBOX | WS_TABSTOP,19,74,324,13
+                    "Button",BS_AUTOCHECKBOX | WS_TABSTOP,19,50,324,13
     LTEXT           "Activate Ditto",IDC_STATIC_ACTIVATE,19,13,71,14,SS_CENTERIMAGE
-    LTEXT           "Named Copy",IDC_STATIC_NAMED_COPY,19,29,70,14,SS_CENTERIMAGE
-    RTEXT           "Position 1",IDC_STATIC_1,16,88,42,14,SS_CENTERIMAGE
-    RTEXT           "Position 2",IDC_STATIC_2,16,103,42,14,SS_CENTERIMAGE
-    RTEXT           "Position 3",IDC_STATIC_3,16,118,42,14,SS_CENTERIMAGE
-    RTEXT           "Position 4",IDC_STATIC_4,16,133,42,14,SS_CENTERIMAGE
-    RTEXT           "Position 5",IDC_STATIC_5,16,148,42,14,SS_CENTERIMAGE
-    RTEXT           "Position 6",IDC_STATIC_6,181,88,42,14,SS_CENTERIMAGE
-    RTEXT           "Position 7",IDC_STATIC_7,181,103,42,14,SS_CENTERIMAGE
-    RTEXT           "Position 8",IDC_STATIC_8,181,118,42,14,SS_CENTERIMAGE
-    RTEXT           "Position 9",IDC_STATIC_9,181,133,42,14,SS_CENTERIMAGE
-    RTEXT           "Position 10",IDC_STATIC_10,181,148,42,14,SS_CENTERIMAGE
-    LTEXT           "Check the ""Win"" Button to include the windows keyboard key in your hot key.",IDC_STATIC_WIN,7,173,336,25
-    CONTROL         "HotKey1",IDC_NAMED_PASTE,"msctls_hotkey32",WS_BORDER | WS_TABSTOP,91,44,80,14
-    CONTROL         "Win",IDC_CHECK_WIN_NAMED_PASTE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,174,44,33,14
-    LTEXT           "Named Paste",IDC_STATIC_NAMED_COPY2,19,44,69,14,SS_CENTERIMAGE
+    RTEXT           "Position 1",IDC_STATIC_1,16,64,42,14,SS_CENTERIMAGE
+    RTEXT           "Position 2",IDC_STATIC_2,16,79,42,14,SS_CENTERIMAGE
+    RTEXT           "Position 3",IDC_STATIC_3,16,94,42,14,SS_CENTERIMAGE
+    RTEXT           "Position 4",IDC_STATIC_4,16,109,42,14,SS_CENTERIMAGE
+    RTEXT           "Position 5",IDC_STATIC_5,16,124,42,14,SS_CENTERIMAGE
+    RTEXT           "Position 6",IDC_STATIC_6,181,64,42,14,SS_CENTERIMAGE
+    RTEXT           "Position 7",IDC_STATIC_7,181,79,42,14,SS_CENTERIMAGE
+    RTEXT           "Position 8",IDC_STATIC_8,181,94,42,14,SS_CENTERIMAGE
+    RTEXT           "Position 9",IDC_STATIC_9,181,109,42,14,SS_CENTERIMAGE
+    RTEXT           "Position 10",IDC_STATIC_10,181,124,42,14,SS_CENTERIMAGE
+    LTEXT           "Check the ""Win"" Button to include the windows keyboard key in your hot key.",IDC_STATIC_WIN,7,149,336,25
     LTEXT           "Send custom strokes Per Application",IDC_STATIC_CUSTOM_KEYS,210,16,133,8
 END
 
@@ -476,35 +470,32 @@ BEGIN
     CONTROL         "Set Database Path",IDC_SET_DB_PATH,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,23,79,320,10
     EDITTEXT        IDC_PATH,23,89,248,12,ES_AUTOHSCROLL
     PUSHBUTTON      "....",IDC_GET_PATH,272,89,14,12
-    CONTROL         "Automatically check for updates online",IDC_CHECK_UPDATES,
-                    "Button",BS_AUTOCHECKBOX | WS_TABSTOP,23,106,173,10
-    PUSHBUTTON      "Check Now",IDC_CHECK_FOR_UPDATES,201,106,86,11
-    CONTROL         "Allow Duplicates",IDC_ALLOW_DUPLICATES,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,23,118,320,10
+    CONTROL         "Allow Duplicates",IDC_ALLOW_DUPLICATES,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,23,105,320,10
     CONTROL         "Update Clip Time On Paste",IDC_UPDATE_TIME_ON_PASTE,
-                    "Button",BS_AUTOCHECKBOX | WS_TABSTOP,23,130,321,10
-    CONTROL         "Save Multi-Pastes",IDC_SAVE_MULTIPASTE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,23,142,321,10
+                    "Button",BS_AUTOCHECKBOX | WS_TABSTOP,23,117,321,10
+    CONTROL         "Save Multi-Pastes",IDC_SAVE_MULTIPASTE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,23,129,321,10
     CONTROL         "Hide Ditto on Hot Key if Ditto is Visible",IDC_HIDE_DITO_ON_HOT_KEY,
-                    "Button",BS_AUTOCHECKBOX | WS_TABSTOP,23,153,322,10
-    LTEXT           "Amount of text to save for description",IDC_STATIC_AMOUNT,23,165,177,8
-    EDITTEXT        IDC_DESC_TEXT_SIZE,206,163,35,12,ES_AUTOHSCROLL
-    LTEXT           "On copy play the sound",IDC_STATIC_SOUND,23,177,139,10
-    EDITTEXT        IDC_EDIT_PLAY_SOUND,167,177,115,12,ES_AUTOHSCROLL
-    PUSHBUTTON      "Play",IDC_BUTTON_PLAY,285,177,35,12
-    PUSHBUTTON      "....",IDC_SELECT_SOUND,323,177,14,12
+                    "Button",BS_AUTOCHECKBOX | WS_TABSTOP,23,140,322,10
+    LTEXT           "Amount of text to save for description",IDC_STATIC_AMOUNT,23,152,177,8
+    EDITTEXT        IDC_DESC_TEXT_SIZE,206,150,35,12,ES_AUTOHSCROLL
+    LTEXT           "On copy play the sound",IDC_STATIC_SOUND,23,164,139,10
+    EDITTEXT        IDC_EDIT_PLAY_SOUND,167,164,115,12,ES_AUTOHSCROLL
+    PUSHBUTTON      "Play",IDC_BUTTON_PLAY,285,164,35,12
+    PUSHBUTTON      "....",IDC_SELECT_SOUND,323,164,14,12
     CONTROL         "Paste Clip in active window after selection",IDC_SEND_PASTE_MESSAGE,
-                    "Button",BS_AUTOCHECKBOX | WS_TABSTOP,23,190,318,10
-    LTEXT           "Maximum Clip Size in Bytes",IDC_STATIC_MAX_SIZE,23,202,137,8
-    EDITTEXT        IDC_EDIT_MAX_SIZE,164,200,59,12,ES_AUTOHSCROLL
-    LTEXT           "(Leave blank for no limit)",IDC_STATIC_NO_LIMIT,232,202,112,8
+                    "Button",BS_AUTOCHECKBOX | WS_TABSTOP,23,177,318,10
+    LTEXT           "Maximum Clip Size in Bytes",IDC_STATIC_MAX_SIZE,23,189,137,8
+    EDITTEXT        IDC_EDIT_MAX_SIZE,164,187,59,12,ES_AUTOHSCROLL
+    LTEXT           "(Leave blank for no limit)",IDC_STATIC_NO_LIMIT,232,189,112,8
     LTEXT           "Lanuage",IDC_STATIC_LANGUAGE,23,65,36,12,SS_CENTERIMAGE
     COMBOBOX        IDC_COMBO_LANGUAGE,65,65,130,95,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP
-    LTEXT           "Ignore copies that occur X milliseconds from the last copy (1000 ms = 1 sec)",IDC_STATIC_SAVE_DELAY,23,215,278,11
-    EDITTEXT        IDC_EDIT_SAVE_DELAY,306,214,38,12,ES_AUTOHSCROLL
+    LTEXT           "Ignore copies that occur X milliseconds from the last copy (1000 ms = 1 sec)",IDC_STATIC_SAVE_DELAY,23,202,278,11
+    EDITTEXT        IDC_EDIT_SAVE_DELAY,306,201,38,12,ES_AUTOHSCROLL
     PUSHBUTTON      "About Language",IDC_BUTTON_ABOUT,204,65,106,12
     CONTROL         "Ensure Ditto is always connected to the clipboard",IDC_ENSURE,
-                    "Button",BS_AUTOCHECKBOX | WS_TABSTOP,23,228,306,10
-    LTEXT           "Multi-Paste clip separator ([LF] = line feed)",IDC_STATIC_CLIP_SEPARATOR,23,242,161,8
-    EDITTEXT        IDC_EDIT_CLIP_SEPARATOR,187,240,106,12,ES_AUTOHSCROLL
+                    "Button",BS_AUTOCHECKBOX | WS_TABSTOP,23,215,306,10
+    LTEXT           "Multi-Paste clip separator ([LF] = line feed)",IDC_STATIC_CLIP_SEPARATOR,23,229,161,8
+    EDITTEXT        IDC_EDIT_CLIP_SEPARATOR,187,227,106,12,ES_AUTOHSCROLL
 END
 
 IDD_SELECT_DB DIALOGEX 0, 0, 276, 46

+ 8 - 0
CP_Main.vcxproj

@@ -302,6 +302,7 @@
       <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Unicode Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Unicode Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
     </ClCompile>
+    <ClCompile Include="Accels.cpp" />
     <ClCompile Include="AccessToSqlite.cpp">
       <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
       <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
@@ -334,6 +335,7 @@
       <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Unicode Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Unicode Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
     </ClCompile>
+    <ClCompile Include="AutoSendToClientThread.cpp" />
     <ClCompile Include="BitmapHelper.cpp">
       <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
       <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
@@ -453,6 +455,7 @@
       <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Unicode Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
     </ClCompile>
     <ClCompile Include="EventThread.cpp" />
+    <ClCompile Include="HotKeys.cpp" />
     <ClCompile Include="MainFrmThread.cpp" />
     <ClCompile Include="MessagePumpThread.cpp" />
     <ClCompile Include="Popup.cpp" />
@@ -1139,6 +1142,7 @@
       <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Unicode Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Unicode Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
     </ClCompile>
+    <ClCompile Include="Tokenizer.cpp" />
     <ClCompile Include="ToolTipEx.cpp">
       <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
       <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
@@ -1292,12 +1296,15 @@
     </ResourceCompile>
   </ItemGroup>
   <ItemGroup>
+    <ClInclude Include="Accels.h" />
     <ClInclude Include="AlphaBlend.h" />
     <ClInclude Include="ArrayEx.h" />
+    <ClInclude Include="AutoSendToClientThread.h" />
     <ClInclude Include="ClipFormatQListCtrl.h" />
     <ClInclude Include="EventThread.h" />
     <ClInclude Include="FormattedTextDraw.h" />
     <ClInclude Include="GroupStatic.h" />
+    <ClInclude Include="HotKeys.h" />
     <ClInclude Include="MainFrmThread.h" />
     <ClInclude Include="memdc.h" />
     <ClInclude Include="MessagePumpThread.h" />
@@ -1307,6 +1314,7 @@
     <ClInclude Include="QPasteWndThread.h" />
     <ClInclude Include="RichEditCtrlEx.h" />
     <ClInclude Include="SearchEditBox.h" />
+    <ClInclude Include="Tokenizer.h" />
     <ClInclude Include="ToolTipEx.h" />
     <ClInclude Include="WndEx.h" />
     <ClInclude Include="Client.h" />

+ 0 - 84
Client.cpp

@@ -90,90 +90,6 @@ BOOL SendToFriend(CSendToFriendInfo &Info)
 	return TRUE;
 }
 
-CCriticalSection SendClientCritSection;
-UINT  SendClientThread(LPVOID pParam)
-{	
-	SendClientCritSection.Lock();
-
-	LogSendRecieveInfo("@@@@@@@@@@@@@@@ - START OF SendClientThread - @@@@@@@@@@@@@@@");
-
-	CClipList *pClipList = (CClipList*)pParam;
-	if(pClipList == NULL)
-	{
-		SendClientCritSection.Unlock();
-		LogSendRecieveInfo("ERROR if(pClipList == NULL)");
-		return FALSE;
-	}
-
-	long lCount = pClipList->GetCount();
-
-	LogSendRecieveInfo(StrF(_T("Start of Send ClientThread Count - %d"), lCount));
-	
-	for(int nClient = 0; nClient < MAX_SEND_CLIENTS; nClient++)
-	{
-		if(g_Opt.m_SendClients[nClient].bSendAll && 
-			g_Opt.m_SendClients[nClient].csIP.GetLength() > 0)
-		{
-			CClient client;
-			if(client.OpenConnection(g_Opt.m_SendClients[nClient].csIP) == FALSE)
-			{
-				LogSendRecieveInfo(StrF(_T("ERROR opening connection to %s"), g_Opt.m_SendClients[nClient].csIP));
-
-				if(g_Opt.m_SendClients[nClient].bShownFirstError == FALSE)
-				{
-					CString cs;
-					cs.Format(_T("Error opening connection to %s"), g_Opt.m_SendClients[nClient].csIP);
-					::SendMessage(theApp.m_MainhWnd, WM_SEND_RECIEVE_ERROR, (WPARAM)cs.GetBuffer(cs.GetLength()), 0);
-					cs.ReleaseBuffer();
-
-					g_Opt.m_SendClients[nClient].bShownFirstError = TRUE;
-				}
-
-				continue;
-			}
-
-			//We were connected successfully show an error next time we can't connect
-			g_Opt.m_SendClients[nClient].bShownFirstError = FALSE;
-
-			CClip* pClip;
-			POSITION pos;
-			pos = pClipList->GetHeadPosition();
-			while(pos)
-			{
-				pClip = pClipList->GetNext(pos);
-				if(pClip == NULL)
-				{
-					ASSERT(FALSE);
-					LogSendRecieveInfo("Error in GetNext");
-					break;
-				}
-
-				LogSendRecieveInfo(StrF(_T("Sending clip to %s"), g_Opt.m_SendClients[nClient].csIP));
-				
-				if(client.SendItem(pClip) == FALSE)
-				{
-					CString cs;
-					cs.Format(_T("Error sending clip to %s"), g_Opt.m_SendClients[nClient].csIP);
-					::SendMessage(theApp.m_MainhWnd, WM_SEND_RECIEVE_ERROR, (WPARAM)cs.GetBuffer(cs.GetLength()), 0);
-					cs.ReleaseBuffer();
-					break;
-				}
-			}
-
-			client.CloseConnection();
-		}
-	}
-
-	delete pClipList;
-	pClipList = NULL;
-	
-	LogSendRecieveInfo("@@@@@@@@@@@@@@@ - END OF SendClientThread - @@@@@@@@@@@@@@@");
-
-	SendClientCritSection.Unlock();
-
-	return TRUE;
-}
-
 CClient::CClient()
 {
 	m_Connection = NULL;

+ 9 - 24
Clip.cpp

@@ -164,7 +164,8 @@ CClip::CClip() :
 	m_lParent(-1),
 	m_lDontAutoDelete(FALSE),
 	m_lShortCut(0),
-	m_bIsGroup(FALSE)
+	m_bIsGroup(FALSE),
+	m_param1(0)
 {
 }
 
@@ -184,6 +185,7 @@ void CClip::Clear()
 	m_lShortCut = 0;
 	m_bIsGroup = FALSE;
 	m_csQuickPaste = "";
+	m_param1 = 0;
 	
 	EmptyFormats();
 }
@@ -507,17 +509,8 @@ bool CClip::AddToDB(bool bCheckForDuplicates)
 			int nID = FindDuplicate();
 			if(nID >= 0)
 			{
-				CString csQuickPasteSQL;
-				if(m_csQuickPaste.IsEmpty() == FALSE)
-				{
-					m_csQuickPaste.Replace(_T("'"), _T("''"));
-					csQuickPasteSQL.Format(_T(", QuickPasteText = '%s'"), m_csQuickPaste);
-				}
-
-				theApp.m_db.execDMLEx(_T("UPDATE Main SET lDate = %d%s where lID = %d;"), 
-										(long)m_Time.GetTime(), csQuickPasteSQL, nID);
-				
-				EmptyFormats();
+				theApp.m_db.execDMLEx(_T("UPDATE Main SET lDate = %d where lID = %d;"), 
+										(long)m_Time.GetTime(), nID);
 
 				m_ID = nID;
 
@@ -540,7 +533,7 @@ bool CClip::AddToDB(bool bCheckForDuplicates)
 	}
 	
 	// should be emptied by AddToDataTable
-	ASSERT(m_Formats.GetSize() == 0);
+	//ASSERT(m_Formats.GetSize() == 0);
 	
 	return bResult;
 }
@@ -687,8 +680,8 @@ bool CClip::AddToDataTable()
 			
 			stmt.execDML();
 			stmt.reset();
-  
-			m_Formats.RemoveAt(i);
+
+			pCF->m_lDBID = theApp.m_db.lastRowId();
 		}
 	}
 	CATCH_SQLITE_EXCEPTION_AND_RETURN(false)
@@ -905,7 +898,7 @@ CClipList::~CClipList()
 
 // returns the number of clips actually saved
 // while this does empty the Format Data, it does not delete the Clips.
-int CClipList::AddToDB(bool bLatestTime, bool bShowStatus)
+int CClipList::AddToDB(bool bLatestTime)
 {
 	Log(_T("AddToDB - Start"));
 
@@ -920,11 +913,6 @@ int CClipList::AddToDB(bool bLatestTime, bool bShowStatus)
 	while(pos)
 	{
 		Log(StrF(_T("AddToDB - while(pos), Start Remaining %d"), nRemaining));
-
-		if(bShowStatus)
-		{
-			theApp.SetStatus(StrF(_T("%d"), nRemaining), true);
-		}
 		nRemaining--;
 		
 		pClip = GetNext(pos);
@@ -939,9 +927,6 @@ int CClipList::AddToDB(bool bLatestTime, bool bShowStatus)
 
 		Log(StrF(_T("AddToDB - while(pos), End Remaining %d, save count: %d"), nRemaining, savedCount));
 	}
-	
-	if(bShowStatus)
-		theApp.SetStatus(NULL, true);
 
 	Log(StrF(_T("AddToDB - Start, count: %d"), savedCount));
 	

+ 2 - 1
Clip.h

@@ -97,6 +97,7 @@ public:
 	BOOL m_bIsGroup;
 	DWORD m_CRC;
 	CString m_csQuickPaste;
+	int m_param1;
 
 	virtual CString Description() { return m_Desc; }
 	virtual void Description(CString csValue) { m_Desc = csValue; }
@@ -149,7 +150,7 @@ public:
 	~CClipList();
 	// returns the number of clips actually saved
 	// while this does empty the Format Data, it does not delete the Clips.
-	int AddToDB( bool bLatestTime = false, bool bShowStatus = true );
+	int AddToDB( bool bLatestTime = false);
 
 	const CClipList& operator=(const CClipList &cliplist);
 };

+ 15 - 61
CopyThread.cpp

@@ -19,12 +19,9 @@ IMPLEMENT_DYNCREATE(CCopyThread, CWinThread)
 CCopyThread::CCopyThread():
 	m_bQuit(false),
 	m_bConfigChanged(false),
-	m_pClips(NULL),
 	m_pClipboardViewer(NULL)
 {
-	m_bAutoDelete = false,
-
-	::InitializeCriticalSection(&m_CS);
+	m_bAutoDelete = false;
 }
 
 CCopyThread::~CCopyThread()
@@ -32,8 +29,6 @@ CCopyThread::~CCopyThread()
 	m_LocalConfig.DeleteTypes();
 	m_SharedConfig.DeleteTypes();
 	DELETE_PTR(m_pClipboardViewer);
-	DELETE_PTR(m_pClips);
-	::DeleteCriticalSection(&m_CS);
 }
 
 BOOL CCopyThread::InitInstance()
@@ -53,16 +48,6 @@ int CCopyThread::ExitInstance()
 	return CWinThread::ExitInstance();
 }
 
-BEGIN_MESSAGE_MAP(CCopyThread, CWinThread)
-	//{{AFX_MSG_MAP(CCopyThread)
-		// NOTE - the ClassWizard will add and remove mapping macros here.
-	//}}AFX_MSG_MAP
-END_MESSAGE_MAP()
-
-/////////////////////////////////////////////////////////////////////////////
-// CCopyThread message handlers
-
-
 // Called within Copy Thread:
 void CCopyThread::OnClipboardChange()
 {
@@ -128,8 +113,6 @@ void CCopyThread::OnClipboardChange()
 		return; // error
 	}
 	
-	AddToClips(pClip);
-	
 	if(m_LocalConfig.m_bAsyncCopy)
 		::PostMessage(m_LocalConfig.m_hClipHandler, WM_CLIPBOARD_COPIED, (WPARAM)pClip, 0);
 	else
@@ -144,7 +127,8 @@ void CCopyThread::SyncConfig()
 	if(m_bConfigChanged)
 	{
 		CClipTypes* pTypes = NULL;
-		Hold();
+		
+		ATL::CCritSecLock csLock(m_cs.m_sect);
 		
 		pTypes = m_LocalConfig.m_pSupportedTypes;
 		
@@ -159,25 +143,14 @@ void CCopyThread::SyncConfig()
 		else
 			m_SharedConfig.m_pSupportedTypes = NULL; // now owned by LocalConfig
 		
-		Release();
 		// delete old types
 		if( pTypes )
+		{
 			delete pTypes;
+		}
 	}
 }
 
-void CCopyThread::AddToClips(CClip* pClip)
-{
-	Hold();
-
-	if(!m_pClips)
-		m_pClips = new CClipList;
-
-	m_pClips->AddTail(pClip); // m_pClips now owns pClip
-
-	Release();
-}
-
 bool CCopyThread::IsClipboardViewerConnected()
 {
 	return m_pClipboardViewer->m_bIsConnected;
@@ -194,20 +167,9 @@ void CCopyThread::SetConnectCV(bool bConnect)
 	::SendMessage( m_pClipboardViewer->m_hWnd, WM_SETCONNECT, bConnect, 0 );
 }
 
-CClipList* CCopyThread::GetClips()
-{
-	Hold();
-	
-	CClipList* pRet = m_pClips;
-	m_pClips = NULL;
-
-	Release();
-	return pRet;
-}
-
 void CCopyThread::SetSupportedTypes( CClipTypes* pTypes )
 {
-	Hold();
+	ATL::CCritSecLock csLock(m_cs.m_sect);
 
 	if(m_SharedConfig.m_pSupportedTypes)
 	{
@@ -216,67 +178,59 @@ void CCopyThread::SetSupportedTypes( CClipTypes* pTypes )
 
 	m_SharedConfig.m_pSupportedTypes = pTypes;
 	m_bConfigChanged = true;
-
-	Release();
 }
 
 HWND CCopyThread::SetClipHandler(HWND hWnd)
 {
-	Hold();
+	ATL::CCritSecLock csLock(m_cs.m_sect);
 
 	HWND hRet = m_SharedConfig.m_hClipHandler;
 	m_SharedConfig.m_hClipHandler = hWnd;
 	m_bConfigChanged = (hRet != hWnd);
 
-	Release();
-
 	return hRet;
 }
 HWND CCopyThread::GetClipHandler()
 {
-	Hold();
+	ATL::CCritSecLock csLock(m_cs.m_sect);
 
 	HWND hRet = m_SharedConfig.m_hClipHandler;
 
-	Release();
-
 	return hRet;
 }
 bool CCopyThread::SetCopyOnChange(bool bVal)
 {
-	Hold();
+	ATL::CCritSecLock csLock(m_cs.m_sect);
 
 	bool bRet = m_SharedConfig.m_bCopyOnChange;
 	m_SharedConfig.m_bCopyOnChange = bVal;
 	m_bConfigChanged = (bRet != bVal);
 
-	Release();
-
 	return bRet;
 }
 bool CCopyThread::GetCopyOnChange()
 {
-	Hold();
+	ATL::CCritSecLock csLock(m_cs.m_sect);
+
 	bool bRet = m_SharedConfig.m_bCopyOnChange;
-	Release();
 
 	return bRet;
 }
 bool CCopyThread::SetAsyncCopy(bool bVal)
 {
-	Hold();
+	ATL::CCritSecLock csLock(m_cs.m_sect);
+
 	bool bRet = m_SharedConfig.m_bAsyncCopy;
 	m_SharedConfig.m_bAsyncCopy = bVal;
 	m_bConfigChanged = (bRet != bVal);
-	Release();
 
 	return bRet;
 }
 bool CCopyThread::GetAsyncCopy()
 {
-	Hold();
+	ATL::CCritSecLock csLock(m_cs.m_sect);
+
 	bool bRet = m_SharedConfig.m_bAsyncCopy;
-	Release();
 
 	return bRet;
 }

+ 9 - 40
CopyThread.h

@@ -1,11 +1,7 @@
-#if !defined(AFX_COPYTHREAD_H__C6766F04_0111_4314_986A_A0E02FF3B322__INCLUDED_)
-#define AFX_COPYTHREAD_H__C6766F04_0111_4314_986A_A0E02FF3B322__INCLUDED_
-
-#if _MSC_VER > 1000
 #pragma once
-#endif // _MSC_VER > 1000
 
 #include "ClipboardViewer.h"
+#include <afxmt.h>
 
 struct CCopyConfig
 {
@@ -57,12 +53,9 @@ public:
 
 	bool m_bQuit;
 
-	// critical section is held whenever shared data is changed 
-	CRITICAL_SECTION		m_CS;
-	void Hold()		{ ::EnterCriticalSection(&m_CS); }
-	void Release()	{ ::LeaveCriticalSection(&m_CS); }
+	CCriticalSection m_cs;
 
-// CopyThread Local (accessed from this CopyThread)
+	// CopyThread Local (accessed from this CopyThread)
 	// window owned by this thread which handles clipboard viewer messages
 	CClipboardViewer*   m_pClipboardViewer; // permanent during lifetime of thread
 	CCopyConfig         m_LocalConfig;
@@ -70,51 +63,27 @@ public:
 	// Called within Copy Thread:
 	void OnClipboardChange(); // called by ClipboardViewer
 	void SyncConfig(); // safely syncs m_LocalConfig with m_SharedConfig
-	void AddToClips( CClip* pClip ); // after this, pClip is owned by m_pClips
 
 // Shared (use thread-safe access functions below)
 	CCopyConfig         m_SharedConfig; 
 	bool                m_bConfigChanged; // true if m_SharedConfig was changed.
-	CClipList*          m_pClips; // snapshots of the clipboard when it changed.
 
 	// Called within Main thread:
 	bool IsClipboardViewerConnected();
 	bool GetConnectCV();
-	void SetConnectCV( bool bConnect );
+	void SetConnectCV(bool bConnect);
 
-	CClipList* GetClips(); // caller owns the returned CClipList
-	void SetSupportedTypes( CClipTypes* pTypes ); // CopyThread will own pTypes
-	HWND SetClipHandler( HWND hWnd ); // returns previous value
+	void SetSupportedTypes(CClipTypes* pTypes); // CopyThread will own pTypes
+	HWND SetClipHandler(HWND hWnd); // returns previous value
 	HWND GetClipHandler();
-	bool SetCopyOnChange( bool bVal ); // returns previous value
+	bool SetCopyOnChange(bool bVal); // returns previous value
 	bool GetCopyOnChange();
-	bool SetAsyncCopy( bool bVal ); // returns previous value
+	bool SetAsyncCopy(bool bVal); // returns previous value
 	bool GetAsyncCopy();
 
-// Main thread
-	void Init( CCopyConfig cfg );
+	void Init(CCopyConfig cfg);
 	bool Quit();
 
-// Overrides
-	// ClassWizard generated virtual function overrides
-	//{{AFX_VIRTUAL(CCopyThread)
-	public:
 	virtual BOOL InitInstance();
 	virtual int ExitInstance();
-	//}}AFX_VIRTUAL
-
-
-	// Generated message map functions
-	//{{AFX_MSG(CCopyThread)
-		// NOTE - the ClassWizard will add and remove member functions here.
-	//}}AFX_MSG
-
-	DECLARE_MESSAGE_MAP()
 };
-
-/////////////////////////////////////////////////////////////////////////////
-
-//{{AFX_INSERT_LOCATION}}
-// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
-
-#endif // !defined(AFX_COPYTHREAD_H__C6766F04_0111_4314_986A_A0E02FF3B322__INCLUDED_)

+ 38 - 6
EventThread.cpp

@@ -43,6 +43,7 @@ bool CEventThread::FireEvent(int eventId)
 		if(it->second == eventId)
 		{
 			eventHandle = it->first;
+			break;
 		}
 	}
 
@@ -55,10 +56,32 @@ bool CEventThread::FireEvent(int eventId)
 	return false;
 }
 
+bool CEventThread::UndoFireEvent(int eventId)
+{
+	HANDLE eventHandle = NULL;
+	for(EventMapType::iterator it = m_eventMap.begin(); it != m_eventMap.end(); it++)
+	{
+		if(it->second == eventId)
+		{
+			eventHandle = it->first;
+			break;
+		}
+	}
+
+	if(eventHandle != NULL)
+	{
+		ResetEvent(eventHandle);
+		return true;
+	}
+
+	return false;
+}
+
 void CEventThread::Start(void *param) 
 {
 	if(m_threadRunning == false)
 	{
+		ResetEvent(m_hEvt);
 		m_exitThread = false;
 		m_param = param;
 		m_thread = (HANDLE)_beginthreadex(NULL, 0, EventThreadFnc, this, 0, &m_threadID);
@@ -66,18 +89,26 @@ void CEventThread::Start(void *param)
 		// now wait until the thread is up and really running
 		WaitForSingleObject(m_hEvt, 1000);
 	}
+	else
+	{
+		UndoFireEvent(EXIT_EVENT);
+	}
 }
 
 void CEventThread::Stop(int waitTime) 
 {
-	m_exitThread = true;
-	FireEvent(EXIT_EVENT);
-
-	if (WAIT_OBJECT_0 != WaitForSingleObject(m_hEvt, waitTime))
+	if(m_threadRunning)
 	{
-		if(TerminateThread(m_thread, 0))
+		m_exitThread = true;	
+		FireEvent(EXIT_EVENT);
+
+		if(waitTime > 0)
 		{
-			m_threadRunning = false;
+			if (WAIT_OBJECT_0 != WaitForSingleObject(m_hEvt, waitTime))
+			{
+				TerminateThread(m_thread, 0);
+				m_threadRunning = false;
+			}
 		}
 	}
 };
@@ -95,6 +126,7 @@ void CEventThread::RunThread()
 	}
 
 	SetEvent(m_hEvt);
+	ResetEvent(m_hEvt);
 
 	while(true)
 	{

+ 1 - 0
EventThread.h

@@ -17,6 +17,7 @@ protected:
 	virtual void OnEvent(int eventId, void *param)	{ return; }
 	virtual void OnTimeOut(void *param) { return; }
 	void RunThread();
+	bool UndoFireEvent(int eventId);
 
 	UINT m_threadID;
 	HANDLE m_thread;

+ 1 - 0
HTMLFormatAggregator.cpp

@@ -1,6 +1,7 @@
 #include "stdafx.h"
 #include ".\htmlformataggregator.h"
 #include "Misc.h"
+#include "Tokenizer.h"
 
 CHTMLFormatAggregator::CHTMLFormatAggregator(CStringA csSepator) :
 	m_csSeparator(csSepator)

+ 627 - 1037
MainFrm.cpp

@@ -16,44 +16,42 @@
 #include "DittoCopyBuffer.h"
 
 #ifdef _DEBUG
-#define new DEBUG_NEW
-#undef THIS_FILE
-static char THIS_FILE[] = __FILE__;
-#endif
+    #define new DEBUG_NEW
+    #undef THIS_FILE
+    static char THIS_FILE[] = __FILE__;
+#endif 
 
-#define	WM_ICON_NOTIFY			WM_APP+10
+#define WM_ICON_NOTIFY			WM_APP+10
 #define MYWM_NOTIFYICON (WM_USER+1)
 
 
 bool CShowMainFrame::m_bShowingMainFrame = false;
 
-CShowMainFrame::CShowMainFrame() : 
-	m_bHideMainFrameOnExit(false), 
-	m_hWnd(NULL)
+CShowMainFrame::CShowMainFrame(): m_bHideMainFrameOnExit(false), m_hWnd(NULL)
 {
-	if(m_bShowingMainFrame == false)
-	{
-		theApp.m_pMainFrame->m_TrayIcon.MaximiseFromTray(theApp.m_pMainFrame);
-		m_bHideMainFrameOnExit = true;
-		m_bShowingMainFrame = true;
-	}
+    if(m_bShowingMainFrame == false)
+    {
+        theApp.m_pMainFrame->m_TrayIcon.MaximiseFromTray(theApp.m_pMainFrame);
+        m_bHideMainFrameOnExit = true;
+        m_bShowingMainFrame = true;
+    }
 
-	m_hWnd = theApp.m_pMainFrame->GetSafeHwnd();
+    m_hWnd = theApp.m_pMainFrame->GetSafeHwnd();
 }
 
 CShowMainFrame::~CShowMainFrame()
 {
-	if(m_bHideMainFrameOnExit && m_hWnd && ::IsWindow(m_hWnd))
-	{
-		theApp.m_pMainFrame->m_TrayIcon.MinimiseToTray(theApp.m_pMainFrame);
-		m_bShowingMainFrame = false;
-	}
+    if(m_bHideMainFrameOnExit && m_hWnd && ::IsWindow(m_hWnd))
+    {
+        theApp.m_pMainFrame->m_TrayIcon.MinimiseToTray(theApp.m_pMainFrame);
+        m_bShowingMainFrame = false;
+    }
 }
 
 
 IMPLEMENT_DYNAMIC(CMainFrame, CFrameWnd)
 
-BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
+	BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
 	//{{AFX_MSG_MAP(CMainFrame)
 	ON_WM_CREATE()
 	ON_COMMAND(ID_FIRST_OPTION, OnFirstOption)
@@ -66,29 +64,24 @@ BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
 	//}}AFX_MSG_MAP
 	ON_MESSAGE(WM_HOTKEY, OnHotKey)
 	ON_MESSAGE(WM_SHOW_TRAY_ICON, OnShowTrayIcon)
-	ON_MESSAGE(WM_COPYPROPERTIES, OnCopyProperties)
-	ON_MESSAGE(WM_CLOSE_APP, OnShutDown)
 	ON_MESSAGE(WM_CLIPBOARD_COPIED, OnClipboardCopied)
 	ON_WM_CLOSE()
 	ON_MESSAGE(WM_ADD_TO_DATABASE_FROM_SOCKET, OnAddToDatabaseFromSocket)
 	ON_MESSAGE(WM_SEND_RECIEVE_ERROR, OnErrorOnSendRecieve)
 	ON_MESSAGE(WM_FOCUS_CHANGED, OnFocusChanged)
-	ON_MESSAGE(WM_FOCUS_CHANGED+1, OnKeyBoardChanged)
 	ON_MESSAGE(WM_CUSTOMIZE_TRAY_MENU, OnCustomizeTrayMenu)
 	ON_COMMAND(ID_FIRST_IMPORT, OnFirstImport)
 	ON_MESSAGE(WM_EDIT_WND_CLOSING, OnEditWndClose)
 	ON_WM_DESTROY()
 	ON_COMMAND(ID_FIRST_NEWCLIP, OnFirstNewclip)
 	ON_MESSAGE(WM_SET_CONNECTED, OnSetConnected)
-	ON_MESSAGE(MYWM_NOTIFYICON, OnTrayNotify)
-END_MESSAGE_MAP()
+	ON_MESSAGE(WM_LOAD_ClIP_ON_CLIPBOARD, OnLoadClipOnClipboard)
+	END_MESSAGE_MAP()
 
-static UINT indicators[] =
+	static UINT indicators[] = 
 {
-	ID_SEPARATOR,           // status line indicator
-	ID_INDICATOR_CAPS,
-	ID_INDICATOR_NUM,
-	ID_INDICATOR_SCRL,
+	ID_SEPARATOR,  // status line indicator
+	ID_INDICATOR_CAPS, ID_INDICATOR_NUM, ID_INDICATOR_SCRL, 
 };
 
 /////////////////////////////////////////////////////////////////////////////
@@ -96,145 +89,137 @@ static UINT indicators[] =
 
 CMainFrame::CMainFrame()
 {
-	m_pEditFrameWnd = NULL;
-	m_keyStateModifiers = 0;
-	m_startKeyStateTime = 0;
-	m_bMovedSelectionMoveKeyState = false;
-	m_keyModifiersTimerCount = 0;
+    m_pEditFrameWnd = NULL;
+    m_keyStateModifiers = 0;
+    m_startKeyStateTime = 0;
+    m_bMovedSelectionMoveKeyState = false;
+    m_keyModifiersTimerCount = 0;
 }
 
 CMainFrame::~CMainFrame()
 {
-	if(g_Opt.m_bUseHookDllForFocus)
-	{
-		Log(_T("Unloading focus dll for tracking focus changes"));
-		StopMonitoringFocusChanges();
-	}
-	
-	CGetSetOptions::SetMainHWND(0);
+    if(g_Opt.m_bUseHookDllForFocus)
+    {
+        Log(_T("Unloading focus dll for tracking focus changes"));
+        StopMonitoringFocusChanges();
+    }
+
+    CGetSetOptions::SetMainHWND(0);
 }
 
 int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
 {
-	if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
-		return -1;
-
-	//Center the main window so message boxes are in the center
-		CRect rcScreen;
-	GetMonitorRect(0, &rcScreen);
-	CPoint cpCenter = rcScreen.CenterPoint();
-	MoveWindow(cpCenter.x,cpCenter.x, -2, -2);
+    if(CFrameWnd::OnCreate(lpCreateStruct) ==  - 1)
+    {
+        return  - 1;
+    }
 
-	//Then set the main window to transparent so it's never shown
-	//if it is shown then only the task tray icon
-	m_Transparency.SetTransparent(m_hWnd, 0, true);
+    //Center the main window so message boxes are in the center
+    CRect rcScreen;
+    GetMonitorRect(0, &rcScreen);
+    CPoint cpCenter = rcScreen.CenterPoint();
+    MoveWindow(cpCenter.x, cpCenter.x,  - 2,  - 2);
 
-	SetWindowText(_T(""));
-
-	if(g_Opt.m_bUseHookDllForFocus)
-	{
-		Log(_T("Loading hook dll to track focus changes"));
-		MonitorFocusChanges(m_hWnd, WM_FOCUS_CHANGED);
-	}
-	else
-	{
-		Log(_T("Setting polling timer to track focus"));
-		SetTimer(ACTIVE_WINDOW_TIMER, g_Opt.FocusWndTimerTimeout(), 0);
-	}
+    //Then set the main window to transparent so it's never shown
+    //if it is shown then only the task tray icon
+    m_Transparency.SetTransparent(m_hWnd, 0, true);
 
-	SetWindowText(_T("Ditto"));
+    SetWindowText(_T(""));
 
-	HICON hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
+    if(g_Opt.m_bUseHookDllForFocus)
+    {
+        Log(_T("Loading hook dll to track focus changes"));
+        MonitorFocusChanges(m_hWnd, WM_FOCUS_CHANGED);
+    }
+    else
+    {
+        Log(_T("Setting polling timer to track focus"));
+        SetTimer(ACTIVE_WINDOW_TIMER, g_Opt.FocusWndTimerTimeout(), 0);
+    }
 
-	m_TrayIcon.Create(NULL,				// Let icon deal with its own messages
-						WM_ICON_NOTIFY,	// Icon notify message to use
-						_T("Ditto"),	// tooltip
-						hIcon,
-						IDR_MENU,			// ID of tray icon
-						FALSE,
-						_T(""),			// balloon tip
-						_T(""),			// balloon title
-						NULL,				// balloon icon
-						20 );
+    SetWindowText(_T("Ditto"));
 
-	m_TrayIcon.SetSingleClickSelect(TRUE);
-	m_TrayIcon.MinimiseToTray(this);
-	m_TrayIcon.SetMenuDefaultItem(ID_FIRST_SHOWQUICKPASTE, FALSE);
+    HICON hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
 
-	//Only if in release
-	#ifndef _DEBUG
-	{
-		//If not showing the icon show it for 40 seconds so they can get to the option
-		//in case they can't remember the hot keys or something like that
-		if(!(CGetSetOptions::GetShowIconInSysTray()))
-			SetTimer(HIDE_ICON_TIMER, 40000, 0);
-	}
-	#endif
+    m_TrayIcon.Create(NULL, WM_ICON_NOTIFY, _T("Ditto"), hIcon, IDR_MENU, FALSE, _T(""), _T(""), NULL, 20);
+    m_TrayIcon.SetSingleClickSelect(TRUE);
+    m_TrayIcon.MinimiseToTray(this);
+    m_TrayIcon.SetMenuDefaultItem(ID_FIRST_SHOWQUICKPASTE, FALSE);
 
-	//don't check for updates if running from a U3 device
-	if(!g_Opt.m_bU3)
-	{
-		SetTimer(CHECK_FOR_UPDATE, ONE_MINUTE*5, 0);
-	}
+    //Only if in release
+    #ifndef _DEBUG
+        {
+            //If not showing the icon show it for 40 seconds so they can get to the option
+            //in case they can't remember the hot keys or something like that
+            if(!(CGetSetOptions::GetShowIconInSysTray()))
+            {
+                SetTimer(HIDE_ICON_TIMER, 40000, 0);
+            }
+        }
+    #endif 
 
-	SetTimer(CLOSE_WINDOW_TIMER, ONE_MINUTE*60, 0);
-	SetTimer(REMOVE_OLD_REMOTE_COPIES, ONE_DAY, 0);
-	SetTimer(REMOVE_OLD_ENTRIES_TIMER, 3000, 0);
+    SetTimer(CLOSE_WINDOW_TIMER, ONE_HOUR *24, 0);
+    SetTimer(REMOVE_OLD_REMOTE_COPIES, ONE_DAY, 0);
+    SetTimer(REMOVE_OLD_ENTRIES_TIMER, ONE_MINUTE *15, 0);
 
-	m_ulCopyGap = CGetSetOptions::GetCopyGap();
+    m_ulCopyGap = CGetSetOptions::GetCopyGap();
 
-	theApp.AfterMainCreate();
+    theApp.AfterMainCreate();
 
-	m_thread.Start(this);
+    m_thread.Start(this);
 
-	return 0;
+    return 0;
 }
 
-BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
+BOOL CMainFrame::PreCreateWindow(CREATESTRUCT &cs)
 {
-	if(cs.hMenu!=NULL)  
-	{
-		::DestroyMenu(cs.hMenu);      // delete menu if loaded
-		cs.hMenu = NULL;              // no menu for this window
-	}
+    if(cs.hMenu != NULL)
+    {
+        ::DestroyMenu(cs.hMenu); // delete menu if loaded
+        cs.hMenu = NULL; // no menu for this window
+    }
 
-	if( !CFrameWnd::PreCreateWindow(cs) )
-		return FALSE;
-
-	WNDCLASS wc;	
-	wc.style = CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW;
-	wc.lpfnWndProc = AfxWndProc;
-	wc.cbClsExtra = 0;
-	wc.cbWndExtra = 0;
-	wc.hInstance = AfxGetInstanceHandle();
-	wc.hIcon = NULL;
-	wc.hCursor = LoadCursor(NULL, IDC_ARROW);
-	wc.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
-	wc.lpszMenuName =  NULL;
-	wc.lpszClassName = _T("Ditto");
-
-	// Create the QPaste window class
-	if (!AfxRegisterClass(&wc))
-		return FALSE;
-
-	cs.lpszClass = wc.lpszClassName;
-	
-	return TRUE;
+    if(!CFrameWnd::PreCreateWindow(cs))
+    {
+        return FALSE;
+    }
+
+    WNDCLASS wc;
+    wc.style = CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW;
+    wc.lpfnWndProc = AfxWndProc;
+    wc.cbClsExtra = 0;
+    wc.cbWndExtra = 0;
+    wc.hInstance = AfxGetInstanceHandle();
+    wc.hIcon = NULL;
+    wc.hCursor = LoadCursor(NULL, IDC_ARROW);
+    wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
+    wc.lpszMenuName = NULL;
+    wc.lpszClassName = _T("Ditto");
+
+    // Create the QPaste window class
+    if(!AfxRegisterClass(&wc))
+    {
+        return FALSE;
+    }
+
+    cs.lpszClass = wc.lpszClassName;
+
+    return TRUE;
 }
 
 /////////////////////////////////////////////////////////////////////////////
 // CMainFrame diagnostics
 
 #ifdef _DEBUG
-void CMainFrame::AssertValid() const
-{
-	CFrameWnd::AssertValid();
-}
+    void CMainFrame::AssertValid()const
+    {
+        CFrameWnd::AssertValid();
+    }
 
-void CMainFrame::Dump(CDumpContext& dc) const
-{
-	CFrameWnd::Dump(dc);
-}
+    void CMainFrame::Dump(CDumpContext &dc)const
+    {
+        CFrameWnd::Dump(dc);
+    }
 
 #endif //_DEBUG
 
@@ -242,1056 +227,661 @@ void CMainFrame::Dump(CDumpContext& dc) const
 // CMainFrame message handlers
 
 
-void CMainFrame::OnFirstOption() 
+void CMainFrame::OnFirstOption()
 {
-	theApp.ShowOptionsDlg();
+    theApp.ShowOptionsDlg();
 }
 
-void CMainFrame::OnFirstExit() 
+void CMainFrame::OnFirstExit()
 {
-//	CloseAllOpenDialogs();
-	this->SendMessage(WM_CLOSE, 0, 0);
+    this->SendMessage(WM_CLOSE, 0, 0);
 }
 
 LRESULT CMainFrame::OnHotKey(WPARAM wParam, LPARAM lParam)
 {
-	if(theApp.m_pDittoHotKey && wParam == theApp.m_pDittoHotKey->m_Atom)
-	{
-		//If they still have the shift/ctrl keys down
-		if(m_keyStateModifiers != 0 && m_quickPaste.IsWindowVisibleEx())
-		{
-			if(m_bMovedSelectionMoveKeyState == false)
-			{
-				Log(_T("Setting flag m_bMovedSelectionMoveKeyState to true, will paste when modifer keys are up"));
-			}
-
-			m_quickPaste.MoveSelection(true);
-			m_bMovedSelectionMoveKeyState = true;
-		}
-		else if(g_Opt.m_HideDittoOnHotKeyIfAlreadyShown && m_quickPaste.IsWindowVisibleEx())
-		{
-			m_quickPaste.HideQPasteWnd();
-		}
-		else
-		{
-			m_keyModifiersTimerCount = 0;
-			m_bMovedSelectionMoveKeyState = false;
-			m_startKeyStateTime = GetTickCount();
-			m_keyStateModifiers = GetKeyStateModifiers();
-			SetTimer(KEY_STATE_MODIFIERS, 50, NULL);
-			
-			theApp.m_activeWnd.TrackActiveWnd(NULL);
-			
-			m_quickPaste.ShowQPasteWnd(this, false, true, FALSE);
-		}		
-	}
-	else if(theApp.m_pNamedCopy && wParam == theApp.m_pNamedCopy->m_Atom)
-	{
-		if(g_Opt.m_bU3 == false)
-		{
-			if(theApp.m_QuickPasteMode == CCP_MainApp::NONE_QUICK_PASTE)
-			{
-				theApp.m_QuickPasteMode = CCP_MainApp::ADDING_QUICK_PASTE;
-
-				theApp.m_activeWnd.SendCopy();
-
-				m_pTypingToolTip = new CToolTipEx;
-				m_pTypingToolTip->Create(this);
-
-				csTypeToolTipTitle = theApp.m_Language.GetString("Named_Copy_Title", "Ditto - Named Copy");
-
-				m_pTypingToolTip->SetToolTipText(csTypeToolTipTitle);
-
-				CRect rcScreen;
-				GetMonitorRect(0, &rcScreen);
-
-				m_ToolTipPoint = theApp.m_activeWnd.FocusCaret();
-				if(m_ToolTipPoint.x < 0 || m_ToolTipPoint.y < 0)
-				{
-					CRect cr;
-					::GetWindowRect(theApp.m_activeWnd.FocusWnd(), cr);
-					m_ToolTipPoint = cr.CenterPoint();
-				}
-				m_ToolTipPoint.Offset(-15, 15);
-				m_pTypingToolTip->Show(m_ToolTipPoint);
-
-				//If they don't type anything for 2 seconds stop looking
-				SetTimer(STOP_LOOKING_FOR_KEYBOARD, 20000, NULL);
-
-				MonitorKeyboardChanges(m_hWnd, WM_FOCUS_CHANGED+1);
-				SetCaptureKeys(true);
-			}
-		}
-	}
-	else if(theApp.m_pNamedPaste && wParam == theApp.m_pNamedPaste->m_Atom)
-	{
-		if(g_Opt.m_bU3 == false)
-		{
-			if(theApp.m_QuickPasteMode == CCP_MainApp::NONE_QUICK_PASTE)
-			{
-				theApp.m_QuickPasteMode = CCP_MainApp::PASTING_QUICK_PASTE;
-
-				m_pTypingToolTip = new CToolTipEx;
-				m_pTypingToolTip->Create(this);
-
-				csTypeToolTipTitle = theApp.m_Language.GetString("Named_Paste_Title", "Ditto - Named Paste");
-				m_pTypingToolTip->SetToolTipText(csTypeToolTipTitle);
-
-				CRect rcScreen;
-
-				m_ToolTipPoint = theApp.m_activeWnd.FocusCaret();
-				if(m_ToolTipPoint.x < 0 || m_ToolTipPoint.y < 0)
-				{
-					CRect cr;
-					::GetWindowRect(theApp.m_activeWnd.FocusWnd(), cr);
-					m_ToolTipPoint = cr.CenterPoint();
-				}
-				m_ToolTipPoint.Offset(-15, 15);
-				m_pTypingToolTip->Show(m_ToolTipPoint);
-
-				//If they don't type anything for 2 seconds stop looking
-				SetTimer(STOP_LOOKING_FOR_KEYBOARD, 20000, NULL);
-
-				MonitorKeyboardChanges(m_hWnd, WM_FOCUS_CHANGED+1);
-				SetCaptureKeys(true);
-			}
-		}
-	}
-	else if(theApp.m_pPosOne && wParam == theApp.m_pPosOne->m_Atom)
-	{
-		DoFirstTenPositionsPaste(0);
-	}
-	else if(theApp.m_pPosTwo && wParam == theApp.m_pPosTwo->m_Atom)
-	{
-		DoFirstTenPositionsPaste(1);
-	}
-	else if(theApp.m_pPosThree && wParam == theApp.m_pPosThree->m_Atom)
-	{
-		DoFirstTenPositionsPaste(2);
-	}
-	else if(theApp.m_pPosFour && wParam == theApp.m_pPosFour->m_Atom)
-	{
-		DoFirstTenPositionsPaste(3);
-	}
-	else if(theApp.m_pPosFive && wParam == theApp.m_pPosFive->m_Atom)
-	{
-		DoFirstTenPositionsPaste(4);
-	}
-	else if(theApp.m_pPosSix && wParam == theApp.m_pPosSix->m_Atom)
-	{
-		DoFirstTenPositionsPaste(5);
-	}
-	else if(theApp.m_pPosSeven && wParam == theApp.m_pPosSeven->m_Atom)
-	{
-		DoFirstTenPositionsPaste(6);
-	}
-	else if(theApp.m_pPosEight && wParam == theApp.m_pPosEight->m_Atom)
-	{
-		DoFirstTenPositionsPaste(7);
-	}
-	else if(theApp.m_pPosNine && wParam == theApp.m_pPosNine->m_Atom)
-	{
-		DoFirstTenPositionsPaste(8);
-	}
-	else if(theApp.m_pPosTen && wParam == theApp.m_pPosTen->m_Atom)
-	{
-		DoFirstTenPositionsPaste(9);
-	}
-	else if(theApp.m_pCopyBuffer1 && wParam == theApp.m_pCopyBuffer1->m_Atom)
-	{
-		theApp.m_CopyBuffer.StartCopy(0);
-	}
-	else if(theApp.m_pPasteBuffer1 && wParam == theApp.m_pPasteBuffer1->m_Atom)
-	{
-		theApp.m_CopyBuffer.PastCopyBuffer(0);
-	}
-	else if(theApp.m_pCutBuffer1 && wParam == theApp.m_pCutBuffer1->m_Atom)
-	{
-		theApp.m_CopyBuffer.StartCopy(0, true);
-	}
-	else if(theApp.m_pCopyBuffer2 && wParam == theApp.m_pCopyBuffer2->m_Atom)
-	{
-		theApp.m_CopyBuffer.StartCopy(1);
-	}
-	else if(theApp.m_pPasteBuffer2 && wParam == theApp.m_pPasteBuffer2->m_Atom)
-	{
-		theApp.m_CopyBuffer.PastCopyBuffer(1);
-	}
-	else if(theApp.m_pCutBuffer2 && wParam == theApp.m_pCutBuffer2->m_Atom)
-	{
-		theApp.m_CopyBuffer.StartCopy(1, true);
-	}
-	else if(theApp.m_pCopyBuffer3 && wParam == theApp.m_pCopyBuffer3->m_Atom)
-	{
-		theApp.m_CopyBuffer.StartCopy(2);
-	}
-	else if(theApp.m_pPasteBuffer3 && wParam == theApp.m_pPasteBuffer3->m_Atom)
-	{	
-		theApp.m_CopyBuffer.PastCopyBuffer(2);
-	}
-	else if(theApp.m_pCutBuffer3 && wParam == theApp.m_pCutBuffer3->m_Atom)
-	{
-		theApp.m_CopyBuffer.StartCopy(2, true);
-	}
-
-	return TRUE;
+    if(theApp.m_pDittoHotKey && wParam == theApp.m_pDittoHotKey->m_Atom)
+    {
+        //If they still have the shift/ctrl keys down
+        if(m_keyStateModifiers != 0 && m_quickPaste.IsWindowVisibleEx())
+        {
+            Log(_T("On Show Ditto HotKey, key state modifiers are still down, moving selection"));
+
+            if(m_bMovedSelectionMoveKeyState == false)
+            {
+                Log(_T("Setting flag m_bMovedSelectionMoveKeyState to true, will paste when modifer keys are up"));
+            }
+
+            m_quickPaste.MoveSelection(true);
+            m_bMovedSelectionMoveKeyState = true;
+        }
+        else if(g_Opt.m_HideDittoOnHotKeyIfAlreadyShown && m_quickPaste.IsWindowVisibleEx())
+        {
+            Log(_T("On Show Ditto HotKey, window is alread visible, hiding window"));
+            m_quickPaste.HideQPasteWnd();
+        }
+        else
+        {
+            Log(_T("On Show Ditto HotKey, showing window"));
+
+            m_keyModifiersTimerCount = 0;
+            m_bMovedSelectionMoveKeyState = false;
+            m_startKeyStateTime = GetTickCount();
+            m_keyStateModifiers = CAccels::GetKeyStateModifiers();
+            SetTimer(KEY_STATE_MODIFIERS, 50, NULL);
+
+            theApp.m_activeWnd.TrackActiveWnd(NULL);
+
+            m_quickPaste.ShowQPasteWnd(this, false, true, FALSE);
+        }
+
+        KillTimer(CLOSE_WINDOW_TIMER);
+        SetTimer(CLOSE_WINDOW_TIMER, ONE_HOUR *24, 0);
+    }
+    else if(theApp.m_pPosOne && wParam == theApp.m_pPosOne->m_Atom)
+    {
+        Log(_T("Pos 1 hot key"));
+        DoFirstTenPositionsPaste(0);
+    }
+    else if(theApp.m_pPosTwo && wParam == theApp.m_pPosTwo->m_Atom)
+    {
+        Log(_T("Pos 2 hot key"));
+        DoFirstTenPositionsPaste(1);
+    }
+    else if(theApp.m_pPosThree && wParam == theApp.m_pPosThree->m_Atom)
+    {
+        Log(_T("Pos 3 hot key"));
+        DoFirstTenPositionsPaste(2);
+    }
+    else if(theApp.m_pPosFour && wParam == theApp.m_pPosFour->m_Atom)
+    {
+        Log(_T("Pos 4 hot key"));
+        DoFirstTenPositionsPaste(3);
+    }
+    else if(theApp.m_pPosFive && wParam == theApp.m_pPosFive->m_Atom)
+    {
+        Log(_T("Pos 5 hot key"));
+        DoFirstTenPositionsPaste(4);
+    }
+    else if(theApp.m_pPosSix && wParam == theApp.m_pPosSix->m_Atom)
+    {
+        Log(_T("Pos 6 hot key"));
+        DoFirstTenPositionsPaste(5);
+    }
+    else if(theApp.m_pPosSeven && wParam == theApp.m_pPosSeven->m_Atom)
+    {
+        Log(_T("Pos 7 hot key"));
+        DoFirstTenPositionsPaste(6);
+    }
+    else if(theApp.m_pPosEight && wParam == theApp.m_pPosEight->m_Atom)
+    {
+        Log(_T("Pos 8 hot key"));
+        DoFirstTenPositionsPaste(7);
+    }
+    else if(theApp.m_pPosNine && wParam == theApp.m_pPosNine->m_Atom)
+    {
+        Log(_T("Pos 9 hot key"));
+        DoFirstTenPositionsPaste(8);
+    }
+    else if(theApp.m_pPosTen && wParam == theApp.m_pPosTen->m_Atom)
+    {
+        Log(_T("Pos 10 hot key"));
+        DoFirstTenPositionsPaste(9);
+    }
+    else if(theApp.m_pCopyBuffer1 && wParam == theApp.m_pCopyBuffer1->m_Atom)
+    {
+        Log(_T("Copy buffer 1 hot key"));
+        theApp.m_CopyBuffer.StartCopy(0);
+    }
+    else if(theApp.m_pPasteBuffer1 && wParam == theApp.m_pPasteBuffer1->m_Atom)
+    {
+        Log(_T("Paste buffer 1 hot key"));
+        theApp.m_CopyBuffer.PastCopyBuffer(0);
+    }
+    else if(theApp.m_pCutBuffer1 && wParam == theApp.m_pCutBuffer1->m_Atom)
+    {
+        Log(_T("Cut buffer 1 hot key"));
+        theApp.m_CopyBuffer.StartCopy(0, true);
+    }
+    else if(theApp.m_pCopyBuffer2 && wParam == theApp.m_pCopyBuffer2->m_Atom)
+    {
+        Log(_T("Copy buffer 2 hot key"));
+        theApp.m_CopyBuffer.StartCopy(1);
+    }
+    else if(theApp.m_pPasteBuffer2 && wParam == theApp.m_pPasteBuffer2->m_Atom)
+    {
+        Log(_T("Paste buffer 2 hot key"));
+        theApp.m_CopyBuffer.PastCopyBuffer(1);
+    }
+    else if(theApp.m_pCutBuffer2 && wParam == theApp.m_pCutBuffer2->m_Atom)
+    {
+        Log(_T("Cut buffer 2 hot key"));
+        theApp.m_CopyBuffer.StartCopy(1, true);
+    }
+    else if(theApp.m_pCopyBuffer3 && wParam == theApp.m_pCopyBuffer3->m_Atom)
+    {
+        Log(_T("Copy buffer 3 hot key"));
+        theApp.m_CopyBuffer.StartCopy(2);
+    }
+    else if(theApp.m_pPasteBuffer3 && wParam == theApp.m_pPasteBuffer3->m_Atom)
+    {
+        Log(_T("Paste buffer 3 hot key"));
+        theApp.m_CopyBuffer.PastCopyBuffer(2);
+    }
+    else if(theApp.m_pCutBuffer3 && wParam == theApp.m_pCutBuffer3->m_Atom)
+    {
+        Log(_T("Cut buffer 3 hot key"));
+        theApp.m_CopyBuffer.StartCopy(2, true);
+    }
+
+    return TRUE;
 }
 
 void CMainFrame::DoFirstTenPositionsPaste(int nPos)
 {
-	try
-	{	
-		CppSQLite3Query q = theApp.m_db.execQueryEx(_T("SELECT lID, bIsGroup, lDate FROM Main ")
-							_T("WHERE ((bIsGroup = 1 AND lParentID = -1) OR bIsGroup = 0) ")
-							_T("ORDER BY bIsGroup ASC, lDate DESC ")
-							_T("LIMIT 1 OFFSET %d"), nPos);
-
-		if(q.eof() == false)
-		{
-			if(q.getIntField(_T("bIsGroup")) == FALSE)
-			{	
-				//Don't move these to the top
-				BOOL bItWas = g_Opt.m_bUpdateTimeOnPaste;
-				g_Opt.m_bUpdateTimeOnPaste = FALSE;
-
-				CProcessPaste paste;
-				paste.GetClipIDs().Add(q.getIntField(_T("lID")));
-				paste.m_bActivateTarget = false;
-				paste.m_bSendPaste = g_Opt.m_bSendPasteOnFirstTenHotKeys ? true : false;
-				paste.DoPaste();
-				theApp.OnPasteCompleted();
-
-				g_Opt.m_bUpdateTimeOnPaste = bItWas;
-			}
-		}
-	}
-	CATCH_SQLITE_EXCEPTION
-}
+    try
+    {
+        CppSQLite3Query q = theApp.m_db.execQueryEx(_T("SELECT lID, bIsGroup, lDate FROM Main ")_T("WHERE ((bIsGroup = 1 AND lParentID = -1) OR bIsGroup = 0) ")_T("ORDER BY bIsGroup ASC, lDate DESC ")_T("LIMIT 1 OFFSET %d"), nPos);
 
-void CMainFrame::DoDittoCopyBufferPaste(int nCopyBuffer)
-{
-	try
-	{	
-		CppSQLite3Query q = theApp.m_db.execQueryEx(_T("SELECT lID FROM Main WHERE CopyBuffer = %d"), nCopyBuffer);
-
-		if(q.eof() == false)
-		{	
-			//Don't move these to the top
-			BOOL bItWas = g_Opt.m_bUpdateTimeOnPaste;
-			g_Opt.m_bUpdateTimeOnPaste = FALSE;
-
-			CProcessPaste paste;
-			paste.GetClipIDs().Add(q.getIntField(_T("lID")));
-			paste.m_bActivateTarget = false;
-			paste.DoPaste();
-			theApp.OnPasteCompleted();
-
-			g_Opt.m_bUpdateTimeOnPaste = bItWas;
-		}
-	}
-	CATCH_SQLITE_EXCEPTION
+        if(q.eof() == false)
+        {
+            if(q.getIntField(_T("bIsGroup")) == FALSE)
+            {
+                //Don't move these to the top
+                BOOL bItWas = g_Opt.m_bUpdateTimeOnPaste;
+                g_Opt.m_bUpdateTimeOnPaste = FALSE;
+
+                CProcessPaste paste;
+                paste.GetClipIDs().Add(q.getIntField(_T("lID")));
+                paste.m_bActivateTarget = false;
+                paste.m_bSendPaste = g_Opt.m_bSendPasteOnFirstTenHotKeys ? true : false;
+                paste.DoPaste();
+                theApp.OnPasteCompleted();
+
+                g_Opt.m_bUpdateTimeOnPaste = bItWas;
+            }
+        }
+    }
+    CATCH_SQLITE_EXCEPTION
 }
 
-void CMainFrame::OnTimer(UINT nIDEvent) 
+void CMainFrame::DoDittoCopyBufferPaste(int nCopyBuffer)
 {
-	switch(nIDEvent)
-	{
-	case HIDE_ICON_TIMER:
-		{
-			m_TrayIcon.HideIcon();
-			KillTimer(nIDEvent);
+    try
+    {
+        CppSQLite3Query q = theApp.m_db.execQueryEx(_T("SELECT lID FROM Main WHERE CopyBuffer = %d"), nCopyBuffer);
+
+        if(q.eof() == false)
+        {
+            //Don't move these to the top
+            BOOL bItWas = g_Opt.m_bUpdateTimeOnPaste;
+            g_Opt.m_bUpdateTimeOnPaste = FALSE;
+
+            CProcessPaste paste;
+            paste.GetClipIDs().Add(q.getIntField(_T("lID")));
+            paste.m_bActivateTarget = false;
+            paste.DoPaste();
+            theApp.OnPasteCompleted();
+
+            g_Opt.m_bUpdateTimeOnPaste = bItWas;
+        }
+    }
+    CATCH_SQLITE_EXCEPTION
+}
+
+void CMainFrame::OnTimer(UINT nIDEvent)
+{
+    switch(nIDEvent)
+    {
+        case HIDE_ICON_TIMER:
+            {
+                m_TrayIcon.HideIcon();
+                KillTimer(nIDEvent);
+            }
 			break;
-		}
-	case CLOSE_WINDOW_TIMER:
-		{
-			m_quickPaste.CloseQPasteWnd();
-			break;
-		}
-	case REMOVE_OLD_ENTRIES_TIMER:
-		{
-			m_thread.FireDeleteEntries();
-			break;
-		}
-	case CHECK_FOR_UPDATE:
-		{
-			KillTimer(CHECK_FOR_UPDATE);
 
-			CInternetUpdate Update;
-			if(Update.CheckForUpdate(NULL, TRUE, FALSE))
-			{
-				PostMessage(WM_CLOSE, 0, 0);
-			}
-			else
-			{
-				SetTimer(CHECK_FOR_UPDATE, ONE_MINUTE*60*24, NULL);
-			}
+        case CLOSE_WINDOW_TIMER:
+            {
+                m_quickPaste.CloseQPasteWnd();
+            }
 			break;
-		}
-	case CLOSE_APP:
-		{
-			PostMessage(WM_CLOSE, 0, 0);
-			KillTimer(CLOSE_APP);
-			
+
+        case REMOVE_OLD_ENTRIES_TIMER:
+            {
+                m_thread.FireDeleteEntries();
+            }
 			break;
-		}
-	case STOP_MONITORING_KEYBOARD_TIMER:
-		{
-			StopLookingForKeystrokes(false);
-			if(m_csKeyboardPaste.IsEmpty() == FALSE)
+
+		case REMOVE_OLD_REMOTE_COPIES:
 			{
-				if(theApp.m_QuickPasteMode == CCP_MainApp::PASTING_QUICK_PASTE)
-				{
-					PasteQuickPasteEntry(m_csKeyboardPaste);
-				}
-				else
-				{
-					SaveQuickPasteEntry(m_csKeyboardPaste, theApp.m_pQuickPasteClip);
-				}
-
-				StopLookingForKeystrokes(true);
+            	m_thread.FireRemoveRemoteFiles();
 			}
-						
 			break;
-		}
-	case STOP_LOOKING_FOR_KEYBOARD:
-		{
-			if(theApp.m_QuickPasteMode == CCP_MainApp::ADDING_QUICK_PASTE)
+
+        case KEY_STATE_MODIFIERS:
+            m_keyModifiersTimerCount++;
+            if(m_keyStateModifiers != 0)
+            {
+                BYTE keyState = CAccels::GetKeyStateModifiers();
+                //Have they release the key state modifiers yet(ctrl, shift, alt)
+                if((m_keyStateModifiers &keyState) == 0)
+                {
+                    KillTimer(KEY_STATE_MODIFIERS);
+                    long waitTime = (long)(GetTickCount() - m_startKeyStateTime);
+
+                    if(m_bMovedSelectionMoveKeyState || m_keyModifiersTimerCount > g_Opt.GetKeyStateWaitTimerCount())
+                    {
+                        Log(StrF(_T("Timer KEY_STATE_MODIFIERS timeout count hit(%d), count (%d), time (%d), Move Selection from Modifer (%d) sending paste"), g_Opt.GetKeyStateWaitTimerCount(), m_keyModifiersTimerCount, waitTime, m_bMovedSelectionMoveKeyState));
+                        m_quickPaste.OnKeyStateUp();
+                    }
+                    else
+                    {
+                        Log(StrF(_T("Timer KEY_STATE_MODIFIERS count NOT hit(%d), count (%d) time (%d)"), g_Opt.GetKeyStateWaitTimerCount(), m_keyModifiersTimerCount, waitTime));
+                        m_quickPaste.SetKeyModiferState(false);
+                    }
+
+                    m_keyStateModifiers = 0;
+                    m_keyModifiersTimerCount = 0;
+                    m_bMovedSelectionMoveKeyState = 0;
+                }
+            }
+            else
+            {
+                KillTimer(KEY_STATE_MODIFIERS);
+            }
+            break;
+
+        case ACTIVE_WINDOW_TIMER:
 			{
-				SaveQuickPasteEntry(m_csKeyboardPaste, theApp.m_pQuickPasteClip);
+	            if(m_quickPaste.IsWindowVisibleEx())
+	            {
+	                theApp.m_activeWnd.TrackActiveWnd(NULL);
+	            }
 			}
+            break;
 
-			//They didn't type anything within 2 seconds stop looking
-			StopLookingForKeystrokes(true);
-
-			break;
-		}
-	case REMOVE_OLD_REMOTE_COPIES:
-		AfxBeginThread(CMainFrame::RemoteOldRemoteFilesThread, NULL);
-		break;
-
-	case KEY_STATE_MODIFIERS:
-		m_keyModifiersTimerCount++;
-		if(m_keyStateModifiers != 0)
-		{
-			BYTE keyState = GetKeyStateModifiers();
-			//Have they release the key state modifiers yet(ctrl, shift, alt)
-			if((m_keyStateModifiers & keyState) == 0)
+        case FOCUS_CHANGED_TIMER:
 			{
-				KillTimer(KEY_STATE_MODIFIERS);
-				long waitTime = (long)(GetTickCount() - m_startKeyStateTime);
-
-				if(m_bMovedSelectionMoveKeyState || m_keyModifiersTimerCount > g_Opt.GetKeyStateWaitTimerCount())
-				{
-					Log(StrF(_T("Timer KEY_STATE_MODIFIERS timeout count hit(%d), count (%d), time (%d), Move Selection from Modifer (%d) sending paste"), g_Opt.GetKeyStateWaitTimerCount(), m_keyModifiersTimerCount, waitTime, m_bMovedSelectionMoveKeyState));
-					m_quickPaste.OnKeyStateUp();
-				}				
-				else
-				{
-					Log(StrF(_T("Timer KEY_STATE_MODIFIERS count NOT hit(%d), count (%d) time (%d)"), g_Opt.GetKeyStateWaitTimerCount(), m_keyModifiersTimerCount, waitTime));
-					m_quickPaste.SetKeyModiferState(false);
-				}
-
-				m_keyStateModifiers = 0;
-				m_keyModifiersTimerCount = 0;
-				m_bMovedSelectionMoveKeyState = 0;
+	            KillTimer(FOCUS_CHANGED_TIMER);
+	            //Log(StrF(_T("Focus Timer %d"), m_tempFocusWnd));
+	            theApp.m_activeWnd.TrackActiveWnd(m_tempFocusWnd);
 			}
-		}
-		else
-		{
-			KillTimer(KEY_STATE_MODIFIERS);
-		}
-		break;
-	case ACTIVE_WINDOW_TIMER:
-		if(m_quickPaste.IsWindowVisibleEx())
-		{
-			theApp.m_activeWnd.TrackActiveWnd(NULL);
-		}
-		break;
-
-	case FOCUS_CHANGED_TIMER:
-		KillTimer(FOCUS_CHANGED_TIMER);
-		//Log(StrF(_T("Focus Timer %d"), m_tempFocusWnd));
-		theApp.m_activeWnd.TrackActiveWnd(m_tempFocusWnd);
-		break;
-	}
-
-	CFrameWnd::OnTimer(nIDEvent);
-}
-
-void CMainFrame::StopLookingForKeystrokes(bool bInitAppVaribles)
-{
-	StopMonitoringKeyboardChanges();
-	SetCaptureKeys(false);
-	
-	KillTimer(STOP_MONITORING_KEYBOARD_TIMER);
-	KillTimer(STOP_LOOKING_FOR_KEYBOARD);
-
-	if(bInitAppVaribles)
-	{
-		theApp.m_QuickPasteMode = CCP_MainApp::NONE_QUICK_PASTE;
-
-		m_csKeyboardPaste.Empty();
-
-		delete theApp.m_pQuickPasteClip;
-		theApp.m_pQuickPasteClip = NULL;
+            break;
+    }
 
-		m_pTypingToolTip->Hide();
-		m_pTypingToolTip->DestroyWindow();
-	}	
+    CFrameWnd::OnTimer(nIDEvent);
 }
 
 LRESULT CMainFrame::OnShowTrayIcon(WPARAM wParam, LPARAM lParam)
 {
-	if(lParam)
-	{
-		if(!m_TrayIcon.Visible())
-		{
-			KillTimer(HIDE_ICON_TIMER);
-			SetTimer(HIDE_ICON_TIMER, 40000, 0);
-		}
-	}
+    if(lParam)
+    {
+        if(!m_TrayIcon.Visible())
+        {
+            KillTimer(HIDE_ICON_TIMER);
+            SetTimer(HIDE_ICON_TIMER, 40000, 0);
+        }
+    }
 
-	if(wParam)
-		m_TrayIcon.ShowIcon();
-	else 
-		m_TrayIcon.HideIcon();
+    if(wParam)
+    {
+        m_TrayIcon.ShowIcon();
+    }
+    else
+    {
+        m_TrayIcon.HideIcon();
+    }
 
-	return TRUE;
+    return TRUE;
 }
 
-void CMainFrame::OnFirstShowquickpaste() 
+void CMainFrame::OnFirstShowquickpaste()
 {
-	m_quickPaste.ShowQPasteWnd(this, true, false, FALSE);
+    m_quickPaste.ShowQPasteWnd(this, true, false, FALSE);
 }
 
 void CMainFrame::OnFirstToggleConnectCV()
 {
-	theApp.ToggleConnectCV();
-}
-
-void CMainFrame::OnUpdateFirstToggleConnectCV(CCmdUI* pCmdUI) 
-{
-	theApp.UpdateMenuConnectCV( pCmdUI->m_pMenu, ID_FIRST_TOGGLECONNECTCV );
-}
-
-LRESULT CMainFrame::OnCopyProperties(WPARAM wParam, LPARAM lParam)
-{
-	long lID = (long)wParam;
-
-	if(lID > 0)
-	{
-		bool bOldState = theApp.EnableCbCopy(false);
-
-		CCopyProperties props(lID, this);
-		props.SetHideOnKillFocus(true);
-		props.DoModal();
-
-		theApp.EnableCbCopy( bOldState );
-	}
-
-	return TRUE;
+    theApp.ToggleConnectCV();
 }
 
-LRESULT CMainFrame::OnShutDown(WPARAM wParam, LPARAM lParam)
+void CMainFrame::OnUpdateFirstToggleConnectCV(CCmdUI *pCmdUI)
 {
-	SetTimer(CLOSE_APP, 100, NULL);
-
-	return TRUE;
+    theApp.UpdateMenuConnectCV(pCmdUI->m_pMenu, ID_FIRST_TOGGLECONNECTCV);
 }
 
 LRESULT CMainFrame::OnClipboardCopied(WPARAM wParam, LPARAM lParam)
 {
-	Log(_T("Start of function OnClipboardCopied"));
-	// if the delay is undesirable, this could be altered to save one at a time,
-	//  allowing the processing of other messages between saving clips.
-	theApp.SaveCopyClips();
+	Log(_T("Start of function OnClipboardCopied, adding clip to thread for processing"));
 
-	Log(_T("End of function OnClipboardCopied"));
-	return TRUE;
+	CClip *pClip = (CClip*)wParam;
+	if(pClip != NULL)
+	{
+		m_thread.AddClipToSave(pClip);
+	} 
+    
+    Log(_T("End of function OnClipboardCopied"));
+    return TRUE;
 }
 
-BOOL CMainFrame::PreTranslateMessage(MSG* pMsg)
+BOOL CMainFrame::PreTranslateMessage(MSG *pMsg)
 {
-	// target before mouse messages change the focus
-	if( theApp.m_bShowingQuickPaste &&
-		WM_MOUSEFIRST <= pMsg->message && pMsg->message <= WM_MOUSELAST )
-	{	
-		if(g_Opt.m_bUseHookDllForFocus == false)
-		{
-			theApp.m_activeWnd.TrackActiveWnd(NULL);
-		}
-	}
+    // target before mouse messages change the focus
+    if(theApp.m_bShowingQuickPaste && WM_MOUSEFIRST <= pMsg->message && pMsg->message <= WM_MOUSELAST)
+    {
+        if(g_Opt.m_bUseHookDllForFocus == false)
+        {
+            theApp.m_activeWnd.TrackActiveWnd(NULL);
+        }
+    }
 
-	return CFrameWnd::PreTranslateMessage(pMsg);
+    return CFrameWnd::PreTranslateMessage(pMsg);
 }
 
 void CMainFrame::OnClose()
-{	
-	CloseAllOpenDialogs();
+{
+    CloseAllOpenDialogs();
 
-	if(m_pEditFrameWnd)
-	{
-		if(m_pEditFrameWnd->CloseAll() == false)
-			return;
-	}
+    if(m_pEditFrameWnd)
+    {
+        if(m_pEditFrameWnd->CloseAll() == false)
+        {
+            return ;
+        }
+    }
 
-	Log(_T("OnClose - before stop MainFrm thread"));
-	m_thread.Stop();
-	Log(_T("OnClose - after stop MainFrm thread"));
+    Log(_T("OnClose - before stop MainFrm thread"));
+    m_thread.Stop();
+    Log(_T("OnClose - after stop MainFrm thread"));
 
-	theApp.BeforeMainClose();
+    theApp.BeforeMainClose();
 
-	CFrameWnd::OnClose();
+    CFrameWnd::OnClose();
 }
 
 bool CMainFrame::CloseAllOpenDialogs()
 {
-	bool bRet = false;
-	DWORD dwordProcessId;
-	DWORD dwordChildWindowProcessId;
-	GetWindowThreadProcessId(this->m_hWnd, &dwordProcessId);
-	ASSERT(dwordProcessId);
-
-	CWnd *pTempWnd = GetDesktopWindow()->GetWindow(GW_CHILD);
-	while((pTempWnd = pTempWnd->GetWindow(GW_HWNDNEXT)) != NULL)
-	{
-		if(pTempWnd->GetSafeHwnd() == NULL)
-			break;
+    bool bRet = false;
+    DWORD dwordProcessId;
+    DWORD dwordChildWindowProcessId;
+    GetWindowThreadProcessId(this->m_hWnd, &dwordProcessId);
+    ASSERT(dwordProcessId);
 
-		GetWindowThreadProcessId(pTempWnd->GetSafeHwnd(), &dwordChildWindowProcessId);
-		if(dwordChildWindowProcessId == dwordProcessId)
-		{
-			TCHAR szTemp[100];
-			GetClassName(pTempWnd->GetSafeHwnd(), szTemp, 100);
+    CWnd *pTempWnd = GetDesktopWindow()->GetWindow(GW_CHILD);
+    while((pTempWnd = pTempWnd->GetWindow(GW_HWNDNEXT)) != NULL)
+    {
+        if(pTempWnd->GetSafeHwnd() == NULL)
+        {
+            break;
+        }
 
-			// #32770 is class name for dialogs so don't process the message if it is a dialog
-			if(STRCMP(szTemp, _T("#32770")) == 0)
-			{
-				pTempWnd->SendMessage(WM_CLOSE, 0, 0);
-				bRet = true;
-			}
-		}
-	}
+        GetWindowThreadProcessId(pTempWnd->GetSafeHwnd(), &dwordChildWindowProcessId);
+        if(dwordChildWindowProcessId == dwordProcessId)
+        {
+            TCHAR szTemp[100];
+            GetClassName(pTempWnd->GetSafeHwnd(), szTemp, 100);
 
-	MSG msg;
-	while(PeekMessage(&msg, NULL, NULL, NULL, PM_REMOVE))
-	{
-		TranslateMessage(&msg);
-		DispatchMessage(&msg);
-	}
+            // #32770 is class name for dialogs so don't process the message if it is a dialog
+            if(STRCMP(szTemp, _T("#32770")) == 0)
+            {
+                pTempWnd->SendMessage(WM_CLOSE, 0, 0);
+                bRet = true;
+            }
+        }
+    }
+
+    MSG msg;
+    while(PeekMessage(&msg, NULL, NULL, NULL, PM_REMOVE))
+    {
+        TranslateMessage(&msg);
+        DispatchMessage(&msg);
+    }
 
-	return bRet;
+    return bRet;
 }
 
-LRESULT CMainFrame::OnAddToDatabaseFromSocket(WPARAM wParam, LPARAM lParam)
+LRESULT CMainFrame::OnLoadClipOnClipboard(WPARAM wParam, LPARAM lParam)
 {
-	LogSendRecieveInfo("---------Start of OnAddToDatabaseFromSocket");
-	
-	CProcessPaste paste;
-	CClipList *pClipList = (CClipList*)wParam;
-	if(pClipList == NULL)
-	{
-		LogSendRecieveInfo("---------ERROR pClipList == NULL");
-		return FALSE;
-	}
-	
-	BOOL bSetToClipBoard = (BOOL)lParam;
+	CClip *pClip = (CClip*)wParam;
+    if(pClip == NULL)
+    {
+        LogSendRecieveInfo("---------ERROR OnLoadClipOnClipboard pClip == NULL");
+        return FALSE;
+    }
 
-	if(bSetToClipBoard)
-	{
-		LogSendRecieveInfo("---------Start of Set to ClipBoard");
+    if(pClip)
+    {
+		CProcessPaste paste;
+		paste.m_bSendPaste = false;
 
-		CClip *pClip = pClipList->GetTail();
-		if(pClip)
-		{
-			CClip NewClip;
-			NewClip = *pClip;
+		LogSendRecieveInfo("---------OnLoadClipOnClipboard - Before PutFormats on clipboard");
 
-			LogSendRecieveInfo("---------After =");
+		paste.m_pOle->PutFormatOnClipboard(&pClip->m_Formats);
+		paste.m_pOle->CacheGlobalData(theApp.m_cfIgnoreClipboard, NewGlobalP("Ignore", sizeof("Ignore")));
 
-			//Don't send the paste just load it into memory
-			paste.m_bSendPaste = false;
-			paste.m_pOle->PutFormatOnClipboard(&NewClip.m_Formats);
-			paste.m_pOle->CacheGlobalData(theApp.m_cfIgnoreClipboard, NewGlobalP("Ignore", sizeof("Ignore")));
+		LogSendRecieveInfo("---------OnLoadClipOnClipboard - After PutFormats on clipboard");
 
-			LogSendRecieveInfo("---------After LoadFormats");
-		}
-		else
-		{
-			LogSendRecieveInfo("---------GetTail returned NULL");
+		LogSendRecieveInfo(StrF(_T("---------OnLoadClipOnClipboard - Setting clip id: %d on ole clipboard"), pClip->m_ID));
+		paste.GetClipIDs().Add(pClip->m_ID);
+		paste.DoPaste();
 
-		}
-
-		LogSendRecieveInfo("---------Start of Set to ClipBoard");
+		LogSendRecieveInfo(StrF(_T("---------OnLoadClipOnClipboard - After paste clip id: %d on ole clipboard"), pClip->m_ID));
 	}
 
-	pClipList->AddToDB(true);
-
-	LogSendRecieveInfo("---------After AddToDB");
-
-	CClip *pClip = pClipList->GetTail();
-	if(pClip)
-	{
-		theApp.m_FocusID = pClip->m_ID;
-
-		//Wait till after we add the clip to the db before we call DoPaste
-		if(bSetToClipBoard)
-		{
-			LogSendRecieveInfo(StrF(_T("---------Setting clip id: %d on ole clipboard"), pClip->m_ID));
-			paste.GetClipIDs().Add(pClip->m_ID);
-			paste.DoPaste();
-		}
-	}
-
-	theApp.RefreshView();
-
-	delete pClipList;
-	pClipList = NULL;
-
-	LogSendRecieveInfo("---------End of OnAddToDatabaseFromSocket");
+	delete pClip;
 
 	return TRUE;
 }
 
-LRESULT CMainFrame::OnErrorOnSendRecieve(WPARAM wParam, LPARAM lParam)
+LRESULT CMainFrame::OnAddToDatabaseFromSocket(WPARAM wParam, LPARAM lParam)
 {
-	CString csNewText = (TCHAR*)wParam;
-
-	ShowErrorMessage(_T("Ditto - Send/Receive Error"), csNewText);
-
-	return TRUE;
-}
+    CClipList *pClipList = (CClipList*)wParam;
+    if(pClipList == NULL)
+    {
+        LogSendRecieveInfo("---------OnAddToDatabaseFromSocket - ERROR pClipList == NULL");
+        return FALSE;
+    }
 
-LRESULT CMainFrame::OnKeyBoardChanged(WPARAM wParam, LPARAM lParam)
-{
-	if(wParam == VK_ESCAPE)
-	{
-		StopLookingForKeystrokes(true);
-	}
-	else if(wParam == VK_RETURN)
-	{
-		StopLookingForKeystrokes(false);
-		if(m_csKeyboardPaste.IsEmpty() == FALSE)
-		{
-			if(theApp.m_QuickPasteMode == CCP_MainApp::PASTING_QUICK_PASTE)
-			{
-				PasteQuickPasteEntry(m_csKeyboardPaste);
-			}
-			else
-			{
-				SaveQuickPasteEntry(m_csKeyboardPaste, theApp.m_pQuickPasteClip);
-			}
+    BOOL bSetToClipBoard = (BOOL)lParam;
+    if(bSetToClipBoard)
+    {
+        CClip *pClip = pClipList->GetTail();
+        if(pClip)
+        {
+			LogSendRecieveInfo("OnAddToDatabaseFromSocket - Adding clip from socket setting clip to be put on clipboard");
+			pClip->m_param1 = TRUE;
 		}
-		StopLookingForKeystrokes(true);
-	}
-	else if((wParam >= 32 && wParam <= 96) || wParam == VK_BACK)
-	{
-		KillTimer(STOP_LOOKING_FOR_KEYBOARD);
-		KillTimer(STOP_MONITORING_KEYBOARD_TIMER);
+    }
 
-		bool bContinue = true;
+	m_thread.AddRemoteClipToSave(pClipList);
 
-		if(wParam == VK_BACK)     
-		{
-			m_csKeyboardPaste = m_csKeyboardPaste.Left(m_csKeyboardPaste.GetLength()-1);
-		}
-		else
-		{
-			CString cs((char)wParam);
-			m_csKeyboardPaste += cs;
-
-			if(theApp.m_QuickPasteMode == CCP_MainApp::PASTING_QUICK_PASTE)
-			{
-				try
-				{
-					int nCount = theApp.m_db.execScalarEx(_T("SELECT COUNT(lID) FROM Main WHERE QuickPasteText LIKE \'%%%s%%\'"), m_csKeyboardPaste);
-					if(nCount == 1)
-					{
-						nCount = theApp.m_db.execScalarEx(_T("SELECT COUNT(lID) FROM Main WHERE QuickPasteText = \'%s\'"), m_csKeyboardPaste);
-						if(nCount == 1)
-						{
-							StopLookingForKeystrokes(false);
-							PasteQuickPasteEntry(m_csKeyboardPaste);
-							StopLookingForKeystrokes(true);
-							bContinue = false;
-						}
-					}
-				}
-				CATCH_SQLITE_EXCEPTION
-			}
-		}
+	delete pClipList;
 
-		if(bContinue)
-		{
-			m_pTypingToolTip->SetToolTipText(csTypeToolTipTitle + "\n\n" + m_csKeyboardPaste);
-			m_pTypingToolTip->Show(m_ToolTipPoint);
+    return TRUE;
+}
 
-			SetTimer(STOP_MONITORING_KEYBOARD_TIMER, 10000, NULL);
+LRESULT CMainFrame::OnErrorOnSendRecieve(WPARAM wParam, LPARAM lParam)
+{
+    CString csNewText = (TCHAR*)wParam;
 
-			Log(StrF(_T("OnKeyboard Changed - %d - %s"), wParam, m_csKeyboardPaste));
-		}
-	}
-	else
-	{
-		CString cs((char)wParam);
-		Log(StrF(_T("INVALID Key OnKeyboard Changed - %d - %s"), wParam, m_csKeyboardPaste));
-	}
+    ShowErrorMessage(_T("Ditto - Send/Receive Error"), csNewText);
 
-	return TRUE;
+    return TRUE;
 }
 
-CString WndName(HWND hParent) 
+CString WndName(HWND hParent)
 {
-	TCHAR cWindowText[200];
+    TCHAR cWindowText[200];
 
-	::GetWindowText(hParent, cWindowText, 100);
+    ::GetWindowText(hParent, cWindowText, 100);
 
-	int nCount = 0;
+    int nCount = 0;
 
-	while(STRLEN(cWindowText) <= 0)
-	{
-		hParent = ::GetParent(hParent);
-		if(hParent == NULL)
-			break;
+    while(STRLEN(cWindowText) <= 0)
+    {
+        hParent = ::GetParent(hParent);
+        if(hParent == NULL)
+        {
+            break;
+        }
 
-		::GetWindowText(hParent, cWindowText, 100);
+        ::GetWindowText(hParent, cWindowText, 100);
 
-		nCount++;
-		if(nCount > 100)
-		{
-			Log(_T("GetTargetName reached maximum search depth of 100"));
-			break;
-		}
-	}
+        nCount++;
+        if(nCount > 100)
+        {
+            Log(_T("GetTargetName reached maximum search depth of 100"));
+            break;
+        }
+    }
 
-	return cWindowText; 
+    return cWindowText;
 }
 
 LRESULT CMainFrame::OnFocusChanged(WPARAM wParam, LPARAM lParam)
 {
-	if(m_quickPaste.IsWindowVisibleEx())
-	{
-		HWND focus = (HWND)wParam;
-		static DWORD dLastDittoHasFocusTick = 0;
-
-		//Sometimes when we bring ditto up there will come a null focus 
-		//rite after that
-		if(focus == NULL && (GetTickCount() - dLastDittoHasFocusTick < 500))
-		{
-			Log(_T("NULL focus within 500 ticks of bringing up ditto"));
-			return TRUE;
-		}
-		else if(focus == NULL)
-		{
-			Log(_T("NULL focus received"));
-		}
+    if(m_quickPaste.IsWindowVisibleEx())
+    {
+        HWND focus = (HWND)wParam;
+        static DWORD dLastDittoHasFocusTick = 0;
 
-		if(theApp.m_activeWnd.DittoHasFocus())
-		{
-			dLastDittoHasFocusTick = GetTickCount();
-		}
+        //Sometimes when we bring ditto up there will come a null focus 
+        //rite after that
+        if(focus == NULL && (GetTickCount() - dLastDittoHasFocusTick < 500))
+        {
+            Log(_T("NULL focus within 500 ticks of bringing up ditto"));
+            return TRUE;
+        }
+        else if(focus == NULL)
+        {
+            Log(_T("NULL focus received"));
+        }
 
-		//Log(StrF(_T("OnFocusChanged %d, title %s"), focus, WndName(focus)));
-		m_tempFocusWnd = focus;
+        if(theApp.m_activeWnd.DittoHasFocus())
+        {
+            dLastDittoHasFocusTick = GetTickCount();
+        }
 
-		KillTimer(FOCUS_CHANGED_TIMER);
-		SetTimer(FOCUS_CHANGED_TIMER, g_Opt.FocusChangedDelay(), NULL);
-	}
+        //Log(StrF(_T("OnFocusChanged %d, title %s"), focus, WndName(focus)));
+        m_tempFocusWnd = focus;
 
-	return TRUE;
-}
+        KillTimer(FOCUS_CHANGED_TIMER);
+        SetTimer(FOCUS_CHANGED_TIMER, g_Opt.FocusChangedDelay(), NULL);
+    }
 
-void CMainFrame::OnFirstHelp() 
-{
-	CString csFile = CGetSetOptions::GetPath(PATH_HELP);
-	csFile += "DittoGettingStarted.htm";
-	CHyperLink::GotoURL(csFile, SW_SHOW);
+    return TRUE;
 }
 
-LRESULT CMainFrame::OnCustomizeTrayMenu(WPARAM wParam, LPARAM lParam)
+void CMainFrame::OnFirstHelp()
 {
-	CMenu *pMenu = (CMenu*)wParam;
-	if(pMenu)
-	{
-		theApp.m_Language.UpdateTrayIconRightClickMenu(pMenu);
-	}
-
-	return true;
+    CString csFile = CGetSetOptions::GetPath(PATH_HELP);
+    csFile += "DittoGettingStarted.htm";
+    CHyperLink::GotoURL(csFile, SW_SHOW);
 }
 
-bool CMainFrame::PasteQuickPasteEntry(CString csQuickPaste)
-{
-	Log(StrF(_T("PasteQuickPasteEntry -- %s"), csQuickPaste));
-
-	CString csTitle = theApp.m_Language.GetString("Named_Paste_Title", "Ditto - Named Paste");
-	bool bRet = false;
-	try
-	{
-		csQuickPaste.Replace(_T("'"), _T("''"));
-		CppSQLite3Query q = theApp.m_db.execQueryEx(_T("SELECT lID FROM Main WHERE QuickPasteText = '%s'"), csQuickPaste);
-			
-		if(q.eof() == false)
-		{
-			CClip Clip;
-			if(Clip.LoadFormats(q.getIntField(_T("lID"))))
-			{
-				CProcessPaste paste;
-				paste.m_pOle->PutFormatOnClipboard(&Clip.m_Formats);
-				paste.m_pOle->CacheGlobalData(theApp.m_cfIgnoreClipboard, NewGlobalP("Ignore", sizeof("Ignore")));
-					
-				if(paste.DoPaste())
-				{
-					bRet = TRUE;
-				}
-			}
-			else
-			{
-				CString csError = theApp.m_Language.GetString("Named_Paste_Error1", "Error loading data");
-				ShowErrorMessage(csTitle, StrF(_T("%s - id:%d"), csError, q.getIntField(_T("lID"))));
-			}
-		}
-		else
-		{
-			CString csError = theApp.m_Language.GetString("Named_Paste_Error2", "Error finding clip with QuickPaste Text of");
-			ShowErrorMessage(csTitle, StrF(_T("%s - '%s'"), csError, csQuickPaste));
-		}
-	}
-	catch (CppSQLite3Exception& e)
-	{
-		CString csError = theApp.m_Language.GetString("Named_Paste_Error3", "Exception finding the clip");
-		ShowErrorMessage(csTitle, StrF(_T("%s - '%s'  -  %s"), csError, csQuickPaste, e.errorMessage()));
-	}	
-
-	return bRet;
-}
-
-bool CMainFrame::SaveQuickPasteEntry(CString csQuickPaste, CClipList *pClipList)
+LRESULT CMainFrame::OnCustomizeTrayMenu(WPARAM wParam, LPARAM lParam)
 {
-	Log(StrF(_T("SaveQuickPasteEntry text = %s - recived copy = %d"), csQuickPaste, pClipList != NULL));
-	CString csTitle = theApp.m_Language.GetString("Named_Copy_Title", "Ditto - Named Copy");
-
-	bool bRet = false;
-
-	if(pClipList)
-	{
-		try
-		{
-			CClip *pClip = pClipList->GetHead();
-			pClip->m_csQuickPaste = csQuickPaste;
-			pClip->m_lDontAutoDelete = (long)CTime::GetCurrentTime().GetTime();
+    CMenu *pMenu = (CMenu*)wParam;
+    if(pMenu)
+    {
+        theApp.m_Language.UpdateTrayIconRightClickMenu(pMenu);
+    }
 
-			if(csQuickPaste.IsEmpty() == FALSE)
-			{
-				//Remove any other instances of this quick paste
-				csQuickPaste.Replace(_T("'"), _T("''"));
-				int nCount = theApp.m_db.execDMLEx(_T("UPDATE Main SET QuickPasteText = '' WHERE QuickPasteText = '%s';"), csQuickPaste);
-
-				if(nCount > 0)
-				{
-					Log(StrF(_T("Removed quick paste '%s', count = %d"), csQuickPaste, nCount));
-				}
-			}
-				
-			int count = pClipList->AddToDB(true);
-			if(count > 0)
-			{
-				long lID = pClipList->GetTail()->m_ID;
-				theApp.OnCopyCompleted(lID, count);
-
-				bRet = true;
-			}
-			else
-			{
-				CString csError = theApp.m_Language.GetString("Named_Copy_Error1", "Error saving Named Coy to Database");
-				ShowErrorMessage(csTitle, csError);
-			}
-		}
-		catch (CppSQLite3Exception& e)
-		{
-			Log(StrF(_T("SQLITE Exception %d - %s"), e.errorCode(), e.errorMessage()));
-			ASSERT(FALSE);
-
-			CString csError = theApp.m_Language.GetString("Named_Copy_Error2", "Exception saving Named Copy");
-			ShowErrorMessage(csTitle, StrF(_T("%s - %s"), csError, e.errorMessage()));
-		}	
-	}
-	else
-	{
-		CString csError = theApp.m_Language.GetString("Named_Copy_Error3", "Ditto did not receive a copy");
-		ShowErrorMessage(csTitle, csError);
-	}
-
-	return bRet;
+    return true;
 }
 
 void CMainFrame::ShowErrorMessage(CString csTitle, CString csMessage)
 {
-	Log(StrF(_T("ShowErrorMessage %s - %s"), csTitle, csMessage));
+    Log(StrF(_T("ShowErrorMessage %s - %s"), csTitle, csMessage));
 
-	CToolTipEx *pErrorWnd = new CToolTipEx;
-	pErrorWnd->Create(this);
-	pErrorWnd->SetToolTipText(csTitle + "\n\n" + csMessage);
+    CToolTipEx *pErrorWnd = new CToolTipEx;
+    pErrorWnd->Create(this);
+    pErrorWnd->SetToolTipText(csTitle + "\n\n" + csMessage);
 
-	CPoint pt;
-	CRect rcScreen;
-	GetMonitorRect(0, &rcScreen);
-	pt = rcScreen.BottomRight();
+    CPoint pt;
+    CRect rcScreen;
+    GetMonitorRect(0, &rcScreen);
+    pt = rcScreen.BottomRight();
 
-	CRect cr = pErrorWnd->GetBoundsRect();
+    CRect cr = pErrorWnd->GetBoundsRect();
 
-	pt.x -= max(cr.Width()+50, 150);
-	pt.y -= max(cr.Height()+50, 150);
+    pt.x -= max(cr.Width() + 50, 150);
+    pt.y -= max(cr.Height() + 50, 150);
 
-	pErrorWnd->Show(pt);
-	pErrorWnd->HideWindowInXMilliSeconds(4000);
+    pErrorWnd->Show(pt);
+    pErrorWnd->HideWindowInXMilliSeconds(4000);
 }
 
-void CMainFrame::DeleteOldRemoteCopies(CString csDir)
-{
-	//must be deleting a sub folder in the musicgen directory
-	if(csDir.Find(_T("\\ReceivedFiles\\")) == -1)
-		return;
-
-	FIX_CSTRING_PATH(csDir);
-
-	CTime ctOld = CTime::GetCurrentTime();
-	CTime ctFile;
-	ctOld -= CTimeSpan(0, 0, 0, 1);
-
-	CFileFind Find;
-
-	CString csFindString;
-	csFindString.Format(_T("%s*.*"), csDir);
-
-	BOOL bFound = Find.FindFile(csFindString);
-	while(bFound)
-	{
-		bFound = Find.FindNextFile();
-
-		if(Find.IsDots())
-			continue;
-
-		if(Find.IsDirectory())
-		{
-			CString csDir(Find.GetFilePath());
-			DeleteOldRemoteCopies(csDir);
-			RemoveDirectory(csDir);
-		}
-
-		if(Find.GetLastAccessTime(ctFile))
-		{
-			//Delete the remote copied file if it has'nt been used for the last day
-			if(ctFile < ctOld)
-			{
-				DeleteFile(Find.GetFilePath());
-			}
-		}
-		else
-		{
-			DeleteFile(Find.GetFilePath());
-		}
-	}
-}
-
-UINT CMainFrame::RemoteOldRemoteFilesThread(LPVOID pParam)
-{
-	CString csDir = CGetSetOptions::GetPath(PATH_REMOTE_FILES);
-	if(FileExists(csDir))
-	{
-		DeleteOldRemoteCopies(csDir);
-	}
-
-	return TRUE;
-}
 void CMainFrame::OnFirstImport()
 {
-	theApp.ImportClips(theApp.m_MainhWnd);
+    theApp.ImportClips(theApp.m_MainhWnd);
 }
 
 void CMainFrame::ShowEditWnd(CClipIDs &Ids)
 {
-	CWaitCursor wait;
-
-	bool bCreatedWindow = false;
-	if(m_pEditFrameWnd == NULL)
-	{
-		m_pEditFrameWnd = new CEditFrameWnd;
-		m_pEditFrameWnd->LoadFrame(IDR_MAINFRAME);
-		bCreatedWindow = true;
-	}
-	if(m_pEditFrameWnd)
-	{		
-		m_pEditFrameWnd->EditIds(Ids);
-		m_pEditFrameWnd->SetNotifyWnd(m_hWnd);
-
-		if(bCreatedWindow)
-		{
-			CSize sz;
-			CPoint pt;
-			CGetSetOptions::GetEditWndSize(sz);
-			CGetSetOptions::GetEditWndPoint(pt);
-			CRect cr(pt, sz);
-			EnsureWindowVisible(&cr);
-			m_pEditFrameWnd->MoveWindow(cr);
-		}
-
-		m_pEditFrameWnd->ShowWindow(SW_SHOW);
-		m_pEditFrameWnd->SetForegroundWindow();
-		m_pEditFrameWnd->SetFocus();
-	}
+    CWaitCursor wait;
+
+    bool bCreatedWindow = false;
+    if(m_pEditFrameWnd == NULL)
+    {
+        m_pEditFrameWnd = new CEditFrameWnd;
+        m_pEditFrameWnd->LoadFrame(IDR_MAINFRAME);
+        bCreatedWindow = true;
+    }
+    if(m_pEditFrameWnd)
+    {
+        m_pEditFrameWnd->EditIds(Ids);
+        m_pEditFrameWnd->SetNotifyWnd(m_hWnd);
+
+        if(bCreatedWindow)
+        {
+            CSize sz;
+            CPoint pt;
+            CGetSetOptions::GetEditWndSize(sz);
+            CGetSetOptions::GetEditWndPoint(pt);
+            CRect cr(pt, sz);
+            EnsureWindowVisible(&cr);
+            m_pEditFrameWnd->MoveWindow(cr);
+        }
+
+        m_pEditFrameWnd->ShowWindow(SW_SHOW);
+        m_pEditFrameWnd->SetForegroundWindow();
+        m_pEditFrameWnd->SetFocus();
+    }
 }
 
 LRESULT CMainFrame::OnEditWndClose(WPARAM wParam, LPARAM lParam)
 {
-	m_pEditFrameWnd = NULL;
-	return TRUE;
+    m_pEditFrameWnd = NULL;
+    return TRUE;
 }
 
 LRESULT CMainFrame::OnSetConnected(WPARAM wParam, LPARAM lParam)
 {
-	if(wParam)
-		theApp.SetConnectCV(true);
-	else if(lParam)
-		theApp.SetConnectCV(false);
+    if(wParam)
+    {
+        theApp.SetConnectCV(true);
+    }
+    else if(lParam)
+    {
+        theApp.SetConnectCV(false);
+    }
 
-	return TRUE;
+    return TRUE;
 }
 
 void CMainFrame::OnDestroy()
 {
-	Shell_NotifyIcon(NIM_DELETE, &tnd);
-	m_TrayMenu.DestroyMenu();
-
-	CFrameWnd::OnDestroy();
+    CFrameWnd::OnDestroy();
 
-	if(m_pEditFrameWnd)
-	{
-		m_pEditFrameWnd->DestroyWindow();
-	}
+    if(m_pEditFrameWnd)
+    {
+        m_pEditFrameWnd->DestroyWindow();
+    }
 }
 
 void CMainFrame::OnFirstNewclip()
 {
-	CClipIDs IDs;
-	IDs.Add(-1);
-	theApp.EditItems(IDs, true);
-}
-
-LRESULT CMainFrame::OnTrayNotify(WPARAM wParam, LPARAM lParam)
-{
-	UINT uMsg = (UINT) lParam; 
-	switch (uMsg ) 
-	{ 
-	case WM_LBUTTONDBLCLK:
-		//this->ShowWindow(SW_SHOW);
-		m_TrayMenu.DestroyMenu();
-		this->OnClose();
-		break;
-	case WM_RBUTTONUP:
-		CPoint pt;	
-		GetCursorPos(&pt);
-		m_TrayMenu.GetSubMenu(0)->TrackPopupMenu(TPM_RIGHTALIGN|TPM_LEFTBUTTON|TPM_RIGHTBUTTON,pt.x,pt.y,this);
-		break;
-	} 
-	return TRUE;
+    CClipIDs IDs;
+    IDs.Add( - 1);
+    theApp.EditItems(IDs, true);
 }

+ 112 - 147
MainFrm.h

@@ -1,147 +1,112 @@
-// MainFrm.h : interface of the CMainFrame class
-//
-/////////////////////////////////////////////////////////////////////////////
-
-#if !defined(AFX_MAINFRM_H__147283E8_5032_4C0A_9828_1CC59DECFD62__INCLUDED_)
-#define AFX_MAINFRM_H__147283E8_5032_4C0A_9828_1CC59DECFD62__INCLUDED_
-
-#if _MSC_VER > 1000
-#pragma once
-#endif // _MSC_VER > 1000
-
-#include "SystemTray.h"
-#include "QuickPaste.h"
-#include "ToolTipEx.h"
-#include "EditFrameWnd.h"
-#include "MainFrmThread.h"
-
-
-#define CLOSE_WINDOW_TIMER				1	
-#define HIDE_ICON_TIMER					2
-#define REMOVE_OLD_ENTRIES_TIMER		3
-#define CHECK_FOR_UPDATE				4
-#define CLOSE_APP						5
-#define STOP_MONITORING_KEYBOARD_TIMER	7
-#define STOP_LOOKING_FOR_KEYBOARD		8
-#define REMOVE_OLD_REMOTE_COPIES		9
-#define END_DITTO_BUFFER_CLIPBOARD_TIMER	10
-#define KEY_STATE_MODIFIERS				11
-#define ACTIVE_WINDOW_TIMER				12
-#define FOCUS_CHANGED_TIMER				13
-
-class CMainFrame : public CFrameWnd
-{
-public:
-	CMainFrame();
-protected: 
-	DECLARE_DYNAMIC(CMainFrame)
-
-// Attributes
-public:
-
-// Operations
-public:
-
-	BOOL ResetKillDBTimer();
-
-// Overrides
-	// ClassWizard generated virtual function overrides
-	//{{AFX_VIRTUAL(CMainFrame)
-	public:
-	virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
-//	virtual BOOL Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext = NULL);
-	//}}AFX_VIRTUAL
-
-// Implementation
-public:
-	virtual ~CMainFrame();
-#ifdef _DEBUG
-	virtual void AssertValid() const;
-	virtual void Dump(CDumpContext& dc) const;
-#endif
-
-	CQuickPaste m_quickPaste;
-	CSystemTray m_TrayIcon;
-	ULONG m_ulCopyGap;
-	CString m_csKeyboardPaste;
-	CToolTipEx *m_pTypingToolTip;
-	CString csTypeToolTipTitle;
-	CPoint m_ToolTipPoint;
-	CAlphaBlend m_Transparency;
-	BYTE m_keyStateModifiers;
-	DWORD m_startKeyStateTime;
-	bool m_bMovedSelectionMoveKeyState;
-	short m_keyModifiersTimerCount;
-	HWND m_tempFocusWnd;
-	CMainFrmThread m_thread;
-
-	CMenu m_TrayMenu;
-	NOTIFYICONDATA tnd;
-
-	void DoDittoCopyBufferPaste(int nCopyBuffer);
-	void DoFirstTenPositionsPaste(int nPos);
-	void StopLookingForKeystrokes(bool bInitAppVaribles);
-	bool PasteQuickPasteEntry(CString csQuickPaste);
-	bool SaveQuickPasteEntry(CString csQuickPaste, CClipList *pClipList);
-	void ShowErrorMessage(CString csTitle, CString csMessage);
-	bool CloseAllOpenDialogs();
-
-	static void DeleteOldRemoteCopies(CString csDir);
-	static UINT RemoteOldRemoteFilesThread(LPVOID pParam);
-
-	void ShowEditWnd(CClipIDs &Ids);
-	CEditFrameWnd *m_pEditFrameWnd;
-
-// Generated message map functions
-protected:
-	//{{AFX_MSG(CMainFrame)
-	afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
-	afx_msg void OnFirstOption();
-	afx_msg void OnFirstExit();
-	afx_msg void OnChangeCbChain(HWND hWndRemove, HWND hWndAfter);
-	afx_msg void OnDrawClipboard();
-	afx_msg void OnTimer(UINT nIDEvent);
-	afx_msg void OnFirstShowquickpaste();
-	afx_msg void OnFirstToggleConnectCV();
-	afx_msg void OnUpdateFirstToggleConnectCV(CCmdUI* pCmdUI);
-	afx_msg void OnFirstHelp();
-	//}}AFX_MSG
-	afx_msg LRESULT OnHotKey(WPARAM wParam, LPARAM lParam);
-	afx_msg LRESULT OnShowTrayIcon(WPARAM wParam, LPARAM lParam);
-//	afx_msg LRESULT OnGetIsTopView(WPARAM wParam, LPARAM lParam);
-	afx_msg LRESULT OnCopyProperties(WPARAM wParam, LPARAM lParam);
-	afx_msg LRESULT OnShutDown(WPARAM wParam, LPARAM lParam);
-	afx_msg LRESULT OnClipboardCopied(WPARAM wParam, LPARAM lParam);
-	afx_msg LRESULT OnAddToDatabaseFromSocket(WPARAM wParam, LPARAM lParam);
-	afx_msg LRESULT OnErrorOnSendRecieve(WPARAM wParam, LPARAM lParam);
-	afx_msg LRESULT OnFocusChanged(WPARAM wParam, LPARAM lParam);
-	afx_msg LRESULT OnCustomizeTrayMenu(WPARAM wParam, LPARAM lParam);
-	afx_msg LRESULT OnKeyBoardChanged(WPARAM wParam, LPARAM lParam);
-	afx_msg LRESULT OnEditWndClose(WPARAM wParam, LPARAM lParam);
-	afx_msg LRESULT OnSetConnected(WPARAM wParam, LPARAM lParam);
-	DECLARE_MESSAGE_MAP()
-public:
-	virtual BOOL PreTranslateMessage(MSG* pMsg);
-	afx_msg void OnClose();
-	afx_msg void OnFirstImport();
-	afx_msg void OnDestroy();
-	afx_msg void OnFirstNewclip();
-	afx_msg LRESULT OnTrayNotify(WPARAM wParam, LPARAM lParam);
-};
-
-class CShowMainFrame
-{
-public:
-	CShowMainFrame();
-	~CShowMainFrame();
-	static bool m_bShowingMainFrame;
-	bool m_bHideMainFrameOnExit;
-	HWND m_hWnd;
-};
-
-/////////////////////////////////////////////////////////////////////////////
-
-//{{AFX_INSERT_LOCATION}}
-// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
-
-#endif // !defined(AFX_MAINFRM_H__147283E8_5032_4C0A_9828_1CC59DECFD62__INCLUDED_)
+#pragma once
+
+#include "SystemTray.h"
+#include "QuickPaste.h"
+#include "ToolTipEx.h"
+#include "EditFrameWnd.h"
+#include "MainFrmThread.h"
+
+
+#define CLOSE_WINDOW_TIMER				1	
+#define HIDE_ICON_TIMER					2
+#define REMOVE_OLD_ENTRIES_TIMER		3
+#define REMOVE_OLD_REMOTE_COPIES		6
+#define END_DITTO_BUFFER_CLIPBOARD_TIMER	7
+#define KEY_STATE_MODIFIERS				8
+#define ACTIVE_WINDOW_TIMER				9
+#define FOCUS_CHANGED_TIMER				10
+
+class CMainFrame: public CFrameWnd
+{
+public:
+    CMainFrame();
+protected:
+    DECLARE_DYNAMIC(CMainFrame)
+
+    // Attributes
+public:
+
+    // Operations
+public:
+
+    BOOL ResetKillDBTimer();
+
+    // Overrides
+    // ClassWizard generated virtual function overrides
+    //{{AFX_VIRTUAL(CMainFrame)
+public:
+    virtual BOOL PreCreateWindow(CREATESTRUCT &cs);
+    //	virtual BOOL Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext = NULL);
+    //}}AFX_VIRTUAL
+
+    // Implementation
+public:
+    virtual ~CMainFrame();
+    #ifdef _DEBUG
+        virtual void AssertValid()const;
+        virtual void Dump(CDumpContext &dc)const;
+    #endif 
+
+    CQuickPaste m_quickPaste;
+    CSystemTray m_TrayIcon;
+    ULONG m_ulCopyGap;
+    CString m_csKeyboardPaste;
+    CAlphaBlend m_Transparency;
+    BYTE m_keyStateModifiers;
+    DWORD m_startKeyStateTime;
+    bool m_bMovedSelectionMoveKeyState;
+    short m_keyModifiersTimerCount;
+    HWND m_tempFocusWnd;
+    CMainFrmThread m_thread;
+
+    void DoDittoCopyBufferPaste(int nCopyBuffer);
+    void DoFirstTenPositionsPaste(int nPos);
+    bool PasteQuickPasteEntry(CString csQuickPaste);
+    bool SaveQuickPasteEntry(CString csQuickPaste, CClipList *pClipList);
+    void ShowErrorMessage(CString csTitle, CString csMessage);
+    bool CloseAllOpenDialogs();
+
+    void ShowEditWnd(CClipIDs &Ids);
+    CEditFrameWnd *m_pEditFrameWnd;
+
+    // Generated message map functions
+protected:
+    //{{AFX_MSG(CMainFrame)
+    afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
+    afx_msg void OnFirstOption();
+    afx_msg void OnFirstExit();
+    afx_msg void OnChangeCbChain(HWND hWndRemove, HWND hWndAfter);
+    afx_msg void OnDrawClipboard();
+    afx_msg void OnTimer(UINT nIDEvent);
+    afx_msg void OnFirstShowquickpaste();
+    afx_msg void OnFirstToggleConnectCV();
+    afx_msg void OnUpdateFirstToggleConnectCV(CCmdUI *pCmdUI);
+    afx_msg void OnFirstHelp();
+    //}}AFX_MSG
+    afx_msg LRESULT OnHotKey(WPARAM wParam, LPARAM lParam);
+    afx_msg LRESULT OnShowTrayIcon(WPARAM wParam, LPARAM lParam);
+    afx_msg LRESULT OnClipboardCopied(WPARAM wParam, LPARAM lParam);
+    afx_msg LRESULT OnAddToDatabaseFromSocket(WPARAM wParam, LPARAM lParam);
+    afx_msg LRESULT OnErrorOnSendRecieve(WPARAM wParam, LPARAM lParam);
+    afx_msg LRESULT OnFocusChanged(WPARAM wParam, LPARAM lParam);
+    afx_msg LRESULT OnCustomizeTrayMenu(WPARAM wParam, LPARAM lParam);
+    afx_msg LRESULT OnEditWndClose(WPARAM wParam, LPARAM lParam);
+    afx_msg LRESULT OnSetConnected(WPARAM wParam, LPARAM lParam);
+	afx_msg LRESULT OnLoadClipOnClipboard(WPARAM wParam, LPARAM lParam);
+DECLARE_MESSAGE_MAP()public:
+    virtual BOOL PreTranslateMessage(MSG *pMsg);
+    afx_msg void OnClose();
+    afx_msg void OnFirstImport();
+    afx_msg void OnDestroy();
+    afx_msg void OnFirstNewclip();
+};
+
+class CShowMainFrame
+{
+public:
+    CShowMainFrame();
+    ~CShowMainFrame();
+    static bool m_bShowingMainFrame;
+    bool m_bHideMainFrameOnExit;
+    HWND m_hWnd;
+};

+ 1 - 0
MainTableFunctions.cpp

@@ -5,6 +5,7 @@
 #include "stdafx.h"
 #include "cp_main.h"
 #include "MainTableFunctions.h"
+#include "Tokenizer.h"
 
 #ifdef _DEBUG
 #undef THIS_FILE

+ 877 - 1273
Misc.cpp

@@ -1,1274 +1,878 @@
-#include "stdafx.h"
-#include "CP_Main.h"
-#include "Misc.h"
-#include "OptionsSheet.h"
-#include "TextConvert.h"
-#include "AlphaBlend.h"
-#include "Tlhelp32.h"
-
-// Debug Functions
-
-
-CString GetIPAddress()
-{
-	WORD wVersionRequested;
-    WSADATA wsaData;
-    char name[255];
-    CString IP;
-	PHOSTENT hostinfo;
-	wVersionRequested = MAKEWORD(2,0);
-	
-	if (WSAStartup(wVersionRequested, &wsaData)==0)
-	{
-		if(gethostname(name, sizeof(name))==0)
-		{
-			if((hostinfo=gethostbyname(name)) != NULL)
-			{
-				IP = inet_ntoa(*(struct in_addr*)* hostinfo->h_addr_list);
-			}
-		}
-		
-		WSACleanup();
-	} 
-	IP.MakeUpper();
-
-	return IP;
-}
-
-CString GetComputerName()
-{
-	TCHAR ComputerName[MAX_COMPUTERNAME_LENGTH+1] = _T("");
-	DWORD Size=MAX_COMPUTERNAME_LENGTH+1;
-	GetComputerName(ComputerName, &Size);
-
-	CString cs(ComputerName);
-	cs.MakeUpper();
-
-	return cs;
-}
-
-void AppendToFile(const TCHAR* fn, const TCHAR* msg)
-{
-#ifdef _UNICODE
-	FILE *file = _wfopen(fn, _T("a"));
-#else
-	FILE *file = fopen(fn, _T("a"));
-#endif
-
-	ASSERT( file );
-
-#ifdef _UNICODE
-	fwprintf(file, msg);
-#else
-	fprintf(file, msg);
-#endif
-
-	fclose(file);
-}
-
-void log(const TCHAR* msg, bool bFromSendRecieve, CString csFile, long lLine)
-{
-	ASSERT(AfxIsValidString(msg));
-	CTime	time = CTime::GetCurrentTime();
-	CString	csText = time.Format("[%Y/%m/%d %I:%M:%S %p - ");
-
-	CString csFileLine;
-	csFile = GetFileName(csFile);
-	csFileLine.Format(_T("%s %d] "), csFile, lLine);
-	csText += csFileLine;
-	
-	csText += msg;
-	csText += "\n";
-
-#ifndef _DEBUG
-	if(CGetSetOptions::m_bOutputDebugString)
-#endif
-	{
-		OutputDebugString(csText);
-	}
-
-#ifndef _DEBUG
-	if(!bFromSendRecieve)
-	{
-		if(!g_Opt.m_bEnableDebugLogging)
-			return;
-	}
-#endif
-	
-	CString csExeFile = CGetSetOptions::GetPath(PATH_LOG_FILE);
-	csExeFile += "Ditto.log";
-
-	AppendToFile(csExeFile, csText);
-}
-
-void logsendrecieveinfo(CString cs, CString csFile, long lLine)
-{
-	if(g_Opt.m_bLogSendReceiveErrors)
-		log(cs, true, csFile, lLine);
-}
-
-CString GetErrorString( int err )
-{
-	CString str;
-	LPVOID lpMsgBuf;
-	
-	::FormatMessage( 
-		FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
-		NULL,
-		err,
-		MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
-		(LPTSTR) &lpMsgBuf,
-		0,
-		NULL 
-		);
-	str = (LPCTSTR) lpMsgBuf;
-	// Display the string.
-	//  ::MessageBox( NULL, lpMsgBuf, "GetLastError", MB_OK|MB_ICONINFORMATION );
-	::LocalFree( lpMsgBuf );
-	return str;
-	
-}
-
-// Utility Functions
-
-CString StrF(const TCHAR * pszFormat, ...)
-{
-	ASSERT( AfxIsValidString( pszFormat ) );
-	CString str;
-	va_list argList;
-	va_start( argList, pszFormat );
-	str.FormatV( pszFormat, argList );
-	va_end( argList );
-	return str;
-}
-
-BYTE GetEscapeChar( BYTE ch )
-{
-	switch(ch)
-	{
-	case '\'':	return '\''; // Single quotation mark (') = 39 or 0x27
-	case '\"':	return '\"'; // Double quotation mark (") = 34 or 0x22
-	case '?':	return '\?'; // Question mark (?) = 63 or 0x3f
-	case '\\':	return '\\'; // Backslash (\) = 92 or 0x5c
-	case 'a':	return '\a'; // Alert (BEL) = 7
-	case 'b':	return '\b'; // Backspace (BS) = 8
-	case 'f':	return '\f'; // Formfeed (FF) = 12 or 0x0c
-	case 'n':	return '\n'; // Newline (NL or LF) = 10 or 0x0a
-	case 'r':	return '\r'; // Carriage Return (CR) = 13 or 0x0d
-	case 't':	return '\t'; // Horizontal tab (HT) = 9
-	case 'v':	return '\v'; // Vertical tab (VT) = 11 or 0x0b
-	case '0':	return '\0'; // Null character (NUL) = 0
-	}
-	return 0; // invalid
-}
-
-CString RemoveEscapes( const TCHAR* str )
-{
-	ASSERT( str );
-	CString ret;
-	TCHAR* pSrc = (TCHAR*) str;
-	TCHAR* pDest = ret.GetBuffer(STRLEN(pSrc));
-	TCHAR* pStart = pDest;
-	while( *pSrc != '\0' )
-	{
-		if( *pSrc == '\\' )
-		{
-			pSrc++;
-			*pDest = GetEscapeChar((BYTE)pSrc );
-		}
-		else
-			*pDest = *pSrc;
-		pSrc++;
-		pDest++;
-	}
-	ret.ReleaseBuffer( pDest - pStart );
-	return ret;
-}
-
-CString GetWndText( HWND hWnd )
-{
-	CString text;
-	if( !IsWindow(hWnd) )
-		return "! NOT A VALID WINDOW !";
-	CWnd* pWnd = CWnd::FromHandle(hWnd);
-	pWnd->GetWindowText(text);
-	return text;
-}
-
-bool IsAppWnd( HWND hWnd )
-{
-	DWORD dwMyPID = ::GetCurrentProcessId();
-	DWORD dwTestPID;
-	::GetWindowThreadProcessId( hWnd, &dwTestPID );
-	return dwMyPID == dwTestPID;
-}
-
-/*----------------------------------------------------------------------------*\
-Global Memory Helper Functions
-\*----------------------------------------------------------------------------*/
-
-// make sure the given HGLOBAL is valid.
-BOOL IsValid( HGLOBAL hGlobal )
-{
-	void* pvData = ::GlobalLock( hGlobal );
-	::GlobalUnlock( hGlobal );
-	return ( pvData != NULL );
-}
-
-// asserts if hDest isn't big enough
-void CopyToGlobalHP( HGLOBAL hDest, LPVOID pBuf, ULONG ulBufLen )
-{
-	ASSERT( hDest && pBuf && ulBufLen );
-	LPVOID pvData = GlobalLock(hDest);
-	ASSERT( pvData );
-	ULONG size = GlobalSize(hDest);
-	ASSERT( size >= ulBufLen );	// assert if hDest isn't big enough
-	memcpy(pvData, pBuf, ulBufLen);
-	GlobalUnlock(hDest);
-}
-
-void CopyToGlobalHH( HGLOBAL hDest, HGLOBAL hSource, ULONG ulBufLen )
-{
-	ASSERT( hDest && hSource && ulBufLen );
-	LPVOID pvData = GlobalLock(hSource);
-	ASSERT( pvData );
-	ULONG size = GlobalSize(hSource);
-	ASSERT( size >= ulBufLen );	// assert if hSource isn't big enough
-	CopyToGlobalHP(hDest, pvData, ulBufLen);
-	GlobalUnlock(hSource);
-}
-
-
-HGLOBAL NewGlobalP( LPVOID pBuf, UINT nLen )
-{
-	ASSERT( pBuf && nLen );
-	HGLOBAL hDest = GlobalAlloc( GMEM_MOVEABLE | GMEM_SHARE, nLen );
-	ASSERT( hDest );
-	CopyToGlobalHP( hDest, pBuf, nLen );
-	return hDest;
-}
-
-HGLOBAL NewGlobal(UINT nLen)
-{
-	ASSERT(nLen);
-	HGLOBAL hDest = GlobalAlloc(GMEM_MOVEABLE | GMEM_SHARE, nLen);
-	return hDest;
-}
-
-HGLOBAL NewGlobalH( HGLOBAL hSource, UINT nLen )
-{
-	ASSERT( hSource && nLen );
-	LPVOID pvData = GlobalLock( hSource );
-	HGLOBAL hDest = NewGlobalP( pvData, nLen );
-	GlobalUnlock( hSource );
-	return hDest;
-}
-
-int CompareGlobalHP(HGLOBAL hLeft, LPVOID pBuf, ULONG ulBufLen)
-{
-	ASSERT(hLeft && pBuf && ulBufLen);
-
-	LPVOID pvData = GlobalLock(hLeft);
-	
-	ASSERT(pvData);
-	ASSERT(ulBufLen <= GlobalSize(hLeft));
-
-	int result = memcmp(pvData, pBuf, ulBufLen);
-	
-	GlobalUnlock(hLeft);
-
-	return result;
-}
-
-int CompareGlobalHH( HGLOBAL hLeft, HGLOBAL hRight, ULONG ulBufLen )
-{
-	ASSERT( hLeft && hRight && ulBufLen );
-	ASSERT( ulBufLen <= GlobalSize(hRight) );
-	LPVOID pvData = GlobalLock(hRight);
-	ASSERT( pvData );
-	int result = CompareGlobalHP( hLeft, pvData, ulBufLen );
-	GlobalUnlock( hLeft );
-	return result;
-}
-
-
-//Do not change these these are stored in the database
-CLIPFORMAT GetFormatID(LPCTSTR cbName)
-{
-	if(STRCMP(cbName, _T("CF_TEXT")) == 0)
-		return CF_TEXT;
-	else if(STRCMP(cbName, _T("CF_METAFILEPICT")) == 0)
-		return CF_METAFILEPICT;
-	else if(STRCMP(cbName, _T("CF_SYLK")) == 0)
-		return CF_SYLK;
-	else if(STRCMP(cbName, _T("CF_DIF")) == 0)
-		return CF_DIF;
-	else if(STRCMP(cbName, _T("CF_TIFF")) == 0)
-		return CF_TIFF;
-	else if(STRCMP(cbName, _T("CF_OEMTEXT")) == 0)
-		return CF_OEMTEXT;
-	else if(STRCMP(cbName, _T("CF_DIB")) == 0)
-		return CF_DIB;
-	else if(STRCMP(cbName, _T("CF_PALETTE")) == 0)
-		return CF_PALETTE;
-	else if(STRCMP(cbName, _T("CF_PENDATA")) == 0)
-		return CF_PENDATA;
-	else if(STRCMP(cbName, _T("CF_RIFF")) == 0)
-		return CF_RIFF;
-	else if(STRCMP(cbName, _T("CF_WAVE")) == 0)
-		return CF_WAVE;
-	else if(STRCMP(cbName, _T("CF_UNICODETEXT")) == 0)
-		return CF_UNICODETEXT;
-	else if(STRCMP(cbName, _T("CF_ENHMETAFILE")) == 0)
-		return CF_ENHMETAFILE;
-	else if(STRCMP(cbName, _T("CF_HDROP")) == 0)
-		return CF_HDROP;
-	else if(STRCMP(cbName, _T("CF_LOCALE")) == 0)
-		return CF_LOCALE;
-	else if(STRCMP(cbName, _T("CF_OWNERDISPLAY")) == 0)
-		return CF_OWNERDISPLAY;
-	else if(STRCMP(cbName, _T("CF_DSPTEXT")) == 0)
-		return CF_DSPTEXT;
-	else if(STRCMP(cbName, _T("CF_DSPBITMAP")) == 0)
-		return CF_DSPBITMAP;
-	else if(STRCMP(cbName, _T("CF_DSPMETAFILEPICT")) == 0)
-		return CF_DSPMETAFILEPICT;
-	else if(STRCMP(cbName, _T("CF_DSPENHMETAFILE")) == 0)
-		return CF_DSPENHMETAFILE;
-	
-	
-	return ::RegisterClipboardFormat(cbName);
-}
-
-//Do not change these these are stored in the database
-CString GetFormatName(CLIPFORMAT cbType)
-{
-	switch(cbType)
-	{
-	case CF_TEXT:
-		return _T("CF_TEXT");
-	case CF_BITMAP:
-		return _T("CF_BITMAP");
-	case CF_METAFILEPICT:
-		return _T("CF_METAFILEPICT");
-	case CF_SYLK:
-		return _T("CF_SYLK");
-	case CF_DIF:
-		return _T("CF_DIF");
-	case CF_TIFF:
-		return _T("CF_TIFF");
-	case CF_OEMTEXT:
-		return _T("CF_OEMTEXT");
-	case CF_DIB:
-		return _T("CF_DIB");
-	case CF_PALETTE:
-		return _T("CF_PALETTE");
-	case CF_PENDATA:
-		return _T("CF_PENDATA");
-	case CF_RIFF:
-		return _T("CF_RIFF");
-	case CF_WAVE:
-		return _T("CF_WAVE");
-	case CF_UNICODETEXT:
-		return _T("CF_UNICODETEXT");
-	case CF_ENHMETAFILE:
-		return _T("CF_ENHMETAFILE");
-	case CF_HDROP:
-		return _T("CF_HDROP");
-	case CF_LOCALE:
-		return _T("CF_LOCALE");
-	case CF_OWNERDISPLAY:
-		return _T("CF_OWNERDISPLAY");
-	case CF_DSPTEXT:
-		return _T("CF_DSPTEXT");
-	case CF_DSPBITMAP:
-		return _T("CF_DSPBITMAP");
-	case CF_DSPMETAFILEPICT:
-		return _T("CF_DSPMETAFILEPICT");
-	case CF_DSPENHMETAFILE:
-		return _T("CF_DSPENHMETAFILE");
-	default:
-		//Not a default type get the name from the clipboard
-		if (cbType != 0)
-		{
-			TCHAR szFormat[256];
-            GetClipboardFormatName(cbType, szFormat, 256);
-			return szFormat;
-		}
-		break;
-	}
-	
-	return "ERROR";
-}
-
-CString GetFilePath(CString csFileName)
-{
-	long lSlash = csFileName.ReverseFind('\\');
-	
-	if(lSlash > -1)
-	{
-		csFileName = csFileName.Left(lSlash + 1);
-	}
-	
-	return csFileName;
-}
-
-CString GetFileName(CString csFileName)
-{
-	long lSlash = csFileName.ReverseFind('\\');
-	if(lSlash > -1)
-	{
-		csFileName = csFileName.Right(csFileName.GetLength() - lSlash - 1);
-	}
-
-	return csFileName;
-}
-
-
-/*------------------------------------------------------------------*\
-CHotKey - a single system-wide hotkey
-\*------------------------------------------------------------------*/
-
-CHotKey::CHotKey( CString name, DWORD defKey, bool bUnregOnShowDitto ) 
-: m_Name(name), m_bIsRegistered(false), m_bUnRegisterOnShowDitto(bUnregOnShowDitto)
-{
-	m_Atom = ::GlobalAddAtom( m_Name );
-	ASSERT( m_Atom );
-	m_Key = (DWORD) g_Opt.GetProfileLong( m_Name, (long) defKey );
-	g_HotKeys.Add( this );
-}
-CHotKey::~CHotKey()
-{
-	Unregister();
-}
-
-void CHotKey::SetKey( DWORD key, bool bSave )
-{
-	if( m_Key == key )
-		return;
-	if( m_bIsRegistered )
-		Unregister();
-	m_Key = key;
-	if( bSave )
-		SaveKey();
-}
-
-void CHotKey::LoadKey()
-{
-	SetKey( (DWORD) g_Opt.GetProfileLong( m_Name, 0 ) );
-}
-
-bool CHotKey::SaveKey()
-{
-	return g_Opt.SetProfileLong( m_Name, (long) m_Key ) != FALSE;
-}
-
-//	CString GetKeyAsText();
-//	void SetKeyFromText( CString text );
-
-BOOL CHotKey::ValidateHotKey(DWORD dwHotKey)
-{
-	ATOM id = ::GlobalAddAtom(_T("HK_VALIDATE"));
-	BOOL bResult = ::RegisterHotKey( g_HotKeys.m_hWnd,
-		id,
-		GetModifier(dwHotKey),
-		LOBYTE(dwHotKey) );
-	
-	if(bResult)
-		::UnregisterHotKey(g_HotKeys.m_hWnd, id);
-	
-	::GlobalDeleteAtom(id);
-	
-	return bResult;
-}
-
-void CHotKey::CopyFromCtrl(CHotKeyCtrl& ctrl, HWND hParent, int nWindowsCBID) 
-{ 
-	long lHotKey = ctrl.GetHotKey();
-
-	short sKeyKode = LOBYTE(lHotKey);
-	short sModifers = HIBYTE(lHotKey);
-
-	if(lHotKey && ::IsDlgButtonChecked(hParent, nWindowsCBID))
-	{
-		sModifers |= HOTKEYF_EXT;
-	}
-
-	SetKey(MAKEWORD(sKeyKode, sModifers)); 
-}
-
-void CHotKey::CopyToCtrl(CHotKeyCtrl& ctrl, HWND hParent, int nWindowsCBID)
-{
-	long lModifiers = HIBYTE(m_Key);
-
-	ctrl.SetHotKey(LOBYTE(m_Key), (WORD)lModifiers); 
-
-	if(lModifiers & HOTKEYF_EXT)
-	{
-		::CheckDlgButton(hParent, nWindowsCBID, BST_CHECKED);
-	}
-}
-
-UINT CHotKey::GetModifier(DWORD dwHotKey)
-{
-	UINT uMod = 0;
-	if( HIBYTE(dwHotKey) & HOTKEYF_SHIFT )   uMod |= MOD_SHIFT;
-	if( HIBYTE(dwHotKey) & HOTKEYF_CONTROL ) uMod |= MOD_CONTROL;
-	if( HIBYTE(dwHotKey) & HOTKEYF_ALT )     uMod |= MOD_ALT;
-	if( HIBYTE(dwHotKey) & HOTKEYF_EXT )     uMod |= MOD_WIN;
-	
-	return uMod;
-}
-
-bool CHotKey::Register()
-{
-	if(m_Key)
-	{
-		if(m_bIsRegistered == false)
-		{
-			ASSERT(g_HotKeys.m_hWnd);
-			m_bIsRegistered = ::RegisterHotKey(g_HotKeys.m_hWnd,
-												m_Atom,
-												GetModifier(),
-												LOBYTE(m_Key) ) == TRUE;
-		}
-	}
-	else
-		m_bIsRegistered = true;
-	
-	return m_bIsRegistered;
-}
-bool CHotKey::Unregister(bool bOnShowingDitto)
-{
-	if(!m_bIsRegistered)
-		return true;
-	
-	if(bOnShowingDitto)
-	{
-		if(m_bUnRegisterOnShowDitto == false)
-			return true;
-	}
-
-	if(m_Key)
-	{
-		ASSERT(g_HotKeys.m_hWnd);
-		if(::UnregisterHotKey( g_HotKeys.m_hWnd, m_Atom))
-		{
-			m_bIsRegistered = false;
-			return true;
-		}
-		else
-		{
-			Log(_T("Unregister FAILED!"));
-			ASSERT(0);
-		}
-	}
-	else
-	{
-		m_bIsRegistered = false;
-		return true;
-	}
-	
-	return false;
-}
-
-
-/*------------------------------------------------------------------*\
-CHotKeys - Manages system-wide hotkeys
-\*------------------------------------------------------------------*/
-
-CHotKeys g_HotKeys;
-
-CHotKeys::CHotKeys() : m_hWnd(NULL) {}
-CHotKeys::~CHotKeys()
-{
-	CHotKey* pHotKey;
-	int count = GetSize();
-	for(int i=0; i < count; i++)
-	{
-		pHotKey = ElementAt(i);
-		if(pHotKey)
-			delete pHotKey;
-	}
-}
-
-int CHotKeys::Find( CHotKey* pHotKey )
-{
-	int count = GetSize();
-	for(int i=0; i < count; i++)
-	{
-		if( pHotKey == ElementAt(i) )
-			return i;
-	}
-	return -1;
-}
-
-bool CHotKeys::Remove( CHotKey* pHotKey )
-{
-	int i = Find(pHotKey);
-	if(i >= 0)
-	{
-		RemoveAt(i);
-		return true;
-	}
-	return false;
-}
-
-void CHotKeys::LoadAllKeys()
-{
-	int count = GetSize();
-	for(int i=0; i < count; i++)
-		ElementAt(i)->LoadKey();
-}
-
-void CHotKeys::SaveAllKeys()
-{
-	int count = GetSize();
-	for(int i=0; i < count; i++)
-		ElementAt(i)->SaveKey();
-}
-
-void CHotKeys::RegisterAll(bool bMsgOnError)
-{
-	CString str;
-	CHotKey* pHotKey;
-	int count = GetSize();
-	for(int i = 0; i < count; i++)
-	{
-		pHotKey = ElementAt(i);
-		if(!pHotKey->Register())
-		{
-			str =  "Error Registering ";
-			str += pHotKey->GetName();
-			Log(str);
-			if(bMsgOnError)
-				AfxMessageBox(str);
-		}
-	}
-}
-
-void CHotKeys::UnregisterAll(bool bMsgOnError, bool bOnShowDitto)
-{
-	CString str;
-	CHotKey* pHotKey;
-	int count = GetSize();
-	for(int i = 0; i < count; i++)
-	{
-		pHotKey = ElementAt(i);
-		if(!pHotKey->Unregister(bOnShowDitto))
-		{
-			str = "Error Unregistering ";
-			str += pHotKey->GetName();
-			Log(str);
-			if(bMsgOnError)
-				AfxMessageBox(str);
-		}
-	}
-}
-
-void CHotKeys::GetKeys(ARRAY& keys)
-{
-	int count = GetSize();
-	keys.SetSize(count);
-	for(int i=0; i < count; i++)
-		keys[i] = ElementAt(i)->GetKey();
-}
-
-// caution! this alters hotkeys based upon corresponding indexes
-void CHotKeys::SetKeys(ARRAY& keys, bool bSave)
-{
-	int count = GetSize();
-	ASSERT(count == keys.GetSize());
-	for(int i=0; i < count; i++)
-		ElementAt(i)->SetKey(keys[i], bSave);
-}
-
-bool CHotKeys::FindFirstConflict(ARRAY& keys, int* pX, int* pY)
-{
-	bool bConflict = false;
-	int i, j;
-	int count = keys.GetSize();
-	DWORD key;
-	for(i = 0; i < count && !bConflict; i++)
-	{
-		key = keys.ElementAt(i);
-		// only check valid keys
-		if(key == 0)
-			continue;
-
-		// scan the array for a duplicate
-		for(j = i+1; j < count; j++ )
-		{
-			if(keys.ElementAt(j) == key)
-			{
-				bConflict = true;
-				break;
-			}
-		}
-	}
-	
-	if(bConflict)
-	{
-		if(pX)
-			*pX = i-1;
-		if(pY)
-			*pY = j;
-	}
-	
-	return bConflict;
-}
-
-// if true, pX and pY (if valid) are set to the indexes of the conflicting hotkeys.
-bool CHotKeys::FindFirstConflict(int* pX, int* pY)
-{
-	ARRAY keys;
-	GetKeys(keys);
-	return FindFirstConflict(keys, pX, pY);
-}
-
-/****************************************************************************************************
-BOOL CALLBACK MyMonitorEnumProc(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData)
-***************************************************************************************************/
-typedef struct
-{
-	long	lFlags;				// Flags
-	LPRECT	pVirtualRect;		// Ptr to rect that receives the results, or the src of the monitor search method
-	int		iMonitor;			// Ndx to the mointor to look at, -1 for all, -or- result of the monitor search method
-	int		nMonitorCount;		// Total number of monitors found, -1 for monitor search method
-}	MONITOR_ENUM_PARAM;
-#define	MONITOR_SEARCH_METOHD	0x00000001
-BOOL CALLBACK MyMonitorEnumProc(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData)
-{
-	// Typecast param
-	MONITOR_ENUM_PARAM* pParam = (MONITOR_ENUM_PARAM*)dwData;
-	if(pParam)
-	{
-		// If a dest rect was passed
-		if(pParam->pVirtualRect)
-		{
-			// If MONITOR_SEARCH_METOHD then we are being asked for the index of the monitor
-			// that the rect falls inside of
-			if(pParam->lFlags & MONITOR_SEARCH_METOHD)
-			{
-				if(	(pParam->pVirtualRect->right	< lprcMonitor->left)	||
-					(pParam->pVirtualRect->left		> lprcMonitor->right)	||
-					(pParam->pVirtualRect->bottom	< lprcMonitor->top)		||
-					(pParam->pVirtualRect->top		> lprcMonitor->bottom))
-				{
-					// Nothing
-				}
-				else
-				{
-					// This is the one
-					pParam->iMonitor = pParam->nMonitorCount;
-					
-					// Stop the enumeration
-					return FALSE;
-				}
-			}
-			else
-			{
-				if(pParam->iMonitor == pParam->nMonitorCount)
-				{
-					*pParam->pVirtualRect = *lprcMonitor;
-				}
-				else
-					if(pParam->iMonitor == -1)
-					{
-						pParam->pVirtualRect->left = min(pParam->pVirtualRect->left, lprcMonitor->left);
-						pParam->pVirtualRect->top = min(pParam->pVirtualRect->top, lprcMonitor->top);
-						pParam->pVirtualRect->right = max(pParam->pVirtualRect->right, lprcMonitor->right);
-						pParam->pVirtualRect->bottom = max(pParam->pVirtualRect->bottom, lprcMonitor->bottom);
-					}
-			}
-		}
-		
-		// Up the count if necessary
-		pParam->nMonitorCount++;
-	}
-	return TRUE;
-}
-
-int GetScreenWidth(void)
-{
-	OSVERSIONINFO OS_Version_Info;
-	DWORD dwPlatform = 0;
-	
-	if(GetVersionEx(&OS_Version_Info) != 0)
-	{
-		dwPlatform = OS_Version_Info.dwPlatformId;
-	}
-	
-	if(dwPlatform == VER_PLATFORM_WIN32_NT)
-	{
-		int width, height;
-		
-		width = GetSystemMetrics(SM_CXSCREEN);
-		height = GetSystemMetrics(SM_CYSCREEN);
-		switch(width)
-		{
-		default:
-		case 640:
-		case 800:
-		case 1024:
-			return(width);
-		case 1280:
-			if(height == 480)
-			{
-				return(width / 2);
-			}
-			return(width);
-		case 1600:
-			if(height == 600)
-			{
-				return(width / 2);
-			}
-			return(width);
-		case 2048:
-			if(height == 768)
-			{
-				return(width / 2);
-			}
-			return(width);
-		}
-	}
-	else
-	{
-		return(GetSystemMetrics(SM_CXSCREEN));
-	}
-}
-
-int GetScreenHeight(void)
-{
-	OSVERSIONINFO OS_Version_Info;
-	DWORD dwPlatform = 0;
-	
-	if(GetVersionEx(&OS_Version_Info) != 0)
-	{
-		dwPlatform = OS_Version_Info.dwPlatformId;
-	}
-	
-	if(dwPlatform == VER_PLATFORM_WIN32_NT)
-	{
-		int width, height;
-		
-		width = GetSystemMetrics(SM_CXSCREEN);
-		height = GetSystemMetrics(SM_CYSCREEN);
-		switch(height)
-		{
-		default:
-		case 480:
-		case 600:
-		case 768:
-			return(height);
-		case 960:
-			if(width == 640)
-			{
-				return(height / 2);
-			}
-			return(height);
-		case 1200:
-			if(width == 800)
-			{
-				return(height / 2);
-			}
-			return(height);
-		case 1536:
-			if(width == 1024)
-			{
-				return(height / 2);
-			}
-			return(height);
-		}
-	}
-	else
-	{
-		return(GetSystemMetrics(SM_CYSCREEN));
-	}
-}
-
-int GetMonitorFromRect(LPRECT lpMonitorRect)
-{
-	// Build up the param
-	MONITOR_ENUM_PARAM	EnumParam;
-	ZeroMemory(&EnumParam, sizeof(EnumParam));
-	EnumParam.lFlags = MONITOR_SEARCH_METOHD;
-	EnumParam.pVirtualRect = lpMonitorRect;
-	EnumParam.iMonitor = -1;
-	
-	// Enum Displays
-	EnumDisplayMonitors(NULL, NULL, MyMonitorEnumProc, (long)&EnumParam);
-	
-	// Return the result
-	return EnumParam.iMonitor;
-}
-
-void GetMonitorRect(int iMonitor, LPRECT lpDestRect)
-{
-	// Build up the param
-	MONITOR_ENUM_PARAM	EnumParam;
-	ZeroMemory(&EnumParam, sizeof(EnumParam));
-	EnumParam.iMonitor = iMonitor;
-	EnumParam.pVirtualRect = lpDestRect;
-	
-	// Zero out dest rect
-	lpDestRect->bottom = lpDestRect->left = lpDestRect->right = lpDestRect->top = 0;
-	
-	// Enum Displays
-	EnumDisplayMonitors(NULL, NULL, MyMonitorEnumProc, (long)&EnumParam);
-	
-	// If not successful, default to the screen dimentions
-	if(lpDestRect->right == 0 || lpDestRect->bottom == 0)
-	{
-		lpDestRect->right = GetScreenWidth();
-		lpDestRect->bottom = GetScreenHeight();
-	}
-}
-
-
-/*------------------------------------------------------------------*\
-CAccel - an Accelerator (in-app hotkey)
-
-  - the win32 CreateAcceleratorTable using ACCEL was insufficient
-  because it only allowed a WORD for the cmd associated with it.
-\*------------------------------------------------------------------*/
-
-/*------------------------------------------------------------------*\
-CAccels - Manages a set of CAccel
-\*------------------------------------------------------------------*/
-
-int CompareAccel( const void* pLeft, const void* pRight )
-{
-	WORD w;
-	int l,r;
-	// swap bytes: place the VirtualKey in the MSB and the modifier in the LSB
-	//  so that Accels based upon the same vkey are grouped together.
-	// this is required by our use of m_Index
-	// alternatively, we could store them this way in CAccel.
-	w = (WORD) ((CAccel*)pLeft)->Key;
-	l = (ACCEL_VKEY(w) << 8) | ACCEL_MOD(w);
-	w = (WORD) ((CAccel*)pRight)->Key;
-	r = (ACCEL_VKEY(w) << 8) | ACCEL_MOD(w);
-	return l - r;
-}
-
-CAccels::CAccels()
-{}
-
-void CAccels::AddAccel( CAccel& a )
-{
-	m_Map.SetAt(a.Key, a.Cmd);
-	
-}
-
-bool CAccels::OnMsg( MSG* pMsg, DWORD &dID)
-{
-	// bit 30 (0x40000000) is 1 if this is NOT the first msg of the key
-	//  i.e. auto-repeat may cause multiple msgs of the same key
-	if( (pMsg->lParam & 0x40000000) ||
-		(pMsg->message != WM_KEYDOWN &&
-		pMsg->message != WM_SYSKEYDOWN) )
-	{	
-		return NULL; 
-	}
-	
-	if( !pMsg || m_Map.GetCount() <= 0 )
-		return NULL;
-	
-	BYTE vkey = LOBYTE(pMsg->wParam);
-	BYTE mod  = GetKeyStateModifiers();
-	DWORD key = ACCEL_MAKEKEY( vkey, mod );
-
-	CString cs;
-	cs.Format(_T("Key: %d, Mod: %d, vkey: %d"), key, mod, vkey);
-	OutputDebugString(cs);
-	
-	if(m_Map.Lookup(key, dID))
-		return true;;
-	
-	return false;
-}
-
-BYTE GetKeyStateModifiers()
-{
-	BYTE m=0;
-	if( GetKeyState(VK_SHIFT) & 0x8000 )
-		m |= HOTKEYF_SHIFT;
-	if( GetKeyState(VK_CONTROL) & 0x8000 )
-		m |= HOTKEYF_CONTROL;
-	if( GetKeyState(VK_MENU) & 0x8000 )
-		m |= HOTKEYF_ALT;
-	if( GetKeyState(VK_LWIN) & 0x8000 )
-		m |= HOTKEYF_EXT;
-	if( GetKeyState(VK_RWIN) & 0x8000 )
-		m |= HOTKEYF_EXT;
-	return m;
-}
-
-/*------------------------------------------------------------------*\
-CTokenizer - Tokenizes a string using given delimiters
-\*------------------------------------------------------------------*/
-
-CTokenizer::CTokenizer(const CString& cs, const CString& csDelim):
-m_cs(cs),
-m_nCurPos(0)
-{
-	SetDelimiters(csDelim);
-}
-
-void CTokenizer::SetDelimiters(const CString& csDelim)
-{
-	for(int i = 0; i < csDelim.GetLength(); ++i)
-		m_delim.Add(csDelim[i]);
-
-	m_delim.SortAscending();
-}
-
-bool CTokenizer::Next(CString& cs)
-{
-	cs.Empty();
-	int len = m_cs.GetLength();
-
-	while (m_nCurPos < len && m_delim.Find(m_cs[m_nCurPos]))
-		++ m_nCurPos;
-
-	if (m_nCurPos >= len)
-		return false;
-
-	int nStartPos = m_nCurPos;
-
-	while (m_nCurPos < len && !m_delim.Find(m_cs[m_nCurPos]))
-		++ m_nCurPos;
-
-	cs = m_cs.Mid(nStartPos, m_nCurPos - nStartPos);
-
-	return true;
-}
-
-CString	CTokenizer::Tail()
-{
-	int len = m_cs.GetLength();
-	int nCurPos = m_nCurPos;
-	
-	while(nCurPos < len && m_delim.Find(m_cs[nCurPos]))
-		++nCurPos;
-	
-	CString csResult;
-	if(nCurPos < len)
-		csResult = m_cs.Mid(nCurPos);
-	
-	return csResult;
-}
-
-/*------------------------------------------------------------------*\
-ID based Globals
-\*------------------------------------------------------------------*/
-
-long NewGroupID(long lParentID, CString text)
-{
-	long lID=0;
-	CTime time;
-	time = CTime::GetCurrentTime();
-	
-	try
-	{
-		//sqlite doesn't like single quotes ' replace them with double ''
-		if(text.IsEmpty())
-			text = time.Format("NewGroup %y/%m/%d %H:%M:%S");
-		text.Replace(_T("'"), _T("''"));
-
-		CString cs;
-		cs.Format(_T("insert into Main values(NULL, %d, '%s', 0, %d, 0, 1, %d, '');"),
-							(long)time.GetTime(),
-							text,
-							(long)time.GetTime(),
-							lParentID);
-
-		theApp.m_db.execDML(cs);
-
-		lID = (long)theApp.m_db.lastRowId();
-	}
-	CATCH_SQLITE_EXCEPTION_AND_RETURN(0)
-	
-	return lID;
-}
-
-BOOL DeleteAllIDs()
-{
-	try
-	{
-		theApp.m_db.execDML(_T("DELETE FROM Data;"));
-		theApp.m_db.execDML(_T("DELETE FROM Main;"));
-	}
-	CATCH_SQLITE_EXCEPTION
-
-	return TRUE;
-}
-
-BOOL DeleteFormats(long lParentID, ARRAY& formatIDs)
-{	
-	if(formatIDs.GetSize() <= 0)
-		return TRUE;
-		
-	try
-	{
-		//Delete the requested data formats
-		int nCount = formatIDs.GetSize();
-		for(int i = 0; i < nCount; i++)
-		{
-			theApp.m_db.execDMLEx(_T("DELETE FROM Data WHERE lID = %d;"), formatIDs[i]);
-		}
-
-		CClip clip;
-		if(clip.LoadFormats(lParentID))
-		{
-			DWORD CRC = clip.GenerateCRC();
-
-			//Update the main table with new size
-			theApp.m_db.execDMLEx(_T("UPDATE Main SET CRC = %d WHERE lID = %d"), CRC, lParentID);
-		}
-	}
-	CATCH_SQLITE_EXCEPTION
-		
-	return TRUE;
-}
-
-BOOL EnsureWindowVisible(CRect *pcrRect)
-{
-	int nMonitor = GetMonitorFromRect(pcrRect);
-	if(nMonitor < 0)
-	{
-		GetMonitorRect(0, pcrRect);
-		pcrRect->right = pcrRect->left + 300;
-		pcrRect->bottom = pcrRect->top + 300;
-
-		return TRUE;
-	}
-
-	CRect crMonitor;
-	GetMonitorRect(nMonitor, crMonitor);
-
-	//Validate the left
-	long lDiff = pcrRect->left - crMonitor.left;
-	if(lDiff < 0)
-	{
-		pcrRect->left += abs(lDiff);
-		pcrRect->right += abs(lDiff);
-	}
-
-	//Right side
-	lDiff = pcrRect->right - crMonitor.right;
-	if(lDiff > 0)
-	{
-		pcrRect->left -= abs(lDiff);
-		pcrRect->right -= abs(lDiff);
-	}
-
-	//Top
-	lDiff = pcrRect->top - crMonitor.top;
-	if(lDiff < 0)
-	{
-		pcrRect->top += abs(lDiff);
-		pcrRect->bottom += abs(lDiff);
-	}
-
-	//Bottom
-	lDiff = pcrRect->bottom - crMonitor.bottom;
-	if(lDiff > 0)
-	{
-		pcrRect->top -= abs(lDiff);
-		pcrRect->bottom -= abs(lDiff);
-	}
-
-	return TRUE;
-}
-
-__int64 GetLastWriteTime(const CString &csFile)
-{
-	__int64 nLastWrite = 0;
-	CFileFind finder;
-	BOOL bResult = finder.FindFile(csFile);
-
-	if (bResult)
-	{
-		finder.FindNextFile();
-
-		FILETIME ft;
-		finder.GetLastWriteTime(&ft);
-
-		memcpy(&nLastWrite, &ft, sizeof(ft));
-	}
-
-	return nLastWrite;
-}
-
-CString GetProcessName(HWND hWnd) 
-{
-	DWORD Id;
-	GetWindowThreadProcessId(hWnd, &Id);
-
-	PROCESSENTRY32 processEntry = { 0 };
-
-	HANDLE hSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
-	processEntry.dwSize = sizeof(PROCESSENTRY32);
-
-	if (Process32First(hSnapShot, &processEntry)) 
-	{
-		do 
-		{
-			if (processEntry.th32ProcessID == Id) 
-			{
-				return processEntry.szExeFile;
-			}
-		} while(Process32Next(hSnapShot, &processEntry));
-	}
-	CloseHandle(hSnapShot);
-
-	return "";
-}
-
-BOOL IsVista()
-{
-	OSVERSIONINFO osver;
-
-	osver.dwOSVersionInfoSize = sizeof( OSVERSIONINFO );
-
-	if (::GetVersionEx( &osver ) && 
-		osver.dwPlatformId == VER_PLATFORM_WIN32_NT && 
-		(osver.dwMajorVersion >= 6 ) )
-	{
-		return TRUE;
-	}
-
-	return FALSE;
-}
-
-bool IsRunningLimited()
-{
-	LPCTSTR pszSubKey = _T("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Policies\\System");
-	LPCTSTR pszValue = _T("EnableLUA");
-	DWORD dwType = 0;
-	DWORD dwValue = 0;
-	DWORD dwValueSize = sizeof(DWORD);
-
-	if(ERROR_SUCCESS != SHGetValue(HKEY_LOCAL_MACHINE, pszSubKey, pszValue, &dwType, &dwValue, &dwValueSize))
-	{
-		//failed to read the reg key, either it's not there or we don't have access to the registry
-		//If we are vista then assume we don't have access and we are running as a limited app
-		//otherwise we are xp and the reg key probably doesn't exist and we are not a limited running app
-		if(IsVista())
-		{
-			OutputDebugString(_T("Ditto - Failed to read registry entry finding UAC, Running as limited application"));
-			return true;
-		}
-	}
-
-	if(dwValue == 1)
-	{
-		OutputDebugString(_T("Ditto - UAC ENABLED, Running as limited application"));
-		return true;
-	}
-
-	OutputDebugString(_T("Ditto - Running as standard application"));	
-	return false;
+#include "stdafx.h"
+#include "CP_Main.h"
+#include "Misc.h"
+#include "OptionsSheet.h"
+#include "TextConvert.h"
+#include "AlphaBlend.h"
+#include "Tlhelp32.h"
+
+CString GetIPAddress()
+{
+	WORD wVersionRequested;
+    WSADATA wsaData;
+    char name[255];
+    CString IP;
+	PHOSTENT hostinfo;
+	wVersionRequested = MAKEWORD(2,0);
+	
+	if (WSAStartup(wVersionRequested, &wsaData)==0)
+	{
+		if(gethostname(name, sizeof(name))==0)
+		{
+			if((hostinfo=gethostbyname(name)) != NULL)
+			{
+				IP = inet_ntoa(*(struct in_addr*)* hostinfo->h_addr_list);
+			}
+		}
+		
+		WSACleanup();
+	} 
+	IP.MakeUpper();
+
+	return IP;
+}
+
+CString GetComputerName()
+{
+	TCHAR ComputerName[MAX_COMPUTERNAME_LENGTH+1] = _T("");
+	DWORD Size=MAX_COMPUTERNAME_LENGTH+1;
+	GetComputerName(ComputerName, &Size);
+
+	CString cs(ComputerName);
+	cs.MakeUpper();
+
+	return cs;
+}
+
+void AppendToFile(const TCHAR* fn, const TCHAR* msg)
+{
+#ifdef _UNICODE
+	FILE *file = _wfopen(fn, _T("a"));
+#else
+	FILE *file = fopen(fn, _T("a"));
+#endif
+
+	ASSERT( file );
+
+#ifdef _UNICODE
+	fwprintf(file, msg);
+#else
+	fprintf(file, msg);
+#endif
+
+	fclose(file);
+}
+
+void log(const TCHAR* msg, bool bFromSendRecieve, CString csFile, long lLine)
+{
+	ASSERT(AfxIsValidString(msg));
+	CTime	time = CTime::GetCurrentTime();
+	CString	csText = time.Format("[%Y/%m/%d %I:%M:%S %p - ");
+
+	CString csFileLine;
+	csFile = GetFileName(csFile);
+	csFileLine.Format(_T("%s %d] "), csFile, lLine);
+	csText += csFileLine;
+	
+	csText += msg;
+	csText += "\n";
+
+#ifndef _DEBUG
+	if(CGetSetOptions::m_bOutputDebugString)
+#endif
+	{
+		OutputDebugString(csText);
+	}
+
+#ifndef _DEBUG
+	if(!bFromSendRecieve)
+	{
+		if(!g_Opt.m_bEnableDebugLogging)
+			return;
+	}
+#endif
+	
+	CString csExeFile = CGetSetOptions::GetPath(PATH_LOG_FILE);
+	csExeFile += "Ditto.log";
+
+	AppendToFile(csExeFile, csText);
+}
+
+void logsendrecieveinfo(CString cs, CString csFile, long lLine)
+{
+	if(g_Opt.m_bLogSendReceiveErrors)
+		log(cs, true, csFile, lLine);
+}
+
+CString GetErrorString( int err )
+{
+	CString str;
+	LPVOID lpMsgBuf;
+	
+	::FormatMessage( 
+		FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
+		NULL,
+		err,
+		MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
+		(LPTSTR) &lpMsgBuf,
+		0,
+		NULL 
+		);
+	str = (LPCTSTR) lpMsgBuf;
+	// Display the string.
+	//  ::MessageBox( NULL, lpMsgBuf, "GetLastError", MB_OK|MB_ICONINFORMATION );
+	::LocalFree( lpMsgBuf );
+	return str;
+}
+
+CString StrF(const TCHAR * pszFormat, ...)
+{
+	ASSERT( AfxIsValidString( pszFormat ) );
+	CString str;
+	va_list argList;
+	va_start( argList, pszFormat );
+	str.FormatV( pszFormat, argList );
+	va_end( argList );
+	return str;
+}
+
+BYTE GetEscapeChar( BYTE ch )
+{
+	switch(ch)
+	{
+	case '\'':	return '\''; // Single quotation mark (') = 39 or 0x27
+	case '\"':	return '\"'; // Double quotation mark (") = 34 or 0x22
+	case '?':	return '\?'; // Question mark (?) = 63 or 0x3f
+	case '\\':	return '\\'; // Backslash (\) = 92 or 0x5c
+	case 'a':	return '\a'; // Alert (BEL) = 7
+	case 'b':	return '\b'; // Backspace (BS) = 8
+	case 'f':	return '\f'; // Formfeed (FF) = 12 or 0x0c
+	case 'n':	return '\n'; // Newline (NL or LF) = 10 or 0x0a
+	case 'r':	return '\r'; // Carriage Return (CR) = 13 or 0x0d
+	case 't':	return '\t'; // Horizontal tab (HT) = 9
+	case 'v':	return '\v'; // Vertical tab (VT) = 11 or 0x0b
+	case '0':	return '\0'; // Null character (NUL) = 0
+	}
+	return 0; // invalid
+}
+
+CString RemoveEscapes( const TCHAR* str )
+{
+	ASSERT( str );
+	CString ret;
+	TCHAR* pSrc = (TCHAR*) str;
+	TCHAR* pDest = ret.GetBuffer(STRLEN(pSrc));
+	TCHAR* pStart = pDest;
+	while( *pSrc != '\0' )
+	{
+		if( *pSrc == '\\' )
+		{
+			pSrc++;
+			*pDest = GetEscapeChar((BYTE)pSrc );
+		}
+		else
+			*pDest = *pSrc;
+		pSrc++;
+		pDest++;
+	}
+	ret.ReleaseBuffer( pDest - pStart );
+	return ret;
+}
+
+CString GetWndText( HWND hWnd )
+{
+	CString text;
+	if( !IsWindow(hWnd) )
+		return "! NOT A VALID WINDOW !";
+	CWnd* pWnd = CWnd::FromHandle(hWnd);
+	pWnd->GetWindowText(text);
+	return text;
+}
+
+bool IsAppWnd( HWND hWnd )
+{
+	DWORD dwMyPID = ::GetCurrentProcessId();
+	DWORD dwTestPID;
+	::GetWindowThreadProcessId( hWnd, &dwTestPID );
+	return dwMyPID == dwTestPID;
+}
+
+/*----------------------------------------------------------------------------*\
+Global Memory Helper Functions
+\*----------------------------------------------------------------------------*/
+
+// make sure the given HGLOBAL is valid.
+BOOL IsValid( HGLOBAL hGlobal )
+{
+	void* pvData = ::GlobalLock( hGlobal );
+	::GlobalUnlock( hGlobal );
+	return ( pvData != NULL );
+}
+
+// asserts if hDest isn't big enough
+void CopyToGlobalHP( HGLOBAL hDest, LPVOID pBuf, ULONG ulBufLen )
+{
+	ASSERT( hDest && pBuf && ulBufLen );
+	LPVOID pvData = GlobalLock(hDest);
+	ASSERT( pvData );
+	ULONG size = GlobalSize(hDest);
+	ASSERT( size >= ulBufLen );	// assert if hDest isn't big enough
+	memcpy(pvData, pBuf, ulBufLen);
+	GlobalUnlock(hDest);
+}
+
+void CopyToGlobalHH( HGLOBAL hDest, HGLOBAL hSource, ULONG ulBufLen )
+{
+	ASSERT( hDest && hSource && ulBufLen );
+	LPVOID pvData = GlobalLock(hSource);
+	ASSERT( pvData );
+	ULONG size = GlobalSize(hSource);
+	ASSERT( size >= ulBufLen );	// assert if hSource isn't big enough
+	CopyToGlobalHP(hDest, pvData, ulBufLen);
+	GlobalUnlock(hSource);
+}
+
+
+HGLOBAL NewGlobalP( LPVOID pBuf, UINT nLen )
+{
+	ASSERT( pBuf && nLen );
+	HGLOBAL hDest = GlobalAlloc( GMEM_MOVEABLE | GMEM_SHARE, nLen );
+	ASSERT( hDest );
+	CopyToGlobalHP( hDest, pBuf, nLen );
+	return hDest;
+}
+
+HGLOBAL NewGlobal(UINT nLen)
+{
+	ASSERT(nLen);
+	HGLOBAL hDest = GlobalAlloc(GMEM_MOVEABLE | GMEM_SHARE, nLen);
+	return hDest;
+}
+
+HGLOBAL NewGlobalH( HGLOBAL hSource, UINT nLen )
+{
+	ASSERT( hSource && nLen );
+	LPVOID pvData = GlobalLock( hSource );
+	HGLOBAL hDest = NewGlobalP( pvData, nLen );
+	GlobalUnlock( hSource );
+	return hDest;
+}
+
+int CompareGlobalHP(HGLOBAL hLeft, LPVOID pBuf, ULONG ulBufLen)
+{
+	ASSERT(hLeft && pBuf && ulBufLen);
+
+	LPVOID pvData = GlobalLock(hLeft);
+	
+	ASSERT(pvData);
+	ASSERT(ulBufLen <= GlobalSize(hLeft));
+
+	int result = memcmp(pvData, pBuf, ulBufLen);
+	
+	GlobalUnlock(hLeft);
+
+	return result;
+}
+
+int CompareGlobalHH( HGLOBAL hLeft, HGLOBAL hRight, ULONG ulBufLen )
+{
+	ASSERT( hLeft && hRight && ulBufLen );
+	ASSERT( ulBufLen <= GlobalSize(hRight) );
+	LPVOID pvData = GlobalLock(hRight);
+	ASSERT( pvData );
+	int result = CompareGlobalHP( hLeft, pvData, ulBufLen );
+	GlobalUnlock( hLeft );
+	return result;
+}
+
+
+//Do not change these these are stored in the database
+CLIPFORMAT GetFormatID(LPCTSTR cbName)
+{
+	if(STRCMP(cbName, _T("CF_TEXT")) == 0)
+		return CF_TEXT;
+	else if(STRCMP(cbName, _T("CF_METAFILEPICT")) == 0)
+		return CF_METAFILEPICT;
+	else if(STRCMP(cbName, _T("CF_SYLK")) == 0)
+		return CF_SYLK;
+	else if(STRCMP(cbName, _T("CF_DIF")) == 0)
+		return CF_DIF;
+	else if(STRCMP(cbName, _T("CF_TIFF")) == 0)
+		return CF_TIFF;
+	else if(STRCMP(cbName, _T("CF_OEMTEXT")) == 0)
+		return CF_OEMTEXT;
+	else if(STRCMP(cbName, _T("CF_DIB")) == 0)
+		return CF_DIB;
+	else if(STRCMP(cbName, _T("CF_PALETTE")) == 0)
+		return CF_PALETTE;
+	else if(STRCMP(cbName, _T("CF_PENDATA")) == 0)
+		return CF_PENDATA;
+	else if(STRCMP(cbName, _T("CF_RIFF")) == 0)
+		return CF_RIFF;
+	else if(STRCMP(cbName, _T("CF_WAVE")) == 0)
+		return CF_WAVE;
+	else if(STRCMP(cbName, _T("CF_UNICODETEXT")) == 0)
+		return CF_UNICODETEXT;
+	else if(STRCMP(cbName, _T("CF_ENHMETAFILE")) == 0)
+		return CF_ENHMETAFILE;
+	else if(STRCMP(cbName, _T("CF_HDROP")) == 0)
+		return CF_HDROP;
+	else if(STRCMP(cbName, _T("CF_LOCALE")) == 0)
+		return CF_LOCALE;
+	else if(STRCMP(cbName, _T("CF_OWNERDISPLAY")) == 0)
+		return CF_OWNERDISPLAY;
+	else if(STRCMP(cbName, _T("CF_DSPTEXT")) == 0)
+		return CF_DSPTEXT;
+	else if(STRCMP(cbName, _T("CF_DSPBITMAP")) == 0)
+		return CF_DSPBITMAP;
+	else if(STRCMP(cbName, _T("CF_DSPMETAFILEPICT")) == 0)
+		return CF_DSPMETAFILEPICT;
+	else if(STRCMP(cbName, _T("CF_DSPENHMETAFILE")) == 0)
+		return CF_DSPENHMETAFILE;
+	
+	
+	return ::RegisterClipboardFormat(cbName);
+}
+
+//Do not change these these are stored in the database
+CString GetFormatName(CLIPFORMAT cbType)
+{
+	switch(cbType)
+	{
+	case CF_TEXT:
+		return _T("CF_TEXT");
+	case CF_BITMAP:
+		return _T("CF_BITMAP");
+	case CF_METAFILEPICT:
+		return _T("CF_METAFILEPICT");
+	case CF_SYLK:
+		return _T("CF_SYLK");
+	case CF_DIF:
+		return _T("CF_DIF");
+	case CF_TIFF:
+		return _T("CF_TIFF");
+	case CF_OEMTEXT:
+		return _T("CF_OEMTEXT");
+	case CF_DIB:
+		return _T("CF_DIB");
+	case CF_PALETTE:
+		return _T("CF_PALETTE");
+	case CF_PENDATA:
+		return _T("CF_PENDATA");
+	case CF_RIFF:
+		return _T("CF_RIFF");
+	case CF_WAVE:
+		return _T("CF_WAVE");
+	case CF_UNICODETEXT:
+		return _T("CF_UNICODETEXT");
+	case CF_ENHMETAFILE:
+		return _T("CF_ENHMETAFILE");
+	case CF_HDROP:
+		return _T("CF_HDROP");
+	case CF_LOCALE:
+		return _T("CF_LOCALE");
+	case CF_OWNERDISPLAY:
+		return _T("CF_OWNERDISPLAY");
+	case CF_DSPTEXT:
+		return _T("CF_DSPTEXT");
+	case CF_DSPBITMAP:
+		return _T("CF_DSPBITMAP");
+	case CF_DSPMETAFILEPICT:
+		return _T("CF_DSPMETAFILEPICT");
+	case CF_DSPENHMETAFILE:
+		return _T("CF_DSPENHMETAFILE");
+	default:
+		//Not a default type get the name from the clipboard
+		if (cbType != 0)
+		{
+			TCHAR szFormat[256];
+            GetClipboardFormatName(cbType, szFormat, 256);
+			return szFormat;
+		}
+		break;
+	}
+	
+	return "ERROR";
+}
+
+CString GetFilePath(CString csFileName)
+{
+	long lSlash = csFileName.ReverseFind('\\');
+	
+	if(lSlash > -1)
+	{
+		csFileName = csFileName.Left(lSlash + 1);
+	}
+	
+	return csFileName;
+}
+
+CString GetFileName(CString csFileName)
+{
+	long lSlash = csFileName.ReverseFind('\\');
+	if(lSlash > -1)
+	{
+		csFileName = csFileName.Right(csFileName.GetLength() - lSlash - 1);
+	}
+
+	return csFileName;
+}
+
+
+/****************************************************************************************************
+BOOL CALLBACK MyMonitorEnumProc(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData)
+***************************************************************************************************/
+typedef struct
+{
+	long	lFlags;				// Flags
+	LPRECT	pVirtualRect;		// Ptr to rect that receives the results, or the src of the monitor search method
+	int		iMonitor;			// Ndx to the mointor to look at, -1 for all, -or- result of the monitor search method
+	int		nMonitorCount;		// Total number of monitors found, -1 for monitor search method
+}	MONITOR_ENUM_PARAM;
+#define	MONITOR_SEARCH_METOHD	0x00000001
+BOOL CALLBACK MyMonitorEnumProc(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData)
+{
+	// Typecast param
+	MONITOR_ENUM_PARAM* pParam = (MONITOR_ENUM_PARAM*)dwData;
+	if(pParam)
+	{
+		// If a dest rect was passed
+		if(pParam->pVirtualRect)
+		{
+			// If MONITOR_SEARCH_METOHD then we are being asked for the index of the monitor
+			// that the rect falls inside of
+			if(pParam->lFlags & MONITOR_SEARCH_METOHD)
+			{
+				if(	(pParam->pVirtualRect->right	< lprcMonitor->left)	||
+					(pParam->pVirtualRect->left		> lprcMonitor->right)	||
+					(pParam->pVirtualRect->bottom	< lprcMonitor->top)		||
+					(pParam->pVirtualRect->top		> lprcMonitor->bottom))
+				{
+					// Nothing
+				}
+				else
+				{
+					// This is the one
+					pParam->iMonitor = pParam->nMonitorCount;
+					
+					// Stop the enumeration
+					return FALSE;
+				}
+			}
+			else
+			{
+				if(pParam->iMonitor == pParam->nMonitorCount)
+				{
+					*pParam->pVirtualRect = *lprcMonitor;
+				}
+				else
+					if(pParam->iMonitor == -1)
+					{
+						pParam->pVirtualRect->left = min(pParam->pVirtualRect->left, lprcMonitor->left);
+						pParam->pVirtualRect->top = min(pParam->pVirtualRect->top, lprcMonitor->top);
+						pParam->pVirtualRect->right = max(pParam->pVirtualRect->right, lprcMonitor->right);
+						pParam->pVirtualRect->bottom = max(pParam->pVirtualRect->bottom, lprcMonitor->bottom);
+					}
+			}
+		}
+		
+		// Up the count if necessary
+		pParam->nMonitorCount++;
+	}
+	return TRUE;
+}
+
+int GetScreenWidth(void)
+{
+	OSVERSIONINFO OS_Version_Info;
+	DWORD dwPlatform = 0;
+	
+	if(GetVersionEx(&OS_Version_Info) != 0)
+	{
+		dwPlatform = OS_Version_Info.dwPlatformId;
+	}
+	
+	if(dwPlatform == VER_PLATFORM_WIN32_NT)
+	{
+		int width, height;
+		
+		width = GetSystemMetrics(SM_CXSCREEN);
+		height = GetSystemMetrics(SM_CYSCREEN);
+		switch(width)
+		{
+		default:
+		case 640:
+		case 800:
+		case 1024:
+			return(width);
+		case 1280:
+			if(height == 480)
+			{
+				return(width / 2);
+			}
+			return(width);
+		case 1600:
+			if(height == 600)
+			{
+				return(width / 2);
+			}
+			return(width);
+		case 2048:
+			if(height == 768)
+			{
+				return(width / 2);
+			}
+			return(width);
+		}
+	}
+	else
+	{
+		return(GetSystemMetrics(SM_CXSCREEN));
+	}
+}
+
+int GetScreenHeight(void)
+{
+	OSVERSIONINFO OS_Version_Info;
+	DWORD dwPlatform = 0;
+	
+	if(GetVersionEx(&OS_Version_Info) != 0)
+	{
+		dwPlatform = OS_Version_Info.dwPlatformId;
+	}
+	
+	if(dwPlatform == VER_PLATFORM_WIN32_NT)
+	{
+		int width, height;
+		
+		width = GetSystemMetrics(SM_CXSCREEN);
+		height = GetSystemMetrics(SM_CYSCREEN);
+		switch(height)
+		{
+		default:
+		case 480:
+		case 600:
+		case 768:
+			return(height);
+		case 960:
+			if(width == 640)
+			{
+				return(height / 2);
+			}
+			return(height);
+		case 1200:
+			if(width == 800)
+			{
+				return(height / 2);
+			}
+			return(height);
+		case 1536:
+			if(width == 1024)
+			{
+				return(height / 2);
+			}
+			return(height);
+		}
+	}
+	else
+	{
+		return(GetSystemMetrics(SM_CYSCREEN));
+	}
+}
+
+int GetMonitorFromRect(LPRECT lpMonitorRect)
+{
+	// Build up the param
+	MONITOR_ENUM_PARAM	EnumParam;
+	ZeroMemory(&EnumParam, sizeof(EnumParam));
+	EnumParam.lFlags = MONITOR_SEARCH_METOHD;
+	EnumParam.pVirtualRect = lpMonitorRect;
+	EnumParam.iMonitor = -1;
+	
+	// Enum Displays
+	EnumDisplayMonitors(NULL, NULL, MyMonitorEnumProc, (long)&EnumParam);
+	
+	// Return the result
+	return EnumParam.iMonitor;
+}
+
+void GetMonitorRect(int iMonitor, LPRECT lpDestRect)
+{
+	// Build up the param
+	MONITOR_ENUM_PARAM	EnumParam;
+	ZeroMemory(&EnumParam, sizeof(EnumParam));
+	EnumParam.iMonitor = iMonitor;
+	EnumParam.pVirtualRect = lpDestRect;
+	
+	// Zero out dest rect
+	lpDestRect->bottom = lpDestRect->left = lpDestRect->right = lpDestRect->top = 0;
+	
+	// Enum Displays
+	EnumDisplayMonitors(NULL, NULL, MyMonitorEnumProc, (long)&EnumParam);
+	
+	// If not successful, default to the screen dimentions
+	if(lpDestRect->right == 0 || lpDestRect->bottom == 0)
+	{
+		lpDestRect->right = GetScreenWidth();
+		lpDestRect->bottom = GetScreenHeight();
+	}
+}
+
+/*------------------------------------------------------------------*\
+ID based Globals
+\*------------------------------------------------------------------*/
+
+long NewGroupID(long lParentID, CString text)
+{
+	long lID=0;
+	CTime time;
+	time = CTime::GetCurrentTime();
+	
+	try
+	{
+		//sqlite doesn't like single quotes ' replace them with double ''
+		if(text.IsEmpty())
+			text = time.Format("NewGroup %y/%m/%d %H:%M:%S");
+		text.Replace(_T("'"), _T("''"));
+
+		CString cs;
+		cs.Format(_T("insert into Main values(NULL, %d, '%s', 0, %d, 0, 1, %d, '');"),
+							(long)time.GetTime(),
+							text,
+							(long)time.GetTime(),
+							lParentID);
+
+		theApp.m_db.execDML(cs);
+
+		lID = (long)theApp.m_db.lastRowId();
+	}
+	CATCH_SQLITE_EXCEPTION_AND_RETURN(0)
+	
+	return lID;
+}
+
+BOOL DeleteAllIDs()
+{
+	try
+	{
+		theApp.m_db.execDML(_T("DELETE FROM Data;"));
+		theApp.m_db.execDML(_T("DELETE FROM Main;"));
+	}
+	CATCH_SQLITE_EXCEPTION
+
+	return TRUE;
+}
+
+BOOL DeleteFormats(long lParentID, ARRAY& formatIDs)
+{	
+	if(formatIDs.GetSize() <= 0)
+		return TRUE;
+		
+	try
+	{
+		//Delete the requested data formats
+		int nCount = formatIDs.GetSize();
+		for(int i = 0; i < nCount; i++)
+		{
+			theApp.m_db.execDMLEx(_T("DELETE FROM Data WHERE lID = %d;"), formatIDs[i]);
+		}
+
+		CClip clip;
+		if(clip.LoadFormats(lParentID))
+		{
+			DWORD CRC = clip.GenerateCRC();
+
+			//Update the main table with new size
+			theApp.m_db.execDMLEx(_T("UPDATE Main SET CRC = %d WHERE lID = %d"), CRC, lParentID);
+		}
+	}
+	CATCH_SQLITE_EXCEPTION
+		
+	return TRUE;
+}
+
+BOOL EnsureWindowVisible(CRect *pcrRect)
+{
+	int nMonitor = GetMonitorFromRect(pcrRect);
+	if(nMonitor < 0)
+	{
+		GetMonitorRect(0, pcrRect);
+		pcrRect->right = pcrRect->left + 300;
+		pcrRect->bottom = pcrRect->top + 300;
+
+		return TRUE;
+	}
+
+	CRect crMonitor;
+	GetMonitorRect(nMonitor, crMonitor);
+
+	//Validate the left
+	long lDiff = pcrRect->left - crMonitor.left;
+	if(lDiff < 0)
+	{
+		pcrRect->left += abs(lDiff);
+		pcrRect->right += abs(lDiff);
+	}
+
+	//Right side
+	lDiff = pcrRect->right - crMonitor.right;
+	if(lDiff > 0)
+	{
+		pcrRect->left -= abs(lDiff);
+		pcrRect->right -= abs(lDiff);
+	}
+
+	//Top
+	lDiff = pcrRect->top - crMonitor.top;
+	if(lDiff < 0)
+	{
+		pcrRect->top += abs(lDiff);
+		pcrRect->bottom += abs(lDiff);
+	}
+
+	//Bottom
+	lDiff = pcrRect->bottom - crMonitor.bottom;
+	if(lDiff > 0)
+	{
+		pcrRect->top -= abs(lDiff);
+		pcrRect->bottom -= abs(lDiff);
+	}
+
+	return TRUE;
+}
+
+__int64 GetLastWriteTime(const CString &csFile)
+{
+	__int64 nLastWrite = 0;
+	CFileFind finder;
+	BOOL bResult = finder.FindFile(csFile);
+
+	if (bResult)
+	{
+		finder.FindNextFile();
+
+		FILETIME ft;
+		finder.GetLastWriteTime(&ft);
+
+		memcpy(&nLastWrite, &ft, sizeof(ft));
+	}
+
+	return nLastWrite;
+}
+
+CString GetProcessName(HWND hWnd) 
+{
+	DWORD Id;
+	GetWindowThreadProcessId(hWnd, &Id);
+
+	PROCESSENTRY32 processEntry = { 0 };
+
+	HANDLE hSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
+	processEntry.dwSize = sizeof(PROCESSENTRY32);
+
+	if (Process32First(hSnapShot, &processEntry)) 
+	{
+		do 
+		{
+			if (processEntry.th32ProcessID == Id) 
+			{
+				return processEntry.szExeFile;
+			}
+		} while(Process32Next(hSnapShot, &processEntry));
+	}
+	CloseHandle(hSnapShot);
+
+	return "";
+}
+
+BOOL IsVista()
+{
+	OSVERSIONINFO osver;
+
+	osver.dwOSVersionInfoSize = sizeof( OSVERSIONINFO );
+
+	if (::GetVersionEx( &osver ) && 
+		osver.dwPlatformId == VER_PLATFORM_WIN32_NT && 
+		(osver.dwMajorVersion >= 6 ) )
+	{
+		return TRUE;
+	}
+
+	return FALSE;
+}
+
+bool IsRunningLimited()
+{
+	LPCTSTR pszSubKey = _T("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Policies\\System");
+	LPCTSTR pszValue = _T("EnableLUA");
+	DWORD dwType = 0;
+	DWORD dwValue = 0;
+	DWORD dwValueSize = sizeof(DWORD);
+
+	if(ERROR_SUCCESS != SHGetValue(HKEY_LOCAL_MACHINE, pszSubKey, pszValue, &dwType, &dwValue, &dwValueSize))
+	{
+		//failed to read the reg key, either it's not there or we don't have access to the registry
+		//If we are vista then assume we don't have access and we are running as a limited app
+		//otherwise we are xp and the reg key probably doesn't exist and we are not a limited running app
+		if(IsVista())
+		{
+			OutputDebugString(_T("Ditto - Failed to read registry entry finding UAC, Running as limited application"));
+			return true;
+		}
+	}
+
+	if(dwValue == 1)
+	{
+		OutputDebugString(_T("Ditto - UAC ENABLED, Running as limited application"));
+		return true;
+	}
+
+	OutputDebugString(_T("Ditto - Running as standard application"));	
+	return false;
+}
+
+void DeleteReceivedFiles(CString csDir)
+{
+	if(csDir.Find(_T("\\ReceivedFiles\\")) == -1)
+		return;
+
+	FIX_CSTRING_PATH(csDir);
+
+	CTime ctOld = CTime::GetCurrentTime();
+	CTime ctFile;
+	ctOld -= CTimeSpan(0, 0, 0, 1);
+
+	CFileFind Find;
+
+	CString csFindString;
+	csFindString.Format(_T("%s*.*"), csDir);
+
+	BOOL bFound = Find.FindFile(csFindString);
+	while(bFound)
+	{
+		bFound = Find.FindNextFile();
+
+		if(Find.IsDots())
+			continue;
+
+		if(Find.IsDirectory())
+		{
+			CString csDir(Find.GetFilePath());
+			DeleteReceivedFiles(csDir);
+			RemoveDirectory(csDir);
+		}
+
+		if(Find.GetLastAccessTime(ctFile))
+		{
+			//Delete the remote copied file if it has'nt been used for the last day
+			if(ctFile < ctOld)
+			{
+				DeleteFile(Find.GetFilePath());
+			}
+		}
+		else
+		{
+			DeleteFile(Find.GetFilePath());
+		}
+	}
 }

+ 3 - 146
Misc.h

@@ -7,7 +7,6 @@
 #endif // _MSC_VER > 1000
 
 #include "ArrayEx.h"
-#include <vector>
 
 #define ONE_MINUTE				60000
 #define ONE_HOUR				3600000
@@ -101,7 +100,6 @@ CString GetProcessName(HWND hWnd);
 #define WM_SHOW_TRAY_ICON		WM_USER + 200
 #define WM_SETCONNECT			WM_USER + 201
 #define WM_CV_IS_CONNECTED		WM_USER + 202
-#define WM_COPYPROPERTIES		WM_USER + 203
 #define WM_CLOSE_APP			WM_USER + 204
 #define WM_REFRESH_VIEW			WM_USER + 205
 #define WM_CLIPBOARD_COPIED		WM_USER + 206
@@ -111,156 +109,13 @@ CString GetProcessName(HWND hWnd);
 #define WM_CV_GETCONNECT		WM_USER + 211
 #define WM_EDIT_WND_CLOSING		WM_USER	+ 212
 #define WM_SET_CONNECTED		WM_USER	+ 213
+#define WM_LOAD_ClIP_ON_CLIPBOARD		WM_USER	+ 214
 //defined in tray icon #define WM_CUSTOMIZE_TRAY_MENU	WM_USER + 211
 
-
-
-/*------------------------------------------------------------------*\
-	CHotKey - a single system-wide hotkey
-\*------------------------------------------------------------------*/
-
-class CHotKey
-{
-public:
-	CString	m_Name;
-	ATOM	m_Atom;
-	DWORD	m_Key; //704 is ctrl-tilda
-	bool	m_bIsRegistered;
-	bool	m_bUnRegisterOnShowDitto;
-	
-	CHotKey( CString name, DWORD defKey = 0, bool bUnregOnShowDitto = false );
-	~CHotKey();
-
-	bool	IsRegistered() { return m_bIsRegistered; }
-	CString GetName()      { return m_Name; }
-	DWORD   GetKey()       { return m_Key; }
-
-	void SetKey( DWORD key, bool bSave = false );
-	// profile
-	void LoadKey();
-	bool SaveKey();
-
-	void CopyFromCtrl(CHotKeyCtrl& ctrl, HWND hParent, int nWindowsCBID);
-	void CopyToCtrl(CHotKeyCtrl& ctrl, HWND hParent, int nWindowsCBID);
-
-//	CString GetKeyAsText();
-//	void SetKeyFromText( CString text );
-
-	static BOOL ValidateHotKey(DWORD dwHotKey);
-	static UINT GetModifier(DWORD dwHotKey);
-	UINT GetModifier() { return GetModifier(m_Key); }
-
-	bool Register();
-	bool Unregister(bool bOnShowingDitto = false);
-};
-
-
-/*------------------------------------------------------------------*\
-	CHotKeys - Manages system-wide hotkeys
-\*------------------------------------------------------------------*/
-
-class CHotKeys : public CArray<CHotKey*,CHotKey*>
-{
-public:
-	HWND	m_hWnd;
-
-	CHotKeys();
-	~CHotKeys();
-
-	void Init( HWND hWnd ) { m_hWnd = hWnd; }
-
-	int Find( CHotKey* pHotKey );
-	bool Remove( CHotKey* pHotKey ); // pHotKey is NOT deleted.
-
-	// profile load / save
-	void LoadAllKeys();
-	void SaveAllKeys();
-
-	void RegisterAll(bool bMsgOnError = false);
-	void UnregisterAll(bool bMsgOnError = false, bool bOnShowDitto = false);
-
-	void GetKeys( ARRAY& keys );
-	void SetKeys( ARRAY& keys, bool bSave = false ); // caution! this alters hotkeys based upon corresponding indexes
-
-	static bool FindFirstConflict( ARRAY& keys, int* pX = NULL, int* pY = NULL );
-	// if true, pX and pY (if valid) are set to the index of the conflicting hotkeys.
-	bool FindFirstConflict( int* pX = NULL, int* pY = NULL );
-};
-
-extern CHotKeys g_HotKeys;
-
-/*------------------------------------------------------------------*\
-	CAccel - an Accelerator (in-app hotkey)
-
-    - the win32 CreateAcceleratorTable using ACCEL was insufficient
-    because it only allowed a WORD for the cmd associated with it.
-\*------------------------------------------------------------------*/
-
-#define ACCEL_VKEY(key)			LOBYTE(key)
-#define ACCEL_MOD(key)			HIBYTE(key)
-#define ACCEL_MAKEKEY(vkey,mod) ((mod << 8) | vkey)
-
-class CAccel
-{
-public:
-	DWORD	Key; // directly uses the CHotKeyCtrl format
-	DWORD	Cmd;
-	CAccel( DWORD key=0, DWORD cmd=0 ) { Key = key;  Cmd = cmd; } 
-};
-
-/*------------------------------------------------------------------*\
-	CAccels - Manages a set of CAccel
-\*------------------------------------------------------------------*/
-class CAccels
-{
-public:
-	CAccels();
-
-	CMap<DWORD, DWORD, DWORD, DWORD> m_Map;
-
-	void AddAccel( CAccel& a );
-
-	// handles a key's first WM_KEYDOWN or WM_SYSKEYDOWN message.
-	// it uses GetKeyState to test for modifiers.
-	// returns a pointer to the internal CAccel if it matches the given key or NULL
-	bool OnMsg( MSG* pMsg , DWORD &dID );
-};
-
-// returns a BYTE representing the current GetKeyState modifiers:
-//  HOTKEYF_SHIFT, HOTKEYF_CONTROL, HOTKEYF_ALT
-BYTE GetKeyStateModifiers();
-
-/*------------------------------------------------------------------*\
-	CTokenizer - Tokenizes a string using given delimiters
-\*------------------------------------------------------------------*/
-// Based upon:
-// Date:        Monday, October 22, 2001
-// Autor:       Eduardo Velasquez
-// Description: Tokenizer class for CStrings. Works like strtok.
-///////////////
-
 #if !defined(_BITSET_)
 #	include <bitset>
 #endif // !defined(_BITSET_)
 
-class CTokenizer
-{
-public:
-	CString m_cs;
-	CArrayEx<TCHAR> m_delim;
-	int m_nCurPos;
-
-	CTokenizer(const CString& cs, const CString& csDelim);
-	void SetDelimiters(const CString& csDelim);
-
-	bool Next(CString& cs);
-	CString	Tail();
-};
-
-
-/*------------------------------------------------------------------*\
-	ID based Globals
-\*------------------------------------------------------------------*/
 long NewGroupID(long lParentID = 0, CString text = "");
 BOOL DeleteAllIDs();
 BOOL DeleteFormats(long lDataID, ARRAY& formatIDs);
@@ -273,5 +128,7 @@ __inline BOOL FileExists(LPCTSTR pszFile)
 bool IsRunningLimited();
 BOOL IsVista();
 
+void DeleteReceivedFiles(CString csDir);
+
 
 #endif // !defined(AFX_CP_GUI_GLOBALS__FBCDED09_A6F2_47EB_873F_50A746EBC86B__INCLUDED_)

+ 6 - 0
OleClipSource.cpp

@@ -114,6 +114,8 @@ BOOL COleClipSource::DoImmediateRender()
 
 long COleClipSource::PutFormatOnClipboard(CClipFormats *pFormats)
 {
+	Log(_T("Start of put format on clipboard"));
+
 	CClipFormat* pCF;
 	int	count = pFormats->GetSize();
 	bool bDelayedRenderCF_HDROP = false;
@@ -146,6 +148,8 @@ long COleClipSource::PutFormatOnClipboard(CClipFormats *pFormats)
 			continue;
 		}
 
+		Log(StrF(_T("Setting clipboard type: %s to the clipboard"), GetFormatName(pCF->m_cfType)));
+
 		CacheGlobalData(pCF->m_cfType, pCF->m_hgData);
 		pCF->m_hgData = 0; // OLE owns it now
 	}
@@ -154,6 +158,8 @@ long COleClipSource::PutFormatOnClipboard(CClipFormats *pFormats)
 
 	m_bLoadedFormats = true;
 
+	Log(_T("End of put format on clipboard"));
+
 	return count;
 }  
 

+ 0 - 16
OptionsGeneral.cpp

@@ -52,7 +52,6 @@ void COptionsGeneral::DoDataExchange(CDataExchange* pDX)
 	DDX_Control(pDX, IDC_GET_PATH, m_btGetPath);
 	DDX_Control(pDX, IDC_PATH, m_ePath);
 	DDX_Control(pDX, IDC_SET_DB_PATH, m_btSetDatabasePath);
-	DDX_Control(pDX, IDC_CHECK_UPDATES, m_btCheckForUpdates);
 	DDX_Control(pDX, IDC_EXPIRE_AFTER, m_eExpireAfter);
 	DDX_Control(pDX, IDC_MAX_SAVED_COPIES, m_eMaxSavedCopies);
 	DDX_Control(pDX, IDC_MAXIMUM, m_btMaximumCheck);
@@ -71,7 +70,6 @@ void COptionsGeneral::DoDataExchange(CDataExchange* pDX)
 BEGIN_MESSAGE_MAP(COptionsGeneral, CPropertyPage)
 	//{{AFX_MSG_MAP(COptionsGeneral)
 	ON_BN_CLICKED(IDC_BT_COMPACT_AND_REPAIR, OnBtCompactAndRepair)
-	ON_BN_CLICKED(IDC_CHECK_FOR_UPDATES, OnCheckForUpdates)
 	ON_BN_CLICKED(IDC_SET_DB_PATH, OnSetDbPath)
 	ON_BN_CLICKED(IDC_GET_PATH, OnGetPath)
 	ON_BN_CLICKED(IDC_SELECT_SOUND, OnSelectSound)
@@ -93,7 +91,6 @@ BOOL COptionsGeneral::OnInitDialog()
 	m_btShowIconInSysTray.SetCheck(CGetSetOptions::GetShowIconInSysTray());
 	m_btMaximumCheck.SetCheck(CGetSetOptions::GetCheckForMaxEntries());
 	m_btExpire.SetCheck(CGetSetOptions::GetCheckForExpiredEntries());
-	m_btCheckForUpdates.SetCheck(CGetSetOptions::GetCheckForUpdates());
 	
 	m_eExpireAfter.SetNumber(CGetSetOptions::GetExpiredEntries());
 	m_eMaxSavedCopies.SetNumber(CGetSetOptions::GetMaxEntries());
@@ -146,7 +143,6 @@ BOOL COptionsGeneral::OnInitDialog()
 		m_btSetDatabasePath.EnableWindow(FALSE);
 		m_btGetPath.EnableWindow(FALSE);
 		m_ePath.SetWindowText(_T("U3 Device"));
-		m_btCheckForUpdates.ShowWindow(SW_HIDE);
 		::ShowWindow(::GetDlgItem(m_hWnd, IDC_CHECK_FOR_UPDATES), SW_HIDE);
 	}
 
@@ -201,7 +197,6 @@ BOOL COptionsGeneral::OnApply()
 	CGetSetOptions::SetRunOnStartUp(m_btRunOnStartup.GetCheck());
 	CGetSetOptions::SetCheckForMaxEntries(m_btMaximumCheck.GetCheck());
 	CGetSetOptions::SetCheckForExpiredEntries(m_btExpire.GetCheck());
-	CGetSetOptions::SetCheckForUpdates(m_btCheckForUpdates.GetCheck());
 	CGetSetOptions::SetHideDittoOnHotKeyIfAlreadyShown(m_btHideDittoOnHotKey.GetCheck());
 	CGetSetOptions::SetSendPasteAfterSelection(m_btSendPasteMessage.GetCheck());
 	CGetSetOptions::SetEnsureConnectToClipboard(m_EnsureConnected.GetCheck());
@@ -318,17 +313,6 @@ void COptionsGeneral::OnBtCompactAndRepair()
 	CATCH_SQLITE_EXCEPTION
 }
 
-void COptionsGeneral::OnCheckForUpdates() 
-{
-	CInternetUpdate update;
-
-	if(update.CheckForUpdate(m_hWnd, FALSE, TRUE))
-	{
-		::PostMessage(theApp.m_MainhWnd, WM_CLOSE_APP, 0, 0);
-		m_pParent->EndDialog(-1);
-	}
-}
-
 void COptionsGeneral::OnSetDbPath() 
 {
 	if(m_btSetDatabasePath.GetCheck() == BST_CHECKED)

+ 5 - 7
OptionsGeneral.h

@@ -29,21 +29,20 @@ public:
 	enum { IDD = IDD_OPTIONS_GENERAL };
 	CButton	m_EnsureConnected;
 	CNumberEdit	m_SaveDelay;
-	CComboBox	m_cbLanguage;
-	CEdit	m_MaxClipSize;
+	CComboBox m_cbLanguage;
+	CEdit m_MaxClipSize;
 	CButton	m_btSendPasteMessage;
 	CButton	m_btHideDittoOnHotKey;
 	CNumberEdit	m_DescTextSize;
 	CButton	m_btGetPath;
-	CEdit	m_ePath;
+	CEdit m_ePath;
 	CButton	m_btSetDatabasePath;
-	CButton	m_btCheckForUpdates;
 	CNumberEdit	m_eExpireAfter;
 	CNumberEdit	m_eMaxSavedCopies;
 	CButton	m_btMaximumCheck;
 	CButton	m_btExpire;
-	CButton		m_btShowIconInSysTray;
-	CButton		m_btRunOnStartup;
+	CButton m_btShowIconInSysTray;
+	CButton	m_btRunOnStartup;
 	CButton m_btAllowDuplicates;
 	CButton m_btUpdateTimeOnPaste;
 	CButton m_btSaveMultiPaste;
@@ -75,7 +74,6 @@ protected:
 	//{{AFX_MSG(COptionsGeneral)
 	virtual BOOL OnInitDialog();
 	afx_msg void OnBtCompactAndRepair();
-	afx_msg void OnCheckForUpdates();
 	afx_msg void OnSetDbPath();
 	afx_msg void OnGetPath();
 	afx_msg void OnSelectSound();

+ 0 - 18
OptionsKeyBoard.cpp

@@ -34,7 +34,6 @@ void COptionsKeyBoard::DoDataExchange(CDataExchange* pDX)
 {
 	CPropertyPage::DoDataExchange(pDX);
 	//{{AFX_DATA_MAP(COptionsKeyBoard)
-	DDX_Control(pDX, IDC_NAMED_PASTE, m_NamedPaste);
 	DDX_Control(pDX, IDC_CHECK_SEND_PASTE, m_btSendPaste);
 	DDX_Control(pDX, IDC_HOTKEY9, m_Nine);
 	DDX_Control(pDX, IDC_HOTKEY8, m_Eight);
@@ -46,7 +45,6 @@ void COptionsKeyBoard::DoDataExchange(CDataExchange* pDX)
 	DDX_Control(pDX, IDC_HOTKEY2, m_Two);
 	DDX_Control(pDX, IDC_HOTKEY10, m_Ten);
 	DDX_Control(pDX, IDC_HOTKEY1, m_One);
-	DDX_Control(pDX, IDC_NAMED_COPY, m_NamedCopy);
 	DDX_Control(pDX, IDC_HOTKEY, m_HotKey);
 	//}}AFX_DATA_MAP
 	DDX_Control(pDX, IDC_STATIC_CUSTOM_KEYS, m_CustomeKeysHelp);
@@ -72,14 +70,6 @@ BOOL COptionsKeyBoard::OnInitDialog()
 
 	theApp.m_pDittoHotKey->CopyToCtrl(m_HotKey, m_hWnd, IDC_CHECK_WIN_DITTO);
 
-	//A U3 device is unable to use the keyboard hooks, so named paste and copy 
-	//can't be used
-	if(!g_Opt.m_bU3)
-	{
-		theApp.m_pNamedCopy->CopyToCtrl(m_NamedCopy, m_hWnd, IDC_CHECK_WIN_NAMED_COPY);
-		theApp.m_pNamedPaste->CopyToCtrl(m_NamedPaste, m_hWnd, IDC_CHECK_WIN_NAMED_PASTE);
-	}
-
 	theApp.m_pPosOne->CopyToCtrl(m_One, m_hWnd, IDC_CHECK_WIN1);
 	theApp.m_pPosTwo->CopyToCtrl(m_Two, m_hWnd, IDC_CHECK_WIN2);
 	theApp.m_pPosThree->CopyToCtrl(m_Three, m_hWnd, IDC_CHECK_WIN3);
@@ -138,14 +128,6 @@ BOOL COptionsKeyBoard::OnApply()
 	
 	theApp.m_pDittoHotKey->CopyFromCtrl(m_HotKey, m_hWnd, IDC_CHECK_WIN_DITTO);
 	
-	//A U3 device is unable to use the keyboard hooks, so named paste and copy 
-	//can't be used
-	if(!g_Opt.m_bU3)
-	{
-		theApp.m_pNamedCopy->CopyFromCtrl(m_NamedCopy, m_hWnd, IDC_CHECK_WIN_NAMED_COPY);
-		theApp.m_pNamedPaste->CopyFromCtrl(m_NamedPaste, m_hWnd, IDC_CHECK_WIN_NAMED_PASTE);
-	}
-	
 	theApp.m_pPosOne->CopyFromCtrl(m_One, m_hWnd, IDC_CHECK_WIN1);
 	theApp.m_pPosTwo->CopyFromCtrl(m_Two, m_hWnd, IDC_CHECK_WIN2);
 	theApp.m_pPosThree->CopyFromCtrl(m_Three, m_hWnd, IDC_CHECK_WIN3);

+ 0 - 2
OptionsKeyBoard.h

@@ -27,7 +27,6 @@ public:
 // Dialog Data
 	//{{AFX_DATA(COptionsKeyBoard)
 	enum { IDD = IDD_OPTIONS_KEYSTROKES };
-	CHotKeyCtrl	m_NamedPaste;
 	CButton	m_btSendPaste;
 	CHotKeyCtrl	m_Nine;
 	CHotKeyCtrl	m_Eight;
@@ -39,7 +38,6 @@ public:
 	CHotKeyCtrl	m_Two;
 	CHotKeyCtrl	m_Ten;
 	CHotKeyCtrl	m_One;
-	CHotKeyCtrl	m_NamedCopy;
 	CHotKeyCtrl	m_HotKey;
 	//}}AFX_DATA
 

+ 8 - 6
ProcessPaste.cpp

@@ -57,11 +57,13 @@ BOOL CProcessPaste::DoPaste()
 //#ifndef _DEBUG
 		if(m_bSendPaste)
 		{
+			Log(_T("Sending Paste to active window"));
 			theApp.m_activeWnd.SendPaste(m_bActivateTarget);
 		}
 //#else
 		if(m_bActivateTarget)
 		{
+			Log(_T("Activating active window"));
 			theApp.m_activeWnd.ActivateTarget();
 		}
 //#endif
@@ -84,7 +86,7 @@ BOOL CProcessPaste::DoDrag()
 
 void CProcessPaste::MarkAsPasted()
 {
-//	Log(_T("start of MarkAsPasted"));
+	Log(_T("start of MarkAsPasted"));
 
 	CClipIDs& clips = GetClipIDs();
 	if(clips.GetSize() == 1)
@@ -100,7 +102,7 @@ void CProcessPaste::MarkAsPasted()
 		AfxBeginThread(CProcessPaste::MarkAsPastedThread, (LPVOID)lID, THREAD_PRIORITY_LOWEST);
 	}
 
-//	Log(_T("End of MarkAsPasted"));
+	Log(_T("End of MarkAsPasted"));
 }
 
 UINT CProcessPaste::MarkAsPastedThread(LPVOID pParam)
@@ -108,7 +110,7 @@ UINT CProcessPaste::MarkAsPastedThread(LPVOID pParam)
 	static CEvent UpdateTimeEvent(TRUE, TRUE, _T("Ditto_Update_Clip_Time"), NULL);
 	UpdateTimeEvent.ResetEvent();
 
-//	Log(_T("Start of MarkAsPastedThread"));
+	Log(_T("Start of MarkAsPastedThread"));
 
 	//If running from a U3 device then wait a little before updating the db
 	//updating the db can take a second or two and it delays the act of pasting
@@ -141,17 +143,17 @@ UINT CProcessPaste::MarkAsPastedThread(LPVOID pParam)
 				}
 			}
 		}
-
 		CATCH_SQLITE_EXCEPTION
 
+		Log(StrF(_T("Setting clipId: %d, time: %d"), lID, now.GetTime()));
+
 		Local_db.execDMLEx(_T("UPDATE Main SET lDate = %d where lID = %d;"), (long)now.GetTime(), lID);
 		Local_db.close();
 		bRet = TRUE;
 	}
-
 	CATCH_SQLITE_EXCEPTION
 
-//	Log(_T("End of MarkAsPastedThread"));
+	Log(_T("End of MarkAsPastedThread"));
 
 	UpdateTimeEvent.SetEvent();
 	return bRet;

+ 0 - 1
QListCtrl.cpp

@@ -1231,7 +1231,6 @@ HWND CQListCtrl::GetToolTipHWnd()
 
 BOOL CQListCtrl::SetItemCountEx(int iCount, DWORD dwFlags /* = LVSICF_NOINVALIDATEALL */)
 {
-	theApp.SetStatus(NULL, TRUE);
 	return CListCtrl::SetItemCountEx(iCount, dwFlags);
 }
 

+ 1 - 0
QListCtrl.h

@@ -11,6 +11,7 @@
 #include "FormattedTextDraw.h"
 #include "sqlite/CppSQLite3.h"
 #include "ClipFormatQListCtrl.h"
+#include "Accels.h"
 
 #define NM_SELECT					WM_USER+0x100
 #define NM_RIGHT					WM_USER+0x101

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 1503 - 1335
QPasteWnd.cpp


+ 235 - 264
QPasteWnd.h

@@ -1,11 +1,4 @@
-#if !defined(AFX_QPASTEWND_H__65261F0F_FEFD_48CF_A0CD_01D8BFEB353B__INCLUDED_)
-#define AFX_QPASTEWND_H__65261F0F_FEFD_48CF_A0CD_01D8BFEB353B__INCLUDED_
-
-#if _MSC_VER > 1000
 #pragma once
-#endif // _MSC_VER > 1000
-// QPasteWnd.h : header file
-//
 
 #include "QListCtrl.h"
 #include "SearchEditBox.h"
@@ -23,282 +16,260 @@
 class CMainTable
 {
 public:
-	CMainTable():
-		m_lID(-1),
-		m_bDontAutoDelete(false),
-		m_bIsGroup(false),
-		m_bHasShortCut(false),
-		m_bHasParent(false),
-		m_listIndex(-1),
-		m_hasCF_Dib(true),
-		m_hasCF_Rtf(true)
-	{
-	}
-	
-	~CMainTable()
+    CMainTable(): m_lID( - 1), m_bDontAutoDelete(false), m_bIsGroup(false), m_bHasShortCut(false), m_bHasParent(false), m_listIndex( - 1){}
+
+    ~CMainTable()
 	{
-		
-	}
 
-	long m_lID;
-	CString m_Desc;
-	bool m_bDontAutoDelete;
-	bool m_bIsGroup;
-	bool m_bHasShortCut;	
-	bool m_bHasParent;
-	CString m_QuickPaste;
-	int m_listIndex;
-	bool m_hasCF_Dib;
-	bool m_hasCF_Rtf;
+    }
+
+    long m_lID;
+    CString m_Desc;
+    bool m_bDontAutoDelete;
+    bool m_bIsGroup;
+    bool m_bHasShortCut;
+    bool m_bHasParent;
+    CString m_QuickPaste;
+    int m_listIndex;
 };
 
 
-typedef std::map<int, CMainTable> MainTypeMap;
-typedef std::map<int, CClipFormatQListCtrl> CF_DibTypeMap;
+typedef std::map < int, CMainTable > MainTypeMap;
+typedef std::map < int, CClipFormatQListCtrl > CF_DibTypeMap;
 
 
 
 /////////////////////////////////////////////////////////////////////////////
 // CQPasteWnd window
 
-class CQPasteWnd : public CWndEx
+class CQPasteWnd: public CWndEx
 {
-// Construction
+    // Construction
 public:
-	CQPasteWnd();
+    CQPasteWnd();
 
-// Attributes
+    // Attributes
 public:
 
-// Operations
+    // Operations
 public:
 
-// Overrides
-	// ClassWizard generated virtual function overrides
-	//{{AFX_VIRTUAL(CQPasteWnd)
-	public:
-	virtual BOOL Create(const POINT& ptStart, CWnd* pParentWnd);
-	virtual BOOL PreTranslateMessage(MSG* pMsg);
-	//}}AFX_VIRTUAL
-
-// Implementation
+    // Overrides
+    // ClassWizard generated virtual function overrides
+    //{{AFX_VIRTUAL(CQPasteWnd)
 public:
-	bool Add(const CString &csHeader, const CString &csText, int nID);
-	virtual ~CQPasteWnd();
-
-	void UpdateFont();
-
-//protected:
-	CQListCtrl		m_lstHeader;
-
-	CAlphaBlend		m_Alpha;
-	CFont			m_TitleFont;
-	CSearchEditBox	m_Search;
-	CFont			m_SearchFont;
-	CButton			m_btCancel;
-	bool			m_bHideWnd;
-	CString			m_strSQLSearch;
-	CGroupStatic	m_stGroup;
-	CFont			GroupFont;
-	CString			m_Title;
-	CGroupTree		m_GroupTree;
-	CBitmapButton	m_ShowGroupsFolderBottom;
-	CBitmapButton	m_ShowGroupsFolderTop;
-	CBitmapButton	m_BackButton;
-	bool			m_bAllowRepaintImmediately;
-
-	CString			m_SQL;
-	CString			m_CountSQL;
-	long			m_lRecordCount;
-	bool			m_bStopQuery;
-	bool			m_bHandleSearchTextChange;
-	bool			m_bFoundClipToSetFocusTo;
-	long			m_lItemsPerPage;
-	bool			m_bModifersMoveActive;
-
-	CQPasteWndThread m_thread;
-	MainTypeMap m_mapCache;
-	std::vector<CPoint> m_loadItems;
-	std::vector<CClipFormatQListCtrl> m_ExtraDataLoadItems;
-	CF_DibTypeMap m_cf_dibCache;
-	CF_DibTypeMap m_cf_rtfCache;
-	CCriticalSection m_CritSection;
-
-	CAccels m_MainAccels;
-	
-	void RefreshNc( bool bRepaintImmediately = false );
-	void UpdateStatus( bool bRepaintImmediately = false );  // regenerates the status (caption) text
-	BOOL FillList(CString csSQLSearch = "");
-	BOOL HideQPasteWindow();
-	BOOL ShowQPasteWindow(BOOL bFillList = TRUE);
-	void MoveControls();
-
-	void DeleteSelectedRows();
-
-	BOOL OpenID(long lID, bool bOnlyLoad_CF_TEXT = false, CClipFormats *pPasteFormats = NULL);
-	BOOL OpenSelection(bool bOnlyLoad_CF_TEXT = false);
-	BOOL OpenIndex( long nItem );
-	BOOL NewGroup( bool bGroupSelection = true );
+    virtual BOOL Create(const POINT &ptStart, CWnd *pParentWnd);
+    virtual BOOL PreTranslateMessage(MSG *pMsg);
+    //}}AFX_VIRTUAL
 
-	CString LoadDescription( int nItem );
-	bool SaveDescription( int nItem, CString text );
-
-	//Menu Items
-	void SetLinesPerRow(long lLines);
-	void SetTransparency(long lPercent);
-	void OnUpdateLinesPerRow(CCmdUI* pCmdUI, int nValue);
-	void OnUpdateTransparency(CCmdUI* pCmdUI, int nValue);
-	void SetMenuChecks(CMenu *pMenu);
-	void SetSendToMenu(CMenu *pMenu, int nMenuID, int nArrayPos);
-
-	BOOL SendToFriendbyPos(int nPos);
-
-	bool InsertNextNRecords(int nEnd);
-	
-	CString GetDisplayText(long lDontAutoDelete, long lShortCut, bool bIsGroup, long lParentID, CString csText);
-
-	void FillMainTable(CMainTable &table, CppSQLite3Query &q);
-	void RunThread();
-	void MoveSelection(bool down);
-	void OnKeyStateUp();
-	void SetKeyModiferState(bool bActive);
-
-	// Generated message map functions
+    // Implementation
+public:
+    bool Add(const CString &csHeader, const CString &csText, int nID);
+    virtual ~CQPasteWnd();
+
+    void UpdateFont();
+
+    //protected:
+    CQListCtrl m_lstHeader;
+
+    CAlphaBlend m_Alpha;
+    CFont m_TitleFont;
+    CSearchEditBox m_Search;
+    CFont m_SearchFont;
+    CButton m_btCancel;
+    bool m_bHideWnd;
+    CString m_strSQLSearch;
+    CGroupStatic m_stGroup;
+    CFont GroupFont;
+    CString m_Title;
+    CGroupTree m_GroupTree;
+    CBitmapButton m_ShowGroupsFolderBottom;
+    CBitmapButton m_ShowGroupsFolderTop;
+    CBitmapButton m_BackButton;
+    bool m_bAllowRepaintImmediately;
+
+    CString m_SQL;
+    CString m_CountSQL;
+    long m_lRecordCount;
+    bool m_bStopQuery;
+    bool m_bHandleSearchTextChange;
+    bool m_bFoundClipToSetFocusTo;
+    long m_lItemsPerPage;
+    bool m_bModifersMoveActive;
+
+    CQPasteWndThread m_thread;
+    MainTypeMap m_mapCache;
+    std::vector < CPoint > m_loadItems;
+    std::vector < CClipFormatQListCtrl > m_ExtraDataLoadItems;
+    CF_DibTypeMap m_cf_dibCache;
+    CF_DibTypeMap m_cf_rtfCache;
+    CCriticalSection m_CritSection;
+
+    CAccels m_MainAccels;
+
+    void RefreshNc(bool bRepaintImmediately = false);
+    void UpdateStatus(bool bRepaintImmediately = false); // regenerates the status (caption) text
+    BOOL FillList(CString csSQLSearch = "");
+    BOOL HideQPasteWindow();
+    BOOL ShowQPasteWindow(BOOL bFillList = TRUE);
+    void MoveControls();
+
+    void DeleteSelectedRows();
+
+    BOOL OpenID(long lID, bool bOnlyLoad_CF_TEXT = false, CClipFormats *pPasteFormats = NULL);
+    BOOL OpenSelection(bool bOnlyLoad_CF_TEXT = false);
+    BOOL OpenIndex(long nItem);
+    BOOL NewGroup(bool bGroupSelection = true);
+
+    CString LoadDescription(int nItem);
+    bool SaveDescription(int nItem, CString text);
+
+    //Menu Items
+    void SetLinesPerRow(long lLines);
+    void SetTransparency(long lPercent);
+    void OnUpdateLinesPerRow(CCmdUI *pCmdUI, int nValue);
+    void OnUpdateTransparency(CCmdUI *pCmdUI, int nValue);
+    void SetMenuChecks(CMenu *pMenu);
+    void SetSendToMenu(CMenu *pMenu, int nMenuID, int nArrayPos);
+
+    BOOL SendToFriendbyPos(int nPos);
+
+    bool InsertNextNRecords(int nEnd);
+
+    CString GetDisplayText(long lDontAutoDelete, long lShortCut, bool bIsGroup, long lParentID, CString csText);
+
+    void FillMainTable(CMainTable &table, CppSQLite3Query &q);
+    void RunThread();
+    void MoveSelection(bool down);
+    void OnKeyStateUp();
+    void SetKeyModiferState(bool bActive);
+
+    // Generated message map functions
 protected:
-	//{{AFX_MSG(CQPasteWnd)
-	DECLARE_MESSAGE_MAP()
-	afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
-	afx_msg void OnSize(UINT nType, int cx, int cy);
-	afx_msg void OnSetFocus(CWnd* pOldWnd);
-	afx_msg void OnActivate(UINT nState, CWnd* pWndOther, BOOL bMinimized);
-	afx_msg void OnMenuLinesperrow1();
-	afx_msg void OnMenuLinesperrow2();
-	afx_msg void OnMenuLinesperrow3();
-	afx_msg void OnMenuLinesperrow4();
-	afx_msg void OnMenuLinesperrow5();
-	afx_msg void OnMenuTransparency10();
-	afx_msg void OnMenuTransparency15();
-	afx_msg void OnMenuTransparency20();
-	afx_msg void OnMenuTransparency25();
-	afx_msg void OnMenuTransparency30();
-	afx_msg void OnMenuTransparency40();
-	afx_msg void OnMenuTransparency5();
-	afx_msg void OnMenuTransparencyNone();
-	afx_msg void OnRclickQuickPaste(NMHDR* pNMHDR, LRESULT* pResult);
-	afx_msg void OnMenuDelete();
-	afx_msg void OnMenuPositioningAtcaret();
-	afx_msg void OnMenuPositioningAtcursor();
-	afx_msg void OnMenuPositioningAtpreviousposition();
-	afx_msg void OnMenuOptions();
-	afx_msg void OnCancelFilter();
-	afx_msg void OnMenuExitprogram();
-	afx_msg void OnMenuToggleConnectCV();
-	afx_msg void OnMenuProperties();
-	afx_msg void OnClose();
-	afx_msg void OnBegindrag(NMHDR* pNMHDR, LRESULT* pResult);
-	afx_msg void OnSysKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags);
-	afx_msg void GetDispInfo(NMHDR* pNMHDR, LRESULT* pResult);
-	afx_msg void OnFindItem(NMHDR* pNMHDR, LRESULT* pResult);
-	afx_msg void OnMenuFirsttenhotkeysUsectrlnum();
-	afx_msg void OnMenuFirsttenhotkeysShowhotkeytext();
-	afx_msg void OnMenuQuickoptionsAllwaysshowdescription();
-	afx_msg void OnMenuQuickoptionsDoubleclickingoncaptionTogglesalwaysontop();
-	afx_msg void OnMenuQuickoptionsDoubleclickingoncaptionRollupwindow();
-	afx_msg void OnMenuQuickoptionsDoubleclickingoncaptionTogglesshowdescription();
-	afx_msg void OnMenuQuickoptionsPromptfornewgroupnames();
-	afx_msg void OnShowGroupsBottom();
-	afx_msg void OnShowGroupsTop();
-	afx_msg void OnMenuViewgroups();
-	afx_msg void OnMenuQuickpropertiesSettoneverautodelete();
-	afx_msg void OnMenuQuickpropertiesAutodelete();
-	afx_msg void OnMenuQuickpropertiesRemovehotkey();
-	afx_msg void OnMenuSenttoFriendEight();
-	afx_msg void OnMenuSenttoFriendEleven();
-	afx_msg void OnMenuSenttoFriendFifteen();
-	afx_msg void OnMenuSenttoFriendFive();
-	afx_msg void OnMenuSenttoFriendFore();
-	afx_msg void OnMenuSenttoFriendForeteen();
-	afx_msg void OnMenuSenttoFriendNine();
-	afx_msg void OnMenuSenttoFriendSeven();
-	afx_msg void OnMenuSenttoFriendSix();
-	afx_msg void OnMenuSenttoFriendTen();
-	afx_msg void OnMenuSenttoFriendThirteen();
-	afx_msg void OnMenuSenttoFriendThree();
-	afx_msg void OnMenuSenttoFriendTwelve();
-	afx_msg void OnMenuSenttoFriendTwo();
-	afx_msg void OnMenuSenttoFriendone();
-	afx_msg void OnMenuSenttoPromptforip();
-	afx_msg void OnMenuGroupsMovetogroup();
-	afx_msg void OnMenuPasteplaintextonly();
-	afx_msg void OnMenuHelp();
-	afx_msg void OnMenuQuickoptionsFont();
-	afx_msg void OnMenuQuickoptionsShowthumbnails();
-	afx_msg void OnMenuQuickoptionsDrawrtftext();
-	afx_msg void OnMenuQuickoptionsPasteclipafterselection();
-	afx_msg void OnSearchEditChange();
-	afx_msg void OnMenuQuickoptionsFindasyoutype();
-	afx_msg void OnMenuQuickoptionsEnsureentirewindowisvisible();
-	afx_msg void OnMenuQuickoptionsShowclipsthatareingroupsinmainlist();
-	afx_msg void OnMenuPastehtmlasplaintext();
-	afx_msg void OnPromptToDeleteClip();
-	afx_msg void OnUpdateMenuNewgroup(CCmdUI* pCmdUI);
-	afx_msg void OnUpdateMenuNewgroupselection(CCmdUI* pCmdUI);
-	afx_msg void OnUpdateMenuAllwaysontop(CCmdUI* pCmdUI);
-	afx_msg void OnUpdateMenuViewfulldescription(CCmdUI* pCmdUI);
-	afx_msg void OnUpdateMenuViewgroups(CCmdUI* pCmdUI);
-	afx_msg void OnUpdateMenuPasteplaintextonly(CCmdUI* pCmdUI);
-	afx_msg void OnUpdateMenuDelete(CCmdUI* pCmdUI);
-	afx_msg void OnUpdateMenuProperties(CCmdUI* pCmdUI);	
-	afx_msg void OnDestroy();
-	afx_msg LRESULT OnListSelect(WPARAM wParam, LPARAM lParam);
-	afx_msg LRESULT OnListEnd(WPARAM wParam, LPARAM lParam);
-	afx_msg LRESULT OnSearch(WPARAM wParam, LPARAM lParam);
-	afx_msg LRESULT OnDelete(WPARAM wParam, LPARAM lParam);
-	afx_msg LRESULT OnProperties(WPARAM wParam, LPARAM lParam);
-	afx_msg void OnGetToolTipText(NMHDR* pNMHDR, LRESULT* pResult);
-	afx_msg LRESULT OnListSelect_DB_ID(WPARAM wParam, LPARAM lParam);
-	afx_msg LRESULT OnListSelect_Index(WPARAM wParam, LPARAM lParam);
-	afx_msg LRESULT OnRefreshView(WPARAM wParam, LPARAM lParam);
-	afx_msg LRESULT OnGroupTreeMessage(WPARAM wParam, LPARAM lParam);
-	afx_msg LRESULT OnFillRestOfList(WPARAM wParam, LPARAM lParam);
-	afx_msg LRESULT OnRefeshRow(WPARAM wParam, LPARAM lParam);
-	afx_msg LRESULT OnSetListCount(WPARAM wParam, LPARAM lParam);
-	afx_msg HBRUSH CtlColor(CDC* pDC, UINT nCtlColor) ;
-	afx_msg void OnNcLButtonDblClk(UINT nHitTest, CPoint point);
-	afx_msg void OnWindowPosChanging(WINDOWPOS* lpwndpos);
-	afx_msg void OnViewcaptionbaronRight();
-	afx_msg void OnViewcaptionbaronBottom();
-	afx_msg void OnViewcaptionbaronLeft();
-	afx_msg void OnViewcaptionbaronTop();
-	afx_msg void OnMenuAutohide();
-	afx_msg void OnMenuViewfulldescription();
-	afx_msg void OnMenuAllwaysontop();
-	afx_msg void OnSortAscending();
-	afx_msg void OnSortDescending();
-	afx_msg void OnMenuNewGroup();
-	afx_msg void OnMenuNewGroupSelection();
-	afx_msg void OnBackButton();
-	afx_msg LRESULT OnUpDown(WPARAM wParam, LPARAM lParam);
-	afx_msg LRESULT OnItemDeleted(WPARAM wParam, LPARAM lParam);
-	LRESULT OnToolTipWndInactive(WPARAM wParam, LPARAM lParam);
-	afx_msg void OnTimer(UINT_PTR nIDEvent);
-	afx_msg void OnMenuExport();
-	afx_msg void OnMenuImport();
-	afx_msg void OnQuickpropertiesRemovequickpaste();
-	afx_msg void OnMenuEdititem();
-	afx_msg void OnMenuNewclip();
-	afx_msg void OnUpdateMenuEdititem(CCmdUI *pCmdUI);
-	afx_msg void OnUpdateMenuNewclip(CCmdUI *pCmdUI);
-	afx_msg void CQPasteWnd::OnAddinSelect(UINT id);
-	afx_msg LRESULT OnSelectAll(WPARAM wParam, LPARAM lParam);
-//}}AFX_MSG
+    //{{AFX_MSG(CQPasteWnd)
+    DECLARE_MESSAGE_MAP()afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
+    afx_msg void OnSize(UINT nType, int cx, int cy);
+    afx_msg void OnSetFocus(CWnd *pOldWnd);
+    afx_msg void OnActivate(UINT nState, CWnd *pWndOther, BOOL bMinimized);
+    afx_msg void OnMenuLinesperrow1();
+    afx_msg void OnMenuLinesperrow2();
+    afx_msg void OnMenuLinesperrow3();
+    afx_msg void OnMenuLinesperrow4();
+    afx_msg void OnMenuLinesperrow5();
+    afx_msg void OnMenuTransparency10();
+    afx_msg void OnMenuTransparency15();
+    afx_msg void OnMenuTransparency20();
+    afx_msg void OnMenuTransparency25();
+    afx_msg void OnMenuTransparency30();
+    afx_msg void OnMenuTransparency40();
+    afx_msg void OnMenuTransparency5();
+    afx_msg void OnMenuTransparencyNone();
+    afx_msg void OnRclickQuickPaste(NMHDR *pNMHDR, LRESULT *pResult);
+    afx_msg void OnMenuDelete();
+    afx_msg void OnMenuPositioningAtcaret();
+    afx_msg void OnMenuPositioningAtcursor();
+    afx_msg void OnMenuPositioningAtpreviousposition();
+    afx_msg void OnMenuOptions();
+    afx_msg void OnCancelFilter();
+    afx_msg void OnMenuExitprogram();
+    afx_msg void OnMenuToggleConnectCV();
+    afx_msg void OnMenuProperties();
+    afx_msg void OnClose();
+    afx_msg void OnBegindrag(NMHDR *pNMHDR, LRESULT *pResult);
+    afx_msg void OnSysKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags);
+    afx_msg void GetDispInfo(NMHDR *pNMHDR, LRESULT *pResult);
+    afx_msg void OnFindItem(NMHDR *pNMHDR, LRESULT *pResult);
+    afx_msg void OnMenuFirsttenhotkeysUsectrlnum();
+    afx_msg void OnMenuFirsttenhotkeysShowhotkeytext();
+    afx_msg void OnMenuQuickoptionsAllwaysshowdescription();
+    afx_msg void OnMenuQuickoptionsDoubleclickingoncaptionTogglesalwaysontop();
+    afx_msg void OnMenuQuickoptionsDoubleclickingoncaptionRollupwindow();
+    afx_msg void OnMenuQuickoptionsDoubleclickingoncaptionTogglesshowdescription();
+    afx_msg void OnMenuQuickoptionsPromptfornewgroupnames();
+    afx_msg void OnShowGroupsBottom();
+    afx_msg void OnShowGroupsTop();
+    afx_msg void OnMenuViewgroups();
+    afx_msg void OnMenuQuickpropertiesSettoneverautodelete();
+    afx_msg void OnMenuQuickpropertiesAutodelete();
+    afx_msg void OnMenuQuickpropertiesRemovehotkey();
+    afx_msg void OnMenuSenttoFriendEight();
+    afx_msg void OnMenuSenttoFriendEleven();
+    afx_msg void OnMenuSenttoFriendFifteen();
+    afx_msg void OnMenuSenttoFriendFive();
+    afx_msg void OnMenuSenttoFriendFore();
+    afx_msg void OnMenuSenttoFriendForeteen();
+    afx_msg void OnMenuSenttoFriendNine();
+    afx_msg void OnMenuSenttoFriendSeven();
+    afx_msg void OnMenuSenttoFriendSix();
+    afx_msg void OnMenuSenttoFriendTen();
+    afx_msg void OnMenuSenttoFriendThirteen();
+    afx_msg void OnMenuSenttoFriendThree();
+    afx_msg void OnMenuSenttoFriendTwelve();
+    afx_msg void OnMenuSenttoFriendTwo();
+    afx_msg void OnMenuSenttoFriendone();
+    afx_msg void OnMenuSenttoPromptforip();
+    afx_msg void OnMenuGroupsMovetogroup();
+    afx_msg void OnMenuPasteplaintextonly();
+    afx_msg void OnMenuHelp();
+    afx_msg void OnMenuQuickoptionsFont();
+    afx_msg void OnMenuQuickoptionsShowthumbnails();
+    afx_msg void OnMenuQuickoptionsDrawrtftext();
+    afx_msg void OnMenuQuickoptionsPasteclipafterselection();
+    afx_msg void OnSearchEditChange();
+    afx_msg void OnMenuQuickoptionsFindasyoutype();
+    afx_msg void OnMenuQuickoptionsEnsureentirewindowisvisible();
+    afx_msg void OnMenuQuickoptionsShowclipsthatareingroupsinmainlist();
+    afx_msg void OnMenuPastehtmlasplaintext();
+    afx_msg void OnPromptToDeleteClip();
+    afx_msg void OnUpdateMenuNewgroup(CCmdUI *pCmdUI);
+    afx_msg void OnUpdateMenuNewgroupselection(CCmdUI *pCmdUI);
+    afx_msg void OnUpdateMenuAllwaysontop(CCmdUI *pCmdUI);
+    afx_msg void OnUpdateMenuViewfulldescription(CCmdUI *pCmdUI);
+    afx_msg void OnUpdateMenuViewgroups(CCmdUI *pCmdUI);
+    afx_msg void OnUpdateMenuPasteplaintextonly(CCmdUI *pCmdUI);
+    afx_msg void OnUpdateMenuDelete(CCmdUI *pCmdUI);
+    afx_msg void OnUpdateMenuProperties(CCmdUI *pCmdUI);
+    afx_msg void OnDestroy();
+    afx_msg LRESULT OnListSelect(WPARAM wParam, LPARAM lParam);
+    afx_msg LRESULT OnListEnd(WPARAM wParam, LPARAM lParam);
+    afx_msg LRESULT OnSearch(WPARAM wParam, LPARAM lParam);
+    afx_msg LRESULT OnDelete(WPARAM wParam, LPARAM lParam);
+    afx_msg LRESULT OnProperties(WPARAM wParam, LPARAM lParam);
+    afx_msg void OnGetToolTipText(NMHDR *pNMHDR, LRESULT *pResult);
+    afx_msg LRESULT OnListSelect_DB_ID(WPARAM wParam, LPARAM lParam);
+    afx_msg LRESULT OnListSelect_Index(WPARAM wParam, LPARAM lParam);
+    afx_msg LRESULT OnRefreshView(WPARAM wParam, LPARAM lParam);
+    afx_msg LRESULT OnGroupTreeMessage(WPARAM wParam, LPARAM lParam);
+    afx_msg LRESULT OnFillRestOfList(WPARAM wParam, LPARAM lParam);
+    afx_msg LRESULT OnRefeshRow(WPARAM wParam, LPARAM lParam);
+    afx_msg LRESULT OnSetListCount(WPARAM wParam, LPARAM lParam);
+    afx_msg HBRUSH CtlColor(CDC *pDC, UINT nCtlColor);
+    afx_msg void OnNcLButtonDblClk(UINT nHitTest, CPoint point);
+    afx_msg void OnWindowPosChanging(WINDOWPOS *lpwndpos);
+    afx_msg void OnViewcaptionbaronRight();
+    afx_msg void OnViewcaptionbaronBottom();
+    afx_msg void OnViewcaptionbaronLeft();
+    afx_msg void OnViewcaptionbaronTop();
+    afx_msg void OnMenuAutohide();
+    afx_msg void OnMenuViewfulldescription();
+    afx_msg void OnMenuAllwaysontop();
+    afx_msg void OnSortAscending();
+    afx_msg void OnSortDescending();
+    afx_msg void OnMenuNewGroup();
+    afx_msg void OnMenuNewGroupSelection();
+    afx_msg void OnBackButton();
+    afx_msg LRESULT OnUpDown(WPARAM wParam, LPARAM lParam);
+    afx_msg LRESULT OnItemDeleted(WPARAM wParam, LPARAM lParam);
+    LRESULT OnToolTipWndInactive(WPARAM wParam, LPARAM lParam);
+    afx_msg void OnTimer(UINT_PTR nIDEvent);
+    afx_msg void OnMenuExport();
+    afx_msg void OnMenuImport();
+    afx_msg void OnQuickpropertiesRemovequickpaste();
+    afx_msg void OnMenuEdititem();
+    afx_msg void OnMenuNewclip();
+    afx_msg void OnUpdateMenuEdititem(CCmdUI *pCmdUI);
+    afx_msg void OnUpdateMenuNewclip(CCmdUI *pCmdUI);
+    afx_msg void CQPasteWnd::OnAddinSelect(UINT id);
+    afx_msg LRESULT OnSelectAll(WPARAM wParam, LPARAM lParam);
+    //}}AFX_MSG
 };
-
-
-
-/////////////////////////////////////////////////////////////////////////////
-
-//{{AFX_INSERT_LOCATION}}
-// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
-
-#endif // !defined(AFX_QPASTEWND_H__65261F0F_FEFD_48CF_A0CD_01D8BFEB353B__INCLUDED_)

+ 2 - 0
Server.cpp

@@ -222,7 +222,9 @@ void CServer::OnDataStart(CSendInfo &info)
 		if(m_cf.m_hgData)
 		{
 			if(m_pClip)
+			{
 				m_pClip->m_lTotalCopySize += lOutSize;
+			}
 
 			LPVOID pvData = GlobalLock(m_cf.m_hgData);
 			if(pvData)

+ 1 - 0
Theme.cpp

@@ -3,6 +3,7 @@
 #include "TextConvert.h"
 #include "Misc.h"
 #include "Options.h"
+#include "Tokenizer.h"
 
 CTheme::CTheme(void)
 {

+ 554 - 522
ToolTipEx.cpp

@@ -1,522 +1,554 @@
-// ToolTipEx.cpp : implementation file
-//
-
-#include "stdafx.h"
-#include "cp_main.h"
-#include "ToolTipEx.h"
-#include "BitmapHelper.h"
-
-#ifdef _DEBUG
-#define new DEBUG_NEW
-#undef THIS_FILE
-static char THIS_FILE[] = __FILE__;
-#endif
-
-#define DELETE_BITMAP	if(m_pBitmap)					\
-						{								\
-							m_pBitmap->DeleteObject();	\
-							DELETE_PTR(m_pBitmap);		\
-						}
-
-
-/////////////////////////////////////////////////////////////////////////////
-// CToolTipEx
-
-CToolTipEx::CToolTipEx() :
-	m_dwTextStyle(DT_EXPANDTABS|DT_EXTERNALLEADING|DT_NOPREFIX|DT_WORDBREAK),
-	m_rectMargin(2, 2, 3, 3),
-	m_pBitmap(NULL),
-	m_pNotifyWnd(NULL)
-{
-}
-
-CToolTipEx::~CToolTipEx()
-{
-	DELETE_BITMAP
-	
-	m_Font.DeleteObject();
-}
-
-
-BEGIN_MESSAGE_MAP(CToolTipEx, CWnd)
-	//{{AFX_MSG_MAP(CToolTipEx)
-	ON_WM_PAINT()
-	ON_WM_SIZE()
-	ON_WM_NCHITTEST()
-	ON_WM_ACTIVATE()
-	//}}AFX_MSG_MAP
-	ON_WM_TIMER()
-END_MESSAGE_MAP()
-
-
-/////////////////////////////////////////////////////////////////////////////
-// CToolTipEx message handlers
-
-BOOL CToolTipEx::Create(CWnd* pParentWnd)
-{    
-    // Get the class name and create the window
-    CString szClassName = AfxRegisterWndClass(CS_CLASSDC|CS_SAVEBITS, 
-                                              LoadCursor(NULL, IDC_ARROW));
-
-    // Create the window - just don't show it yet.
-    if (!CWnd::CreateEx(WS_EX_TOPMOST, szClassName, _T(""), 
-                        WS_POPUP|WS_BORDER, 
-                        0, 0, 10, 10, // size & position updated when needed
-                        pParentWnd->GetSafeHwnd(), 0, NULL))
-	{
-        return FALSE;
-	}
-
-	m_RichEdit.Create(_T(""), _T(""), WS_CHILD|WS_VISIBLE|WS_VSCROLL|WS_HSCROLL|ES_MULTILINE|ES_AUTOVSCROLL|ES_AUTOHSCROLL, CRect(10,10,100,200), this, 1);
-
-	m_RichEdit.SetReadOnly();
-	m_RichEdit.SetBackgroundColor(FALSE, GetSysColor(COLOR_INFOBK));
-
-	SetLogFont(GetSystemToolTipFont(), FALSE);
-   
-    return TRUE;
-}
-
-BOOL CToolTipEx::Show(CPoint point)
-{
-	if(m_pBitmap)
-	{
-		m_RichEdit.ShowWindow(SW_HIDE);
-	}
-	else
-	{
-		m_RichEdit.ShowWindow(SW_SHOW);
-	}
-
-	CRect rect = GetBoundsRect();
-
-	//account for the scroll bars
-	rect.right += 20;
-	rect.bottom += 20;
-
-	//if showing rtf then increase the size because
-	//rtf will probably draw bigger
-	if(m_csRTF != "")
-	{
-		long lNewWidth = (long)rect.Width() + (long)(rect.Width() * .3);
-		rect.right = rect.left + lNewWidth;
-
-		long lNewHeight = rect.Height() + (rect.Height() * 1);
-		rect.bottom = rect.top + lNewHeight;
-	}
-
-	CRect rcScreen;
-
-	ClientToScreen(rect);
-
-	CRect cr(point, point);
-
-	int nMonitor = GetMonitorFromRect(&cr);
-	GetMonitorRect(nMonitor, &rcScreen);
-		
-	//ensure that we don't go outside the screen
-	if(point.x < 0)
-		point.x = 5;
-	if(point.y < 0)
-		point.y = 5;
-
-	rcScreen.DeflateRect(0, 0, 5, 5);
-
-	long lWidth = rect.Width();
-	long lHeight = rect.Height();
-
-	rect.left = point.x;
-	rect.top = point.y;
-	rect.right = rect.left + lWidth;
-	rect.bottom = rect.top + lHeight;
-
-	if(rect.right > rcScreen.right)
-		rect.right = rcScreen.right;
-	if(rect.bottom > rcScreen.bottom)
-		rect.bottom = rcScreen.bottom;
-
-	SetWindowPos(&CWnd::wndTopMost,
-		         point.x, point.y,
-			     rect.Width(), rect.Height(),
-				 SWP_SHOWWINDOW|SWP_NOCOPYBITS|SWP_NOACTIVATE|SWP_NOZORDER);
-
-	return TRUE;
-}
-
-BOOL CToolTipEx::Hide()
-{
-	DELETE_BITMAP
-	
-	ShowWindow(SW_HIDE);
-
-	m_csRTF = "";
-	m_csText = "";
-
-	return TRUE;
-}
-
-void CToolTipEx::OnPaint() 
-{
-	CPaintDC dc(this); // device context for painting
-
-	CRect rect;
-	GetClientRect(rect);
-
-//	CBrush  Brush, *pOldBrush;
-//	Brush.CreateSolidBrush(GetSysColor(COLOR_INFOBK));
-
-//	pOldBrush = dc.SelectObject(&Brush);
-//	CFont *pOldFont = dc.SelectObject(&m_Font);
-
-  //  dc.FillRect(&rect, &Brush);
-
-	// Draw Text
-//    dc.SetBkMode(TRANSPARENT);
-//    rect.DeflateRect(m_rectMargin);
-
-	if(m_pBitmap)
-	{
-		CDC MemDc;
-		MemDc.CreateCompatibleDC(&dc);
-
-		CBitmap* oldBitmap = MemDc.SelectObject(m_pBitmap);
-
-		int nWidth = CBitmapHelper::GetCBitmapWidth(*m_pBitmap);
-		int nHeight = CBitmapHelper::GetCBitmapHeight(*m_pBitmap);
-		
-		dc.BitBlt(rect.left, rect.top, nWidth, nHeight, &MemDc, 0, 0, SRCCOPY);
-
-		MemDc.SelectObject(oldBitmap);
-
-		rect.top += nHeight;
-	}
-
-    //dc.DrawText(m_csText, rect, m_dwTextStyle);
-
-	// Cleanup
-//  dc.SelectObject(pOldBrush);
-//	dc.SelectObject(pOldFont);
-}
-
-void CToolTipEx::PostNcDestroy() 
-{
-	CWnd::PostNcDestroy();
-
-    delete this;
-}
-
-BOOL CToolTipEx::PreTranslateMessage(MSG* pMsg) 
-{
-	switch(pMsg->message) 
-	{
-	case WM_KEYDOWN:
-		
-		switch( pMsg->wParam )
-		{
-		case VK_ESCAPE:
-			Hide();
-			return TRUE;
-		case 'C':
-			if(GetKeyState(VK_CONTROL) & 0x8000)
-			{
-				m_RichEdit.Copy();
-			}
-			break;
-		}
-	}
-
-	return CWnd::PreTranslateMessage(pMsg);
-}
-
-BOOL CToolTipEx::OnMsg(MSG* pMsg)
-{
-	if(FALSE == IsWindowVisible())
-	{
-		return FALSE;
-	}
-
-	switch(pMsg->message) 
-	{
-		case WM_WINDOWPOSCHANGING:
-		case WM_LBUTTONDOWN:
-		{
-			if (!IsCursorInToolTip())
-				Hide();
-			break;
-		}
-		case WM_KEYDOWN:
-		{
-			WPARAM vk = pMsg->wParam;
-			if(vk == VK_ESCAPE)
-			{
-				Hide();
-				return TRUE;
-			}
-			else if(vk == VK_TAB)
-			{
-				m_RichEdit.SetFocus();
-				return TRUE;
-			}
-
-			Hide();
-
-			break;
-		}
-		case WM_LBUTTONDBLCLK:
-		case WM_RBUTTONDOWN :
-		case WM_RBUTTONDBLCLK:
-		case WM_MBUTTONDOWN:
-		case WM_MBUTTONDBLCLK:
-		case WM_NCLBUTTONDOWN:
-		case WM_NCLBUTTONDBLCLK:
-		case WM_NCRBUTTONDOWN:
-		case WM_NCRBUTTONDBLCLK:
-		case WM_NCMBUTTONDOWN:
-		case WM_NCMBUTTONDBLCLK:
-		{
-			Hide();
-			break;
-		}
-	}
-
-	return FALSE;
-}
-
-CRect CToolTipEx::GetBoundsRect()
-{
-    CWindowDC dc(NULL);
-   
-	CFont *pOldFont = (CFont*) dc.SelectObject((CFont*)&m_Font); 
-	
-	int nLineWidth = 0;
-
-	if (nLineWidth == 0)
-    {
-        // Count the number of lines of text
-        int nStart = 0, nNumLines = 0;
-		CString strTextCopy = m_csText;
-        do 
-		{
-            nStart = strTextCopy.Find(_T("\n"));
-
-            // skip found character 
-            if (nStart >= 0)
-                strTextCopy = strTextCopy.Mid(nStart+1);
-
-            nNumLines++;
-        } while (nStart >= 0);
-
-        // Find the widest line
-        for (int i = 0; i < nNumLines; i++)
-        {
-            CString strLine = GetFieldFromString(m_csText, i, _T('\n')) + _T("  ");
-            nLineWidth = max(nLineWidth, dc.GetTextExtent(strLine).cx);
-        }
-    }
-
-    CRect rect(0, 0, max(0,nLineWidth), 0);
-    dc.DrawText(m_csText, rect, DT_CALCRECT | m_dwTextStyle);
-
-	dc.SelectObject(pOldFont);
-	
-    rect.bottom += m_rectMargin.top + m_rectMargin.bottom;
-    rect.right += m_rectMargin.left + m_rectMargin.right + 2;
-
-	if(m_pBitmap)
-	{
-		int nWidth = CBitmapHelper::GetCBitmapWidth(*m_pBitmap);
-		int nHeight = CBitmapHelper::GetCBitmapHeight(*m_pBitmap);
-
-		rect.bottom += nHeight;
-		if((rect.left + nWidth) > rect.right)
-			rect.right = rect.left + nWidth;
-	}
-
-    return rect;
-}
-
-CString CToolTipEx::GetFieldFromString(CString ref, int nIndex, TCHAR ch)
-{
-    CString strReturn;
-    LPCTSTR pstrStart = ref.LockBuffer();
-    LPCTSTR pstrBuffer = pstrStart;
-    int nCurrent = 0;
-    int nStart = 0;
-    int nEnd = 0;
-    int nOldStart = 0;
-
-    while (nCurrent <= nIndex && *pstrBuffer != _T('\0'))
-    {
-        if (*pstrBuffer == ch)
-        {
-            nOldStart = nStart;
-            nStart = nEnd+1;
-            nCurrent++;
-        }
-        nEnd++;
-        pstrBuffer++;
-    }
-
-    // May have reached the end of the string
-    if (*pstrBuffer == _T('\0'))
-    {
-        nOldStart = nStart;
-        nEnd++;
-    }
-
-    ref.UnlockBuffer();
-
-    if (nCurrent < nIndex) 
-    {
-        //TRACE1("Warning: GetStringField - Couldn't find field %d.\n", nIndex);
-        return strReturn;
-    }
-    return ref.Mid(nOldStart, nEnd-nOldStart-1);
-}
-
-LPLOGFONT CToolTipEx::GetSystemToolTipFont()
-{
-    static LOGFONT LogFont;
-
-    NONCLIENTMETRICS ncm;
-    ncm.cbSize = sizeof(NONCLIENTMETRICS);
-    if(!SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICS), &ncm, 0))
-       return FALSE;
-
-    memcpy(&LogFont, &(ncm.lfStatusFont), sizeof(LOGFONT));
-
-    return &LogFont;
-}
-
-BOOL CToolTipEx::SetLogFont(LPLOGFONT lpLogFont, BOOL bRedraw /*=TRUE*/)
-{
-    ASSERT(lpLogFont);
-    if (!lpLogFont)
-        return FALSE;
-
-	LOGFONT LogFont;
-
-    // Store font as the global default
-    memcpy(&LogFont, lpLogFont, sizeof(LOGFONT));
-
-    // Create the actual font object
-    m_Font.DeleteObject();
-    m_Font.CreateFontIndirect(&LogFont);
-
-    if (bRedraw && ::IsWindow(GetSafeHwnd())) 
-        Invalidate();
-
-    return TRUE;
-}
-
-void CToolTipEx::SetBitmap(CBitmap *pBitmap)
-{
-	DELETE_BITMAP
-
-	m_pBitmap = pBitmap;
-}
-
-void CToolTipEx::OnSize(UINT nType, int cx, int cy) 
-{
-	CWnd::OnSize(nType, cx, cy);
-	
-	if(::IsWindow(m_RichEdit.GetSafeHwnd()) == FALSE)
-		return;
-
-	CRect cr;
-	GetClientRect(cr);
-//	cr.DeflateRect(0, 0, 15, 0);
-	m_RichEdit.MoveWindow(cr);
-}
-
-BOOL CToolTipEx::IsCursorInToolTip()
-{
-	CRect cr;
-	GetWindowRect(cr);
-
-	CPoint cursorPos;
-	GetCursorPos(&cursorPos);
-
-	return cr.PtInRect(cursorPos);
-}
-
-void CToolTipEx::SetRTFText(const char *pRTF)
-{
-	m_RichEdit.SetRTF(pRTF);
-	m_csRTF = pRTF;
-}
-
-//void CToolTipEx::SetRTFText(const CString &csRTF)
-//{
-//	m_RichEdit.SetRTF(csRTF);
-//	m_csRTF = csRTF;
-//}
-
-void CToolTipEx::SetToolTipText(const CString &csText)
-{
-	m_csText = csText;
-	m_RichEdit.SetFont(&m_Font);
-	m_RichEdit.SetText(csText);
-}
-
-HITTEST_RET CToolTipEx::OnNcHitTest(CPoint point) 
-{
-	CRect crWindow;
-	GetWindowRect(crWindow);
-	
-	const static int nBorder = 10;
-
-	if((point.y < crWindow.top + nBorder) &&
-		(point.x < crWindow.left + nBorder))
-		return HTTOPLEFT;
-	else if((point.y < crWindow.top + nBorder) &&
-		(point.x > crWindow.right - nBorder))
-		return HTTOPRIGHT;
-	else if((point.y > crWindow.bottom - nBorder) &&
-		(point.x > crWindow.right - nBorder))
-		return HTBOTTOMRIGHT;
-	else if((point.y > crWindow.bottom - nBorder) &&
-		(point.x < crWindow.left + nBorder))
-		return HTBOTTOMLEFT;
-
-	if(point.y < crWindow.top + nBorder)
-		return HTTOP;
-	else if(point.y > crWindow.bottom - nBorder)
-		return HTBOTTOM;
-	else if(point.x > crWindow.right - nBorder)
-		return HTRIGHT;
-	else if(point.x < crWindow.left + nBorder)
-		return HTLEFT;
-
-//	if(point.x > crWindow.right - 15)
-//		return HTCAPTION;
-
-	return CWnd::OnNcHitTest(point);
-}
-
-void CToolTipEx::OnActivate(UINT nState, CWnd* pWndOther, BOOL bMinimized) 
-{
-	CWnd::OnActivate(nState, pWndOther, bMinimized);
-	
-	if (nState == WA_INACTIVE)
-	{
-		Hide();
-
-		if(m_pNotifyWnd)
-		{
-			m_pNotifyWnd->PostMessage(NM_INACTIVE_TOOLTIPWND, 0, 0);
-		}
-	}
-}
-void CToolTipEx::OnTimer(UINT_PTR nIDEvent)
-{
-	switch(nIDEvent)
-	{
-	case HIDE_WINDOW_TIMER:
-		Hide();
-		PostMessage(WM_DESTROY, 0, 0);
-		break;
-	}
-
-	CWnd::OnTimer(nIDEvent);
-}
+#include "stdafx.h"
+#include "cp_main.h"
+#include "ToolTipEx.h"
+#include "BitmapHelper.h"
+
+#ifdef _DEBUG
+    #define new DEBUG_NEW
+    #undef THIS_FILE
+    static char THIS_FILE[] = __FILE__;
+#endif 
+
+#define DELETE_BITMAP	if(m_pBitmap)					\
+{								\
+m_pBitmap->DeleteObject();	\
+DELETE_PTR(m_pBitmap);		\
+}
+
+
+/////////////////////////////////////////////////////////////////////////////
+// CToolTipEx
+
+CToolTipEx::CToolTipEx(): m_dwTextStyle(DT_EXPANDTABS | DT_EXTERNALLEADING |
+                       DT_NOPREFIX | DT_WORDBREAK), m_rectMargin(2, 2, 3, 3),
+                       m_pBitmap(NULL), m_pNotifyWnd(NULL){}
+
+CToolTipEx::~CToolTipEx()
+{
+    DELETE_BITMAP 
+
+    m_Font.DeleteObject();
+}
+
+
+BEGIN_MESSAGE_MAP(CToolTipEx, CWnd)
+//{{AFX_MSG_MAP(CToolTipEx)
+ON_WM_PAINT()ON_WM_SIZE()ON_WM_NCHITTEST()ON_WM_ACTIVATE()
+//}}AFX_MSG_MAP
+ON_WM_TIMER()END_MESSAGE_MAP()
+
+
+/////////////////////////////////////////////////////////////////////////////
+// CToolTipEx message handlers
+
+BOOL CToolTipEx::Create(CWnd *pParentWnd)
+{
+    // Get the class name and create the window
+    CString szClassName = AfxRegisterWndClass(CS_CLASSDC | CS_SAVEBITS,
+        LoadCursor(NULL, IDC_ARROW));
+
+    // Create the window - just don't show it yet.
+    if( !CWnd::CreateEx(WS_EX_TOPMOST, szClassName, _T(""), WS_POPUP | WS_BORDER,
+       0, 0, 10, 10,  // size & position updated when needed
+    pParentWnd->GetSafeHwnd(), 0, NULL))
+    {
+        return FALSE;
+    }
+
+    m_RichEdit.Create(_T(""), _T(""), WS_CHILD | WS_VISIBLE | WS_VSCROLL |
+                      WS_HSCROLL | ES_MULTILINE | ES_AUTOVSCROLL |
+                      ES_AUTOHSCROLL, CRect(10, 10, 100, 200), this, 1);
+
+    m_RichEdit.SetReadOnly();
+    m_RichEdit.SetBackgroundColor(FALSE, GetSysColor(COLOR_INFOBK));
+
+    SetLogFont(GetSystemToolTipFont(), FALSE);
+
+    return TRUE;
+}
+
+BOOL CToolTipEx::Show(CPoint point)
+{
+    if(m_pBitmap)
+    {
+        m_RichEdit.ShowWindow(SW_HIDE);
+    }
+    else
+    {
+        m_RichEdit.ShowWindow(SW_SHOW);
+    }
+
+    CRect rect = GetBoundsRect();
+
+    //account for the scroll bars
+    rect.right += 20;
+    rect.bottom += 20;
+
+    //if showing rtf then increase the size because
+    //rtf will probably draw bigger
+    if(m_csRTF != "")
+    {
+        long lNewWidth = (long)rect.Width() + (long)(rect.Width() *.3);
+        rect.right = rect.left + lNewWidth;
+
+        long lNewHeight = rect.Height() + (rect.Height() *1);
+        rect.bottom = rect.top + lNewHeight;
+    }
+
+    CRect rcScreen;
+
+    ClientToScreen(rect);
+
+    CRect cr(point, point);
+
+    int nMonitor = GetMonitorFromRect(&cr);
+    GetMonitorRect(nMonitor, &rcScreen);
+
+    //ensure that we don't go outside the screen
+    if(point.x < 0)
+    {
+        point.x = 5;
+    }
+    if(point.y < 0)
+    {
+        point.y = 5;
+    }
+
+    rcScreen.DeflateRect(0, 0, 5, 5);
+
+    long lWidth = rect.Width();
+    long lHeight = rect.Height();
+
+    rect.left = point.x;
+    rect.top = point.y;
+    rect.right = rect.left + lWidth;
+    rect.bottom = rect.top + lHeight;
+
+    if(rect.right > rcScreen.right)
+    {
+        rect.right = rcScreen.right;
+    }
+    if(rect.bottom > rcScreen.bottom)
+    {
+        rect.bottom = rcScreen.bottom;
+    }
+
+    SetWindowPos(&CWnd::wndTopMost, point.x, point.y, rect.Width(), rect.Height
+                 (), SWP_SHOWWINDOW | SWP_NOCOPYBITS | SWP_NOACTIVATE |
+                 SWP_NOZORDER);
+
+    return TRUE;
+}
+
+BOOL CToolTipEx::Hide()
+{
+    DELETE_BITMAP 
+
+    ShowWindow(SW_HIDE);
+
+    m_csRTF = "";
+    m_csText = "";
+
+    return TRUE;
+}
+
+void CToolTipEx::OnPaint()
+{
+    CPaintDC dc(this); // device context for painting
+
+    CRect rect;
+    GetClientRect(rect);
+
+    //	CBrush  Brush, *pOldBrush;
+    //	Brush.CreateSolidBrush(GetSysColor(COLOR_INFOBK));
+
+    //	pOldBrush = dc.SelectObject(&Brush);
+    //	CFont *pOldFont = dc.SelectObject(&m_Font);
+
+    //  dc.FillRect(&rect, &Brush);
+
+    // Draw Text
+    //    dc.SetBkMode(TRANSPARENT);
+    //    rect.DeflateRect(m_rectMargin);
+
+    if(m_pBitmap)
+    {
+        CDC MemDc;
+        MemDc.CreateCompatibleDC(&dc);
+
+        CBitmap *oldBitmap = MemDc.SelectObject(m_pBitmap);
+
+        int nWidth = CBitmapHelper::GetCBitmapWidth(*m_pBitmap);
+        int nHeight = CBitmapHelper::GetCBitmapHeight(*m_pBitmap);
+
+        dc.BitBlt(rect.left, rect.top, nWidth, nHeight, &MemDc, 0, 0, SRCCOPY);
+
+        MemDc.SelectObject(oldBitmap);
+
+        rect.top += nHeight;
+    }
+
+    //dc.DrawText(m_csText, rect, m_dwTextStyle);
+
+    // Cleanup
+    //  dc.SelectObject(pOldBrush);
+    //	dc.SelectObject(pOldFont);
+}
+
+void CToolTipEx::PostNcDestroy()
+{
+    CWnd::PostNcDestroy();
+
+    delete this;
+}
+
+BOOL CToolTipEx::PreTranslateMessage(MSG *pMsg)
+{
+    switch(pMsg->message)
+    {
+        case WM_KEYDOWN:
+
+            switch(pMsg->wParam)
+            {
+            case VK_ESCAPE:
+                Hide();
+                return TRUE;
+            case 'C':
+                if(GetKeyState(VK_CONTROL) &0x8000)
+                {
+                    m_RichEdit.Copy();
+                }
+                break;
+            }
+    }
+
+    return CWnd::PreTranslateMessage(pMsg);
+}
+
+BOOL CToolTipEx::OnMsg(MSG *pMsg)
+{
+    if(FALSE == IsWindowVisible())
+    {
+        return FALSE;
+    }
+
+    switch(pMsg->message)
+    {
+        case WM_WINDOWPOSCHANGING:
+        case WM_LBUTTONDOWN:
+            {
+                if(!IsCursorInToolTip())
+                {
+                    Hide();
+                }
+                break;
+            }
+        case WM_KEYDOWN:
+            {
+                WPARAM vk = pMsg->wParam;
+                if(vk == VK_ESCAPE)
+                {
+                    Hide();
+                    return TRUE;
+                }
+                else if(vk == VK_TAB)
+                {
+                    m_RichEdit.SetFocus();
+                    return TRUE;
+                }
+
+                Hide();
+
+                break;
+            }
+        case WM_LBUTTONDBLCLK:
+        case WM_RBUTTONDOWN:
+        case WM_RBUTTONDBLCLK:
+        case WM_MBUTTONDOWN:
+        case WM_MBUTTONDBLCLK:
+        case WM_NCLBUTTONDOWN:
+        case WM_NCLBUTTONDBLCLK:
+        case WM_NCRBUTTONDOWN:
+        case WM_NCRBUTTONDBLCLK:
+        case WM_NCMBUTTONDOWN:
+        case WM_NCMBUTTONDBLCLK:
+            {
+                Hide();
+                break;
+            }
+    }
+
+    return FALSE;
+}
+
+CRect CToolTipEx::GetBoundsRect()
+{
+    CWindowDC dc(NULL);
+
+    CFont *pOldFont = (CFont*)dc.SelectObject((CFont*) &m_Font);
+
+    int nLineWidth = 0;
+
+    if(nLineWidth == 0)
+    {
+        // Count the number of lines of text
+        int nStart = 0, nNumLines = 0;
+        CString strTextCopy = m_csText;
+        do
+        {
+            nStart = strTextCopy.Find(_T("\n"));
+
+            // skip found character 
+            if(nStart >= 0)
+            {
+                strTextCopy = strTextCopy.Mid(nStart + 1);
+            }
+
+            nNumLines++;
+        }
+
+        while(nStart >= 0);
+
+        // Find the widest line
+        for(int i = 0; i < nNumLines; i++)
+        {
+            CString strLine = GetFieldFromString(m_csText, i, _T('\n')) + _T(
+                "  ");
+            nLineWidth = max(nLineWidth, dc.GetTextExtent(strLine).cx);
+        }
+    }
+
+    CRect rect(0, 0, max(0, nLineWidth), 0);
+    dc.DrawText(m_csText, rect, DT_CALCRECT | m_dwTextStyle);
+
+    dc.SelectObject(pOldFont);
+
+    rect.bottom += m_rectMargin.top + m_rectMargin.bottom;
+    rect.right += m_rectMargin.left + m_rectMargin.right + 2;
+
+    if(m_pBitmap)
+    {
+        int nWidth = CBitmapHelper::GetCBitmapWidth(*m_pBitmap);
+        int nHeight = CBitmapHelper::GetCBitmapHeight(*m_pBitmap);
+
+        rect.bottom += nHeight;
+        if((rect.left + nWidth) > rect.right)
+        {
+            rect.right = rect.left + nWidth;
+        }
+    }
+
+    return rect;
+}
+
+CString CToolTipEx::GetFieldFromString(CString ref, int nIndex, TCHAR ch)
+{
+    CString strReturn;
+    LPCTSTR pstrStart = ref.LockBuffer();
+    LPCTSTR pstrBuffer = pstrStart;
+    int nCurrent = 0;
+    int nStart = 0;
+    int nEnd = 0;
+    int nOldStart = 0;
+
+    while(nCurrent <= nIndex &&  *pstrBuffer != _T('\0'))
+    {
+        if(*pstrBuffer == ch)
+        {
+            nOldStart = nStart;
+            nStart = nEnd + 1;
+            nCurrent++;
+        }
+        nEnd++;
+        pstrBuffer++;
+    }
+
+    // May have reached the end of the string
+    if(*pstrBuffer == _T('\0'))
+    {
+        nOldStart = nStart;
+        nEnd++;
+    }
+
+    ref.UnlockBuffer();
+
+    if(nCurrent < nIndex)
+    {
+        //TRACE1("Warning: GetStringField - Couldn't find field %d.\n", nIndex);
+        return strReturn;
+    }
+    return ref.Mid(nOldStart, nEnd - nOldStart - 1);
+}
+
+LPLOGFONT CToolTipEx::GetSystemToolTipFont()
+{
+    static LOGFONT LogFont;
+
+    NONCLIENTMETRICS ncm;
+    ncm.cbSize = sizeof(NONCLIENTMETRICS);
+    if(!SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICS),
+       &ncm, 0))
+    {
+        return FALSE;
+    }
+
+    memcpy(&LogFont, &(ncm.lfStatusFont), sizeof(LOGFONT));
+
+    return  &LogFont;
+}
+
+BOOL CToolTipEx::SetLogFont(LPLOGFONT lpLogFont, BOOL bRedraw /*=TRUE*/)
+{
+    ASSERT(lpLogFont);
+    if(!lpLogFont)
+    {
+        return FALSE;
+    }
+
+    LOGFONT LogFont;
+
+    // Store font as the global default
+    memcpy(&LogFont, lpLogFont, sizeof(LOGFONT));
+
+    // Create the actual font object
+    m_Font.DeleteObject();
+    m_Font.CreateFontIndirect(&LogFont);
+
+    if(bRedraw && ::IsWindow(GetSafeHwnd()))
+    {
+        Invalidate();
+    }
+
+    return TRUE;
+}
+
+void CToolTipEx::SetBitmap(CBitmap *pBitmap)
+{
+    DELETE_BITMAP 
+
+    m_pBitmap = pBitmap;
+}
+
+void CToolTipEx::OnSize(UINT nType, int cx, int cy)
+{
+    CWnd::OnSize(nType, cx, cy);
+
+    if(::IsWindow(m_RichEdit.GetSafeHwnd()) == FALSE)
+    {
+        return ;
+    }
+
+    CRect cr;
+    GetClientRect(cr);
+    //	cr.DeflateRect(0, 0, 15, 0);
+    m_RichEdit.MoveWindow(cr);
+}
+
+BOOL CToolTipEx::IsCursorInToolTip()
+{
+    CRect cr;
+    GetWindowRect(cr);
+
+    CPoint cursorPos;
+    GetCursorPos(&cursorPos);
+
+    return cr.PtInRect(cursorPos);
+}
+
+void CToolTipEx::SetRTFText(const char *pRTF)
+{
+    m_RichEdit.SetRTF(pRTF);
+    m_csRTF = pRTF;
+}
+
+//void CToolTipEx::SetRTFText(const CString &csRTF)
+//{
+//	m_RichEdit.SetRTF(csRTF);
+//	m_csRTF = csRTF;
+//}
+
+void CToolTipEx::SetToolTipText(const CString &csText)
+{
+    m_csText = csText;
+    m_RichEdit.SetFont(&m_Font);
+    m_RichEdit.SetText(csText);
+}
+
+HITTEST_RET CToolTipEx::OnNcHitTest(CPoint point)
+{
+    CRect crWindow;
+    GetWindowRect(crWindow);
+
+    const static int nBorder = 10;
+
+    if((point.y < crWindow.top + nBorder) && (point.x < crWindow.left + nBorder)
+       )
+    {
+        return HTTOPLEFT;
+    }
+    else if((point.y < crWindow.top + nBorder) && (point.x > crWindow.right -
+            nBorder))
+    {
+        return HTTOPRIGHT;
+    }
+    else if((point.y > crWindow.bottom - nBorder) && (point.x > crWindow.right 
+            - nBorder))
+    {
+        return HTBOTTOMRIGHT;
+    }
+    else if((point.y > crWindow.bottom - nBorder) && (point.x < crWindow.left +
+            nBorder))
+    {
+        return HTBOTTOMLEFT;
+    }
+
+    if(point.y < crWindow.top + nBorder)
+    {
+        return HTTOP;
+    }
+    else if(point.y > crWindow.bottom - nBorder)
+    {
+        return HTBOTTOM;
+    }
+    else if(point.x > crWindow.right - nBorder)
+    {
+        return HTRIGHT;
+    }
+    else if(point.x < crWindow.left + nBorder)
+    {
+        return HTLEFT;
+    }
+
+    //	if(point.x > crWindow.right - 15)
+    //		return HTCAPTION;
+
+    return CWnd::OnNcHitTest(point);
+}
+
+void CToolTipEx::OnActivate(UINT nState, CWnd *pWndOther, BOOL bMinimized)
+{
+    CWnd::OnActivate(nState, pWndOther, bMinimized);
+
+    if(nState == WA_INACTIVE)
+    {
+        Hide();
+
+        if(m_pNotifyWnd)
+        {
+            m_pNotifyWnd->PostMessage(NM_INACTIVE_TOOLTIPWND, 0, 0);
+        }
+    }
+}
+
+void CToolTipEx::OnTimer(UINT_PTR nIDEvent)
+{
+    switch(nIDEvent)
+    {
+        case HIDE_WINDOW_TIMER:
+            Hide();
+            PostMessage(WM_DESTROY, 0, 0);
+            break;
+    }
+
+    CWnd::OnTimer(nIDEvent);
+}

برخی فایل ها در این مقایسه diff نمایش داده نمی شوند زیرا تعداد فایل ها بسیار زیاد است