summaryrefslogtreecommitdiff
path: root/plugins/ContactsPlus
diff options
context:
space:
mode:
authorVadim Dashevskiy <watcherhd@gmail.com>2012-05-15 10:38:20 +0000
committerVadim Dashevskiy <watcherhd@gmail.com>2012-05-15 10:38:20 +0000
commit48540940b6c28bb4378abfeb500ec45a625b37b6 (patch)
tree2ef294c0763e802f91d868bdef4229b6868527de /plugins/ContactsPlus
parent5c350913f011e119127baeb32a6aedeb4f0d33bc (diff)
initial commit
git-svn-id: http://svn.miranda-ng.org/main/trunk@2 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c
Diffstat (limited to 'plugins/ContactsPlus')
-rw-r--r--plugins/ContactsPlus/contacts.cpp31
-rw-r--r--plugins/ContactsPlus/contacts.dsp171
-rw-r--r--plugins/ContactsPlus/contacts.dsw29
-rw-r--r--plugins/ContactsPlus/contacts.h79
-rw-r--r--plugins/ContactsPlus/contacts.rc191
-rw-r--r--plugins/ContactsPlus/contacts.sln36
-rw-r--r--plugins/ContactsPlus/contacts.vcxproj578
-rw-r--r--plugins/ContactsPlus/contacts.vcxproj.filters56
-rw-r--r--plugins/ContactsPlus/langpack_contacts.txt33
-rw-r--r--plugins/ContactsPlus/main.cpp363
-rw-r--r--plugins/ContactsPlus/readme_contacts.txt158
-rw-r--r--plugins/ContactsPlus/receive.cpp522
-rw-r--r--plugins/ContactsPlus/receive.h65
-rw-r--r--plugins/ContactsPlus/res/SendContacts.icobin0 -> 2606 bytes
-rw-r--r--plugins/ContactsPlus/resource.h44
-rw-r--r--plugins/ContactsPlus/send.cpp609
-rw-r--r--plugins/ContactsPlus/send.h110
-rw-r--r--plugins/ContactsPlus/utils.cpp876
-rw-r--r--plugins/ContactsPlus/utils.h91
19 files changed, 4042 insertions, 0 deletions
diff --git a/plugins/ContactsPlus/contacts.cpp b/plugins/ContactsPlus/contacts.cpp
new file mode 100644
index 0000000000..a7ba2cdfbb
--- /dev/null
+++ b/plugins/ContactsPlus/contacts.cpp
@@ -0,0 +1,31 @@
+// --------------------------------------------------------------------------
+// Contacts+ for Miranda Instant Messenger
+// _______________________________________
+//
+// Copyright © 2002 Dominus Procellarum
+// Copyright © 2004-2008 Joe Kucera
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// -----------------------------------------------------------------------------
+
+#include "contacts.h"
+
+
+bool WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
+{
+ hInst = hinstDLL;
+ return TRUE;
+}
diff --git a/plugins/ContactsPlus/contacts.dsp b/plugins/ContactsPlus/contacts.dsp
new file mode 100644
index 0000000000..29adec3bd8
--- /dev/null
+++ b/plugins/ContactsPlus/contacts.dsp
@@ -0,0 +1,171 @@
+# Microsoft Developer Studio Project File - Name="contacts" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=contacts - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "contacts.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "contacts.mak" CFG="contacts - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "contacts - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "contacts - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "contacts - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CONTACTS_EXPORTS" /YX /FD /c
+# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\include" /I "..\ExternalAPI" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CONTACTS_EXPORTS" /Yu"contacts.h" /FD /c
+# SUBTRACT CPP /Fr
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x405 /d "NDEBUG"
+# ADD RSC /l 0x405 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comctl32.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /map /machine:I386 /ALIGN:4096 /ignore:4108
+# SUBTRACT LINK32 /pdb:none /debug
+
+!ELSEIF "$(CFG)" == "contacts - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CONTACTS_EXPORTS" /YX /FD /GZ /c
+# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "..\include" /I "..\ExternalAPI" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CONTACTS_EXPORTS" /YX /FD /GZ /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x405 /d "_DEBUG"
+# ADD RSC /l 0x405 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
+
+!ENDIF
+
+# Begin Target
+
+# Name "contacts - Win32 Release"
+# Name "contacts - Win32 Debug"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=.\contacts.cpp
+
+!IF "$(CFG)" == "contacts - Win32 Release"
+
+# ADD CPP /Yc
+
+!ELSEIF "$(CFG)" == "contacts - Win32 Debug"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\main.cpp
+
+!IF "$(CFG)" == "contacts - Win32 Release"
+
+# ADD CPP /Yu
+
+!ELSEIF "$(CFG)" == "contacts - Win32 Debug"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\receive.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\send.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\utils.cpp
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# Begin Source File
+
+SOURCE=.\contacts.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\receive.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\resource.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\send.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\utils.h
+# End Source File
+# End Group
+# Begin Group "Resource Files"
+
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+# Begin Source File
+
+SOURCE=.\contacts.rc
+# End Source File
+# Begin Source File
+
+SOURCE=.\res\SendContacts.ico
+# End Source File
+# End Group
+# End Target
+# End Project
diff --git a/plugins/ContactsPlus/contacts.dsw b/plugins/ContactsPlus/contacts.dsw
new file mode 100644
index 0000000000..de931e6c9f
--- /dev/null
+++ b/plugins/ContactsPlus/contacts.dsw
@@ -0,0 +1,29 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "contacts"=".\contacts.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --git a/plugins/ContactsPlus/contacts.h b/plugins/ContactsPlus/contacts.h
new file mode 100644
index 0000000000..73123a4c62
--- /dev/null
+++ b/plugins/ContactsPlus/contacts.h
@@ -0,0 +1,79 @@
+// ---------------------------------------------------------------------------
+// Contacts+ for Miranda Instant Messenger
+// _______________________________________
+//
+// Copyright © 2002 Dominus Procellarum
+// Copyright © 2004-2008 Joe Kucera
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// ---------------------------------------------------------------------------
+
+#define _CRT_SECURE_NO_WARNINGS
+#define _CRT_NONSTDC_NO_WARNINGS
+
+#include <windows.h>
+#include <commctrl.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <crtdbg.h>
+#include <malloc.h>
+#include <time.h>
+
+//!!this is fake - this plugin maintains backward compatibility internally
+#define MIRANDA_VER 0x800
+
+#include "newpluginapi.h"
+#include "m_system.h"
+#include "m_protocols.h"
+#include "m_protosvc.h"
+#include "m_database.h"
+#include "m_utils.h"
+#include "m_langpack.h"
+#include "m_skin.h"
+#include "m_clist.h"
+#include "m_clc.h"
+#include "m_clui.h"
+#include "m_addcontact.h"
+#include "m_history.h"
+#include "m_userinfo.h"
+#include "m_button.h"
+#include "m_contacts.h"
+#include "m_message.h"
+#include "statusmodes.h"
+#include "win2k.h"
+
+#include "resource.h"
+
+#include "m_updater.h"
+
+#include "utils.h"
+#include "send.h"
+#include "receive.h"
+
+#define MODULENAME "SendReceiveContacts"
+
+
+#define MS_CONTACTS_SEND "ContactsTransfer/SendContacts"
+#define MS_CONTACTS_RECEIVE "ContactsTransfer/ReceiveContacts"
+
+// Global Variables
+extern int g_UnicodeCore;
+extern int g_NewProtoAPI;
+extern int g_SendAckSupported;
+extern int g_Utf8EventsSupported;
diff --git a/plugins/ContactsPlus/contacts.rc b/plugins/ContactsPlus/contacts.rc
new file mode 100644
index 0000000000..3edfca49c4
--- /dev/null
+++ b/plugins/ContactsPlus/contacts.rc
@@ -0,0 +1,191 @@
+//Microsoft Developer Studio generated resource script.
+//
+#include "resource.h"
+#include "winres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+// Neutral resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_NEU)
+#ifdef _WIN32
+LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
+#pragma code_page(1250)
+#endif //_WIN32
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+IDD_SEND DIALOGEX 0, 0, 308, 242
+STYLE DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_VISIBLE | WS_CAPTION |
+ WS_SYSMENU
+EXSTYLE WS_EX_CONTROLPARENT
+CAPTION "Send contacts"
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+ CONTROL "",IDC_PROTOCOL,"Button",BS_OWNERDRAW | WS_TABSTOP,5,7,
+ 12,12
+ LTEXT "",IDC_NAME,19,7,118,9,SS_NOPREFIX | SS_CENTERIMAGE
+ CONTROL "&A",IDC_ADD,"MButtonClass",WS_TABSTOP,231,5,16,14,
+ 0x18000000L
+ CONTROL "6",IDC_USERMENU,"MButtonClass",WS_TABSTOP,249,5,16,14,
+ 0x18000000L
+ CONTROL "&D",IDC_DETAILS,"MButtonClass",WS_TABSTOP,267,5,16,14,
+ 0x18000000L
+ CONTROL "&H",IDC_HISTORY,"MButtonClass",WS_TABSTOP,285,5,16,14,
+ 0x18000000L
+ CONTROL "Choose contacts to be send:",IDC_STATIC,"Static",
+ SS_SIMPLE | WS_GROUP,5,20,300,10,WS_EX_TRANSPARENT
+ DEFPUSHBUTTON "&Send",IDOK,195,220,50,14
+ PUSHBUTTON "Cancel",IDCANCEL,249,220,50,14
+ CONTROL "",IDC_LIST,"CListControl",WS_TABSTOP | 0x3da,5,30,298,
+ 185,WS_EX_CLIENTEDGE
+ PUSHBUTTON "&Select All",ID_SELECTALL,5,220,50,14
+END
+
+IDD_RECEIVE DIALOGEX 0, 0, 320, 225
+STYLE DS_SETFOREGROUND | DS_3DLOOK | DS_FIXEDSYS | DS_CENTER |
+ WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_POPUP | WS_VISIBLE | WS_CAPTION |
+ WS_SYSMENU | WS_THICKFRAME
+CAPTION "Received contacts"
+FONT 8, "MS Shell Dlg", 0, 0, 0x1
+BEGIN
+ CONTROL "",IDC_PROTOCOL,"Button",BS_OWNERDRAW | WS_TABSTOP,5,7,
+ 12,12
+ LTEXT "",IDC_NAME,19,7,118,9,SS_NOPREFIX | SS_CENTERIMAGE
+ CONTROL "&A",IDC_ADD,"MButtonClass",WS_TABSTOP,243,5,16,14,
+ 0x18000000L
+ CONTROL "6",IDC_USERMENU,"MButtonClass",WS_TABSTOP,261,5,16,14,
+ 0x18000000L
+ CONTROL "&D",IDC_DETAILS,"MButtonClass",WS_TABSTOP,279,5,16,14,
+ 0x18000000L
+ CONTROL "&H",IDC_HISTORY,"MButtonClass",WS_TABSTOP,297,5,16,14,
+ 0x18000000L
+ CONTROL "",IDC_CONTACTS,"SysListView32",LVS_REPORT |
+ LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_AUTOARRANGE |
+ WS_BORDER | WS_TABSTOP,5,22,310,178
+ CONTROL "Add to &group:",IDC_ENABLEGROUPS,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,7,205,80,12
+ COMBOBOX IDC_GROUPS,90,205,72,140,CBS_DROPDOWNLIST | CBS_SORT |
+ WS_VSCROLL | WS_TABSTOP | 0x8000
+ PUSHBUTTON "&Add",IDOK,169,204,46,14,WS_DISABLED
+ PUSHBUTTON "&Details",IDDETAILS,215,204,46,14,WS_DISABLED
+ PUSHBUTTON "Close",IDCANCEL,261,204,52,14
+END
+
+IDD_MSGSENDERROR DIALOGEX 0, 0, 187, 97
+STYLE DS_MODALFRAME | DS_SETFOREGROUND | DS_3DLOOK | DS_FIXEDSYS | WS_POPUP |
+ WS_VISIBLE | WS_CAPTION | WS_SYSMENU
+EXSTYLE WS_EX_CONTROLPARENT
+CAPTION "Contacts send error"
+FONT 8, "MS Shell Dlg", 0, 0, 0x1
+BEGIN
+ LTEXT "An error has occured. The protocol reported the following error:",
+ IDC_STATIC,5,5,177,28
+ DEFPUSHBUTTON "Try again",IDOK,22,78,63,14
+ PUSHBUTTON "Cancel",IDCANCEL,104,78,61,14
+ EDITTEXT IDC_ERRORTEXT,5,37,177,35,ES_MULTILINE | ES_READONLY |
+ WS_VSCROLL
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// DESIGNINFO
+//
+
+#ifdef APSTUDIO_INVOKED
+GUIDELINES DESIGNINFO MOVEABLE PURE
+BEGIN
+ IDD_SEND, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 300
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 235
+ END
+
+ IDD_RECEIVE, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 313
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 218
+ END
+END
+#endif // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Menu
+//
+
+IDR_CONTACTMENU MENUEX DISCARDABLE
+BEGIN
+ POPUP "Popup", 0,MFT_STRING,MFS_ENABLED
+ BEGIN
+ MENUITEM "Add to List", 111,MFT_STRING,MFS_ENABLED
+ MENUITEM "User Details", 113,MFT_STRING,
+ MFS_ENABLED | MFS_UNCHECKED | MFS_UNHILITE | MFS_DEFAULT
+ MENUITEM MFT_SEPARATOR
+ MENUITEM "Send Message", 112,MFT_STRING,MFS_ENABLED
+ END
+END
+
+
+#ifndef _MAC
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 1,5,2,0
+ PRODUCTVERSION 0,8,0,0
+ FILEFLAGSMASK 0x17L
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x4L
+ FILETYPE 0x2L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "Comments", "Requires Miranda 0.3+; Recommended Miranda 0.4+\0"
+ VALUE "CompanyName", "Jokusoftware, Dusk Horizon\0"
+ VALUE "FileDescription", "Send/Receive Contacts plugin for Miranda (Unicode 2in1)\0"
+ VALUE "FileVersion", "1, 5, 2, 0\0"
+ VALUE "InternalName", "contacts+\0"
+ VALUE "LegalCopyright", "Copyright (C) 2004-2008 Jokusoftware, Original code (C) 2002 Dominus Procellarum\0"
+ VALUE "LegalTrademarks", "\0"
+ VALUE "OriginalFilename", "contacts.dll\0"
+ VALUE "ProductName", "Send/Receive Contacts plugin for Miranda\0"
+ VALUE "ProductVersion", "0, 8, 0, 0\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
+
+#endif // !_MAC
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Icon
+//
+
+// Icon with lowest ID value placed first to ensure application icon
+// remains consistent on all systems.
+IDI_CONTACTS ICON DISCARDABLE "res\\SendContacts.ico"
+#endif // Neutral resources
+/////////////////////////////////////////////////////////////////////////////
diff --git a/plugins/ContactsPlus/contacts.sln b/plugins/ContactsPlus/contacts.sln
new file mode 100644
index 0000000000..573e39f319
--- /dev/null
+++ b/plugins/ContactsPlus/contacts.sln
@@ -0,0 +1,36 @@
+
+Microsoft Visual Studio Solution File, Format Version 11.00
+# Visual Studio 2010
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "contacts", "contacts.vcxproj", "{3E2FEAB1-3749-A6E4-A81E-54853C5B194E}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug Unicode|Win32 = Debug Unicode|Win32
+ Debug Unicode|x64 = Debug Unicode|x64
+ Debug|Win32 = Debug|Win32
+ Debug|x64 = Debug|x64
+ Release Unicode|Win32 = Release Unicode|Win32
+ Release Unicode|x64 = Release Unicode|x64
+ Release|Win32 = Release|Win32
+ Release|x64 = Release|x64
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {3E2FEAB1-3749-A6E4-A81E-54853C5B194E}.Debug Unicode|Win32.ActiveCfg = Debug Unicode|Win32
+ {3E2FEAB1-3749-A6E4-A81E-54853C5B194E}.Debug Unicode|Win32.Build.0 = Debug Unicode|Win32
+ {3E2FEAB1-3749-A6E4-A81E-54853C5B194E}.Debug Unicode|x64.ActiveCfg = Debug Unicode|Win32
+ {3E2FEAB1-3749-A6E4-A81E-54853C5B194E}.Debug|Win32.ActiveCfg = Debug|Win32
+ {3E2FEAB1-3749-A6E4-A81E-54853C5B194E}.Debug|Win32.Build.0 = Debug|Win32
+ {3E2FEAB1-3749-A6E4-A81E-54853C5B194E}.Debug|x64.ActiveCfg = Debug|x64
+ {3E2FEAB1-3749-A6E4-A81E-54853C5B194E}.Debug|x64.Build.0 = Debug|x64
+ {3E2FEAB1-3749-A6E4-A81E-54853C5B194E}.Release Unicode|Win32.ActiveCfg = Release Unicode|Win32
+ {3E2FEAB1-3749-A6E4-A81E-54853C5B194E}.Release Unicode|Win32.Build.0 = Release Unicode|Win32
+ {3E2FEAB1-3749-A6E4-A81E-54853C5B194E}.Release Unicode|x64.ActiveCfg = Release Unicode|Win32
+ {3E2FEAB1-3749-A6E4-A81E-54853C5B194E}.Release|Win32.ActiveCfg = Release|Win32
+ {3E2FEAB1-3749-A6E4-A81E-54853C5B194E}.Release|Win32.Build.0 = Release|Win32
+ {3E2FEAB1-3749-A6E4-A81E-54853C5B194E}.Release|x64.ActiveCfg = Release|x64
+ {3E2FEAB1-3749-A6E4-A81E-54853C5B194E}.Release|x64.Build.0 = Release|x64
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/plugins/ContactsPlus/contacts.vcxproj b/plugins/ContactsPlus/contacts.vcxproj
new file mode 100644
index 0000000000..0effcb9218
--- /dev/null
+++ b/plugins/ContactsPlus/contacts.vcxproj
@@ -0,0 +1,578 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug Unicode|Win32">
+ <Configuration>Debug Unicode</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug Unicode|x64">
+ <Configuration>Debug Unicode</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release Unicode|Win32">
+ <Configuration>Release Unicode</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release Unicode|x64">
+ <Configuration>Release Unicode</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <SccProjectName />
+ <SccLocalPath />
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ <CharacterSet>MultiByte</CharacterSet>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release Unicode|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ <CharacterSet>MultiByte</CharacterSet>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release Unicode|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <OutDir>$(SolutionDir)$(Configuration)/Plugins\</OutDir>
+ <IntDir>$(SolutionDir)$(Configuration)/Obj/$(ProjectName)\</IntDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <OutDir>$(SolutionDir)$(Configuration)64/Plugins\</OutDir>
+ <IntDir>$(SolutionDir)$(Configuration)64/Obj/$(ProjectName)\</IntDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'">
+ <OutDir>$(SolutionDir)$(Configuration)/Plugins\</OutDir>
+ <IntDir>$(SolutionDir)$(Configuration)/Obj/$(ProjectName)\</IntDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release Unicode|x64'">
+ <OutDir>$(SolutionDir)$(Configuration)/Plugins\</OutDir>
+ <IntDir>$(SolutionDir)$(Configuration)/Obj/$(ProjectName)\</IntDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release Unicode|x64'">
+ <LinkIncremental>false</LinkIncremental>
+ <OutDir>$(SolutionDir)$(Configuration)64/Plugins\</OutDir>
+ <IntDir>$(SolutionDir)$(Configuration)64/Obj/$(ProjectName)\</IntDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <OutDir>$(SolutionDir)$(Configuration)/Plugins\</OutDir>
+ <IntDir>$(SolutionDir)$(Configuration)/Obj/$(ProjectName)\</IntDir>
+ <LinkIncremental>true</LinkIncremental>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <OutDir>$(SolutionDir)$(Configuration)64/Plugins\</OutDir>
+ <IntDir>$(SolutionDir)$(Configuration)64/Obj/$(ProjectName)\</IntDir>
+ <LinkIncremental>true</LinkIncremental>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'">
+ <OutDir>$(SolutionDir)$(Configuration)/Plugins\</OutDir>
+ <IntDir>$(SolutionDir)$(Configuration)/Obj/$(ProjectName)\</IntDir>
+ <LinkIncremental>true</LinkIncremental>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|x64'">
+ <OutDir>$(SolutionDir)$(Configuration)/Plugins\</OutDir>
+ <IntDir>$(SolutionDir)$(Configuration)/Obj/$(ProjectName)\</IntDir>
+ <LinkIncremental>true</LinkIncremental>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|x64'">
+ <OutDir>$(SolutionDir)$(Configuration)64/Plugins\</OutDir>
+ <IntDir>$(SolutionDir)$(Configuration)64/Obj/$(ProjectName)\</IntDir>
+ <LinkIncremental>true</LinkIncremental>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <StringPooling>true</StringPooling>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <Optimization>Full</Optimization>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <WarningLevel>Level3</WarningLevel>
+ <AdditionalIncludeDirectories>../../include;../ExternalAPI;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;CONTACTS_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PrecompiledHeader>Use</PrecompiledHeader>
+ <PrecompiledHeaderFile>contacts.h</PrecompiledHeaderFile>
+ <FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ </ClCompile>
+ <Midl>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <TypeLibraryName>.\Release\contacts.tlb</TypeLibraryName>
+ <MkTypLibCompatible>true</MkTypLibCompatible>
+ <TargetEnvironment>Win32</TargetEnvironment>
+ </Midl>
+ <ResourceCompile>
+ <Culture>0x0405</Culture>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ResourceCompile>
+ <Bscmake>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ </Bscmake>
+ <Link>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <LinkDLL>true</LinkDLL>
+ <GenerateDebugInformation>false</GenerateDebugInformation>
+ <SubSystem>Console</SubSystem>
+ <AdditionalOptions> /ALIGN:4096 /ignore:4108</AdditionalOptions>
+ <AdditionalDependencies>comctl32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ <LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ClCompile>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <StringPooling>true</StringPooling>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <Optimization>Full</Optimization>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <WarningLevel>Level3</WarningLevel>
+ <AdditionalIncludeDirectories>../../include;../ExternalAPI;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;CONTACTS_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PrecompiledHeader>Use</PrecompiledHeader>
+ <PrecompiledHeaderFile>contacts.h</PrecompiledHeaderFile>
+ <FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ </ClCompile>
+ <Midl>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <TypeLibraryName>.\Release\contacts.tlb</TypeLibraryName>
+ <MkTypLibCompatible>true</MkTypLibCompatible>
+ </Midl>
+ <ResourceCompile>
+ <Culture>0x0405</Culture>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ResourceCompile>
+ <Bscmake>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ </Bscmake>
+ <Link>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <LinkDLL>true</LinkDLL>
+ <GenerateDebugInformation>false</GenerateDebugInformation>
+ <SubSystem>Console</SubSystem>
+ <AdditionalOptions> /ALIGN:4096 /ignore:4108</AdditionalOptions>
+ <AdditionalDependencies>comctl32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ <LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'">
+ <ClCompile>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <StringPooling>true</StringPooling>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <Optimization>Full</Optimization>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <WarningLevel>Level3</WarningLevel>
+ <AdditionalIncludeDirectories>../../include;../ExternalAPI;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;CONTACTS_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PrecompiledHeader>Use</PrecompiledHeader>
+ <PrecompiledHeaderFile>contacts.h</PrecompiledHeaderFile>
+ <FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <ExceptionHandling>false</ExceptionHandling>
+ </ClCompile>
+ <Midl>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <TypeLibraryName>.\Release\contacts.tlb</TypeLibraryName>
+ <MkTypLibCompatible>true</MkTypLibCompatible>
+ <TargetEnvironment>Win32</TargetEnvironment>
+ </Midl>
+ <ResourceCompile>
+ <Culture>0x0405</Culture>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ResourceCompile>
+ <Bscmake>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ </Bscmake>
+ <Link>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <LinkDLL>true</LinkDLL>
+ <SubSystem>Console</SubSystem>
+ <AdditionalOptions> /ALIGN:4096 /ignore:4108</AdditionalOptions>
+ <AdditionalDependencies>comctl32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ <LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release Unicode|x64'">
+ <ClCompile>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <StringPooling>true</StringPooling>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <Optimization>Full</Optimization>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <WarningLevel>Level3</WarningLevel>
+ <AdditionalIncludeDirectories>../../include;../ExternalAPI;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;CONTACTS_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PrecompiledHeader>Use</PrecompiledHeader>
+ <PrecompiledHeaderFile>contacts.h</PrecompiledHeaderFile>
+ <FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <ExceptionHandling>false</ExceptionHandling>
+ </ClCompile>
+ <Midl>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <TypeLibraryName>.\Release\contacts.tlb</TypeLibraryName>
+ <MkTypLibCompatible>true</MkTypLibCompatible>
+ </Midl>
+ <ResourceCompile>
+ <Culture>0x0405</Culture>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ResourceCompile>
+ <Bscmake>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ </Bscmake>
+ <Link>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <LinkDLL>true</LinkDLL>
+ <SubSystem>Console</SubSystem>
+ <AdditionalOptions> /ALIGN:4096 /ignore:4108</AdditionalOptions>
+ <AdditionalDependencies>comctl32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ <LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release Unicode|x64'">
+ <ClCompile>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <StringPooling>true</StringPooling>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <Optimization>Full</Optimization>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <WarningLevel>Level3</WarningLevel>
+ <AdditionalIncludeDirectories>../../include;../ExternalAPI;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;CONTACTS_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PrecompiledHeader>Use</PrecompiledHeader>
+ <PrecompiledHeaderFile>contacts.h</PrecompiledHeaderFile>
+ <FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ </ClCompile>
+ <Midl>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <TypeLibraryName>.\Release\contacts.tlb</TypeLibraryName>
+ <MkTypLibCompatible>true</MkTypLibCompatible>
+ </Midl>
+ <ResourceCompile>
+ <Culture>0x0405</Culture>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ResourceCompile>
+ <Bscmake>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ </Bscmake>
+ <Link>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <LinkDLL>true</LinkDLL>
+ <GenerateDebugInformation>false</GenerateDebugInformation>
+ <SubSystem>Console</SubSystem>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ <AdditionalOptions> /ALIGN:4096 /ignore:4108</AdditionalOptions>
+ <AdditionalDependencies>comctl32.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <InlineFunctionExpansion>Default</InlineFunctionExpansion>
+ <FunctionLevelLinking>false</FunctionLevelLinking>
+ <Optimization>Disabled</Optimization>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <WarningLevel>Level3</WarningLevel>
+ <MinimalRebuild>true</MinimalRebuild>
+ <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
+ <AdditionalIncludeDirectories>../../include;../ExternalAPI;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;CONTACTS_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <ExceptionHandling>false</ExceptionHandling>
+ </ClCompile>
+ <Midl>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <TypeLibraryName>.\Debug\contacts.tlb</TypeLibraryName>
+ <MkTypLibCompatible>true</MkTypLibCompatible>
+ <TargetEnvironment>Win32</TargetEnvironment>
+ </Midl>
+ <ResourceCompile>
+ <Culture>0x0405</Culture>
+ <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ResourceCompile>
+ <Bscmake>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ </Bscmake>
+ <Link>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <LinkDLL>true</LinkDLL>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Console</SubSystem>
+ <AdditionalDependencies>comctl32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ClCompile>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <InlineFunctionExpansion>Default</InlineFunctionExpansion>
+ <FunctionLevelLinking>false</FunctionLevelLinking>
+ <Optimization>Disabled</Optimization>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <AdditionalIncludeDirectories>../../include;../ExternalAPI;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;CONTACTS_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <ExceptionHandling>false</ExceptionHandling>
+ </ClCompile>
+ <Midl>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <TypeLibraryName>.\Debug\contacts.tlb</TypeLibraryName>
+ <MkTypLibCompatible>true</MkTypLibCompatible>
+ </Midl>
+ <ResourceCompile>
+ <Culture>0x0405</Culture>
+ <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ResourceCompile>
+ <Bscmake>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ </Bscmake>
+ <Link>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <LinkDLL>true</LinkDLL>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Console</SubSystem>
+ <AdditionalDependencies>comctl32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'">
+ <ClCompile>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <InlineFunctionExpansion>Default</InlineFunctionExpansion>
+ <FunctionLevelLinking>false</FunctionLevelLinking>
+ <Optimization>Disabled</Optimization>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <WarningLevel>Level3</WarningLevel>
+ <MinimalRebuild>true</MinimalRebuild>
+ <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
+ <AdditionalIncludeDirectories>../../include;../ExternalAPI;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;CONTACTS_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <ExceptionHandling>false</ExceptionHandling>
+ </ClCompile>
+ <Midl>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <TypeLibraryName>.\Debug\contacts.tlb</TypeLibraryName>
+ <MkTypLibCompatible>true</MkTypLibCompatible>
+ <TargetEnvironment>Win32</TargetEnvironment>
+ </Midl>
+ <ResourceCompile>
+ <Culture>0x0405</Culture>
+ <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ResourceCompile>
+ <Bscmake>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ </Bscmake>
+ <Link>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <LinkDLL>true</LinkDLL>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Console</SubSystem>
+ <AdditionalDependencies>comctl32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|x64'">
+ <ClCompile>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <InlineFunctionExpansion>Default</InlineFunctionExpansion>
+ <FunctionLevelLinking>false</FunctionLevelLinking>
+ <Optimization>Disabled</Optimization>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <AdditionalIncludeDirectories>../../include;../ExternalAPI;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;CONTACTS_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <ExceptionHandling>false</ExceptionHandling>
+ </ClCompile>
+ <Midl>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <TypeLibraryName>.\Debug\contacts.tlb</TypeLibraryName>
+ <MkTypLibCompatible>true</MkTypLibCompatible>
+ </Midl>
+ <ResourceCompile>
+ <Culture>0x0405</Culture>
+ <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ResourceCompile>
+ <Bscmake>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ </Bscmake>
+ <Link>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <LinkDLL>true</LinkDLL>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Console</SubSystem>
+ <AdditionalDependencies>comctl32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|x64'">
+ <ClCompile>
+ <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+ <InlineFunctionExpansion>Default</InlineFunctionExpansion>
+ <FunctionLevelLinking>false</FunctionLevelLinking>
+ <Optimization>Disabled</Optimization>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <AdditionalIncludeDirectories>../../include;../ExternalAPI;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;CONTACTS_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ </ClCompile>
+ <Midl>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <TypeLibraryName>.\Debug\contacts.tlb</TypeLibraryName>
+ <MkTypLibCompatible>true</MkTypLibCompatible>
+ </Midl>
+ <ResourceCompile>
+ <Culture>0x0405</Culture>
+ <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ResourceCompile>
+ <Bscmake>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ </Bscmake>
+ <Link>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <LinkDLL>true</LinkDLL>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Console</SubSystem>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ <AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="contacts.cpp">
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'">Create</PrecompiledHeader>
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release Unicode|x64'">Create</PrecompiledHeader>
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release Unicode|x64'">Create</PrecompiledHeader>
+ <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">contacts.h</PrecompiledHeaderFile>
+ <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|x64'">contacts.h</PrecompiledHeaderFile>
+ <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'">contacts.h</PrecompiledHeaderFile>
+ <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release Unicode|x64'">contacts.h</PrecompiledHeaderFile>
+ <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release Unicode|x64'">contacts.h</PrecompiledHeaderFile>
+ </ClCompile>
+ <ClCompile Include="main.cpp">
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Use</PrecompiledHeader>
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Use</PrecompiledHeader>
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'">Use</PrecompiledHeader>
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release Unicode|x64'">Use</PrecompiledHeader>
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release Unicode|x64'">Use</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="receive.cpp" />
+ <ClCompile Include="send.cpp" />
+ <ClCompile Include="utils.cpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="contacts.h" />
+ <ClInclude Include="receive.h" />
+ <ClInclude Include="resource.h" />
+ <ClInclude Include="send.h" />
+ <ClInclude Include="utils.h" />
+ </ItemGroup>
+ <ItemGroup>
+ <ResourceCompile Include="contacts.rc" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/plugins/ContactsPlus/contacts.vcxproj.filters b/plugins/ContactsPlus/contacts.vcxproj.filters
new file mode 100644
index 0000000000..8270d92a72
--- /dev/null
+++ b/plugins/ContactsPlus/contacts.vcxproj.filters
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="Source Files">
+ <UniqueIdentifier>{c0e9ea51-8fc0-4db3-a0d9-491b3e4fecde}</UniqueIdentifier>
+ <Extensions>cpp;c;cxx;rc;def;r;odl;idl;hpj;bat</Extensions>
+ </Filter>
+ <Filter Include="Header Files">
+ <UniqueIdentifier>{05b2429f-b6fd-4862-97a2-f5686ee35703}</UniqueIdentifier>
+ <Extensions>h;hpp;hxx;hm;inl</Extensions>
+ </Filter>
+ <Filter Include="Resource Files">
+ <UniqueIdentifier>{56ec564b-af99-40f8-ae70-af5307bdc3f5}</UniqueIdentifier>
+ <Extensions>ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe</Extensions>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="contacts.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="main.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="receive.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="send.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="utils.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="contacts.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="receive.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="resource.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="send.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="utils.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ </ItemGroup>
+ <ItemGroup>
+ <ResourceCompile Include="contacts.rc">
+ <Filter>Resource Files</Filter>
+ </ResourceCompile>
+ </ItemGroup>
+</Project> \ No newline at end of file
diff --git a/plugins/ContactsPlus/langpack_contacts.txt b/plugins/ContactsPlus/langpack_contacts.txt
new file mode 100644
index 0000000000..13341fc88a
--- /dev/null
+++ b/plugins/ContactsPlus/langpack_contacts.txt
@@ -0,0 +1,33 @@
+;[Incoming Contacts]
+;[Outgoing Contacts]
+;[Contacts received from]
+;[Contacts]
+;[Error]
+
+; receive dlg
+;[Contacts from]
+;[Nick]
+;[First Name]
+;[Last Name]
+;[Add to &group:]
+;[&Add]
+;[&Details]
+;[Close]
+;[Add to List]
+;[User Details]
+;[Send Message]
+
+;send dlg
+;[Send Contacts to]
+;[The contacts send timed out.]
+;[Contacts transfer failed!]
+;[The selected contact does not support receiving contacts.]
+;[Choose contacts to be send:]
+;[&Send]
+;[Cancel]
+;[Select All]
+
+;error dlg
+;[An error has occured. The protocol reported the following error:]
+;[Try again]
+;[Cancel] \ No newline at end of file
diff --git a/plugins/ContactsPlus/main.cpp b/plugins/ContactsPlus/main.cpp
new file mode 100644
index 0000000000..7f167c84d0
--- /dev/null
+++ b/plugins/ContactsPlus/main.cpp
@@ -0,0 +1,363 @@
+// --------------------------------------------------------------------------
+// Contacts+ for Miranda Instant Messenger
+// _______________________________________
+//
+// Copyright © 2002 Dominus Procellarum
+// Copyright © 2004-2008 Joe Kucera
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// -----------------------------------------------------------------------------
+
+#include "contacts.h"
+
+
+HINSTANCE hInst;
+
+PLUGINLINK *pluginLink;
+
+int g_NewProtoAPI = FALSE;
+
+int g_SendAckSupported = FALSE;
+int g_Utf8EventsSupported = FALSE;
+
+HANDLE ghSendWindowList;
+HANDLE ghRecvWindowList;
+gAckList gaAckData;
+
+HANDLE hServiceSend;
+HANDLE hServiceReceive;
+
+HANDLE hHookModulesLoaded = NULL;
+HANDLE hHookDBEventAdded = NULL;
+HANDLE hHookContactDeleted = NULL;
+HANDLE hHookContactSettingChanged = NULL;
+HANDLE hHookPreBuildContactMenu = NULL;
+
+HANDLE hContactMenuItem = NULL;
+
+int g_UnicodeCore;
+
+PLUGININFOEX pluginInfo = {
+ sizeof(PLUGININFOEX),
+#ifdef WIN64
+ "Send/Receive Contacts+ (x64)",
+#else
+ "Send/Receive Contacts+",
+#endif
+ PLUGIN_MAKE_VERSION(1,5,2,0),
+ "Allows you to send and receive contacts",
+ "Joe Kucera, Todor Totev",
+ "jokusoftware@miranda-im.org",
+ "(C) 2004-2008 Joe Kucera, Original Code (C) 2002 Dominus Procellarum",
+ "http://addons.miranda-im.org/details.php?action=viewfile&id=1253",
+ 0, //no flags by default
+ 0, //doesn't replace anything built-in
+ {0x0324785E, 0x74CE, 0x4600, {0xB7, 0x81, 0x85, 0x17, 0x73, 0xB3, 0xEF, 0xC5 } } // {0324785E-74CE-4600-B781-851773B3EFC5}
+};
+
+
+static int HookDBEventAdded(WPARAM wParam, LPARAM lParam)
+{
+ HANDLE hContact = (HANDLE)wParam;
+ HANDLE hDbEvent = (HANDLE)lParam;
+ //process the event
+ DBEVENTINFO dbe = {0};
+
+ dbe.cbSize = sizeof(DBEVENTINFO);
+ //get event details
+ CallService(MS_DB_EVENT_GET, (WPARAM)hDbEvent, (LPARAM)&dbe);
+ //check if we should process the event
+ if (dbe.flags & (DBEF_SENT|DBEF_READ) || dbe.eventType != EVENTTYPE_CONTACTS) return 0;
+ //get event contents
+ dbe.cbBlob = CallService(MS_DB_EVENT_GETBLOBSIZE, (WPARAM)hDbEvent, 0);
+ if (dbe.cbBlob != -1)
+ dbe.pBlob = (PBYTE)_alloca(dbe.cbBlob);
+ CallService(MS_DB_EVENT_GET, (WPARAM)hDbEvent, (LPARAM)&dbe);
+ //play received sound
+ SkinPlaySound("RecvContacts");
+ { //add event to the contact list
+ CLISTEVENT cle = {0};
+ TCHAR caToolTip[128];
+
+ cle.cbSize = sizeof(cle);
+ cle.hContact = hContact;
+ cle.hDbEvent = hDbEvent;
+ cle.hIcon = LoadIcon(hInst, MAKEINTRESOURCE(IDI_CONTACTS));
+ cle.pszService = MS_CONTACTS_RECEIVE;
+
+ WCHAR tmp[MAX_PATH];
+ _snprintfT(caToolTip, 64, "%s %s", SRCTranslateT("Contacts received from", tmp), (TCHAR*)GetContactDisplayNameT(hContact));
+
+ cle.ptszTooltip = caToolTip;
+ if (g_UnicodeCore)
+ cle.flags |= CLEF_UNICODE;
+ CallService(MS_CLIST_ADDEVENT, 0, (LPARAM)&cle);
+ }
+ return 0; //continue processing by other hooks
+}
+
+
+static void ProcessUnreadEvents(void)
+{
+ DBEVENTINFO dbei = {0};
+ HANDLE hDbEvent,hContact;
+
+ dbei.cbSize = sizeof(dbei);
+
+ hContact = SRCFindFirstContact();
+ while (hContact)
+ {
+ hDbEvent = (HANDLE)CallService(MS_DB_EVENT_FINDFIRSTUNREAD,(WPARAM)hContact,0);
+
+ while (hDbEvent)
+ {
+ dbei.cbBlob=0;
+ CallService(MS_DB_EVENT_GET,(WPARAM)hDbEvent,(LPARAM)&dbei);
+ if (!(dbei.flags&(DBEF_SENT|DBEF_READ)) && dbei.eventType==EVENTTYPE_CONTACTS)
+ { //process the event
+ HookDBEventAdded((WPARAM)hContact, (LPARAM)hDbEvent);
+ }
+ hDbEvent = (HANDLE)CallService(MS_DB_EVENT_FINDNEXT,(WPARAM)hDbEvent,0);
+ }
+ hContact = SRCFindNextContact(hContact);
+ }
+}
+
+
+static bool CheckContactsServiceSupport(const char* szProto)
+{
+ if (g_NewProtoAPI)
+ { // there is no way to determine if the service exists (only proto_interface call is supported by 0.8+)
+ if (SRCCallProtoService(szProto, PS_GETCAPS, PFLAGNUM_1, 0) & PF1_CONTACTSEND)
+ return true;
+ }
+ else
+ { // check the real send service (only 0.7.x and older)
+ char serstr[MAX_PATH+30];
+
+ strcpy(serstr, szProto);
+ strcat(serstr, PSS_CONTACTS);
+ if (ServiceExists(serstr))
+ return true;
+ }
+ return false;
+}
+
+
+static int HookPreBuildContactMenu(WPARAM wParam, LPARAM lParam)
+{
+ HANDLE hContact = (HANDLE)wParam;
+ char* szProto = GetContactProto(hContact);
+ int bVisible = FALSE;
+
+ if (szProto && CheckContactsServiceSupport(szProto))
+ { // known protocol, protocol supports contacts sending
+ // check the selected contact if it supports contacts receive
+ if (SRCCallProtoService(szProto, PS_GETCAPS, PFLAG_MAXCONTACTSPERPACKET, (LPARAM)hContact))
+ bVisible = TRUE;
+ }
+
+ { // update contact menu item's visibility
+ CLISTMENUITEM mi = {0};
+
+ mi.cbSize = sizeof(mi);
+ if (bVisible)
+ mi.flags = CMIM_FLAGS;
+ else
+ mi.flags = CMIM_FLAGS | CMIF_HIDDEN;
+
+ CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hContactMenuItem, (LPARAM)&mi);
+ }
+
+ return 0;
+}
+
+
+static int HookModulesLoaded(WPARAM wParam, LPARAM lParam)
+{
+ char* modules[2] = {0};
+ WCHAR tmp[MAX_PATH];
+
+ modules[0] = MODULENAME;
+ CallService("DBEditorpp/RegisterModule",(WPARAM)modules,(LPARAM)1);
+
+ CLISTMENUITEM mi = {0};
+ mi.cbSize = sizeof(mi);
+ mi.ptszName = SRCTranslateT("Contacts", tmp);
+ mi.position = -2000009990; //position in menu
+ mi.flags = CMIF_KEEPUNTRANSLATED;
+ if (g_UnicodeCore)
+ mi.flags |= CMIF_UNICODE;
+ mi.pszService = MS_CONTACTS_SEND;
+ mi.hIcon = LoadIcon(hInst, MAKEINTRESOURCE(IDI_CONTACTS));
+
+ hContactMenuItem = (HANDLE)CallService(MS_CLIST_ADDCONTACTMENUITEM, 0, (LPARAM)&mi);
+ hHookPreBuildContactMenu = HookEvent(ME_CLIST_PREBUILDCONTACTMENU, HookPreBuildContactMenu);
+
+ ghSendWindowList = (HANDLE)CallService(MS_UTILS_ALLOCWINDOWLIST, 0, 0); // no need to destroy this
+ ghRecvWindowList = (HANDLE)CallService(MS_UTILS_ALLOCWINDOWLIST, 0, 0); // no need to destroy this
+
+#ifndef WIN64
+ //register for Update (the FL name is different...)
+ CallService(MS_UPDATE_REGISTERFL, 1253, (WPARAM)&pluginInfo);
+#endif
+
+ ProcessUnreadEvents();
+ return 0;
+}
+
+
+static int HookContactSettingChanged(WPARAM wParam, LPARAM lParam)
+{
+ DBCONTACTWRITESETTING *cws = (DBCONTACTWRITESETTING*)lParam;
+ char *szProto = GetContactProto((HANDLE)wParam);
+
+ if (strcmpnull(cws->szModule,"CList") && strcmpnull(cws->szModule, szProto)) return 0;
+
+ WindowList_Broadcast(ghSendWindowList,DM_UPDATETITLE,0,0);
+ WindowList_Broadcast(ghRecvWindowList,DM_UPDATETITLE,0,0);
+
+ return 0;
+}
+
+
+static int HookContactDeleted(WPARAM wParam, LPARAM lParam)
+{ // if our contact gets deleted close his window
+ HWND h = WindowList_Find(ghSendWindowList,(HANDLE)wParam);
+
+ if (h)
+ {
+ SendMessageT(h,WM_CLOSE,0,0);
+ }
+
+ while (h = WindowList_Find(ghRecvWindowList, (HANDLE)wParam))
+ { // since we hack the window list - more windows for one contact, we need to close them all
+ SendMessageT(h, WM_CLOSE,0,0);
+ }
+ return 0;
+}
+
+
+static INT_PTR ServiceSendCommand(WPARAM wParam, LPARAM lParam)
+{
+ HWND hWnd;
+ //find window for hContact
+ hWnd = WindowList_Find(ghSendWindowList, (HANDLE)wParam);
+
+ if (!hWnd)
+ CreateDialogParamT(hInst, MAKEINTRESOURCE(IDD_SEND), NULL, SendDlgProc, (LPARAM)(HANDLE)wParam);
+ else
+ {
+ SetForegroundWindow(hWnd);
+ SetFocus(hWnd);
+ }
+ return 0;
+}
+
+static INT_PTR ServiceReceiveCommand(WPARAM wParam, LPARAM lParam)
+{
+ CLISTEVENT* pcle = (CLISTEVENT*)lParam;
+
+ CreateDialogParamT(hInst, MAKEINTRESOURCE(IDD_RECEIVE), NULL, RecvDlgProc, (LPARAM)pcle);
+
+ return 0;
+}
+
+
+static void* PrepareMirandaPluginInfo(DWORD mirandaVersion)
+{
+ if (!(mirandaVersion >= PLUGIN_MAKE_VERSION(0,4,0,0)))
+ pluginInfo.description = "Allows you to send and receive contacts; Please upgrade your Miranda IM to version 0.4 for better functionality.";
+ else
+ g_SendAckSupported = TRUE;
+
+ if (mirandaVersion >= PLUGIN_MAKE_VERSION(0,7,0,0))
+ g_Utf8EventsSupported = TRUE;
+
+ if (mirandaVersion >= PLUGIN_MAKE_VERSION(0,8,0,8))
+ g_NewProtoAPI = TRUE;
+
+ if (mirandaVersion >= PLUGIN_MAKE_VERSION(0,3,3,0))
+ {
+ // Are we running under Unicode Windows version ?
+ if ((GetVersion() & 0x80000000) == 0)
+ {
+ pluginInfo.flags = 1; // UNICODE_AWARE
+ }
+ return &pluginInfo;
+ }
+ return NULL;
+}
+
+extern "C" __declspec(dllexport) PLUGININFOEX* MirandaPluginInfoEx(DWORD mirandaVersion)
+{
+ pluginInfo.cbSize = sizeof(PLUGININFOEX);
+ return (PLUGININFOEX*)PrepareMirandaPluginInfo(mirandaVersion);
+}
+
+extern "C" __declspec(dllexport) PLUGININFO* MirandaPluginInfo(DWORD mirandaVersion)
+{
+ pluginInfo.cbSize = sizeof(PLUGININFO);
+ return (PLUGININFO*)PrepareMirandaPluginInfo(mirandaVersion);
+}
+
+static const MUUID interfaces[] = {MIID_SRCONTACTS, MIID_LAST};
+extern "C" __declspec(dllexport) const MUUID* MirandaPluginInterfaces(void)
+{
+ return interfaces;
+}
+
+extern "C" __declspec(dllexport) int Load(PLUGINLINK *link)
+{
+ pluginLink = link;
+ InitCommonControls();
+ InitI18N();
+
+ { // Are we running under unicode Miranda core ?
+ char szVer[MAX_PATH];
+
+ CallService(MS_SYSTEM_GETVERSIONTEXT, MAX_PATH, (LPARAM)szVer);
+ _strlwr(szVer);
+ g_UnicodeCore = (strstr(szVer, "unicode") != NULL);
+ }
+ //init hooks
+ hHookModulesLoaded = HookEvent(ME_SYSTEM_MODULESLOADED, HookModulesLoaded);
+ hHookDBEventAdded = HookEvent(ME_DB_EVENT_ADDED, HookDBEventAdded);
+ hHookContactDeleted = HookEvent(ME_DB_CONTACT_DELETED, HookContactDeleted);
+ hHookContactSettingChanged = HookEvent(ME_DB_CONTACT_SETTINGCHANGED, HookContactSettingChanged);
+ //create services
+ hServiceSend = CreateServiceFunction(MS_CONTACTS_SEND, ServiceSendCommand);
+ hServiceReceive = CreateServiceFunction(MS_CONTACTS_RECEIVE, ServiceReceiveCommand);
+ //define event sounds
+ SkinAddNewSound("RecvContacts", LPGEN("Incoming Contacts"), "contacts.wav");
+ SkinAddNewSound("SentContacts", LPGEN("Outgoing Contacts"), "ocontacts.wav");
+
+ return 0;
+}
+
+extern "C" __declspec(dllexport) int Unload(void)
+{
+ UnhookEvent(hHookModulesLoaded);
+ UnhookEvent(hHookDBEventAdded);
+ UnhookEvent(hHookContactDeleted);
+ UnhookEvent(hHookContactSettingChanged);
+ UnhookEvent(hHookPreBuildContactMenu);
+
+ DestroyServiceFunction(hServiceSend);
+ DestroyServiceFunction(hServiceReceive);
+
+ return 0;
+}
diff --git a/plugins/ContactsPlus/readme_contacts.txt b/plugins/ContactsPlus/readme_contacts.txt
new file mode 100644
index 0000000000..f3ae933be3
--- /dev/null
+++ b/plugins/ContactsPlus/readme_contacts.txt
@@ -0,0 +1,158 @@
+About
+-----
+
+Send and receive contacts ui
+Version 1.5.2.0
+by Joe Kucera aka Jokusoftware
+Original Code by Todor Totev aka Dominus Procellarum
+for use with Miranda IM 0.3.3+
+Best for Miranda IM 0.4+
+
+
+Description
+-----------
+
+This plugin allows you to send and receive contacts.
+It is protocol independent, although currently the only
+protocol supporting contacts transfer is ICQ.
+
+
+Installation
+------------
+
+For the contactsp.zip zip archive -
+ Extract contacts.dll to Miranda plugin folder -
+ usually this is C:\Program Files\Miranda\Plugins.
+ All other files are not mandatory and can go to Miranda folder.
+
+
+Source
+------
+
+The source code for this plugin can be downloaded from Miranda IM
+website http://addons.miranda-im.org.
+
+
+License
+-------
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+1. Redistributions of source code must retain the copyright
+ notice, this list of conditions and the following disclaimer.
+2. The origin of this software must not be misrepresented; you must
+ not claim that you wrote the original software. If you use this
+ software in a product, an acknowledgment in the product
+ documentation would be appreciated but is not required.
+3. Altered source versions must be plainly marked as such, and must
+ not be misrepresented as being the original software.
+4. The name of the author may not be used to endorse or promote
+ products derived from this software without specific prior written
+ permission.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+For more information, e-mail jokusoftware@miranda-im.org
+
+
+Version history
+---------------
+1.0.11.0
+ initial release - working ui, but M is still crashing
+1.0.12.0
+ 20-may night build of M - underlying code is OK, so i can continue this plugin
+ remove inverse logic in MirandaPluginInfo()
+ removed #include "win2k.h" for cleaner build
+ attempt to show more user info on receive contacts
+1.0.13.0
+ cleaned main.cpp
+ added icon to dialogue windows
+1.0.14.0
+ Nick / UIN swapped upon showing received contacts /silly me/
+ bigger size of nick string allowed to accomodate non-english nicks /cyrrilic letters requires 2 times more bytes/
+ added icon for menu item
+1.0.15.0
+ list columns default size is more convinient
+ save restore window position / size
+1.0.16.0
+ receive dlg is resizable one /thanks to WTL there was virtually no code to write/
+1.0.17.0
+ add button is enabled only when at least one item in the list view is checked-in
+1.0.18.0
+ more translate()-friendly
+ at last contacts are permanently added to DB
+1.0.19.0
+ receive window is now being put on top
+ lots of big-fixes
+1.1.0.0
+ source beautify
+ receive user iface and internal dependancies re-design
+ now only contacts which details are requested are being added to the DB
+ std::vector is used instead of std::deque for 10KB smaller dll
+ this should be the official release build
+ you can get detailed info about contacts being sent to you
+ more bug fixes
+1.2.0.0
+ bugfix - contacts are always being added outside any group /forget actually writing to the DB/
+ sending contacts is now a Miranda service, accessible via m_contacts.h
+ implemented contactlist event, no more popup windows
+ NOTE: the langpack is modified, because my english is at least questionable and some items are now obsolete
+
+1.4.0.0 (New developer: Joe @ Whale, jokusoftware@miranda-im.org)
+ now fully protocol independent
+ made sending with full acknowledgement (needs miranda 0.3.4alpha) & improved Send Dialog
+ now sent contacts are added to history (can be viewed by e.g. History++)
+ improved Receive Dialog - added popup & some convenient functions, display more info (like ICQ)
+ many fixes
+1.4.1.3
+ fixed multipacket sending (if 15 contacts, do not try to send empty packet)
+ optimisations (reimplemented many structures, size cut by 20kB)
+ when contact gets deleted close his send window
+ redesigned Send dialog - more nice & effective (show only contacts of the same protocol + many more)
+ grouplist on receive dialog now gets updated
+1.4.1.7
+ redesigned and improved Received dialog (get rid of WTL & MFC)
+ empty groups in send dialog are hidden according to clui setting
+ fixed multi-packet error handling
+ fixed crashes on exit (thanks to Ghazan)
+ small fixes
+1.4.1.8
+ fixed received dialog not showed on some systems
+ other small fixes
+1.4.2.0
+ fixed memory leak on any event received (thx to Ghazan)
+ fixed other small memory leaks
+ popup menu on Received dialog gets translated now
+ added DBE3++ Known Modules support
+1.5.0.0
+ many internal optimisations
+ added Unicode 2in1 support
+ added support for Unicode ready DB contacts events
+ added Updater plug-in support
+1.5.1.0
+ added support for per-contact contacts API capabilities
+ improved compatibility with unicode database API
+ added support for new clist groups API
+ several internal fixes & improvements
+1.5.2.0
+ fixed possible crash during contacts send (with older Miranda IM)
+ fixed compatibility with the new Account API introduced in Miranda IM 0.8
+
+
+Translation
+-----------
+
+Contacts plugin can be translated via the Miranda language files.
+The required strings are provided in langpack_contacts.txt file.
diff --git a/plugins/ContactsPlus/receive.cpp b/plugins/ContactsPlus/receive.cpp
new file mode 100644
index 0000000000..24caf66a5a
--- /dev/null
+++ b/plugins/ContactsPlus/receive.cpp
@@ -0,0 +1,522 @@
+// --------------------------------------------------------------------------
+// Contacts+ for Miranda Instant Messenger
+// _______________________________________
+//
+// Copyright © 2002 Dominus Procellarum
+// Copyright © 2004-2008 Joe Kucera
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// -----------------------------------------------------------------------------
+
+#include "contacts.h"
+
+
+/* TRecvContactsData */
+
+TReceivedItem* TRecvContactsData::AddReceivedItem() {
+ int iItem = cbReceived;
+
+ cbReceived++;
+ maReceived = (TReceivedItem**)realloc(maReceived, cbReceived*sizeof(TReceivedItem*));
+ maReceived[iItem] = new TReceivedItem();
+
+ return maReceived[iItem];
+}
+
+
+static int RecvDlg_Resize(HWND hwndDlg,LPARAM lParam,UTILRESIZECONTROL *urc)
+{
+ switch (urc->wId)
+ {
+ case IDC_CONTACTS:
+ return RD_ANCHORX_WIDTH | RD_ANCHORY_HEIGHT;
+ break;
+ case IDOK:
+ case IDDETAILS:
+ case IDC_ENABLEGROUPS:
+ case IDC_GROUPS:
+ return RD_ANCHORX_LEFT | RD_ANCHORY_BOTTOM;
+ break;
+ case IDC_ADD:
+ case IDC_HISTORY:
+ case IDC_USERMENU:
+ case IDC_DETAILS:
+ return RD_ANCHORX_RIGHT | RD_ANCHORY_TOP;
+ break;
+ case IDCANCEL:
+ return RD_ANCHORY_BOTTOM | RD_ANCHORX_RIGHT;
+ break;
+ }
+ return RD_ANCHORX_LEFT | RD_ANCHORY_TOP; // default
+}
+
+
+static char* ListView_GetItemTextEx(HWND hLV, int iItem, int iSubItem)
+{
+ LVITEM lvi = {0};
+
+ lvi.mask = LVIF_TEXT;
+ lvi.iSubItem = iSubItem;
+ lvi.cchTextMax = 64;
+ lvi.pszText = (char*)malloc(lvi.cchTextMax);
+ while (SendMessageT(hLV, LVM_GETITEMTEXT, iItem, (LPARAM)&lvi) == lvi.cchTextMax - 1)
+ { // loop until the returned size is smaller than buffer size
+ SAFE_FREE((void**)&lvi.pszText);
+ lvi.cchTextMax += 64;
+ lvi.pszText = (char*)malloc(lvi.cchTextMax);
+ }
+ return lvi.pszText;
+}
+
+
+static void EnableGroupCombo(HWND hwndDlg)
+{
+ EnableDlgItem(hwndDlg, IDC_GROUPS, SendMessageT(GetDlgItem(hwndDlg, IDC_ENABLEGROUPS), BM_GETCHECK, 0, 0));
+}
+
+
+static void RebuildGroupCombo(HWND hwndDlg)
+{
+ DBVARIANT dbv = {0};
+ char caGroupId[33];
+ int bHasGroups = !DBGetContactSettingT(NULL, "CListGroups", "0", &dbv);
+ HWND hGroupsCombo = GetDlgItem(hwndDlg, IDC_GROUPS);
+
+ DBFreeVariant(&dbv);
+ if (bHasGroups)
+ {
+ int curs = SendMessageT(hGroupsCombo, CB_GETCURSEL, 0, 0);
+ TCHAR* curst;
+
+ EnableDlgItem(hwndDlg, IDC_ENABLEGROUPS, TRUE);
+ EnableGroupCombo(hwndDlg);
+
+ if (curs != CB_ERR)
+ {
+ curst = (char*)_alloca((SendMessageT(hGroupsCombo, CB_GETLBTEXTLEN, curs, 0) + 1) * sizeof(WCHAR));
+ SendMessageT(hGroupsCombo, CB_GETLBTEXT, curs, (LPARAM)curst);
+ }
+ SendMessageT(hGroupsCombo, CB_RESETCONTENT, 0, 0);
+
+ for (int groupId=0; ; groupId++)
+ {
+ itoa(groupId, caGroupId, 10);
+ TCHAR* szGroup = DBGetContactSettingStringT(NULL, "CListGroups", caGroupId, NULL);
+ int nPrefix = g_UnicodeCore ? sizeof(WCHAR) : sizeof(char);
+ if (!szGroup) break;
+ int nIndex = SendMessageT(hGroupsCombo, CB_ADDSTRING, 0, (LPARAM)szGroup + nPrefix);
+ SendMessageT(hGroupsCombo, CB_SETITEMDATA, nIndex, groupId+1);
+ SAFE_FREE((void**)&szGroup);
+ }
+ if (curs != CB_ERR)
+ SendMessageT(hGroupsCombo, CB_SELECTSTRING, -1, (LPARAM)curst);
+ else
+ SendMessageT(hGroupsCombo, CB_SETCURSEL, 0, 0);
+ }
+ else
+ { // no groups available
+ EnableDlgItem(hwndDlg, IDC_ENABLEGROUPS, FALSE);
+ EnableDlgItem(hwndDlg, IDC_GROUPS, FALSE);
+ }
+}
+
+
+static HANDLE CreateTemporaryContactForItem(HWND hwndDlg, TRecvContactsData* wndData, int iItem)
+{
+ char* caUIN = ListView_GetItemTextEx(GetDlgItem(hwndDlg, IDC_CONTACTS), iItem, 0);
+ char* szProto = GetContactProto(wndData->mhContact);
+ wndData->rhSearch = (HANDLE)SRCCallProtoService(szProto, PS_BASICSEARCH, 0, (LPARAM)caUIN); // find it
+ SAFE_FREE((void**)&wndData->haUin);
+ wndData->haUin = caUIN;
+ for (int j = 0; j < wndData->cbReceived; j++)
+ if (!strcmpnull(wndData->maReceived[j]->mcaUIN, caUIN))
+ return (HANDLE)SRCCallProtoService(szProto, PS_ADDTOLISTBYEVENT, MAKEWPARAM(PALF_TEMPORARY, j), (LPARAM)wndData->mhDbEvent);
+ return NULL;
+}
+
+
+void RecvListView_AddColumn(HWND hList, int nWidth, const char* szTitle, int nTranslate, int nItem) {
+ LVCOLUMN col;
+ WCHAR tmp[MAX_PATH];
+
+
+ col.mask = LVCF_FMT|LVCF_WIDTH|LVCF_TEXT|LVCF_SUBITEM;
+ col.fmt = LVCFMT_LEFT;
+ col.cx = nWidth;
+ if (nTranslate) {
+ col.pszText = SRCTranslateT(szTitle, tmp);
+ }
+ else {
+ if (!szTitle) szTitle = "UID";
+ col.pszText = ansi_to_tchar(szTitle, CallService(MS_LANGPACK_GETCODEPAGE, 0, 0));
+ }
+ col.iSubItem = nItem;
+ ListView_InsertColumnT(hList, nItem, &col);
+ if (!nTranslate)
+ SAFE_FREE((void**)&col.pszText);
+}
+
+
+INT_PTR CALLBACK RecvDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ TRecvContactsData* wndData = (TRecvContactsData*)GetWindowLong(hwndDlg, DWLP_USER);
+
+ switch (msg)
+ {
+ case WM_INITDIALOG:
+ {
+ CLISTEVENT* pcle = (CLISTEVENT*)lParam; /// got it
+
+ TranslateDialogDefault(hwndDlg);
+ WindowList_Add(ghRecvWindowList, hwndDlg, pcle->hContact);
+ SendMessageT(hwndDlg, WM_SETICON, ICON_SMALL, (LPARAM)LoadIcon(hInst, MAKEINTRESOURCE(IDI_CONTACTS)));
+ EnableDlgItem(hwndDlg, IDOK, FALSE);
+ EnableDlgItem(hwndDlg, IDDETAILS, FALSE);
+ wndData = new TRecvContactsData(pcle->hContact);
+ SetWindowLong(hwndDlg, DWLP_USER, (LONG)wndData);
+ wndData->mhDbEvent = pcle->hDbEvent; /// initialized, pcle not needed anymore
+ wndData->mhListIcon = ImageList_Create(GetSystemMetrics(SM_CXSMICON),GetSystemMetrics(SM_CYSMICON),ILC_COLORDDB|ILC_MASK, 0, 1);
+ wndData->mhPopup = LoadMenu(hInst, MAKEINTRESOURCE(IDR_CONTACTMENU));
+ CallService(MS_LANGPACK_TRANSLATEMENU, (WPARAM)wndData->mhPopup, 0);
+ wndData->hHook = HookEventMessage(ME_PROTO_ACK, hwndDlg, HM_EVENTSENT);
+
+ char *szProto = GetContactProto(wndData->mhContact);
+
+ HWND hLV = GetDlgItem(hwndDlg, IDC_CONTACTS);
+ ListView_SetExtendedListViewStyle(hLV, LVS_EX_CHECKBOXES|LVS_EX_FULLROWSELECT);
+ // add columns
+ RecvListView_AddColumn(hLV, 120, (char*)SRCCallProtoService(szProto, PS_GETCAPS, PFLAG_UNIQUEIDTEXT, 0), FALSE, 0);
+ RecvListView_AddColumn(hLV, 100, "Nick", TRUE, 1);
+ RecvListView_AddColumn(hLV, 100, "First Name", TRUE, 2);
+ RecvListView_AddColumn(hLV, 100, "Last Name", TRUE, 3);
+
+ // fill in groups
+ SendMessageT(GetDlgItem(hwndDlg, IDC_ENABLEGROUPS), BM_SETCHECK, (WPARAM)BST_UNCHECKED, 0);
+ RebuildGroupCombo(hwndDlg);
+
+ { // fill listview with received contacts
+ DBEVENTINFO dbe = {0};
+
+ dbe.cbSize = sizeof(DBEVENTINFO);
+ dbe.cbBlob = CallService(MS_DB_EVENT_GETBLOBSIZE, (WPARAM)wndData->mhDbEvent, 0);
+ if (dbe.cbBlob != -1) // this marks an invalid hDbEvent - all smashed anyway...
+ dbe.pBlob = (PBYTE)_alloca(dbe.cbBlob);
+ CallService(MS_DB_EVENT_GET, (WPARAM)wndData->mhDbEvent, (LPARAM)&dbe);
+ char* pcBlob = (char*)dbe.pBlob;
+ char* pcEnd = (char*)dbe.pBlob + dbe.cbBlob;
+
+ HICON hiProto = LoadContactProtoIcon(wndData->mhContact);
+ ImageList_AddIcon(wndData->mhListIcon, hiProto);
+ DestroyIcon(hiProto); // imagelist copied the resource
+ ListView_SetImageList(hLV, wndData->mhListIcon, LVSIL_SMALL);
+ LVITEM lvi = {0};
+ lvi.iImage = 0;
+ lvi.mask = LVIF_TEXT | LVIF_IMAGE;
+
+ for (int nItem = 0; ; nItem++)
+ { // Nick
+ int strsize = (int)strlennull(pcBlob);
+ TReceivedItem* pItem = wndData->AddReceivedItem();
+
+ if (dbe.flags & DBEF_UTF)
+ pItem->mcaNick = utf8_to_tchar((unsigned char*)pcBlob);
+ else
+ pItem->mcaNick = ansi_to_tchar(pcBlob);
+ pcBlob += strsize + 1;
+ // UIN
+ strsize = (int)strlennull(pcBlob);
+ pItem->mcaUIN = null_strdup(pcBlob);
+ pcBlob += strsize + 1;
+ // add to listview
+ lvi.iItem = nItem;
+ lvi.pszText = pItem->mcaUIN;
+ ListView_InsertItem(hLV, &lvi); // with image
+ ListView_SetItemTextT(hLV, nItem, 1, pItem->mcaNick);
+ // check for end of contacts
+ if (pcBlob >= pcEnd)
+ break;
+ }
+ }
+ // new dlg init
+ wndData->hIcons[0] = InitMButton(hwndDlg, IDC_ADD, MAKEINTRESOURCEA(IDI_ADDCONTACT), "Add Contact Permanently to List");
+ wndData->hIcons[1] = InitMButton(hwndDlg, IDC_DETAILS, MAKEINTRESOURCEA(IDI_USERDETAILS), "View User's Details");
+ wndData->hIcons[2] = InitMButton(hwndDlg, IDC_HISTORY, MAKEINTRESOURCEA(IDI_HISTORY), "View User's History");
+ wndData->hIcons[3] = InitMButton(hwndDlg, IDC_USERMENU, MAKEINTRESOURCEA(IDI_DOWNARROW), "User Menu");
+
+ SendMessageT(hwndDlg,DM_UPDATETITLE,0,0);
+ // new dialog init done
+ Utils_RestoreWindowPosition(hwndDlg, NULL, MODULENAME, "");
+ return TRUE;
+ }
+ case WM_NOTIFY:
+ if (((LPNMHDR)lParam)->idFrom == IDC_CONTACTS)
+ {
+ switch (((LPNMHDR)lParam)->code)
+ {
+ case NM_DBLCLK:
+ {
+ HWND hLV = GetDlgItem(hwndDlg, IDC_CONTACTS);
+ if (ListView_GetSelectedCount(hLV) != 1) break; // if not clicking on item, bye
+ wndData->iPopupItem = ListView_GetNextItem(hLV, -1, LVNI_ALL|LVNI_SELECTED);
+ if (wndData->iPopupItem == -1) break; // if no item selected no user details available
+ return SendMessageT(hwndDlg, WM_COMMAND, ID_POPUP_USERDETAILS, 0); // show user details
+ }
+ case LVN_ITEMCHANGED:
+ {
+ LPNMLISTVIEW pNMLV = (LPNMLISTVIEW)lParam;
+ HWND hLV = GetDlgItem(hwndDlg, IDC_CONTACTS); // optimisation, for FOR-Cycle
+ bool bExistsCheckedItem = false; // there must be no checked items to disable "Add" button
+
+ if (ListView_GetCheckState(hLV, pNMLV->iItem))
+ { // the user has checked this item
+ bExistsCheckedItem = true; // enable "Add" button
+ }
+ else
+ { // loop thru items and check if at least one is checked
+ for (int i = 0; i < ListView_GetItemCount(hLV); i++)
+ if (ListView_GetCheckState(hLV, i))
+ { // we found checked item, enable add, exit loop
+ bExistsCheckedItem = true;
+ break;
+ }
+ }
+ EnableDlgItem(hwndDlg, IDOK, bExistsCheckedItem);
+ EnableDlgItem(hwndDlg, IDDETAILS, ListView_GetSelectedCount(hLV) > 0);
+ break;
+ }
+ }
+ }
+ break;
+
+ case WM_COMMAND:
+ {
+ if (!lParam && CallService(MS_CLIST_MENUPROCESSCOMMAND, MAKEWPARAM(LOWORD(wParam), MPCF_CONTACTMENU), (LPARAM)wndData->mhContact))
+ break;
+
+ switch(LOWORD(wParam))
+ {
+ case IDOK: // "Add Selected" button click
+ { // for each selected item, find its index in the hDbEvent
+ // and after that add this item to the DB permanently
+ char* caUIN;
+ HWND hLV = GetDlgItem(hwndDlg, IDC_CONTACTS);
+ HWND hGroupsCombo = GetDlgItem(hwndDlg, IDC_GROUPS);
+ HWND hGroupsCheck = GetDlgItem(hwndDlg, IDC_ENABLEGROUPS);
+ int curs = SendMessageT(hGroupsCombo, CB_GETCURSEL, 0, 0);
+ TCHAR* caGroup = NULL;
+ int nGroupId = -1;
+ if (curs != CB_ERR && IsWindowEnabled(hGroupsCheck) && SendMessageT(hGroupsCheck, BM_GETCHECK, 0, 0))
+ { //got groups, get the one selected in combo
+ TCHAR* caGroup = (TCHAR*)_alloca((SendMessageT(hGroupsCombo, CB_GETLBTEXTLEN, curs, 0) + 1) * sizeof(WCHAR));
+ SendMessageT(hGroupsCombo, CB_GETLBTEXT, curs, (LPARAM)caGroup);
+ nGroupId = SendMessageT(hGroupsCombo, CB_GETITEMDATA, curs, 0);
+ }
+
+ for (int i = 0; i < ListView_GetItemCount(hLV); i++)
+ if (ListView_GetCheckState(hLV, i))
+ { // found checked contact item, add it
+ caUIN = ListView_GetItemTextEx(hLV, i, 0);
+ for (int j = 0; j < wndData->cbReceived; j++) // determine item index in packet
+ if (!strcmpnull(wndData->maReceived[j]->mcaUIN, caUIN))
+ {
+ char* szProto = GetContactProto(wndData->mhContact);
+ HANDLE hContact = (HANDLE)SRCCallProtoService(szProto, PS_ADDTOLISTBYEVENT, MAKEWPARAM(0, j), (LPARAM)wndData->mhDbEvent);
+ if (hContact && caGroup)
+ { // use newest group API if available
+ if (ServiceExists(MS_CLIST_CONTACTCHANGEGROUP))
+ CallService(MS_CLIST_CONTACTCHANGEGROUP, (WPARAM)hContact, (LPARAM)nGroupId);
+ else
+ DBWriteContactSettingStringT(hContact, "CList", "Group", caGroup);
+ }
+ break;
+ }
+ SAFE_FREE((void**)&caUIN);
+ } // move to next item
+ break;
+ }
+ case IDDETAILS:
+ { // for each selected item, find its index in the hDbEvent
+ // and after that add this item to the DB
+ // finally, request Details window for this hContact
+ HWND hLV = GetDlgItem(hwndDlg, IDC_CONTACTS);
+ for (int i = 0; i < ListView_GetItemCount(hLV); i++)
+ if (ListView_GetItemState(hLV, i, LVIS_SELECTED))
+ {
+ HANDLE hContact = CreateTemporaryContactForItem(hwndDlg, wndData, i);
+ if (hContact)
+ CallService(MS_USERINFO_SHOWDIALOG, (WPARAM)hContact, 0);
+ }
+ break;
+ }
+ case IDCANCEL:
+ {
+ SendMessageT(hwndDlg, WM_CLOSE, 0, 0);
+ break;
+ }
+ case IDC_ENABLEGROUPS:
+ {
+ EnableGroupCombo(hwndDlg);
+ break;
+ }
+ case IDC_GROUPS:
+ { // rebuild group list on popup
+ if (HIWORD(wParam) == CBN_DROPDOWN)
+ RebuildGroupCombo(hwndDlg);
+ break;
+ }
+ case ID_POPUP_ADDUSER:
+ {
+ HANDLE hContact = CreateTemporaryContactForItem(hwndDlg, wndData, wndData->iPopupItem);
+
+ if (hContact)
+ DialogAddContactExecute(hwndDlg, hContact);
+ break;
+ }
+ case ID_POPUP_USERDETAILS:
+ {
+ HANDLE hContact = CreateTemporaryContactForItem(hwndDlg, wndData, wndData->iPopupItem);
+
+ if (hContact)
+ CallService(MS_USERINFO_SHOWDIALOG, (WPARAM)hContact, 0 );
+ break;
+ }
+ case ID_POPUP_SENDMESSAGE:
+ {
+ HANDLE hContact = CreateTemporaryContactForItem(hwndDlg, wndData, wndData->iPopupItem);
+
+ if (hContact)
+ CallService(MS_MSG_SENDMESSAGE, (WPARAM)hContact, 0);
+ break;
+ }
+ case IDC_USERMENU:
+ {
+ RECT rc;
+ HMENU hMenu = (HMENU)CallService(MS_CLIST_MENUBUILDCONTACT, (WPARAM)wndData->mhContact, 0);
+ GetWindowRect(GetDlgItem(hwndDlg,IDC_USERMENU), &rc);
+ TrackPopupMenu(hMenu, 0, rc.left, rc.bottom, 0, hwndDlg, NULL);
+ DestroyMenu(hMenu);
+ break;
+ }
+ case IDC_HISTORY:
+ CallService(MS_HISTORY_SHOWCONTACTHISTORY,(WPARAM)wndData->mhContact,0);
+ break;
+ case IDC_DETAILS:
+ CallService(MS_USERINFO_SHOWDIALOG,(WPARAM)wndData->mhContact,0);
+ break;
+ case IDC_ADD:
+ DialogAddContactExecute(hwndDlg, wndData->mhContact);
+ break;
+ }
+ break;
+ }
+ case WM_CONTEXTMENU:
+ {
+ HWND hLV = GetDlgItem(hwndDlg, IDC_CONTACTS);
+ LVHITTESTINFO lvh;
+ RECT rt;
+
+ wndData->iPopupItem = -1;
+ if ((HWND)wParam != hLV) break; // if not our ListView go away
+ lvh.pt.x = LOWORD(lParam);
+ lvh.pt.y = HIWORD(lParam);
+ if (GetWindowRect(hLV, &rt)==0) return FALSE; // ?? why this, some check ??
+ ScreenToClient(hLV, &lvh.pt); // convert to ListView local coordinates
+ int ci = ListView_HitTest(hLV, &lvh);
+ if (ci==-1) break; // mouse is not over any item
+ wndData->iPopupItem = ci;
+ TrackPopupMenu(GetSubMenu(wndData->mhPopup, 0), TPM_LEFTALIGN|TPM_TOPALIGN, LOWORD(lParam), HIWORD(lParam), 0, hwndDlg, NULL);
+ break;
+ }
+ case HM_EVENTSENT:
+ {
+ ACKDATA *ack=(ACKDATA*)lParam;
+ if (ack->type!=ACKTYPE_SEARCH) break; // not search ack, go away
+ if (ack->hProcess!=wndData->rhSearch) break; //not our search, go away
+ if (ack->result==ACKRESULT_DATA)
+ {
+ HWND hLV = GetDlgItem(hwndDlg, IDC_CONTACTS);
+ PROTOSEARCHRESULT* psr = (PROTOSEARCHRESULT*)ack->lParam;
+ LVFINDINFO fi;
+ fi.flags = LVFI_STRING;
+ fi.psz = wndData->haUin;
+ int iLPos = ListView_FindItem(hLV, -1, &fi);
+ if (iLPos==-1) iLPos=0;
+// ListView_SetItemText(hLV, iLPos, 0, psr->email); // not sent by ICQ, and currently unsupported either
+ if (strcmpnull(psr->nick, "") && psr->nick) ListView_SetItemText(hLV, iLPos, 1, psr->nick);
+ ListView_SetItemText(hLV, iLPos, 2, psr->firstName);
+ ListView_SetItemText(hLV, iLPos, 3, psr->lastName);
+ break;
+ }
+ SAFE_FREE((void**)&wndData->haUin);
+ break;
+ }
+ case WM_CLOSE: // user closed window, so destroy it
+ {
+ WindowList_Remove(ghRecvWindowList, hwndDlg);
+ DestroyWindow(hwndDlg);
+ break;
+ }
+ case WM_DESTROY: // last message received by this dialog, cleanup
+ {
+ CallService(MS_DB_EVENT_MARKREAD, (WPARAM)wndData->mhContact, (LPARAM)wndData->mhDbEvent);
+ Utils_SaveWindowPosition(hwndDlg, NULL, MODULENAME, "");
+ ImageList_Destroy(wndData->mhListIcon);
+ UnhookEvent(wndData->hHook);
+ DestroyMenu(wndData->mhPopup);
+ for (int i=0; i < SIZEOF(wndData->hIcons); i++)
+ DestroyIcon(wndData->hIcons[i]);
+ delete wndData; // automatically calls destructor
+ break;
+ }
+ case WM_MEASUREITEM:
+ return CallService(MS_CLIST_MENUMEASUREITEM, wParam, lParam);
+
+ case WM_DRAWITEM:
+ {
+ DrawProtocolIcon(hwndDlg, lParam, wndData->mhContact);
+ return CallService(MS_CLIST_MENUDRAWITEM, wParam, lParam);
+ }
+ case WM_SIZE:
+ { // make the dlg resizeable
+ UTILRESIZEDIALOG urd = {0};
+
+ if (IsIconic(hwndDlg)) break;
+ urd.cbSize = sizeof(urd);
+ urd.hInstance = hInst;
+ urd.hwndDlg = hwndDlg;
+ urd.lParam = 0; // user-defined
+ urd.lpTemplate = MAKEINTRESOURCEA(IDD_RECEIVE);
+ urd.pfnResizer = RecvDlg_Resize;
+ CallService(MS_UTILS_RESIZEDIALOG, 0, (LPARAM) & urd);
+ break;
+ }
+ case WM_GETMINMAXINFO:
+ {
+ MINMAXINFO* mmi=(MINMAXINFO*)lParam;
+ mmi->ptMinTrackSize.x = 480+2*GetSystemMetrics(SM_CXSIZEFRAME);
+ mmi->ptMinTrackSize.y = 130+2*GetSystemMetrics(SM_CYSIZEFRAME);
+ break;
+ }
+ case DM_UPDATETITLE:
+ {
+ UpdateDialogTitle(hwndDlg, wndData?wndData->mhContact:NULL, "Contacts from");
+ if (wndData)
+ UpdateDialogAddButton(hwndDlg, wndData->mhContact);
+ break;
+ }
+ }
+ return FALSE;
+}
diff --git a/plugins/ContactsPlus/receive.h b/plugins/ContactsPlus/receive.h
new file mode 100644
index 0000000000..fe35d94be6
--- /dev/null
+++ b/plugins/ContactsPlus/receive.h
@@ -0,0 +1,65 @@
+// ---------------------------------------------------------------------------
+// Contacts+ for Miranda Instant Messenger
+// _______________________________________
+//
+// Copyright © 2002 Dominus Procellarum
+// Copyright © 2004-2008 Joe Kucera
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// ---------------------------------------------------------------------------
+
+#ifndef __RECEIVE_H
+#define __RECEIVE_H
+
+
+#define HM_EVENTSENT (WM_USER+10)
+
+#define DM_UPDATETITLE (WM_USER+11)
+
+#define IDI_ADDCONTACT 210
+#define IDI_USERDETAILS 160
+#define IDI_HISTORY 174
+#define IDI_DOWNARROW 264
+
+struct TReceivedItem {
+ char* mcaUIN;
+ TCHAR* mcaNick;
+ ~TReceivedItem() { SAFE_FREE((void**)&mcaUIN); SAFE_FREE((void**)&mcaNick); }
+ TReceivedItem() { mcaUIN = NULL; mcaNick = NULL; }
+};
+
+struct TRecvContactsData {
+ HANDLE mhDbEvent; // handle to recv DB event
+ HANDLE mhContact; // from whom we received this
+ HIMAGELIST mhListIcon;// icons for listview
+ HMENU mhPopup; // popup menu for listview
+ HANDLE hHook; // hook to event
+ HANDLE rhSearch; // handle to uin-search
+ char* haUin;
+ int iPopupItem;
+ TReceivedItem** maReceived;// received contacts
+ int cbReceived;
+ TReceivedItem* AddReceivedItem();
+ HICON hIcons[4]; // icons for dialog
+ TRecvContactsData(HANDLE contact) { mhContact = contact; hHook = NULL; cbReceived = 0; maReceived = NULL; haUin = NULL; };
+ ~TRecvContactsData() { if (cbReceived) { for(int i=0;i<cbReceived;i++) delete maReceived[i]; SAFE_FREE((void**)&maReceived); SAFE_FREE((void**)&haUin); }; };
+};
+
+extern HANDLE ghRecvWindowList;
+
+INT_PTR CALLBACK RecvDlgProc( HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
+
+#endif /* __RECEIVE_H */ \ No newline at end of file
diff --git a/plugins/ContactsPlus/res/SendContacts.ico b/plugins/ContactsPlus/res/SendContacts.ico
new file mode 100644
index 0000000000..6c118a1a02
--- /dev/null
+++ b/plugins/ContactsPlus/res/SendContacts.ico
Binary files differ
diff --git a/plugins/ContactsPlus/resource.h b/plugins/ContactsPlus/resource.h
new file mode 100644
index 0000000000..e4ed78f866
--- /dev/null
+++ b/plugins/ContactsPlus/resource.h
@@ -0,0 +1,44 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by contacts.rc
+//
+#define ID_SELECTALL 3
+#define IDDETAILS 5
+#define IDD_SEND 101
+#define IDC_PROTOCOL 1580
+#define IDC_NAME 1009
+#define IDC_ADD 1070
+#define IDC_USERMENU 1071
+#define IDC_DETAILS 1069
+#define IDC_HISTORY 1080
+#define IDB_LOGO 102
+#define IDD_RECEIVE 103
+#define IDD_MSGSENDERROR 104
+#define IDI_CONTACTS 109
+#define IDR_CONTACTMENU 110
+#define ID_POPUP_ADDUSER 111
+#define ID_POPUP_SENDMESSAGE 112
+#define ID_POPUP_USERDETAILS 113
+#define ID_POPUP_USERDETAILS_FAKE 114
+#define IDC_LOGO 1001
+#define IDC_OK 1002
+#define IDC_CANCEL 1003
+#define IDC_BACKIMAGE 1004
+#define IDC_GROUPS 1006
+#define IDC_ENABLEGROUPS 1007
+#define IDC_LIST 1079
+#define IDC_RESULTS 1142
+#define IDC_CONTACTS 1142
+#define IDC_STATUSBAR 1389
+#define IDC_ERRORTEXT 1400
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 114
+#define _APS_NEXT_COMMAND_VALUE 40001
+#define _APS_NEXT_CONTROL_VALUE 1008
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/plugins/ContactsPlus/send.cpp b/plugins/ContactsPlus/send.cpp
new file mode 100644
index 0000000000..1382b627b5
--- /dev/null
+++ b/plugins/ContactsPlus/send.cpp
@@ -0,0 +1,609 @@
+// --------------------------------------------------------------------------
+// Contacts+ for Miranda Instant Messenger
+// _______________________________________
+//
+// Copyright © 2002 Dominus Procellarum
+// Copyright © 2004-2008 Joe Kucera
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// -----------------------------------------------------------------------------
+
+#include "contacts.h"
+
+
+/* TSendProcessList */
+
+void TSendProcessList::Add(HANDLE hProcc) {
+ EnterCriticalSection(&lock);
+ Items=(HANDLE*)realloc(Items, (Count+1)*sizeof(HANDLE));
+ Items[Count]=hProcc;
+ Count++;
+ LeaveCriticalSection(&lock);
+}
+
+
+void TSendProcessList::Remove(HANDLE hProcc) {
+ EnterCriticalSection(&lock);
+ for (int i=0; i<Count; i++)
+ if (Items[i]==hProcc) {
+ memmove(Items+i, Items+i+1, (Count-i-1)*sizeof(HANDLE));
+ Count--;
+ break;
+ }
+ LeaveCriticalSection(&lock);
+}
+
+
+TSendProcessList::TSendProcessList() {
+ InitializeCriticalSection(&lock);
+ Count = 0;
+ Items = NULL;
+}
+
+
+TSendProcessList::~TSendProcessList() {
+ if (Count)
+ SAFE_FREE((void**)&Items);
+ DeleteCriticalSection(&lock);
+}
+
+
+/* TSendContactsData */
+
+TSendContactsData::TSendContactsData(HANDLE contact): uacklist() {
+ hContact = contact;
+ hHook = NULL;
+ hError = NULL;
+ aContacts = NULL;
+ nContacts = 0;
+}
+
+
+TSendContactsData::~TSendContactsData() {
+ ClearContacts();
+ UnhookProtoAck();
+}
+
+
+void TSendContactsData::HookProtoAck(HWND hwndDlg) {
+ if (!hHook)
+ hHook = HookEventMessage(ME_PROTO_ACK, hwndDlg, HM_EVENTSENT);
+};
+
+
+void TSendContactsData::UnhookProtoAck() {
+ if (hHook)
+ {
+ UnhookEvent(hHook);
+ hHook=NULL;
+ };
+}
+
+
+void TSendContactsData::ShowErrorDlg(HWND hwndDlg, char* szMsg, bool bAllowRetry) {
+ ShowWindow(hwndDlg, SW_SHOWNORMAL);
+ EnableWindow(hwndDlg, FALSE);
+ if (!hError)
+ {
+ hError = CreateDialogParamT(hInst, MAKEINTRESOURCEA(IDD_MSGSENDERROR), hwndDlg, ErrorDlgProc, (LPARAM)szMsg);
+ if (!bAllowRetry)
+ EnableDlgItem(hError, IDOK, FALSE); // do not allow again - fatal, could not be better
+ }
+}
+
+
+void TSendContactsData::ClearContacts() {
+ if (nContacts)
+ SAFE_FREE((void**)&aContacts);
+ nContacts=0;
+}
+
+
+void TSendContactsData::AddContact(HANDLE hContact) {
+ aContacts = (HANDLE*)realloc(aContacts, (nContacts+1)*sizeof(HANDLE));
+ aContacts[nContacts] = hContact;
+ nContacts++;
+}
+
+
+int TSendContactsData::SendContactsPacket(HWND hwndDlg, HANDLE *phContacts, int nContacts) {
+ HANDLE hProcc = (HANDLE)SRCCallContactService(hContact, PSS_CONTACTS, MAKEWPARAM(0, nContacts), (LPARAM)phContacts);
+ if (!hProcc)
+ { // on trivial error - do not close dialog
+ ShowErrorDlg(hwndDlg, "Contacts transfer failed!", FALSE);
+ return FALSE; // Failure
+ }
+ TAckData* ackData = gaAckData.Add(hProcc, new TAckData(hContact));
+ uacklist.Add(hProcc);
+ ackData->nContacts = nContacts;
+ ackData->aContacts = (HANDLE*)malloc(nContacts*sizeof(HANDLE));
+ memmove(ackData->aContacts, phContacts, nContacts*sizeof(HANDLE)); // copy the array of hContact for ack array
+ EnableDlgItem(hwndDlg, IDOK, FALSE);
+ EnableDlgItem(hwndDlg, IDC_LIST, FALSE);
+
+ return TRUE; // Success
+}
+
+
+int TSendContactsData::SendContacts(HWND hwndDlg) {
+ char* szProto = GetContactProto(hContact);
+ int nMaxContacts = SRCCallProtoService(szProto, PS_GETCAPS, PFLAG_MAXCONTACTSPERPACKET, (LPARAM)hContact);
+
+ if (!nMaxContacts) {
+ ShowErrorDlg(hwndDlg, "The selected contact does not support receiving contacts.", FALSE);
+ return FALSE;
+ }
+ // hook event - we want to receive protocol acknowledgements
+ HookProtoAck(hwndDlg);
+
+ for (int j = 0; j < nContacts / nMaxContacts; j++ )
+ { // send in packets, each of nMaxContacts contacts
+ if (!SendContactsPacket(hwndDlg, aContacts + j*nMaxContacts, nMaxContacts))
+ return FALSE;
+ }
+ if (nContacts%nMaxContacts!=0)
+ {
+ if (!SendContactsPacket(hwndDlg, aContacts + nContacts/nMaxContacts*nMaxContacts, nContacts%nMaxContacts))
+ return FALSE;
+ }
+ return TRUE;
+}
+
+
+/* Send Dialog Implementation */
+
+static void ResetListOptions(HWND hwndList)
+{
+ COLORREF bgColour,fgColour;
+
+ SendMessageT(hwndList,CLM_SETBKBITMAP,0,(LPARAM)(HBITMAP)NULL);
+ bgColour=GetSysColor(COLOR_WINDOW);
+ SendMessageT(hwndList,CLM_SETBKCOLOR,bgColour,0);
+ SendMessageT(hwndList,CLM_SETGREYOUTFLAGS,0,0);
+ SendMessageT(hwndList,CLM_SETLEFTMARGIN,4,0);
+ SendMessageT(hwndList,CLM_SETINDENT,10,0);
+ for(int i=0; i<=FONTID_MAX; i++)
+ {
+ fgColour=(COLORREF)SendMessageT(hwndList,CLM_GETTEXTCOLOR,i,0);
+ if(abs(GetRValue(fgColour)-GetRValue(bgColour))<10 &&
+ abs(GetGValue(fgColour)-GetGValue(bgColour))<10 &&
+ abs(GetBValue(fgColour)-GetBValue(bgColour))<10)
+ SendMessageT(hwndList,CLM_SETTEXTCOLOR,i,GetSysColor(COLOR_WINDOWTEXT));
+ }
+}
+
+
+static HANDLE FindNextClistContact(HWND hList, HANDLE hContact, HANDLE *phItem)
+{
+ HANDLE hNextContact = SRCFindNextContact(hContact);
+ HANDLE hNextItem = NULL;
+
+ while (hNextContact && !(hNextItem = (HANDLE)SendMessageT(hList, CLM_FINDCONTACT, (WPARAM)hNextContact,0)))
+ hNextContact = SRCFindNextContact(hNextContact);
+
+ if (phItem)
+ *phItem = hNextItem;
+
+ return hNextContact;
+}
+
+
+static HANDLE FindFirstClistContact(HWND hList, HANDLE *phItem)
+{
+ HANDLE hContact = SRCFindFirstContact();
+ HANDLE hItem = (HANDLE)SendMessageT(hList, CLM_FINDCONTACT, (WPARAM)hContact, 0);
+
+ if (hContact && !hItem)
+ return FindNextClistContact(hList, hContact, phItem);
+
+ if (phItem)
+ *phItem = hItem;
+
+ return hContact;
+}
+
+
+bool binListEvent = FALSE;
+
+static void SetAllContactChecks(HWND hwndList, HANDLE hReceiver) // doubtful name
+{
+ HANDLE hContact, hItem;
+
+ if (binListEvent) return;
+ binListEvent = TRUE;
+ char* szProto = GetContactProto(hReceiver);
+ if (szProto == NULL) return;
+
+ if (CallService(MS_CLUI_GETCAPS, 0, 0) & CLUIF_HIDEEMPTYGROUPS && DBGetContactSettingByte(NULL, "CList", "HideEmptyGroups", SETTING_USEGROUPS_DEFAULT))
+ SendMessageT(hwndList, CLM_SETHIDEEMPTYGROUPS, (WPARAM) TRUE, 0);
+ else
+ SendMessageT(hwndList, CLM_SETHIDEEMPTYGROUPS, (WPARAM) FALSE, 0);
+
+ hContact = FindFirstClistContact(hwndList, &hItem);
+ while (hContact)
+ {
+ char* szProto2 = GetContactProto(hContact);
+
+ if (strcmpnull(szProto, szProto2))
+ { // different protocols or protocol undefined, remove contact, useless anyway
+ SendMessageT(hwndList, CLM_DELETEITEM, (WPARAM)hItem, 0);
+ }
+ else // otherwise uncheck
+ SendMessageT(hwndList, CLM_SETCHECKMARK,(WPARAM)hItem, 0);
+
+ hContact = FindNextClistContact(hwndList, hContact, &hItem);
+ }
+
+ binListEvent = FALSE;
+}
+
+
+INT_PTR CALLBACK SendDlgProc( HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ TSendContactsData* wndData = (TSendContactsData*)GetWindowLong(hwndDlg, DWLP_USER);
+
+ switch (msg)
+ {
+ case WM_INITDIALOG:
+ {
+ TranslateDialogDefault(hwndDlg);
+ SendMessageT(hwndDlg, WM_SETICON, ICON_SMALL, (LPARAM)LoadIcon(hInst, MAKEINTRESOURCE(IDI_CONTACTS)));
+ ResetListOptions(GetDlgItem(hwndDlg,IDC_LIST));
+ SetAllContactChecks(GetDlgItem(hwndDlg,IDC_LIST), (HANDLE)lParam);
+ WindowList_Add(ghSendWindowList, hwndDlg, (HANDLE)lParam);
+ wndData = new TSendContactsData((HANDLE)lParam);
+ SetWindowLong(hwndDlg, DWLP_USER, (LONG)wndData);
+ // new dlg init
+ wndData->hIcons[0] = InitMButton(hwndDlg, IDC_ADD, MAKEINTRESOURCEA(IDI_ADDCONTACT), "Add Contact Permanently to List");
+ wndData->hIcons[1] = InitMButton(hwndDlg, IDC_DETAILS, MAKEINTRESOURCEA(IDI_USERDETAILS), "View User's Details");
+ wndData->hIcons[2] = InitMButton(hwndDlg, IDC_HISTORY, MAKEINTRESOURCEA(IDI_HISTORY), "View User's History");
+ wndData->hIcons[3] = InitMButton(hwndDlg, IDC_USERMENU, MAKEINTRESOURCEA(IDI_DOWNARROW), "User Menu");
+
+ SendMessageT(hwndDlg,DM_UPDATETITLE,0,0);
+ // new dialog init done
+ return TRUE;
+ }
+
+ case WM_SETFOCUS:
+ SetFocus(GetDlgItem(hwndDlg,IDC_LIST));
+ break;
+
+ case WM_NOTIFY:
+ if (((LPNMHDR)lParam)->idFrom == IDC_LIST)
+ {
+ switch (((LPNMHDR)lParam)->code)
+ {
+ case CLN_NEWCONTACT:
+ case CLN_LISTREBUILT: // rebuild list
+ if (wndData) SetAllContactChecks(GetDlgItem(hwndDlg,IDC_LIST), wndData->hContact);
+ case CLN_OPTIONSCHANGED:
+ ResetListOptions(GetDlgItem(hwndDlg,IDC_LIST));
+ break;
+ }
+ }
+ break;
+
+ case WM_TIMER:
+ if (wParam == TIMERID_MSGSEND)
+ {
+ if (!g_SendAckSupported)
+ { // old Miranda has this ack unimplemented, we need to send it by ourselves
+ ACKDATA ack = {0};
+
+ ack.cbSize = sizeof(ACKDATA);
+ ack.type = ACKTYPE_CONTACTS;
+ ack.result = ACKRESULT_SUCCESS;
+ ack.hContact = wndData->hContact;
+ while (wndData->uacklist.Count)
+ { // the uack gets empty after processing all messages :)
+ ack.hProcess = wndData->uacklist.Items[0];
+ SendMessageT(hwndDlg, HM_EVENTSENT, NULL, (WPARAM)&ack); // this removes the ack from our array
+ }
+ break;
+ }
+ KillTimer(hwndDlg,wParam);
+ wndData->ShowErrorDlg(hwndDlg, "The contacts send timed out.", TRUE);
+ }
+ break;
+
+ case DM_ERRORDECIDED:
+ {
+ EnableWindow(hwndDlg,TRUE);
+ wndData->hError = NULL;
+ switch(wParam)
+ {
+ case MSGERROR_CANCEL:
+ {
+ wndData->UnhookProtoAck();
+ if (wndData->uacklist.Count)
+ {
+ for (int i=0; i<wndData->uacklist.Count; i++)
+ {
+ delete gaAckData.Remove(wndData->uacklist.Items[i]); // remove our ackdata & release structure
+ }
+ SAFE_FREE((void**)&wndData->uacklist.Items);
+ wndData->uacklist.Count = 0;
+ }
+ EnableDlgItem(hwndDlg,IDOK,TRUE);
+ EnableDlgItem(hwndDlg,IDC_LIST,TRUE);
+ ShowWindow(hwndDlg,SW_SHOWNORMAL);
+ SetFocus(GetDlgItem(hwndDlg,IDC_LIST));
+ break;
+ }
+ case MSGERROR_DONE:
+ // contacts were delivered succesfully after timeout
+ SetFocus(GetDlgItem(hwndDlg,IDC_LIST));
+ wndData->UnhookProtoAck();
+ break;
+
+ case MSGERROR_RETRY:// resend timeouted packets
+
+ for (int i=0; i<wndData->uacklist.Count; i++)
+ {
+ TAckData* lla = gaAckData.Remove(wndData->uacklist.Items[i]);
+ HANDLE hProcc = (HANDLE)SRCCallContactService(wndData->hContact, PSS_CONTACTS, MAKEWPARAM(0, lla->nContacts), (LPARAM)lla->aContacts);
+
+ if (!hProcc) // if fatal do not include
+ {
+ wndData->uacklist.Remove(wndData->uacklist.Items[i]);
+ delete lla; // release the structure
+ continue;
+ }
+ else
+ { // update process code
+ wndData->uacklist.Items[i] = hProcc;
+ gaAckData.Add(hProcc, lla);
+ }
+ }// collect TAckData for our window, resend
+ break;
+ }
+ break;
+ }
+
+ case WM_COMMAND:
+ {
+ if(!lParam && CallService(MS_CLIST_MENUPROCESSCOMMAND,MAKEWPARAM(LOWORD(wParam), MPCF_CONTACTMENU), (LPARAM)wndData->hContact))
+ break;
+
+ switch(LOWORD(wParam))
+ {
+ case IDOK:
+ {
+ if (!IsWindowEnabled(GetDlgItem(hwndDlg,IDOK))) break;
+ HANDLE hContact, hItem;
+ wndData->ClearContacts(); // do not include contacts twice
+
+ HWND hList = GetDlgItem(hwndDlg, IDC_LIST);
+ hContact = FindFirstClistContact(hList, &hItem);
+ while (hContact)
+ {
+ if (SendMessageT(hList, CLM_GETCHECKMARK, (WPARAM)hItem, 0))
+ { // build list of contacts to send
+ wndData->AddContact(hContact);
+ }
+ hContact = FindNextClistContact(hList, hContact, &hItem);
+ }
+ /* send contacts */
+ if (!wndData->SendContacts(hwndDlg))
+ break;
+
+ if (g_SendAckSupported)
+ SetTimer(hwndDlg,TIMERID_MSGSEND,DBGetContactSettingDword(NULL,"SRMsg","MessageTimeout",TIMEOUT_MSGSEND),NULL);
+ else
+ SetTimer(hwndDlg,TIMERID_MSGSEND,1000,NULL); // wait one second - if no error occures
+
+ break;
+ }
+ case IDCANCEL:
+ {
+ DestroyWindow(hwndDlg);
+ break;
+ }
+ case ID_SELECTALL:
+ { // select all contacts
+ HANDLE hContact, hItem;
+ HWND hwndList = GetDlgItem(hwndDlg, IDC_LIST);
+
+ hContact = FindFirstClistContact(hwndList, &hItem);
+ while (hContact) {
+ SendMessageT(hwndList,CLM_SETCHECKMARK,(WPARAM)hItem, 1);
+ hContact = FindNextClistContact(hwndList, hContact, &hItem);
+ };
+ break;
+ }
+ case IDC_USERMENU:
+ {
+ RECT rc;
+ HMENU hMenu = (HMENU)CallService(MS_CLIST_MENUBUILDCONTACT,(WPARAM)wndData->hContact,0);
+
+ GetWindowRect(GetDlgItem(hwndDlg,IDC_USERMENU),&rc);
+ TrackPopupMenu(hMenu,0,rc.left,rc.bottom,0,hwndDlg,NULL);
+ DestroyMenu(hMenu);
+ break;
+ }
+ case IDC_HISTORY:
+ CallService(MS_HISTORY_SHOWCONTACTHISTORY,(WPARAM)wndData->hContact,0);
+ break;
+
+ case IDC_DETAILS:
+ CallService(MS_USERINFO_SHOWDIALOG,(WPARAM)wndData->hContact,0);
+ break;
+
+ case IDC_ADD:
+ DialogAddContactExecute(hwndDlg, wndData->hContact);
+ break;
+ }
+ break;
+ }
+ case HM_EVENTSENT:
+ {
+ ACKDATA *ack=(ACKDATA*)lParam;
+ DBEVENTINFO dbei={0};
+
+ if (ack->type != ACKTYPE_CONTACTS) break;
+
+ TAckData* ackData = gaAckData.Get(ack->hProcess);
+
+ if (ackData == NULL) break; // on unknown hprocc go away
+
+ if (ackData->hContact != ack->hContact) break; // this is not ours, strange
+
+ if (ack->result == ACKRESULT_FAILED)
+ { // some process failed, show error dialog
+ KillTimer(hwndDlg, TIMERID_MSGSEND);
+ wndData->ShowErrorDlg(hwndDlg, (char *)ack->lParam, TRUE);
+ // ackData get used in error handling, released there
+ break;
+ }
+
+ dbei.cbSize = sizeof(dbei);
+ dbei.szModule = GetContactProto(ackData->hContact);
+ dbei.eventType = EVENTTYPE_CONTACTS;
+ dbei.flags = DBEF_SENT;
+ if (g_UnicodeCore && g_Utf8EventsSupported)
+ dbei.flags |= DBEF_UTF;
+ dbei.timestamp = time(NULL);
+ //make blob
+ TCTSend* maSend = (TCTSend*)_alloca(ackData->nContacts*sizeof(TCTSend));
+ ZeroMemory(maSend, ackData->nContacts*sizeof(TCTSend));
+ dbei.cbBlob=0;
+ char* pBlob;
+ int i;
+ for (i=0; i<ackData->nContacts; i++)
+ { // prepare data & count size
+ if (g_UnicodeCore && g_Utf8EventsSupported)
+ maSend[i].mcaNick = make_utf8_string((WCHAR*)GetContactDisplayNameT(ackData->aContacts[i]));
+ else
+ maSend[i].mcaNick = (unsigned char*)null_strdup((char*)CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)ackData->aContacts[i], 0));
+ maSend[i].mcaUIN = GetContactUID(ackData->aContacts[i], FALSE);
+ dbei.cbBlob += (DWORD)strlennull(maSend[i].mcaUIN) + (DWORD)strlennull((char*)maSend[i].mcaNick) + 2;
+ }
+ dbei.pBlob = (PBYTE)_alloca(dbei.cbBlob);
+ for (i=0, pBlob=(char*)dbei.pBlob; i < ackData->nContacts; i++)
+ {
+ strcpy(pBlob, (char*)maSend[i].mcaNick);
+ pBlob += strlennull(pBlob) + 1;
+ strcpy(pBlob, maSend[i].mcaUIN);
+ pBlob += strlennull(pBlob) + 1;
+ }
+ CallService(MS_DB_EVENT_ADD, (WPARAM)ackData->hContact,(LPARAM)&dbei);
+ gaAckData.Remove(ack->hProcess); // do not release here, still needed
+ wndData->uacklist.Remove(ack->hProcess); // packet confirmed
+ for (i=0; i<ackData->nContacts; i++)
+ {
+ SAFE_FREE((void**)&maSend[i].mcaUIN);
+ SAFE_FREE((void**)&maSend[i].mcaNick);
+ }
+ delete ackData; // all done, release structure
+ if (!wndData->uacklist.Count)
+ {
+ SkinPlaySound("SentContacts");
+ KillTimer(hwndDlg, TIMERID_MSGSEND);
+
+ if (wndData->hError)
+ SendMessageT(wndData->hError, DM_ERRORDECIDED, MSGERROR_DONE, 0);
+
+ SendMessageT(hwndDlg, WM_CLOSE, 0, 0); // all packets confirmed, close the dialog
+ }
+ break;
+ }
+
+ case WM_CLOSE:
+ {
+ wndData->UnhookProtoAck();
+ DestroyWindow(hwndDlg);
+ break;
+ }
+ case WM_DESTROY:
+ {
+ int i;
+ for (i = 0; i < SIZEOF(wndData->hIcons); i++)
+ DestroyIcon(wndData->hIcons[i]);
+ WindowList_Remove(ghSendWindowList, hwndDlg);
+ delete wndData;
+ break;
+ }
+ case WM_MEASUREITEM:
+ return CallService(MS_CLIST_MENUMEASUREITEM,wParam,lParam);
+
+ case WM_DRAWITEM:
+ {
+ DrawProtocolIcon(hwndDlg, lParam, wndData->hContact);
+ return CallService(MS_CLIST_MENUDRAWITEM,wParam,lParam);
+ }
+ case DM_UPDATETITLE:
+ {
+ UpdateDialogTitle(hwndDlg, wndData?wndData->hContact:NULL, "Send Contacts to");
+ if (wndData)
+ UpdateDialogAddButton(hwndDlg, wndData->hContact);
+ break;
+ }
+ }
+
+ return FALSE;
+}
+
+
+// Error Dialog
+
+INT_PTR CALLBACK ErrorDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ switch(msg)
+ {
+ case WM_INITDIALOG:
+ {
+ RECT rc, rcParent;
+
+ TranslateDialogDefault(hwndDlg);
+
+ if (lParam)
+ {
+ WCHAR tmp[MAX_PATH];
+
+ SetDlgItemTextT(hwndDlg, IDC_ERRORTEXT, SRCTranslateT((char*)lParam, tmp));
+ }
+ GetWindowRect(hwndDlg, &rc);
+ GetWindowRect(GetParent(hwndDlg), &rcParent);
+ SetWindowPos(hwndDlg, 0,
+ (rcParent.left+rcParent.right-(rc.right-rc.left))/2,
+ (rcParent.top+rcParent.bottom-(rc.bottom-rc.top))/2,
+ 0, 0, SWP_NOZORDER|SWP_NOSIZE);
+ }
+ return TRUE;
+
+ case WM_COMMAND:
+ switch(LOWORD(wParam))
+ {
+ case IDOK:
+ SendMessageT(GetParent(hwndDlg), DM_ERRORDECIDED, MSGERROR_RETRY, 0);
+ DestroyWindow(hwndDlg);
+ break;
+
+ case IDCANCEL:
+ SendMessageT(GetParent(hwndDlg), DM_ERRORDECIDED, MSGERROR_CANCEL, 0);
+ DestroyWindow(hwndDlg);
+ break;
+ }
+ break;
+ case DM_ERRORDECIDED:
+ if (wParam!=MSGERROR_DONE) break;
+ SendMessageT(GetParent(hwndDlg), DM_ERRORDECIDED, MSGERROR_DONE, 0);
+ DestroyWindow(hwndDlg);
+ break;
+ }
+
+ return FALSE;
+}
diff --git a/plugins/ContactsPlus/send.h b/plugins/ContactsPlus/send.h
new file mode 100644
index 0000000000..c8580a4eb1
--- /dev/null
+++ b/plugins/ContactsPlus/send.h
@@ -0,0 +1,110 @@
+// ---------------------------------------------------------------------------
+// Contacts+ for Miranda Instant Messenger
+// _______________________________________
+//
+// Copyright © 2002 Dominus Procellarum
+// Copyright © 2004-2008 Joe Kucera
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// ---------------------------------------------------------------------------
+
+#ifndef __SEND_H
+#define __SEND_H
+
+
+#define TIMERID_MSGSEND 1024
+#define TIMEOUT_MSGSEND 9000 //ms
+#define HM_EVENTSENT (WM_USER+10)
+#define DM_ERRORDECIDED (WM_USER+18)
+#define DM_UPDATETITLE (WM_USER+11)
+#define MSGERROR_CANCEL 0
+#define MSGERROR_RETRY 1
+#define MSGERROR_DONE 2
+
+#define IDI_ADDCONTACT 210
+#define IDI_USERDETAILS 160
+#define IDI_HISTORY 174
+#define IDI_DOWNARROW 264
+
+struct TSendProcessList {
+ int Count;
+ HANDLE* Items;
+ CRITICAL_SECTION lock;
+ void Add(HANDLE hProcc);
+ void Remove(HANDLE hProcc);
+ TSendProcessList();
+ ~TSendProcessList();
+};
+
+struct TSendContactsData { // hope uack is released automaticly, static property
+ HANDLE hHook; // hook to event
+ void HookProtoAck(HWND hwndDlg);
+ void UnhookProtoAck();
+ HANDLE* aContacts; // contacts to be sent
+ int nContacts; // now many UIDs shall we send?
+ void ClearContacts();
+ void AddContact(HANDLE hContact);
+ HANDLE hContact; // to whom shall we send?
+ TSendProcessList uacklist;// ackdata - necessary for errorbox
+ HWND hError; // handle of error box, if any
+ void ShowErrorDlg(HWND hwndDlg, char* szMsg, bool bAllowRetry);
+ int SendContactsPacket(HWND hwndDlg, HANDLE *phContacts, int nContacts);
+ int SendContacts(HWND hwndDlg);
+ HICON hIcons[4]; // icons for dialog
+ TSendContactsData(HANDLE contact);
+ ~TSendContactsData();
+};
+
+struct TAckData {
+ HANDLE hContact; // to whom was it sent
+ HANDLE* aContacts; // obj
+ int nContacts; // how many
+ TAckData(HANDLE contact) { hContact = contact; aContacts = NULL; nContacts = 0;};
+ ~TAckData() { if (nContacts) SAFE_FREE((void**)&aContacts); }
+};
+
+typedef TAckData* PAckData;
+
+struct TCTSend {
+ char* mcaUIN;
+ unsigned char* mcaNick;
+};
+
+struct gAckItem { // some shit here
+ HANDLE hProcc;
+ PAckData ackData;
+ gAckItem(HANDLE procC, PAckData aData) { ackData=aData; hProcc=procC; };
+ ~gAckItem() { /*delete ackData;*/ };
+};
+
+struct gAckList {
+ gAckItem** Items;
+ int Count;
+ TAckData* Get(HANDLE hProcc) { for (int i=0; i<Count; i++) if (Items[i]->hProcc==hProcc) { return Items[i]->ackData; }; return NULL; };
+ TAckData* Add(HANDLE hProcc, TAckData* ackData) { Items=(gAckItem**)realloc(Items, (Count+1)*sizeof(gAckItem*)); Items[Count]=new gAckItem(hProcc, ackData); Count++; return ackData; };
+ TAckData* Remove(HANDLE hProcc) { for (int i=0; i<Count; i++) if (Items[i]->hProcc==hProcc) { TAckData* data=Items[i]->ackData; delete Items[i]; memmove(Items+i, Items+i+1, (Count-i-1)*sizeof(gAckItem*)); Count--; return data; }; return NULL; };
+ gAckList() { Count = 0; Items = NULL; }
+ ~gAckList() { if (Count) { for (int i=0; i<Count; i++) delete Items[i]; SAFE_FREE((void**)&Items); }; }
+};
+
+extern HANDLE ghSendWindowList;
+extern gAckList gaAckData;
+
+INT_PTR CALLBACK SendDlgProc( HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
+INT_PTR CALLBACK ErrorDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam);
+
+
+#endif /* __SEND_H */ \ No newline at end of file
diff --git a/plugins/ContactsPlus/utils.cpp b/plugins/ContactsPlus/utils.cpp
new file mode 100644
index 0000000000..a86cdff85f
--- /dev/null
+++ b/plugins/ContactsPlus/utils.cpp
@@ -0,0 +1,876 @@
+// ---------------------------------------------------------------------------
+// Contacts+ for Miranda Instant Messenger
+// _______________________________________
+//
+// Copyright © 2002 Dominus Procellarum
+// Copyright © 2004-2008 Joe Kucera
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// ---------------------------------------------------------------------------
+
+#include "contacts.h"
+
+
+int SRCCallProtoService(const char *szModule, const char *szService, WPARAM wParam, LPARAM lParam)
+{
+ if (!g_NewProtoAPI)
+ {
+ char str[MAXMODULELABELLENGTH];
+ strcpy(str,szModule);
+ strcat(str,szService);
+ return CallService(str,wParam,lParam);
+ }
+ else // this will call pluginLink.CallProtoService (only 0.8.0.8+)
+ return CallProtoService(szModule, szService, wParam, lParam);
+}
+
+
+int SRCCallContactService(HANDLE hContact, const char *szProtoService, WPARAM wParam, LPARAM lParam)
+{
+ if (!g_NewProtoAPI)
+ {
+ CCSDATA ccs;
+ ccs.hContact=hContact;
+ ccs.szProtoService=szProtoService;
+ ccs.wParam=wParam;
+ ccs.lParam=lParam;
+ return CallService(MS_PROTO_CALLCONTACTSERVICE,0,(LPARAM)&ccs);
+ }
+ else // this will call pluginLink.CallContactService (only 0.8.0.8+)
+ return CallContactService(hContact, szProtoService, wParam, lParam);
+}
+
+
+int utf8_decode(const unsigned char *from, char **to);
+
+
+/* a strlennull() that likes NULL */
+size_t __fastcall strlennull(const char *string)
+{
+ if (string)
+ return strlen(string);
+
+ return 0;
+}
+
+
+int __fastcall strcmpnull(const char *str1, const char *str2)
+{
+ if (!str1 || !str2) return 1;
+
+ return strcmp(str1, str2);
+}
+
+
+char* __fastcall null_strdup(const char *string)
+{
+ if (string)
+ return strdup(string);
+
+ return NULL;
+}
+
+
+void __fastcall SAFE_FREE(void** p)
+{
+ if (*p)
+ {
+ free(*p);
+ *p = NULL;
+ }
+}
+
+
+char *GetContactProto(HANDLE hContact)
+{
+ return (char*)CallService(MS_PROTO_GETCONTACTBASEPROTO,(WPARAM)hContact,0);
+}
+
+
+TCHAR *GetContactDisplayNameT(HANDLE hContact)
+{
+ return (TCHAR*)CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)hContact, g_UnicodeCore ? GCDNF_UNICODE : 0);
+}
+
+
+char *GetContactUID(HANDLE hContact, int bTchar)
+{
+ DBVARIANT vrUid;
+ char *szUid = NULL;
+
+ char *szProto = GetContactProto(hContact);
+ char *uid = (char*)SRCCallProtoService(szProto, PS_GETCAPS, PFLAG_UNIQUEIDSETTING, 0); // v0.3+ only
+
+ if (((int)uid != CALLSERVICE_NOTFOUND) && uid)
+ { // it worked, yeah :)
+ if (!DBGetContactSettingT(hContact, szProto, uid, &vrUid))
+ {
+ if (vrUid.type == DBVT_DWORD)
+ {
+ szUid = (char*)_alloca(17);
+ szUid[0] = 0; // empty string
+ _itoa(vrUid.dVal, szUid, 10);
+ }
+ else if (vrUid.type == DBVT_ASCIIZ)
+ {
+ szUid = (char*)_alloca(strlennull(vrUid.pszVal) + 1);
+ strcpy(szUid, vrUid.pszVal);
+ }
+ else if (vrUid.type == DBVT_UTF8)
+ { // yeah, jabber gives this!
+ char *szAnsi = NULL;
+
+ if (utf8_decode((unsigned char*)vrUid.pszVal, &szAnsi))
+ {
+ szUid = (char*)_alloca(strlennull(szAnsi) + 1);
+ strcpy(szUid, szAnsi);
+ SAFE_FREE((void**)&szAnsi);
+ }
+ }
+ DBFreeVariant(&vrUid);
+ }
+ }
+ if (bTchar)
+ return ansi_to_tchar(szUid);
+ else
+ return null_strdup(szUid);
+}
+
+
+TCHAR* MirandaStatusToStringT(int mirandaStatus)
+{
+ return (TCHAR *)CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, mirandaStatus, g_UnicodeCore ? GSMDF_UNICODE : 0);
+}
+
+HANDLE __fastcall SRCFindFirstContact()
+{
+ return (HANDLE)CallService(MS_DB_CONTACT_FINDFIRST, 0, 0);
+}
+
+HANDLE __fastcall SRCFindNextContact(HANDLE hContact)
+{
+ return (HANDLE)CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM)hContact, 0);
+}
+
+int DBGetContactSettingT(HANDLE hContact, const char *szModule, const char* szSetting, DBVARIANT *dbv)
+{
+ if (ServiceExists(MS_DB_CONTACT_GETSETTING_STR))
+ return DBGetContactSettingW(hContact, szModule, szSetting, dbv);
+ else
+ return DBGetContactSetting(hContact, szModule, szSetting, dbv);
+}
+
+
+TCHAR* DBGetContactSettingStringT(HANDLE hContact, const char *szModule, const char* szSetting, TCHAR* szDef)
+{
+ DBVARIANT dbv = {DBVT_DELETED};
+ TCHAR* szRes;
+
+ if (g_UnicodeCore)
+ {
+ if (DBGetContactSettingWString(hContact, szModule, szSetting, &dbv))
+ return strdupT(szDef);
+
+ szRes = strdupT(dbv.ptszVal);
+ DBFreeVariant(&dbv);
+ }
+ else
+ {
+ if (DBGetContactSettingT(hContact, szModule, szSetting, &dbv))
+ return strdupT(szDef);
+
+ if (dbv.type == DBVT_ASCIIZ)
+ szRes = ansi_to_tchar(dbv.pszVal);
+ else if (dbv.type == DBVT_UTF8)
+ szRes = utf8_to_tchar((unsigned char*)dbv.pszVal);
+ else
+ szRes = strdupT(szDef);
+ DBFreeVariant(&dbv);
+ }
+ return szRes;
+}
+
+int DBWriteContactSettingStringT(HANDLE hContact, const char *szModule, const char* szSetting, TCHAR* szValue)
+{
+ if (g_UnicodeCore)
+ return DBWriteContactSettingWString(hContact, szModule, szSetting, (WCHAR*)szValue);
+ else
+ return DBWriteContactSettingString(hContact, szModule, szSetting, (char*)szValue);
+}
+
+
+
+int __fastcall SRCTranslateDialog(HWND hwndDlg)
+{
+ LANGPACKTRANSLATEDIALOG lptd;
+
+ lptd.cbSize=sizeof(lptd);
+ lptd.flags=0;
+ lptd.hwndDlg=hwndDlg;
+ lptd.ignoreControls=NULL;
+ return CallService(MS_LANGPACK_TRANSLATEDIALOG,0,(LPARAM)&lptd);
+}
+
+
+void DialogAddContactExecute(HWND hwndDlg, HANDLE hNewContact)
+{
+ ADDCONTACTSTRUCT acs={0};
+
+ acs.handle = hNewContact;
+ acs.handleType = HANDLE_CONTACT;
+
+ CallService(MS_ADDCONTACT_SHOW, (WPARAM)hwndDlg, (LPARAM)&acs);
+}
+
+
+void DrawProtocolIcon(HWND hwndDlg, LPARAM lParam, HANDLE hContact)
+{
+ LPDRAWITEMSTRUCT dis=(LPDRAWITEMSTRUCT)lParam;
+
+ if (dis->hwndItem==GetDlgItem(hwndDlg, IDC_PROTOCOL))
+ {
+ HICON hIcon = LoadContactProtoIcon(hContact);
+ if (hIcon)
+ {
+ DrawIconEx(dis->hDC,dis->rcItem.left,dis->rcItem.top,hIcon,GetSystemMetrics(SM_CXSMICON),GetSystemMetrics(SM_CYSMICON),0,NULL,DI_NORMAL);
+ DestroyIcon(hIcon);
+ }
+ }
+}
+
+
+void UpdateDialogTitle(HWND hwndDlg, HANDLE hContact, char* pszTitleStart)
+{
+ TCHAR newtitle[512];
+ WCHAR str[MAX_PATH];
+ TCHAR *oldTitle;
+ TCHAR *szStatus;
+ char *szProto;
+
+ if (hContact)
+ {
+ szProto = GetContactProto(hContact);
+ if (szProto)
+ {
+ TCHAR *uid = GetContactUID(hContact, TRUE);
+ TCHAR *contactName = GetContactDisplayNameT(hContact);
+
+ oldTitle = GetDlgItemTextT(hwndDlg, IDC_NAME);
+
+ if (strcmpT(uid?uid:contactName, oldTitle))
+ SetDlgItemTextT(hwndDlg, IDC_NAME, uid?uid:contactName);
+
+ szStatus = MirandaStatusToStringT(szProto==NULL ? ID_STATUS_OFFLINE:DBGetContactSettingWord(hContact,szProto,"Status",ID_STATUS_OFFLINE));
+ _snprintfT(newtitle, 256, "%s %s (%s)", SRCTranslateT(pszTitleStart, str), contactName, szStatus);
+
+ SAFE_FREE((void**)&uid);
+ SAFE_FREE((void**)&oldTitle);
+ }
+ else
+ strncpyT(newtitle, SRCTranslateT(pszTitleStart, str), 256);
+ }
+ else
+ strncpyT(newtitle, SRCTranslateT(pszTitleStart, str), 256);
+
+ oldTitle = GetWindowTextT(hwndDlg);
+
+ if (strcmpT(newtitle, oldTitle))
+ SetWindowTextT(hwndDlg, newtitle);
+
+ SAFE_FREE((void**)&oldTitle);
+}
+
+
+void UpdateDialogAddButton(HWND hwndDlg, HANDLE hContact)
+{
+ int bVisible = DBGetContactSettingByte(hContact,"CList","NotOnList",0);
+
+ ShowWindow(GetDlgItem(hwndDlg, IDC_ADD), bVisible?SW_SHOW:SW_HIDE);
+}
+
+
+HICON InitMButton(HWND hDlg, int idButton, LPCSTR szIcon, char* szTip)
+{
+ HWND hButton = GetDlgItem(hDlg, idButton);
+ HICON hIcon = (HICON)LoadImage(GetModuleHandle(NULL),szIcon,IMAGE_ICON,GetSystemMetrics(SM_CXSMICON),GetSystemMetrics(SM_CYSMICON),0);
+
+ SendMessageT(hButton, BM_SETIMAGE, IMAGE_ICON, (LPARAM)hIcon);
+ SendMessageT(hButton, BUTTONSETASFLATBTN, 0, 0);
+ SendMessageT(hButton, BUTTONADDTOOLTIP, (WPARAM)Translate(szTip), 0);
+
+ return hIcon;
+}
+
+
+HICON LoadContactProtoIcon(HANDLE hContact)
+{
+ char* szProto = GetContactProto(hContact);
+ if (szProto)
+ return (HICON)SRCCallProtoService(szProto, PS_LOADICON, PLI_PROTOCOL|PLIF_SMALL, 0);
+ return NULL;
+}
+
+
+void EnableDlgItem(HWND hwndDlg, UINT control, int state)
+{
+ EnableWindow(GetDlgItem(hwndDlg, control), state);
+}
+
+
+LRESULT SendMessageT(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
+{
+ if (g_UnicodeCore)
+ return SendMessageW(hWnd, Msg, wParam, lParam);
+ else
+ return SendMessageA(hWnd, Msg, wParam, lParam);
+}
+
+TCHAR* GetWindowTextT(HWND hWnd)
+{
+ if (g_UnicodeCore)
+ {
+ int len = GetWindowTextLengthW(hWnd) + 1;
+ WCHAR* txt = (WCHAR*)malloc(len * sizeof(WCHAR));
+ if (txt) {
+ txt[0] = 0;
+ GetWindowTextW(hWnd, txt, len);
+ }
+ return (TCHAR*)txt;
+ }
+ else
+ {
+ int len = GetWindowTextLengthA(hWnd) + 1;
+ char* txt = (char*)malloc(len * sizeof(char));
+ if (txt) {
+ txt[0] = 0;
+ GetWindowTextA(hWnd, txt, len);
+ }
+ return (TCHAR*)txt;
+ }
+}
+
+BOOL SetWindowTextT(HWND hWnd, TCHAR* lpString)
+{
+ if (g_UnicodeCore)
+ return SetWindowTextW(hWnd, (WCHAR*)lpString);
+ else
+ return SetWindowTextA(hWnd, lpString);
+}
+
+TCHAR* GetDlgItemTextT(HWND hDlg, int nIDDlgItem)
+{
+ return GetWindowTextT(GetDlgItem(hDlg, nIDDlgItem));
+}
+
+BOOL SetDlgItemTextT(HWND hDlg, int nIDDlgItem, TCHAR* lpString)
+{
+ return SetWindowTextT(GetDlgItem(hDlg, nIDDlgItem), lpString);
+}
+
+HWND CreateDialogParamT(HINSTANCE hInstance, const char* szTemplate, HWND hWndParent, DLGPROC lpDialogFunc, LPARAM dwInitParam)
+{
+ if (g_UnicodeCore)
+ return CreateDialogParamW(hInstance, (LPCWSTR)szTemplate, hWndParent, lpDialogFunc, dwInitParam);
+ else
+ return CreateDialogParamA(hInstance, szTemplate, hWndParent, lpDialogFunc, dwInitParam);
+}
+
+int ListView_InsertColumnT(HWND hwnd, int iCol, const LPLVCOLUMN pcol)
+{
+ return SendMessageT(hwnd, g_UnicodeCore ? LVM_INSERTCOLUMNW : LVM_INSERTCOLUMNA, (WPARAM)iCol, (LPARAM)pcol);
+}
+
+void ListView_SetItemTextT(HWND hwnd, int i, int iSubItem, TCHAR* pszText)
+{
+ LV_ITEM lvi = {0};
+
+ lvi.iSubItem = iSubItem;
+ lvi.pszText = pszText;
+ SendMessageT(hwnd, g_UnicodeCore ? LVM_SETITEMTEXTW : LVM_SETITEMTEXTA, (WPARAM)i, (LPARAM)&lvi);
+}
+
+
+
+size_t __fastcall strlenT(const TCHAR *string)
+{
+ if (string)
+ {
+ if (g_UnicodeCore)
+ return wcslen((WCHAR*)string);
+ else
+ return strlen((char*)string);
+ }
+ return 0;
+}
+
+TCHAR* __fastcall strdupT(const TCHAR *string)
+{
+ if (string)
+ {
+ if (g_UnicodeCore)
+ return (TCHAR*)wcsdup((WCHAR*)string);
+ else
+ return (TCHAR*)strdup((char*)string);
+ }
+ return NULL;
+}
+
+int __fastcall strcmpT(const TCHAR *string1, const TCHAR *string2)
+{
+ if (!string1 || !string2) return 1;
+
+ if (g_UnicodeCore)
+ return wcscmp((WCHAR*)string1, (WCHAR*)string2);
+ else
+ return strcmp((char*)string1, (char*)string2);
+}
+
+TCHAR* __fastcall strcpyT(TCHAR* dest, const TCHAR* src)
+{
+ if (src)
+ {
+ if (g_UnicodeCore)
+ return (TCHAR*)wcscpy((WCHAR*)dest, (WCHAR*)src);
+ else
+ return (TCHAR*)strcpy((char*)dest, (char*)src);
+ }
+ return dest;
+}
+
+TCHAR* __fastcall strncpyT(TCHAR* dest, const TCHAR* src, size_t len)
+{
+ if (src)
+ {
+ if (g_UnicodeCore)
+ return (TCHAR*)wcsncpy((WCHAR*)dest, (WCHAR*)src, len);
+ else
+ return (TCHAR*)strncpy((char*)dest, (char*)src, len);
+ }
+ return dest;
+}
+
+TCHAR* __fastcall strcatT(TCHAR* dest, const TCHAR* src)
+{
+ if (src)
+ {
+ if (g_UnicodeCore)
+ return (TCHAR*)wcscat((WCHAR*)dest, (WCHAR*)src);
+ else
+ return (TCHAR*)strcat((char*)dest, (char*)src);
+ }
+ return dest;
+}
+
+int _snprintfT(TCHAR *buffer, size_t count, const char* fmt, ...)
+{
+ va_list va;
+ int len;
+
+ va_start(va, fmt);
+ if (g_UnicodeCore)
+ {
+ TCHAR* wfmt = ansi_to_tchar(fmt);
+
+ len = _vsnwprintf((WCHAR*)buffer, count-1, (WCHAR*)wfmt, va);
+ ((WCHAR*)buffer)[count-1] = 0;
+ SAFE_FREE((void**)&wfmt);
+ }
+ else
+ {
+ len = _vsnprintf((char*)buffer, count-1, fmt, va);
+ ((char*)buffer)[count-1] = 0;
+ }
+ va_end(va);
+ return len;
+}
+
+TCHAR* __fastcall SRCTranslateT(const char* src, const WCHAR* unibuf)
+{ // this takes Ascii strings only!!!
+ char* szRes = NULL;
+
+ if (!strlennull(src))
+ { // for the case of empty strings
+ return "";
+ }
+
+ if (g_UnicodeCore)
+ { // we give WCHAR
+ WCHAR *unicode;
+ int wchars, err;
+
+ wchars = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, src,
+ (int)strlennull(src), NULL, 0);
+
+ if (wchars == 0) return NULL; // Failure
+
+ unicode = (WCHAR*)unibuf;
+ if (!unicode)
+ unicode = (WCHAR*)malloc((wchars + 1) * sizeof(WCHAR));
+
+ unicode[wchars] = 0;
+
+ err = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, src,
+ (int)strlennull(src), unicode, wchars);
+ if (err != wchars) return NULL; // Failure
+
+ return (TCHAR*)TranslateW(unicode);
+ }
+ else
+ return (TCHAR*)Translate(src);
+}
+
+static BOOL bHasCP_UTF8 = FALSE;
+
+
+void InitI18N(void)
+{
+ CPINFO CPInfo;
+
+
+ bHasCP_UTF8 = GetCPInfo(CP_UTF8, &CPInfo);
+}
+
+
+// Scans a string encoded in UTF-8 to verify that it contains
+// only valid sequences. It will return 1 if the string contains
+// only legitimate encoding sequences; otherwise it will return 0;
+// From 'Secure Programming Cookbook', John Viega & Matt Messier, 2003
+int UTF8_IsValid(const unsigned char* pszInput)
+{
+ int nb, i;
+ const unsigned char* c = pszInput;
+
+ if (!pszInput) return 0;
+
+ for (c = pszInput; *c; c += (nb + 1))
+ {
+ if (!(*c & 0x80))
+ nb = 0;
+ else if ((*c & 0xc0) == 0x80) return 0;
+ else if ((*c & 0xe0) == 0xc0) nb = 1;
+ else if ((*c & 0xf0) == 0xe0) nb = 2;
+ else if ((*c & 0xf8) == 0xf0) nb = 3;
+ else if ((*c & 0xfc) == 0xf8) nb = 4;
+ else if ((*c & 0xfe) == 0xfc) nb = 5;
+
+ for (i = 1; i<=nb; i++) // we this forward, do not cross end of string
+ if ((*(c + i) & 0xc0) != 0x80)
+ return 0;
+ }
+
+ return 1;
+}
+
+
+/*
+ * The following UTF8 routines are
+ *
+ * Copyright (C) 2001 Peter Harris <peter.harris@hummingbird.com>
+ * Copyright (C) 2001 Edmund Grimley Evans <edmundo@rano.org>
+ *
+ * under a GPL license
+ *
+ * --------------------------------------------------------------
+ * Convert a string between UTF-8 and the locale's charset.
+ * Invalid bytes are replaced by '#', and characters that are
+ * not available in the target encoding are replaced by '?'.
+ *
+ * If the locale's charset is not set explicitly then it is
+ * obtained using nl_langinfo(CODESET), where available, the
+ * environment variable CHARSET, or assumed to be US-ASCII.
+ *
+ * Return value of conversion functions:
+ *
+ * -1 : memory allocation failed
+ * 0 : data was converted exactly
+ * 1 : valid data was converted approximately (using '?')
+ * 2 : input was invalid (but still converted, using '#')
+ * 3 : unknown encoding (but still converted, using '?')
+ */
+
+
+
+/*
+ * Convert a string between UTF-8 and the locale's charset.
+ */
+unsigned char *make_utf8_string(const wchar_t *unicode)
+{
+ int size = 0;
+ int index = 0;
+ int out_index = 0;
+ unsigned char* out;
+ unsigned short c;
+
+ if (!unicode) return NULL;
+
+ /* first calculate the size of the target string */
+ c = unicode[index++];
+ while (c)
+ {
+ if (c < 0x0080)
+ size += 1;
+ else if (c < 0x0800)
+ size += 2;
+ else
+ size += 3;
+ c = unicode[index++];
+ }
+
+ out = (unsigned char*)malloc(size + 1);
+ if (out == NULL)
+ return NULL;
+ index = 0;
+
+ c = unicode[index++];
+ while (c)
+ {
+ if (c < 0x080)
+ {
+ out[out_index++] = (unsigned char)c;
+ }
+ else if (c < 0x800)
+ {
+ out[out_index++] = 0xc0 | (c >> 6);
+ out[out_index++] = 0x80 | (c & 0x3f);
+ }
+ else
+ {
+ out[out_index++] = 0xe0 | (c >> 12);
+ out[out_index++] = 0x80 | ((c >> 6) & 0x3f);
+ out[out_index++] = 0x80 | (c & 0x3f);
+ }
+ c = unicode[index++];
+ }
+ out[out_index] = 0x00;
+
+ return out;
+}
+
+
+
+WCHAR *make_unicode_string(const unsigned char *utf8)
+{
+ int size = 0, index = 0, out_index = 0;
+ wchar_t *out;
+ unsigned char c;
+
+ if (!utf8) return NULL;
+
+ /* first calculate the size of the target string */
+ c = utf8[index++];
+ while (c)
+ {
+ if ((c & 0x80) == 0)
+ {
+ index += 0;
+ }
+ else if ((c & 0xe0) == 0xe0)
+ {
+ index += 2;
+ }
+ else
+ {
+ index += 1;
+ }
+ size += 1;
+ c = utf8[index++];
+ }
+
+ out = (wchar_t*)malloc((size + 1) * sizeof(wchar_t));
+ if (out == NULL)
+ return NULL;
+ index = 0;
+
+ c = utf8[index++];
+ while (c)
+ {
+ if((c & 0x80) == 0)
+ {
+ out[out_index++] = c;
+ }
+ else if((c & 0xe0) == 0xe0)
+ {
+ out[out_index] = (c & 0x1F) << 12;
+ c = utf8[index++];
+ out[out_index] |= (c & 0x3F) << 6;
+ c = utf8[index++];
+ out[out_index++] |= (c & 0x3F);
+ }
+ else
+ {
+ out[out_index] = (c & 0x3F) << 6;
+ c = utf8[index++];
+ out[out_index++] |= (c & 0x3F);
+ }
+ c = utf8[index++];
+ }
+ out[out_index] = 0;
+
+ return out;
+}
+
+
+// Returns 0 on error, 1 on success
+static int utf8_decode(const unsigned char *from, char **to)
+{
+ int nResult = 0;
+
+// _ASSERTE(!(*to)); // You passed a non-zero pointer, make sure it doesnt point to unfreed memory
+
+ // Validate the string
+ if (!UTF8_IsValid(from))
+ return 0;
+
+ // Use the native conversion routines when available
+ if (bHasCP_UTF8)
+ {
+ WCHAR *wszTemp = NULL;
+ int inlen = (int)strlennull((char*)from);
+
+ wszTemp = (WCHAR *)_alloca(sizeof(WCHAR) * (inlen + 1));
+
+ // Convert the UTF-8 string to UCS
+ if (MultiByteToWideChar(CP_UTF8, 0, (char*)from, -1, wszTemp, inlen + 1))
+ {
+ // Convert the UCS string to local ANSI codepage
+ *to = (char*)malloc(inlen+1);
+ if (WideCharToMultiByte(CP_ACP, 0, wszTemp, -1, *to, inlen+1, NULL, NULL))
+ {
+ nResult = 1;
+ }
+ else
+ {
+ SAFE_FREE((void**)to);
+ }
+ }
+ }
+ else
+ {
+ wchar_t *unicode;
+ int chars;
+ int err;
+
+ unicode = make_unicode_string(from);
+ if (unicode == NULL)
+ {
+// fprintf(stderr, "Out of memory processing string from UTF8 to UNICODE16\n");
+ return 0;
+ }
+
+ chars = WideCharToMultiByte(CP_ACP, WC_COMPOSITECHECK, unicode, -1, NULL, 0, NULL, NULL);
+
+ if(chars == 0)
+ {
+// fprintf(stderr, "Unicode translation error %d\n", GetLastError());
+ SAFE_FREE((void**)&unicode);
+ return 0;
+ }
+
+ *to = (char*)malloc((chars + 1)*sizeof(unsigned char));
+ if(*to == NULL)
+ {
+// fprintf(stderr, "Out of memory processing string to local charset\n");
+ SAFE_FREE((void**)&unicode);
+ return 0;
+ }
+
+ err = WideCharToMultiByte(CP_ACP, WC_COMPOSITECHECK, unicode, -1, *to, chars, NULL, NULL);
+ if (err != chars)
+ {
+// fprintf(stderr, "Unicode translation error %d\n", GetLastError());
+ SAFE_FREE((void**)&unicode);
+ SAFE_FREE((void**)to);
+ return 0;
+ }
+
+ SAFE_FREE((void**)&unicode);
+
+ nResult = 1;
+ }
+
+ return nResult;
+}
+
+
+
+TCHAR* ansi_to_tchar(const char* src, int codepage)
+{
+ if (g_UnicodeCore)
+ {
+ WCHAR *unicode;
+ int wchars, err;
+
+ wchars = MultiByteToWideChar(codepage, MB_PRECOMPOSED, src, (int)strlennull(src), NULL, 0);
+
+ if (wchars == 0) return NULL; // Failure
+
+ unicode = (WCHAR*)malloc((wchars + 1) * sizeof(WCHAR));
+ unicode[wchars] = 0;
+
+ err = MultiByteToWideChar(codepage, MB_PRECOMPOSED, src, (int)strlennull(src), unicode, wchars);
+ if (err != wchars)
+ {
+ SAFE_FREE((void**)&unicode);
+ return NULL; // Failure
+ }
+
+ return (TCHAR*)unicode;
+ }
+ else
+ return strdupT((TCHAR*)src);
+}
+
+char* tchar_to_ansi(const TCHAR* src)
+{
+ if (g_UnicodeCore)
+ {
+ char *ansi;
+ int chars;
+ int err;
+
+ chars = WideCharToMultiByte(CP_ACP, WC_COMPOSITECHECK, (WCHAR*)src, -1, NULL, 0, NULL, NULL);
+
+ if (chars == 0) return NULL; // Failure
+
+ ansi = (char*)malloc((chars + 1)*sizeof(char));
+ if (ansi == NULL) return NULL; // Failure
+
+ err = WideCharToMultiByte(CP_ACP, WC_COMPOSITECHECK, (WCHAR*)src, -1, ansi, chars, NULL, NULL);
+ if (err != chars)
+ {
+ SAFE_FREE((void**)&ansi);
+ return NULL;
+ }
+ return ansi;
+ }
+ else
+ return (char*)strdupT(src);
+}
+
+TCHAR* utf8_to_tchar(const unsigned char* utf)
+{
+ if (g_UnicodeCore)
+ return (TCHAR*)make_unicode_string(utf);
+ else
+ {
+ char* szAnsi = NULL;
+
+ if (utf8_decode(utf, &szAnsi))
+ return (TCHAR*)szAnsi;
+ else
+ return NULL; // Failure
+ }
+} \ No newline at end of file
diff --git a/plugins/ContactsPlus/utils.h b/plugins/ContactsPlus/utils.h
new file mode 100644
index 0000000000..2b9af014b7
--- /dev/null
+++ b/plugins/ContactsPlus/utils.h
@@ -0,0 +1,91 @@
+// ---------------------------------------------------------------------------
+// Contacts+ for Miranda Instant Messenger
+// _______________________________________
+//
+// Copyright © 2002 Dominus Procellarum
+// Copyright © 2004-2008 Joe Kucera
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// ---------------------------------------------------------------------------
+
+#ifndef __UTILS_H
+#define __UTILS_H
+
+
+extern HINSTANCE hInst;
+extern PLUGINLINK *pluginLink;
+
+// Compatibility functions
+int SRCCallProtoService(const char *szModule, const char *szService, WPARAM wParam, LPARAM lParam);
+int SRCCallContactService(HANDLE hContact, const char *szProtoService, WPARAM wParam, LPARAM lParam);
+
+// utils.cpp
+void __fastcall SAFE_FREE(void** p);
+size_t __fastcall strlennull(const char *string);
+int __fastcall strcmpnull(const char *str1, const char *str2);
+char* __fastcall null_strdup(const char *string);
+
+char *GetContactProto(HANDLE hContact);
+char *GetContactUID(HANDLE hContact, int bTchar);
+TCHAR *GetContactDisplayNameT(HANDLE hContact);
+TCHAR* MirandaStatusToStringT(int mirandaStatus);
+
+HANDLE __fastcall SRCFindFirstContact();
+HANDLE __fastcall SRCFindNextContact(HANDLE hContact);
+int DBGetContactSettingT(HANDLE hContact, const char *szModule, const char* szSetting, DBVARIANT *dbv);
+TCHAR* DBGetContactSettingStringT(HANDLE hContact, const char *szModule,const char* szSetting, TCHAR* szDef);
+int DBWriteContactSettingStringT(HANDLE hContact, const char *szModule, const char* szSetting, TCHAR* szValue);
+
+void DrawProtocolIcon(HWND hwndDlg, LPARAM lParam, HANDLE hContact);
+void UpdateDialogTitle(HWND hwndDlg, HANDLE hContact, char* pszTitleStart);
+void UpdateDialogAddButton(HWND hwndDlg, HANDLE hContact);
+
+HICON InitMButton(HWND hDlg, int idButton, LPCSTR szIcon, char* szTip);
+
+void DialogAddContactExecute(HWND hwndDlg, HANDLE hNewContact);
+
+HICON LoadContactProtoIcon(HANDLE hContact);
+
+void EnableDlgItem(HWND hwndDlg, UINT control, int state);
+
+/// Unicode 2 in 1 Framework
+size_t __fastcall strlenT(const TCHAR *string);
+TCHAR* __fastcall strdupT(const TCHAR *string);
+int __fastcall strcmpT(const TCHAR *string1, const TCHAR *string2);
+TCHAR* __fastcall strcpyT(TCHAR* dest, const TCHAR* src);
+TCHAR* __fastcall strncpyT(TCHAR* dest, const TCHAR* src, size_t len);
+TCHAR* __fastcall strcatT(TCHAR* dest, const TCHAR* src);
+int _snprintfT(TCHAR *buffer, size_t count, const char* fmt, ...);
+
+LRESULT SendMessageT(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
+TCHAR* GetWindowTextT(HWND hWnd);
+BOOL SetWindowTextT(HWND hWnd, TCHAR* lpString);
+TCHAR* GetDlgItemTextT(HWND hDlg, int nIDDlgItem);
+BOOL SetDlgItemTextT(HWND hDlg, int nIDDlgItem, TCHAR* lpString);
+HWND CreateDialogParamT(HINSTANCE hInstance, const char* szTemplate, HWND hWndParent, DLGPROC lpDialogFunc, LPARAM dwInitParam);
+int ListView_InsertColumnT(HWND hwnd, int iCol, const LPLVCOLUMN pcol);
+void ListView_SetItemTextT(HWND hwnd, int i, int iSubItem, TCHAR* pszText);
+
+TCHAR* __fastcall SRCTranslateT(const char* src, const WCHAR* unibuf);
+
+void InitI18N(void);
+TCHAR* ansi_to_tchar(const char* string, int codepage = CP_ACP);
+char* tchar_to_ansi(const TCHAR* src);
+TCHAR* utf8_to_tchar(const unsigned char* utf);
+unsigned char *make_utf8_string(const wchar_t *unicode);
+
+
+#endif /* __UTILS_H */ \ No newline at end of file