浏览代码

Added DittoUtil Addin to paste any clip as text

git-svn-id: svn://svn.code.sf.net/p/ditto-cp/code/trunk@460 595ec19a-5cb4-439b-94a8-42fb3063c22c
sabrogden 16 年之前
父节点
当前提交
de167d22ba
共有 27 个文件被更改,包括 281 次插入179 次删除
  1. 13 0
      About.cpp
  2. 2 1
      About.h
  3. 3 3
      CP_Main.cpp
  4. 1 1
      CP_Main.h
  5. 9 10
      CP_Main.rc
  6. 8 2
      CP_Main.vcproj
  7. 2 2
      Clip.cpp
  8. 4 2
      Clip.h
  9. 2 0
      DittoAddin.h
  10. 39 1
      DittoAddins.cpp
  11. 1 0
      DittoAddins.h
  12. 4 1
      DittoSetup/Changes.txt
  13. 6 7
      DittoSetup/DittoSetup.iss
  14. 68 36
      MainFrm.cpp
  15. 1 1
      MainFrm.h
  16. 46 0
      Misc.cpp
  17. 3 0
      Misc.h
  18. 5 48
      OleClipSource.cpp
  19. 1 2
      OleClipSource.h
  20. 49 26
      Options.cpp
  21. 2 0
      Options.h
  22. 0 2
      ProcessPaste.cpp
  23. 0 1
      ProcessPaste.h
  24. 1 1
      QListCtrl.cpp
  25. 7 30
      QPasteWnd.cpp
  26. 2 2
      QPasteWnd.h
  27. 2 0
      Shared/IClip.h

+ 13 - 0
About.cpp

@@ -90,6 +90,19 @@ BOOL CAbout::OnInitDialog()
 	cs = "            - Kevin Edwards, [email protected]";
 	m_List.AddString(cs);
 
+	m_List.AddString(_T(""));
+
+	m_List.AddString(_T("Addins"));
+
+	//Show what addins are loaded
+	CStringArray arr;
+	theApp.m_Addins.AboutScreenText(arr);
+	int count = arr.GetCount();
+	for(int i = 0; i < count; i++)
+	{
+		m_List.AddString(_T("    ") + arr[i]);
+	}
+
 	CRect rect;
 	GetClientRect(rect);
 	

+ 2 - 1
About.h

@@ -11,6 +11,7 @@
 // CAbout dialog
 
 #include "hyperlink.h"
+#include "HListBox.h"
 
 class CAbout : public CPropertyPage
 {
@@ -26,7 +27,7 @@ public:
 	enum { IDD = IDD_ABOUT };
 	CHyperLink	m_Link;
 	CHyperLink	m_HyperLink;
-	CListBox	m_List;
+	CHListBox	m_List;
 	//}}AFX_DATA
 
 

+ 3 - 3
CP_Main.cpp

@@ -904,7 +904,7 @@ int CCP_MainApp::ShowOptionsDlg()
 		int nRet = Sheet.DoModal();
 		if(nRet == IDOK)
 		{
-			m_pMainFrame->QuickPaste.ShowQPasteWnd(m_pMainFrame, false, false, TRUE);	
+			m_pMainFrame->m_quickPaste.ShowQPasteWnd(m_pMainFrame, false, false, TRUE);	
 		}
 		bShowingOptions = false;
 	}
@@ -926,9 +926,9 @@ HWND CCP_MainApp::QPastehWnd()
 { 
 	if(m_pMainFrame != NULL)
 	{
-		if(m_pMainFrame->QuickPaste.m_pwndPaste != NULL)
+		if(m_pMainFrame->m_quickPaste.m_pwndPaste != NULL)
 		{
-			return m_pMainFrame->QuickPaste.m_pwndPaste->GetSafeHwnd();
+			return m_pMainFrame->m_quickPaste.m_pwndPaste->GetSafeHwnd();
 		}
 	}
 

+ 1 - 1
CP_Main.h

@@ -143,7 +143,7 @@ public:
 	bool	m_bRefreshView;
 
 	CString m_Status;
-	CQPasteWnd* QPasteWnd() { return m_pMainFrame->QuickPaste.m_pwndPaste; }
+	CQPasteWnd* QPasteWnd() { return m_pMainFrame->m_quickPaste.m_pwndPaste; }
 	HWND QPastehWnd();
 	void SetStatus(const TCHAR* status = NULL, bool bRepaintImmediately = false);
 

+ 9 - 10
CP_Main.rc

@@ -340,7 +340,6 @@ BEGIN
         MENUITEM "View Full Description",       32793,MFT_STRING,MFS_ENABLED
         MENUITEM "View Groups",                 32819,MFT_STRING,MFS_ENABLED
         MENUITEM "Paste Plain Text Only",       32841,MFT_STRING,MFS_ENABLED
-        MENUITEM "Paste HTML as Plain Text",    32851,MFT_STRING,MFS_ENABLED
         MENUITEM MFT_SEPARATOR
         MENUITEM "Delete Entry",                32801,MFT_STRING,MFS_ENABLED
         MENUITEM MFT_SEPARATOR
@@ -752,14 +751,14 @@ BEGIN
     LTEXT           "Quick Paste Text",IDC_STATIC,7,56,62,13,SS_CENTERIMAGE
 END
 
-IDD_ABOUT DIALOG  0, 0, 292, 153
+IDD_ABOUT DIALOGEX 0, 0, 329, 153
 STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | 
     WS_SYSMENU
 CAPTION "About"
-FONT 8, "MS Shell Dlg"
+FONT 8, "MS Shell Dlg", 0, 0, 0x0
 BEGIN
-    LISTBOX         IDC_LIST,7,16,271,86,LBS_NOINTEGRALHEIGHT | WS_VSCROLL | 
-                    WS_TABSTOP
+    LISTBOX         IDC_LIST,7,16,315,86,LBS_NOINTEGRALHEIGHT | WS_VSCROLL | 
+                    WS_HSCROLL | WS_TABSTOP
     LTEXT           "E-mail Scott Brogden",IDC_HYPER_LINK,7,108,67,8
     LTEXT           "Ditto Home Page - ditto-cp.sf.net",IDC_STATIC_LINK,7,
                     126,104,8
@@ -919,8 +918,8 @@ END
 //
 
 VS_VERSION_INFO VERSIONINFO
- FILEVERSION 3,16,5,0
- PRODUCTVERSION 3,16,5,0
+ FILEVERSION 3,16,6,0
+ PRODUCTVERSION 3,16,6,0
  FILEFLAGSMASK 0x3fL
 #ifdef _DEBUG
  FILEFLAGS 0x1L
@@ -936,12 +935,12 @@ BEGIN
         BLOCK "040904b0"
         BEGIN
             VALUE "FileDescription", "Ditto"
-            VALUE "FileVersion", "3, 16, 5, 0"
+            VALUE "FileVersion", "3, 16, 6, 0"
             VALUE "InternalName", "CP_Main"
             VALUE "LegalCopyright", "Copyright (C) 2003"
             VALUE "OriginalFilename", "Ditto"
             VALUE "ProductName", "Ditto"
-            VALUE "ProductVersion", "3, 16, 5, 0"
+            VALUE "ProductVersion", "3, 16, 6, 0"
         END
     END
     BLOCK "VarFileInfo"
@@ -1034,7 +1033,7 @@ BEGIN
     IDD_ABOUT, DIALOG
     BEGIN
         LEFTMARGIN, 7
-        RIGHTMARGIN, 285
+        RIGHTMARGIN, 322
         TOPMARGIN, 7
         BOTTOMMARGIN, 146
     END

+ 8 - 2
CP_Main.vcproj

@@ -1074,6 +1074,9 @@
 						BasicRuntimeChecks="3"/>
 				</FileConfiguration>
 			</File>
+			<File
+				RelativePath=".\HListBox.cpp">
+			</File>
 			<File
 				RelativePath=".\HTMLFormatAggregator.cpp">
 			</File>
@@ -2747,6 +2750,9 @@
 			<File
 				RelativePath="GroupTree.h">
 			</File>
+			<File
+				RelativePath=".\HListBox.h">
+			</File>
 			<File
 				RelativePath=".\HTMLFormatAggregator.h">
 			</File>
@@ -2978,7 +2984,7 @@
 				</FileConfiguration>
 			</File>
 			<File
-				RelativePath="Release\focus.dll">
+				RelativePath="Debug\focus.dll">
 				<FileConfiguration
 					Name="Release|Win32"
 					ExcludedFromBuild="TRUE">
@@ -3005,7 +3011,7 @@
 				</FileConfiguration>
 			</File>
 			<File
-				RelativePath="Debug\focus.dll">
+				RelativePath="Release\focus.dll">
 				<FileConfiguration
 					Name="Release|Win32"
 					ExcludedFromBuild="TRUE">

+ 2 - 2
Clip.cpp

@@ -101,7 +101,7 @@ CClipFormat::CClipFormat(CLIPFORMAT cfType, HGLOBAL hgData, long lDBID)
 {
 	m_cfType = cfType;
 	m_hgData = hgData;
-	bDeleteData = true;
+	m_autoDeleteData = true;
 	m_lDBID = lDBID;
 }
 
@@ -119,7 +119,7 @@ void CClipFormat::Clear()
 
 void CClipFormat::Free()
 {
-	if(bDeleteData)
+	if(m_autoDeleteData)
 	{
 		if(m_hgData)
 		{

+ 4 - 2
Clip.h

@@ -36,7 +36,7 @@ class CClipFormat : public IClipFormat
 public:
 	CLIPFORMAT	m_cfType;
     HGLOBAL		m_hgData;
-	bool		bDeleteData;
+	bool		m_autoDeleteData;
 	long		m_lDBID;
 
 	CClipFormat(CLIPFORMAT cfType = 0, HGLOBAL hgData = 0, long lDBID = -1);
@@ -49,6 +49,8 @@ public:
 	virtual HGLOBAL Data() { return m_hgData; }
 	virtual void Type(CLIPFORMAT type) { m_cfType = type; }
 	virtual void Data(HGLOBAL data) { m_hgData = data; }
+	virtual void AutoDeleteData(bool autoDeleteData) { m_autoDeleteData = autoDeleteData; }
+	virtual bool AutoDeleteData()	{ return m_autoDeleteData; }
 };
 
 /*----------------------------------------------------------------------------*\
@@ -65,7 +67,7 @@ public:
 	virtual IClipFormat *GetAt(int nPos) { return &this->ElementAt(nPos); }
 	virtual void DeleteAt(int nPos) { this->RemoveAt(nPos); }
 	virtual void DeleteAll() { this->RemoveAll(); }
-	virtual int AddNew(CLIPFORMAT type, HGLOBAL data) {CClipFormat ft(type, data, -1); ft.bDeleteData = false; return this->Add(ft); }
+	virtual int AddNew(CLIPFORMAT type, HGLOBAL data) {CClipFormat ft(type, data, -1); ft.m_autoDeleteData = false; return this->Add(ft); }
 	virtual IClipFormat *FindFormatEx(CLIPFORMAT type)	{ return FindFormat((UINT)type); }
 };
 

+ 2 - 0
DittoAddin.h

@@ -16,6 +16,8 @@ public:
 	bool PrePasteFunction(const CDittoInfo &DittoInfo, CStringA Function, IClip *pClip);
 
 	CString DisplayName() { return m_DittoAddinInfo.m_Name; }
+	int Version() { return m_DittoAddinInfo.m_AddinVersion; }
+	int PrivateVersion() { return m_DittoAddinInfo.PrivateVersion(); }
 	CString LastError()	{ return m_csLastError; }
 
 protected:

+ 39 - 1
DittoAddins.cpp

@@ -82,7 +82,7 @@ bool CDittoAddins::AddPrePasteAddinsToMenu(CMenu *pMenu)
 		if(pAddin)
 		{
 			int nSubCount = pAddin->m_PrePasteFunctions.size();
-			if(nSubCount > 0)
+			if(nSubCount > 1)
 			{
 				HMENU AddinMenu = ::CreateMenu();
 				for(int x = 0; x < nSubCount; x++)
@@ -99,6 +99,21 @@ bool CDittoAddins::AddPrePasteAddinsToMenu(CMenu *pMenu)
 				::AppendMenu(AllAddinsMenu, MF_ENABLED|MF_POPUP, (UINT)AddinMenu, pAddin->DisplayName());
 				bRet = true;
 			}
+			else if(nSubCount == 1)
+			{
+				//If there is only 1 function for this add in then just show one menu with addin name - function
+				CFunctionLookup lookup;
+				lookup.m_csFunctionName = pAddin->m_PrePasteFunctions[0].m_csFunction;
+				lookup.m_pAddin = pAddin;
+				m_FunctionMap.SetAt(nMenuId, lookup);
+
+				CString menuName;
+				menuName.Format(_T("%s - %s"), pAddin->DisplayName(), pAddin->m_PrePasteFunctions[0].m_csDisplayName);
+
+				::AppendMenu(AllAddinsMenu, MF_ENABLED, nMenuId, menuName);
+				bRet = true;
+				nMenuId++;
+			}
 		}
 	}
 
@@ -133,4 +148,27 @@ void CDittoAddins::LoadDittoInfo(CDittoInfo &DittoInfo)
 	DittoInfo.m_nVersion = update.GetRunningVersion();
 	DittoInfo.m_csSqliteVersion = sqlite3_libversion();
 	DittoInfo.m_hWndDitto = theApp.QPastehWnd();
+}
+
+void CDittoAddins::AboutScreenText(CStringArray &arr)
+{
+	int nCount = m_Addins.size();
+	for(int i = 0; i < nCount; i++)
+	{
+		CDittoAddin *pAddin = m_Addins[i];
+		if(pAddin)
+		{
+			CString csLine;
+			csLine.Format(_T("%s Ver: %d, Ver2: %d"), pAddin->DisplayName(), pAddin->Version(), pAddin->PrivateVersion());
+			arr.Add(csLine);
+			int nSubCount = pAddin->m_PrePasteFunctions.size();
+			for(int x = 0; x < nSubCount; x++)
+			{
+				CString csLine2;
+				csLine2.Format(_T("    %s (%s)"), pAddin->m_PrePasteFunctions[x].m_csDisplayName, pAddin->m_PrePasteFunctions[x].m_csDetailDescription);
+				arr.Add(csLine2);
+			}
+			arr.Add("");
+		}
+	}
 }

+ 1 - 0
DittoAddins.h

@@ -17,6 +17,7 @@ public:
 
 	bool AddPrePasteAddinsToMenu(CMenu *pMenu);
 	bool CallPrePasteFunction(int Id, IClip *pClip);
+	void AboutScreenText(CStringArray &arr);
 
 protected:
 	std::vector<CDittoAddin*> m_Addins;

+ 4 - 1
DittoSetup/Changes.txt

@@ -1,4 +1,7 @@
-3.16.2.0  1-25-09
+3.16.6.0  3-12-09
+- Added DittoUtil Addin, adds the ability to paste any clip type as text
+
+3.16.5.0  3-23-09
 - Fixed SetFocus fix in ActivateTarget -- needed AttachThreadInput
 - Added the ability to create add-ins, called before an item is pasted
 - Fixed issue with getting the currently focused window when not using the hook dll

+ 6 - 7
DittoSetup/DittoSetup.iss

@@ -43,8 +43,6 @@ Name: Korean; MessagesFile: Korean.isl
 Name: RunAtStartup; Description: Run Ditto on Windows Startup
 ;Name: UseFocusDll; Description: Use System Hook to track currently focused window
 
-Name: OutlookExpressAddIn; Description: Outlook Express Add-in; GroupDescription: Add-Ins
-
 [Files]
 ;Unicode for 2000 and later
 Source: ..\Release\DittoU.exe; DestDir: {app}; DestName: Ditto.exe; Flags: ignoreversion; MinVersion: 0, 4.0
@@ -67,7 +65,12 @@ Source: mfc-crt\*; DestDir: {app}
 ;Add help files
 Source: ..\Help\*.htm; DestDir: {app}\Help; Flags: ignoreversion
 
-Source: ..\Addins\OutlookExpress\Release\OutlookExpress.dll; DestDir: {app}\Addins; Flags: ignoreversion; Tasks: OutlookExpressAddIn
+;Addins and the mfc dlls to the addins folder
+Source: ..\Addins\DittoUtil\Release\DittoUtil.dll; DestDir: {app}\Addins; Flags: ignoreversion
+Source: {app}\MFC71.dll; DestDir: {app}\Addins; Flags: ignoreversion external
+Source: {app}\mfc71u.dll; DestDir: {app}\Addins; Flags: ignoreversion external
+Source: {app}\msvcp71.dll; DestDir: {app}\Addins; Flags: ignoreversion external
+Source: {app}\msvcr71.dll; DestDir: {app}\Addins; Flags: ignoreversion external
 
 [Icons]
 Name: {group}\Ditto; Filename: {app}\Ditto.exe
@@ -84,10 +87,6 @@ Root: HKCU; Subkey: Software\Ditto; Flags: uninsdeletekey
 Root: HKCU; Subkey: SOFTWARE\Microsoft\Windows\CurrentVersion\Run; ValueType: string; ValueName: Ditto; flags: uninsdeletevalue; ValueData: {app}\Ditto.exe; Tasks: RunAtStartup
 Root: HKCU; Subkey: Software\Ditto; ValueType: string; ValueName: LanguageFile; ValueData: {language}
 
-;Always set UseHookdll to false then to true only if the task is set
-;Root: HKCU; Subkey: Software\Ditto; ValueType: dword; ValueName: UseHookDllForFocus; ValueData: 0
-;Root: HKCU; Subkey: Software\Ditto; ValueType: dword; ValueName: UseHookDllForFocus; ValueData: 1; Tasks: UseFocusDll
-
 Root: HKCU; Subkey: Software\Ditto\PasteStrings; ValueType: string; ValueName: gvim.exe; ValueData: """{{PLUS}gP"
 Root: HKCU; Subkey: Software\Ditto\CopyStrings; ValueType: string; ValueName: gvim.exe; ValueData: """{{PLUS}y"
 Root: HKCU; Subkey: Software\Ditto\CutStrings; ValueType: string; ValueName: gvim.exe; ValueData: """{{PLUS}x"

+ 68 - 36
MainFrm.cpp

@@ -131,7 +131,7 @@ int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
 	}
 	else
 	{
-		SetTimer(ACTIVE_WINDOW_TIMER, 5000, 0);
+		SetTimer(ACTIVE_WINDOW_TIMER, g_Opt.FocusWndTimerTimeout(), 0);
 	}
 	
 	SetWindowText(_T("Ditto"));
@@ -250,19 +250,19 @@ 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 && QuickPaste.IsWindowVisibleEx())
+		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"));
 			}
 
-			QuickPaste.MoveSelection(true);
+			m_quickPaste.MoveSelection(true);
 			m_bMovedSelectionMoveKeyState = true;
 		}
-		else if(g_Opt.m_HideDittoOnHotKeyIfAlreadyShown && QuickPaste.IsWindowVisibleEx())
+		else if(g_Opt.m_HideDittoOnHotKeyIfAlreadyShown && m_quickPaste.IsWindowVisibleEx())
 		{
-			QuickPaste.HideQPasteWnd();
+			m_quickPaste.HideQPasteWnd();
 		}
 		else
 		{
@@ -271,11 +271,10 @@ LRESULT CMainFrame::OnHotKey(WPARAM wParam, LPARAM lParam)
 			m_startKeyStateTime = GetTickCount();
 			m_keyStateModifiers = GetKeyStateModifiers();
 			SetTimer(KEY_STATE_MODIFIERS, 50, NULL);
-			if(g_Opt.m_bUseHookDllForFocus == false)
-			{
-				theApp.m_activeWnd.TrackActiveWnd(NULL);
-			}
-			QuickPaste.ShowQPasteWnd(this, false, true, FALSE);
+			
+			theApp.m_activeWnd.TrackActiveWnd(NULL);
+			
+			m_quickPaste.ShowQPasteWnd(this, false, true, FALSE);
 		}		
 	}
 	else if(theApp.m_pNamedCopy && wParam == theApp.m_pNamedCopy->m_Atom)
@@ -497,7 +496,7 @@ void CMainFrame::OnTimer(UINT nIDEvent)
 		}
 	case CLOSE_WINDOW_TIMER:
 		{
-			QuickPaste.CloseQPasteWnd();
+			m_quickPaste.CloseQPasteWnd();
 			break;
 		}
 	case REMOVE_OLD_ENTRIES_TIMER:
@@ -578,12 +577,12 @@ void CMainFrame::OnTimer(UINT nIDEvent)
 				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));
-					QuickPaste.OnKeyStateUp();
+					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));
-					QuickPaste.SetKeyModiferState(false);
+					m_quickPaste.SetKeyModiferState(false);
 				}
 
 				m_keyStateModifiers = 0;
@@ -597,7 +596,10 @@ void CMainFrame::OnTimer(UINT nIDEvent)
 		}
 		break;
 	case ACTIVE_WINDOW_TIMER:
-		theApp.m_activeWnd.TrackActiveWnd(NULL);
+		if(m_quickPaste.IsWindowVisibleEx())
+		{
+			theApp.m_activeWnd.TrackActiveWnd(NULL);
+		}
 		break;
 
 	case FOCUS_CHANGED_TIMER:
@@ -653,7 +655,7 @@ LRESULT CMainFrame::OnShowTrayIcon(WPARAM wParam, LPARAM lParam)
 
 void CMainFrame::OnFirstShowquickpaste() 
 {
-	QuickPaste.ShowQPasteWnd(this, true, false, FALSE);
+	m_quickPaste.ShowQPasteWnd(this, true, false, FALSE);
 }
 
 void CMainFrame::OnFirstToggleConnectCV()
@@ -794,7 +796,7 @@ LRESULT CMainFrame::OnAddToDatabaseFromSocket(WPARAM wParam, LPARAM lParam)
 			CProcessPaste paste;
 			//Don't send the paste just load it into memory
 			paste.m_bSendPaste = false;
-			paste.m_pOle->PutFormatOnClipboard(&NewClip.m_Formats, false);
+			paste.m_pOle->PutFormatOnClipboard(&NewClip.m_Formats);
 			paste.m_pOle->CacheGlobalData(theApp.m_cfIgnoreClipboard, NewGlobalP("Ignore", sizeof("Ignore")));
 
 			LogSendRecieveInfo("---------After LoadFormats");
@@ -919,33 +921,63 @@ LRESULT CMainFrame::OnKeyBoardChanged(WPARAM wParam, LPARAM lParam)
 	return TRUE;
 }
 
-LRESULT CMainFrame::OnFocusChanged(WPARAM wParam, LPARAM lParam)
+CString WndName(HWND hParent) 
 {
-	HWND focus = (HWND)wParam;
-	static DWORD dLastDittoHasFocusTick = 0;
+	TCHAR cWindowText[200];
 
-	//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)
+	::GetWindowText(hParent, cWindowText, 100);
+
+	int nCount = 0;
+
+	while(STRLEN(cWindowText) <= 0)
 	{
-		Log(_T("NULL focus received"));
+		hParent = ::GetParent(hParent);
+		if(hParent == NULL)
+			break;
+
+		::GetWindowText(hParent, cWindowText, 100);
+
+		nCount++;
+		if(nCount > 100)
+		{
+			Log(_T("GetTargetName reached maximum search depth of 100"));
+			break;
+		}
 	}
 
-	if(theApp.m_activeWnd.DittoHasFocus())
+	return cWindowText; 
+}
+
+LRESULT CMainFrame::OnFocusChanged(WPARAM wParam, LPARAM lParam)
+{
+	if(m_quickPaste.IsWindowVisibleEx())
 	{
-		dLastDittoHasFocusTick = GetTickCount();
-	}
+		HWND focus = (HWND)wParam;
+		static DWORD dLastDittoHasFocusTick = 0;
 
-	//Log(StrF(_T("OnFocusChanged %d"), focus));
-	m_tempFocusWnd = focus;
+		//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(theApp.m_activeWnd.DittoHasFocus())
+		{
+			dLastDittoHasFocusTick = GetTickCount();
+		}
+
+		//Log(StrF(_T("OnFocusChanged %d, title %s"), focus, WndName(focus)));
+		m_tempFocusWnd = focus;
 
-	KillTimer(FOCUS_CHANGED_TIMER);
-	SetTimer(FOCUS_CHANGED_TIMER, g_Opt.FocusChangedDelay(), NULL);
+		KillTimer(FOCUS_CHANGED_TIMER);
+		SetTimer(FOCUS_CHANGED_TIMER, g_Opt.FocusChangedDelay(), NULL);
+	}
 
 	return TRUE;
 }
@@ -985,7 +1017,7 @@ bool CMainFrame::PasteQuickPasteEntry(CString csQuickPaste)
 			if(Clip.LoadFormats(q.getIntField(_T("lID"))))
 			{
 				CProcessPaste paste;
-				paste.m_pOle->PutFormatOnClipboard(&Clip.m_Formats, false);
+				paste.m_pOle->PutFormatOnClipboard(&Clip.m_Formats);
 				paste.m_pOle->CacheGlobalData(theApp.m_cfIgnoreClipboard, NewGlobalP("Ignore", sizeof("Ignore")));
 					
 				if(paste.DoPaste())

+ 1 - 1
MainFrm.h

@@ -59,7 +59,7 @@ public:
 	virtual void Dump(CDumpContext& dc) const;
 #endif
 
-	CQuickPaste QuickPaste;
+	CQuickPaste m_quickPaste;
 	CSystemTray m_TrayIcon;
 	ULONG m_ulCopyGap;
 	CString m_csKeyboardPaste;

+ 46 - 0
Misc.cpp

@@ -1505,4 +1505,50 @@ CString GetProcessName(HWND hWnd)
 	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;
 }

+ 3 - 0
Misc.h

@@ -331,5 +331,8 @@ __inline BOOL FileExists(LPCTSTR pszFile)
 	return (GetFileAttributes(pszFile) != 0xffffffff); 
 }
 
+bool IsRunningLimited();
+BOOL IsVista();
+
 
 #endif // !defined(AFX_CP_GUI_GLOBALS__FBCDED09_A6F2_47EB_873F_50A746EBC86B__INCLUDED_)

+ 5 - 48
OleClipSource.cpp

@@ -16,7 +16,6 @@ COleClipSource::COleClipSource()
 {
 	m_bLoadedFormats = false;
 	m_bOnlyPaste_CF_TEXT = false;
-	m_bPasteHTMLFormatAs_CF_TEXT = false;
 	m_pCustomPasteFormats = NULL;
 }
 
@@ -48,7 +47,7 @@ BOOL COleClipSource::DoImmediateRender()
 
 	if(m_pCustomPasteFormats != NULL)
 	{
-		return PutFormatOnClipboard(m_pCustomPasteFormats, m_bPasteHTMLFormatAs_CF_TEXT);
+		return PutFormatOnClipboard(m_pCustomPasteFormats);
 	}
 	
 	int count = m_ClipIDs.GetSize();
@@ -107,65 +106,23 @@ BOOL COleClipSource::DoImmediateRender()
 
 		clip.LoadFormats(m_ClipIDs[0], m_bOnlyPaste_CF_TEXT);
 		
-		return PutFormatOnClipboard(&clip.m_Formats, m_bPasteHTMLFormatAs_CF_TEXT);
+		return PutFormatOnClipboard(&clip.m_Formats);
 	}		
 
 	return bProcessedMult;
 }
 
-long COleClipSource::PutFormatOnClipboard(CClipFormats *pFormats, bool bPasteHTMLFormatAs_CF_TEXT)
+long COleClipSource::PutFormatOnClipboard(CClipFormats *pFormats)
 {
 	CClipFormat* pCF;
-	bool bDelayedRenderCF_HDROP = false;
 	int	count = pFormats->GetSize();
 	int i = 0;
 
-	//see if the html format is in the list
-	//if it is the list we will not paste CF_TEXT
 	for(i = 0; i < count; i++)
 	{
 		pCF = &pFormats->ElementAt(i);
 
-		if(bPasteHTMLFormatAs_CF_TEXT)
-		{
-			if(pCF->m_cfType == theApp.m_HTML_Format)
-				break;
-		}
-
-		if(pCF->m_cfType == theApp.m_RemoteCF_HDROP)
-		{
-			bDelayedRenderCF_HDROP = true;
-		}
-	}
-
-	//Didn't find html format
-	if(i == count)
-		bPasteHTMLFormatAs_CF_TEXT = false;
-	
-	for(i = 0; i < count; i++)
-	{
-		pCF = &pFormats->ElementAt(i);
-
-		if(bDelayedRenderCF_HDROP)
-		{
-			if(pCF->m_cfType == CF_HDROP)
-			{
-				DelayRenderData(pCF->m_cfType);
-			}
-
-			continue;
-		}
-		
-		if(bPasteHTMLFormatAs_CF_TEXT)
-		{
-			if(pCF->m_cfType == CF_TEXT)
-				continue;
-
-			if(pCF->m_cfType == theApp.m_HTML_Format)
-				pCF->m_cfType = CF_TEXT;
-		}
-
-		CacheGlobalData( pCF->m_cfType, pCF->m_hgData );
+		CacheGlobalData(pCF->m_cfType, pCF->m_hgData);
 		pCF->m_hgData = 0; // OLE owns it now
 	}
 
@@ -238,7 +195,7 @@ BOOL COleClipSource::OnRenderGlobalData(LPFORMATETC lpFormatEtc, HGLOBAL* phGlob
 		}
 
 		CClipFormat format(lpFormatEtc->cfFormat, hCopy);
-		format.bDeleteData = false; //owned by m_DelayRenderedFormats
+		format.m_autoDeleteData = false; //owned by m_DelayRenderedFormats
 		m_DelayRenderedFormats.Add(format);
 	}
 

+ 1 - 2
OleClipSource.h

@@ -13,7 +13,6 @@ public:
 	CClipIDs	m_ClipIDs;
 	bool		m_bLoadedFormats;
 	bool		m_bOnlyPaste_CF_TEXT;
-	bool		m_bPasteHTMLFormatAs_CF_TEXT;
 	CClipFormats *m_pCustomPasteFormats;
 
 	COleClipSource();
@@ -21,7 +20,7 @@ public:
 
 	BOOL DoDelayRender();
 	BOOL DoImmediateRender();
-	long PutFormatOnClipboard(CClipFormats *pFormats, bool bPasteHTMLFormatAs_CF_TEXT);
+	long PutFormatOnClipboard(CClipFormats *pFormats);
 
 public:
 	virtual BOOL OnRenderGlobalData(LPFORMATETC lpFormatEtc, HGLOBAL* phGlobal);

+ 49 - 26
Options.cpp

@@ -134,12 +134,23 @@ void CGetSetOptions::LoadSettings()
 	m_csIPListToPutOnClipboard = GetListToPutOnClipboard();
 	m_bLogSendReceiveErrors = GetLogSendReceiveErrors();
 	
-	//If running from U3 then we can't use the hook dll because we are unable
-	//to delete the hook dll, it's loaded by other processes
-	if(m_bU3)
-		m_bUseHookDllForFocus = GetProfileLong("UseHookDllForFocus", FALSE);
+	if(IsRunningLimited() == false)
+	{
+		//If running from U3 then we can't use the hook dll because we are unable
+		//to delete the hook dll, it's loaded by other processes
+		if(m_bU3)
+		{
+			m_bUseHookDllForFocus = GetProfileLong("UseHookDllForFocus", FALSE);
+		}
+		else
+		{
+			m_bUseHookDllForFocus = GetProfileLong("UseHookDllForFocus", TRUE);
+		}
+	}
 	else
-		m_bUseHookDllForFocus = GetProfileLong("UseHookDllForFocus", TRUE);
+	{
+		m_bUseHookDllForFocus = false;
+	}
 
 	m_HideDittoOnHotKeyIfAlreadyShown = GetHideDittoOnHotKeyIfAlreadyShown();
 	m_lPort = GetPort();
@@ -161,10 +172,6 @@ void CGetSetOptions::LoadSettings()
 
 	GetExtraNetworkPassword(true);
 
-#ifdef _DEBUG
-	//m_bUseHookDllForFocus = FALSE;
-#endif
-
 	for(int i = 0; i < MAX_SEND_CLIENTS; i++)
 	{
 		GetSendClients(i);
@@ -330,28 +337,36 @@ CString CGetSetOptions::GetIniFileName(bool bLocalIniFile)
 		}
 		else
 		{
-			LPMALLOC pMalloc;
+			csPath = GetAppDataPath();
+		}
+	}
 
-			if(SUCCEEDED(::SHGetMalloc(&pMalloc))) 
-			{ 
-				LPITEMIDLIST pidlPrograms;
+	csPath += "Ditto.Settings";
 
-				SHGetSpecialFolderLocation(NULL, CSIDL_APPDATA, &pidlPrograms);
+	return csPath;
+}
 
-				TCHAR string[MAX_PATH];
-				SHGetPathFromIDList(pidlPrograms, string);
+CString CGetSetOptions::GetAppDataPath()
+{
+	CString csPath;
+	LPMALLOC pMalloc;
 
-				pMalloc->Free(pidlPrograms);
-				pMalloc->Release();
+	if(SUCCEEDED(::SHGetMalloc(&pMalloc))) 
+	{ 
+		LPITEMIDLIST pidlPrograms;
 
-				csPath = string;		
-			}
-			FIX_CSTRING_PATH(csPath);
-			csPath += "Ditto\\";
-		}
-	}
+		SHGetSpecialFolderLocation(NULL, CSIDL_APPDATA, &pidlPrograms);
 
-	csPath += "Ditto.Settings";
+		TCHAR string[MAX_PATH];
+		SHGetPathFromIDList(pidlPrograms, string);
+
+		pMalloc->Free(pidlPrograms);
+		pMalloc->Release();
+
+		csPath = string;		
+	}
+	FIX_CSTRING_PATH(csPath);
+	csPath += "Ditto\\";
 
 	return csPath;
 }
@@ -1662,10 +1677,13 @@ CString CGetSetOptions::GetPath(long lPathID)
 			csDir = GETENV(_T("U3_HOST_EXEC_PATH"));
 			FIX_CSTRING_PATH(csDir);
 		}
+		else
+		{
+			csDir = GetAppDataPath();
+		}
 
 		break;
 
-
 	case PATH_UPDATE_FILE:
 		//same path as the executable
 		break;
@@ -1886,4 +1904,9 @@ DWORD CGetSetOptions::WaitForActiveWndTimeout()
 DWORD CGetSetOptions::FocusChangedDelay()
 {
 	return (DWORD)GetProfileLong(_T("FocusChangedDelay"), 100);
+}
+
+DWORD CGetSetOptions::FocusWndTimerTimeout()
+{
+	return (DWORD)GetProfileLong(_T("FocusWndTimerTimeout"), 2000);
 }

+ 2 - 0
Options.h

@@ -75,6 +75,7 @@ public:
 	static void LoadSettings();
 	static CString GetIniFileName(bool bLocalIniFile);
 	static void ConverSettingsToIni();
+	static CString GetAppDataPath();
 
 	static CString GetExeFileName();
 	static CString GetAppName();
@@ -386,6 +387,7 @@ public:
 	static DWORD	SendKeysDelay();
 	static DWORD	WaitForActiveWndTimeout();
 	static DWORD	FocusChangedDelay();
+	static DWORD	FocusWndTimerTimeout();
 };
 
 // global for easy access and for initialization of fast access variables

+ 0 - 2
ProcessPaste.cpp

@@ -15,7 +15,6 @@ CProcessPaste::CProcessPaste()
 	m_bSendPaste = true;
 	m_bActivateTarget = true;
 	m_bOnlyPaste_CF_TEXT = false;
-	m_bPasteHTMLFormatAs_CF_TEXT = false;
 }
 
 CProcessPaste::~CProcessPaste()
@@ -26,7 +25,6 @@ CProcessPaste::~CProcessPaste()
 BOOL CProcessPaste::DoPaste()
 {
 	m_pOle->m_bOnlyPaste_CF_TEXT = m_bOnlyPaste_CF_TEXT;
-	m_pOle->m_bPasteHTMLFormatAs_CF_TEXT = m_bPasteHTMLFormatAs_CF_TEXT;
 
 	if(m_pOle->DoImmediateRender())
 	{

+ 0 - 1
ProcessPaste.h

@@ -25,7 +25,6 @@ public:
 	bool m_bSendPaste;
 	bool m_bActivateTarget;
 	bool m_bOnlyPaste_CF_TEXT;
-	bool m_bPasteHTMLFormatAs_CF_TEXT;
 
 	CProcessPaste();
 	~CProcessPaste();

+ 1 - 1
QListCtrl.cpp

@@ -623,7 +623,7 @@ BOOL CQListCtrl::DrawBitMap(int nItem, CRect &crRect, CDC *pDC)
 		HPALETTE hPal = NULL;
 		pThumbnail->m_hgData = CBitmapHelper::hBitmapToDIB( (HBITMAP)Bitmap, BI_RGB, hPal );
 
-		ASSERT( pThumbnail->bDeleteData ); // the map owns the data.
+		ASSERT( pThumbnail->m_autoDeleteData ); // the map owns the data.
 
 		Bitmap.DeleteObject();
 	}

+ 7 - 30
QPasteWnd.cpp

@@ -143,7 +143,6 @@ BEGIN_MESSAGE_MAP(CQPasteWnd, CWndEx)
 	ON_COMMAND(ID_MENU_QUICKOPTIONS_FINDASYOUTYPE, OnMenuQuickoptionsFindasyoutype)
 	ON_COMMAND(ID_MENU_QUICKOPTIONS_ENSUREENTIREWINDOWISVISIBLE, OnMenuQuickoptionsEnsureentirewindowisvisible)
 	ON_COMMAND(ID_MENU_QUICKOPTIONS_SHOWCLIPSTHATAREINGROUPSINMAINLIST, OnMenuQuickoptionsShowclipsthatareingroupsinmainlist)
-	ON_COMMAND(ID_MENU_PASTEHTMLASPLAINTEXT, OnMenuPastehtmlasplaintext)
 	ON_UPDATE_COMMAND_UI(ID_MENU_NEWGROUP, OnUpdateMenuNewgroup)
 	ON_UPDATE_COMMAND_UI(ID_MENU_NEWGROUPSELECTION, OnUpdateMenuNewgroupselection)
 	ON_UPDATE_COMMAND_UI(ID_MENU_ALLWAYSONTOP, OnUpdateMenuAllwaysontop)
@@ -552,7 +551,7 @@ bool CQPasteWnd::Add(const CString &csHeader, const CString &csText, int nID)
 	return true;
 }
 
-BOOL CQPasteWnd::OpenID(long lID, bool bOnlyLoad_CF_TEXT, bool bPasteHTMLAs_CF_TEXT, CClipFormats *pPasteFormats)
+BOOL CQPasteWnd::OpenID(long lID, bool bOnlyLoad_CF_TEXT, CClipFormats *pPasteFormats)
 {
 	if(pPasteFormats == NULL)
 	{
@@ -570,7 +569,6 @@ BOOL CQPasteWnd::OpenID(long lID, bool bOnlyLoad_CF_TEXT, bool bPasteHTMLAs_CF_T
 	
 	paste.m_bSendPaste = g_Opt.m_bSendPasteMessageAfterSelection == TRUE ? true : false;
 	paste.m_bOnlyPaste_CF_TEXT = bOnlyLoad_CF_TEXT;
-	paste.m_bPasteHTMLFormatAs_CF_TEXT = bPasteHTMLAs_CF_TEXT;
 
 	if(pPasteFormats != NULL)
 	{
@@ -592,7 +590,7 @@ BOOL CQPasteWnd::OpenID(long lID, bool bOnlyLoad_CF_TEXT, bool bPasteHTMLAs_CF_T
 	return TRUE;
 }
 
-BOOL CQPasteWnd::OpenSelection(bool bOnlyLoad_CF_TEXT, bool bPasteHTMLAs_CF_TEXT)
+BOOL CQPasteWnd::OpenSelection(bool bOnlyLoad_CF_TEXT)
 {
 	ARRAY IDs;
 	m_lstHeader.GetSelectionItemData( IDs );
@@ -603,7 +601,7 @@ BOOL CQPasteWnd::OpenSelection(bool bOnlyLoad_CF_TEXT, bool bPasteHTMLAs_CF_TEXT
 		return FALSE;
 	
 	if(count == 1)
-		return OpenID(IDs[0], bOnlyLoad_CF_TEXT, bPasteHTMLAs_CF_TEXT);
+		return OpenID(IDs[0], bOnlyLoad_CF_TEXT);
 
 	if(GetKeyState(VK_SHIFT) & 0x8000)
 	{
@@ -614,7 +612,6 @@ BOOL CQPasteWnd::OpenSelection(bool bOnlyLoad_CF_TEXT, bool bPasteHTMLAs_CF_TEXT
 
 	paste.m_bSendPaste = g_Opt.m_bSendPasteMessageAfterSelection == TRUE ? true : false;
 	paste.m_bOnlyPaste_CF_TEXT = bOnlyLoad_CF_TEXT;
-	paste.m_bPasteHTMLFormatAs_CF_TEXT = bPasteHTMLAs_CF_TEXT;
 	
 	paste.GetClipIDs().Copy(IDs);
 	paste.DoPaste();
@@ -720,7 +717,7 @@ LRESULT CQPasteWnd::OnListSelect(WPARAM wParam, LPARAM lParam)
 	int nCount = (int) wParam;
 	long *pItems = (long*) lParam;
 	
-	OpenSelection(false, false);
+	OpenSelection(false);
 	
 	return TRUE;
 }
@@ -1675,12 +1672,7 @@ void CQPasteWnd::OnMenuGroupsMovetogroup()
 
 void CQPasteWnd::OnMenuPasteplaintextonly() 
 {
-	OpenSelection(true, false);	
-}
-
-void CQPasteWnd::OnMenuPastehtmlasplaintext() 
-{
-	OpenSelection(false, true);
+	OpenSelection(true);	
 }
 
 void CQPasteWnd::OnPromptToDeleteClip() 
@@ -3083,7 +3075,7 @@ void CQPasteWnd::OnTimer(UINT_PTR nIDEvent)
 		if(m_bModifersMoveActive)
 		{
 			Log(_T("Open Selection\n"));
-			OpenSelection(false, false);
+			OpenSelection(false);
 		}
 		else
 		{
@@ -3096,21 +3088,6 @@ void CQPasteWnd::OnTimer(UINT_PTR nIDEvent)
 
 void CQPasteWnd::OnAddinSelect(UINT id)
 {
-	/*if((GetKeyState(VK_SHIFT) & 0x8000) &&
-		(GetKeyState(VK_CONTROL) & 0x8000))
-	{
-		if(theApp.m_Addins.Loaded())
-		{
-			theApp.m_Addins.UnloadAll();
-			MessageBox(_T("Addin Unloaded"));
-		}
-		else
-		{
-			theApp.m_Addins.LoadAll();
-			MessageBox(_T("Addin Loaded"));
-		}
-	}*/
-
 	ARRAY IDs;
 	m_lstHeader.GetSelectionItemData(IDs);
 
@@ -3125,7 +3102,7 @@ void CQPasteWnd::OnAddinSelect(UINT id)
 				bool bCont = theApp.m_Addins.CallPrePasteFunction(id, &clip);
 				if(bCont)
 				{
-					OpenID(-1, false, false, &clip.m_Formats);
+					OpenID(-1, false, &clip.m_Formats);
 				}
 			}
 		}

+ 2 - 2
QPasteWnd.h

@@ -115,8 +115,8 @@ public:
 
 	void DeleteSelectedRows();
 
-	BOOL OpenID(long lID, bool bOnlyLoad_CF_TEXT = false, bool bPasteHTMLAs_CF_TEXT = false, CClipFormats *pPasteFormats = NULL);
-	BOOL OpenSelection(bool bOnlyLoad_CF_TEXT = false, bool bPasteHTMLAs_CF_TEXT = false);
+	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 );
 	// moves the caret to the given ID, selects it, and ensures it is visible.

+ 2 - 0
Shared/IClip.h

@@ -8,8 +8,10 @@ class IClipFormat
 public:
 	virtual CLIPFORMAT Type() = 0;
 	virtual HGLOBAL Data() = 0;
+	virtual bool AutoDeleteData() = 0;
 	virtual void Type(CLIPFORMAT type) = 0;
 	virtual void Data(HGLOBAL data) = 0;
+	virtual void AutoDeleteData(bool autoDelete) = 0;
 };
 
 //Contains a list of IClipFormats