Browse Source

first pass at add-ins
[SAB]


git-svn-id: svn://svn.code.sf.net/p/ditto-cp/code/trunk@435 595ec19a-5cb4-439b-94a8-42fb3063c22c

sabrogden 17 years ago
parent
commit
d1ccf1413a

+ 16 - 32
CP_Main.cpp

@@ -265,6 +265,8 @@ BOOL CCP_MainApp::InitInstance()
 	// prevent no one having focus on startup
 	ReleaseFocus();
 
+	m_Addins.LoadAll();
+
 	return TRUE;
 }
 
@@ -412,40 +414,9 @@ bool CCP_MainApp::TargetActiveWindow()
 
 bool CCP_MainApp::ActivateTarget()
 {
-//	HWND top = m_hTargetWnd;
-//	HWND next = ::GetParent(top);
-//	while( next != NULL )
-//	{
-//		top = next;
-//		next = ::GetParent(top);
-//	}
-
-    DWORD tidTarget = ::GetWindowThreadProcessId( m_hTargetWnd, NULL );
-    DWORD tidSelf = ::GetCurrentThreadId();
-
-    // We can't set the focus window from another thread,
-	// so we have to attach to the thread input first:
-	::AttachThreadInput( tidTarget, tidSelf, TRUE );
-
-//    ::SetWindowPos( top, 0, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE );
-//    ::SetForegroundWindow( top );
-//    ::SetForegroundWindow( m_hTargetWnd );
+	::SetForegroundWindow(m_hTargetWnd);
 	::SetFocus(m_hTargetWnd);
 
-//	Log( StrF(
-//		_T("ActivateTarget - AFTER:") \
-//		_T("\n\tm_hTargetWnd = %s") \
-//		_T("\n\tGetForegroundWindow = %s") \
-//		_T("\n\tGetActiveWindow = %s") \
-//		_T("\n\tGetFocus = %s\n"),
-//			GetParentsString(m_hTargetWnd),
-//			GetParentsString(::GetForegroundWindow()),
-//			GetParentsString(::GetActiveWindow()),
-//			GetParentsString(::GetFocus()) ) );
-
-    // Detach from thread input
-	::AttachThreadInput( tidTarget, tidSelf, FALSE );
-
 	return true;
 }
 
@@ -1173,4 +1144,17 @@ void CCP_MainApp::PumpMessageEx()
 		::TranslateMessage(&KeyboardMsg);
 		::DispatchMessage(&KeyboardMsg);
 	}
+}
+
+HWND CCP_MainApp::QPastehWnd() 
+{ 
+	if(m_pMainFrame != NULL)
+	{
+		if(m_pMainFrame->QuickPaste.m_pwndPaste != NULL)
+		{
+			return m_pMainFrame->QuickPaste.m_pwndPaste->GetSafeHwnd();
+		}
+	}
+
+	return NULL;
 }

+ 4 - 0
CP_Main.h

@@ -25,6 +25,7 @@
 #include "ClipboardSaveRestore.h"
 #include "DittoCopyBuffer.h"
 #include "sqlite\CppSQLite3.h"
+#include "DittoAddins.h"
 
 //#define GET_APP ((CMainWnd*)theApp)
 extern class CCP_MainApp theApp;
@@ -150,6 +151,7 @@ public:
 
 	CString m_Status;
 	CQPasteWnd* QPasteWnd() { return m_pMainFrame->QuickPaste.m_pwndPaste; }
+	HWND QPastehWnd();
 	void SetStatus(const TCHAR* status = NULL, bool bRepaintImmediately = false);
 
 	void ShowPersistent(bool bVal);
@@ -191,6 +193,8 @@ public:
 	CDittoCopyBuffer m_CopyBuffer;
 	void PumpMessageEx();
 
+	CDittoAddins m_Addins;
+
 protected:
 // Overrides
 	// ClassWizard generated virtual function overrides

+ 15 - 0
CP_Main.vcproj

@@ -804,6 +804,12 @@
 						BasicRuntimeChecks="3"/>
 				</FileConfiguration>
 			</File>
+			<File
+				RelativePath=".\DittoAddin.cpp">
+			</File>
+			<File
+				RelativePath=".\DittoAddins.cpp">
+			</File>
 			<File
 				RelativePath=".\DittoCopyBuffer.cpp">
 				<FileConfiguration
@@ -2693,9 +2699,18 @@
 			<File
 				RelativePath="DialogResizer.h">
 			</File>
+			<File
+				RelativePath=".\DittoAddin.h">
+			</File>
+			<File
+				RelativePath=".\DittoAddins.h">
+			</File>
 			<File
 				RelativePath=".\DittoCopyBuffer.h">
 			</File>
+			<File
+				RelativePath=".\Shared\DittoDefines.h">
+			</File>
 			<File
 				RelativePath=".\DittoRulerRichEditCtrl.h">
 			</File>

+ 29 - 3
Clip.h

@@ -11,6 +11,7 @@
 #include <afxole.h>
 #include <afxtempl.h>
 #include "tinyxml.h"
+#include "Shared\IClip.h"
 
 class CClip;
 class CCopyThread;
@@ -30,7 +31,7 @@ public:
 /*----------------------------------------------------------------------------*\
 	CClipFormat - holds the data of one clip format.
 \*----------------------------------------------------------------------------*/
-class CClipFormat
+class CClipFormat : public IClipFormat
 {
 public:
 	CLIPFORMAT	m_cfType;
@@ -43,17 +44,29 @@ public:
 
 	void Clear();
 	void Free();
+
+	virtual CLIPFORMAT Type() { return m_cfType; }
+	virtual HGLOBAL Data() { return m_hgData; }
+	virtual void Type(CLIPFORMAT type) { m_cfType = type; }
+	virtual void Data(HGLOBAL data) { m_hgData = data; }
 };
 
 /*----------------------------------------------------------------------------*\
 	CClipFormats - holds an array of CClipFormat
 \*----------------------------------------------------------------------------*/
-class CClipFormats : public CArray<CClipFormat,CClipFormat&>
+class CClipFormats : public CArray<CClipFormat,CClipFormat&>, public IClipFormats
 {
 public:
 	// returns a pointer to the CClipFormat in this array which matches the given type
 	//  or NULL if that type doesn't exist in this array.
 	CClipFormat* FindFormat(UINT cfType); 
+
+	virtual int Size() { return this->GetCount(); }
+	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 IClipFormat *FindFormatEx(CLIPFORMAT type)	{ return FindFormat((UINT)type); }
 };
 
 
@@ -61,7 +74,7 @@ public:
 	CClip - holds multiple CClipFormats and clip statistics
 	- provides static functions for manipulating a Clip as a single unit.
 \*----------------------------------------------------------------------------*/
-class CClip
+class CClip : public IClip
 {
 public:
 	CClip();
@@ -83,6 +96,19 @@ public:
 	DWORD m_CRC;
 	CString m_csQuickPaste;
 
+	virtual CString Description() { return m_Desc; }
+	virtual void Description(CString csValue) { m_Desc = csValue; }
+	virtual CTime PasteTime() { return m_Time; }
+	virtual int ID() { return m_ID; }
+	virtual int Parent() { return m_lParent; }
+	virtual void Parent(int nParent) { m_lParent = nParent; }
+	virtual int DontAutoDelete() { return m_lDontAutoDelete; }
+	virtual void DontAutoDelete(int Dont) { m_lDontAutoDelete = Dont; }
+	virtual CString QuickPaste() { return m_csQuickPaste; }
+	virtual void QuickPaste(CString csValue) { m_csQuickPaste = csValue; }
+
+	virtual IClipFormats *Clips() { return (IClipFormats*)&m_Formats; }
+
 	void Clear();
 	void EmptyFormats();
 	bool AddFormat(CLIPFORMAT cfType, void* pData, UINT nLen);

+ 1 - 1
CopyProperties.cpp

@@ -193,7 +193,7 @@ void CCopyProperties::OnOK()
 			int nCount = m_DeletedData.GetSize();
 			for(int i = 0; i < nCount; i++)
 			{
-				m_pMemoryClip->m_Formats.RemoveAt(m_DeletedData[i], 1);
+				m_pMemoryClip->m_Formats.RemoveAt(m_DeletedData[i]);
 			}
 		}
 		else

+ 1 - 1
Debug/Language/Chinese Traditional.xml

@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="Ascii"?>
-<Ditto_Language_File Version = "1" Author = "Minson" Notes = "http://sulatio.blogspot.com">
+<Ditto_Language_File Version = "1" Author = "Minson" Notes = "http://sulatio.blogspot.com" LanguageCode = "chi">
 	<Ditto_Right_Click_Menu>
 		<Item English_Text = "Groups" ID = "-1">¸s²Õ</Item>
 		<Item English_Text = "New Group	Ctrl-F7" ID = "32811">·s«Ø¸s²Õ</Item>

+ 1 - 1
Debug/Language/Chinese.xml

@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="Ascii"?>
-<Ditto_Language_File Version = "1" Author = "石珊珊(Shi ShanShan)" Notes = "此中文语言文件根据Ditto_03.15.01.00版本自带的英文语言文件制作翻译而成。部分选项标签和菜单由于软件作者未在英文语言文件中给出翻译用接口,故未能译为中文。翻译风格直译与意译结合,部分语句考虑到在菜单或窗口显示长度的问题,有做精简处理。本人现今博客:hi.baidu.com/ttzm33 常用邮箱:[email protected] 欢迎指正交流~:-)2007年11月14日注">
+<Ditto_Language_File Version = "1" Author = "石珊珊(Shi ShanShan)" Notes = "此中文语言文件根据Ditto_03.15.01.00版本自带的英文语言文件制作翻译而成。部分选项标签和菜单由于软件作者未在英文语言文件中给出翻译用接口,故未能译为中文。翻译风格直译与意译结合,部分语句考虑到在菜单或窗口显示长度的问题,有做精简处理。本人现今博客:hi.baidu.com/ttzm33 常用邮箱:[email protected] 欢迎指正交流~:-)2007年11月14日注" LanguageCode = "chi">
 	<Ditto_Right_Click_Menu>
 		<Item English_Text = "Groups" ID = "-1">组</Item>
 		<Item English_Text = "New Group	Ctrl-F7" ID = "32811">新建组</Item>

+ 1 - 1
Debug/Language/Croatian.xml

@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="Ascii"?>
-<Ditto_Language_File Version = "1" Author = "Robert Dragicevic" Notes = "[email protected]">
+<Ditto_Language_File Version = "1" Author = "Robert Dragicevic" Notes = "[email protected]" LanguageCode = "hrv">
 	<Ditto_Right_Click_Menu>
 		<Item English_Text = "Groups" ID = "-1">Skupina</Item>
 		<Item English_Text = "New Group Ctrl-F7" ID = "32811">Nova skupina Ctrl-F7</Item>

+ 1 - 1
Debug/Language/Dutch.xml

@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="Ascii"?>
-<Ditto_Language_File Version = "2" Author = "Rob Meijer" Notes = "[email protected]">
+<Ditto_Language_File Version = "2" Author = "Rob Meijer" Notes = "[email protected]" LanguageCode = "dut">
 	<Ditto_Right_Click_Menu>
 		<Item English_Text = "Groups" ID = "-1">Groepen</Item>		
 		<Item English_Text = "New Group Ctrl-F7" ID = "32811">Nieuwe Groep</Item>		

+ 1 - 1
Debug/Language/English.xml

@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="Ascii"?>
-<Ditto_Language_File Version = "1" Author = "Scott Brogden" Notes = "">
+<Ditto_Language_File Version = "1" Author = "Scott Brogden" Notes = "" LanguageCode = "eng">
 	<Ditto_Right_Click_Menu>
 		<Item English_Text = "Groups" ID = "-1"></Item>
 		<Item English_Text = "New Group	Ctrl-F7" ID = "32811"></Item>

+ 1 - 1
Debug/Language/French.xml

@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<Ditto_Language_File Version = "1" Author = "Alain AUPEIX" Notes = "http://perso.wanadoo.fr/jujuland/">
+<Ditto_Language_File Version = "1" Author = "Alain AUPEIX" Notes = "http://perso.wanadoo.fr/jujuland/" LanguageCode="fre">
 	<Ditto_Right_Click_Menu>
 		<Item English_Text = "Groups" ID = "-1">Groupes</Item>
 		<Item English_Text = "New Group	Ctrl-F7" ID = "32811">Nouveau Groupe Ctrl-F7</Item>

+ 1 - 1
Debug/Language/German.xml

@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<Ditto_Language_File Version = "1.1" Author = "Stephan Jaeger" Notes = "">
+<Ditto_Language_File Version = "1.1" Author = "Stephan Jaeger" Notes = "" LanguageCode="ger">
 	<Ditto_Right_Click_Menu>
 		<Item English_Text = "Groups" ID = "-1">Gruppen</Item>
 		<Item English_Text = "New Group	Ctrl-F7" ID = "32811">Neue Gruppe STRG-F7</Item>

+ 1 - 1
Debug/Language/Japanese.xml

@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<Ditto_Language_File Version = "1" Author = "Nardog" Notes = "">
+<Ditto_Language_File Version = "1" Author = "Nardog" Notes = "" LanguageCode="jpn">
 	<Ditto_Right_Click_Menu>
 		<Item English_Text = "Groups" ID = "-1">グループ</Item>
 		<Item English_Text = "New Group	Ctrl-F7" ID = "32811">新しいグループ	Ctrl-F7</Item>

+ 1 - 1
Debug/Language/Polski.xml

@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="Ascii"?>
-<Ditto_Language_File Version = "0.1" Author = "Radoslaw Szambelan" Notes = "Draft">
+<Ditto_Language_File Version = "0.1" Author = "Radoslaw Szambelan" Notes = "Draft" LanguageCode = "pol">
 	<Ditto_Right_Click_Menu>
 		<Item English_Text = "Groups" ID = "-1">Grupy</Item>
 		<Item English_Text = "New Group	Ctrl-F7" ID = "32811">Nowa Grupa	Ctrl-F7</Item>

+ 1 - 1
Debug/Language/Portuguese.xml

@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="Ascii"?>
-<Ditto_Language_File Version = "1" Author = "Hélder Podence" Notes = "Versão 1.1 do 29/12/2006">
+<Ditto_Language_File Version = "1" Author = "Hélder Podence" Notes = "Versão 1.1 do 29/12/2006" LanguageCode = "por">
 	<Ditto_Right_Click_Menu>
 		<Item English_Text = "Groups" ID = "-1">Grupos</Item>
 		<Item English_Text = "New Group	Ctrl-F7" ID = "32811">Novo grupo	Ctrl-F7</Item>

+ 1 - 1
Debug/Language/Romanian.xml

@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<Ditto_Language_File Version = "1" Author = "Alexandru Bogdan Munteanu" Notes = "http://muntealb.bravehost.com/">
+<Ditto_Language_File Version = "1" Author = "Alexandru Bogdan Munteanu" Notes = "http://muntealb.bravehost.com/" LanguageCode = "rum">
 	<Ditto_Right_Click_Menu>
 		<Item English_Text = "Groups" ID = "-1">Grupuri</Item>
 		<Item English_Text = "New Group	Ctrl-F7" ID = "32811">Grup Nou  [Ctrl-F7]</Item>

+ 1 - 1
Debug/Language/Spanish.xml

@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="Ascii"?>
-<Ditto_Language_File Version = "1" Author = "Victor Gascon" Notes = "http://www.vgascon.com">
+<Ditto_Language_File Version = "1" Author = "Victor Gascon" Notes = "http://www.vgascon.com" LanguageCode = "spa">
 	<Ditto_Right_Click_Menu>
 		<Item English_Text = "Groups" ID = "-1">Grupos</Item>
 		<Item English_Text = "New Group	Ctrl-F7" ID = "32811">Nuevo Grupo</Item>

+ 1 - 1
Debug/Language/Swedish.xml

@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="Ascii"?>
-<Ditto_Language_File Version = "1" Author = "Ulf Swedjemark" Notes = "[email protected]">
+<Ditto_Language_File Version = "1" Author = "Ulf Swedjemark" Notes = "[email protected]" LanguageCode = "swe">
 	<Ditto_Right_Click_Menu>
 		<Item English_Text = "Groups" ID = "-1">Grupper</Item>
 		<Item English_Text = "New Group	Ctrl-F7" ID = "32811">Ny grupp Ctrl-F7</Item>

+ 1 - 1
Debug/Language/Turkish.xml

@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="Ascii"?>
-<Ditto_Language_File Version = "1" Author = "Kadir Danýþ" Notes = "[email protected]">
+<Ditto_Language_File Version = "1" Author = "Kadir Danýþ" Notes = "[email protected]" LanguageCode = "tur">
 	<Ditto_Right_Click_Menu>
 		<Item English_Text = "Groups" ID = "-1">Gruplar</Item>
 		<Item English_Text = "New Group	Ctrl-F7" ID = "32811">Yeni Grup</Item>

+ 1 - 1
Debug/Language/italiano.xml

@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<Ditto_Language_File Version = "1" Author = "Salvatore Giarratana" Notes = "http://labx.altervista.org">
+<Ditto_Language_File Version = "1" Author = "Salvatore Giarratana" Notes = "http://labx.altervista.org" LanguageCode="ita">
 	<Ditto_Right_Click_Menu>
 		<Item English_Text = "Groups" ID = "-1">Gruppo</Item>
 		<Item English_Text = "New Group	Ctrl-F7" ID = "32811">Nuovo Gruppo Ctrl-F7</Item>

BIN
Debug/focus.dll


BIN
Debug/focus.lib


BIN
Debug/zlib1.dll


+ 110 - 0
DittoAddin.cpp

@@ -0,0 +1,110 @@
+#include "stdafx.h"
+#include "DittoAddin.h"
+#include "Misc.h"
+#include "TextConvert.h"
+
+CDittoAddin::CDittoAddin() :
+	m_hModule(NULL)
+{
+}
+
+CDittoAddin::~CDittoAddin()
+{
+	Cleanup();
+}
+
+bool CDittoAddin::DoLoad(LPCTSTR lpszDllName, CDittoInfo DittoInfo)
+{
+	bool bLoaded = false;
+	m_csLastError.Empty();
+	Cleanup();
+
+	if(lpszDllName)
+	{
+		_tcscpy(m_DllName, lpszDllName);
+
+		m_hModule = ::LoadLibrary(lpszDllName);
+
+		if( m_hModule )
+		{
+			bool (__cdecl *DittoAddin)(const CDittoInfo&, CDittoAddinInfo&);
+			DittoAddin = (bool(__cdecl*)(const CDittoInfo&, CDittoAddinInfo&))GetProcAddress(m_hModule, "DittoAddin");
+			if(DittoAddin)
+			{
+				bLoaded = DittoAddin(DittoInfo, m_DittoAddinInfo);
+				if(bLoaded)
+				{
+					m_SupportedFunctions = (bool(__cdecl*)(const CDittoInfo&, FunctionType,std::vector<CFunction>&))GetProcAddress(m_hModule, "SupportedFunctions");
+					SupportedFunctions(DittoInfo, eFuncType_PRE_PASTE, m_PrePasteFunctions);
+				}
+				else
+				{
+					m_csLastError.Format((_T("Ditto Addin - DittoAddin return false, not loading Addin")));
+				}
+			}
+			else
+			{
+				m_csLastError.Format((_T("Ditto Addin - Failed to Get Function DittoAddin")));
+			}
+		}
+		else
+		{
+			m_csLastError.Format((_T("Ditto Addin - Failed to load library on Addin %s"), lpszDllName));
+		}
+	}
+
+	return bLoaded;
+}
+
+void CDittoAddin::Cleanup()
+{
+	if(m_hModule)
+	{
+		// release resources to the dll
+		::FreeLibrary(m_hModule);
+		m_hModule = NULL;
+	}
+}
+
+bool CDittoAddin::SupportedFunctions(const CDittoInfo &DittoInfo, FunctionType type, std::vector<CFunction> &Functions)
+{
+	bool bRet = false;
+	m_csLastError.Empty();
+
+	if(m_SupportedFunctions != NULL)
+	{
+		bRet = m_SupportedFunctions(DittoInfo, type, Functions);
+		if(bRet)
+		{
+			int nCount = Functions.size();
+			for(int i = 0; i < nCount; i++)
+			{
+				CFunction func = Functions[i];
+				Log(StrF(_T("Ditto Addin - Supported Function Display: %s, Function: %s, Desc: %s"), func.m_csDisplayName, CTextConvert::MultiByteToUnicodeString(func.m_csFunction), func.m_csDetailDescription));
+			}
+		}
+		else
+		{
+			m_csLastError = _T("Ditto Addin - m_SupportedFunctions returned false");
+		}
+	}
+	else
+	{
+		m_csLastError = _T("Ditto Addin - m_SupportedFunctions is null, not call function load supported functions");
+	}
+
+	return bRet;
+}
+
+bool CDittoAddin::PrePasteFunction(const CDittoInfo &DittoInfo, CStringA Function, IClip *pClip)
+{
+	bool (__cdecl *PrePasteFunc)(const CDittoInfo &, IClip*);
+
+	PrePasteFunc = (bool(__cdecl*)(const CDittoInfo &, IClip*))GetProcAddress(m_hModule, Function);
+	if(PrePasteFunc)
+	{
+		return PrePasteFunc(DittoInfo, pClip);
+	}
+
+	return false;
+}

+ 32 - 0
DittoAddin.h

@@ -0,0 +1,32 @@
+#pragma once
+
+#include "Shared\DittoDefines.h"
+#include "Shared\IClip.h"
+#include <vector>
+
+class CDittoAddin
+{
+public:
+	CDittoAddin();
+	virtual ~CDittoAddin();
+
+	bool DoLoad(LPCTSTR lpszDllName, CDittoInfo DittoInfo);
+
+	std::vector<CFunction> m_PrePasteFunctions;
+	bool PrePasteFunction(const CDittoInfo &DittoInfo, CStringA Function, IClip *pClip);
+
+	CString DisplayName() { return m_DittoAddinInfo.m_Name; }
+	CString LastError()	{ return m_csLastError; }
+
+protected:
+	TCHAR m_DllName[MAX_PATH];
+	HMODULE m_hModule;
+	CDittoAddinInfo m_DittoAddinInfo;
+	CString m_csLastError;
+	
+protected:
+	void Cleanup();
+
+	bool (__cdecl *m_SupportedFunctions)(const CDittoInfo&, FunctionType,std::vector<CFunction>&);
+	bool SupportedFunctions(const CDittoInfo &DittoInfo, FunctionType type, std::vector<CFunction> &Functions);	
+};

+ 136 - 0
DittoAddins.cpp

@@ -0,0 +1,136 @@
+#include "stdafx.h"
+#include ".\dittoaddins.h"
+#include "InternetUpdate.h"
+#include "CP_Main.h"
+
+CDittoAddins::CDittoAddins(void)
+{
+}
+
+CDittoAddins::~CDittoAddins(void)
+{
+	UnloadAll();
+}
+
+bool CDittoAddins::UnloadAll()
+{
+	Log(StrF(_T("Ditto Addin - Unloading all addins Count: %d"), m_Addins.size()));
+
+	int nCount = m_Addins.size();
+	for(int i = 0; i < nCount; i++)
+	{
+		CDittoAddin *pAddin = m_Addins[i];
+		if(pAddin)
+		{
+			delete pAddin;
+			pAddin = NULL;
+		}
+	}
+
+	m_Addins.clear();
+
+	return true;
+}
+
+bool CDittoAddins::LoadAll()
+{
+	CDittoInfo DittoInfo;
+	LoadDittoInfo(DittoInfo);
+
+	CString csDir = CGetSetOptions::GetPath(PATH_ADDINS);
+
+	CFileFind find;
+	BOOL bCont = find.FindFile(csDir + _T("*.dll"));
+
+	while(bCont)
+	{
+		bCont = find.FindNextFile();
+
+		Log(StrF(_T("Ditto Addin - Trying to load addin file %s"), find.GetFilePath()));
+
+		CDittoAddin *pAddin = new CDittoAddin;
+		if(pAddin->DoLoad(find.GetFilePath(), DittoInfo))
+		{
+			Log(StrF(_T("Ditto Addin - Success, loaded addin: %s"), find.GetFilePath()));
+			m_Addins.push_back(pAddin);
+		}
+		else
+		{
+			Log(StrF(_T("Ditto Addin - Failed loading Adding Error: %s"), pAddin->LastError()));
+
+			delete pAddin;
+			pAddin = NULL;
+		}
+	}
+
+	return m_Addins.size() > 0;
+}
+
+bool CDittoAddins::AddPrePasteAddinsToMenu(CMenu *pMenu)
+{
+	bool bRet = false;
+
+	m_FunctionMap.RemoveAll();
+	int nMenuId = 3000;
+
+	HMENU AllAddinsMenu = ::CreateMenu();
+
+	int nCount = m_Addins.size();
+	for(int i = 0; i < nCount; i++)
+	{
+		CDittoAddin *pAddin = m_Addins[i];
+		if(pAddin)
+		{
+			int nSubCount = pAddin->m_PrePasteFunctions.size();
+			if(nSubCount > 0)
+			{
+				HMENU AddinMenu = ::CreateMenu();
+				for(int x = 0; x < nSubCount; x++)
+				{
+					::AppendMenu(AddinMenu, MF_ENABLED, nMenuId, pAddin->m_PrePasteFunctions[x].m_csDisplayName);
+
+					CFunctionLookup lookup;
+					lookup.m_csFunctionName = pAddin->m_PrePasteFunctions[x].m_csFunction;
+					lookup.m_pAddin = pAddin;
+					m_FunctionMap.SetAt(nMenuId, lookup);
+					nMenuId++;
+				}
+
+				::AppendMenu(AllAddinsMenu, MF_ENABLED|MF_POPUP, (UINT)AddinMenu, pAddin->DisplayName());
+				bRet = true;
+			}
+		}
+	}
+
+	if(bRet)
+	{
+		pMenu->InsertMenu(3, MF_BYPOSITION|MF_ENABLED|MF_STRING|MF_POPUP, (UINT)AllAddinsMenu, _T("Add-Ins"));
+	}
+
+	return bRet;
+}
+
+bool CDittoAddins::CallPrePasteFunction(int Id, IClip *pClip)
+{
+	bool bRet = false;
+	CFunctionLookup func;
+	if(m_FunctionMap.Lookup(Id, func))
+	{
+		CDittoInfo DittoInfo;
+		LoadDittoInfo(DittoInfo);
+
+		bRet = func.m_pAddin->PrePasteFunction(DittoInfo, func.m_csFunctionName, pClip);
+	}
+
+	return bRet;
+}
+
+void CDittoAddins::LoadDittoInfo(CDittoInfo &DittoInfo)
+{
+	DittoInfo.m_csDatabasePath = CGetSetOptions::GetDBPath();
+	DittoInfo.m_csLanguageCode = theApp.m_Language.GetLangCode();
+	CInternetUpdate update;
+	DittoInfo.m_nVersion = update.GetRunningVersion();
+	DittoInfo.m_csSqliteVersion = sqlite3_libversion();
+	DittoInfo.m_hWndDitto = theApp.QPastehWnd();
+}

+ 35 - 0
DittoAddins.h

@@ -0,0 +1,35 @@
+#pragma once
+
+#include "DittoAddin.h"
+#include <vector>
+#include <afxtempl.h>
+
+class CDittoAddins
+{
+public:
+	CDittoAddins(void);
+	~CDittoAddins(void);
+
+	bool LoadAll();
+	bool UnloadAll();
+
+	bool Loaded()	{ return m_Addins.size() > 0; }
+
+	bool AddPrePasteAddinsToMenu(CMenu *pMenu);
+	bool CallPrePasteFunction(int Id, IClip *pClip);
+
+protected:
+	std::vector<CDittoAddin*> m_Addins;
+
+	class CFunctionLookup
+	{
+	public:
+		CDittoAddin *m_pAddin;
+		CStringA m_csFunctionName;
+	};
+
+	CMap<int, int, CFunctionLookup, CFunctionLookup> m_FunctionMap;
+
+protected:
+	void LoadDittoInfo(CDittoInfo &DittoInfo);
+};

BIN
EncryptDecryptD.lib


+ 1 - 21
Misc.cpp

@@ -74,7 +74,7 @@ void log(const TCHAR* msg, bool bFromSendRecieve, CString csFile, long lLine)
 
 	CString csFileLine;
 	csFile = GetFileName(csFile);
-	csFileLine.Format(_T("%s [%d] "), csFile, lLine);
+	csFileLine.Format(_T("%s %d] "), csFile, lLine);
 	csText += csFileLine;
 	
 	csText += msg;
@@ -195,26 +195,6 @@ CString GetWndText( HWND hWnd )
 	return text;
 }
 
-CString GetParentsString( HWND hWndStart, TCHAR* sSep )
-{
-HWND hWnd = hWndStart;
-CString sOne = "";
-CString sResult = "";
-TCHAR pBuf[255];
-
-    pBuf[0] = 0;
-    do {
-        ::GetClassName(hWnd, pBuf, 255);
-        sOne = StrF( _T("\n->[0x%08x: (%s) \"%s\"]"),
-            hWnd, pBuf, (LPCTSTR) GetWndText(hWnd) );
-        sResult += sSep;
-        sResult += sOne;
-        hWnd = ::GetParent(hWnd);
-    } while( hWnd != NULL );
-
-    return sResult;
-}
-
 bool IsAppWnd( HWND hWnd )
 {
 	DWORD dwMyPID = ::GetCurrentProcessId();

+ 0 - 1
Misc.h

@@ -64,7 +64,6 @@ BYTE GetEscapeChar( BYTE ch );
 CString RemoveEscapes( const TCHAR* str );
 
 CString GetWndText( HWND hWnd );
-CString GetParentsString( HWND hWndStart, TCHAR* sSep = _T("\n->") );
 // returns true if the given window is owned by this process
 bool IsAppWnd( HWND hWnd );
 // returns the current Focus window even if it is not owned by our thread.

+ 3 - 1
MultiLanguage.cpp

@@ -21,6 +21,7 @@ static char THIS_FILE[]=__FILE__;
 CMultiLanguage::CMultiLanguage()
 {
 	m_csAuthor = "";
+	m_csLangCode = "";
 	m_lFileVersion = 0;
 	m_bOnlyGetHeader = false;
 }
@@ -33,6 +34,7 @@ CMultiLanguage::~CMultiLanguage()
 void CMultiLanguage::ClearArrays()
 {
 	m_csAuthor = "";
+	m_csLangCode = "";
 	m_lFileVersion = 0;
 	m_bOnlyGetHeader = false;
 
@@ -294,11 +296,11 @@ bool CMultiLanguage::LoadLanguageFile(CString csFile)
 	m_lFileVersion = ATOI(csVersion);
 	m_csAuthor = ItemHeader->Attribute("Author");
 	m_csNotes = ItemHeader->Attribute("Notes");
+	m_csLangCode = ItemHeader->Attribute("LanguageCode");
 
 	if(m_bOnlyGetHeader)
 		return true;
 
-
 	bool bRet = LoadSection(*ItemHeader, m_RightClickMenu, "Ditto_Right_Click_Menu");
 	bRet = LoadSection(*ItemHeader, m_OptionsGeneral, "Ditto_Options_General");
 	bRet = LoadSection(*ItemHeader, m_ClipProperties, "Ditto_Clip_Properties");

+ 2 - 0
MultiLanguage.h

@@ -60,6 +60,7 @@ public:
 	CString GetAuthor()	{ return m_csAuthor;		}
 	long	GetVersion(){ return m_lFileVersion;	}
 	CString GetNotes()	{ return m_csNotes;			}
+	CString GetLangCode() { return m_csLangCode;	}
 
 	void	SetOnlyGetHeader(bool bVal)	{ m_bOnlyGetHeader = true;	}
 	static CMenu* GetMenuPos(CMenu *pMenu, const CString &csLookingForMenuText, int &nMenuPos);
@@ -86,6 +87,7 @@ protected:
 	CString m_csAuthor;
 	CString m_csNotes;
 	long	m_lFileVersion;
+	CString m_csLangCode;
 
 	bool	m_bOnlyGetHeader;
 

+ 6 - 0
OleClipSource.cpp

@@ -17,6 +17,7 @@ COleClipSource::COleClipSource()
 	m_bLoadedFormats = false;
 	m_bOnlyPaste_CF_TEXT = false;
 	m_bPasteHTMLFormatAs_CF_TEXT = false;
+	m_pCustomPasteFormats = NULL;
 }
 
 COleClipSource::~COleClipSource()
@@ -44,6 +45,11 @@ BOOL COleClipSource::DoImmediateRender()
 		return TRUE;
 
 	m_bLoadedFormats = true;
+
+	if(m_pCustomPasteFormats != NULL)
+	{
+		return PutFormatOnClipboard(m_pCustomPasteFormats, m_bPasteHTMLFormatAs_CF_TEXT);
+	}
 	
 	int count = m_ClipIDs.GetSize();
 	if(count <= 0)

+ 1 - 0
OleClipSource.h

@@ -14,6 +14,7 @@ public:
 	bool		m_bLoadedFormats;
 	bool		m_bOnlyPaste_CF_TEXT;
 	bool		m_bPasteHTMLFormatAs_CF_TEXT;
+	CClipFormats *m_pCustomPasteFormats;
 
 	COleClipSource();
 	virtual ~COleClipSource();

+ 13 - 0
Options.cpp

@@ -1694,6 +1694,19 @@ CString CGetSetOptions::GetPath(long lPathID)
 			FIX_CSTRING_PATH(csDir);
 		}
 		break;
+
+	case PATH_ADDINS:
+		if(m_bU3)
+		{
+			csDir = GETENV(_T("U3_DEVICE_EXEC_PATH"));
+			FIX_CSTRING_PATH(csDir);
+		}
+
+		csDir += "Addins\\";
+
+		csDir = _T("C:\\Documents and Settings\\Brogdens\\Desktop\\ditto\\Addins\\OutlookExpress\\Debug\\");
+
+		break;
 	}
 
 	return csDir;

+ 1 - 0
Options.h

@@ -58,6 +58,7 @@ public:
 #define PATH_INI			6
 #define PATH_U3_HWND_INI	7
 #define PATH_THEMES			8
+#define PATH_ADDINS			9
 
 class CGetSetOptions
 {

+ 2 - 0
ProcessPaste.h

@@ -37,6 +37,8 @@ public:
 
 	void MarkAsPasted();
 	static UINT MarkAsPastedThread(LPVOID pParam);
+
+	void SetCustomPasteFormats(CClipFormats *pFormats) { m_pOle->m_pCustomPasteFormats = pFormats; }
 };
 
 #endif // !defined(AFX_PROCESSPASTE_H__185CBB6F_4B63_4397_8FF9_E18D777DA506__INCLUDED_)

+ 64 - 4
QPasteWnd.cpp

@@ -189,12 +189,22 @@ BEGIN_MESSAGE_MAP(CQPasteWnd, CWndEx)
 	ON_COMMAND(ID_MENU_NEWCLIP, OnMenuNewclip)
 	ON_UPDATE_COMMAND_UI(ID_MENU_EDITITEM, OnUpdateMenuEdititem)
 	ON_UPDATE_COMMAND_UI(ID_MENU_NEWCLIP, OnUpdateMenuNewclip)
+	ON_WM_CTLCOLOR_REFLECT()
+	ON_COMMAND_RANGE(3000, 4000, OnAddinSelect)
 	END_MESSAGE_MAP()
 
 
 /////////////////////////////////////////////////////////////////////////////
 // CQPasteWnd message handlers
 
+HBRUSH CQPasteWnd::CtlColor(CDC* pDC, UINT nCtlColor) 
+{
+	pDC->SetBkMode(TRANSPARENT);
+	pDC->SetBkColor(RGB(255, 0, 0));
+
+	return (HBRUSH)GetStockObject(NULL_BRUSH);
+}
+
 BOOL CQPasteWnd::Create(const POINT& ptStart, CWnd* pParentWnd) 
 {
 	// Get the previous size of the QPaste window
@@ -535,10 +545,13 @@ 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)
+BOOL CQPasteWnd::OpenID(long lID, bool bOnlyLoad_CF_TEXT, bool bPasteHTMLAs_CF_TEXT, CClipFormats *pPasteFormats)
 {
-	if( theApp.EnterGroupID(lID) )
-		return TRUE;
+	if(pPasteFormats == NULL)
+	{
+		if(theApp.EnterGroupID(lID))
+			return TRUE;
+	}
 
 	if(GetKeyState(VK_SHIFT) & 0x8000)
 	{
@@ -552,7 +565,14 @@ BOOL CQPasteWnd::OpenID(long lID, bool bOnlyLoad_CF_TEXT, bool bPasteHTMLAs_CF_T
 	paste.m_bOnlyPaste_CF_TEXT = bOnlyLoad_CF_TEXT;
 	paste.m_bPasteHTMLFormatAs_CF_TEXT = bPasteHTMLAs_CF_TEXT;
 
-	paste.GetClipIDs().Add(lID);
+	if(pPasteFormats != NULL)
+	{
+		paste.SetCustomPasteFormats(pPasteFormats);
+	}
+	else
+	{
+		paste.GetClipIDs().Add(lID);
+	}
 	paste.DoPaste();
 	theApp.OnPasteCompleted();
 
@@ -899,6 +919,8 @@ void CQPasteWnd::OnRclickQuickPaste(NMHDR* pNMHDR, LRESULT* pResult)
 			pp.y = rc.bottom;
 		}
 		
+		theApp.m_Addins.AddPrePasteAddinsToMenu(cmSubMenu);
+
 		theApp.m_Language.UpdateRightClickMenu(cmSubMenu);
 
 		SetMenuChecks(cmSubMenu);
@@ -2941,3 +2963,41 @@ void CQPasteWnd::OnTimer(UINT_PTR nIDEvent)
 
 	CWndEx::OnTimer(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);
+
+	if(IDs.GetCount() > 0)
+	{
+		long lID = IDs[0];
+		CClip clip;
+		if(clip.LoadMainTable(lID))
+		{
+			if(clip.LoadFormats(lID, false))
+			{
+				bool bCont = theApp.m_Addins.CallPrePasteFunction(id, &clip);
+				if(bCont)
+				{
+					OpenID(-1, false, false, &clip.m_Formats);
+				}
+			}
+		}
+	}
+}

+ 5 - 5
QPasteWnd.h

@@ -112,7 +112,7 @@ public:
 
 	void DeleteSelectedRows();
 
-	BOOL OpenID(long lID, bool bOnlyLoad_CF_TEXT = false, bool bPasteHTMLAs_CF_TEXT = false);
+	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 OpenIndex( long nItem );
 	BOOL NewGroup( bool bGroupSelection = true );
@@ -142,6 +142,7 @@ public:
 	// 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);
@@ -225,7 +226,6 @@ protected:
 	afx_msg void OnUpdateMenuDelete(CCmdUI* pCmdUI);
 	afx_msg void OnUpdateMenuProperties(CCmdUI* pCmdUI);	
 	afx_msg void OnDestroy();
-	//}}AFX_MSG
 	afx_msg LRESULT OnListSelect(WPARAM wParam, LPARAM lParam);
 	afx_msg LRESULT OnListEnd(WPARAM wParam, LPARAM lParam);
 	afx_msg LRESULT OnSearch(WPARAM wParam, LPARAM lParam);
@@ -239,8 +239,7 @@ protected:
 	afx_msg LRESULT OnFillRestOfList(WPARAM wParam, LPARAM lParam);
 	afx_msg LRESULT OnRefeshVisibleRows(WPARAM wParam, LPARAM lParam);
 	afx_msg LRESULT OnSetListCount(WPARAM wParam, LPARAM lParam);
-	DECLARE_MESSAGE_MAP()
-public:
+	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();
@@ -258,7 +257,6 @@ public:
 	afx_msg LRESULT OnUpDown(WPARAM wParam, LPARAM lParam);
 	afx_msg LRESULT OnItemDeleted(WPARAM wParam, LPARAM lParam);
 	LRESULT OnToolTipWndInactive(WPARAM wParam, LPARAM lParam);
-public:
 	afx_msg void OnTimer(UINT_PTR nIDEvent);
 	afx_msg void OnMenuExport();
 	afx_msg void OnMenuImport();
@@ -267,6 +265,8 @@ public:
 	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
 };
 
 

BIN
Release/zlib1.dll


+ 196 - 0
Shared/DittoDefines.h

@@ -0,0 +1,196 @@
+#pragma once
+
+#include <shlwapi.h>
+
+#define DITTO_ADD_IN_VERSION 1
+
+typedef enum
+{
+	eFuncType_PRE_PASTE
+}FunctionType;
+
+class CFunction
+{
+public:
+	CStringA m_csFunction;
+	CString m_csDisplayName;
+	CString m_csDetailDescription;
+};
+
+class CDittoAddinInfo
+{
+public:
+	CDittoAddinInfo()
+	{
+		m_nPrivateVersion = DITTO_ADD_IN_VERSION;
+		m_AddinVersion = 0;
+		m_nSizeOfThis = sizeof(CDittoAddinInfo);
+	}
+	
+	bool ValidateSize() const  { return m_nSizeOfThis == sizeof(CDittoAddinInfo); }
+	int PrivateVersion() const { return m_nPrivateVersion; }
+
+	int m_nSizeOfThis;
+	CString m_Name;
+	int m_AddinVersion;
+
+private:
+	int m_nPrivateVersion;
+};
+
+class CDittoInfo
+{
+public:
+	CDittoInfo()
+	{
+		m_nVersion = 0;
+		m_hWndDitto = NULL;
+		m_nSizeOfThis = sizeof(CDittoInfo);
+	}
+
+	bool ValidateSize() const  { return m_nSizeOfThis == sizeof(CDittoInfo); }
+	int PrivateVersion() const { return m_nPrivateVersion; }
+
+	int m_nSizeOfThis;
+	int m_nVersion;
+	CString m_csSqliteVersion;
+	CString m_csLanguageCode; //http://www.loc.gov/standards/iso639-2/php/code_list.php
+	CString m_csDatabasePath;
+	HWND m_hWndDitto;
+
+private:
+	int m_nPrivateVersion;
+};
+
+class DittoAddinHelpers
+{
+public:
+	static void CopyToGlobalHP(HGLOBAL hDest, LPVOID pBuf, ULONG ulBufLen)
+	{
+		ASSERT(hDest && pBuf && ulBufLen);
+		LPVOID pvData = GlobalLock(hDest);
+		ASSERT(pvData);
+		ULONG size = (ULONG)GlobalSize(hDest);
+		ASSERT(size >= ulBufLen);	// assert if hDest isn't big enough
+		memcpy(pvData, pBuf, ulBufLen);
+		GlobalUnlock(hDest);
+	}
+
+	static 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;
+	}
+
+
+	//Do not change these these are stored in the database
+	static 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
+	static 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 _T("ERROR");
+	}
+};

+ 19 - 0
Shared/IAddinExports.h

@@ -0,0 +1,19 @@
+#pragma once
+
+#include "DittoDefines.h"
+#include "IClip.h"
+#include <vector>
+
+extern "C" 
+{
+	//DittoAddin returns infor about your addin, version, display name
+	bool __declspec(dllexport) DittoAddin(const CDittoInfo &DittoInfo, CDittoAddinInfo &info);
+	
+	//Supported functions returns a list of available functions your addin supports based on the type passed in
+	//For each of the functions you must have an exported function that matches the returned function name
+	//CDittoInfo contains info about ditto. Included language code, to support multiple languages return the correct string based off of the language code currently used in ditto (//http://www.loc.gov/standards/iso639-2/php/code_list.php)
+	bool __declspec(dllexport) SupportedFunctions(const CDittoInfo &DittoInfo, FunctionType type, std::vector<CFunction> &Functions);
+
+	//Each exported functions must follow the following format
+	bool __declspec(dllexport) ConvertPathToHtmlImageTag(const CDittoInfo &DittoInfo, IClip *pClip);
+}

+ 43 - 0
Shared/IClip.h

@@ -0,0 +1,43 @@
+#pragma once
+
+//Contains the actual data of a clip format
+// Type is the type of clipboard format
+// Data is a HGLOBAL object pointing to the clipboard format data
+class IClipFormat
+{
+public:
+	virtual CLIPFORMAT Type() = 0;
+	virtual HGLOBAL Data() = 0;
+	virtual void Type(CLIPFORMAT type) = 0;
+	virtual void Data(HGLOBAL data) = 0;
+};
+
+//Contains a list of IClipFormats
+//This is a list of all data associated with a clip
+class IClipFormats
+{
+public:
+	virtual int Size() = 0;
+	virtual IClipFormat *GetAt(int nPos) = 0;
+	virtual void DeleteAt(int nPos) = 0;
+	virtual void DeleteAll() = 0;
+	virtual int AddNew(CLIPFORMAT type, HGLOBAL data) = 0;
+	virtual IClipFormat *FindFormatEx(CLIPFORMAT type) = 0;
+};
+
+class IClip
+{
+public:
+	virtual CString Description() = 0;
+	virtual void Description(CString csValue) = 0;
+	virtual CTime PasteTime() = 0;
+	virtual int ID() = 0;
+	virtual int Parent() = 0;
+	virtual void Parent(int nParent) = 0;
+	virtual int DontAutoDelete() = 0;
+	virtual void DontAutoDelete(int Dont) = 0;
+	virtual CString QuickPaste() = 0;
+	virtual void QuickPaste(CString csValue) = 0;
+
+	virtual IClipFormats *Clips() = 0;
+};