summaryrefslogtreecommitdiff
path: root/plugins/tipper
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/tipper')
-rw-r--r--plugins/tipper/common.h78
-rw-r--r--plugins/tipper/docs/autoexec_Tipper(Omniwolf).ini339
-rw-r--r--plugins/tipper/docs/autoexec_Tipper(Tweety).ini379
-rw-r--r--plugins/tipper/docs/licence_Tipper.txt6
-rw-r--r--plugins/tipper/docs/m_tipper.h23
-rw-r--r--plugins/tipper/docs/readme_tipper.txt144
-rw-r--r--plugins/tipper/m_metacontacts.h162
-rw-r--r--plugins/tipper/m_notify.h177
-rw-r--r--plugins/tipper/m_tipper.h19
-rw-r--r--plugins/tipper/m_trigger.h1024
-rw-r--r--plugins/tipper/m_updater.h150
-rw-r--r--plugins/tipper/m_variables.h668
-rw-r--r--plugins/tipper/message_pump.cpp217
-rw-r--r--plugins/tipper/message_pump.h44
-rw-r--r--plugins/tipper/options.cpp1190
-rw-r--r--plugins/tipper/options.h77
-rw-r--r--plugins/tipper/popwin.cpp937
-rw-r--r--plugins/tipper/popwin.h17
-rw-r--r--plugins/tipper/resource.h93
-rw-r--r--plugins/tipper/resource.rc6
-rw-r--r--plugins/tipper/str_utils.cpp102
-rw-r--r--plugins/tipper/str_utils.h34
-rw-r--r--plugins/tipper/subst.cpp450
-rw-r--r--plugins/tipper/subst.h18
-rw-r--r--plugins/tipper/tipper.cpp277
-rw-r--r--plugins/tipper/tipper.dep7
-rw-r--r--plugins/tipper/tipper.dsp245
-rw-r--r--plugins/tipper/tipper.dsw33
-rw-r--r--plugins/tipper/tipper.h12
-rw-r--r--plugins/tipper/tipper.mak555
-rw-r--r--plugins/tipper/tipper.mdsp118
-rw-r--r--plugins/tipper/tipper.rc260
-rw-r--r--plugins/tipper/tipper.vcproj382
-rw-r--r--plugins/tipper/tipper_10.sln38
-rw-r--r--plugins/tipper/tipper_10.vcxproj429
-rw-r--r--plugins/tipper/tipper_10.vcxproj.filters80
-rw-r--r--plugins/tipper/tipper_8.sln23
-rw-r--r--plugins/tipper/tipper_8.vcproj537
-rw-r--r--plugins/tipper/tipper_9.sln38
-rw-r--r--plugins/tipper/tipper_9.vcproj981
-rw-r--r--plugins/tipper/translations.cpp598
-rw-r--r--plugins/tipper/translations.h12
-rw-r--r--plugins/tipper/version.h29
-rw-r--r--plugins/tipper/version.rc34
44 files changed, 11042 insertions, 0 deletions
diff --git a/plugins/tipper/common.h b/plugins/tipper/common.h
new file mode 100644
index 0000000000..70ac51e0a4
--- /dev/null
+++ b/plugins/tipper/common.h
@@ -0,0 +1,78 @@
+// stdafx.h : include file for standard system include files,
+// or project specific include files that are used frequently, but
+// are changed infrequently
+//
+
+#pragma once
+
+// Modify the following defines if you have to target a platform prior to the ones specified below.
+// Refer to MSDN for the latest info on corresponding values for different platforms.
+#ifndef WINVER // Allow use of features specific to Windows XP or later.
+#define WINVER 0x0501 // Change this to the appropriate value to target other versions of Windows.
+#endif
+
+#ifndef _WIN32_WINNT // Allow use of features specific to Windows XP or later.
+#define _WIN32_WINNT 0x0501 // Change this to the appropriate value to target other versions of Windows.
+#endif
+
+#ifndef _WIN32_WINDOWS // Allow use of features specific to Windows 98 or later.
+#define _WIN32_WINDOWS 0x0410 // Change this to the appropriate value to target Windows Me or later.
+#endif
+
+#ifndef _WIN32_IE // Allow use of features specific to IE 6.0 or later.
+#define _WIN32_IE 0x0600 // Change this to the appropriate value to target other versions of IE.
+#endif
+
+#define MIRANDA_VER 0x0700 // for tabbed options
+
+#include <m_stdhdr.h>
+
+#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
+// Windows Header Files:
+#include <windows.h>
+#include <commctrl.h>
+#include <commdlg.h>
+
+#include <stddef.h>
+#include <time.h>
+
+#include <win2k.h>
+#include <newpluginapi.h>
+#include <statusmodes.h>
+#include <m_database.h>
+#include <m_langpack.h>
+#include <m_options.h>
+#include <m_system.h>
+#include <m_idle.h>
+#include <m_skin.h>
+#include <m_clui.h>
+#include <m_clist.h>
+#include <m_clc.h>
+#include <m_cluiframes.h>
+#include <m_awaymsg.h>
+#include <m_utils.h>
+#include <m_protocols.h>
+#include <m_protosvc.h>
+#include <m_protomod.h>
+#include <m_contacts.h>
+#include <m_timezones.h>
+
+#include <m_popup.h>
+#include <m_fontservice.h>
+#include <m_avatars.h>
+#include <m_icq.h>
+#include <m_imgsrvc.h>
+
+#include "m_updater.h"
+#include "m_variables.h"
+#include "m_notify.h"
+#include "m_metacontacts.h"
+
+#define MODULE "Tipper"
+
+extern HMODULE hInst;
+
+extern HFONT hFontTitle, hFontLabels, hFontValues;
+extern COLORREF colTitle, colLabels, colBg, colValues;
+
+extern int code_page;
diff --git a/plugins/tipper/docs/autoexec_Tipper(Omniwolf).ini b/plugins/tipper/docs/autoexec_Tipper(Omniwolf).ini
new file mode 100644
index 0000000000..b68bdc8d75
--- /dev/null
+++ b/plugins/tipper/docs/autoexec_Tipper(Omniwolf).ini
@@ -0,0 +1,339 @@
+SETTINGS:
+
+[Tipper]
+WinWidth=d400
+WinMaxHeight=d400
+Transparency=b19
+Border=b0
+RoundCorners=b1
+Animate=b0
+TransparentBg=b0
+RightIcon=b0
+AVLayout=b2
+AVSize=d86
+TextIndent=d22
+ShowNoFocus=b1
+DSNumValues=w19
+DINumValues=w22
+ShowStatusMsg=b1
+Type0=b1
+TransFunc0=w7
+DIValue0=u%Status%
+DILineAbove0=b0
+DIValNewline0=b0
+Type1=b1
+TransFunc1=w7
+DILineAbove1=b0
+DIValNewline1=b0
+Type2=b1
+TransFunc2=w2
+DILineAbove2=b0
+DIValNewline2=b0
+Type3=b1
+TransFunc3=w3
+Type4=b1
+TransFunc4=w1
+DILineAbove3=b0
+DIValNewline3=b0
+Type5=b1
+TransFunc5=w1
+DILineAbove4=b1
+DIValNewline4=b0
+Type6=b1
+TransFunc6=w1
+DILineAbove5=b0
+DIValNewline5=b0
+DILabel0=uStatus:
+Type7=b1
+TransFunc7=w1
+DILineAbove6=b0
+DIValNewline6=b0
+Name8=umetaS0
+Type8=b1
+TransFunc8=w1
+Name9=umetaS1
+Type9=b1
+TransFunc9=w1
+Name10=umetaS2
+Type10=b1
+TransFunc10=w1
+Name11=umetaS3
+Type11=b1
+TransFunc11=w1
+Name12=umetaS4
+Type12=b1
+TransFunc12=w1
+Name13=umetaS5
+Type13=b1
+TransFunc13=w1
+Type14=b1
+TransFunc14=w1
+Type15=b1
+TransFunc15=w1
+Type16=b1
+TransFunc16=w1
+DILineAbove7=b0
+DIValNewline7=b0
+DILineAbove8=b1
+DIValNewline8=b0
+DILineAbove9=b1
+DIValNewline9=b0
+DILineAbove10=b1
+DIValNewline10=b1
+Name14=umetaS6
+Name16=umetaS8
+Type17=b1
+TransFunc17=w1
+Name15=umetaS7
+Name17=umetaS9
+Type18=b1
+TransFunc18=w1
+Type19=b1
+TransFunc19=w0
+Type20=b1
+TransFunc20=w0
+FontFirstSize=b241
+FontFirstSty=b1
+FontFirstSet=b0
+FontFirstCol=d255
+FontLabelsSize=b243
+FontLabelsSty=b0
+FontLabelsSet=b0
+FontLabelsCol=d4210752
+FontValuesSize=b243
+FontValuesSty=b0
+FontValuesSet=b0
+FontValuesCol=d0
+ColourBg=d14476004
+Name0=uicqIP
+Name18=uStatus
+Type21=b1
+TransFunc21=w1
+DILineAbove11=b1
+DIValNewline11=b1
+Name1=uicqIPreal
+Name19=uMirVer
+Name20=usametimeID
+Name21=uStatus
+Name22=uUIN
+Type22=b1
+TransFunc22=w0
+DILineAbove12=b1
+DIValNewline12=b0
+RightLabels=b0
+TimeIn=w500
+DILineAbove17=b0
+DIValNewline17=b0
+DILineAbove18=b0
+DIValNewline18=b0
+DILineAbove19=b0
+DIValNewline19=b0
+DILineAbove20=b0
+DIValNewline20=b0
+DILineAbove21=b0
+DIValNewline21=b0
+DILineAbove13=b0
+DIValNewline13=b0
+DILineAbove14=b0
+DIValNewline14=b0
+DILineAbove15=b0
+DIValNewline15=b0
+DILineAbove16=b0
+DIValNewline16=b0
+DILineAbove22=b1
+DIValNewline22=b0
+Module0=s
+Setting0=sIP
+Module1=s
+Setting1=sRealIP
+Module2=s
+Setting2=sIdleTS
+Module3=s
+Setting3=sIdleTS
+Module4=s
+Module5=s
+Module6=s
+Module7=s
+Module8=s
+Module9=s
+Module10=s
+Module11=s
+Module12=s
+Module13=s
+Module14=s
+Module15=s
+Module16=s
+Setting16=sStatus8
+Module17=s
+Setting17=sStatus9
+Module18=s
+Module19=s
+Setting19=sMirVer
+Module20=s
+Setting20=sstid
+Module21=s
+Setting21=sStatus
+Module22=s
+Setting22=sUIN
+BorderCol=d0
+Name3=uIdleTS-diff
+Setting7=sLogonTS
+Setting8=sStatus0
+Setting9=sStatus1
+Setting10=sStatus2
+Setting11=sStatus3
+Setting12=sStatus4
+Setting13=sStatus5
+DILineAbove23=b0
+DIValNewline23=b0
+DILineAbove24=b0
+DIValNewline24=b0
+DILineAbove25=b0
+DIValNewline25=b0
+DILineAbove26=b0
+DIValNewline26=b0
+DILineAbove27=b0
+DIValNewline27=b0
+DILineAbove28=b0
+DIValNewline28=b0
+TitleLayout=b0
+Padding=w4
+Position=b1
+MinWidth=d0
+MinHeight=d0
+WORD to status description=d1
+NextFuncId=d17
+DWORD timestamp to time=d2
+DWORD timestamp to time difference=d3
+BYTE to Yes/No=d4
+BYTE to Male/Female (ICQ)=d5
+WORD to country name=d6
+DWORD to ip address=d7
+<prefix>Day|Month|Year to date=d8
+<prefix>Day|Month|Year to age=d9
+<prefix>Hours|Minutes|Seconds to time=d10
+<prefix>Day|Month|Year|Hours|Minutes|Seconds to time difference=d11
+DWORD timestamp to time (no seconds)=d12
+<prefix>Hours|Minutes to time=d13
+DWORD timestamp to date (short)=d14
+DWORD timestamp to date (long)=d15
+MaxWidth=d350
+MaxHeight=d400
+Opacity=b85
+TransFuncId0=d7
+TransFuncId1=d7
+TransFuncId2=d14
+TransFuncId3=d3
+TransFuncId4=d12
+TransFuncId5=d14
+TransFuncId6=d3
+TransFuncId7=d12
+TransFuncId8=d1
+TransFuncId9=d1
+TransFuncId10=d1
+TransFuncId11=d1
+TransFuncId12=d1
+TransFuncId13=d1
+TransFuncId14=d1
+MouseTollerance=b16
+DropShadow=b1
+DILineAbove29=b0
+DIValNewline29=b0
+RightValues=b0
+SBarTips=b1
+xStatus: empty xStatus name to default name=d16
+DILineAbove30=b0
+DIValNewline30=b0
+DividerCol=d8421440
+SidebarCol=d9741995
+AvatarRoundCorners=b0
+AvatarPadding=w7
+TextPadding=w4
+SidebarWidth=d22
+Name2=uIdleTS-date
+Name4=uIdleTS-time
+Setting4=sIdleTS
+Setting14=sStatus6
+TransFuncId15=d1
+Name5=uLogonTS-date
+Name6=uLogonTS-diff
+Name7=uLogonTS-time
+Setting15=sStatus7
+TransFuncId16=d1
+TransFuncId17=d1
+Setting18=sStatus
+TransFuncId18=d1
+Setting5=sLogonTS
+Setting6=sLogonTS
+FontValues=uTahoma
+FontLabels=uTahoma
+FontFirst=uTahoma
+DILabel26=uHigh/Low:
+DILabel27=uPressure:
+DILabel1=uName:
+DIValue1=u%raw:/FirstName|% %raw:/LastName%
+DIValue3=u%raw:/MirVer%
+DILabel6=uExternal IP:
+DILabel23=uVisibility:
+DILabel28=uHumidity:
+DILabel7=uInternal IP:
+DILabel8=uActive subcontact:
+DIValue8=u%sys:meta_subproto% - %sys:meta_subname%
+DILabel22=uObservation time:
+DIValue22=u%raw:Current/Update%
+DIValue23=u%raw:Current/Visibility%
+DILabel24=uFeels like:
+DIValue24=u%raw:Current/Feel%
+DILabel25=uWind:
+DIValue25=u%raw:Current/Wind Direction% (%raw:Current/Wind Direction DEG%)/%raw:Current/Wind Speed%
+DIValue26=u%raw:Current/High%/%raw:Current/Low%
+DIValue27=u%raw:Current/Pressure% (%raw:Current/Pressure Tendency%)
+DIValue28=u%raw:Current/Humidity%
+DILabel29=uUV Index:
+DIValue29=u%raw:Current/UV% - %raw:Current/UVI%
+DILabel30=uSunrise/Sunset:
+DIValue30=u%raw:Current/Sunrise%/%raw:Current/Sunset%
+DILabel31=uMoonphase
+DIValue31=u%raw:Current/Moon%
+DILineAbove31=b0
+DIValNewline31=b0
+DIValue6=u%icqIP%
+DIValue7=u%icqIPreal%
+DILabel2=u%sys:uidname^!MetaContacts%:
+DIValue2=u%sys:uid%
+DILabel3=uClient:
+DILabel4=uLogged on:
+DIValue4=u%LogonTS-diff%
+DILabel5=uIdle:
+DIValue5=u%IdleTS-diff%
+FontFirstFlags=d288
+FontLabelsFlags=d288
+FontValuesFlags=d288
+DILabel9=uListening To:
+DIValue9=u%raw:/ListeningTo%
+DILabel10=uLast message: (%sys:last_msg_reltime% ago)
+DIValue10=u%sys:last_msg%
+DILabel11=uStatus Message:
+DIValue11=u%sys:status_msg%
+DILabel12=uObservation time:
+DIValue12=u%raw:Current/Update%
+DILabel13=uVisibility:
+DIValue13=u%raw:Current/Visibility%
+DILabel14=uFeels like:
+DIValue14=u%raw:Current/Feel%
+DILabel15=uWind:
+DIValue15=u%raw:Current/Wind Direction% (%raw:Current/Wind Direction DEG%)/%raw:Current/Wind Speed%
+DILabel16=uHigh/Low:
+DIValue16=u%raw:Current/High%/%raw:Current/Low%
+DILabel17=uPressure:
+DIValue17=u%raw:Current/Pressure% (%raw:Current/Pressure Tendency%)
+DILabel18=uHumidity:
+DIValue18=u%raw:Current/Humidity%
+DILabel19=uUV Index:
+DIValue19=u%raw:Current/UV% - %raw:Current/UVI%
+DILabel20=uSunrise/Sunset:
+DIValue20=u%raw:Current/Sunrise%/%raw:Current/Sunset%
+DILabel21=uMoonphase
+DIValue21=u%raw:Current/Moon%
+
+
diff --git a/plugins/tipper/docs/autoexec_Tipper(Tweety).ini b/plugins/tipper/docs/autoexec_Tipper(Tweety).ini
new file mode 100644
index 0000000000..46584f6767
--- /dev/null
+++ b/plugins/tipper/docs/autoexec_Tipper(Tweety).ini
@@ -0,0 +1,379 @@
+SETTINGS:
+
+[Tipper]
+WORD to status description=d1
+NextFuncId=d17
+DWORD timestamp to time=d2
+DWORD timestamp to time difference=d3
+BYTE to Yes/No=d4
+BYTE to Male/Female (ICQ)=d5
+WORD to country name=d6
+DWORD to ip address=d7
+<prefix>Day|Month|Year to date=d8
+<prefix>Day|Month|Year to age=d9
+<prefix>Hours|Minutes|Seconds to time=d10
+<prefix>Day|Month|Year|Hours|Minutes|Seconds to time difference=d11
+DWORD timestamp to time (no seconds)=d12
+<prefix>Hours|Minutes to time=d13
+DWORD timestamp to date (short)=d14
+DWORD timestamp to date (long)=d15
+WinWidth=d400
+WinMaxHeight=d400
+Transparency=b19
+Border=b0
+RoundCorners=b1
+Animate=b1
+TransparentBg=b0
+RightIcon=b0
+AVLayout=b2
+AVSize=d80
+TextIndent=d23
+ShowNoFocus=b1
+NumValues=w3
+FontFirstSize=b247
+FontFirstSty=b1
+FontFirstSet=b0
+FontFirstCol=d6572572
+FontLabelsSize=b247
+FontLabelsSty=b1
+FontLabelsSet=b0
+FontLabelsCol=d6572572
+FontValuesSize=b247
+FontValuesSty=b0
+FontValuesSet=b0
+FontValuesCol=d6049571
+ColourBg=d15987699
+Label0=uEtat
+Type0=b0
+TransFunc0=w7
+Label1=uMessage d'état
+Type1=b1
+TransFunc1=w7
+Label2=uDernier Message
+Type2=b1
+TransFunc2=w2
+ShowStatusMsg=b1
+DSNumValues=w21
+DILineAbove0=b0
+DIValNewline0=b0
+DINumValues=w38
+DILineAbove1=b0
+DIValNewline1=b0
+DILineAbove2=b0
+DIValNewline2=b0
+DILineAbove3=b0
+DIValNewline3=b0
+DILineAbove4=b0
+DIValNewline4=b0
+Type3=b1
+TransFunc3=w3
+Type4=b1
+TransFunc4=w1
+Type5=b1
+TransFunc5=w1
+Type6=b0
+TransFunc6=w1
+DILineAbove5=b0
+DIValNewline5=b0
+Type7=b1
+TransFunc7=w1
+DILineAbove6=b0
+DIValNewline6=b0
+Type8=b1
+TransFunc8=w1
+Type9=b1
+TransFunc9=w1
+Name10=umetaS0
+Type10=b1
+TransFunc10=w1
+Name11=umetaS1
+Type11=b1
+TransFunc11=w1
+Name12=umetaS2
+Type12=b1
+TransFunc12=w1
+Name13=umetaS3
+Type13=b1
+TransFunc13=w1
+Type14=b1
+TransFunc14=w1
+Type15=b1
+TransFunc15=w1
+Type16=b1
+TransFunc16=w1
+DILineAbove7=b0
+DIValNewline7=b0
+DILineAbove8=b1
+DIValNewline8=b0
+DILineAbove9=b0
+DIValNewline9=b0
+DILineAbove10=b0
+DIValNewline10=b0
+Name14=umetaS4
+Name16=umetaS6
+Type17=b1
+TransFunc17=w1
+Name15=umetaS5
+Name17=umetaS7
+Type18=b1
+TransFunc18=w1
+Type19=b1
+TransFunc19=w0
+Type20=b1
+TransFunc20=w0
+Name18=umetaS8
+Type21=b1
+TransFunc21=w1
+DILineAbove11=b0
+DIValNewline11=b0
+Name19=umetaS9
+Name21=uStatus
+Name22=uUIN
+Type22=b1
+TransFunc22=w0
+DILineAbove12=b0
+DIValNewline12=b0
+RightLabels=b0
+TimeIn=w300
+DILineAbove17=b0
+DIValNewline17=b0
+DILineAbove18=b0
+DIValNewline18=b0
+DILineAbove19=b0
+DIValNewline19=b0
+DILineAbove20=b0
+DIValNewline20=b0
+DILineAbove21=b0
+DIValNewline21=b0
+DILineAbove13=b1
+DIValNewline13=b1
+DILineAbove14=b0
+DIValNewline14=b1
+DILineAbove15=b1
+DIValNewline15=b0
+DILineAbove16=b0
+DIValNewline16=b0
+DILineAbove22=b0
+DIValNewline22=b0
+Module1=s
+Module2=s
+Setting2=sRealIP
+Module3=s
+Setting3=sIdleTS
+Module7=s
+Module8=s
+Module9=s
+Module10=s
+Module11=s
+Module12=s
+Module13=s
+Module14=s
+Module15=s
+Module16=s
+Module17=s
+Module18=s
+Module19=s
+Module20=s
+Module21=s
+Setting21=sStatus
+Module22=s
+Setting22=sUIN
+BorderCol=d6567708
+Setting7=sLogonTS
+Setting8=sLogonTS
+Setting9=sLogonTS
+Setting10=sStatus0
+Setting11=sStatus1
+Setting12=sStatus2
+Setting13=sStatus3
+DILineAbove23=b0
+DIValNewline23=b0
+DILineAbove24=b0
+DIValNewline24=b0
+DILineAbove25=b1
+DIValNewline25=b1
+DILineAbove26=b1
+DIValNewline26=b1
+DILineAbove27=b1
+DIValNewline27=b1
+DILineAbove28=b1
+DIValNewline28=b0
+Setting14=sStatus4
+DILineAbove29=b0
+DIValNewline29=b0
+DILineAbove30=b0
+DIValNewline30=b0
+DILineAbove31=b0
+DIValNewline31=b0
+TitleLayout=b0
+Padding=w3
+Position=b1
+MinWidth=d300
+MinHeight=d0
+TransFuncId0=d5
+TransFuncId1=d7
+TransFuncId2=d7
+TransFuncId3=d3
+TransFuncId4=d14
+TransFuncId5=d12
+TransFuncId6=d1
+TransFuncId7=d3
+TransFuncId8=d14
+TransFuncId9=d12
+TransFuncId10=d1
+TransFuncId11=d1
+TransFuncId12=d1
+TransFuncId13=d1
+TransFuncId14=d1
+TransFuncId15=d1
+DILineAbove32=b0
+DIValNewline32=b0
+DILineAbove33=b0
+DIValNewline33=b0
+MaxWidth=d350
+MaxHeight=d400
+Opacity=b75
+DILabel21=uHumidity:
+DILineAbove34=b0
+DIValNewline34=b0
+Module4=s
+Setting15=sStatus5
+TransFuncId16=d1
+DILineAbove35=b0
+DIValNewline35=b0
+DILineAbove36=b0
+DIValNewline36=b0
+MouseTollerance=b16
+DILineAbove37=b0
+DIValNewline37=b0
+DILineAbove38=b0
+DIValNewline38=b0
+FontValues=uTahoma
+FontLabels=uTahoma
+FontFirst=uTahoma
+xStatus: empty xStatus name to default name=d16
+DropShadow=b1
+RightValues=b0
+SBarTips=b1
+DividerCol=d10304821
+SidebarCol=d15391189
+AvatarRoundCorners=b0
+AvatarPadding=w6
+TextPadding=w4
+SidebarWidth=d22
+TransFuncId17=d1
+TransFuncId18=d1
+Name0=uGender
+Module0=sUserInfo
+Setting0=sGender
+Name1=uicqIP
+Setting1=sIP
+Name2=uicqIPreal
+DILabel20=uPressure:
+DILabel39=uLast message: (%sys:last_msg_reltime% ago)
+DIValue39=u%sys:last_msg%
+DILineAbove39=b1
+DIValNewline39=b1
+DILabel0=uStatus:
+DIValue0=u%Status%
+DILabel4=uID:
+DILabel1=uNick:
+DIValue1=u%raw:/Nick%
+DIValue29=u%raw:/CListName1% (%metaS1%) %raw:/Login1%
+DILabel29=u%raw:/Protocol1%:
+DILabel30=u%raw:/Protocol2%:
+DILabel31=u%raw:/Protocol3%:
+DILabel32=u%raw:/Protocol4%:
+DIValue30=u%raw:/CListName2% (%metaS2%) %raw:/Login2%
+DIValue31=u%raw:/CListName3% (%metaS3%) %raw:/Login3%
+DIValue32=u%raw:/CListName4% (%metaS4%) %raw:/Login4%
+DILabel38=u%raw:/Protocol9%:
+DIValue38=u%raw:/CListName9% (%metaS9%) %raw:/Login9%
+DILabel37=u%raw:/Protocol9%:
+DIValue37=u%raw:/CListName9% (%metaS9%) %raw:/Login9%
+DILabel35=u%raw:/Protocol7%:
+DIValue35=u%raw:/CListName7% (%metaS7%) %raw:/Login7%
+DILabel36=u%raw:/Protocol8%:
+DIValue36=u%raw:/CListName8% (%metaS8%) %raw:/Login8%
+DILabel33=u%raw:/Protocol5%:
+DIValue33=u%raw:/CListName5% (%metaS5%) %raw:/Login5%
+DILabel34=u%raw:/Protocol6%:
+DIValue34=u%raw:/CListName6% (%metaS6%) %raw:/Login6%
+FontFirstFlags=d288
+FontLabelsFlags=d288
+FontValuesFlags=d288
+DILabel16=uVisibility:
+DILabel19=uHigh/Low:
+DILabel28=u%raw:/Protocol0%:
+DIValue28=u%raw:/CListName0% (%metaS0%) %raw:/Login0%
+Name3=uidle_ago
+Name4=uidle_date
+Name5=uidle_time
+Module5=s
+Name6=ulastseen_status
+Module6=sSeenModule
+Setting6=sStatus
+Setting16=sStatus6
+Setting4=sIdleTS
+Setting5=sIdleTS
+Name8=ulogon_date
+Setting17=sStatus7
+Setting18=sStatus8
+TransFuncId19=d1
+DILabel13=uExtra status title:
+DIValue13=u%raw:/XStatusName%
+DILabel14=uExtra status message:
+DIValue14=u%raw:/XStatusMsg%
+DILabel15=uObservation time:
+DIValue15=u%raw:Current/Update%
+DIValue16=u%raw:Current/Visibility%
+DILabel17=uFeels like:
+DIValue17=u%raw:Current/Feel%
+DILabel18=uWind:
+DIValue18=u%raw:Current/Wind Direction% (%raw:Current/Wind Direction DEG%)/%raw:Current/Wind Speed%
+DIValue19=u%raw:Current/High%/%raw:Current/Low%
+DIValue20=u%raw:Current/Pressure% (%raw:Current/Pressure Tendency%)
+DIValue21=u%raw:Current/Humidity%
+DILabel22=uUV Index:
+DIValue22=u%raw:Current/UV% - %raw:Current/UVI%
+DILabel23=uSunrise/Sunset:
+DIValue23=u%raw:Current/Sunrise%/%raw:Current/Sunset%
+DILabel24=uMoonphase
+DIValue24=u%raw:Current/Moon%
+DILabel25=uTopic :
+DIValue25=u%raw:/Topic%
+DILabel26=uLast message: (%sys:last_msg_reltime% ago)
+DIValue26=u%sys:last_msg%
+DILabel27=uStatus message :
+DIValue27=u%sys:status_msg%
+Name9=ulogon_time
+Setting19=sStatus9
+Name20=uStatus
+Setting20=sStatus
+TransFuncId20=d1
+DIValue8=u%raw:/MirVer%
+DILabel11=uIdle:
+DIValue11=u%idle_date% @ %idle_time% (%idle_ago%)
+DILabel12=uLogon:
+DIValue12=u%logon_date% @ %logon_time% (%logon_ago%)
+Name7=ulogon_ago
+DILabel8=uClient:
+DILabel9=uIP:
+DIValue9=u%icqIP% (%icqIPreal%)
+DILabel10=uLast seen:
+DIValue10=u%raw:SeenModule/Day%.%raw:SeenModule/Month%.%raw:SeenModule/Year% @ %raw:SeenModule/Hours%:%raw:SeenModule/Minutes%:%raw:SeenModule/Seconds% (%lastseen_status%)
+DILabel2=uEmail:
+DIValue2=u%raw:/e-mail%
+DILabel3=uUIN:
+DIValue3=u%raw:/UIN%
+DIValue4=u%raw:/stid%
+DILabel5=uID:
+DIValue5=u%raw:/jid%
+DILabel6=uGender:
+DIValue6=u%Gender%
+DILabel7=uBirthday:
+DIValue7=u%raw:mBirthday/BirthDay%-%raw:mBirthday/BirthMonth%-%raw:mBirthday/BirthYear% ( %raw:UserInfo/Age% )
+DILineAbove28=b0
+DIValNewline28=b0
+DILabel28=uListening To:
+DIValue28=u%raw:/ListeningTo% \ No newline at end of file
diff --git a/plugins/tipper/docs/licence_Tipper.txt b/plugins/tipper/docs/licence_Tipper.txt
new file mode 100644
index 0000000000..082744b8a8
--- /dev/null
+++ b/plugins/tipper/docs/licence_Tipper.txt
@@ -0,0 +1,6 @@
+The Tipper plugin for Miranda-IM is Copyright (c) 2006 Scott Ellis (mail@scottellis.com.au)
+
+http://www.scottellis.com.au
+
+It is released under the General Public Licence, available here:
+http://www.gnu.org/copyleft/gpl.html \ No newline at end of file
diff --git a/plugins/tipper/docs/m_tipper.h b/plugins/tipper/docs/m_tipper.h
new file mode 100644
index 0000000000..031d490632
--- /dev/null
+++ b/plugins/tipper/docs/m_tipper.h
@@ -0,0 +1,23 @@
+// Tipper API
+// note: Tipper is internally unicode and requires unicows.dll to function correctly on 95/98/ME
+// so you'll find a lot of wchar_t stuff in here
+
+// use hContact, module and setting to read your db value(s) and put the resulting string into buff
+// return buff if the translation was successful, or return 0 for failure
+typedef wchar_t *(TranslateFunc)(HANDLE hContact, const char *module, const char *setting_or_prefix, wchar_t *buff, int bufflen);
+
+typedef struct {
+ TranslateFunc *tfunc; // address of your translation function (see typedef above)
+ const wchar_t *name; // make sure this is unique, and DO NOT translate it
+ DWORD id; // will be overwritten by Tipper - do not use
+} DBVTranslation;
+
+// add a translation to tipper
+// wParam not used
+// lParam = (DBVTranslation *)translation
+#define MS_TIPPER_ADDTRANSLATION "Tipper/AddTranslation"
+
+// unicode extension to the basic functionality
+// wParam - optional (wchar_t *)text for text-only tips
+// lParam - (CLCINFOTIP *)infoTip
+#define MS_TIPPER_SHOWTIPW "mToolTip/ShowTipW"
diff --git a/plugins/tipper/docs/readme_tipper.txt b/plugins/tipper/docs/readme_tipper.txt
new file mode 100644
index 0000000000..bb8bd97183
--- /dev/null
+++ b/plugins/tipper/docs/readme_tipper.txt
@@ -0,0 +1,144 @@
+Document updated: 28/9/06
+
+******
+Tipper - shows a tooltip when you hover the mouse over a contact in your contact list
+******
+
+Most options are self explanitory...except for 'items' and 'substitutions'.
+
+If you want to set this up yourself, you need a moderate understanding of the miranda database (profile) and the Database Editor++ plugin.
+
+The easiest way is to copy the autoexec_tipper.ini file (in the same folder as this document) to the miranda program folder and restart -
+it will (normally) ask you if you wish to import the settings. If you click yes, you will find several examples in your Tipper options that
+will get you started. You can also ask your nerdier miranda-using buddies to create such a file for you, if they have a good setup.
+
+To get an idea of how tipper works, try playing with items. Items are simply a label and some text (the value). Try adding some items. Once
+you've played around a bit you'll get the idea, and then you'll understand the need for substitutions.
+
+Substitutions allow you to put useful, contact related, information into the label or value of an item. To create a substitution you need
+to have a relatively good understanding of the miranda database - a few hours browsing with dbeditor++ will give you a clue. You create a
+substitution by specifying a name and the database module and setting names for the data it will contain. You can then put this data into
+any item (label or value) by enclosing the substitution name in '%' symbols. Many database values are not terribly friendly to humans, so
+when creating a substitution, you can also choose a translation which will convert the value into a more readable format.
+
+To get technical:
+
+A 'Substitution' is a name for a database value, represented according to a particular translation. When creating new substitutions, you
+specify its name, the database module (or the contact's protocol module) and the setting name. Then you select a translation from the drop
+down list. This transformation will convert the database value into a string.
+
+An 'Item' is just a label and a value. However, any substitution names (surrounded by % symbols) occuring in either a label or a value will
+be substituted as described above. If you want to put a % symbol in a value or label, use '%%' instead.
+
+A good example is representing a contacts status (as 'Online' etc) in the tooltip.
+
+First, create a substitution called 'status' (without quotes) - the module will be the contact's protocol module, the setting name will be
+'Status' (without quotes - note the capital 'S') and the translation will be 'WORD to status description' (since this value is a WORD value
+in the database). Then, create an item and specify 'Status:' for the label and '%status%' for the value. Done.
+
+There is also a built in substitution, called a 'raw' substitution. It is not listed in the substitution list, but it is available in all
+labels and values. It's format is:
+
+%raw:<db module>/<db setting>%
+
+No translation is performed on 'raw' values. For example, to display a contact's contact list group in the tooltip, add an item with the
+label 'Group:' and the value '%raw:CList/Group%'. If you do not specify a module name (you must still include the '/'), the contact's
+protocol module will be used. This is ultimately just a shortcut for the 'null translation'.
+
+There are also 'system' substitutions (thanks to y_b), also not listed but available in all item labels and values, with the following
+format:
+
+%sys:<name>%
+
+Were name can be any of the following:
+
+uid - contact's unique identifier
+uidname - name of unique identifier
+proto - contact's protocol
+time - contact's time
+status_msg - contact's status message
+last_msg - last message received from contact
+last_msg_time - time of last received message
+last_msg_date - date of last received message
+last_msg_reltime - relative time of last message (i.e. time between then and now)
+meta_subname - nickname of active subcontact (for metacontacts)
+meta_subuid - unique id of active subcontact
+meta_subproto - active subcontact protocol (also for metacontacts)
+
+If a substitution's value results in no text (or nothing but spaces, tabs, newlines, and carriage returns), the whole item containing that
+substitution will not be displayed. If there is an error during the substitution process (e.g. a substitution name that does not exist, an odd
+number of % symbols, etc) then the value of that substitution will be "*". Note that you can use double-percent ("%%") in plain text (not in
+substitutions) if you want an actual percent symbol.
+
+ADVANCED
+--------
+
+Alternative Text:
+In any substitution you can have 'alternate text' to use if the substitution fails (missing db value, etc). The format is:
+
+%x|y%
+
+where x is the original substitution and y is the alternative text. Note that you can use '|' in the alternative text, since it uses the
+*first* occurence to determine where the alternative text begins. Normally if any substitution results in no value, the entire item will not
+be displayed - but if you omit the 'y' value above (i.e. have nothing for the 'alternate' text) then the substitution process will continue.
+As an example, consider the following item value:
+
+%raw:/FirstName|% %raw:/LastName%
+
+The above value will display the contact's first name if it's available, and then their last name - but if the last name is not available, the
+entire item will not be displayed.
+
+Specific protocol:
+If you end a substitution with '^' and a protocol name, then that substitution will only be displayed if the contact belongs to the given
+protocol:
+
+%x^y%
+
+where y is the protocol name. If you want to display an item for every protocol *except* one, use
+
+%x^!y%
+
+If you use alternative text and specific protocol together, specify the alternative text first:
+
+%x|y^z%
+
+In such substitutions you can use a '^' symbol in the alternative text, as Tipper will take the *last* '^' symbol as the start of the protocol
+specifier. If you want to use a '^' symbol in alternative text without a specific protocol, just append a '^' to the end of the descriptor,
+e.g.:
+
+%x|y^%
+
+
+'HIDDEN' DB SETTINGS
+--------------------
+
+Due to space constraints in the options page and my own laziness, the following settings are only accessible via the database (i.e. using dbeditor++):
+
+DWORD Tipper/MinHeight
+DWORD Tipper/MinWidth
+WORD Tipper/AvatarPadding
+WORD Tipper/TextPadding (space between lines of text)
+DWORD Tipper/SidebarWidth
+BYTE Tipper/MouseTollerance (distance mouse can move while tip is shown, before it is automatically closed, in pixels)
+BYTE Tipper/AvatarRoundCorners
+
+
+********************
+'Variables' support:
+********************
+
+This plugin supports the variables plugin by UnregistereD (http://www.cs.vu.nl/~pboon/variables.zip)
+
+Be sure to use the unicode version!
+
+All text in 'Items' - that is, labels and values, will be processed by variables BEFORE Tipper substitutions are applied.
+
+
+Good luck and have fun.
+
+
+Scott
+mail@scottellis.com.au
+www.scottellis.com.au
+
+p.s. Thanks to Omniwolf and Tweety for compiling autoexec_Tipper(*).ini files
diff --git a/plugins/tipper/m_metacontacts.h b/plugins/tipper/m_metacontacts.h
new file mode 100644
index 0000000000..1da12b97fa
--- /dev/null
+++ b/plugins/tipper/m_metacontacts.h
@@ -0,0 +1,162 @@
+/*
+
+Miranda IM: the free IM client for Microsoft* Windows*
+
+Copyright © 2004 Universite Louis PASTEUR, STRASBOURG.
+Copyright © 2004 Scott Ellis (www.scottellis.com.au mail@scottellis.com.au)
+
+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 M_METACONTACTS_H__
+#define M_METACONTACTS_H__ 1
+
+//get the handle for a contact's parent metacontact
+//wParam=(HANDLE)hSubContact
+//lParam=0
+//returns a handle to the parent metacontact, or null if this contact is not a subcontact
+#define MS_MC_GETMETACONTACT "MetaContacts/GetMeta"
+
+//gets the handle for the default contact
+//wParam=(HANDLE)hMetaContact
+//lParam=0
+//returns a handle to the default contact, or null on failure
+#define MS_MC_GETDEFAULTCONTACT "MetaContacts/GetDefault"
+
+//gets the contact number for the default contact
+//wParam=(HANDLE)hMetaContact
+//lParam=0
+//returns a DWORD contact number, or -1 on failure
+#define MS_MC_GETDEFAULTCONTACTNUM "MetaContacts/GetDefaultNum"
+
+//gets the handle for the 'most online' contact
+//wParam=(HANDLE)hMetaContact
+//lParam=0
+//returns a handle to the 'most online' contact
+#define MS_MC_GETMOSTONLINECONTACT "MetaContacts/GetMostOnline"
+
+//gets the number of subcontacts for a metacontact
+//wParam=(HANDLE)hMetaContact
+//lParam=0
+//returns a DWORD representing the number of subcontacts for the given metacontact
+#define MS_MC_GETNUMCONTACTS "MetaContacts/GetNumContacts"
+
+//gets the handle of a subcontact, using the subcontact's number
+//wParam=(HANDLE)hMetaContact
+//lParam=(DWORD)contact number
+//returns a handle to the specified subcontact
+#define MS_MC_GETSUBCONTACT "MetaContacts/GetSubContact"
+
+//sets the default contact, using the subcontact's contact number
+//wParam=(HANDLE)hMetaContact
+//lParam=(DWORD)contact number
+//returns 0 on success
+#define MS_MC_SETDEFAULTCONTACTNUM "MetaContacts/SetDefault"
+
+//sets the default contact, using the subcontact's handle
+//wParam=(HANDLE)hMetaContact
+//lParam=(HANDLE)hSubcontact
+//returns 0 on success
+#define MS_MC_SETDEFAULTCONTACT "MetaContacts/SetDefaultByHandle"
+
+//forces the metacontact to send using a specific subcontact, using the subcontact's contact number
+//wParam=(HANDLE)hMetaContact
+//lParam=(DWORD)contact number
+//returns 0 on success
+#define MS_MC_FORCESENDCONTACTNUM "MetaContacts/ForceSendContact"
+
+//forces the metacontact to send using a specific subcontact, using the subcontact's handle
+//wParam=(HANDLE)hMetaContact
+//lParam=(HANDLE)hSubcontact
+//returns 0 on success (will fail if 'force default' is in effect)
+#define MS_MC_FORCESENDCONTACT "MetaContacts/ForceSendContactByHandle"
+
+//'unforces' the metacontact to send using a specific subcontact
+//wParam=(HANDLE)hMetaContact
+//lParam=0
+//returns 0 on success (will fail if 'force default' is in effect)
+#define MS_MC_UNFORCESENDCONTACT "MetaContacts/UnforceSendContact"
+
+//'forces' or 'unforces' (i.e. toggles) the metacontact to send using it's default contact
+// overrides (and clears) 'force send' above, and will even force use of offline contacts
+// will send ME_MC_FORCESEND or ME_MC_UNFORCESEND event
+//wParam=(HANDLE)hMetaContact
+//lParam=0
+//returns 1(true) or 0(false) representing new state of 'force default'
+#define MS_MC_FORCEDEFAULT "MetaContacts/ForceSendDefault"
+
+// method to get state of 'force' for a metacontact
+// wParam=(HANDLE)hMetaContact
+// lParam= (DWORD)&contact_number or NULL
+//
+// if lparam supplied, the contact_number of the contatct 'in force' will be copied to the address it points to,
+// or if none is in force, the value (DWORD)-1 will be copied
+// (v0.8.0.8+ returns 1 if 'force default' is true with *lParam == default contact number, else returns 0 with *lParam as above)
+#define MS_MC_GETFORCESTATE "MetaContacts/GetForceState"
+
+// fired when a metacontact's default contact changes (fired upon creation of metacontact also, when default is initially set)
+// wParam=(HANDLE)hMetaContact
+// lParam=(HANDLE)hDefaultContact
+#define ME_MC_DEFAULTTCHANGED "MetaContacts/DefaultChanged"
+
+// fired when a metacontact's subcontacts change (fired upon creation of metacontact, when contacts are added or removed, and when
+// contacts are reordered) - a signal to re-read metacontact data
+// wParam=(HANDLE)hMetaContact
+// lParam=0
+#define ME_MC_SUBCONTACTSCHANGED "MetaContacts/SubcontactsChanged"
+
+// fired when a metacontact is forced to send using a specific subcontact
+// wParam=(HANDLE)hMetaContact
+// lParam=(HANDLE)hForceContact
+#define ME_MC_FORCESEND "MetaContacts/ForceSend"
+
+// fired when a metacontact is 'unforced' to send using a specific subcontact
+// wParam=(HANDLE)hMetaContact
+// lParam=0
+#define ME_MC_UNFORCESEND "MetaContacts/UnforceSend"
+
+// method to get protocol name - used to be sure you're dealing with a "real" metacontacts plugin :)
+// wParam=lParam=0
+#define MS_MC_GETPROTOCOLNAME "MetaContacts/GetProtoName"
+
+
+// added 0.9.5.0 (22/3/05)
+// wParam=(HANDLE)hContact
+// lParam=0
+// convert a given contact into a metacontact
+#define MS_MC_CONVERTTOMETA "MetaContacts/ConvertToMetacontact"
+
+// added 0.9.5.0 (22/3/05)
+// wParam=(HANDLE)hContact
+// lParam=(HANDLE)hMeta
+// add an existing contact to a metacontact
+#define MS_MC_ADDTOMETA "MetaContacts/AddToMetacontact"
+
+// added 0.9.5.0 (22/3/05)
+// wParam=0
+// lParam=(HANDLE)hContact
+// remove a contact from a metacontact
+#define MS_MC_REMOVEFROMMETA "MetaContacts/RemoveFromMetacontact"
+
+
+// added 0.9.13.2 (6/10/05)
+// wParam=(BOOL)disable
+// lParam=0
+// enable/disable the 'hidden group hack' - for clists that support subcontact hiding using 'IsSubcontact' setting
+// should be called once in the clist 'onmodulesloaded' event handler (which, since it's loaded after the db, will be called
+// before the metacontact onmodulesloaded handler where the subcontact hiding is usually done)
+#define MS_MC_DISABLEHIDDENGROUP "MetaContacts/DisableHiddenGroup"
+
+#endif
diff --git a/plugins/tipper/m_notify.h b/plugins/tipper/m_notify.h
new file mode 100644
index 0000000000..f9bce9624e
--- /dev/null
+++ b/plugins/tipper/m_notify.h
@@ -0,0 +1,177 @@
+#ifndef __m_notify_h__
+#define __m_notify_h__
+
+/*** Miranda Notify Dispatcher ************************************************\
+Notify Dispatcher provides common interface to different notification plugins
+like osd, popup, ticker etc.
+\******************************************************************************/
+
+/* Options UI event and service. The same as for miranda options */
+#define ME_NOTIFY_OPT_INITIALISE "Notify/Opt/Initialise"
+#define MS_NOTIFY_OPT_ADDPAGE "Notify/Opt/AddPage"
+
+typedef struct tagMNOTIFYACTIONINFO {
+ HICON icon;
+ char name[MAXMODULELABELLENGTH];
+ char service[MAXMODULELABELLENGTH];
+ DWORD cookie;
+} MNOTIFYACTIONINFO;
+
+// Just like miranda pluginLink... This should work faster then services,
+// we need some reactivity in notifications.
+typedef struct tagMNNOTIFYLINK
+{
+ /* Create a new notification type */
+ HANDLE (* Register)(const char *name, HICON icon);
+
+ // Create a new notification object
+ HANDLE (* Create)(HANDLE type);
+
+ // Check is handle is a valid notification object
+ int (* IsValid)(HANDLE notify);
+
+ // Set/get information about object, or type defaults
+ int (* Set)(HANDLE notifyORtype, const char *name, DBVARIANT val);
+ int (* Get)(HANDLE notifyORtype, const char *name, DBVARIANT *val);
+
+ // Set/get actions
+ int (* AddAction)(HANDLE notifyORtype, HICON icon, const char *name, const char *service, DWORD cookie);
+ int (* GetActions)(HANDLE notifyORtype, MNOTIFYACTIONINFO *actions);
+
+ // Increment/decrement refer count of notification object. Unreferred objects are destroyed
+ int (* AddRef)(HANDLE notify);
+ int (* Release)(HANDLE notify);
+
+ // Notify user
+ void (* Show)(HANDLE notify);
+ void (* Update)(HANDLE notify);
+ void (* Remove)(HANDLE notify);
+} MNOTIFYLINK;
+
+// Get the MNOTIFYLINK struct
+// result = (LRESULT)(MNOTIFYLINK*)notifyLink
+#define MS_NOTIFY_GETLINK "Notify/GetLink"
+
+// Hook this to process corresponding actions
+#define ME_NOTIFY_SHOW "Notify/Show"
+#define ME_NOTIFY_UPDATE "Notify/Update"
+#define ME_NOTIFY_REMOVE "Notify/Remove"
+
+#if !defined(MNOTIFY_NOEXTERN)
+ extern
+ #ifdef __cpluplus
+ "C"
+ #endif
+ MNOTIFYLINK *notifyLink;
+#endif
+
+#if !defined(MNOTIFY_NOHELPERS) && !defined(MNOTIFY_NOEXTERN)
+ #define MNotifyRegister(a,b) (notifyLink?notifyLink->Register((a),(b)):0)
+ #define MNotifyCreate(a) (notifyLink?notifyLink->Create((a)):0)
+ #define MNotifyIsValid(a) (notifyLink?notifyLink->IsValid((a)):0)
+ #define MNotifySet(a,b,c) (notifyLink?notifyLink->Set((a),(b),(c)):0)
+ #define MNotifyGet(a,b,c) (notifyLink?notifyLink->Get((a),(b),(c)):0)
+ #define MNotifyAddAction(a,b,c) (notifyLink?notifyLink->AddAction((a),(b),(c)):0)
+ #define MNotifyGetActions(a,b) (notifyLink?notifyLink->GetActions((a),(b)):0)
+ #define MNotifyGet(a,b,c) (notifyLink?notifyLink->Get((a),(b),(c)):0)
+ #define MNotifyAddRef(a) (notifyLink?notifyLink->AddRef((a)):0)
+ #define MNotifyRelease(a) (notifyLink?notifyLink->Release((a)):0)
+ #define MNotifyShow(a) (notifyLink?notifyLink->Show(a):0)
+ #define MNotifyUpdate(a) (notifyLink?notifyLink->Update(a):0)
+ #define MNotifyRemove(a) (notifyLink?notifyLink->Remove(a):0)
+
+ static void __inline MNotifyGetLink()
+ {
+ notifyLink = ServiceExists(MS_NOTIFY_GETLINK) ? (MNOTIFYLINK *)CallService(MS_NOTIFY_GETLINK,0,0) : 0;
+ }
+
+ // get helpers
+ static __inline BYTE MNotifyGetByte(HANDLE notifyORtype, const char *name, BYTE defValue)
+ {
+ DBVARIANT dbv;
+ MNotifyGet(notifyORtype, name, &dbv);
+ if (dbv.type != DBVT_BYTE) return defValue;
+ return dbv.bVal;
+ }
+ static __inline WORD MNotifyGetWord(HANDLE notifyORtype, const char *name, WORD defValue)
+ {
+ DBVARIANT dbv;
+ MNotifyGet(notifyORtype, name, &dbv);
+ if (dbv.type != DBVT_WORD) return defValue;
+ return dbv.wVal;
+ }
+ static __inline DWORD MNotifyGetDWord(HANDLE notifyORtype, const char *name, DWORD defValue)
+ {
+ DBVARIANT dbv;
+ MNotifyGet(notifyORtype, name, &dbv);
+ if (dbv.type != DBVT_DWORD) return defValue;
+ return dbv.dVal;
+ }
+ static __inline const char *MNotifyGetString(HANDLE notifyORtype, const char *name, const char *defValue)
+ {
+ DBVARIANT dbv;
+ MNotifyGet(notifyORtype, name, &dbv);
+ if (dbv.type != DBVT_ASCIIZ) return defValue;
+ return dbv.pszVal;
+ }
+ static __inline const WCHAR *MNotifyGetWString(HANDLE notifyORtype, const char *name, const WCHAR *defValue)
+ {
+ DBVARIANT dbv;
+ MNotifyGet(notifyORtype, name, &dbv);
+ if (dbv.type != DBVT_WCHAR) return defValue;
+ return dbv.pwszVal;
+ }
+
+ // set helpers
+ static __inline void MNotifySetByte(HANDLE notifyORtype, const char *name, BYTE value)
+ {
+ DBVARIANT dbv;
+ dbv.type = DBVT_BYTE;
+ dbv.bVal = value;
+ MNotifySet(notifyORtype, name, dbv);
+ }
+ static __inline void MNotifySetWord(HANDLE notifyORtype, const char *name, WORD value)
+ {
+ DBVARIANT dbv;
+ dbv.type = DBVT_WORD;
+ dbv.wVal = value;
+ MNotifySet(notifyORtype, name, dbv);
+ }
+ static __inline void MNotifySetDWord(HANDLE notifyORtype, const char *name, DWORD value)
+ {
+ DBVARIANT dbv;
+ dbv.type = DBVT_DWORD;
+ dbv.dVal = value;
+ MNotifySet(notifyORtype, name, dbv);
+ }
+ static __inline void MNotifySetString(HANDLE notifyORtype, const char *name, const char *value)
+ {
+ DBVARIANT dbv;
+ dbv.type = DBVT_ASCIIZ;
+ dbv.pszVal = (char *)value;
+ MNotifySet(notifyORtype, name, dbv);
+ }
+ static __inline void MNotifySetWString(HANDLE notifyORtype, const char *name, const WCHAR *value)
+ {
+ DBVARIANT dbv;
+ dbv.type = DBVT_WCHAR;
+ dbv.pwszVal = (WCHAR *)value;
+ MNotifySet(notifyORtype, name, dbv);
+ }
+#endif
+
+// Common options for Get/Set actions
+#define NFOPT_TYPENAME "General/TypeName"
+#define NFOPT_ICON "General/Icon"
+#define NFOPT_CONTACT "General/Contact"
+#define NFOPT_EVENT "General/Event"
+#define NFOPT_TEXT "General/Text"
+#define NFOPT_TEXTW "General/TextW"
+#define NFOPT_TITLE "General/Title"
+#define NFOPT_TITLEW "General/TitleW"
+#define NFOPT_BACKCOLOR "General/BackColor"
+#define NFOPT_TEXTCOLOR "General/TextColor"
+#define NFOPT_TIMEOUT "General/Timeout"
+//#define NFOPT_ONDESTROY "General/OnDestroy"
+
+#endif // __m_notify_h__
diff --git a/plugins/tipper/m_tipper.h b/plugins/tipper/m_tipper.h
new file mode 100644
index 0000000000..a2b5abfc50
--- /dev/null
+++ b/plugins/tipper/m_tipper.h
@@ -0,0 +1,19 @@
+// Tipper API
+// note: Tipper is internally unicode and requires unicows.dll to function correctly on 95/98/ME
+// so you'll find a lot of wchar_t stuff in here
+
+// translation function type
+// use hContact, module and setting to read your db value(s) and put the resulting string into buff
+// return buff if the translation was successful, or return 0 for failure
+typedef TCHAR *(TranslateFunc)(HANDLE hContact, const char *module, const char *setting_or_prefix, TCHAR *buff, int bufflen);
+
+typedef struct {
+ TranslateFunc *tfunc; // address of your translation function (see typedef above)
+ const TCHAR *name; // make sure this is unique, and DO NOT translate it
+ DWORD id; // will be overwritten by Tipper - do not use
+} DBVTranslation;
+
+// add a translation to tipper
+// wParam not used
+// lParam = (DBVTranslation *)translation
+#define MS_TIPPER_ADDTRANSLATION "Tipper/AddTranslation"
diff --git a/plugins/tipper/m_trigger.h b/plugins/tipper/m_trigger.h
new file mode 100644
index 0000000000..92ab1a0338
--- /dev/null
+++ b/plugins/tipper/m_trigger.h
@@ -0,0 +1,1024 @@
+#ifndef __M_TRIGGER_H__
+#define __M_TRIGGER_H__
+
+#if !defined(_TCHAR_DEFINED)
+#include <tchar.h>
+#endif
+#include "m_utils.h"
+
+// --------------------------------------------------------------------------
+// Triggers
+// --------------------------------------------------------------------------
+
+// This section explains how to create your own trigger. A trigger can be seen
+// as an event which can result in a set of actions that will be performed.
+// Implementing a trigger consists of two parts. First, you register a trigger
+// with MS_TRIGGER_REGISTERTRIGGER to allow a user to configure it in the
+// options dialog. Second, when the event occurs belonging to your registered
+// trigger, you inform the trigger plugin with MS_TRIGGER_REPORTEVENT. You can
+// send a 'payload' together with this notification. This payload, called
+// 'TriggerData', can consist of a certain contact, protocol, status and/or a
+// piece of text.
+
+// --------------------------------------------------------------------------
+// Triggers: Register a trigger
+// --------------------------------------------------------------------------
+
+#define MS_TRIGGER_REGISTERTRIGGER "/TriggerPlugin/RegisterTrigger"
+
+// Parameters:
+// ------------------------
+// wParam = (WPARAM)0
+// lParam = (LPARAM)(TRIGGERREGISTER *)&tr
+// Pointer to a structure describing the trigger to add (see below).
+
+// Return Value:
+// ------------------------
+// Returns 0 on success, nozero otherwise. Registering an already existing
+// trigger will replace this previously registered trigger.
+
+typedef struct {
+ int cbSize; // Set to sizeof(TRIGGERREGISTER).
+ char *pszName; // Used as identifier and shown in the options dialog, must
+ // be unique.
+ HINSTANCE hInstance; // Only needed when options screen is available.
+ DLGPROC pfnDlgProc; // Optional, the callback procedure for the options page.
+ char *pszTemplate; // Optional, template for the options page; must be
+ // WS_CHILD.
+ int flags; // Flags, see below.
+ int dFlags; // Specify the default DF_* flags which your trigger can send
+ // (see below).
+} TRIGGERREGISTER;
+
+// Flags
+#define TRF_NOEXPORT 0x01 // This trigger cannot be exported. Set this flag
+ // in case you stored settings not using the helper
+ // functions at the end of this header. On export,
+ // TriggerPlugin will search for these settings
+ // and export them automatically. Contact-specific
+ // settings are never exported.
+
+// Please specify the dFlags to indicate what kind of data your trigger is
+// able to send as TriggerData. Please specify the maximum set, if your trigger
+// does not always send a certain data, please specify it anyway.
+
+#define DF_CONTACT 0x01 // The trigger might send a contact handle with the
+ // TriggerData.
+#define DF_PROTO 0x02 // The trigger might send a protocol ID with the
+ // TriggerData.
+#define DF_STATUS 0x04 // The trigger might send a status code with the
+ // TriggerData.
+#define DF_TEXT 0x08 // The trigger might send a string with the
+ // TriggerData.
+#define DF_LPARAM 0x10 // The trigger might send a custom parameter with the
+ // TriggerData.
+#define DF_UNICODE 0x20 // The trigger processes WCHAR strings.
+
+#if defined(UNICODE) || defined(_UNICODE)
+#define DF_TCHAR DF_UNICODE // Strings in structure are TCHAR*.
+#else
+#define DF_TCHAR 0
+#endif
+
+// Dialog Messages
+// The following message should be processed by your options dialog procedure,
+// if available. You can create an options dialog to give the user the
+// possibility to report your event only under certain circumstances. Each
+// trigger is assigned a certain ID. This ID can be used to store the settings
+// for your trigger.
+
+// WM_INITDIALOG
+
+// Parameters:
+// ------------------------
+// lParam = (LPARAM)(DWORD)triggerID
+// The trigger ID for which the options are to be set. This can be a new ID
+// or an ID of a trigger which is being edited. Initialize your options
+// dialog accordingly. There are helper function at the end of this header
+// file to read your settings for a certain trigger ID.
+
+#define TM_ADDTRIGGER WM_APP+10
+
+// TM_ADDTRIGGER
+// 'OK' is pressed and a new trigger will be added. Save your settings using
+// the given trigger ID.
+
+// Parameters:
+// ------------------------
+// wParam = (WPARAM)(DWORD)triggerID
+// The trigger ID for which the settings are to be stored. There are helper
+// function at the end of this header file to store your settings with a
+// certain trigger ID.
+// lParam = 0
+
+#define TM_DELTRIGGER WM_APP+11
+
+// TM_DELTRIGGER
+// The trigger addociated with the given trigger ID will be removed.
+
+// Parameters:
+// ------------------------
+// wParam = (WPARAM)(DWORD)triggerID
+// The trigger ID for which the settings are to be removed. There is a
+// helper service at the end of this header file to easily cleanup settings
+// for a certain trigger ID.
+// lParam = 0
+
+// --------------------------------------------------------------------------
+// Triggers: Report the Event
+// --------------------------------------------------------------------------
+
+// When the event occurs, you report it with MS_TRIGGER_REPORTEVENT. If your
+// trigger is configurable, so it has an options screen, you might want to
+// report your trigger for certain trigger ID's only. Please use the
+// MS_TRIGGER_FINDNEXTTRIGGERID to enumerate over the trigger ID's associated
+// with your trigger in the correct order as specified by the user. It's up
+// to you to found out whether or not the trigger is to be reported for a
+// certain ID.
+
+#define MS_TRIGGER_FINDNEXTTRIGGERID "/TriggerPlugin/FindNextTriggerID"
+
+// Enumerate over the associated trigger ID's for your trigger in the correct
+// order.
+
+// Parameters:
+// ------------------------
+// wParam = (WPARAM)(DWORD)triggerID
+// 0 to retrieve the first trigger ID for your trigger or the previous ID
+// returned by this service to get the next one.
+// lParam = 0
+
+// Return Value:
+// ------------------------
+// Returns the next trigger ID given the parameter or 0 if no more trigger IDs
+// are available.
+
+#define MS_TRIGGER_REPORTEVENT "/TriggerPlugin/ReportEvent"
+
+// Report your event for further processing. This can be a general event for
+// which no individual settings exist, or a specific event for a given
+// trigger ID.
+
+// Parameters:
+// ------------------------
+// wParam = 0
+// lParam = (LPARAM)(REPORTINFO *)&ri
+// See below.
+
+// Return Value:
+// ------------------------
+// Returns CRV_TRUE if all conditions specific to this trigger hold and the
+// chain was executed. Returns CRV_FALSE if these conditions did not hold and
+// the chain were not processed.
+
+// The structure below can be used to send TriggerData with your trigger. This
+// can be used by the associated conditions and actions.
+
+typedef struct {
+ int cbSize; // Set to sizeof(TRIGGERDATA)
+ int dFlags; // Indicate which members are valid using the DF_* flags (see
+ // above).
+ HANDLE hContact; // Associate a contact handle to this event.
+ char *szProto; // Associate a protocol ID to this event.
+ int status; // Associcate a status code to this event.
+ union {
+ char *szText; // Associate a string to this event.
+ TCHAR *tszText;
+ WCHAR *wszText;
+ };
+ LPARAM lParam; // Associate custom data to this trigger.
+} TRIGGERDATA;
+
+typedef struct {
+ int cbSize; // Set to sizeof(REPORTINFO).
+ DWORD triggerID; // The trigger ID of the event to trigger or 0 if this does
+ // not apply.
+ char *pszName; // The name of the trigger (this may be NULL if triggerID is
+ // not 0).
+ int flags; // On of the TRG_* flags, see below.
+ TRIGGERDATA *td; // Optional, the associated TriggerData, see above.
+} REPORTINFO;
+
+#define TRG_PERFORM 0x01 // Indicates the event for this trigger actually
+ // occured and needs to be processed accordingly.
+#define TRG_CLEANUP 0x02 // Indicates the trigger instructs to remove the
+ // itself and all associated information. This can
+ // be used for "one time triggers". Remove your own
+ // settings by yourself.
+
+// --------------------------------------------------------------------------
+// Actions
+// --------------------------------------------------------------------------
+
+// An actions might be performed as a reaction to a reported event by a
+// trigger. You first register your action so it can be associated to a
+// trigger in the options screen. Next, your provided service or function
+// will be called when necessary.
+
+#define MS_TRIGGER_REGISTERACTION "/TriggerPlugin/RegisterAction"
+
+// Parameters:
+// ------------------------
+// wParam = (WPARAM)0
+// lParam = (LPARAM)(ACTIONREGISTER *)&ar
+// Pointer to a structure describing the action to add (see below).
+
+// Return Value:
+// ------------------------
+// Returns 0 on success, nozero otherwise. Registering an already existing
+// action will replace this previously registered action.
+
+typedef int (* ACTIONFUNCTION)(DWORD actionID, REPORTINFO* ri);
+
+typedef struct {
+ int cbSize; // Set to sizeof(ACTIONREGISTER).
+ char *pszName; // The name of this action, it must be a unique string.
+ union {
+ char *pszService; // A service (called with wParam =
+ // (WPARAM)(DWORD)actionID, lParam =
+ // (LPARAM)(REPORTINFO *)&ri) or function to be called
+ // when the action has to be performed.
+ ACTIONFUNCTION actionFunction;
+ };
+ HINSTANCE hInstance; // Only needed when an options screen is available.
+ DLGPROC pfnDlgProc; // Optional, the callback procedure for the options
+ // dialog.
+ char *pszTemplate; // Optional, template for the options dialog, must be
+ // WS_CHILD.
+ int flags; // One of the ARF_* flags, see below.
+} ACTIONREGISTER;
+
+#define ARF_UNICODE 0x01 // This action processes unicode strings.
+#define ARF_FUNCTION 0x02 // The actionFunction will be called instead of
+ // the service.
+#define ARF_NOEXPORT 0x04 // This action cannot be exported. Set this flag in
+ // case you stored settings not using the helper
+ // functions at the end of this header. On export,
+ // TriggerPlugin will search for these settings
+ // and export them automatically. Contact-specific
+ // settings are never exported.
+
+#if defined(UNICODE) || defined(_UNICODE)
+#define ARF_TCHAR ARF_UNICODE
+#else
+#define ARF_TCHAR 0
+#endif
+
+// The service or actionFunction will be called with a pointer to a REPORTINFO
+// struct, containing information about the trigger event. If you can use
+// TriggerData from this struct, always check the ri->td->dFlags before using
+// it. It's up to you to deal with an action in case the expected TriggerData
+// is not available. It's recommened though, to cancel your action. The
+// ri->flags is a combination of the ACT_* flags, indicating how to process the
+// call, see below.
+
+#define ACT_PERFORM 0x01 // Your action is to be performed.
+#define ACT_CLEANUP 0x02 // The settings associated to this action should be
+ // removed.
+
+// Dialog Messages
+// The following messages are to be processed by the options dialog, if there
+// is one.
+
+// WM_INITDIALOG
+
+// Parameters:
+// ------------------------
+// lParam = (LPARAM)(DWORD)actionID
+// The action ID for which the options are to be set. This can be a new ID
+// or an ID of an action which is being edited. Initialize your options
+// dialog accordingly. There are helper function at the end of this header
+// file to read your settings for a certain action ID.
+
+#define TM_ADDACTION WM_APP+12
+
+// TM_ADDACTION
+// 'OK' is pressed and a new action will be added. Save your settings using
+// the given action ID. Helper functions can be found at the end of this
+// header file.
+
+// Parameters:
+// ------------------------
+// wParam = (WPARAM)(DWORD)actionID
+// The action ID for which the settings are to be saved. There are helper
+// functions at the end of this header file to store settings with a certain
+// action ID.
+// lParam = 0
+
+// Dialog Messages
+// You can send the following messages to the parent window of your dialog.
+// When initalizing your dialog, you might be interested in the TriggerData
+// the associated trigger is able to provide, you can do so by sending the
+// folowing message to the parent of your dialog.
+
+#define TM_GETTRIGGERINFO WM_APP+13
+
+// Parameters:
+// ------------------------
+// wParam = 0
+// lParam = (LPARAM)(TRIGGERINFO *)&ti
+
+// Return Value:
+// ------------------------
+// Returns 0 on success, the struct given will be filled with the requested
+// information. Returns any other value on error.
+
+typedef struct {
+ int cbSize; // (in) Set to sizeof(TRIGGERINFO).
+ int dFlags; // (out) The default DF_* flags used by the trigger (as indicated
+ // by its TRIGGERREGISTER).
+} TRIGGERINFO;
+
+// --------------------------------------------------------------------------
+// Conditions
+// --------------------------------------------------------------------------
+
+// Depending on the configuration of the user, a condition may need to hold
+// for an action to be performed. A condition function is called and its
+// return value specifies whether or not the condition holds. A condition
+// needs to be registered. After its registered, the condition function might
+// be called to check whether or not the condition holds.
+
+#define MS_TRIGGER_REGISTERCONDITION "/TriggerPlugin/RegisterCondition"
+
+// Parameters:
+// ------------------------
+// wParam = (WPARAM)0
+// lParam = (LPARAM)(CONDITIONREGISTER *)&cr
+// Pointer to a structure describing the condition to add (see below).
+
+// Return Value:
+// ------------------------
+// Returns 0 on success, nozero otherwise. Registering an already existing
+// condition will replace this previously registered condition.
+
+typedef int (* CONDITIONFUNCTION)(DWORD conditionID, REPORTINFO *ri);
+
+typedef struct {
+ int cbSize; // Set to sizeof(CONDITIONREGISTER).
+ char *pszName; // The name identifying this condition, must be unique.
+ union {
+ char *pszService; // The service (wParam = (WPARAM)(DWORD)conditionID,
+ // lParam = (LPARAM)(REPORTINFO *)&ri) or function which
+ // is called to see whether the condition holds. Must
+ // return CRV_TRUE if the condition holds, CRV_FALSE
+ // otherwise.
+ CONDITIONFUNCTION conditionFunction;
+ };
+ HINSTANCE hInstance; // Only needed when an options dialog is available.
+ DLGPROC pfnDlgProc; // Optional, the dialog procedure for the options
+ // dialog.
+ char *pszTemplate; // Optional, template for the options dialog, must be
+ // WS_CHILD.
+ int flags; // CRF_* flags, see below.
+} CONDITIONREGISTER;
+
+// The flags that can be used to register the condition.
+
+#define CRF_UNICODE 0x01 // The condition function or service processes
+ // unicode strings.
+#define CRF_FUNCTION 0x02 // The conditionFunction will be called instead of
+ // the service.
+#define CRF_NOEXPORT 0x04 // This condition cannot be exported. Set this flag
+ // in case you stored settings not using the helper
+ // functions at the end of this header. On export,
+ // TriggerPlugin will search for these settings
+ // and export them automatically. Contact-specific
+ // settings are never exported.
+
+#if defined(UNICODE) || defined(_UNICODE)
+#define CRF_TCHAR CRF_UNICODE
+#else
+#define CRF_TCHAR 0
+#endif
+
+// The service or conditionFunction will be called with a pointer to a
+// REPORTINFO struct, containing information about the trigger event. If you
+// can use TriggerData from this struct, always check the ri->td->dFlags before
+// using it. It's up to you to deal with an condition in case the expected
+// TriggerData is not available. It's recommened though, to return CRV_FALSE in
+// those cases. The ri->flags is a combination of the CND_* flags, indicating
+// how to process the call, see below.
+
+// Return values for the condition function or service. The condition service
+// or function is expected to return one of the following.
+
+#define CRV_FALSE 0 // The condition does not hold.
+#define CRV_TRUE 1 // The condition does hold.
+
+// REPORTINFO flags, received by the condition function or service. These
+// indicate how to process the call.
+
+#define CND_PERFORM 0x01 // Perform your condition and return either
+ // CRV_TRUE or CRV_FALSE to indicate whether or not
+ // your condition holds at this moment.
+#define CND_CLEANUP 0x02 // The condition is deleted. Remove your settings
+ // from the DB. There is a helper service below to
+ // easily remove settings given a condition ID.
+
+// Dialog Messages
+// The following messages are to be processed by the options dialog, if there
+// is one.
+
+// WM_INITDIALOG
+
+// Parameters:
+// ------------------------
+// lParam = (LPARAM)(DWORD)conditionID
+// The condition ID for which the options are to be set. This can be a new ID
+// or an ID of a condition which is being edited. Initialize your options
+// dialog accordingly. There are helper function at the end of this header
+// file to read your settings for a certain condition ID.
+
+#define TM_ADDCONDITION WM_APP+14
+
+// TM_ADDCONDITION
+// 'OK' is pressed and a new condition will be added. Save your settings using
+// the given condition ID. Helper functions can be found at the end of this
+// header file.
+
+// Parameters:
+// ------------------------
+// wParam = (WPARAM)(DWORD)conditionID
+// The condition ID for which the settings are to be saved. There are helper
+// functions at the end of this header file to store settings with a certain
+// condition ID.
+// lParam = 0
+
+// When initalizing your dialog, you might be interested in the TriggerData the
+// associated trigger is able to provide, you can find out by sending a
+// TM_GETTRIGGERINFO message to the parent of your dialog. See the section on
+// dialog messages for actions for more information (above).
+
+// --------------------------------------------------------------------------
+// Misc. Services
+// --------------------------------------------------------------------------
+
+#define MS_TRIGGER_ENABLETRIGGER "/TriggerPlugin/EnableTrigger"
+
+// Parameters:
+// ------------------------
+// wParam = (WPARAM)(DWORD)triggerID
+// The triggerID to set or get the state from or 0 for the global state.
+// lParam = (LPARAM)(int)type
+// One of ETT_* (see below).
+
+// Return Value:
+// ------------------------
+// Returns the state (0=disabled) if ETT_GETSTATE is given as lParam.
+// Otherwise, it returns 0 if setting the state was succesful or any other on
+// failure. The global state must be enabled if a single state is to be
+// changed.
+
+#define ETT_DISABLE 0 // Disable the trigger(s).
+#define ETT_ENABLE 1 // Enable the trigger(s).
+#define ETT_TOGGLE 2 // Toggle the state of the trigger(s).
+#define ETT_GETSTATE 3 // Retrieve the state of the trigger (0=disabled).
+
+#define ME_TRIGGER_TRIGGERENABLED "/TriggerPlugin/TriggerEnabled"
+
+// Parameters:
+// ------------------------
+// wParam = (WPARAM)(DWORD)triggerID
+// The triggerID to set or get the state from or 0 for the global state.
+// lParam = (LPARAM)(int)type
+// Either ETT_DISABLE or ETT_ENABLE describing the new state.
+
+// This event is fired when one or all of the triggers enabled state is
+// changed. This can be used to (de)initialize internal variables. For
+// example if your trigger reads the triggers from the DB in memory during
+// an initialization fase. It is recommended to do this when this event is
+// fired with wParam = 0 and lParam = ETT_ENABLE (remember triggers can be
+// imported, without calling your options screen callback). This event is
+// fired upon startup and shutdown in case the module is enabled.
+
+// --------------------------------------------------------------------------
+// Database Helper Services
+// --------------------------------------------------------------------------
+
+// The rest of this header file defines helper services and functions to easily
+// store and retrieve settings for a certain trigger, action or condition.
+
+#define MS_TRIGGER_REMOVESETTINGS "/TriggerPlugin/RemoveSettings"
+
+// Parameters:
+// ------------------------
+// wParam = (WPARAM)0
+// lParam = (LPARAM)(REMOVETRIGGERSETTINGS *)&rts
+// Pointer to a structure describing the settings to remove (see below).
+
+// Return Value:
+// ------------------------
+// Returns the number of settings removed from the database.
+
+// This service helps you remove all settings you have written with the DB
+// helper functions, defined at the end of this header file.
+
+typedef struct {
+ int cbSize; // Set to sizeof(REMOVETRIGGERSETTINGS).
+ char *prefix; // A string indicating what kind of setting are to be removed,
+ // see below.
+ DWORD id; // The ID of the set of settings to be removed.
+ char *szModule; // The module where the settings are stored.
+ HANDLE hContact; // The contact for which the setting are to be removed. Can
+ // be INVALID_HANDLE_VALUE to remove the settings for all
+ // contacts and NULL.
+} REMOVETRIGGERSETTINGS;
+
+// The following prefixes indicate what kind of settings are to be removed from
+// the database.
+
+#define PREFIX_ACTIONID "aid" // The prefix for a DB setting associated to
+ // an action.
+#define PREFIX_TRIGGERID "tid" // The prefix for a DB setting associated to
+ // a trigger.
+#define PREFIX_CONDITIONID "cid" // The prefix for a DB setting associated
+ // to a condition.
+
+#ifndef TRIGGER_NOHELPER
+
+// Helper #1: RemoveAllTriggerSettings
+// ------------------------
+// Remove all settings from the DB given the triggerID and module.
+
+static __inline int RemoveAllTriggerSettings(DWORD triggerID, char *szModule) {
+
+ REMOVETRIGGERSETTINGS rts;
+
+ rts.cbSize = sizeof(REMOVETRIGGERSETTINGS);
+ rts.prefix = PREFIX_TRIGGERID;
+ rts.id = triggerID;
+ rts.szModule = szModule;
+ rts.hContact = INVALID_HANDLE_VALUE;
+
+ return CallService(MS_TRIGGER_REMOVESETTINGS, 0, (LPARAM)&rts);
+}
+
+// Helper #2: RemoveAllActionSettings
+// ------------------------
+// Remove all settings from the DB given the actionID and module.
+
+static __inline int RemoveAllActionSettings(DWORD actionID, char *szModule) {
+
+ REMOVETRIGGERSETTINGS rts;
+
+ rts.cbSize = sizeof(REMOVETRIGGERSETTINGS);
+ rts.prefix = PREFIX_ACTIONID;
+ rts.id = actionID;
+ rts.szModule = szModule;
+ rts.hContact = INVALID_HANDLE_VALUE;
+
+ return CallService(MS_TRIGGER_REMOVESETTINGS, 0, (LPARAM)&rts);
+}
+
+// Helper #1: RemoveAllConditionSettings
+// ------------------------
+// Remove all settings from the DB given the conditionID and module.
+
+static __inline int RemoveAllConditionSettings(DWORD conditionID, char *szModule) {
+
+ REMOVETRIGGERSETTINGS rts;
+
+ rts.cbSize = sizeof(REMOVETRIGGERSETTINGS);
+ rts.prefix = PREFIX_CONDITIONID;
+ rts.id = conditionID;
+ rts.szModule = szModule;
+ rts.hContact = INVALID_HANDLE_VALUE;
+
+ return CallService(MS_TRIGGER_REMOVESETTINGS, 0, (LPARAM)&rts);
+}
+
+// --------------------------------------------------------------------------
+// Database Helper Functions
+// --------------------------------------------------------------------------
+
+// Basically, these function work the same as Miranda's helper functions for
+// getting/setting DB settings. There is one extra parameter, the ID for the
+// trigger/action/condition. The settings are named as follows:
+
+// DBWriteTriggerSetting*(DWORD triggerID, ...) to write a setting given a
+// trigger ID.
+// DBGetTriggerSetting*(DWORD triggerID, ...) to read a setting given a
+// trigger ID.
+// DBWriteActionSetting*(DWORD actionID, ...) to write a setting given an
+// action ID.
+// DBGetActionSetting*(DWORD actionID, ...) to read a setting given an
+// action ID.
+// DBWriteConditionSetting*(DWORD conditionID, ...) to write a setting given a
+// condition ID.
+// DBGetConditionSetting*(DWORD conditionID, ...) to read a setting given a
+// condition ID.
+
+#define MAX_SETTING_LEN 255 // Max. length of a DB setting including the
+ // prefix and ID.
+
+// --------------------------------------------------------------------------
+// Database Helper Functions: Triggers
+// --------------------------------------------------------------------------
+
+static int __inline DBWriteTriggerSettingByte(DWORD triggerID, HANDLE hContact,const char *szModule,const char *szSetting,BYTE val) {
+
+ char dbSetting[MAX_SETTING_LEN];
+
+ mir_snprintf(dbSetting, sizeof(dbSetting), "%s%u_%s", PREFIX_TRIGGERID, triggerID, szSetting);
+ return DBWriteContactSettingByte(hContact, szModule, dbSetting, val);
+}
+
+static int __inline DBWriteTriggerSettingWord(DWORD triggerID, HANDLE hContact,const char *szModule,const char *szSetting,WORD val) {
+
+ char dbSetting[MAX_SETTING_LEN];
+
+ mir_snprintf(dbSetting, sizeof(dbSetting), "%s%u_%s", PREFIX_TRIGGERID, triggerID, szSetting);
+ return DBWriteContactSettingWord(hContact, szModule, dbSetting, val);
+}
+
+static int __inline DBWriteTriggerSettingDword(DWORD triggerID, HANDLE hContact,const char *szModule,const char *szSetting,DWORD val) {
+
+ char dbSetting[MAX_SETTING_LEN];
+
+ mir_snprintf(dbSetting, sizeof(dbSetting), "%s%u_%s", PREFIX_TRIGGERID, triggerID, szSetting);
+ return DBWriteContactSettingDword(hContact, szModule, dbSetting, val);
+}
+
+static int __inline DBWriteTriggerSettingString(DWORD triggerID, HANDLE hContact,const char *szModule,const char *szSetting,const char *val) {
+
+ char dbSetting[MAX_SETTING_LEN];
+
+ mir_snprintf(dbSetting, sizeof(dbSetting), "%s%u_%s", PREFIX_TRIGGERID, triggerID, szSetting);
+ return DBWriteContactSettingString(hContact, szModule, dbSetting, val);
+}
+
+static int __inline DBWriteTriggerSettingTString(DWORD triggerID, HANDLE hContact,const char *szModule,const char *szSetting,const TCHAR *val) {
+
+ char dbSetting[MAX_SETTING_LEN];
+
+ mir_snprintf(dbSetting, sizeof(dbSetting), "%s%u_%s", PREFIX_TRIGGERID, triggerID, szSetting);
+ return DBWriteContactSettingTString(hContact, szModule, dbSetting, val);
+}
+
+static int __inline DBWriteTriggerSettingWString(DWORD triggerID, HANDLE hContact,const char *szModule,const char *szSetting,const WCHAR *val) {
+
+ char dbSetting[MAX_SETTING_LEN];
+
+ mir_snprintf(dbSetting, sizeof(dbSetting), "%s%u_%s", PREFIX_TRIGGERID, triggerID, szSetting);
+ return DBWriteContactSettingWString(hContact, szModule, dbSetting, val);
+}
+
+static int __inline DBWriteTriggerSettingStringUtf(DWORD triggerID, HANDLE hContact,const char *szModule,const char *szSetting,const char *val) {
+
+ char dbSetting[MAX_SETTING_LEN];
+
+ mir_snprintf(dbSetting, sizeof(dbSetting), "%s%u_%s", PREFIX_TRIGGERID, triggerID, szSetting);
+ return DBWriteContactSettingStringUtf(hContact, szModule, dbSetting, val);
+}
+
+static int __inline DBGetTriggerSettingByte(DWORD triggerID, HANDLE hContact, const char *szModule, const char *szSetting, int errorValue) {
+
+
+ char dbSetting[MAX_SETTING_LEN];
+
+ mir_snprintf(dbSetting, sizeof(dbSetting), "%s%u_%s", PREFIX_TRIGGERID, triggerID, szSetting);
+ return DBGetContactSettingByte(hContact, szModule, dbSetting, errorValue);
+}
+
+static WORD __inline DBGetTriggerSettingWord(DWORD triggerID, HANDLE hContact, const char *szModule, const char *szSetting, int errorValue) {
+
+
+ char dbSetting[MAX_SETTING_LEN];
+
+ mir_snprintf(dbSetting, sizeof(dbSetting), "%s%u_%s", PREFIX_TRIGGERID, triggerID, szSetting);
+ return DBGetContactSettingWord(hContact, szModule, dbSetting, errorValue);
+}
+
+static DWORD __inline DBGetTriggerSettingDword(DWORD triggerID, HANDLE hContact, const char *szModule, const char *szSetting, int errorValue) {
+
+
+ char dbSetting[MAX_SETTING_LEN];
+
+ mir_snprintf(dbSetting, sizeof(dbSetting), "%s%u_%s", PREFIX_TRIGGERID, triggerID, szSetting);
+ return DBGetContactSettingDword(hContact, szModule, dbSetting, errorValue);
+}
+
+static int __inline DBGetTriggerSetting(DWORD triggerID, HANDLE hContact, const char *szModule, const char *szSetting, DBVARIANT *dbv) {
+
+
+ char dbSetting[MAX_SETTING_LEN];
+
+ mir_snprintf(dbSetting, sizeof(dbSetting), "%s%u_%s", PREFIX_TRIGGERID, triggerID, szSetting);
+ return DBGetContactSetting(hContact, szModule, dbSetting, dbv);
+}
+
+static int __inline DBGetTriggerSettingW(DWORD triggerID, HANDLE hContact,const char *szModule, const char *szSetting,DBVARIANT *dbv) {
+
+ char dbSetting[MAX_SETTING_LEN];
+
+ mir_snprintf(dbSetting, sizeof(dbSetting), "%s%u_%s", PREFIX_TRIGGERID, triggerID, szSetting);
+ return DBGetContactSettingW(hContact, szModule, dbSetting, dbv);
+}
+
+static int __inline DBGetTriggerSettingTString(DWORD triggerID, HANDLE hContact,const char *szModule, const char *szSetting,DBVARIANT *dbv) {
+
+ char dbSetting[MAX_SETTING_LEN];
+
+ mir_snprintf(dbSetting, sizeof(dbSetting), "%s%u_%s", PREFIX_TRIGGERID, triggerID, szSetting);
+ return DBGetContactSettingTString(hContact, szModule, dbSetting, dbv);
+}
+
+static int __inline DBGetTriggerSettingWString(DWORD triggerID, HANDLE hContact,const char *szModule, const char *szSetting,DBVARIANT *dbv) {
+
+ char dbSetting[MAX_SETTING_LEN];
+
+ mir_snprintf(dbSetting, sizeof(dbSetting), "%s%u_%s", PREFIX_TRIGGERID, triggerID, szSetting);
+ return DBGetContactSettingWString(hContact, szModule, dbSetting, dbv);
+}
+
+static int __inline DBGetTriggerSettingStringUtf(DWORD triggerID, HANDLE hContact,const char *szModule, const char *szSetting,DBVARIANT *dbv) {
+
+ char dbSetting[MAX_SETTING_LEN];
+
+ mir_snprintf(dbSetting, sizeof(dbSetting), "%s%u_%s", PREFIX_TRIGGERID, triggerID, szSetting);
+ return DBGetContactSettingStringUtf(hContact, szModule, dbSetting, dbv);
+}
+
+static int __inline DBDeleteTriggerSetting(DWORD triggerID, HANDLE hContact,const char *szModule,const char *szSetting) {
+
+ char dbSetting[MAX_SETTING_LEN];
+
+ mir_snprintf(dbSetting, sizeof(dbSetting), "%s%u_%s", PREFIX_TRIGGERID, triggerID, szSetting);
+ return DBDeleteContactSetting(hContact, szModule, dbSetting);
+}
+
+// --------------------------------------------------------------------------
+// Database Helper Functions: Actions
+// --------------------------------------------------------------------------
+
+static int __inline DBWriteActionSettingByte(DWORD actionID, HANDLE hContact,const char *szModule,const char *szSetting,BYTE val) {
+
+ char dbSetting[MAX_SETTING_LEN];
+
+ mir_snprintf(dbSetting, sizeof(dbSetting), "%s%u_%s", PREFIX_ACTIONID, actionID, szSetting);
+ return DBWriteContactSettingByte(hContact, szModule, dbSetting, val);
+}
+
+static int __inline DBWriteActionSettingWord(DWORD actionID, HANDLE hContact,const char *szModule,const char *szSetting,WORD val) {
+
+ char dbSetting[MAX_SETTING_LEN];
+
+ mir_snprintf(dbSetting, sizeof(dbSetting), "%s%u_%s", PREFIX_ACTIONID, actionID, szSetting);
+ return DBWriteContactSettingWord(hContact, szModule, dbSetting, val);
+}
+
+static int __inline DBWriteActionSettingDword(DWORD actionID, HANDLE hContact,const char *szModule,const char *szSetting,DWORD val) {
+
+ char dbSetting[MAX_SETTING_LEN];
+
+ mir_snprintf(dbSetting, sizeof(dbSetting), "%s%u_%s", PREFIX_ACTIONID, actionID, szSetting);
+ return DBWriteContactSettingDword(hContact, szModule, dbSetting, val);
+}
+
+static int __inline DBWriteActionSettingString(DWORD actionID, HANDLE hContact,const char *szModule,const char *szSetting,const char *val) {
+
+ char dbSetting[MAX_SETTING_LEN];
+
+ mir_snprintf(dbSetting, sizeof(dbSetting), "%s%u_%s", PREFIX_ACTIONID, actionID, szSetting);
+ return DBWriteContactSettingString(hContact, szModule, dbSetting, val);
+}
+
+static int __inline DBWriteActionSettingTString(DWORD actionID, HANDLE hContact,const char *szModule,const char *szSetting,const TCHAR *val) {
+
+ char dbSetting[MAX_SETTING_LEN];
+
+ mir_snprintf(dbSetting, sizeof(dbSetting), "%s%u_%s", PREFIX_ACTIONID, actionID, szSetting);
+ return DBWriteContactSettingTString(hContact, szModule, dbSetting, val);
+}
+
+static int __inline DBWriteActionSettingWString(DWORD actionID, HANDLE hContact,const char *szModule,const char *szSetting,const WCHAR *val) {
+
+ char dbSetting[MAX_SETTING_LEN];
+
+ mir_snprintf(dbSetting, sizeof(dbSetting), "%s%u_%s", PREFIX_ACTIONID, actionID, szSetting);
+ return DBWriteContactSettingWString(hContact, szModule, dbSetting, val);
+}
+
+static int __inline DBWriteActionSettingStringUtf(DWORD actionID, HANDLE hContact,const char *szModule,const char *szSetting,const char *val) {
+
+ char dbSetting[MAX_SETTING_LEN];
+
+ mir_snprintf(dbSetting, sizeof(dbSetting), "%s%u_%s", PREFIX_ACTIONID, actionID, szSetting);
+ return DBWriteContactSettingStringUtf(hContact, szModule, dbSetting, val);
+}
+
+static int __inline DBGetActionSettingByte(DWORD actionID, HANDLE hContact, const char *szModule, const char *szSetting, int errorValue) {
+
+
+ char dbSetting[MAX_SETTING_LEN];
+
+ mir_snprintf(dbSetting, sizeof(dbSetting), "%s%u_%s", PREFIX_ACTIONID, actionID, szSetting);
+ return DBGetContactSettingByte(hContact, szModule, dbSetting, errorValue);
+}
+
+static WORD __inline DBGetActionSettingWord(DWORD actionID, HANDLE hContact, const char *szModule, const char *szSetting, int errorValue) {
+
+
+ char dbSetting[MAX_SETTING_LEN];
+
+ mir_snprintf(dbSetting, sizeof(dbSetting), "%s%u_%s", PREFIX_ACTIONID, actionID, szSetting);
+ return DBGetContactSettingWord(hContact, szModule, dbSetting, errorValue);
+}
+
+static DWORD __inline DBGetActionSettingDword(DWORD actionID, HANDLE hContact, const char *szModule, const char *szSetting, int errorValue) {
+
+
+ char dbSetting[MAX_SETTING_LEN];
+
+ mir_snprintf(dbSetting, sizeof(dbSetting), "%s%u_%s", PREFIX_ACTIONID, actionID, szSetting);
+ return DBGetContactSettingDword(hContact, szModule, dbSetting, errorValue);
+}
+
+static int __inline DBGetActionSetting(DWORD actionID, HANDLE hContact, const char *szModule, const char *szSetting, DBVARIANT *dbv) {
+
+
+ char dbSetting[MAX_SETTING_LEN];
+
+ mir_snprintf(dbSetting, sizeof(dbSetting), "%s%u_%s", PREFIX_ACTIONID, actionID, szSetting);
+ return DBGetContactSetting(hContact, szModule, dbSetting, dbv);
+}
+
+static int __inline DBGetActionSettingW(DWORD actionID, HANDLE hContact,const char *szModule, const char *szSetting,DBVARIANT *dbv) {
+
+ char dbSetting[MAX_SETTING_LEN];
+
+ mir_snprintf(dbSetting, sizeof(dbSetting), "%s%u_%s", PREFIX_ACTIONID, actionID, szSetting);
+ return DBGetContactSettingW(hContact, szModule, dbSetting, dbv);
+}
+
+static int __inline DBGetActionSettingTString(DWORD actionID, HANDLE hContact,const char *szModule, const char *szSetting,DBVARIANT *dbv) {
+
+ char dbSetting[MAX_SETTING_LEN];
+
+ mir_snprintf(dbSetting, sizeof(dbSetting), "%s%u_%s", PREFIX_ACTIONID, actionID, szSetting);
+ return DBGetContactSettingTString(hContact, szModule, dbSetting, dbv);
+}
+
+static int __inline DBGetActionSettingWString(DWORD actionID, HANDLE hContact,const char *szModule, const char *szSetting,DBVARIANT *dbv) {
+
+ char dbSetting[MAX_SETTING_LEN];
+
+ mir_snprintf(dbSetting, sizeof(dbSetting), "%s%u_%s", PREFIX_ACTIONID, actionID, szSetting);
+ return DBGetContactSettingWString(hContact, szModule, dbSetting, dbv);
+}
+
+static int __inline DBGetActionSettingStringUtf(DWORD actionID, HANDLE hContact,const char *szModule, const char *szSetting,DBVARIANT *dbv) {
+
+ char dbSetting[MAX_SETTING_LEN];
+
+ mir_snprintf(dbSetting, sizeof(dbSetting), "%s%u_%s", PREFIX_ACTIONID, actionID, szSetting);
+ return DBGetContactSettingStringUtf(hContact, szModule, dbSetting, dbv);
+}
+
+static int __inline DBDeleteActionSetting(DWORD actionID, HANDLE hContact,const char *szModule,const char *szSetting) {
+
+ char dbSetting[MAX_SETTING_LEN];
+
+ mir_snprintf(dbSetting, sizeof(dbSetting), "%s%u_%s", PREFIX_ACTIONID, actionID, szSetting);
+ return DBDeleteContactSetting(hContact, szModule, dbSetting);
+}
+
+// --------------------------------------------------------------------------
+// Database Helper Functions: Conditions
+// --------------------------------------------------------------------------
+
+static int __inline DBWriteConditionSettingByte(DWORD conditionID, HANDLE hContact,const char *szModule,const char *szSetting,BYTE val) {
+
+ char dbSetting[MAX_SETTING_LEN];
+
+ mir_snprintf(dbSetting, sizeof(dbSetting), "%s%u_%s", PREFIX_CONDITIONID, conditionID, szSetting);
+ return DBWriteContactSettingByte(hContact, szModule, dbSetting, val);
+}
+
+static int __inline DBWriteConditionSettingWord(DWORD conditionID, HANDLE hContact,const char *szModule,const char *szSetting,WORD val) {
+
+ char dbSetting[MAX_SETTING_LEN];
+
+ mir_snprintf(dbSetting, sizeof(dbSetting), "%s%u_%s", PREFIX_CONDITIONID, conditionID, szSetting);
+ return DBWriteContactSettingWord(hContact, szModule, dbSetting, val);
+}
+
+static int __inline DBWriteConditionSettingDword(DWORD conditionID, HANDLE hContact,const char *szModule,const char *szSetting,DWORD val) {
+
+ char dbSetting[MAX_SETTING_LEN];
+
+ mir_snprintf(dbSetting, sizeof(dbSetting), "%s%u_%s", PREFIX_CONDITIONID, conditionID, szSetting);
+ return DBWriteContactSettingDword(hContact, szModule, dbSetting, val);
+}
+
+static int __inline DBWriteConditionSettingString(DWORD conditionID, HANDLE hContact,const char *szModule,const char *szSetting,const char *val) {
+
+ char dbSetting[MAX_SETTING_LEN];
+
+ mir_snprintf(dbSetting, sizeof(dbSetting), "%s%u_%s", PREFIX_CONDITIONID, conditionID, szSetting);
+ return DBWriteContactSettingString(hContact, szModule, dbSetting, val);
+}
+
+static int __inline DBWriteConditionSettingTString(DWORD conditionID, HANDLE hContact,const char *szModule,const char *szSetting,const TCHAR *val) {
+
+ char dbSetting[MAX_SETTING_LEN];
+
+ mir_snprintf(dbSetting, sizeof(dbSetting), "%s%u_%s", PREFIX_CONDITIONID, conditionID, szSetting);
+ return DBWriteContactSettingTString(hContact, szModule, dbSetting, val);
+}
+
+static int __inline DBWriteConditionSettingWString(DWORD conditionID, HANDLE hContact,const char *szModule,const char *szSetting,const WCHAR *val) {
+
+ char dbSetting[MAX_SETTING_LEN];
+
+ mir_snprintf(dbSetting, sizeof(dbSetting), "%s%u_%s", PREFIX_CONDITIONID, conditionID, szSetting);
+ return DBWriteContactSettingWString(hContact, szModule, dbSetting, val);
+}
+
+static int __inline DBWriteConditionSettingStringUtf(DWORD conditionID, HANDLE hContact,const char *szModule,const char *szSetting,const char *val) {
+
+ char dbSetting[MAX_SETTING_LEN];
+
+ mir_snprintf(dbSetting, sizeof(dbSetting), "%s%u_%s", PREFIX_CONDITIONID, conditionID, szSetting);
+ return DBWriteContactSettingStringUtf(hContact, szModule, dbSetting, val);
+}
+
+static int __inline DBGetConditionSettingByte(DWORD conditionID, HANDLE hContact, const char *szModule, const char *szSetting, int errorValue) {
+
+
+ char dbSetting[MAX_SETTING_LEN];
+
+ mir_snprintf(dbSetting, sizeof(dbSetting), "%s%u_%s", PREFIX_CONDITIONID, conditionID, szSetting);
+ return DBGetContactSettingByte(hContact, szModule, dbSetting, errorValue);
+}
+
+static WORD __inline DBGetConditionSettingWord(DWORD conditionID, HANDLE hContact, const char *szModule, const char *szSetting, int errorValue) {
+
+
+ char dbSetting[MAX_SETTING_LEN];
+
+ mir_snprintf(dbSetting, sizeof(dbSetting), "%s%u_%s", PREFIX_CONDITIONID, conditionID, szSetting);
+ return DBGetContactSettingWord(hContact, szModule, dbSetting, errorValue);
+}
+
+static DWORD __inline DBGetConditionSettingDword(DWORD conditionID, HANDLE hContact, const char *szModule, const char *szSetting, int errorValue) {
+
+
+ char dbSetting[MAX_SETTING_LEN];
+
+ mir_snprintf(dbSetting, sizeof(dbSetting), "%s%u_%s", PREFIX_CONDITIONID, conditionID, szSetting);
+ return DBGetContactSettingDword(hContact, szModule, dbSetting, errorValue);
+}
+
+static int __inline DBGetConditionSetting(DWORD conditionID, HANDLE hContact, const char *szModule, const char *szSetting, DBVARIANT *dbv) {
+
+
+ char dbSetting[MAX_SETTING_LEN];
+
+ mir_snprintf(dbSetting, sizeof(dbSetting), "%s%u_%s", PREFIX_CONDITIONID, conditionID, szSetting);
+ return DBGetContactSetting(hContact, szModule, dbSetting, dbv);
+}
+
+static int __inline DBGetConditionSettingW(DWORD conditionID, HANDLE hContact,const char *szModule, const char *szSetting,DBVARIANT *dbv) {
+
+ char dbSetting[MAX_SETTING_LEN];
+
+ mir_snprintf(dbSetting, sizeof(dbSetting), "%s%u_%s", PREFIX_CONDITIONID, conditionID, szSetting);
+ return DBGetContactSettingW(hContact, szModule, dbSetting, dbv);
+}
+
+static int __inline DBGetConditionSettingTString(DWORD conditionID, HANDLE hContact,const char *szModule, const char *szSetting,DBVARIANT *dbv) {
+
+ char dbSetting[MAX_SETTING_LEN];
+
+ mir_snprintf(dbSetting, sizeof(dbSetting), "%s%u_%s", PREFIX_CONDITIONID, conditionID, szSetting);
+ return DBGetContactSettingTString(hContact, szModule, dbSetting, dbv);
+}
+
+static int __inline DBGetConditionSettingWString(DWORD conditionID, HANDLE hContact,const char *szModule, const char *szSetting,DBVARIANT *dbv) {
+
+ char dbSetting[MAX_SETTING_LEN];
+
+ mir_snprintf(dbSetting, sizeof(dbSetting), "%s%u_%s", PREFIX_CONDITIONID, conditionID, szSetting);
+ return DBGetContactSettingWString(hContact, szModule, dbSetting, dbv);
+}
+
+static int __inline DBGetConditionSettingStringUtf(DWORD conditionID, HANDLE hContact,const char *szModule, const char *szSetting,DBVARIANT *dbv) {
+
+ char dbSetting[MAX_SETTING_LEN];
+
+ mir_snprintf(dbSetting, sizeof(dbSetting), "%s%u_%s", PREFIX_CONDITIONID, conditionID, szSetting);
+ return DBGetContactSettingStringUtf(hContact, szModule, dbSetting, dbv);
+}
+
+static int __inline DBDeleteConditionSetting(DWORD conditionID, HANDLE hContact,const char *szModule,const char *szSetting) {
+
+ char dbSetting[MAX_SETTING_LEN];
+
+ mir_snprintf(dbSetting, sizeof(dbSetting), "%s%u_%s", PREFIX_CONDITIONID, conditionID, szSetting);
+ return DBDeleteContactSetting(hContact, szModule, dbSetting);
+}
+
+#endif // nohelper
+#endif // m_trigger
diff --git a/plugins/tipper/m_updater.h b/plugins/tipper/m_updater.h
new file mode 100644
index 0000000000..488d3722ce
--- /dev/null
+++ b/plugins/tipper/m_updater.h
@@ -0,0 +1,150 @@
+#ifndef _M_UPDATER_H
+#define _M_UPDATER_H
+
+// NOTES:
+// - For langpack updates, include a string of the following format in the langpack text file:
+// ";FLID: <file listing name> <version>"
+// version must be four numbers seperated by '.', in the range 0-255 inclusive
+// - Updater will disable plugins that are downloaded but were not active prior to the update (this is so that, if an archive contains e.g. ansi and
+// unicode versions, the correct plugin will be the only one active after the new version is installed)...so if you add a support plugin, you may need
+// to install an ini file to make the plugin activate when miranda restarts after the update
+// - Updater will replace all dlls that have the same internal shortName as a downloaded update dll (this is so that msn1.dll and msn2.dll, for example,
+// will both be updated) - so if you have a unicode and a non-unicode version of a plugin in your archive, you should make the internal names different (which will break automatic
+// updates from the file listing if there is only one file listing entry for both versions, unless you use the 'MS_UPDATE_REGISTER' service below)
+// - Updater will install all files in the root of the archive into the plugins folder, except for langpack files that contain the FLID string which go into the root folder (same
+// folder as miranda32.exe)...all folders in the archive will also be copied to miranda's root folder, and their contents transferred into the new folders. The only exception is a
+// special folder called 'root_files' - if there is a folder by that name in the archive, it's contents will also be copied into miranda's root folder - this is intended to be used
+// to install additional dlls etc that a plugin may require)
+
+// if you set Update.szUpdateURL to the following value when registering, as well as setting your beta site and version data,
+// Updater will ignore szVersionURL and pbVersionPrefix, and attempt to find the file listing URL's from the backend XML data.
+// for this to work, the plugin name in pluginInfo.shortName must match the file listing exactly (except for case)
+#define UPDATER_AUTOREGISTER "UpdaterAUTOREGISTER"
+// Updater will also use the backend xml data if you provide URL's that reference the miranda file listing for updates (so you can use that method
+// if e.g. your plugin shortName does not match the file listing) - it will grab the file listing id from the end of these URLs
+
+typedef struct Update_tag {
+ int cbSize;
+ char *szComponentName; // component name as it will appear in the UI (will be translated before displaying)
+
+ char *szVersionURL; // URL where the current version can be found (NULL to disable)
+ BYTE *pbVersionPrefix; // bytes occuring in VersionURL before the version, used to locate the version information within the URL data
+ // (note that this URL could point at a binary file - dunno why, but it could :)
+ int cpbVersionPrefix; // number of bytes pointed to by pbVersionPrefix
+ char *szUpdateURL; // URL where dll/zip is located
+ // set to UPDATER_AUTOREGISTER if you want Updater to find the file listing URLs (ensure plugin shortName matches file listing!)
+
+ char *szBetaVersionURL; // URL where the beta version can be found (NULL to disable betas)
+ BYTE *pbBetaVersionPrefix; // bytes occuring in VersionURL before the version, used to locate the version information within the URL data
+ int cpbBetaVersionPrefix; // number of bytes pointed to by pbVersionPrefix
+ char *szBetaUpdateURL; // URL where dll/zip is located
+
+ BYTE *pbVersion; // bytes of current version, used for comparison with those in VersionURL
+ int cpbVersion; // number of bytes pointed to by pbVersion
+
+ char *szBetaChangelogURL; // url for displaying changelog for beta versions
+} Update;
+
+// register a comonent with Updater
+//
+// wparam = 0
+// lparam = (LPARAM)&Update
+#define MS_UPDATE_REGISTER "Update/Register"
+
+// utility functions to create a version string from a DWORD or from pluginInfo
+// point buf at a buffer at least 16 chars wide - but note the version string returned may be shorter
+//
+__inline static char *CreateVersionString(DWORD version, char *buf) {
+ mir_snprintf(buf, 16, "%d.%d.%d.%d", (version >> 24) & 0xFF, (version >> 16) & 0xFF, (version >> 8) & 0xFF, version & 0xFF);
+ return buf;
+}
+
+__inline static char *CreateVersionStringPlugin(PLUGININFO *pluginInfo, char *buf) {
+ return CreateVersionString(pluginInfo->version, buf);
+}
+
+__inline static char *CreateVersionStringPluginEx(PLUGININFOEX *pluginInfo, char *buf) {
+ return CreateVersionString(pluginInfo->version, buf);
+}
+
+
+// register the 'easy' way - use this method if you have no beta URL and the plugin is on the miranda file listing
+// NOTE: the plugin version string on the file listing must be the string version of the version in pluginInfo (i.e. 0.0.0.1,
+// four numbers between 0 and 255 inclusivem, so no letters, brackets, etc.)
+//
+// wParam = (int)fileID - this is the file ID from the file listing (i.e. the number at the end of the download link)
+// lParam = (PLUGININFO*)&pluginInfo
+#define MS_UPDATE_REGISTERFL "Update/RegisterFL"
+
+// this function can be used to 'unregister' components - useful for plugins that register non-plugin/langpack components and
+// may need to change those components on the fly
+// lParam = (char *)szComponentName
+#define MS_UPDATE_UNREGISTER "Update/Unregister"
+
+// this event is fired when the startup process is complete, but NOT if a restart is imminent
+// it is designed for status managment plugins to use as a trigger for beggining their own startup process
+// wParam = lParam = 0 (unused)
+// (added in version 0.1.6.0)
+#define ME_UPDATE_STARTUPDONE "Update/StartupDone"
+
+// this service can be used to enable/disable Updater's global status control
+// it can be called from the StartupDone event handler
+// wParam = (BOOL)enable
+// lParam = 0
+// (added in version 0.1.6.0)
+#define MS_UPDATE_ENABLESTATUSCONTROL "Update/EnableStatusControl"
+
+// An description of usage of the above service and event:
+// Say you are a status control plugin that normally sets protocol or global statuses in your ModulesLoaded event handler.
+// In order to make yourself 'Updater compatible', you would move the status control code from ModulesLoaded to another function,
+// say DoStartup. Then, in ModulesLoaded you would check for the existence of the MS_UPDATE_ENABLESTATUSCONTROL service.
+// If it does not exist, call DoStartup. If it does exist, hook the ME_UPDATE_STARTUPDONE event and call DoStartup from there. You may
+// also wish to call MS_UPDATE_ENABLESTATUSCONTROL with wParam == FALSE at this time, to disable Updater's own status control feature.
+
+// this service can be used to determine whether updates are possible for a component with the given name
+// wParam = 0
+// lParam = (char *)szComponentName
+// returns TRUE if updates are supported, FALSE otherwise
+#define MS_UPDATE_ISUPDATESUPPORTED "Update/IsUpdateSupported"
+
+#endif
+
+
+/////////////// Usage Example ///////////////
+
+#ifdef EXAMPLE_CODE
+
+// you need to #include "m_updater.h" and HookEvent(ME_SYSTEM_MODULESLOADED, OnModulesLoaded) in your Load function...
+
+int OnModulesLoaded(WPARAM wParam, LPARAM lParam) {
+
+ Update update = {0}; // for c you'd use memset or ZeroMemory...
+ char szVersion[16];
+
+ update.cbSize = sizeof(Update);
+
+ update.szComponentName = pluginInfo.shortName;
+ update.pbVersion = (BYTE *)CreateVersionString(&pluginInfo, szVersion);
+ update.cpbVersion = strlen((char *)update.pbVersion);
+
+ // these are the three lines that matter - the archive, the page containing the version string, and the text (or data)
+ // before the version that we use to locate it on the page
+ // (note that if the update URL and the version URL point to standard file listing entries, the backend xml
+ // data will be used to check for updates rather than the actual web page - this is not true for beta urls)
+ update.szUpdateURL = "http://scottellis.com.au:81/test/updater.zip";
+ update.szVersionURL = "http://scottellis.com.au:81/test/updater_test.html";
+ update.pbVersionPrefix = (BYTE *)"Updater version ";
+
+ update.cpbVersionPrefix = strlen((char *)update.pbVersionPrefix);
+
+ // do the same for the beta versions of the above struct members if you wish to allow beta updates from another URL
+
+ CallService(MS_UPDATE_REGISTER, 0, (WPARAM)&update);
+
+ // Alternatively, to register a plugin with e.g. file ID 2254 on the file listing...
+ // CallService(MS_UPDATE_REGISTERFL, (WPARAM)2254, (LPARAM)&pluginInfo);
+
+ return 0;
+}
+
+#endif
diff --git a/plugins/tipper/m_variables.h b/plugins/tipper/m_variables.h
new file mode 100644
index 0000000000..152994dbbc
--- /dev/null
+++ b/plugins/tipper/m_variables.h
@@ -0,0 +1,668 @@
+/*
+ Variables Plugin for Miranda-IM (www.miranda-im.org)
+ Copyright 2003-2006 P. Boon
+
+ 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 __M_VARS
+#define __M_VARS
+
+#if !defined(_TCHAR_DEFINED)
+#include <tchar.h>
+#endif
+
+#ifndef VARIABLES_NOHELPER
+#include <m_button.h>
+#endif
+
+// --------------------------------------------------------------------------
+// Memory management
+// --------------------------------------------------------------------------
+
+// Release memory that was allocated by the Variables plugin, e.g. returned
+// strings.
+
+#define MS_VARS_FREEMEMORY "Vars/FreeMemory"
+
+// Parameters:
+// ------------------------
+// wParam = (WPARAM)(void *)pntr
+// Pointer to memory that was allocated by the Variables plugin (e.g. a
+// returned string) (can be NULL).
+// lParam = 0
+
+// Return Value:
+// ------------------------
+// Does return 0 on success, nozero otherwise.
+
+// Note: Do only use this service to free memory that was *explicitliy*
+// stated that it should be free with this service.
+
+
+
+#define MS_VARS_GET_MMI "Vars/GetMMI"
+
+// Get Variable's RTL/CRT function poiners to malloc(), free() and
+// realloc().
+
+// Parameters:
+// ------------------------
+// wParam = 0
+// lParam = (LPARAM) &MM_INTERFACE
+// Pointer to a memory manager interface struct (see m_system.h).
+
+// Return Value:
+// ------------------------
+// Returns 0 on success, nozero otherwise
+
+// Note: Works exactly the same as the MS_SYSTEM_GET_MMI service
+// service of m_system.h.
+
+// Helper function for easy using:
+#ifndef VARIABLES_NOHELPER
+__inline static void variables_free(void *pntr) {
+
+ CallService(MS_VARS_FREEMEMORY, (WPARAM)pntr, 0);
+}
+#endif
+
+
+
+// --------------------------------------------------------------------------
+// String formatting
+// --------------------------------------------------------------------------
+
+#define MS_VARS_FORMATSTRING "Vars/FormatString"
+
+// This service can be used to parse tokens in a text. The tokens will be
+// replaced by their resolved values. A token can either be a field or a
+// function. A field takes no arguments and is represented between
+// %-characters, e.g. "%winampsong%". A function can take any number of
+// arguments and is represented by a ? or !-character followed by the name
+// of the function and a list of arguments, e.g. "?add(1,2)".
+
+// Parameters:
+// ------------------------
+// wParam = (WPARAM)(FORMATINFO *)&fi
+// See below.
+// lParam = 0
+
+// Return Value:
+// ------------------------
+// Returns a pointer to the resolved string or NULL in case of an error.
+
+// Note: The returned pointer needs to be freed using MS_VARS_FREEMEMORY.
+
+typedef struct {
+ int cbSize; // Set this to sizeof(FORMATINFO).
+ int flags; // Flags to use (see FIF_* below).
+ union {
+ char *szFormat; // Text in which the tokens will be replaced (can't be
+ // NULL).
+ WCHAR *wszFormat;
+ TCHAR *tszFormat;
+ };
+ union {
+ char *szExtraText; // Extra, context-specific string (can be NULL) ->
+ // The field "extratext" will be replaced by this
+ // string. (Previously szSource).
+ WCHAR *wszExtraText;
+ TCHAR *tszExtraText;
+ };
+ HANDLE hContact; // Handle to contact (can be NULL) -> The field "subject"
+ // represents this contact.
+ int pCount; // (output) Number of succesful parsed tokens, needs to be set
+ // to 0 before the call
+ int eCount; // (output) Number of failed tokens, needs to be set to 0
+ // before the call
+} FORMATINFO;
+
+// Possible flags:
+#define FIF_UNICODE 0x01 // Expects and returns unicode text (WCHAR*).
+
+#if defined(UNICODE) || defined(_UNICODE)
+#define FIF_TCHAR FIF_UNICODE // Strings in structure are TCHAR*.
+#else
+#define FIF_TCHAR 0
+#endif
+
+// Helper functions for easy using:
+
+// Helper #1: variables_parse
+// ------------------------
+// The returned string needs to be freed using MS_VARS_FREEMEMORY.
+
+#ifndef VARIABLES_NOHELPER
+__inline static TCHAR *variables_parse(TCHAR *tszFormat, TCHAR *tszExtraText, HANDLE hContact) {
+
+ FORMATINFO fi;
+
+ ZeroMemory(&fi, sizeof(fi));
+ fi.cbSize = sizeof(fi);
+ fi.tszFormat = tszFormat;
+ fi.tszExtraText = tszExtraText;
+ fi.hContact = hContact;
+ fi.flags = FIF_TCHAR;
+
+ return (TCHAR *)CallService(MS_VARS_FORMATSTRING, (WPARAM)&fi, 0);
+}
+#endif
+
+// Helper #2: variables_parsedup
+// ------------------------
+// Returns a _strdup()'ed copy of the unparsed string when Variables is not
+// installed, returns a strdup()'ed copy of the parsed result otherwise.
+
+// Note: The returned pointer needs to be released using your own free().
+
+#ifndef VARIABLES_NOHELPER
+__inline static TCHAR *variables_parsedup(TCHAR *tszFormat, TCHAR *tszExtraText, HANDLE hContact) {
+
+ if (ServiceExists(MS_VARS_FORMATSTRING)) {
+ FORMATINFO fi;
+ TCHAR *tszParsed, *tszResult;
+
+ ZeroMemory(&fi, sizeof(fi));
+ fi.cbSize = sizeof(fi);
+ fi.tszFormat = tszFormat;
+ fi.tszExtraText = tszExtraText;
+ fi.hContact = hContact;
+ fi.flags |= FIF_TCHAR;
+ tszParsed = (TCHAR *)CallService(MS_VARS_FORMATSTRING, (WPARAM)&fi, 0);
+ if (tszParsed) {
+ tszResult = _tcsdup(tszParsed);
+ CallService(MS_VARS_FREEMEMORY, (WPARAM)tszParsed, 0);
+ return tszResult;
+ }
+ }
+ return tszFormat?_tcsdup(tszFormat):tszFormat;
+}
+#endif
+
+
+
+// --------------------------------------------------------------------------
+// Register tokens
+// --------------------------------------------------------------------------
+
+// Plugins can define tokens which will be parsed by the Variables plugin.
+
+#define MS_VARS_REGISTERTOKEN "Vars/RegisterToken"
+
+// With this service you can define your own token. The newly added tokens
+// using this service are taken into account on every call to
+// MS_VARS_FORMATSTRING.
+
+// Parameters:
+// ------------------------
+// wParam = 0
+// lParam = (LPARAM)(TOKENREGISTER*)&tr
+// See below.
+
+// Return Value:
+// ------------------------
+// Returns 0 on success, nonzero otherwise. Existing tokens will be
+// 'overwritten' if registered twice.
+
+// Needed for szService and parseFunction:
+typedef struct {
+ int cbSize; // You need to check if this is >=sizeof(ARGUMENTSINFO)
+ // (already filled in).
+ FORMATINFO *fi; // Arguments passed to MS_VARS_FORMATSTRING.
+ unsigned int argc; // Number of elements in the argv array.
+ union {
+ char **argv; // Argv[0] will be the token name, the following elements
+ // are the additional arguments.
+ WCHAR **wargv; // If the registered token was registered as a unicode
+ // token, wargv should be accessed.
+ TCHAR **targv;
+ };
+ int flags; // (output) You can set flags here (initially 0), use the
+ // AIF_* flags (see below).
+} ARGUMENTSINFO;
+
+// Available flags for ARGUMENTSINFO:
+// Set the flags of the ARGUMENTSINFO struct to any of these to influence
+// further parsing.
+#define AIF_DONTPARSE 0x01 // Don't parse the result of this function,
+ // usually the result of a token is parsed
+ // again, if the `?` is used as a function
+ // character.
+#define AIF_FALSE 0x02 // The function returned logical false.
+
+// Definition of parse/cleanup functions:
+typedef char* (*VARPARSEFUNCA)(ARGUMENTSINFO *ai);
+typedef WCHAR* (*VARPARSEFUNCW)(ARGUMENTSINFO *ai);
+typedef void (*VARCLEANUPFUNCA)(char *szReturn);
+typedef void (*VARCLEANUPFUNCW)(WCHAR *wszReturn);
+
+#if defined(UNICODE) || defined(_UNICODE)
+#define VARPARSEFUNC VARPARSEFUNCW
+#define VARCLEANUPFUNC VARCLEANUPFUNCW
+#else
+#define VARPARSEFUNC VARPARSEFUNCA
+#define VARCLEANUPFUNC VARCLEANUPFUNCA
+#endif
+
+typedef struct {
+ int cbSize; // Set this to sizeof(TOKENREGISTER).
+ union {
+ char *szTokenString; // Name of the new token to be created, without %,
+ // ?, ! etc. signs (can't be NULL).
+ WCHAR *wszTokenString;
+ TCHAR *tszTokenString;
+ };
+ union {
+ char *szService; // Name of a service that is used to request the
+ // token's value, if no service is used, a function
+ // and TRF_PARSEFUNC must be used.
+ VARPARSEFUNCA parseFunction; // See above, use with TRF_PARSEFUNC.
+ VARPARSEFUNCW parseFunctionW;
+ VARPARSEFUNC parseFunctionT;
+ };
+ union {
+ char *szCleanupService; // Name of a service to be called when the
+ // memory allocated in szService can be freed
+ // (only used when flag VRF_CLEANUP is set,
+ // else set this to NULL).
+ VARCLEANUPFUNCA cleanupFunction; // See above, use with TRF_CLEANUPFUNC.
+ VARCLEANUPFUNCW cleanupFunctionW;
+ VARCLEANUPFUNC cleanupFunctionT;
+ };
+ char *szHelpText; // Help info shown in help dialog (can be NULL). Has to
+ // be in the following format:
+ // "subject\targuments\tdescription"
+ // (Example: "math\t(x, y ,...)\tx + y + ..."), or:
+ // "subject\tdescription"
+ // (Example: "miranda\tPath to the Miranda-IM
+ // executable").
+ // Note: subject and description are translated by
+ // Variables.
+ int memType; // Describes which method Varibale's plugin needs to use to
+ // free the returned buffer, use one of the VR_MEM_* values
+ // (see below). Only valid if the flag VRF_FREEMEM is set,
+ // use TR_MEM_OWNER otherwise).
+ int flags; // Flags to use (see below), one of TRF_* (see below).
+} TOKENREGISTER;
+
+// Available Memory Storage Types:
+// These values describe which method Variables Plugin will use to free the
+// buffer returned by the parse function or service
+#define TR_MEM_VARIABLES 1 // Memory is allocated using the functions
+ // retrieved by MS_VARS_GET_MMI.
+#define TR_MEM_MIRANDA 2 // Memory is allocated using Miranda's Memory
+ // Manager Interface (using the functions
+ // returned by MS_SYSTEM_GET_MMI), if
+ // VRF_FREEMEM is set, the memory will be
+ // freed by Variables.
+#define TR_MEM_OWNER 3 // Memory is owned by the calling plugin
+ // (can't be freed by Variables Plugin
+ // automatically). This should be used if
+ // VRF_FREEMEM is not specified in the flags.
+
+// Available Flags for TOKENREGISTER:
+#define TRF_FREEMEM 0x01 // Variables Plugin will automatically free the
+ // pointer returned by the parse function or
+ // service (which method it will us is
+ // specified in memType -> see above).
+#define TRF_CLEANUP 0x02 // Call cleanup service or function, notifying
+ // that the returned buffer can be freed.
+ // Normally you should use either TRF_FREEMEM
+ // or TRF_CLEANUP.
+#define TRF_PARSEFUNC 0x40 // parseFunction will be used instead of a
+ // service.
+#define TRF_CLEANUPFUNC 0x80 // cleanupFunction will be used instead of a
+ // service.
+#define TRF_USEFUNCS TRF_PARSEFUNC|TRF_CLEANUPFUNC
+#define TRF_UNPARSEDARGS 0x04 // Provide the arguments for the parse
+ // function in their raw (unparsed) form.
+ // By default, arguments are parsed before
+ // presenting them to the parse function.
+#define TRF_FIELD 0x08 // The token can be used as a %field%.
+#define TRF_FUNCTION 0x10 // The token can be used as a ?function().
+ // Normally you should use either TRF_FIELD or
+ // TRF_FUNCTION.
+#define TRF_UNICODE 0x20 // Strings in structure are unicode (WCHAR*).
+ // In this case, the strings pointing to the
+ // arguments in the ARGUMENTS struct are
+ // unicode also. The returned buffer is
+ // expected to be unicode also, and the
+ // unicode parse and cleanup functions are
+ // called.
+
+#if defined(UNICODE) || defined(_UNICODE)
+#define TRF_TCHAR TRF_UNICODE // Strings in structure are TCHAR*.
+#else
+#define TRF_TCHAR 0
+#endif
+
+// Deprecated:
+#define TRF_CALLSVC TRF_CLEANUP
+
+// Callback Service (szService) / parseFunction:
+// ------------------------
+// Service that is called automatically by the Variable's Plugin to resolve a
+// registered variable.
+
+// Parameters:
+// wParam = 0
+// lParam = (LPARAM)(ARGUMENTSINFO *)&ai
+// see above
+
+// Return Value:
+// Needs to return the pointer to a dynamically allocacated string or NULL.
+// A return value of NULL is regarded as an error (eCount will be increaded).
+// Flags in the ARGUMENTSINFO struct can be set (see above).
+
+// Callback Service (szCallbackService) / cleanupFunction:
+// ------------------------
+// This service is called when the memory that was allocated by the parse
+// function or service can be freed. Note: It will only be called when the
+// flag VRF_CLEANUP of TOKENREGISTER is set.
+
+// Parameters:
+// wParam = 0
+// lParam = (LPARAM)(char *)&res
+// Result from parse function or service (pointer to a string).
+
+// Return Value:
+// Should return 0 on success.
+
+
+
+// --------------------------------------------------------------------------
+// Show the help dialog
+// --------------------------------------------------------------------------
+
+// Plugins can invoke Variables' help dialog which can be used for easy input
+// by users.
+
+#define MS_VARS_SHOWHELPEX "Vars/ShowHelpEx"
+
+// This service can be used to open the help dialog of Variables. This dialog
+// provides easy input for the user and/or information about the available
+// tokens.
+
+// Parameters:
+// ------------------------
+// wParam = (WPARAM)(HWND)hwndParent
+// lParam = (LPARAM)(VARHELPINFO)&vhi
+// See below.
+
+// Return Value:
+// ------------------------
+// Returns 0 on succes, any other value on error.
+
+typedef struct {
+ int cbSize; // Set to sizeof(VARHELPINFO).
+ FORMATINFO *fi; // Used for both input and output. If this pointer is not
+ // NULL, the information is used as the initial values for
+ // the dialog.
+ HWND hwndCtrl; // Used for both input and output. The window text of this
+ // window will be read and used as the initial input of the
+ // input dialog. If the user presses the OK button the window
+ // text of this window will be set to the text of the input
+ // field and a EN_CHANGE message via WM_COMMAND is send to
+ // this window. (Can be NULL).
+ char *szSubjectDesc; // The description of the %subject% token will be set
+ // to this text, if not NULL. This is translated
+ // automatically.
+ char *szExtraTextDesc; // The description of the %extratext% token will be
+ // set to this text, if not NULL. This is translated
+ // automatically.
+ int flags; // Flags, see below.
+} VARHELPINFO;
+
+
+// Flags for VARHELPINFO
+#define VHF_TOKENS 0x00000001 // Create a dialog with the list of
+ // tokens
+#define VHF_INPUT 0x00000002 // Create a dialog with an input
+ // field (this contains the list of
+ // tokens as well).
+#define VHF_SUBJECT 0x00000004 // Create a dialog to select a
+ // contact for the %subject% token.
+#define VHF_EXTRATEXT 0x00000008 // Create a dialog to enter a text
+ // for the %extratext% token.
+#define VHF_HELP 0x00000010 // Create a dialog with help info.
+#define VHF_HIDESUBJECTTOKEN 0x00000020 // Hide the %subject% token in the
+ // list of tokens.
+#define VHF_HIDEEXTRATEXTTOKEN 0x00000040 // Hide the %extratext% token in
+ // the list of tokens.
+#define VHF_DONTFILLSTRUCT 0x00000080 // Don't fill the struct with the
+ // new information if OK is pressed
+#define VHF_FULLFILLSTRUCT 0x00000100 // Fill all members of the struct
+ // when OK is pressed. By default
+ // only szFormat is set. With this
+ // flag on, hContact and
+ // szExtraText are also set.
+#define VHF_SETLASTSUBJECT 0x00000200 // Set the last contact that was
+ // used in the %subject% dialog in
+ // case fi.hContact is NULL.
+
+// Predefined flags
+#define VHF_FULLDLG VHF_INPUT|VHF_SUBJECT|VHF_EXTRATEXT|VHF_HELP
+#define VHF_SIMPLEDLG VHF_INPUT|VHF_HELP
+#define VHF_NOINPUTDLG VHF_TOKENS|VHF_HELP
+
+// If the service fills information in the struct for szFormat or szExtraText,
+// these members must be free'd using the free function of Variables.
+// If wParam==NULL, the dialog is created modeless. Only one dialog can be
+// shown at the time.
+// If both hwndCtrl and fi are NULL, the user input will not be retrievable.
+// In this case, the dialog is created with only a "Close" button, instead of
+// the "OK" and "Cancel" buttons.
+// In case of modeless dialog and fi != NULL, please make sure this pointer
+// stays valid while the dialog is open.
+
+// Helper function for easy use in standard case:
+#ifndef VARIABLES_NOHELPER
+__inline static int variables_showhelp(HWND hwndDlg, UINT uIDEdit, int flags, char *szSubjectDesc, char *szExtraDesc) {
+
+ VARHELPINFO vhi;
+
+ ZeroMemory(&vhi, sizeof(VARHELPINFO));
+ vhi.cbSize = sizeof(VARHELPINFO);
+ if (flags == 0) {
+ flags = VHF_SIMPLEDLG;
+ }
+ vhi.flags = flags;
+ vhi.hwndCtrl = GetDlgItem(hwndDlg, uIDEdit);
+ vhi.szSubjectDesc = szSubjectDesc;
+ vhi.szExtraTextDesc = szExtraDesc;
+
+ return CallService(MS_VARS_SHOWHELPEX, (WPARAM)hwndDlg, (LPARAM)&vhi);
+}
+#endif
+
+
+#define MS_VARS_GETSKINITEM "Vars/GetSkinItem"
+
+// This service can be used to get the icon you can use for example on the
+// Variables help button in your options screen. You can also get the tooltip
+// text to use with such a button. If icon library is available the icon will
+// be retrieved from icon library manager, otherwise the default is returned.
+
+// Parameters:
+// ------------------------
+// wParam = (WPARAM)0
+// lParam = (LPARAM)VSI_* (see below)
+
+// Return Value:
+// ------------------------
+// Depends on the information to retrieve (see below).
+
+// VSI_ constants
+#define VSI_HELPICON 1 // Can be used on the button accessing the
+ // Variables help dialog. Returns (HICON)hIcon on
+ // success or NULL on failure;
+#define VSI_HELPTIPTEXT 2 // Returns the tooltip text you can use for the
+ // help button. Returns (char *)szTipText, a
+ // static, translated buffer containing the help
+ // text or NULL on error.
+
+// Helper to set the icon on a button accessing the help dialog.
+// Preferably a 16x14 MButtonClass control, but it works on a standard
+// button control as well. If no icon is availble (because of old version of
+// Variables) the string "V" is shown on the button. If Variables is not
+// available, the button will be hidden.
+#ifndef VARIABLES_NOHELPER
+__inline static int variables_skin_helpbutton(HWND hwndDlg, UINT uIDButton) {
+
+ int res;
+ HICON hIcon;
+ TCHAR tszClass[32];
+
+ hIcon = NULL;
+ res = 0;
+ if (ServiceExists(MS_VARS_GETSKINITEM)) {
+ hIcon = (HICON)CallService(MS_VARS_GETSKINITEM, 0, (LPARAM)VSI_HELPICON);
+ }
+ GetClassName(GetDlgItem(hwndDlg, uIDButton), tszClass, sizeof(tszClass));
+ if (!_tcscmp(tszClass, _T("Button"))) {
+ if (hIcon != NULL) {
+ SetWindowLong(GetDlgItem(hwndDlg, uIDButton), GWL_STYLE, GetWindowLong(GetDlgItem(hwndDlg, uIDButton), GWL_STYLE)|BS_ICON);
+ SendMessage(GetDlgItem(hwndDlg, uIDButton), BM_SETIMAGE, (WPARAM)IMAGE_ICON, (LPARAM)hIcon);
+ }
+ else {
+ SetWindowLong(GetDlgItem(hwndDlg, uIDButton), GWL_STYLE, GetWindowLong(GetDlgItem(hwndDlg, uIDButton), GWL_STYLE)&~BS_ICON);
+ SetDlgItemText(hwndDlg, uIDButton, _T("V"));
+ }
+ }
+ else if (!_tcscmp(tszClass, MIRANDABUTTONCLASS)) {
+ if (hIcon != NULL) {
+ char *szTipInfo;
+
+ SendMessage(GetDlgItem(hwndDlg, uIDButton), BM_SETIMAGE, (WPARAM)IMAGE_ICON, (LPARAM)hIcon);
+ if (ServiceExists(MS_VARS_GETSKINITEM)) {
+ szTipInfo = (char *)CallService(MS_VARS_GETSKINITEM, 0, (LPARAM)VSI_HELPTIPTEXT);
+ }
+ if (szTipInfo == NULL) {
+ szTipInfo = Translate("Open String Formatting Help");
+ }
+ SendMessage(GetDlgItem(hwndDlg, uIDButton), BUTTONADDTOOLTIP, (WPARAM)szTipInfo, 0);
+ SendDlgItemMessage(hwndDlg, uIDButton, BUTTONSETASFLATBTN, 0, 0);
+ }
+ else {
+ SetDlgItemText(hwndDlg, uIDButton, _T("V"));
+ }
+ }
+ else {
+ res = -1;
+ }
+ ShowWindow(GetDlgItem(hwndDlg, uIDButton), ServiceExists(MS_VARS_FORMATSTRING));
+
+ return res;
+}
+#endif
+
+
+#define MS_VARS_SHOWHELP "Vars/ShowHelp"
+
+// WARNING: This service is obsolete, please use MS_VARS_SHOWHELPEX
+
+// Shows a help dialog where all possible tokens are displayed. The tokens
+// are explained on the dialog, too. The user can edit the initial string and
+// insert as many tokens as he likes.
+
+// Parameters:
+// ------------------------
+// wParam = (HWND)hwndEdit
+// Handle to an edit control in which the modified string
+// should be inserted (When the user clicks OK in the dialog the edited
+// string will be set to hwndEdit) (can be NULL).
+// lParam = (char *)pszInitialString
+// String that the user is provided with initially when
+// the dialog gets opened (If this is NULL then the current text in the
+// hwndEdit edit control will be used) (can be NULL).
+
+// Return Value:
+// ------------------------
+// Returns the handle to the help dialog (HWND).
+
+// Note: Only one help dialog can be opened at a time. When the dialog gets
+// closed an EN_CHANGE of the edit controll will be triggered because the
+// contents were updated. (Only when user selected OK).
+
+// Example:
+// CallService(MS_VARS_SHOWHELP, (WPARAM)hwndEdit, (LPARAM)"some initial text");
+
+// --------------------------------------------------------------------------
+// Retrieve a contact's HANDLE given a string
+// --------------------------------------------------------------------------
+
+#define MS_VARS_GETCONTACTFROMSTRING "Vars/GetContactFromString"
+
+// Searching for contacts in the database. You can find contacts in db by
+// searching for their name, e.g first name.
+
+// Parameters:
+// ------------------------
+// wParam = (WPARAM)(CONTACTSINFO *)&ci
+// See below.
+// lParam = 0
+
+// Return Value:
+// ------------------------
+// Returns number of contacts found matching the given string representation.
+// The hContacts array of CONTACTSINFO struct contains these hContacts after
+// the call.
+
+// Note: The hContacts array needs to be freed after use using
+// MS_VARS_FREEMEMORY.
+
+typedef struct {
+ int cbSize; // Set this to sizeof(CONTACTSINFO).
+ union {
+ char *szContact; // String to search for, e.g. last name (can't be NULL).
+ WCHAR * wszContact;
+ TCHAR *tszContact;
+ };
+ HANDLE *hContacts; // (output) Array of contacts found.
+ DWORD flags; // Contact details that will be matched with the search
+ // string (flags can be combined).
+} CONTACTSINFO;
+
+// Possible flags:
+#define CI_PROTOID 0x00000001 // The contact in the string is encoded
+ // in the format <PROTOID:UNIQUEID>, e.g.
+ // <ICQ:12345678>.
+#define CI_NICK 0x00000002 // Search nick names.
+#define CI_LISTNAME 0x00000004 // Search custom names shown in contact
+ // list.
+#define CI_FIRSTNAME 0x00000008 // Search contact's first names (contact
+ // details).
+#define CI_LASTNAME 0x00000010 // Search contact's last names (contact
+ // details).
+#define CI_EMAIL 0x00000020 // Search contact's email adresses
+ // (contact details).
+#define CI_UNIQUEID 0x00000040 // Search unique ids of the contac, e.g.
+ // UIN.
+#define CI_CNFINFO 0x40000000 // Searches one of the CNF_* flags (set
+ // flags to CI_CNFINFO|CNF_X), only one
+ // CNF_ type possible
+#define CI_UNICODE 0x80000000 // tszContact is a unicode string
+ // (WCHAR*).
+
+#if defined(UNICODE) || defined(_UNICODE)
+#define CI_TCHAR CI_UNICODE // Strings in structure are TCHAR*.
+#else
+#define CI_TCHAR 0
+#endif
+
+
+
+#endif //__M_VARS
diff --git a/plugins/tipper/message_pump.cpp b/plugins/tipper/message_pump.cpp
new file mode 100644
index 0000000000..88b0858258
--- /dev/null
+++ b/plugins/tipper/message_pump.cpp
@@ -0,0 +1,217 @@
+#include "common.h"
+#include "message_pump.h"
+#include "popwin.h"
+#include "options.h"
+#include "str_utils.h"
+
+BOOL (WINAPI *MySetLayeredWindowAttributes)(HWND,COLORREF,BYTE,DWORD);
+BOOL (WINAPI *MyAnimateWindow)(HWND hWnd,DWORD dwTime,DWORD dwFlags);
+HMONITOR (WINAPI *MyMonitorFromPoint)(POINT, DWORD);
+BOOL (WINAPI *MyGetMonitorInfo)(HMONITOR, LPMONITORINFO);
+
+unsigned int message_pump_thread_id;
+
+unsigned int CALLBACK MessagePumpThread(void *param)
+{
+ HWND hwndTip = 0;
+
+ MSG hwndMsg = {0};
+ while (GetMessage(&hwndMsg, 0, 0, 0) > 0 && !Miranda_Terminated())
+ {
+ if (!IsDialogMessage(hwndMsg.hwnd, &hwndMsg))
+ {
+ switch(hwndMsg.message)
+ {
+ case MUM_CREATEPOPUP:
+ if(hwndTip) DestroyWindow(hwndTip);
+ // if child of clist, zorder is right, but it steals the first click on a contact :(
+
+ // copy topmost exstyle from clist, since we'll put clist under tip in WM_CREATE message
+ //LONG clist_exstyle = GetWindowLong((HWND)CallService(MS_CLUI_GETHWND, 0, 0), GWL_EXSTYLE);
+ //hwndTip = CreateWindowEx((clist_exstyle & WS_EX_TOPMOST), POP_WIN_CLASS, _T("TipperPopup"), WS_POPUP, 0, 0, 0, 0, 0/*(HWND)CallService(MS_CLUI_GETHWND, 0, 0)*/, 0, hInst, (LPVOID)hwndMsg.lParam);
+
+ hwndTip = CreateWindowEx(WS_EX_TOOLWINDOW | WS_EX_TOPMOST, POP_WIN_CLASS, _T("TipperPopup"), WS_POPUP, 0, 0, 0, 0, 0/*(HWND)CallService(MS_CLUI_GETHWND, 0, 0)*/, 0, hInst, (LPVOID)hwndMsg.lParam);
+ if(hwndMsg.lParam) free((LPVOID)hwndMsg.lParam);
+ break;
+
+ case MUM_DELETEPOPUP:
+ if(hwndTip) {
+ DestroyWindow(hwndTip);
+ hwndTip = NULL;
+ }
+ break;
+
+ case MUM_GOTSTATUS:
+ if(hwndTip) SendMessage(hwndTip, PUM_SETSTATUSTEXT, hwndMsg.wParam, hwndMsg.lParam);
+ else if(hwndMsg.lParam) free((void *)hwndMsg.lParam);
+ break;
+
+ case MUM_REDRAW:
+ if(hwndTip) SendMessage(hwndTip, PUM_REFRESH_VALUES, hwndMsg.wParam, hwndMsg.lParam);
+ break;
+
+ case MUM_GOTAVATAR:
+ if(hwndTip) SendMessage(hwndTip, PUM_SETAVATAR, hwndMsg.wParam, hwndMsg.lParam);
+ break;
+
+ default:
+ TranslateMessage(&hwndMsg);
+ DispatchMessage(&hwndMsg);
+ break;
+ }
+ }
+ }
+
+ return 0;
+}
+
+void PostMPMessage(UINT msg, WPARAM wParam, LPARAM lParam) {
+ PostThreadMessage(message_pump_thread_id, msg, wParam, lParam);
+}
+
+void InitMessagePump() {
+ WNDCLASS popup_win_class = {0};
+ popup_win_class.lpfnWndProc = PopupWindowProc;
+ popup_win_class.hInstance = hInst;
+ popup_win_class.lpszClassName = POP_WIN_CLASS;
+ popup_win_class.hCursor = LoadCursor(NULL, IDC_ARROW);
+ RegisterClass(&popup_win_class);
+
+ HMODULE hUserDll = GetModuleHandle(_T("user32.dll"));
+ if (hUserDll) {
+ MySetLayeredWindowAttributes = (BOOL (WINAPI *)(HWND,COLORREF,BYTE,DWORD))GetProcAddress(hUserDll, "SetLayeredWindowAttributes");
+ MyAnimateWindow=(BOOL (WINAPI*)(HWND,DWORD,DWORD))GetProcAddress(hUserDll,"AnimateWindow");
+ MyMonitorFromPoint = (HMONITOR (WINAPI*)(POINT, DWORD))GetProcAddress(hUserDll, "MonitorFromPoint");
+#ifdef _UNICODE
+ MyGetMonitorInfo = (BOOL (WINAPI*)(HMONITOR, LPMONITORINFO))GetProcAddress(hUserDll, "GetMonitorInfoW");
+#else
+ MyGetMonitorInfo = (BOOL (WINAPI*)(HMONITOR, LPMONITORINFO))GetProcAddress(hUserDll, "GetMonitorInfoA");
+#endif
+ }
+
+
+
+ CloseHandle(mir_forkthreadex(MessagePumpThread, NULL, 0, &message_pump_thread_id));
+}
+
+void DeinitMessagePump() {
+ PostMPMessage(WM_QUIT, 0, 0);
+
+ UnregisterClass(POP_WIN_CLASS, hInst);
+}
+
+INT_PTR ShowTip(WPARAM wParam, LPARAM lParam) {
+ CLCINFOTIP *clcit = (CLCINFOTIP *)lParam;
+ if(clcit->isGroup) return 0; // no group tips (since they're pretty useless)
+ if(clcit->isTreeFocused == 0 && options.show_no_focus == false) return 0;
+
+ CLCINFOTIPEX *clcit2 = (CLCINFOTIPEX *)malloc(sizeof(CLCINFOTIPEX));
+ memcpy(clcit2, clcit, sizeof(CLCINFOTIP));
+ clcit2->cbSize = sizeof(CLCINFOTIPEX);
+ clcit2->proto = 0;
+ clcit2->text = 0;
+
+ if(wParam) { // wParam is char pointer containing text - e.g. status bar tooltip
+ clcit2->text = a2t((char *)wParam);
+ GetCursorPos(&clcit2->ptCursor);
+
+ //MessageBox(0, clcit2->text, _T("ShowTip"), MB_OK);
+ }
+
+ PostMPMessage(MUM_CREATEPOPUP, 0, (LPARAM)clcit2);
+ return 1;
+}
+
+int ShowTipHook(WPARAM wParam, LPARAM lParam) {
+ ShowTip(wParam, lParam);
+ return 0;
+}
+
+#ifdef _UNICODE
+INT_PTR ShowTipW(WPARAM wParam, LPARAM lParam) {
+ CLCINFOTIP *clcit = (CLCINFOTIP *)lParam;
+ if(clcit->isGroup) return 0; // no group tips (since they're pretty useless)
+ if(clcit->isTreeFocused == 0 && options.show_no_focus == false) return 0;
+
+ CLCINFOTIPEX *clcit2 = (CLCINFOTIPEX *)malloc(sizeof(CLCINFOTIPEX));
+ memcpy(clcit2, clcit, sizeof(CLCINFOTIP));
+ clcit2->cbSize = sizeof(CLCINFOTIPEX);
+ clcit2->proto = 0;
+ clcit2->text = 0;
+
+ if(wParam) { // wParam is char pointer containing text - e.g. status bar tooltip
+ clcit2->text = _tcsdup((TCHAR *)wParam);
+ GetCursorPos(&clcit2->ptCursor);
+ }
+
+ PostMPMessage(MUM_CREATEPOPUP, 0, (LPARAM)clcit2);
+ return 1;
+}
+#endif
+
+INT_PTR HideTip(WPARAM wParam, LPARAM lParam) {
+ //CLCINFOTIP *clcit = (CLCINFOTIP *)lParam;
+ PostMPMessage(MUM_DELETEPOPUP, 0, 0);
+ return 1;
+}
+
+int HideTipHook(WPARAM wParam, LPARAM lParam) {
+ HideTip(wParam, lParam);
+ return 0;
+}
+
+int ProtoAck(WPARAM wParam, LPARAM lParam) {
+ ACKDATA *ack = (ACKDATA *)lParam;
+ if (ack->type == ACKTYPE_AWAYMSG && ack->result == ACKRESULT_SUCCESS)
+ {
+#ifdef _UNICODE
+ DBVARIANT dbv;
+ if (!DBGetContactSetting(ack->hContact, "CList", "StatusMsg", &dbv))
+ {
+ bool unicode = (dbv.type == DBVT_UTF8 || dbv.type == DBVT_WCHAR);
+ DBFreeVariant(&dbv);
+ if (unicode) {
+ DBGetContactSettingTString(ack->hContact, "CList", "StatusMsg", &dbv);
+ PostMPMessage(MUM_GOTSTATUS, (WPARAM)ack->hContact, (LPARAM)_tcsdup(dbv.ptszVal));
+ DBFreeVariant(&dbv);
+ return 0;
+ }
+ }
+#endif
+ char *szMsg = (char *)ack->lParam;
+ if (szMsg && szMsg[0])
+ PostMPMessage(MUM_GOTSTATUS, (WPARAM)ack->hContact, (LPARAM)a2t(szMsg));
+ }
+ else if (ack->type == ACKTYPE_GETINFO && ack->result == ACKRESULT_SUCCESS)
+ {
+ PostMPMessage(MUM_REDRAW, (WPARAM)ack->hContact, 0);
+ }
+
+ return 0;
+}
+
+int FramesShowSBTip(WPARAM wParam, LPARAM lParam) {
+ if(options.status_bar_tips) {
+ char *proto = (char *)wParam;
+
+ CLCINFOTIPEX *clcit2 = (CLCINFOTIPEX *)malloc(sizeof(CLCINFOTIPEX));
+ memset(clcit2, 0, sizeof(CLCINFOTIPEX));
+ clcit2->cbSize = sizeof(CLCINFOTIPEX);
+ clcit2->proto = proto; // assume static string
+ GetCursorPos(&clcit2->ptCursor);
+
+ PostMPMessage(MUM_CREATEPOPUP, 0, (LPARAM)clcit2);
+
+ return 1;
+ }
+ return 0;
+}
+
+int FramesHideSBTip(WPARAM wParam, LPARAM lParam) {
+ if(options.status_bar_tips) {
+ PostMPMessage(MUM_DELETEPOPUP, 0, 0);
+ return 1;
+ }
+ return 0;
+}
+
diff --git a/plugins/tipper/message_pump.h b/plugins/tipper/message_pump.h
new file mode 100644
index 0000000000..4f7acfb2f2
--- /dev/null
+++ b/plugins/tipper/message_pump.h
@@ -0,0 +1,44 @@
+#ifndef _MESSAGE_PUMP_INC
+#define _MESSAGE_PUMP_INC
+
+void PostMPMessage(UINT msg, WPARAM, LPARAM);
+
+#define MUM_CREATEPOPUP (WM_USER + 0x011)
+#define MUM_DELETEPOPUP (WM_USER + 0x012)
+#define MUM_GOTSTATUS (WM_USER + 0x013)
+#define MUM_GOTAVATAR (WM_USER + 0x014)
+#define MUM_REDRAW (WM_USER + 0x015)
+
+extern BOOL (WINAPI *MySetLayeredWindowAttributes)(HWND,COLORREF,BYTE,DWORD);
+extern BOOL (WINAPI *MyAnimateWindow)(HWND hWnd,DWORD dwTime,DWORD dwFlags);
+extern HMONITOR (WINAPI *MyMonitorFromPoint)(POINT, DWORD);
+extern BOOL (WINAPI *MyGetMonitorInfo)(HMONITOR, LPMONITORINFO);
+
+void InitMessagePump();
+void DeinitMessagePump();
+
+INT_PTR ShowTip(WPARAM wParam, LPARAM lParam);
+INT_PTR ShowTipW(WPARAM wParam, LPARAM lParam);
+INT_PTR HideTip(WPARAM wParam, LPARAM lParam);
+
+int ShowTipHook(WPARAM wParam, LPARAM lParam);
+int HideTipHook(WPARAM wParam, LPARAM lParam);
+
+int FramesShowSBTip(WPARAM wParam, LPARAM lParam);
+int FramesHideSBTip(WPARAM wParam, LPARAM lParam);
+
+int ProtoAck(WPARAM wParam, LPARAM lParam);
+
+typedef struct {
+ int cbSize;
+ int isTreeFocused; //so the plugin can provide an option
+ int isGroup; //0 if it's a contact, 1 if it's a group
+ HANDLE hItem; //handle to group or contact
+ POINT ptCursor;
+ RECT rcItem;
+ TCHAR *text; // for tips with specific text
+ char *proto; // for proto tips
+} CLCINFOTIPEX;
+
+
+#endif
diff --git a/plugins/tipper/options.cpp b/plugins/tipper/options.cpp
new file mode 100644
index 0000000000..4ebe0a25c6
--- /dev/null
+++ b/plugins/tipper/options.cpp
@@ -0,0 +1,1190 @@
+#include "common.h"
+#include "options.h"
+#include "resource.h"
+#include "popwin.h"
+#include "str_utils.h"
+
+Options options;
+
+#define WMU_ENABLE_LIST_BUTTONS (WM_USER + 0x030)
+#define WMU_ENABLE_MODULE_ENTRY (WM_USER + 0x031)
+
+void CreateDefaultItems() {
+ DSListNode *ds_node;
+ DIListNode *di_node;
+
+ // last message item
+ di_node = (DIListNode *)malloc(sizeof(DIListNode));
+ _tcsncpy(di_node->di.label, _T("Last message: (%sys:last_msg_reltime% ago)"), LABEL_LEN);
+ _tcsncpy(di_node->di.value, _T("%sys:last_msg%"), VALUE_LEN);
+ di_node->di.line_above = di_node->di.value_newline = true;
+ di_node->next = options.di_list;
+ options.di_list = di_node;
+ options.di_count++;
+
+ // status message item
+ di_node = (DIListNode *)malloc(sizeof(DIListNode));
+ _tcsncpy(di_node->di.label, _T("Status message:"), LABEL_LEN);
+ _tcsncpy(di_node->di.value, _T("%sys:status_msg%"), VALUE_LEN);
+ di_node->di.line_above = di_node->di.value_newline = true;
+ di_node->next = options.di_list;
+ options.di_list = di_node;
+ options.di_count++;
+
+ // status substitution
+ ds_node = (DSListNode *)malloc(sizeof(DSListNode));
+ _tcsncpy(ds_node->ds.name, _T("status"), LABEL_LEN);
+ ds_node->ds.type = DVT_PROTODB;
+ strncpy(ds_node->ds.setting_name, "Status", SETTING_NAME_LEN);
+ ds_node->ds.translate_func_id = 1;
+ ds_node->next = options.ds_list;
+ options.ds_list = ds_node;
+ options.ds_count++;
+
+ // status item
+ di_node = (DIListNode *)malloc(sizeof(DIListNode));
+ _tcsncpy(di_node->di.label, _T("Status:"), LABEL_LEN);
+ _tcsncpy(di_node->di.value, _T("%status%"), VALUE_LEN);
+ di_node->di.line_above = di_node->di.value_newline = false;
+ di_node->next = options.di_list;
+ options.di_list = di_node;
+ options.di_count++;
+
+ // Contact time
+ di_node = (DIListNode *)malloc(sizeof(DIListNode));
+ _tcsncpy(di_node->di.label, _T("Time:"), LABEL_LEN);
+ _tcsncpy(di_node->di.value, _T("%sys:time%"), VALUE_LEN);
+ di_node->di.line_above = di_node->di.value_newline = false;
+ di_node->next = options.di_list;
+ options.di_list = di_node;
+ options.di_count++;
+
+ // client substitution
+ ds_node = (DSListNode *)malloc(sizeof(DSListNode));
+ _tcsncpy(ds_node->ds.name, _T("client"), LABEL_LEN);
+ ds_node->ds.type = DVT_PROTODB;
+ strncpy(ds_node->ds.setting_name, "MirVer", SETTING_NAME_LEN);
+ ds_node->ds.translate_func_id = 0;
+ ds_node->next = options.ds_list;
+ options.ds_list = ds_node;
+ options.ds_count++;
+
+ // client item
+ di_node = (DIListNode *)malloc(sizeof(DIListNode));
+ _tcsncpy(di_node->di.label, _T("Client:"), LABEL_LEN);
+ _tcsncpy(di_node->di.value, _T("%client%"), VALUE_LEN);
+ di_node->di.line_above = di_node->di.value_newline = false;
+ di_node->next = options.di_list;
+ options.di_list = di_node;
+ options.di_count++;
+
+ // idle time substitution (long date)
+ ds_node = (DSListNode *)malloc(sizeof(DSListNode));
+ _tcsncpy(ds_node->ds.name, _T("idle"), LABEL_LEN);
+ ds_node->ds.type = DVT_PROTODB;
+ strncpy(ds_node->ds.setting_name, "IdleTS", SETTING_NAME_LEN);
+ ds_node->ds.translate_func_id = 15;
+ ds_node->next = options.ds_list;
+ options.ds_list = ds_node;
+ options.ds_count++;
+
+ // idle time substitution (time difference)
+ ds_node = (DSListNode *)malloc(sizeof(DSListNode));
+ _tcsncpy(ds_node->ds.name, _T("idle_diff"), LABEL_LEN);
+ ds_node->ds.type = DVT_PROTODB;
+ strncpy(ds_node->ds.setting_name, "IdleTS", SETTING_NAME_LEN);
+ ds_node->ds.translate_func_id = 3;
+ ds_node->next = options.ds_list;
+ options.ds_list = ds_node;
+ options.ds_count++;
+
+
+ // idle item
+ di_node = (DIListNode *)malloc(sizeof(DIListNode));
+ _tcsncpy(di_node->di.label, _T("Idle:"), LABEL_LEN);
+ _tcsncpy(di_node->di.value, _T("%idle% (%idle_diff% ago)"), VALUE_LEN);
+ di_node->di.line_above = di_node->di.value_newline = false;
+ di_node->next = options.di_list;
+ options.di_list = di_node;
+ options.di_count++;
+
+ // first name substitution
+ ds_node = (DSListNode *)malloc(sizeof(DSListNode));
+ _tcsncpy(ds_node->ds.name, _T("first_name"), LABEL_LEN);
+ ds_node->ds.type = DVT_PROTODB;
+ strncpy(ds_node->ds.setting_name, "FirstName", SETTING_NAME_LEN);
+ ds_node->ds.translate_func_id = 0;
+ ds_node->next = options.ds_list;
+ options.ds_list = ds_node;
+ options.ds_count++;
+
+ // last name substitution
+ ds_node = (DSListNode *)malloc(sizeof(DSListNode));
+ _tcsncpy(ds_node->ds.name, _T("last_name"), LABEL_LEN);
+ ds_node->ds.type = DVT_PROTODB;
+ strncpy(ds_node->ds.setting_name, "LastName", SETTING_NAME_LEN);
+ ds_node->ds.translate_func_id = 0;
+ ds_node->next = options.ds_list;
+ options.ds_list = ds_node;
+ options.ds_count++;
+
+ // name item
+ di_node = (DIListNode *)malloc(sizeof(DIListNode));
+ _tcsncpy(di_node->di.label, _T("Name:"), LABEL_LEN);
+ _tcsncpy(di_node->di.value, _T("%first_name% %last_name%"), VALUE_LEN);
+ di_node->di.line_above = di_node->di.value_newline = false;
+ di_node->next = options.di_list;
+ options.di_list = di_node;
+ options.di_count++;
+
+}
+
+bool LoadDS(DisplaySubst *ds, int index) {
+ char setting[512];
+ DBVARIANT dbv;
+ mir_snprintf(setting, SIZEOF(setting), "Name%d", index);
+ ds->name[0] = 0;
+ if (!DBGetContactSettingTString(0, MODULE, setting, &dbv)) {
+ _tcsncpy(ds->name, dbv.ptszVal, SIZEOF(ds->name));
+ ds->name[SIZEOF(ds->name) - 1] = 0;
+ DBFreeVariant(&dbv);
+ } else
+ return false;
+
+ mir_snprintf(setting, SIZEOF(setting), "Type%d", index);
+ ds->type = (DisplaySubstType)DBGetContactSettingByte(0, MODULE, setting, DVT_PROTODB);
+
+ mir_snprintf(setting, SIZEOF(setting), "Module%d", index);
+ ds->module_name[0] = 0;
+ if(!DBGetContactSettingString(0, MODULE, setting, &dbv)) {
+ strncpy(ds->module_name, dbv.pszVal, MODULE_NAME_LEN);
+ ds->module_name[MODULE_NAME_LEN - 1] = 0;
+ DBFreeVariant(&dbv);
+ }
+
+ mir_snprintf(setting, 512, "Setting%d", index);
+ ds->setting_name[0] = 0;
+ if(!DBGetContactSettingString(0, MODULE, setting, &dbv)) {
+ strncpy(ds->setting_name, dbv.pszVal, SETTING_NAME_LEN);
+ ds->setting_name[SETTING_NAME_LEN - 1] = 0;
+ DBFreeVariant(&dbv);
+ }
+
+ mir_snprintf(setting, 512, "TransFuncId%d", index);
+ ds->translate_func_id = DBGetContactSettingDword(0, MODULE, setting, (DWORD)-1);
+
+ // a little backward compatibility
+ if((DWORD)ds->translate_func_id == (DWORD)-1) {
+ mir_snprintf(setting, 512, "TransFunc%d", index);
+ ds->translate_func_id = (DWORD)DBGetContactSettingWord(0, MODULE, setting, 0);
+ }
+ return true;
+}
+
+void SaveDS(DisplaySubst *ds, int index) {
+ char setting[512];
+ mir_snprintf(setting, SIZEOF(setting), "Name%d", index);
+ DBWriteContactSettingTString(0, MODULE, setting, ds->name);
+ mir_snprintf(setting, SIZEOF(setting), "Type%d", index);
+ DBWriteContactSettingByte(0, MODULE, setting, (BYTE)ds->type);
+ mir_snprintf(setting, SIZEOF(setting), "Module%d", index);
+ DBWriteContactSettingString(0, MODULE, setting, ds->module_name);
+ mir_snprintf(setting, SIZEOF(setting), "Setting%d", index);
+ DBWriteContactSettingString(0, MODULE, setting, ds->setting_name);
+ mir_snprintf(setting, SIZEOF(setting), "TransFuncId%d", index);
+ DBWriteContactSettingDword(0, MODULE, setting, (WORD)ds->translate_func_id);
+}
+
+bool LoadDI(DisplayItem *di, int index)
+{
+ char setting[512];
+ DBVARIANT dbv;
+ mir_snprintf(setting, SIZEOF(setting), "DILabel%d", index);
+ di->label[0] = 0;
+ if (!DBGetContactSettingTString(0, MODULE, setting, &dbv)) {
+ _tcsncpy( di->label, dbv.ptszVal, SIZEOF(di->label));
+ di->label[SIZEOF(di->label) - 1] = 0;
+ DBFreeVariant(&dbv);
+ } else
+ return false;
+
+ mir_snprintf(setting, SIZEOF(setting), "DIValue%d", index);
+ di->value[0] = 0;
+ if(!DBGetContactSettingTString(0, MODULE, setting, &dbv)) {
+ _tcsncpy(di->value, dbv.ptszVal, SIZEOF(di->value));
+ di->value[SIZEOF(di->value) - 1] = 0;
+ DBFreeVariant(&dbv);
+ }
+
+ mir_snprintf(setting, SIZEOF(setting), "DILineAbove%d", index);
+ di->line_above = (DBGetContactSettingByte(0, MODULE, setting, 0) == 1);
+ mir_snprintf(setting, SIZEOF(setting), "DIValNewline%d", index);
+ di->value_newline = (DBGetContactSettingByte(0, MODULE, setting, 0) == 1);
+
+ return true;
+}
+
+void SaveDI(DisplayItem *di, int index) {
+ char setting[512];
+ mir_snprintf(setting, SIZEOF(setting), "DILabel%d", index);
+ DBWriteContactSettingTString(0, MODULE, setting, di->label);
+ mir_snprintf(setting, SIZEOF(setting), "DIValue%d", index);
+ DBWriteContactSettingTString(0, MODULE, setting, di->value);
+ mir_snprintf(setting, SIZEOF(setting), "DILineAbove%d", index);
+ DBWriteContactSettingByte(0, MODULE, setting, di->line_above ? 1 : 0);
+ mir_snprintf(setting, SIZEOF(setting), "DIValNewline%d", index);
+ DBWriteContactSettingByte(0, MODULE, setting, di->value_newline ? 1 : 0);
+}
+
+void SaveOptions() {
+ DBWriteContactSettingDword(0, MODULE, "MaxWidth", options.win_width);
+ DBWriteContactSettingDword(0, MODULE, "MaxHeight", options.win_max_height);
+ DBWriteContactSettingByte(0, MODULE, "Opacity", (BYTE)options.opacity);
+ DBWriteContactSettingByte(0, MODULE, "Border", (options.border ? 1 : 0));
+ DBWriteContactSettingByte(0, MODULE, "DropShadow", (options.drop_shadow ? 1 : 0));
+ DBWriteContactSettingByte(0, MODULE, "RoundCorners", (options.round ? 1 : 0));
+ DBWriteContactSettingByte(0, MODULE, "AvatarRoundCorners", (options.av_round ? 1 : 0));
+ DBWriteContactSettingByte(0, MODULE, "Animate", (options.animate ? 1 : 0));
+ DBWriteContactSettingByte(0, MODULE, "TransparentBg", (options.trans_bg ? 1 : 0));
+ DBWriteContactSettingByte(0, MODULE, "TitleLayout", (BYTE)options.title_layout);
+ if (ServiceExists(MS_AV_DRAWAVATAR))
+ DBWriteContactSettingByte(0, MODULE, "AVLayout", (BYTE)options.av_layout);
+ DBWriteContactSettingDword(0, MODULE, "AVSize", options.av_size);
+ DBWriteContactSettingDword(0, MODULE, "TextIndent", options.text_indent);
+ DBWriteContactSettingByte(0, MODULE, "ShowNoFocus", (options.show_no_focus ? 1 : 0));
+
+ int index = 0;
+ DSListNode *ds_node = options.ds_list;
+ while(ds_node) {
+ SaveDS(&ds_node->ds, index);
+ ds_node = ds_node->next;
+ index++;
+ }
+ DBWriteContactSettingWord(0, MODULE, "DSNumValues", index);
+
+ index = 0;
+ DIListNode *di_node = options.di_list;
+ while(di_node) {
+ SaveDI(&di_node->di, index);
+ di_node = di_node->next;
+ index++;
+ }
+ DBWriteContactSettingWord(0, MODULE, "DINumValues", index);
+
+ DBWriteContactSettingWord(0, MODULE, "TimeIn", options.time_in);
+ CallService(MS_CLC_SETINFOTIPHOVERTIME, options.time_in, 0);
+
+ DBWriteContactSettingWord(0, MODULE, "Padding", options.padding);
+ DBWriteContactSettingWord(0, MODULE, "AvatarPadding", options.av_padding);
+ DBWriteContactSettingWord(0, MODULE, "TextPadding", options.text_padding);
+ DBWriteContactSettingByte(0, MODULE, "Position", (BYTE)options.pos);
+ DBWriteContactSettingDword(0, MODULE, "MinWidth", (DWORD)options.min_width);
+ DBWriteContactSettingDword(0, MODULE, "MinHeight", (DWORD)options.min_height);
+ DBWriteContactSettingDword(0, MODULE, "SidebarWidth", (DWORD)options.sidebar_width);
+ DBWriteContactSettingByte(0, MODULE, "MouseTollerance", (BYTE)options.mouse_tollerance);
+ DBWriteContactSettingByte(0, MODULE, "SBarTips", (options.status_bar_tips ? 1 : 0));
+
+ DBWriteContactSettingWord(0, MODULE, "LabelVAlign", options.label_valign);
+ DBWriteContactSettingWord(0, MODULE, "LabelHAlign", options.label_halign);
+ DBWriteContactSettingWord(0, MODULE, "ValueVAlign", options.value_valign);
+ DBWriteContactSettingWord(0, MODULE, "ValueHAlign", options.value_halign);
+
+ DBWriteContactSettingByte(0, MODULE, "NoAvatarResize", options.no_resize_av ? 1 : 0);
+ DBWriteContactSettingTString(0, MODULE, "BackgroundFilename", options.bg_fn);
+ DBWriteContactSettingByte(0, MODULE, "StretchBgImg", options.stretch_bg_img ? 1 : 0);
+}
+
+void LoadOptions() {
+ options.win_width = DBGetContactSettingDword(0, MODULE, "MaxWidth", 420);
+ options.win_max_height = DBGetContactSettingDword(0, MODULE, "MaxHeight", 400);
+ options.opacity = DBGetContactSettingByte(0, MODULE, "Opacity", 75);
+ options.border = (DBGetContactSettingByte(0, MODULE, "Border", 1) == 1);
+ options.drop_shadow = (DBGetContactSettingByte(0, MODULE, "DropShadow", 1) == 1);
+ options.round = (DBGetContactSettingByte(0, MODULE, "RoundCorners", 1) == 1);
+ options.av_round = (DBGetContactSettingByte(0, MODULE, "AvatarRoundCorners", options.round ? 1 : 0) == 1);
+ options.animate = (DBGetContactSettingByte(0, MODULE, "Animate", 0) == 1);
+ options.trans_bg = (DBGetContactSettingByte(0, MODULE, "TransparentBg", 0) == 1);
+ options.title_layout = (PopupTitleLayout)DBGetContactSettingByte(0, MODULE, "TitleLayout", (BYTE)PTL_LEFTICON);
+ if(ServiceExists(MS_AV_DRAWAVATAR))
+ options.av_layout = (PopupAvLayout)DBGetContactSettingByte(0, MODULE, "AVLayout", PAV_RIGHT);
+ else
+ options.av_layout = PAV_NONE;
+ options.av_size = DBGetContactSettingDword(0, MODULE, "AVSize", 60); //tweety
+ options.text_indent = DBGetContactSettingDword(0, MODULE, "TextIndent", 22);
+ options.sidebar_width = DBGetContactSettingDword(0, MODULE, "SidebarWidth", 22);
+ options.show_no_focus = (DBGetContactSettingByte(0, MODULE, "ShowNoFocus", 1) == 1);
+
+ int i, real_count = 0;
+ options.ds_list = 0;
+ DSListNode *ds_node;
+ options.ds_count = DBGetContactSettingWord(0, MODULE, "DSNumValues", 0);
+ for(i = options.ds_count - 1; i >= 0; i--) {
+ ds_node = (DSListNode *)malloc(sizeof(DSListNode));
+ if(LoadDS(&ds_node->ds, i)) {
+ ds_node->next = options.ds_list;
+ options.ds_list = ds_node;
+ real_count++;
+ } else free(ds_node);
+ }
+ options.ds_count = real_count;
+
+ real_count = 0;
+ options.di_list = 0;
+ DIListNode *di_node;
+ options.di_count = DBGetContactSettingWord(0, MODULE, "DINumValues", 0);
+ for(i = options.di_count - 1; i >= 0; i--) {
+ di_node = (DIListNode *)malloc(sizeof(DIListNode));
+ if(LoadDI(&di_node->di, i)) {
+ di_node->next = options.di_list;
+ options.di_list = di_node;
+ real_count++;
+ } else free(di_node);
+ }
+ options.di_count = real_count;
+
+ options.time_in = DBGetContactSettingWord(0, MODULE, "TimeIn", 750);
+ options.padding = DBGetContactSettingWord(0, MODULE, "Padding", 4);
+ options.av_padding = DBGetContactSettingWord(0, MODULE, "AvatarPadding", 6);
+ options.text_padding = DBGetContactSettingWord(0, MODULE, "TextPadding", 4);
+ options.pos = (PopupPosition)DBGetContactSettingByte(0, MODULE, "Position", (BYTE)PP_BOTTOMRIGHT);
+ options.min_width = DBGetContactSettingDword(0, MODULE, "MinWidth", 0);
+ options.min_height = DBGetContactSettingDword(0, MODULE, "MinHeight", 0);
+
+ options.mouse_tollerance = DBGetContactSettingByte(0, MODULE, "MouseTollerance", (BYTE)GetSystemMetrics(SM_CXSMICON));
+ options.status_bar_tips = (DBGetContactSettingByte(0, MODULE, "SBarTips", 1) == 1);
+
+ // convert defunct last message and status message options to new 'sys' items, and remove the old settings
+ if(DBGetContactSettingByte(0, MODULE, "ShowLastMessage", 0)) {
+ DBDeleteContactSetting(0, MODULE, "ShowLastMessage");
+
+ // find end of list
+ di_node = options.di_list;
+ while(di_node && di_node->next) di_node = di_node->next;
+
+ // last message item
+ if(di_node) {
+ di_node->next = (DIListNode *)malloc(sizeof(DIListNode));
+ di_node = di_node->next;
+ } else {
+ options.di_list = (DIListNode *)malloc(sizeof(DIListNode));
+ di_node = options.di_list;
+ }
+
+ _tcsncpy(di_node->di.label, _T("Last message: (%sys:last_msg_reltime% ago)"), LABEL_LEN);
+ _tcsncpy(di_node->di.value, _T("%sys:last_msg%"), VALUE_LEN);
+ di_node->di.line_above = di_node->di.value_newline = true;
+ di_node->next = 0;
+ options.di_count++;
+ }
+
+ if(DBGetContactSettingByte(0, MODULE, "ShowStatusMessage", 0)) {
+ DBDeleteContactSetting(0, MODULE, "ShowStatusMessage");
+
+ // find end of list
+ di_node = options.di_list;
+ while(di_node && di_node->next) di_node = di_node->next;
+
+ // status message item
+ if(di_node) {
+ di_node->next = (DIListNode *)malloc(sizeof(DIListNode));
+ di_node = di_node->next;
+ } else {
+ options.di_list = (DIListNode *)malloc(sizeof(DIListNode));
+ di_node = options.di_list;
+ }
+
+ _tcsncpy(di_node->di.label, _T("Status message:"), LABEL_LEN);
+ _tcsncpy(di_node->di.value, _T("%sys:status_msg%"), VALUE_LEN);
+ di_node->di.line_above = di_node->di.value_newline = true;
+ di_node->next = 0;
+ options.di_count++;
+ }
+
+ options.label_valign = DBGetContactSettingWord(0, MODULE, "LabelVAlign", DT_TOP /*DT_VCENTER*/);
+ options.label_halign = DBGetContactSettingWord(0, MODULE, "LabelHAlign", DT_LEFT);
+ options.value_valign = DBGetContactSettingWord(0, MODULE, "ValueVAlign", DT_TOP /*DT_VCENTER*/);
+ options.value_halign = DBGetContactSettingWord(0, MODULE, "ValueHAlign", DT_LEFT);
+
+ if(options.ds_count == 0 && options.di_count == 0 && DBGetContactSettingByte(0, MODULE, "DefaultsCreated", 0) == 0) {
+ // set up some reasonable defaults - but only 'once'
+ CreateDefaultItems();
+ DBWriteContactSettingByte(0, MODULE, "DefaultsCreated", 1);
+ SaveOptions();
+ }
+
+ options.no_resize_av = (DBGetContactSettingByte(0, MODULE, "NoAvatarResize", 0) == 1);
+ DBVARIANT dbv;
+ if(!DBGetContactSettingTString(0, MODULE, "BackgroundFilename", &dbv)) {
+ _tcsncpy(options.bg_fn, dbv.ptszVal, MAX_PATH);
+ DBFreeVariant(&dbv);
+ } else
+ options.bg_fn[0] = 0;
+ options.stretch_bg_img = (DBGetContactSettingByte(0, MODULE, "StretchBgImg", 0) == 1);
+}
+
+static INT_PTR CALLBACK DlgProcAddItem(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) {
+ DisplayItem *di = (DisplayItem *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
+
+ switch ( msg ) {
+ case WM_INITDIALOG:
+ TranslateDialogDefault( hwndDlg );
+ di = (DisplayItem *)lParam;
+ SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)di);
+
+ SetDlgItemText(hwndDlg, IDC_ED_LABEL, di->label);
+ SetDlgItemText(hwndDlg, IDC_ED_VALUE, di->value);
+
+ CheckDlgButton(hwndDlg, IDC_CHK_LINEABOVE, di->line_above ? TRUE : FALSE);
+ CheckDlgButton(hwndDlg, IDC_CHK_VALNEWLINE, di->value_newline ? TRUE : FALSE);
+ SetFocus(GetDlgItem(hwndDlg, IDC_ED_LABEL));
+ return TRUE;
+ case WM_COMMAND:
+ if(HIWORD(wParam) == BN_CLICKED) {
+ switch(LOWORD(wParam)) {
+ case IDOK:
+ GetDlgItemText(hwndDlg, IDC_ED_LABEL, di->label, LABEL_LEN);
+ GetDlgItemText(hwndDlg, IDC_ED_VALUE, di->value, VALUE_LEN);
+
+ di->line_above = (IsDlgButtonChecked(hwndDlg, IDC_CHK_LINEABOVE) ? true : false);
+ di->value_newline = (IsDlgButtonChecked(hwndDlg, IDC_CHK_VALNEWLINE) ? true : false);
+
+ EndDialog(hwndDlg, IDOK);
+ return TRUE;
+ case IDCANCEL:
+ EndDialog(hwndDlg, IDCANCEL);
+ return TRUE;
+ }
+ }
+ break;
+ }
+
+ return 0;
+}
+
+static INT_PTR CALLBACK DlgProcAddSubst(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) {
+ DisplaySubst *ds = (DisplaySubst *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
+
+ switch ( msg ) {
+ case WM_INITDIALOG:
+ TranslateDialogDefault( hwndDlg );
+ ds = (DisplaySubst *)lParam;
+ SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)ds);
+
+ SetDlgItemText(hwndDlg, IDC_ED_LABEL, ds->name);
+
+ switch(ds->type) {
+ case DVT_PROTODB:
+ CheckDlgButton(hwndDlg, IDC_CHK_PROTOMOD, TRUE);
+ SetDlgItemTextA(hwndDlg, IDC_ED_SETTING, ds->setting_name);
+ break;
+ case DVT_DB:
+ SetDlgItemTextA(hwndDlg, IDC_ED_MODULE, ds->module_name);
+ SetDlgItemTextA(hwndDlg, IDC_ED_SETTING, ds->setting_name);
+ break;
+ }
+
+ {
+ int index, id, i;
+ for(i = 0; i < num_tfuncs; i++) {
+ index = SendDlgItemMessage(hwndDlg, IDC_CMB_TRANSLATE, CB_ADDSTRING, (WPARAM)-1, (LPARAM)TranslateTS(translations[i].name));
+ SendDlgItemMessage(hwndDlg, IDC_CMB_TRANSLATE, CB_SETITEMDATA, index, (LPARAM)translations[i].id);
+ }
+ for(i = 0; i < num_tfuncs; i++) {
+ id = SendDlgItemMessage(hwndDlg, IDC_CMB_TRANSLATE, CB_GETITEMDATA, i, 0);
+ if(id == ds->translate_func_id)
+ SendDlgItemMessage(hwndDlg, IDC_CMB_TRANSLATE, CB_SETCURSEL, i, 0);
+ }
+ }
+
+ SendMessage(hwndDlg, WMU_ENABLE_MODULE_ENTRY, 0, 0);
+ SetFocus(GetDlgItem(hwndDlg, IDC_ED_LABEL));
+ return TRUE;
+ case WMU_ENABLE_MODULE_ENTRY:
+ {
+ HWND hw = GetDlgItem(hwndDlg, IDC_CHK_PROTOMOD);
+ EnableWindow(hw, TRUE);
+ hw = GetDlgItem(hwndDlg, IDC_ED_MODULE);
+ EnableWindow(hw, !IsDlgButtonChecked(hwndDlg, IDC_CHK_PROTOMOD));
+ hw = GetDlgItem(hwndDlg, IDC_ED_SETTING);
+ EnableWindow(hw, TRUE);
+ }
+ return TRUE;
+ case WM_COMMAND:
+ if ( HIWORD( wParam ) == CBN_SELCHANGE) {
+ return TRUE;
+ } else if(HIWORD(wParam) == BN_CLICKED) {
+ switch(LOWORD(wParam)) {
+ case IDC_CHK_PROTOMOD:
+ SendMessage(hwndDlg, WMU_ENABLE_MODULE_ENTRY, 0, 0);
+ break;
+ case IDOK:
+ GetDlgItemText(hwndDlg, IDC_ED_LABEL, ds->name, LABEL_LEN);
+ if(ds->name[0] == 0) {
+ MessageBox(hwndDlg, TranslateT("You must enter a label"), TranslateT("Invalid Substitution"), MB_OK | MB_ICONWARNING);
+ return TRUE;
+ }
+
+ if(IsDlgButtonChecked(hwndDlg, IDC_CHK_PROTOMOD))
+ ds->type = DVT_PROTODB;
+ else {
+ ds->type = DVT_DB;
+ GetDlgItemTextA(hwndDlg, IDC_ED_MODULE, ds->module_name, MODULE_NAME_LEN);
+ }
+ GetDlgItemTextA(hwndDlg, IDC_ED_SETTING, ds->setting_name, SETTING_NAME_LEN);
+
+ {
+ int sel = SendDlgItemMessage(hwndDlg, IDC_CMB_TRANSLATE, CB_GETCURSEL, 0, 0);
+ ds->translate_func_id = SendDlgItemMessage(hwndDlg, IDC_CMB_TRANSLATE, CB_GETITEMDATA, sel, 0);
+ }
+
+ EndDialog(hwndDlg, IDOK);
+ return TRUE;
+ case IDCANCEL:
+ EndDialog(hwndDlg, IDCANCEL);
+ return TRUE;
+ }
+ }
+ break;
+ }
+
+ return 0;
+}
+
+static INT_PTR CALLBACK DlgProcOptContent(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) {
+
+ switch ( msg ) {
+ case WM_INITDIALOG:
+ TranslateDialogDefault( hwndDlg );
+ {
+ int index;
+ DIListNode *di_node = options.di_list, *di_value;
+ while(di_node) {
+ di_value = (DIListNode *)malloc(sizeof(DIListNode));
+ *di_value = *di_node;
+ if(di_value->di.label[0] == 0)
+ index = SendDlgItemMessage(hwndDlg, IDC_LST_ITEMS, LB_ADDSTRING, 0, (LPARAM)TranslateT("<No Label>"));
+ else
+ index = SendDlgItemMessage(hwndDlg, IDC_LST_ITEMS, LB_ADDSTRING, 0, (LPARAM)di_value->di.label);
+ SendDlgItemMessage(hwndDlg, IDC_LST_ITEMS, LB_SETITEMDATA, index, (LPARAM)di_value);
+
+ di_node = di_node->next;
+ }
+
+ DSListNode *ds_node = options.ds_list, *ds_value;
+ while(ds_node) {
+ ds_value = (DSListNode *)malloc(sizeof(DSListNode));
+ *ds_value = *ds_node;
+ index = SendDlgItemMessage(hwndDlg, IDC_LST_SUBST, LB_ADDSTRING, 0, (LPARAM)ds_value->ds.name);
+ SendDlgItemMessage(hwndDlg, IDC_LST_SUBST, LB_SETITEMDATA, index, (LPARAM)ds_value);
+
+ ds_node = ds_node->next;
+ }
+ }
+
+ SendMessage(hwndDlg, WMU_ENABLE_LIST_BUTTONS, 0, 0);
+ return FALSE;
+ case WMU_ENABLE_LIST_BUTTONS:
+ {
+ int sel = SendDlgItemMessage(hwndDlg, IDC_LST_ITEMS, LB_GETCURSEL, 0, 0);
+ if(sel == -1) {
+ HWND hw = GetDlgItem(hwndDlg, IDC_BTN_REMOVE);
+ EnableWindow(hw, FALSE);
+ hw = GetDlgItem(hwndDlg, IDC_BTN_UP);
+ EnableWindow(hw, FALSE);
+ hw = GetDlgItem(hwndDlg, IDC_BTN_DOWN);
+ EnableWindow(hw, FALSE);
+ hw = GetDlgItem(hwndDlg, IDC_BTN_EDIT);
+ EnableWindow(hw, FALSE);
+ } else {
+ int count = SendDlgItemMessage(hwndDlg, IDC_LST_ITEMS, LB_GETCOUNT, 0, 0);
+ HWND hw = GetDlgItem(hwndDlg, IDC_BTN_REMOVE);
+ EnableWindow(hw, TRUE);
+ hw = GetDlgItem(hwndDlg, IDC_BTN_UP);
+ EnableWindow(hw, sel > 0);
+ hw = GetDlgItem(hwndDlg, IDC_BTN_DOWN);
+ EnableWindow(hw, sel < count - 1);
+ hw = GetDlgItem(hwndDlg, IDC_BTN_EDIT);
+ EnableWindow(hw, TRUE);
+ }
+
+ sel = SendDlgItemMessage(hwndDlg, IDC_LST_SUBST, LB_GETCURSEL, 0, 0);
+ if(sel == -1) {
+ HWND hw = GetDlgItem(hwndDlg, IDC_BTN_REMOVE2);
+ EnableWindow(hw, FALSE);
+ hw = GetDlgItem(hwndDlg, IDC_BTN_EDIT2);
+ EnableWindow(hw, FALSE);
+ } else {
+ HWND hw = GetDlgItem(hwndDlg, IDC_BTN_REMOVE2);
+ EnableWindow(hw, TRUE);
+ hw = GetDlgItem(hwndDlg, IDC_BTN_EDIT2);
+ EnableWindow(hw, TRUE);
+ }
+ }
+ return TRUE;
+ case WM_COMMAND:
+ if ( HIWORD( wParam ) == LBN_SELCHANGE && LOWORD(wParam) == IDC_LST_ITEMS) {
+ SendMessage(hwndDlg, WMU_ENABLE_LIST_BUTTONS, 0, 0);
+ } else if ( HIWORD( wParam ) == LBN_SELCHANGE && LOWORD(wParam) == IDC_LST_SUBST) {
+ SendMessage(hwndDlg, WMU_ENABLE_LIST_BUTTONS, 0, 0);
+ } else if ( HIWORD( wParam ) == CBN_SELCHANGE) {
+ SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
+ } else if ( HIWORD( wParam ) == EN_CHANGE && ( HWND )lParam == GetFocus()) {
+ SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
+ } else if ( HIWORD( wParam) == LBN_DBLCLK && LOWORD(wParam) == IDC_LST_ITEMS) {
+ {
+ DIListNode *value;
+ int sel = SendDlgItemMessage(hwndDlg, IDC_LST_ITEMS, LB_GETCURSEL, 0, 0);
+ if(sel != -1) {
+ value = (DIListNode *)SendDlgItemMessage(hwndDlg, IDC_LST_ITEMS, LB_GETITEMDATA, sel, 0);
+ if(DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_ITEM), hwndDlg, DlgProcAddItem, (LPARAM)&value->di) == IDOK) {
+ SendDlgItemMessage(hwndDlg, IDC_LST_ITEMS, LB_DELETESTRING, (WPARAM)sel, 0);
+
+ SendDlgItemMessage(hwndDlg, IDC_LST_ITEMS, LB_INSERTSTRING, sel, (LPARAM)value->di.label);
+ SendDlgItemMessage(hwndDlg, IDC_LST_ITEMS, LB_SETITEMDATA, sel, (LPARAM)value);
+
+ SendDlgItemMessage(hwndDlg, IDC_LST_ITEMS, LB_SETCURSEL, sel, 0);
+
+ SendMessage(hwndDlg, WMU_ENABLE_LIST_BUTTONS, 0, 0);
+ SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
+ }
+ }
+ }
+ } else if ( HIWORD( wParam) == LBN_DBLCLK && LOWORD(wParam) == IDC_LST_SUBST) {
+ {
+ DSListNode *value;
+ int sel = SendDlgItemMessage(hwndDlg, IDC_LST_SUBST, LB_GETCURSEL, 0, 0);
+ if(sel != -1) {
+ value = (DSListNode *)SendDlgItemMessage(hwndDlg, IDC_LST_SUBST, LB_GETITEMDATA, sel, 0);
+ if(DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_SUBST), hwndDlg, DlgProcAddSubst, (LPARAM)&value->ds) == IDOK) {
+ SendDlgItemMessage(hwndDlg, IDC_LST_SUBST, LB_DELETESTRING, (WPARAM)sel, 0);
+
+ sel = SendDlgItemMessage(hwndDlg, IDC_LST_SUBST, LB_ADDSTRING, 0, (LPARAM)value->ds.name);
+ SendDlgItemMessage(hwndDlg, IDC_LST_SUBST, LB_SETITEMDATA, sel, (LPARAM)value);
+
+ SendDlgItemMessage(hwndDlg, IDC_LST_SUBST, LB_SETCURSEL, sel, 0);
+
+ SendMessage(hwndDlg, WMU_ENABLE_LIST_BUTTONS, 0, 0);
+ SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
+ }
+ }
+ }
+ } else if ( HIWORD( wParam ) == BN_CLICKED ) {
+ switch(LOWORD(wParam)) {
+ case IDC_BTN_ADD:
+ {
+ DIListNode *value = (DIListNode *)malloc(sizeof(DIListNode));
+ memset(value, 0, sizeof(DIListNode));
+ if(DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_ITEM), hwndDlg, DlgProcAddItem, (LPARAM)&value->di) == IDOK) {
+ int sel = SendDlgItemMessage(hwndDlg, IDC_LST_ITEMS, LB_GETCURSEL, 0, 0), index = sel + 1;
+ if(value->di.label[0] == 0)
+ SendDlgItemMessage(hwndDlg, IDC_LST_ITEMS, LB_INSERTSTRING, index, (LPARAM)TranslateT("<No Label>"));
+ else
+ SendDlgItemMessage(hwndDlg, IDC_LST_ITEMS, LB_INSERTSTRING, index, (LPARAM)value->di.label);
+ SendDlgItemMessage(hwndDlg, IDC_LST_ITEMS, LB_SETITEMDATA, index, (LPARAM)value);
+ SendDlgItemMessage(hwndDlg, IDC_LST_ITEMS, LB_SETCURSEL, index, 0);
+ SendMessage(hwndDlg, WMU_ENABLE_LIST_BUTTONS, 0, 0);
+ SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
+ }
+
+ }
+ return TRUE;
+ case IDC_BTN_REMOVE:
+ {
+ int sel = SendDlgItemMessage(hwndDlg, IDC_LST_ITEMS, LB_GETCURSEL, 0, 0);
+ if(sel != -1) {
+ DIListNode *value = (DIListNode *)SendDlgItemMessage(hwndDlg, IDC_LST_ITEMS, LB_GETITEMDATA, sel, 0);
+ SendDlgItemMessage(hwndDlg, IDC_LST_ITEMS, LB_DELETESTRING, (WPARAM)sel, 0);
+ free(value);
+ SendMessage(hwndDlg, WMU_ENABLE_LIST_BUTTONS, 0, 0);
+ SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
+ }
+ }
+ return TRUE;
+ case IDC_BTN_UP:
+ {
+ DIListNode *value_up;
+ int sel = SendDlgItemMessage(hwndDlg, IDC_LST_ITEMS, LB_GETCURSEL, 0, 0);
+ if(sel > 0) {
+ value_up = (DIListNode *)SendDlgItemMessage(hwndDlg, IDC_LST_ITEMS, LB_GETITEMDATA, sel - 1, 0);
+ SendDlgItemMessage(hwndDlg, IDC_LST_ITEMS, LB_DELETESTRING, (WPARAM)sel - 1, 0);
+
+ SendDlgItemMessage(hwndDlg, IDC_LST_ITEMS, LB_INSERTSTRING, sel, (LPARAM)value_up->di.label);
+ SendDlgItemMessage(hwndDlg, IDC_LST_ITEMS, LB_SETITEMDATA, sel, (LPARAM)value_up);
+
+ SendDlgItemMessage(hwndDlg, IDC_LST_ITEMS, LB_SETCURSEL, sel - 1, 0);
+ }
+ }
+ SendMessage(hwndDlg, WMU_ENABLE_LIST_BUTTONS, 0, 0);
+ SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
+ return TRUE;
+ case IDC_BTN_DOWN:
+ {
+ DIListNode *value_down;
+ int sel = SendDlgItemMessage(hwndDlg, IDC_LST_ITEMS, LB_GETCURSEL, 0, 0);
+ int count = SendDlgItemMessage(hwndDlg, IDC_LST_ITEMS, LB_GETCOUNT, 0, 0);
+ if(sel < count - 1) {
+ value_down = (DIListNode *)SendDlgItemMessage(hwndDlg, IDC_LST_ITEMS, LB_GETITEMDATA, sel + 1, 0);
+ SendDlgItemMessage(hwndDlg, IDC_LST_ITEMS, LB_DELETESTRING, (WPARAM)sel + 1, 0);
+
+ SendDlgItemMessage(hwndDlg, IDC_LST_ITEMS, LB_INSERTSTRING, sel, (LPARAM)value_down->di.label);
+ SendDlgItemMessage(hwndDlg, IDC_LST_ITEMS, LB_SETITEMDATA, sel, (LPARAM)value_down);
+
+ SendDlgItemMessage(hwndDlg, IDC_LST_ITEMS, LB_SETCURSEL, sel + 1, 0);
+ }
+ }
+ SendMessage(hwndDlg, WMU_ENABLE_LIST_BUTTONS, 0, 0);
+ SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
+ return TRUE;
+ case IDC_BTN_EDIT:
+ {
+ DIListNode *value;
+ int sel = SendDlgItemMessage(hwndDlg, IDC_LST_ITEMS, LB_GETCURSEL, 0, 0);
+ if(sel != -1) {
+ value = (DIListNode *)SendDlgItemMessage(hwndDlg, IDC_LST_ITEMS, LB_GETITEMDATA, sel, 0);
+ if(DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_ITEM), hwndDlg, DlgProcAddItem, (LPARAM)&value->di) == IDOK) {
+ SendDlgItemMessage(hwndDlg, IDC_LST_ITEMS, LB_DELETESTRING, (WPARAM)sel, 0);
+
+ if(value->di.label[0] == 0)
+ SendDlgItemMessage(hwndDlg, IDC_LST_ITEMS, LB_INSERTSTRING, sel, (LPARAM)TranslateT("<No Label>"));
+ else
+ SendDlgItemMessage(hwndDlg, IDC_LST_ITEMS, LB_INSERTSTRING, sel, (LPARAM)value->di.label);
+ SendDlgItemMessage(hwndDlg, IDC_LST_ITEMS, LB_SETITEMDATA, sel, (LPARAM)value);
+
+ SendDlgItemMessage(hwndDlg, IDC_LST_ITEMS, LB_SETCURSEL, sel, 0);
+
+ SendMessage(hwndDlg, WMU_ENABLE_LIST_BUTTONS, 0, 0);
+ SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
+ }
+ }
+ }
+ return TRUE;
+
+ case IDC_BTN_ADD2:
+ {
+ DSListNode *value = (DSListNode *)malloc(sizeof(DSListNode));
+ memset(value, 0, sizeof(DSListNode));
+ if(DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_SUBST), hwndDlg, DlgProcAddSubst, (LPARAM)&value->ds) == IDOK) {
+ int index = SendDlgItemMessage(hwndDlg, IDC_LST_SUBST, LB_ADDSTRING, 0, (LPARAM)value->ds.name);
+ SendDlgItemMessage(hwndDlg, IDC_LST_SUBST, LB_SETITEMDATA, index, (LPARAM)value);
+ SendDlgItemMessage(hwndDlg, IDC_LST_SUBST, LB_SETCURSEL, index, 0);
+ SendMessage(hwndDlg, WMU_ENABLE_LIST_BUTTONS, 0, 0);
+ SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
+ }
+
+ }
+ return TRUE;
+ case IDC_BTN_REMOVE2:
+ {
+ int sel = SendDlgItemMessage(hwndDlg, IDC_LST_SUBST, LB_GETCURSEL, 0, 0);
+ if(sel != -1) {
+ DSListNode *value = (DSListNode *)SendDlgItemMessage(hwndDlg, IDC_LST_SUBST, LB_GETITEMDATA, sel, 0);
+ SendDlgItemMessage(hwndDlg, IDC_LST_SUBST, LB_DELETESTRING, (WPARAM)sel, 0);
+ free(value);
+ SendMessage(hwndDlg, WMU_ENABLE_LIST_BUTTONS, 0, 0);
+ SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
+ }
+ }
+ return TRUE;
+ case IDC_BTN_EDIT2:
+ {
+ DSListNode *value;
+ int sel = SendDlgItemMessage(hwndDlg, IDC_LST_SUBST, LB_GETCURSEL, 0, 0);
+ if(sel != -1) {
+ value = (DSListNode *)SendDlgItemMessage(hwndDlg, IDC_LST_SUBST, LB_GETITEMDATA, sel, 0);
+ if(DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_SUBST), hwndDlg, DlgProcAddSubst, (LPARAM)&value->ds) == IDOK) {
+ SendDlgItemMessage(hwndDlg, IDC_LST_SUBST, LB_DELETESTRING, (WPARAM)sel, 0);
+
+ sel = SendDlgItemMessage(hwndDlg, IDC_LST_SUBST, LB_ADDSTRING, 0, (LPARAM)value->ds.name);
+ SendDlgItemMessage(hwndDlg, IDC_LST_SUBST, LB_SETITEMDATA, sel, (LPARAM)value);
+
+ SendDlgItemMessage(hwndDlg, IDC_LST_SUBST, LB_SETCURSEL, sel, 0);
+
+ SendMessage(hwndDlg, WMU_ENABLE_LIST_BUTTONS, 0, 0);
+ SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
+ }
+ }
+ }
+ return TRUE;
+ default:
+ SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
+ return TRUE;
+ }
+ }
+ break;
+ case WM_NOTIFY:
+ if (((LPNMHDR)lParam)->code == (unsigned)PSN_APPLY ) {
+ DIListNode *di_node;
+ int i;
+ while(options.di_list) {
+ di_node = options.di_list;
+ options.di_list = options.di_list->next;
+ free(di_node);
+ }
+
+ DIListNode *di_value;
+ options.di_count = SendDlgItemMessage(hwndDlg, IDC_LST_ITEMS, LB_GETCOUNT, 0, 0);
+ for(i = options.di_count - 1; i >= 0; i--) {
+ di_node = (DIListNode *)SendDlgItemMessage(hwndDlg, IDC_LST_ITEMS, LB_GETITEMDATA, i, 0);
+ di_value = (DIListNode *)malloc(sizeof(DIListNode));
+ *di_value = *di_node;
+
+ di_value->next = options.di_list;
+ options.di_list = di_value;
+ }
+
+ DSListNode *ds_node;
+ while(options.ds_list) {
+ ds_node = options.ds_list;
+ options.ds_list = options.ds_list->next;
+ free(ds_node);
+ }
+
+ DSListNode *ds_value;
+ options.ds_count = SendDlgItemMessage(hwndDlg, IDC_LST_SUBST, LB_GETCOUNT, 0, 0);
+ for(i = options.ds_count - 1; i >= 0; i--) {
+ ds_node = (DSListNode *)SendDlgItemMessage(hwndDlg, IDC_LST_SUBST, LB_GETITEMDATA, i, 0);
+ ds_value = (DSListNode *)malloc(sizeof(DSListNode));
+ *ds_value = *ds_node;
+
+ ds_value->next = options.ds_list;
+ options.ds_list = ds_value;
+ }
+
+ SaveOptions();
+ return TRUE;
+ }
+ break;
+ case WM_DESTROY:
+ {
+ DIListNode *di_value;
+ int i;
+ int count = SendDlgItemMessage(hwndDlg, IDC_LST_ITEMS, LB_GETCOUNT, 0, 0);
+ for(i = 0; i < count; i++) {
+ di_value = (DIListNode *)SendDlgItemMessage(hwndDlg, IDC_LST_ITEMS, LB_GETITEMDATA, i, 0);
+ free(di_value);
+ }
+ DSListNode *ds_value;
+ count = SendDlgItemMessage(hwndDlg, IDC_LST_SUBST, LB_GETCOUNT, 0, 0);
+ for(i = 0; i < count; i++) {
+ ds_value = (DSListNode *)SendDlgItemMessage(hwndDlg, IDC_LST_SUBST, LB_GETITEMDATA, i, 0);
+ free(ds_value);
+ }
+ }
+ break;
+ }
+
+ return 0;
+}
+
+static INT_PTR CALLBACK DlgProcOptWindow(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) {
+
+ switch ( msg ) {
+ case WM_INITDIALOG:
+ TranslateDialogDefault( hwndDlg );
+ SendDlgItemMessage(hwndDlg, IDC_SPIN_WIDTH, UDM_SETRANGE, 0, (LPARAM)MAKELONG(2048, 16));
+ SendDlgItemMessage(hwndDlg, IDC_SPIN_MINWIDTH, UDM_SETRANGE, 0, (LPARAM)MAKELONG(2048, 16));
+ SendDlgItemMessage(hwndDlg, IDC_SPIN_MAXHEIGHT, UDM_SETRANGE, 0, (LPARAM)MAKELONG(2048, 16));
+ SendDlgItemMessage(hwndDlg, IDC_SPIN_MINHEIGHT, UDM_SETRANGE, 0, (LPARAM)MAKELONG(2048, 16));
+ SetDlgItemInt(hwndDlg, IDC_ED_WIDTH, options.win_width, FALSE);
+ SetDlgItemInt(hwndDlg, IDC_ED_MAXHEIGHT, options.win_max_height, FALSE);
+ SetDlgItemInt(hwndDlg, IDC_ED_MINWIDTH, options.min_width, FALSE);
+ SetDlgItemInt(hwndDlg, IDC_ED_MINHEIGHT, options.min_height, FALSE);
+
+ SetDlgItemInt(hwndDlg, IDC_ED_TRANS, options.opacity, FALSE);
+ CheckDlgButton(hwndDlg, IDC_CHK_TRANSBG, options.trans_bg);
+
+ CheckDlgButton(hwndDlg, IDC_CHK_NOFOCUS, options.show_no_focus ? TRUE : FALSE);
+ CheckDlgButton(hwndDlg, IDC_CHK_SBAR, options.status_bar_tips ? TRUE : FALSE);
+ CheckDlgButton(hwndDlg, IDC_CHK_BORDER, options.border);
+ CheckDlgButton(hwndDlg, IDC_CHK_ROUNDCORNERS, options.round);
+ CheckDlgButton(hwndDlg, IDC_CHK_ROUNDCORNERSAV, options.av_round);
+
+ CheckDlgButton(hwndDlg, IDC_CHK_ANIMATE, options.animate);
+ CheckDlgButton(hwndDlg, IDC_CHK_SHADOW, options.drop_shadow);
+
+ SendDlgItemMessage(hwndDlg, IDC_SPIN_HOVER, UDM_SETRANGE, 0, (LPARAM)MAKELONG(5000, 5));
+ SetDlgItemInt(hwndDlg, IDC_ED_HOVER, options.time_in, FALSE);
+ break;
+ case WM_COMMAND:
+ if ( HIWORD( wParam ) == CBN_SELCHANGE) {
+ SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
+ } else if ( HIWORD( wParam ) == EN_CHANGE && ( HWND )lParam == GetFocus()) {
+ SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
+ } else if ( HIWORD( wParam ) == BN_CLICKED ) {
+ SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
+ }
+ break;
+ case WM_NOTIFY:
+ if (((LPNMHDR)lParam)->code == (unsigned)PSN_APPLY ) {
+ BOOL trans;
+ int new_val;
+ new_val = GetDlgItemInt(hwndDlg, IDC_ED_WIDTH, &trans, FALSE);
+ if(trans) options.win_width = new_val;
+ new_val = GetDlgItemInt(hwndDlg, IDC_ED_MINWIDTH, &trans, FALSE);
+ if(trans) options.min_width = new_val;
+ new_val = GetDlgItemInt(hwndDlg, IDC_ED_MAXHEIGHT, &trans, FALSE);
+ if(trans) options.win_max_height = new_val;
+ new_val = GetDlgItemInt(hwndDlg, IDC_ED_MINHEIGHT, &trans, FALSE);
+ if(trans) options.min_height = new_val;
+
+ new_val = GetDlgItemInt(hwndDlg, IDC_ED_TRANS, &trans, FALSE);
+ if(trans) options.opacity = new_val;
+ options.trans_bg = IsDlgButtonChecked(hwndDlg, IDC_CHK_TRANSBG) ? true : false;
+
+ new_val = GetDlgItemInt(hwndDlg, IDC_ED_HOVER, &trans, FALSE);
+ if(trans) options.time_in = new_val;
+
+ options.border = IsDlgButtonChecked(hwndDlg, IDC_CHK_BORDER) && IsWindowEnabled(GetDlgItem(hwndDlg, IDC_CHK_BORDER)) ? true : false;
+ options.round = IsDlgButtonChecked(hwndDlg, IDC_CHK_ROUNDCORNERS) && IsWindowEnabled(GetDlgItem(hwndDlg, IDC_CHK_ROUNDCORNERS)) ? true : false;
+ options.av_round = IsDlgButtonChecked(hwndDlg, IDC_CHK_ROUNDCORNERSAV) && IsWindowEnabled(GetDlgItem(hwndDlg, IDC_CHK_ROUNDCORNERSAV)) ? true : false;
+ options.animate = IsDlgButtonChecked(hwndDlg, IDC_CHK_ANIMATE) ? true : false;
+ options.drop_shadow = IsDlgButtonChecked(hwndDlg, IDC_CHK_SHADOW) ? true : false;
+
+ options.show_no_focus = IsDlgButtonChecked(hwndDlg, IDC_CHK_NOFOCUS) ? true : false;
+ options.status_bar_tips = IsDlgButtonChecked(hwndDlg, IDC_CHK_SBAR) ? true : false;
+
+ SaveOptions();
+ return TRUE;
+ }
+ break;
+ }
+ return 0;
+}
+
+static INT_PTR CALLBACK DlgProcOptLayout(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) {
+
+ switch ( msg ) {
+ case WM_INITDIALOG:
+ TranslateDialogDefault( hwndDlg );
+
+ SendDlgItemMessage(hwndDlg, IDC_CMB_ICON, CB_ADDSTRING, 0, (LPARAM)TranslateT("Icon on left"));
+ SendDlgItemMessage(hwndDlg, IDC_CMB_ICON, CB_ADDSTRING, 0, (LPARAM)TranslateT("Icon on right"));
+ SendDlgItemMessage(hwndDlg, IDC_CMB_ICON, CB_ADDSTRING, 0, (LPARAM)TranslateT("No icon"));
+ SendDlgItemMessage(hwndDlg, IDC_CMB_ICON, CB_ADDSTRING, 0, (LPARAM)TranslateT("No title"));
+ SendDlgItemMessage(hwndDlg, IDC_CMB_ICON, CB_SETCURSEL, (int)options.title_layout, 0);
+
+ SendDlgItemMessage(hwndDlg, IDC_CMB_POS, CB_ADDSTRING, 0, (LPARAM)TranslateT("Bottom right"));
+ SendDlgItemMessage(hwndDlg, IDC_CMB_POS, CB_ADDSTRING, 0, (LPARAM)TranslateT("Bottom left"));
+ SendDlgItemMessage(hwndDlg, IDC_CMB_POS, CB_ADDSTRING, 0, (LPARAM)TranslateT("Top right"));
+ SendDlgItemMessage(hwndDlg, IDC_CMB_POS, CB_ADDSTRING, 0, (LPARAM)TranslateT("Top left"));
+ SendDlgItemMessage(hwndDlg, IDC_CMB_POS, CB_SETCURSEL, (int)options.pos, 0);
+
+ SendDlgItemMessage(hwndDlg, IDC_CMB_LV, CB_ADDSTRING, 0, (LPARAM)TranslateT("Top"));
+ SendDlgItemMessage(hwndDlg, IDC_CMB_LV, CB_ADDSTRING, 0, (LPARAM)TranslateT("Centre"));
+ SendDlgItemMessage(hwndDlg, IDC_CMB_LV, CB_ADDSTRING, 0, (LPARAM)TranslateT("Bottom"));
+ switch(options.label_valign) {
+ case DT_TOP: SendDlgItemMessage(hwndDlg, IDC_CMB_LV, CB_SETCURSEL, 0, 0); break;
+ case DT_VCENTER: SendDlgItemMessage(hwndDlg, IDC_CMB_LV, CB_SETCURSEL, 1, 0); break;
+ case DT_BOTTOM: SendDlgItemMessage(hwndDlg, IDC_CMB_LV, CB_SETCURSEL, 2, 0); break;
+ }
+
+ SendDlgItemMessage(hwndDlg, IDC_CMB_VV, CB_ADDSTRING, 0, (LPARAM)TranslateT("Top"));
+ SendDlgItemMessage(hwndDlg, IDC_CMB_VV, CB_ADDSTRING, 0, (LPARAM)TranslateT("Centre"));
+ SendDlgItemMessage(hwndDlg, IDC_CMB_VV, CB_ADDSTRING, 0, (LPARAM)TranslateT("Bottom"));
+ switch(options.value_valign) {
+ case DT_TOP: SendDlgItemMessage(hwndDlg, IDC_CMB_VV, CB_SETCURSEL, 0, 0); break;
+ case DT_VCENTER: SendDlgItemMessage(hwndDlg, IDC_CMB_VV, CB_SETCURSEL, 1, 0); break;
+ case DT_BOTTOM: SendDlgItemMessage(hwndDlg, IDC_CMB_VV, CB_SETCURSEL, 2, 0); break;
+ }
+
+ SendDlgItemMessage(hwndDlg, IDC_CMB_LH, CB_ADDSTRING, 0, (LPARAM)TranslateT("Left"));
+ SendDlgItemMessage(hwndDlg, IDC_CMB_LH, CB_ADDSTRING, 0, (LPARAM)TranslateT("Right"));
+ switch(options.label_halign) {
+ case DT_LEFT: SendDlgItemMessage(hwndDlg, IDC_CMB_LH, CB_SETCURSEL, 0, 0); break;
+ case DT_RIGHT: SendDlgItemMessage(hwndDlg, IDC_CMB_LH, CB_SETCURSEL, 1, 0); break;
+ }
+
+ SendDlgItemMessage(hwndDlg, IDC_CMB_VH, CB_ADDSTRING, 0, (LPARAM)TranslateT("Left"));
+ SendDlgItemMessage(hwndDlg, IDC_CMB_VH, CB_ADDSTRING, 0, (LPARAM)TranslateT("Right"));
+ switch(options.value_halign) {
+ case DT_LEFT: SendDlgItemMessage(hwndDlg, IDC_CMB_VH, CB_SETCURSEL, 0, 0); break;
+ case DT_RIGHT: SendDlgItemMessage(hwndDlg, IDC_CMB_VH, CB_SETCURSEL, 1, 0); break;
+ }
+
+ SendDlgItemMessage(hwndDlg, IDC_CMB_AV, CB_ADDSTRING, 0, (LPARAM)TranslateT("No avatar"));
+ if(ServiceExists(MS_AV_DRAWAVATAR)) {
+ SendDlgItemMessage(hwndDlg, IDC_CMB_AV, CB_ADDSTRING, 0, (LPARAM)TranslateT("Left avatar"));
+ SendDlgItemMessage(hwndDlg, IDC_CMB_AV, CB_ADDSTRING, 0, (LPARAM)TranslateT("Right avatar"));
+ } else {
+ HWND hw = GetDlgItem(hwndDlg, IDC_CMB_AV);
+ EnableWindow(hw, FALSE);
+ hw = GetDlgItem(hwndDlg, IDC_SPIN_AVSIZE);
+ EnableWindow(hw, FALSE);
+ hw = GetDlgItem(hwndDlg, IDC_ED_AVSIZE);
+ EnableWindow(hw, FALSE);
+ }
+ SendDlgItemMessage(hwndDlg, IDC_CMB_AV, CB_SETCURSEL, (int)options.av_layout, 0);
+
+ SendDlgItemMessage(hwndDlg, IDC_SPIN_TRANS, UDM_SETRANGE, 0, (LPARAM)MAKELONG(99, 0));
+ SendDlgItemMessage(hwndDlg, IDC_SPIN_AVSIZE, UDM_SETRANGE, 0, (LPARAM)MAKELONG(100, 16));
+ SendDlgItemMessage(hwndDlg, IDC_SPIN_INDENT, UDM_SETRANGE, 0, (LPARAM)MAKELONG(400, 0));
+ SendDlgItemMessage(hwndDlg, IDC_SPIN_PADDING, UDM_SETRANGE, 0, (LPARAM)MAKELONG(128, 0));
+ SendDlgItemMessage(hwndDlg, IDC_SPIN_TEXTPADDING, UDM_SETRANGE, 0, (LPARAM)MAKELONG(128, 0));
+ SendDlgItemMessage(hwndDlg, IDC_SPIN_AVPADDING, UDM_SETRANGE, 0, (LPARAM)MAKELONG(128, 0));
+ SendDlgItemMessage(hwndDlg, IDC_SPIN_SBWIDTH, UDM_SETRANGE, 0, (LPARAM)MAKELONG(2048, 0));
+
+ CheckDlgButton(hwndDlg, IDC_CHK_NORESIZEAV, options.no_resize_av);
+ if(options.no_resize_av) {
+ HWND hw = GetDlgItem(hwndDlg, IDC_ED_AVSIZE);
+ EnableWindow(hw, FALSE);
+ hw = GetDlgItem(hwndDlg, IDC_SPIN_AVSIZE);
+ EnableWindow(hw, FALSE);
+ }
+ SetDlgItemInt(hwndDlg, IDC_ED_AVSIZE, options.av_size, FALSE);
+ SetDlgItemInt(hwndDlg, IDC_ED_INDENT, options.text_indent, FALSE);
+ SetDlgItemInt(hwndDlg, IDC_ED_PADDING, options.padding, FALSE);
+ SetDlgItemInt(hwndDlg, IDC_ED_TEXTPADDING, options.text_padding, FALSE);
+ SetDlgItemInt(hwndDlg, IDC_ED_AVPADDING, options.av_padding, FALSE);
+ SetDlgItemInt(hwndDlg, IDC_ED_SBWIDTH, options.sidebar_width, FALSE);
+
+ SetDlgItemText(hwndDlg, IDC_ED_BGFN, options.bg_fn);
+ CheckDlgButton(hwndDlg, IDC_CHK_STRETCHBG, options.stretch_bg_img);
+ if(!ServiceExists(MS_IMG_LOAD)) {
+ HWND hw = GetDlgItem(hwndDlg, IDC_ED_BGFN);
+ EnableWindow(hw, FALSE);
+ hw = GetDlgItem(hwndDlg, IDC_CHK_STRETCHBG);
+ EnableWindow(hw, FALSE);
+ }
+
+ return FALSE;
+ case WM_COMMAND:
+ if ( HIWORD( wParam ) == CBN_SELCHANGE) {
+ SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
+ } else if ( HIWORD( wParam ) == EN_CHANGE && ( HWND )lParam == GetFocus()) {
+ SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
+ } else if ( HIWORD( wParam ) == BN_CLICKED ) {
+ if(LOWORD(wParam) == IDC_BTN_BROWSE) {
+ TCHAR tempBgFn[MAX_PATH];
+ tempBgFn[0] = 0;
+ OPENFILENAME ofn={0};
+ ofn.lStructSize = OPENFILENAME_SIZE_VERSION_400;
+ ofn.hwndOwner = hwndDlg;
+ ofn.lpstrFile = tempBgFn;
+ ofn.lpstrFilter=_T("All Files (*.*)\0*.*\0\0");
+ ofn.nFilterIndex = 1;
+ ofn.nMaxFile = MAX_PATH;
+ ofn.Flags=OFN_HIDEREADONLY;
+ ofn.lpstrInitialDir = _T(".");
+ ofn.lpstrDefExt=_T("");
+ if (GetOpenFileName(&ofn)) {
+ SetDlgItemText(hwndDlg, IDC_ED_BGFN, tempBgFn);
+ SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
+ }
+ } else {
+ if(LOWORD(wParam) == IDC_CHK_NORESIZEAV) {
+ bool checked = IsDlgButtonChecked(hwndDlg, IDC_CHK_NORESIZEAV) != BST_UNCHECKED;
+ HWND hw = GetDlgItem(hwndDlg, IDC_ED_AVSIZE);
+ EnableWindow(hw, !checked);
+ hw = GetDlgItem(hwndDlg, IDC_SPIN_AVSIZE);
+ EnableWindow(hw, !checked);
+ }
+ SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
+ }
+ }
+ break;
+ case WM_NOTIFY:
+ if (((LPNMHDR)lParam)->code == (unsigned)PSN_APPLY ) {
+ BOOL trans;
+ int new_val;
+ new_val = GetDlgItemInt(hwndDlg, IDC_ED_AVSIZE, &trans, FALSE);
+ if(trans) options.av_size = new_val;
+ new_val = GetDlgItemInt(hwndDlg, IDC_ED_INDENT, &trans, FALSE);
+ if(trans) options.text_indent = new_val;
+ new_val = GetDlgItemInt(hwndDlg, IDC_ED_PADDING, &trans, FALSE);
+ if(trans) options.padding = new_val;
+ new_val = GetDlgItemInt(hwndDlg, IDC_ED_TEXTPADDING, &trans, FALSE);
+ if(trans) options.text_padding = new_val;
+ new_val = GetDlgItemInt(hwndDlg, IDC_ED_AVPADDING, &trans, FALSE);
+ if(trans) options.av_padding = new_val;
+ new_val = GetDlgItemInt(hwndDlg, IDC_ED_SBWIDTH, &trans, FALSE);
+ if(trans) options.sidebar_width = new_val;
+
+ options.title_layout = (PopupTitleLayout)SendDlgItemMessage(hwndDlg, IDC_CMB_ICON, CB_GETCURSEL, 0, 0);
+ options.av_layout = (PopupAvLayout)SendDlgItemMessage(hwndDlg, IDC_CMB_AV, CB_GETCURSEL, 0, 0);
+ options.pos = (PopupPosition)SendDlgItemMessage(hwndDlg, IDC_CMB_POS, CB_GETCURSEL, 0, 0);
+
+ switch(SendDlgItemMessage(hwndDlg, IDC_CMB_LV, CB_GETCURSEL, 0, 0)) {
+ case 0: options.label_valign = DT_TOP; break;
+ case 1: options.label_valign = DT_VCENTER; break;
+ case 2: options.label_valign = DT_BOTTOM; break;
+ }
+ switch(SendDlgItemMessage(hwndDlg, IDC_CMB_VV, CB_GETCURSEL, 0, 0)) {
+ case 0: options.value_valign = DT_TOP; break;
+ case 1: options.value_valign = DT_VCENTER; break;
+ case 2: options.value_valign = DT_BOTTOM; break;
+ }
+
+ switch(SendDlgItemMessage(hwndDlg, IDC_CMB_LH, CB_GETCURSEL, 0, 0)) {
+ case 0: options.label_halign = DT_LEFT; break;
+ case 1: options.label_halign = DT_RIGHT; break;
+ }
+ switch(SendDlgItemMessage(hwndDlg, IDC_CMB_VH, CB_GETCURSEL, 0, 0)) {
+ case 0: options.value_halign = DT_LEFT; break;
+ case 1: options.value_halign = DT_RIGHT; break;
+ }
+
+ options.no_resize_av = IsDlgButtonChecked(hwndDlg, IDC_CHK_NORESIZEAV) ? true : false;
+ GetDlgItemText(hwndDlg, IDC_ED_BGFN, options.bg_fn, MAX_PATH);
+ options.stretch_bg_img = IsDlgButtonChecked(hwndDlg, IDC_CHK_STRETCHBG) ? true : false;
+
+ SaveOptions();
+ return TRUE;
+ }
+ break;
+ }
+
+ return 0;
+}
+
+int OptInit(WPARAM wParam, LPARAM lParam) {
+ OPTIONSDIALOGPAGE odp = { 0 };
+
+ odp.cbSize = sizeof(odp);
+
+ odp.flags = ODPF_BOLDGROUPS;
+ odp.position = -790000000;
+ odp.hInstance = hInst;
+ odp.pszTitle = LPGEN("Tooltips");
+ odp.pszGroup = LPGEN("Customize");
+
+ odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPT_WINDOW);
+ odp.pszTab = LPGEN("Window");
+ odp.pfnDlgProc = DlgProcOptWindow;
+ CallService( MS_OPT_ADDPAGE, wParam,( LPARAM )&odp );
+
+ odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPT_LAYOUT);
+ odp.pszTab = LPGEN("Layout");
+ odp.pfnDlgProc = DlgProcOptLayout;
+ CallService( MS_OPT_ADDPAGE, wParam,( LPARAM )&odp );
+
+ odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPT_CONTENT);
+ odp.pszTab = LPGEN("Content");
+ odp.pfnDlgProc = DlgProcOptContent;
+ CallService( MS_OPT_ADDPAGE, wParam,( LPARAM )&odp );
+
+ return 0;
+}
+
+HANDLE hEventOptInit;
+
+void InitOptions() {
+ hEventOptInit = HookEvent(ME_OPT_INITIALISE, OptInit);
+}
+
+void DeinitOptions() {
+ UnhookEvent(hEventOptInit);
+
+ DIListNode *di_node = options.di_list;
+ while(options.di_list) {
+ di_node = options.di_list;
+ options.di_list = options.di_list->next;
+ free(di_node);
+ }
+
+ DSListNode *ds_node = options.ds_list;
+ while(options.ds_list) {
+ ds_node = options.ds_list;
+ options.ds_list = options.ds_list->next;
+ free(ds_node);
+ }
+}
diff --git a/plugins/tipper/options.h b/plugins/tipper/options.h
new file mode 100644
index 0000000000..a1ccf4d911
--- /dev/null
+++ b/plugins/tipper/options.h
@@ -0,0 +1,77 @@
+#ifndef _OPTIONS_INC
+#define _OPTIONS_INC
+
+#include "translations.h"
+
+#define LABEL_LEN 1024
+#define VALUE_LEN 8192
+
+#define MODULE_NAME_LEN 512
+#define SETTING_NAME_LEN 512
+
+typedef struct {
+ TCHAR label[LABEL_LEN];
+ TCHAR value[VALUE_LEN];
+ bool line_above, value_newline;
+} DisplayItem;
+
+typedef enum {DVT_DB = 0, DVT_PROTODB = 1} DisplaySubstType;
+typedef struct {
+ TCHAR name[LABEL_LEN];
+ DisplaySubstType type;
+ char module_name[MODULE_NAME_LEN];
+ char setting_name[SETTING_NAME_LEN];
+ int translate_func_id;
+} DisplaySubst;
+
+struct DSListNode {
+ DisplaySubst ds;
+ DSListNode *next;
+};
+
+struct DIListNode {
+ DisplayItem di;
+ DIListNode *next;
+};
+
+typedef enum {PAV_NONE=0, PAV_LEFT=1, PAV_RIGHT=2} PopupAvLayout;
+typedef enum {PTL_LEFTICON=0, PTL_RIGHTICON=1, PTL_NOICON=2, PTL_NOTITLE=3} PopupTitleLayout;
+typedef enum {PP_BOTTOMRIGHT=0, PP_BOTTOMLEFT=1, PP_TOPRIGHT=2, PP_TOPLEFT=3} PopupPosition;
+
+typedef struct {
+ int win_width, win_max_height, av_size; //tweety
+ int opacity;
+ bool border;
+ bool round, av_round;
+ bool animate;
+ bool drop_shadow;
+ bool trans_bg;
+ PopupTitleLayout title_layout;
+ PopupAvLayout av_layout;
+ int text_indent;
+ bool show_no_focus;
+ DSListNode *ds_list;
+ int ds_count;
+ DIListNode *di_list;
+ int di_count;
+ int time_in;
+ int padding, av_padding, text_padding;
+ PopupPosition pos;
+ int min_width, min_height; // no UI for these
+ int mouse_tollerance;
+ bool status_bar_tips;
+ int sidebar_width;
+ COLORREF bg_col, border_col, div_col, bar_col, title_col, label_col, value_col, sidebar_col;
+ int label_valign, label_halign, value_valign, value_halign;
+ bool no_resize_av;
+ TCHAR bg_fn[MAX_PATH];
+ bool stretch_bg_img;
+} Options;
+
+extern Options options;
+
+void InitOptions();
+void LoadOptions();
+void DeinitOptions();
+
+#endif
diff --git a/plugins/tipper/popwin.cpp b/plugins/tipper/popwin.cpp
new file mode 100644
index 0000000000..109c6f1bd1
--- /dev/null
+++ b/plugins/tipper/popwin.cpp
@@ -0,0 +1,937 @@
+#include "common.h"
+#include "subst.h"
+#include "popwin.h"
+#include "message_pump.h"
+#include "str_utils.h"
+
+#define TITLE_TEXT_LEN 512
+
+#define ANIM_STEPS 20
+#define ANIM_ELAPSE 10
+
+#define CHECKMOUSE_ELAPSE 250
+
+#define ID_TIMER_ANIMATE 0x0100
+#define ID_TIMER_CHECKMOUSE 0x0101
+
+typedef struct {
+ TCHAR *swzLabel, *swzValue;
+ bool value_newline;
+ bool line_above;
+ int label_height, value_height, total_height;
+} RowData;
+
+struct PopupWindowData {
+ HBRUSH bkBrush, barBrush;
+ HPEN bPen, dPen;
+ int tb_height, av_height, text_height, sm_height, lm_height, label_width;
+ int real_av_width, real_av_height;
+ //TCHAR *lm_text, *sm_text;
+ HANDLE hContact;
+ int iconIndex;
+ CLCINFOTIPEX clcit;
+ TCHAR swzTitle[TITLE_TEXT_LEN];
+ RowData *rows;
+ int row_count;
+ int anim_step;
+ bool text_tip;
+ int indent, sb_width;
+ POINT start_cursor_pos; // work around bugs with hiding tips (timer check mouse position)
+ HBITMAP hBm;
+};
+
+LRESULT CALLBACK PopupWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
+ PopupWindowData *pwd = (PopupWindowData *)GetWindowLongPtr(hwnd, GWLP_USERDATA);
+
+ switch(uMsg) {
+ case WM_CREATE:
+ {
+
+ CREATESTRUCT *cs = (CREATESTRUCT *)lParam;
+ pwd = (PopupWindowData *)malloc(sizeof(PopupWindowData));
+ memset(pwd, 0, sizeof(PopupWindowData));
+ pwd->clcit = *(CLCINFOTIPEX *)cs->lpCreateParams;
+ pwd->iconIndex = -1;
+ pwd->bkBrush = CreateSolidBrush(options.bg_col);
+ pwd->barBrush = CreateSolidBrush(options.sidebar_col);
+ pwd->bPen = options.border ? (HPEN)CreatePen(PS_SOLID, 1, options.border_col) : (HPEN)CreatePen(PS_SOLID, 1, options.bg_col);
+ pwd->dPen = (HPEN)CreatePen(PS_SOLID, 1, options.div_col);
+
+ SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)pwd);
+
+ // work around bug hiding tips
+ GetCursorPos(&pwd->start_cursor_pos);
+ SetTimer(hwnd, ID_TIMER_CHECKMOUSE, CHECKMOUSE_ELAPSE, 0);
+
+ if(pwd->clcit.proto) {
+ pwd->text_tip = false;
+ pwd->indent = options.text_indent;
+ pwd->sb_width = options.sidebar_width;
+
+ a2t(pwd->clcit.proto, pwd->swzTitle, TITLE_TEXT_LEN);
+
+ TCHAR uid_buff[256], uid_name_buff[256];
+ if(uid(0, pwd->clcit.proto, uid_buff, 256) && uid_name(pwd->clcit.proto, uid_name_buff, 253)) { // 253 to leave room for ': '
+ _tcscat(uid_name_buff, _T(": "));
+
+ pwd->rows = (RowData *) realloc(pwd->rows, sizeof(RowData) * (pwd->row_count + 1));
+
+ pwd->rows[pwd->row_count].swzLabel = _tcsdup(uid_name_buff);
+ pwd->rows[pwd->row_count].swzValue = _tcsdup(uid_buff);
+ pwd->rows[pwd->row_count].value_newline = false;
+ pwd->rows[pwd->row_count].line_above = false;
+ pwd->row_count++;
+ }
+
+ WORD status = CallProtoService(pwd->clcit.proto, PS_GETSTATUS, 0, 0);
+ TCHAR *strptr = (TCHAR *)CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, status, GSMDF_TCHAR);
+ if (strptr)
+ {
+ pwd->rows = (RowData *) realloc(pwd->rows, sizeof(RowData) * (pwd->row_count + 1));
+
+ pwd->rows[pwd->row_count].swzLabel = _tcsdup(TranslateT("Status:"));
+ pwd->rows[pwd->row_count].swzValue = _tcsdup(strptr);
+ pwd->rows[pwd->row_count].value_newline = false;
+ pwd->rows[pwd->row_count].line_above = false;
+ pwd->row_count++;
+ }
+
+ if(status >= ID_STATUS_OFFLINE && status <= ID_STATUS_IDLE)
+ {
+ TCHAR *swzText = 0;
+ char *status_msg = 0;
+
+ // supported by protocols from Miranda 0.8+
+ TCHAR* p = (TCHAR *)CallProtoService(pwd->clcit.proto, PS_GETMYAWAYMSG, 0, SGMA_TCHAR);
+ if ((INT_PTR)p != CALLSERVICE_NOTFOUND)
+ {
+ if (p == NULL)
+ status_msg = (char *)CallProtoService(pwd->clcit.proto, PS_GETMYAWAYMSG, 0, 0);
+ else
+ {
+ swzText = _tcsdup( p );
+ mir_free( p );
+ }
+ }
+ else
+ status_msg = (char *)CallService(MS_AWAYMSG_GETSTATUSMSG, status, 0);
+
+ if(status_msg && status_msg[0]) swzText = a2t(status_msg);
+
+ if(swzText && swzText[0]) {
+ StripBBCodesInPlace(swzText);
+ pwd->rows = (RowData *) realloc(pwd->rows, sizeof(RowData) * (pwd->row_count + 1));
+
+ pwd->rows[pwd->row_count].swzLabel = _tcsdup(TranslateT("Status message:"));
+ pwd->rows[pwd->row_count].swzValue = swzText;
+ pwd->rows[pwd->row_count].value_newline = true;
+ pwd->rows[pwd->row_count].line_above = true;
+ pwd->row_count++;
+
+ }
+
+ if(status_msg) mir_free(status_msg);
+ }
+ } else if(pwd->clcit.text) {
+ pwd->text_tip = true;
+ pwd->indent = 0;
+ pwd->sb_width = 0;
+
+
+ //MessageBox(0, swzText, _T("tip"), MB_OK);
+
+ TCHAR buff[2048], *swzText = pwd->clcit.text;
+ int buff_pos, i = 0, size = (int)_tcslen(pwd->clcit.text);
+ bool top_message = false;
+
+ while(i < size && swzText[i] != _T('<')) {
+ buff_pos = 0;
+ while(swzText[i] != _T('\n') && swzText[i] != _T('\r') && i < size && buff_pos < 2048) {
+ if(swzText[i] != _T('\t'))
+ buff[buff_pos++] = swzText[i];
+ i++;
+ }
+ buff[buff_pos] = 0;
+
+ if(buff_pos) {
+ pwd->rows = (RowData *)realloc(pwd->rows, sizeof(RowData) * (pwd->row_count + 1));
+ pwd->rows[pwd->row_count].line_above = false;
+ pwd->rows[pwd->row_count].value_newline = true;
+ pwd->rows[pwd->row_count].swzLabel = _tcsdup(_T(""));
+ pwd->rows[pwd->row_count].swzValue = _tcsdup(buff);
+ pwd->row_count++;
+ top_message = true;
+ }
+ while(i < size && (swzText[i] == _T('\n') || swzText[i] == _T('\r')))
+ i++;
+ }
+
+ // parse bold bits into labels and the rest into items
+ while(i < size) {
+ while(i + 2 < size
+ && (swzText[i] != _T('<')
+ || swzText[i + 1] != _T('b')
+ || swzText[i + 2] != _T('>')))
+ {
+ i++;
+ }
+
+ i += 3;
+
+ buff_pos = 0;
+ while(i + 3 < size
+ && buff_pos < 2048
+ && (swzText[i] != _T('<')
+ || swzText[i + 1] != _T('/')
+ || swzText[i + 2] != _T('b')
+ || swzText[i + 3] != _T('>')))
+ {
+ if(swzText[i] != _T('\t'))
+ buff[buff_pos++] = swzText[i];
+ i++;
+ }
+
+ i += 4;
+
+ buff[buff_pos] = 0;
+
+ if(buff_pos) {
+ pwd->rows = (RowData *)realloc(pwd->rows, sizeof(RowData) * (pwd->row_count + 1));
+ pwd->rows[pwd->row_count].value_newline = false;
+ pwd->rows[pwd->row_count].swzLabel = _tcsdup(buff);
+ if(pwd->row_count == 1 && top_message)
+ pwd->rows[pwd->row_count].line_above = true;
+ else
+ pwd->rows[pwd->row_count].line_above = false;
+
+ buff_pos = 0;
+ while(i < size
+ && buff_pos < 2048
+ && swzText[i] != _T('\n'))
+ {
+ if(swzText[i] != _T('\t') && swzText[i] != _T('\r'))
+ buff[buff_pos++] = swzText[i];
+ i++;
+ }
+ buff[buff_pos] = 0;
+
+ pwd->rows[pwd->row_count].swzValue = _tcsdup(buff);
+
+ pwd->row_count++;
+ }
+
+ i++;
+ }
+
+ if(pwd->row_count == 0) {
+ // single item
+ pwd->row_count = 1;
+ pwd->rows = (RowData *)malloc(sizeof(RowData));
+ pwd->rows[0].line_above = pwd->rows[0].value_newline = false;
+ pwd->rows[0].swzLabel = 0;
+ pwd->rows[0].swzValue = _tcsdup(swzText);
+ }
+
+ free(pwd->clcit.text);
+ pwd->clcit.text = 0;
+ } else {
+ pwd->text_tip = false;
+ pwd->indent = options.text_indent;
+ pwd->sb_width = options.sidebar_width;
+ pwd->hContact = pwd->clcit.hItem;
+ pwd->iconIndex = (int)CallService(MS_CLIST_GETCONTACTICON, (WPARAM)pwd->hContact, 0);
+
+ CallContactService(pwd->hContact, PSS_GETINFO, SGIF_ONOPEN, 0);
+
+ // don't use stored status message
+ // problem with delete setting?
+ //DBDeleteContactSetting(pwd->hContact, MODULE, "TempStatusMsg");
+ DBWriteContactSettingTString(pwd->hContact, MODULE, "TempStatusMsg", _T(""));
+
+ TCHAR *stzCDN = (TCHAR *) CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)pwd->hContact, GCDNF_TCHAR);
+
+ if(stzCDN) _tcsncpy(pwd->swzTitle, stzCDN, TITLE_TEXT_LEN);
+ else _tcscpy(pwd->swzTitle, TranslateT("(Unknown)"));
+
+ //get avatar if possible
+ PROTO_AVATAR_INFORMATION AI = { sizeof(AI), pwd->hContact };
+ char *szProto = (char*)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)pwd->hContact, 0);
+ CallProtoService(szProto, PS_GETAVATARINFO, GAIF_FORCE, (LPARAM)&AI);
+ SendMessage(hwnd, PUM_REFRESH_VALUES, 0, 0);
+ }
+ }
+
+ // transparency
+#ifdef WS_EX_LAYERED
+ SetWindowLong(hwnd, GWL_EXSTYLE, GetWindowLong(hwnd, GWL_EXSTYLE) | WS_EX_LAYERED);
+#endif
+
+// not defined in my mingw winuser.h
+#ifdef __GNUC__
+#define CS_DROPSHADOW 0x00020000
+#endif
+#ifdef CS_DROPSHADOW
+ if (options.drop_shadow) SetClassLong(hwnd, GCL_STYLE, CS_DROPSHADOW);
+ else SetClassLong(hwnd, GCL_STYLE, 0);
+#endif
+
+#ifdef LWA_ALPHA
+ if(MySetLayeredWindowAttributes) {
+ MySetLayeredWindowAttributes(hwnd, RGB(0,0,0), (int)(options.opacity / 100.0 * 255), LWA_ALPHA);
+ if(options.trans_bg) {
+ MySetLayeredWindowAttributes(hwnd, options.bg_col, 0, LWA_COLORKEY);
+ }
+ }
+#endif
+ SendMessage(hwnd, PUM_GETHEIGHT, 0, 0); // calculate window height
+ SendMessage(hwnd, PUM_CALCPOS, 0, 0);
+
+ if(options.animate)
+ SetTimer(hwnd, ID_TIMER_ANIMATE, ANIM_ELAPSE, 0);
+
+ ShowWindow(hwnd, SW_SHOWNOACTIVATE);
+ UpdateWindow(hwnd);
+ /*
+ // move clist under?
+ {
+ HWND hwndClist = (HWND)CallService(MS_CLUI_GETHWND, 0, 0);
+ if(GetWindowLong(hwndClist, GWL_EXSTYLE) & WS_EX_TOPMOST)
+ SetWindowPos(hwndClist, hwnd, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
+ }
+ */
+ // since tipper win is topmost, this should put it at top of topmost windows
+ SetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
+ return 0;
+ case WM_ERASEBKGND:
+ {
+ HDC hdc = (HDC) wParam;
+ RECT r, r_bar;
+ GetClientRect(hwnd, &r);
+
+ // bg
+ if (options.bg_fn[0])
+ {
+ BITMAP bm;
+ HBITMAP hBg = (HBITMAP)CallService(MS_IMG_LOAD, (WPARAM)options.bg_fn, IMGL_TCHAR);
+ if(hBg) {
+ HDC hdcMem = CreateCompatibleDC(hdc);
+ HBITMAP hbmOld = (HBITMAP)SelectObject(hdcMem, hBg);
+
+ GetObject(hBg, sizeof(bm), &bm);
+
+ if(options.stretch_bg_img) {
+ StretchBlt(hdc, pwd->sb_width, 0, r.right, r.bottom, hdcMem, 0, 0, bm.bmWidth, bm.bmHeight, SRCCOPY);
+ } else {
+ BitBlt(hdc, pwd->sb_width, 0, r.right, r.bottom, hdcMem, 0, 0, SRCCOPY);
+ }
+
+ SelectObject(hdcMem, hbmOld);
+ DeleteDC(hdcMem);
+ DeleteObject(hBg);
+ } else
+ FillRect(hdc, &r, pwd->bkBrush);
+ } else
+ FillRect(hdc, &r, pwd->bkBrush);
+
+ // sidebar
+ r_bar = r;
+ r_bar.right = r.left + pwd->sb_width;
+ FillRect(hdc, &r_bar, pwd->barBrush);
+ // border
+ if(options.border) {
+
+ HBRUSH hOldBrush = (HBRUSH)SelectObject(hdc, GetStockObject(NULL_BRUSH));
+ HPEN hOldPen = (HPEN)SelectObject(hdc, pwd->bPen);
+
+ int h = 0;
+ if(options.round) {
+ int v;
+ int w=14;
+ h=(r.right-r.left)>(w*2)?w:(r.right-r.left);
+ v=(r.bottom-r.top)>(w*2)?w:(r.bottom-r.top);
+ h=(h<v)?h:v;
+ //} else {
+ // Rectangle(hdc, r.left, r.top, (r.right - r.left), (r.bottom - r.top));
+ }
+ RoundRect(hdc, 0, 0, (r.right - r.left), (r.bottom - r.top), h, h);
+
+ SelectObject(hdc, hOldBrush);
+ SelectObject(hdc, hOldPen);
+ }
+ }
+ return TRUE;
+ case WM_PAINT:
+ {
+ RECT r, r2;
+ //if(GetUpdateRect(hwnd, &r, TRUE)) {
+ PAINTSTRUCT ps;
+ BeginPaint(hwnd, &ps);
+ HDC hdc = ps.hdc;
+ GetClientRect(hwnd, &r);
+ r2 = r;
+ HFONT hOldFont = (HFONT)GetCurrentObject(hdc,OBJ_FONT);
+
+ // text background
+ //SetBkColor(ps.hdc, options.bg_col);
+ SetBkMode(hdc, TRANSPARENT);
+
+ // avatar
+ if(!pwd->text_tip && options.av_layout != PAV_NONE && pwd->av_height && pwd->hBm) {
+ RECT avr;
+ avr.top = options.av_padding;
+
+ if(options.av_layout == PAV_LEFT) {
+ avr.left = r.left + options.av_padding;
+ avr.right = avr.left + pwd->real_av_width;
+ r2.left += pwd->real_av_width + (2 * options.av_padding - options.padding); // padding re-added for text
+ } else if(options.av_layout == PAV_RIGHT) {
+ avr.right = r.right - options.av_padding;
+ avr.left = avr.right - pwd->real_av_width;
+ r2.right -= pwd->real_av_width + (2 * options.av_padding - options.padding);
+ }
+
+ avr.bottom = avr.top + pwd->real_av_height;
+
+ HDC hdcMem = CreateCompatibleDC(hdc);
+ HBITMAP hbmOld = (HBITMAP)SelectObject(hdcMem, pwd->hBm);
+ BITMAP bm;
+
+ GetObject(pwd->hBm, sizeof(bm), &bm);
+ HRGN rgn = 0;
+ if(options.av_round) {
+ rgn = CreateRoundRectRgn(avr.left, avr.top, avr.right + 1, avr.bottom + 1, 10, 10);
+ SelectClipRgn(hdc, rgn);
+ }
+
+ if(options.no_resize_av) {
+ BitBlt(hdc, avr.left, avr.top, avr.right - avr.left, avr.bottom - avr.top, hdcMem, 0, 0, SRCCOPY);
+ } else {
+ SetStretchBltMode(hdc, HALFTONE);
+ StretchBlt(hdc, avr.left, avr.top, avr.right - avr.left, avr.bottom - avr.top, hdcMem, 0, 0, bm.bmWidth, bm.bmHeight, SRCCOPY);
+ }
+
+ if(rgn) {
+ SelectClipRgn(hdc, 0);
+ DeleteObject(rgn);
+ }
+
+ SelectObject(hdcMem, hbmOld);
+ DeleteDC(hdcMem);
+
+ /*
+ AVATARDRAWREQUEST adr = {0};
+ adr.cbSize = sizeof(adr);
+ adr.hContact = pwd->hContact;
+ adr.hTargetDC = ps.hdc;
+ adr.rcDraw = avr;
+ adr.dwFlags = (options.av_round ? AVDRQ_ROUNDEDCORNER : 0);// | (options.no_resize_av ? AVDRQ_DONTRESIZEIFSMALLER : 0);
+ if(!pwd->hContact) { // status bar tip?
+ adr.dwFlags |= AVDRQ_OWNPIC;
+ adr.szProto = pwd->clcit.proto;
+ }
+ adr.radius = (options.av_round ? 5 : 0);
+
+ CallService(MS_AV_DRAWAVATAR, 0, (LPARAM)&adr);
+ */
+ }
+
+ RECT tr;
+ tr.left = r2.left + options.padding; tr.right = r2.right - options.padding; tr.top = tr.bottom = 0;
+ if(!pwd->text_tip && options.title_layout != PTL_NOTITLE) {
+ // title icon
+ if(options.title_layout != PTL_NOICON) {
+ HICON hIcon = 0;
+ bool destroy_icon = true;
+ if(pwd->iconIndex != -1) hIcon = ImageList_GetIcon((HIMAGELIST)CallService(MS_CLIST_GETICONSIMAGELIST, 0, 0), pwd->iconIndex, 0);
+ else if(!pwd->hContact) {
+ WORD status = CallProtoService(pwd->clcit.proto, PS_GETSTATUS, 0, 0);
+ hIcon = LoadSkinnedProtoIcon(pwd->clcit.proto, status);
+ destroy_icon = false;
+ }
+ if(hIcon) {
+ int iconx;
+ if(options.title_layout == PTL_RIGHTICON) {
+ iconx = r2.right - 16 - options.padding;
+ tr.right -= 16 + options.padding;
+ } else {
+ iconx = r2.left + options.padding;
+ tr.left += 16 + options.padding;
+ }
+ DrawIconEx(ps.hdc, iconx, options.padding + (pwd->tb_height - options.padding - 16) / 2, hIcon, 16, 16, 0, NULL, DI_NORMAL);
+ if(destroy_icon) DestroyIcon(hIcon);
+ }
+ }
+
+ // title text
+ if(hFontTitle) SelectObject(ps.hdc, (HGDIOBJ)hFontTitle);
+
+ SetTextColor(ps.hdc, options.title_col);
+
+ tr.top = r.top + options.padding; tr.bottom = tr.top + pwd->tb_height - options.padding;
+ DrawText(ps.hdc, pwd->swzTitle, (int)_tcslen(pwd->swzTitle), &tr, DT_VCENTER | DT_LEFT | DT_END_ELLIPSIS | DT_SINGLELINE | DT_NOPREFIX);
+ }
+
+ // values
+ pwd->text_height = 0;
+ bool use_r = true;
+ int row_height;
+ for(int i = 0; i < pwd->row_count; i++) {
+ tr.top = tr.bottom;
+ use_r = (tr.top + options.text_padding >= pwd->av_height);
+
+ if(use_r) {
+ if(pwd->rows[i].line_above) {
+ HPEN hOldPen = (HPEN)SelectObject(hdc, pwd->dPen);
+ tr.top += options.text_padding;
+ Rectangle(hdc, r.left + options.padding + pwd->indent, tr.top, r.right - options.padding, tr.top + 1);
+ SelectObject(hdc, hOldPen);
+ }
+ tr.left = r.left + options.padding + pwd->indent;
+ if(pwd->rows[i].value_newline)
+ tr.right = r.right - options.padding;
+ else
+ tr.right = r.left + options.padding + pwd->indent + pwd->label_width;
+ } else {
+ if(pwd->rows[i].line_above) {
+ HPEN hOldPen = (HPEN)SelectObject(hdc, pwd->dPen);
+ tr.top += options.text_padding;
+ Rectangle(hdc, r2.left + options.padding + pwd->indent, tr.top, r2.right - options.padding, tr.top + 1);
+ SelectObject(hdc, hOldPen);
+ }
+ tr.left = r2.left + options.padding + pwd->indent;
+ if(pwd->rows[i].value_newline)
+ tr.right = r2.right - options.padding;
+ else
+ tr.right = r2.left + options.padding + pwd->indent + pwd->label_width;
+ }
+
+ if(pwd->rows[i].value_newline)
+ row_height = pwd->rows[i].label_height;
+ else
+ row_height = max(pwd->rows[i].label_height, pwd->rows[i].value_height);
+
+ if(hFontLabels) SelectObject(hdc, (HGDIOBJ)hFontLabels);
+ if(pwd->rows[i].label_height) {
+ tr.top += options.text_padding;
+ tr.bottom = tr.top + row_height;
+ SetTextColor(ps.hdc, options.label_col);
+ DrawText(ps.hdc, pwd->rows[i].swzLabel, (int)_tcslen(pwd->rows[i].swzLabel), &tr, options.label_valign | ((options.label_halign == DT_RIGHT && !pwd->rows[i].value_newline) ? DT_RIGHT : DT_LEFT) | DT_END_ELLIPSIS | DT_SINGLELINE | DT_NOPREFIX);
+ if(pwd->rows[i].value_newline)
+ tr.top = tr.bottom;
+ } else
+ tr.bottom = tr.top;
+
+ if(pwd->rows[i].value_newline)
+ row_height = pwd->rows[i].value_height;
+
+ if(hFontValues) SelectObject(hdc, (HGDIOBJ)hFontValues);
+ SetTextColor(ps.hdc, options.value_col);
+ if(use_r) {
+ if(pwd->rows[i].value_newline)
+ tr.left = r.left + options.padding + pwd->indent;
+ else
+ tr.left = r.left + options.padding + pwd->indent + pwd->label_width + options.padding;
+ tr.right = r.right - options.padding;
+ } else {
+ if(pwd->rows[i].value_newline)
+ tr.left = r2.left + options.padding + pwd->indent;
+ else
+ tr.left = r2.left + options.padding + pwd->indent + pwd->label_width + options.padding;
+ tr.right = r2.right - options.padding;
+ }
+ if(pwd->rows[i].value_height) {
+ if(pwd->rows[i].value_newline || !pwd->rows[i].label_height) tr.top += options.text_padding;
+ tr.bottom = tr.top + row_height;
+ DrawText(ps.hdc, pwd->rows[i].swzValue, (int)_tcslen(pwd->rows[i].swzValue), &tr, options.value_valign | options.value_halign | DT_WORDBREAK | DT_WORD_ELLIPSIS | DT_END_ELLIPSIS | DT_NOPREFIX);
+ }
+ }
+
+ SelectObject(hdc, hOldFont);
+ EndPaint(hwnd, &ps);
+ //}
+ }
+ return 0;
+ case WM_DESTROY:
+ {
+ KillTimer(hwnd, ID_TIMER_CHECKMOUSE);
+ KillTimer(hwnd, ID_TIMER_ANIMATE);
+ ShowWindow(hwnd, SW_HIDE);
+
+ DeleteObject(pwd->bkBrush);
+ DeleteObject(pwd->barBrush);
+ DeleteObject(pwd->bPen);
+ DeleteObject(pwd->dPen);
+
+ for(int i = 0; i < pwd->row_count; i++) {
+ free(pwd->rows[i].swzLabel);
+ free(pwd->rows[i].swzValue);
+ }
+ if(pwd->rows) free(pwd->rows);
+
+ free(pwd); pwd = 0;
+ SetWindowLongPtr(hwnd, GWLP_USERDATA, 0);
+ }
+ break;
+
+ case WM_TIMER:
+ if(wParam == ID_TIMER_ANIMATE) {
+ pwd->anim_step++;
+ if(pwd->anim_step == ANIM_STEPS)
+ KillTimer(hwnd, ID_TIMER_ANIMATE);
+ SendMessage(hwnd, PUM_UPDATERGN, 0, 0);
+ InvalidateRect(hwnd, 0, TRUE);
+ UpdateWindow(hwnd);
+ } else if(wParam == ID_TIMER_CHECKMOUSE) {
+ // workaround for tips that just won't go away
+
+ POINT pt;
+ GetCursorPos(&pt);
+
+ /*
+ // works well, except in e.g. options->events->ignore :(
+ bool hide = false;
+ if(pwd->text_tip) {
+ // tip may be off clist (e.g. systray)
+ if(pt.x != pwd->start_cursor_pos.x || pt.y != pwd->start_cursor_pos.y) // mouse has moved
+ hide = false;
+ } else {
+ // check window under cursor - hide if not clist
+ HWND hwnd_clist = (HWND)CallService(MS_CLUI_GETHWND, 0, 0),
+ hwnd_under = WindowFromPoint(pt);
+ if(hwnd_under != hwnd_clist && !IsChild(hwnd_clist, hwnd_under))
+ hide = true;
+ }
+ if(hide) PostMPMessage(MUM_DELETEPOPUP, 0, 0);
+ */
+
+ if(abs(pt.x - pwd->start_cursor_pos.x) > options.mouse_tollerance
+ || abs(pt.y - pwd->start_cursor_pos.y) > options.mouse_tollerance) // mouse has moved beyond tollerance
+ {
+ PostMPMessage(MUM_DELETEPOPUP, 0, 0);
+ }
+ }
+ break;
+
+ case PUM_SETSTATUSTEXT:
+ if (pwd && (HANDLE)wParam == pwd->hContact)
+ {
+ // in case we have the status message in a row
+ DBVARIANT dbv;
+ if (!DBGetContactSettingTString(pwd->hContact, MODULE, "TempStatusMsg", &dbv))
+ {
+ if (_tcscmp(dbv.ptszVal, (TCHAR*)lParam))
+ {
+ DBWriteContactSettingTString(pwd->hContact, MODULE, "TempStatusMsg", (TCHAR*)lParam);
+ SendMessage(hwnd, PUM_REFRESH_VALUES, 0, 0);
+ }
+ DBFreeVariant(&dbv);
+ }
+ }
+ if(lParam) free((void *)lParam);
+ return TRUE;
+
+ case PUM_SETAVATAR:
+ if(pwd && (HANDLE)wParam == pwd->hContact) {
+ SendMessage(hwnd, PUM_GETHEIGHT, 0, 0); // calculate window height
+ SendMessage(hwnd, PUM_CALCPOS, 0, 0);
+ InvalidateRect(hwnd, 0, TRUE);
+ }
+ return TRUE;
+
+ case PUM_REFRESH_VALUES:
+ if(pwd && pwd->clcit.proto == 0 && pwd->text_tip == false) {
+ for(int i = 0; i < pwd->row_count; i++) {
+ free(pwd->rows[i].swzLabel);
+ free(pwd->rows[i].swzValue);
+ }
+ if(pwd->rows) {
+ free(pwd->rows);
+ pwd->rows = 0;
+ }
+ pwd->row_count = 0;
+
+ DIListNode *node = options.di_list;
+ TCHAR buff_label[LABEL_LEN], buff[VALUE_LEN];
+ while(node) {
+ if(GetLabelText(pwd->hContact, node->di, buff_label, LABEL_LEN) && GetValueText(pwd->hContact, node->di, buff, VALUE_LEN)) {
+ if(node->di.line_above // we have a line above
+ && pwd->row_count > 0 // and we're not the first row
+ && pwd->rows[pwd->row_count - 1].line_above // and above us there's a line above
+ && pwd->rows[pwd->row_count - 1].swzLabel[0] == 0 // with no label
+ && pwd->rows[pwd->row_count - 1].swzValue[0] == 0) // and no value
+ {
+ // overwrite item above
+ pwd->row_count--;
+ free(pwd->rows[pwd->row_count].swzLabel);
+ free(pwd->rows[pwd->row_count].swzValue);
+ } else
+ pwd->rows = (RowData *) realloc(pwd->rows, sizeof(RowData) * (pwd->row_count + 1));
+
+ pwd->rows[pwd->row_count].swzLabel = _tcsdup(buff_label);
+ pwd->rows[pwd->row_count].swzValue = _tcsdup(buff);
+ pwd->rows[pwd->row_count].value_newline = node->di.value_newline;
+ pwd->rows[pwd->row_count].line_above = node->di.line_above;
+ pwd->row_count++;
+ }
+ node = node->next;
+ }
+
+ // if the last item is just a divider, remove it
+ if(pwd->row_count > 0
+ && pwd->rows[pwd->row_count - 1].line_above // and above us there's a line above
+ && pwd->rows[pwd->row_count - 1].swzLabel[0] == 0 // with no label
+ && pwd->rows[pwd->row_count - 1].swzValue[0] == 0) // and no value
+ {
+ pwd->row_count--;
+ free(pwd->rows[pwd->row_count].swzLabel);
+ free(pwd->rows[pwd->row_count].swzValue);
+
+ if(pwd->row_count == 0) {
+ free(pwd->rows);
+ pwd->rows = NULL;
+ }
+ }
+
+ SendMessage(hwnd, PUM_GETHEIGHT, 0, 0); // calculate window height
+ SendMessage(hwnd, PUM_CALCPOS, 0, 0);
+ InvalidateRect(hwnd, 0, TRUE);
+ }
+ return TRUE;
+ case PUM_GETHEIGHT:
+ {
+ int *pHeight = (int *)wParam;
+ HDC hdc = GetDC(hwnd);
+ SIZE size;
+ RECT r;
+ r.top = r.left = 0;
+ r.right = options.win_width;
+ int width = options.padding;
+ HFONT hOldFont = (HFONT)GetCurrentObject(hdc,OBJ_FONT);
+
+ // titlebar height
+ if(!pwd->text_tip && pwd->swzTitle && options.title_layout != PTL_NOTITLE) {
+ if(hFontTitle) SelectObject(hdc, (HGDIOBJ)hFontTitle);
+ GetTextExtentPoint32(hdc, pwd->swzTitle, (int)_tcslen(pwd->swzTitle), &size);
+ width += options.padding + size.cx;
+ if(options.title_layout != PTL_NOICON) {
+ pwd->tb_height = options.padding + max(size.cy, 16);
+ width += 16 + options.padding;
+ } else
+ pwd->tb_height = options.padding + size.cy;
+ } else
+ pwd->tb_height = 0;
+
+ // avatar height
+ pwd->av_height = 0;
+ if (!pwd->text_tip && options.av_layout != PAV_NONE && ServiceExists(MS_AV_DRAWAVATAR))
+ {
+ AVATARCACHEENTRY *ace = 0;
+ if (pwd->hContact) ace = (AVATARCACHEENTRY *)CallService(MS_AV_GETAVATARBITMAP, (WPARAM)pwd->hContact, 0);
+ else ace = (AVATARCACHEENTRY *)CallService(MS_AV_GETMYAVATAR, 0, (LPARAM)pwd->clcit.proto);
+
+ if (ace && (ace->dwFlags & AVS_BITMAP_VALID) && !(ace->dwFlags & AVS_HIDEONCLIST))
+ {
+ pwd->hBm = ace->hbmPic;
+ if (options.no_resize_av || (ace->bmHeight <= options.av_size && ace->bmWidth <= options.av_size)) {
+ pwd->real_av_width = ace->bmWidth;
+ pwd->real_av_height = ace->bmHeight;
+ } else {
+ if (ace->bmHeight >= ace->bmWidth) {
+ pwd->real_av_height = options.av_size;
+ pwd->real_av_width = options.av_size * ace->bmWidth / ace->bmHeight;
+ } else {
+ pwd->real_av_height = options.av_size * ace->bmHeight / ace->bmWidth;
+ pwd->real_av_width = options.av_size;
+ }
+ }
+ pwd->av_height = options.av_padding * 2 + pwd->real_av_height;
+ width += pwd->real_av_width + (2 * options.av_padding - options.padding);
+ }
+ }
+
+ int i;
+ // text height
+ pwd->text_height = pwd->label_width = 0;
+ // iterate once to find max label width for items with label and value on same line, but don't consider width of labels on a new line
+ for(i = 0; i < pwd->row_count; i++) {
+ if(pwd->rows[i].swzLabel && pwd->rows[i].value_newline == false) {
+ if(hFontLabels) SelectObject(hdc, (HGDIOBJ)hFontLabels);
+ GetTextExtentPoint32(hdc, pwd->rows[i].swzLabel, (int)_tcslen(pwd->rows[i].swzLabel), &size);
+ if(size.cx > pwd->label_width)
+ pwd->label_width = size.cx;
+ }
+ }
+
+ for(i = 0; i < pwd->row_count; i++) {
+ if(hFontLabels) SelectObject(hdc, (HGDIOBJ)hFontLabels);
+ if(pwd->rows[i].swzLabel)
+ GetTextExtentPoint32(hdc, pwd->rows[i].swzLabel, (int)_tcslen(pwd->rows[i].swzLabel), &size);
+ else
+ size.cy = size.cx = 0;
+
+ // save so we don't have to recalculate
+ pwd->rows[i].label_height = size.cy;
+
+ if(hFontValues) SelectObject(hdc, (HGDIOBJ)hFontValues);
+ RECT smr;
+ smr.top = smr.bottom = 0;
+ smr.left = r.left + options.padding + pwd->indent;
+ smr.right = r.right;
+ if(pwd->tb_height + pwd->text_height + options.text_padding < pwd->av_height)
+ smr.right -= pwd->real_av_width + 2 * options.av_padding;
+ else
+ smr.right -= options.padding;
+ if(!pwd->rows[i].value_newline) smr.right -= pwd->label_width + options.padding;
+ if(pwd->rows[i].swzValue)
+ DrawText(hdc, pwd->rows[i].swzValue, (int)_tcslen(pwd->rows[i].swzValue), &smr, DT_CALCRECT | DT_VCENTER | DT_LEFT | DT_WORDBREAK | DT_WORD_ELLIPSIS | DT_END_ELLIPSIS | DT_NOPREFIX);
+
+ // save so we don't have to recalculate
+ pwd->rows[i].value_height = smr.bottom;
+
+ pwd->rows[i].total_height = (pwd->rows[i].line_above ? options.text_padding : 0);
+ if(pwd->rows[i].value_newline) {
+ if(size.cy) pwd->rows[i].total_height += size.cy + options.text_padding;
+ if(smr.bottom) pwd->rows[i].total_height += smr.bottom + options.text_padding;
+ } else {
+ int maxheight = max(size.cy, smr.bottom);
+ if(maxheight) pwd->rows[i].total_height += maxheight + options.text_padding;
+ }
+
+ // only consider this item's width, and include it's height, if it doesn't make the window too big
+ if(max(pwd->tb_height + pwd->text_height + options.padding + pwd->rows[i].total_height, pwd->av_height) <= options.win_max_height) {
+ if(width < options.win_width) {
+ int wid = options.padding + pwd->indent + (pwd->rows[i].value_newline ? max(size.cx, smr.right - smr.left) : pwd->label_width + options.padding + (smr.right - smr.left));
+ if(pwd->tb_height + pwd->text_height + options.text_padding < pwd->av_height)
+ width = max(width, wid + pwd->real_av_width + 2 * options.av_padding);
+ else
+ width = max(width, wid + options.padding);
+ }
+
+ pwd->text_height += pwd->rows[i].total_height;
+ }
+ }
+
+ SelectObject(hdc, hOldFont);
+ ReleaseDC(hwnd, hdc);
+
+ int height = max(pwd->tb_height + pwd->text_height + options.padding, pwd->av_height);
+
+ if(height < options.min_height) height = options.min_height;
+ // ignore minwidth for text tips
+ if((!pwd->text_tip) && width < options.min_width) width = options.min_width;
+
+ if(height > options.win_max_height) height = options.win_max_height;
+ if(width > options.win_width) width = options.win_width;
+
+ GetWindowRect(hwnd, &r);
+ if(r.right - r.left != width || r.bottom - r.top != height) {
+
+ SetWindowPos(hwnd, 0, 0, 0, width, height, SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE);
+ SendMessage(hwnd, PUM_UPDATERGN, 0, 0);
+
+ InvalidateRect(hwnd, 0, TRUE);
+ }
+
+ if(pHeight) *pHeight = height;
+ }
+ return TRUE;
+ case PUM_UPDATERGN:
+ {
+ HRGN hRgn1;
+ RECT r;
+
+ int v,h;
+ int w=11;
+ GetWindowRect(hwnd,&r);
+ r.right -= r.left;
+ r.left = 0;
+ r.bottom -= r.top;
+ r.top = 0;
+
+ if(options.animate && pwd->anim_step < ANIM_STEPS) {
+ float frac = 1.0f - pwd->anim_step / (float)ANIM_STEPS;
+ int wi = r.right, hi = r.bottom;
+
+ r.left += (int)(wi / 2.0f * frac + 0.5f);
+ r.right -= (int)(wi / 2.0f * frac + 0.5f);
+ r.top += (int)(hi / 2.0f * frac + 0.5f);
+ r.bottom -= (int)(hi / 2.0f * frac + 0.5f);
+ }
+
+ // round corners
+ if(options.round) {
+ h=(r.right-r.left)>(w*2)?w:(r.right-r.left);
+ v=(r.bottom-r.top)>(w*2)?w:(r.bottom-r.top);
+ h=(h<v)?h:v;
+ } else
+ h = 0;
+ hRgn1=CreateRoundRectRgn(r.left,r.top,r.right + 1,r.bottom + 1,h,h);
+ SetWindowRgn(hwnd,hRgn1,FALSE);
+ }
+ return TRUE;
+
+ case PUM_CALCPOS:
+ {
+ RECT wa_rect, r;
+
+ SystemParametersInfo(SPI_GETWORKAREA, 0, &wa_rect, FALSE);
+ if (MyMonitorFromPoint)
+ {
+ HMONITOR hMon = MyMonitorFromPoint(pwd->clcit.ptCursor, MONITOR_DEFAULTTONEAREST);
+ MONITORINFO mi;
+ mi.cbSize = sizeof(mi);
+ if (MyGetMonitorInfo(hMon, &mi))
+ wa_rect = mi.rcWork;
+ }
+
+ GetWindowRect(hwnd, &r);
+
+ CURSORINFO ci = {sizeof(CURSORINFO)};
+ GetCursorInfo(&ci);
+
+ int x = 0, y = 0, width = (r.right - r.left), height = (r.bottom - r.top);
+
+ switch(options.pos) {
+ case PP_BOTTOMRIGHT:
+ x = pwd->clcit.ptCursor.x + GetSystemMetrics(SM_CXSMICON); // cursor size is too large - use small icon size
+ y = pwd->clcit.ptCursor.y + GetSystemMetrics(SM_CYSMICON);
+ break;
+ case PP_BOTTOMLEFT:
+ x = pwd->clcit.ptCursor.x - width - GetSystemMetrics(SM_CXSMICON);
+ y = pwd->clcit.ptCursor.y + GetSystemMetrics(SM_CYSMICON);
+ break;
+ case PP_TOPRIGHT:
+ x = pwd->clcit.ptCursor.x + GetSystemMetrics(SM_CXSMICON);
+ y = pwd->clcit.ptCursor.y - height - GetSystemMetrics(SM_CYSMICON);
+ break;
+ case PP_TOPLEFT:
+ x = pwd->clcit.ptCursor.x - width - GetSystemMetrics(SM_CXSMICON);
+ y = pwd->clcit.ptCursor.y - height - GetSystemMetrics(SM_CYSMICON);
+ break;
+ }
+
+ if(x + width + 8 > wa_rect.right)
+ x = wa_rect.right - width - 8;
+ if(y + height > wa_rect.bottom)
+ y = pwd->clcit.ptCursor.y - height - 8;
+ if(x - 8 < wa_rect.left)
+ x = wa_rect.left + 8;
+ if(y - 8 < wa_rect.top)
+ y = pwd->clcit.ptCursor.y + GetSystemMetrics(SM_CYSMICON);
+
+ SetWindowPos(hwnd, 0, x, y, 0, 0, SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOZORDER);
+ }
+ return TRUE;
+ }
+
+
+ return DefWindowProc(hwnd, uMsg, wParam, lParam);
+}
+
+int AvatarChanged(WPARAM wParam, LPARAM lParam) {
+ HANDLE hContact = (HANDLE)wParam;
+ PostMPMessage(MUM_GOTAVATAR, (WPARAM)hContact, 0);
+ return 0;
+}
+
+
diff --git a/plugins/tipper/popwin.h b/plugins/tipper/popwin.h
new file mode 100644
index 0000000000..f354d630b8
--- /dev/null
+++ b/plugins/tipper/popwin.h
@@ -0,0 +1,17 @@
+#ifndef _POPWIN_INC
+#define _POPWIN_INC
+
+#define POP_WIN_CLASS _T(MODULE) _T("MimTTClass")
+
+#define PUM_GETHEIGHT (WM_USER + 0x020)
+#define PUM_CALCPOS (WM_USER + 0x021)
+#define PUM_SETSTATUSTEXT (WM_USER + 0x022)
+#define PUM_UPDATERGN (WM_USER + 0x023)
+#define PUM_SETAVATAR (WM_USER + 0x024)
+#define PUM_REFRESH_VALUES (WM_USER + 0x025)
+
+LRESULT CALLBACK PopupWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
+
+int AvatarChanged(WPARAM wParam, LPARAM lParam); // exposed so hook/unhook is in main thread
+
+#endif
diff --git a/plugins/tipper/resource.h b/plugins/tipper/resource.h
new file mode 100644
index 0000000000..03e2540f5d
--- /dev/null
+++ b/plugins/tipper/resource.h
@@ -0,0 +1,93 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by tipper.rc
+//
+#define IDD_OPT_LAYOUT 101
+#define IDD_OPT_CONTENT 102
+#define IDD_SUBST 103
+#define IDD_ITEM 104
+#define IDD_OPT2 105
+#define IDD_OPT_WINDOW 106
+#define IDC_ED_WIDTH 1005
+#define IDC_ED_MAXHEIGHT 1006
+#define IDC_SPIN_WIDTH 1007
+#define IDC_SPIN_MAXHEIGHT 1008
+#define IDC_ED_INDENT 1009
+#define IDC_SPIN_INDENT 1010
+#define IDC_ED_PADDING 1011
+#define IDC_SPIN_PADDING 1012
+#define IDC_ED_TRANS 1013
+#define IDC_SPIN_TRANS 1014
+#define IDC_CHK_BORDER 1015
+#define IDC_CHK_ROUNDCORNERS 1016
+#define IDC_ED_MINWIDTH 1017
+#define IDC_CHK_ANIMATE 1018
+#define IDC_CHK_TRANSBG 1019
+#define IDC_CHK_SHADOW 1020
+#define IDC_SPIN_MINWIDTH 1021
+#define IDC_ED_MINHEIGHT 1022
+#define IDC_SPIN_MINHEIGHT 1023
+#define IDC_ED_SBWIDTH 1024
+#define IDC_SPIN_SBWIDTH 1025
+#define IDC_ED_TEXTPADDING 1026
+#define IDC_ED_AVSIZE 1027
+#define IDC_SPIN_AVSIZE 1028
+#define IDC_ED_HOVER 1029
+#define IDC_SPIN_HOVER 1030
+#define IDC_SPIN_TEXTPADDING 1031
+#define IDC_CMB_ICON 1032
+#define IDC_CMB_AV 1033
+#define IDC_CMB_AV2 1034
+#define IDC_CMB_ICON2 1034
+#define IDC_CMB_POS 1034
+#define IDC_LST_ITEMS 1035
+#define IDC_ED_AVPADDING 1035
+#define IDC_BTN_ADD 1036
+#define IDC_SPIN_AVPADDING 1036
+#define IDC_BTN_REMOVE 1037
+#define IDC_CHK_ROUNDCORNERS2 1037
+#define IDC_CHK_ROUNDCORNERSAV 1037
+#define IDC_BTN_UP 1038
+#define IDC_BTN_DOWN 1039
+#define IDC_CHK_NOFOCUS 1040
+#define IDC_BTN_EDIT 1041
+#define IDC_CHK_NOFOCUS2 1041
+#define IDC_CHK_NORESIZEAV 1041
+#define IDC_LST_SUBST 1042
+#define IDC_BTN_ADD2 1043
+#define IDC_ED_MODULE 1044
+#define IDC_BTN_REMOVE2 1044
+#define IDC_CHK_PROTOMOD 1045
+#define IDC_BTN_UP2 1045
+#define IDC_CHK_RIGHTLABEL 1045
+#define IDC_ED_SETTING 1046
+#define IDC_CMB_TRANSLATE 1047
+#define IDC_BTN_EDIT2 1047
+#define IDC_ED_LABEL 1048
+#define IDC_CHK_STATUSMSG 1048
+#define IDC_CHK_SBAR 1048
+#define IDC_CHK_LASTMSG 1049
+#define IDC_ED_VALUE 1050
+#define IDC_CHK_LINEABOVE 1051
+#define IDC_CHK_VALNEWLINE 1052
+#define IDC_CUSTOM1 1052
+#define IDC_BORDERCOLOUR 1052
+#define IDC_CMB_LV 1053
+#define IDC_CMB_VV 1054
+#define IDC_CMB_LH 1055
+#define IDC_CMB_VH 1056
+#define IDC_ED_BGFN 1057
+#define IDC_BTN_BROWSE 1058
+#define IDC_CHECK1 1059
+#define IDC_CHK_STRETCHBG 1059
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 107
+#define _APS_NEXT_COMMAND_VALUE 40001
+#define _APS_NEXT_CONTROL_VALUE 1060
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/plugins/tipper/resource.rc b/plugins/tipper/resource.rc
new file mode 100644
index 0000000000..41f2ce9169
--- /dev/null
+++ b/plugins/tipper/resource.rc
@@ -0,0 +1,6 @@
+
+// this makes our dependencies work better
+#include "version.h"
+
+#include "tipper.rc"
+#include "version.rc"
diff --git a/plugins/tipper/str_utils.cpp b/plugins/tipper/str_utils.cpp
new file mode 100644
index 0000000000..d1273bef38
--- /dev/null
+++ b/plugins/tipper/str_utils.cpp
@@ -0,0 +1,102 @@
+#include "common.h"
+#include "str_utils.h"
+
+int code_page = CP_ACP;
+
+void set_codepage() {
+ if(ServiceExists(MS_LANGPACK_GETCODEPAGE))
+ code_page = CallService(MS_LANGPACK_GETCODEPAGE, 0, 0);
+}
+
+bool a2w(const char *as, wchar_t *buff, int bufflen){
+ if(as) MultiByteToWideChar(code_page, 0, as, -1, buff, bufflen);
+ return true;
+}
+
+bool w2a(const wchar_t *ws, char *buff, int bufflen) {
+ if(ws) WideCharToMultiByte(code_page, 0, ws, -1, buff, bufflen, 0, 0);
+ return true;
+}
+
+bool t2w(const TCHAR *ts, wchar_t *buff, int bufflen) {
+#ifdef _UNICODE
+ wcsncpy(buff, ts, bufflen);
+ return true;
+#else
+ return a2w(ts, buff, bufflen);
+#endif
+}
+
+bool w2t(const wchar_t *ws, TCHAR *buff, int bufflen) {
+#ifdef _UNICODE
+ wcsncpy(buff, ws, bufflen);
+ return true;
+#else
+ return w2a(ws, buff, bufflen);
+#endif
+}
+
+bool t2a(const TCHAR *ts, char *buff, int bufflen) {
+#ifdef _UNICODE
+ return w2a(ts, buff, bufflen);
+#else
+ strncpy(buff, ts, bufflen);
+ return true;
+#endif
+}
+
+bool a2t(const char *as, TCHAR *buff, int bufflen) {
+#ifdef _UNICODE
+ return a2w(as, buff, bufflen);
+#else
+ strncpy(buff, as, bufflen);
+ return true;
+#endif
+}
+
+wchar_t *a2w(const char *as) {
+ int size = MultiByteToWideChar(code_page, 0, as, -1, 0, 0);
+ wchar_t *buff = (wchar_t *)malloc(size * sizeof(wchar_t));
+ MultiByteToWideChar(code_page, 0, as, -1, buff, size);
+ return buff;
+}
+
+char *w2a(const wchar_t *ws) {
+ int size = WideCharToMultiByte(code_page, 0, ws, -1, 0, 0, 0, 0);
+ char *buff = (char *)malloc(size);
+ WideCharToMultiByte(code_page, 0, ws, -1, buff, size, 0, 0);
+ return buff;
+}
+
+TCHAR *w2t(const wchar_t *ws) {
+#ifdef _UNICODE
+ return wcsdup(ws);
+#else
+ return w2a(ws);
+#endif
+}
+
+wchar_t *t2w(const TCHAR *ts) {
+#ifdef _UNICODE
+ return _tcsdup(ts);
+#else
+ return a2w(ts);
+#endif
+}
+
+
+char *t2a(const TCHAR *ts) {
+#ifdef _UNICODE
+ return w2a(ts);
+#else
+ return _strdup(ts);
+#endif
+}
+
+TCHAR *a2t(const char *as) {
+#ifdef _UNICODE
+ return a2w(as);
+#else
+ return _strdup(as);
+#endif
+}
diff --git a/plugins/tipper/str_utils.h b/plugins/tipper/str_utils.h
new file mode 100644
index 0000000000..26071a1c84
--- /dev/null
+++ b/plugins/tipper/str_utils.h
@@ -0,0 +1,34 @@
+#ifndef _STR_UTILS_INC
+#define _STR_UTILS_INC
+
+void set_codepage();
+
+bool a2w(const char *as, wchar_t *buff, int bufflen);
+bool w2a(const wchar_t *ws, char *buff, int bufflen);
+
+bool u2w(const char *us, wchar_t *buff, int bufflen);
+
+bool a2u(const char *as, char *buff, int bufflen);
+bool u2a(const char *ws, char *buff, int bufflen);
+
+bool t2w(const TCHAR *ts, wchar_t *buff, int bufflen);
+bool w2t(const wchar_t *ws, TCHAR *buff, int bufflen);
+
+bool t2a(const TCHAR *ts, char *buff, int bufflen);
+bool a2t(const char *as, TCHAR *buff, int bufflen);
+
+
+// remember to free return value
+wchar_t *a2w(const char *as);
+char *w2a(const wchar_t *ws);
+
+wchar_t *t2w(const TCHAR *ts);
+TCHAR *w2t(const wchar_t *ws);
+
+char *t2u(const TCHAR *ts);
+
+char *t2a(const TCHAR *ts);
+TCHAR *a2t(const char *as);
+
+#endif
+
diff --git a/plugins/tipper/subst.cpp b/plugins/tipper/subst.cpp
new file mode 100644
index 0000000000..2e8a6aa703
--- /dev/null
+++ b/plugins/tipper/subst.cpp
@@ -0,0 +1,450 @@
+#include "common.h"
+#include "subst.h"
+#include "str_utils.h"
+
+void StripBBCodesInPlace(TCHAR *text) {
+ if(!DBGetContactSettingByte(0, MODULE, "StripBBCodes", 1))
+ return;
+
+ if(text == 0) return;
+
+ int read = 0, write = 0;
+ int len = (int)_tcslen(text);
+
+ while(read <= len) { // copy terminating null too
+ while(read <= len && text[read] != '[') {
+ if(text[read] != text[write]) text[write] = text[read];
+ read++; write++;
+ }
+ if(read > len) break;
+
+ if(len - read >= 3 && (_tcsnicmp(text + read, _T("[b]"), 3) == 0 || _tcsnicmp(text + read, _T("[i]"), 3) == 0))
+ read += 3;
+ else if(len - read >= 4 && (_tcsnicmp(text + read, _T("[/b]"), 4) == 0 || _tcsnicmp(text + read, _T("[/i]"), 4) == 0))
+ read += 4;
+ else if(len - read >= 6 && (_tcsnicmp(text + read, _T("[color"), 6) == 0)) {
+ while(read < len && text[read] != ']') read++;
+ read++;// skip the ']'
+ } else if(len - read >= 8 && (_tcsnicmp(text + read, _T("[/color]"), 8) == 0))
+ read += 8;
+ else if(len - read >= 5 && (_tcsnicmp(text + read, _T("[size"), 5) == 0)) {
+ while(read < len && text[read] != ']') read++;
+ read++;// skip the ']'
+ } else if(len - read >= 7 && (_tcsnicmp(text + read, _T("[/size]"), 7) == 0))
+ read += 7;
+ else {
+ if(text[read] != text[write]) text[write] = text[read];
+ read++; write++;
+ }
+ }
+}
+
+DWORD last_message_timestamp(HANDLE hContact) {
+ DBEVENTINFO dbei = {0};
+ dbei.cbSize = sizeof(dbei);
+ HANDLE hDbEvent = (HANDLE)CallService(MS_DB_EVENT_FINDLAST, (WPARAM)hContact, 0);
+ while(hDbEvent) {
+ dbei.cbBlob = 0;
+ CallService(MS_DB_EVENT_GET, (WPARAM)hDbEvent, (LPARAM)&dbei);
+ if(dbei.eventType == EVENTTYPE_MESSAGE && !(dbei.flags & DBEF_SENT)) {
+ break;
+ }
+ hDbEvent = (HANDLE)CallService(MS_DB_EVENT_FINDPREV, (WPARAM)hDbEvent, 0);
+ }
+
+ if(hDbEvent) return dbei.timestamp;
+
+ return 0;
+}
+
+void format_timestamp(DWORD ts, char *format, TCHAR *buff, int bufflen) {
+ TCHAR form[16];
+ DBTIMETOSTRINGT dbt = {0};
+ dbt.cbDest = bufflen;
+ dbt.szDest = buff;
+ a2t(format, form, 16);
+ dbt.szFormat = form;
+ CallService(MS_DB_TIME_TIMESTAMPTOSTRINGT, (WPARAM)ts, (LPARAM)&dbt);
+}
+
+bool uid(HANDLE hContact, char *proto, TCHAR *buff, int bufflen) {
+ CONTACTINFO ci;
+ ci.cbSize = sizeof(CONTACTINFO);
+ ci.hContact = hContact;
+ // pass in proto so we can get uid when hContact == 0 (i.e. our own uid for a given proto)
+ ci.szProto = proto;//(char *)CallService(MS_PROTO_GETCONTACTBASEPROTO,(WPARAM)hcontact,0);
+ ci.dwFlag = CNF_UNIQUEID | CNF_TCHAR;
+ if(!CallService(MS_CONTACT_GETCONTACTINFO, 0, (LPARAM)&ci)) {
+ switch(ci.type) {
+ case CNFT_BYTE:
+ _ltot(ci.bVal, buff, 10);
+ break;
+ case CNFT_WORD:
+ _ltot(ci.wVal, buff, 10);
+ break;
+ case CNFT_DWORD:
+ _ltot(ci.dVal, buff, 10);
+ break;
+ case CNFT_ASCIIZ:
+ _tcsncpy(buff, ci.pszVal, bufflen);
+ buff[bufflen-1] = 0;
+ break;
+ default:
+ return false;
+ }
+ return true;
+ }
+ return false;
+}
+
+bool uid_name(char *szProto, TCHAR *buff, int bufflen) {
+ if (szProto){
+ char *szUniqueId = (char*)CallProtoService(szProto, PS_GETCAPS, PFLAG_UNIQUEIDTEXT, 0);
+ if(szUniqueId) {
+ a2t(szUniqueId, buff, bufflen);
+ return true;
+ }
+ }
+ return false;
+}
+
+TCHAR *GetLastMessageText(HANDLE hContact) {
+ DBEVENTINFO dbei = {0};
+ dbei.cbSize = sizeof(dbei);
+
+ HANDLE hDbEvent = (HANDLE)CallService(MS_DB_EVENT_FINDLAST, (WPARAM)hContact, 0);
+ while(hDbEvent) {
+ dbei.cbBlob = 0;
+ CallService(MS_DB_EVENT_GET, (WPARAM)hDbEvent, (LPARAM)&dbei);
+ if(dbei.eventType == EVENTTYPE_MESSAGE && !(dbei.flags & DBEF_SENT)) {
+ break;
+ }
+ hDbEvent = (HANDLE)CallService(MS_DB_EVENT_FINDPREV, (WPARAM)hDbEvent, 0);
+ }
+
+ if(hDbEvent) {
+ dbei.pBlob = (BYTE *)alloca(dbei.cbBlob);
+ CallService(MS_DB_EVENT_GET, (WPARAM)hDbEvent, (LPARAM)&dbei);
+
+ if(dbei.cbBlob == 0 || dbei.pBlob == 0) return 0;
+
+ TCHAR *buf = DbGetEventTextT( &dbei, CP_ACP );
+ TCHAR *msg = _tcsdup( buf );
+ mir_free( buf );
+
+ StripBBCodesInPlace(msg);
+ return msg;
+ }
+
+ return 0;
+}
+
+TCHAR *GetStatusMessageText(HANDLE hContact) {
+ TCHAR *ret = 0;
+ DBVARIANT dbv;
+ if(!DBGetContactSettingTString(hContact, MODULE, "TempStatusMsg", &dbv)) {
+ if(dbv.type != DBVT_DELETED && dbv.ptszVal && dbv.ptszVal[0]) {
+ ret = _tcsdup(dbv.ptszVal);
+ StripBBCodesInPlace(ret);
+ } else CallContactService(hContact, PSS_GETAWAYMSG, 0, 0);
+ DBFreeVariant(&dbv);
+ /*
+ // removed - people can use e.g. %raw:CList/StatusMsg% for SMR
+ } else if(!DBGetContactSettingTString(hContact, "CList", "StatusMsg", &dbv)) {
+ if(_tcslen(dbv.ptszVal)) ret = _tcsdup(dbv.ptszVal);
+ else CallContactService(hContact, PSS_GETAWAYMSG, 0, 0);
+ DBFreeVariant(&dbv);
+ */
+ } else
+ CallContactService(hContact, PSS_GETAWAYMSG, 0, 0);
+
+ return ret;
+}
+
+bool GetSysSubstText(HANDLE hContact, TCHAR *raw_spec, TCHAR *buff, int bufflen) {
+ if (!_tcscmp(raw_spec, _T("uid"))) {
+ return uid(hContact, 0, buff, bufflen);
+ } else if (!_tcscmp(raw_spec, _T("proto"))) {
+ char *szProto = (char*)CallService(MS_PROTO_GETCONTACTBASEACCOUNT, (WPARAM)hContact, 0);
+ if ((INT_PTR)szProto == CALLSERVICE_NOTFOUND) {
+ szProto = (char*)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0);
+ if (szProto) {
+ a2t(szProto, buff, bufflen);
+ return true;
+ }
+ }
+ else if (szProto) {
+ PROTOACCOUNT *pa = ProtoGetAccount(szProto);
+ _tcsncpy(buff, pa->tszAccountName, bufflen);
+ return true;
+ }
+ } else if (!_tcscmp(raw_spec, _T("time"))) {
+ if (tmi.printDateTime && !tmi.printDateTimeByContact(hContact, _T("t"), buff, bufflen, TZF_KNOWNONLY))
+ return true;
+ } else if (!_tcscmp(raw_spec, _T("uidname"))) {
+ char *szProto = (char*)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0);
+ return uid_name(szProto, buff, bufflen);
+ } else if (!_tcscmp(raw_spec, _T("status_msg"))) {
+ TCHAR *msg = GetStatusMessageText(hContact);
+ if(msg) {
+ _tcsncpy(buff, msg, bufflen);
+ free(msg);
+ return true;
+ }
+ } else if (!_tcscmp(raw_spec, _T("last_msg"))) {
+ TCHAR *msg = GetLastMessageText(hContact);
+ if(msg) {
+ _tcsncpy(buff, msg, bufflen);
+ free(msg);
+ return true;
+ }
+ } else if (!_tcscmp(raw_spec, _T("meta_subname"))) {
+ // get contact list name of active subcontact
+ HANDLE hSubContact = (HANDLE)CallService(MS_MC_GETMOSTONLINECONTACT, (WPARAM)hContact, 0);
+ if (!hSubContact || (INT_PTR)hSubContact == CALLSERVICE_NOTFOUND) return false;
+
+ TCHAR *stzCDN = (TCHAR *) CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)hSubContact, GCDNF_TCHAR);
+ if(stzCDN) _tcsncpy(buff, stzCDN, bufflen);
+ return true;
+ } else if (!_tcscmp(raw_spec, _T("meta_subuid"))){
+ HANDLE hSubContact = (HANDLE)CallService(MS_MC_GETMOSTONLINECONTACT, (WPARAM)hContact, 0);
+ if (!hSubContact || (INT_PTR)hSubContact == CALLSERVICE_NOTFOUND) return false;
+ return uid(hSubContact, 0, buff, bufflen);
+ } else if (!_tcscmp(raw_spec, _T("meta_subproto"))) {
+ // get protocol of active subcontact
+ HANDLE hSubContact = (HANDLE)CallService(MS_MC_GETMOSTONLINECONTACT, (WPARAM)hContact, 0);
+ if (!hSubContact || (INT_PTR)hSubContact == CALLSERVICE_NOTFOUND) return false;
+
+ char *szProto = (char*)CallService(MS_PROTO_GETCONTACTBASEACCOUNT, (WPARAM)hSubContact, 0);
+ if ((INT_PTR)szProto == CALLSERVICE_NOTFOUND) {
+ szProto = (char*)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hSubContact, 0);
+ if (szProto) {
+ a2t(szProto, buff, bufflen);
+ return true;
+ }
+ }
+ else if (szProto) {
+ PROTOACCOUNT *pa = ProtoGetAccount(szProto);
+ _tcsncpy(buff, pa->tszAccountName, bufflen);
+ return true;
+ }
+ } else if (!_tcscmp(raw_spec, _T("last_msg_time"))) {
+ DWORD ts = last_message_timestamp(hContact);
+ if(ts == 0) return false;
+
+ format_timestamp(ts, "t", buff, bufflen);
+ return true;
+ } else if (!_tcscmp(raw_spec, _T("last_msg_date"))) {
+ DWORD ts = last_message_timestamp(hContact);
+ if(ts == 0) return false;
+
+ format_timestamp(ts, "d", buff, bufflen);
+ return true;
+ } else if (!_tcscmp(raw_spec, _T("last_msg_reltime"))) {
+ DWORD ts = last_message_timestamp(hContact);
+ if(ts == 0) return false;
+
+ DWORD t = (DWORD)time(0);
+ DWORD diff = (t - ts);
+ int d = (diff / 60 / 60 / 24);
+ int h = (diff - d * 60 * 60 * 24) / 60 / 60;
+ int m = (diff - d * 60 * 60 * 24 - h * 60 * 60) / 60;
+ if(d > 0) mir_sntprintf(buff, bufflen, TranslateT("%dd %dh %dm"), d, h, m);
+ else if(h > 0) mir_sntprintf(buff, bufflen, TranslateT("%dh %dm"), h, m);
+ else mir_sntprintf(buff, bufflen, TranslateT("%dm"), m);
+
+ return true;
+ }
+ return false;
+}
+
+bool GetSubstText(HANDLE hContact, const DisplaySubst &ds, TCHAR *buff, int bufflen) {
+ TranslateFunc *tfunc = 0;
+ for(int i = 0; i < num_tfuncs; i++) {
+ if(translations[i].id == (DWORD)ds.translate_func_id) {
+ tfunc = translations[i].tfunc;
+ break;
+ }
+ }
+ if(!tfunc) return false;
+
+ switch(ds.type) {
+ case DVT_DB:
+ return tfunc(hContact, ds.module_name, ds.setting_name, buff, bufflen) != 0;
+ case DVT_PROTODB:
+ {
+ char *proto = (char *)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0);
+ if(proto) {
+ return tfunc(hContact, proto, ds.setting_name, buff, bufflen) != 0;
+ }
+ }
+ break;
+ }
+ return false;
+}
+
+bool GetRawSubstText(HANDLE hContact, char *raw_spec, TCHAR *buff, int bufflen) {
+ int len = (int)strlen(raw_spec);
+ for(int i = 0; i < len; i++) {
+ if(raw_spec[i] == '/') {
+ raw_spec[i] = 0;
+ if(strlen(raw_spec) == 0) {
+ char *proto = (char *)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0);
+ if(proto)
+ return translations[0].tfunc(hContact, proto, &raw_spec[i + 1], buff, bufflen) != 0;
+ else
+ return false;
+ } else
+ return translations[0].tfunc(hContact, raw_spec, &raw_spec[i + 1], buff, bufflen) != 0;
+ }
+ }
+ return false;
+}
+
+bool ApplySubst(HANDLE hContact, const TCHAR *source, TCHAR *dest, int dest_len) {
+ // hack - allow empty strings before passing to variables (note - zero length strings return false after this)
+ if(dest && source &&_tcslen(source) == 0) {
+ dest[0] = 0;
+ return true;
+ }
+
+ // pass to variables plugin if available
+ TCHAR *var_src = variables_parsedup((TCHAR *)source, 0, hContact);
+ //TCHAR *var_src = wcsdup(source); // disable variables
+ int source_len = (int)_tcslen(var_src);
+
+ int si = 0, di = 0, v = 0;
+ TCHAR vname[LABEL_LEN];
+ TCHAR rep[VALUE_LEN], alt[VALUE_LEN];
+ while(si < source_len && di < dest_len - 1) {
+ if(var_src[si] == _T('%')) {
+ si++;
+ v = 0;
+ while(si < source_len && v < LABEL_LEN) {
+ if(var_src[si] == _T('%')) {
+ // two %'s in a row in variable name disabled: e.g. %a%%b% - this is ambiguous]
+ //if(si + 1 < source_len && var_src[si + 1] == _T('%')) {
+ // si++; // skip first %, allow following code to add the second one to the variable name
+ //} else
+ break;
+ }
+ vname[v] = var_src[si];
+ v++; si++;
+ }
+ if(v == 0) { // subst len is 0 - just a % symbol
+ dest[di] = _T('%');
+ } else if(si < source_len) { // we found end %
+ vname[v] = 0;
+
+ bool alt_subst = false;
+ bool subst = false;
+
+ // apply only to specific protocol
+ TCHAR *p = _tcsrchr(vname, _T('^')); // use last '^', so if you want a ^ in alt text, you can just put a '^' on the end
+ if(p) {
+ *p = 0;
+ p++;
+ if(*p) {
+ bool negate = false;
+ if(*p == _T('!')) {
+ p++;
+ if(*p == 0) goto error;
+ negate = true;
+ }
+
+ char sproto[256], *cp;
+ t2a(p, sproto, 256);
+ cp = (char *)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0);
+ if(cp == 0 || (negate ? stricmp(cp, sproto) == 0 : stricmp(cp, sproto) != 0))
+ goto empty;
+ }
+ }
+
+ // get alternate text, if subst fails
+ alt[0] = 0;
+ p = _tcschr(vname, _T('|')); // use first '|' - so you can use the '|' symbol in alt text
+ if(p) {
+ *p = 0; // clip alt from vname
+ alt_subst = true;
+
+ p++;
+ _tcsncpy(alt, p, VALUE_LEN);
+ alt[VALUE_LEN - 1] = 0;
+ }
+
+ // get subst text
+ if(v > 4 && _tcsncmp(vname, _T("raw:"), 4) == 0) { // raw db substitution
+ char raw_spec[LABEL_LEN];
+ t2a(&vname[4], raw_spec, LABEL_LEN);
+ subst = GetRawSubstText(hContact, raw_spec, rep, VALUE_LEN);
+ } else if(v > 4 && _tcsncmp(vname, _T("sys:"), 4) == 0) { // 'system' substitution
+ subst = GetSysSubstText(hContact, &vname[4], rep, VALUE_LEN);
+ } else {
+ // see if we can find the subst
+ DSListNode *ds_node = options.ds_list;
+ while(ds_node) {
+ if(_tcscmp(ds_node->ds.name, vname) == 0)
+ break;
+
+ ds_node = ds_node->next;
+ }
+ if(!ds_node) goto error; // no such subst
+
+ subst = GetSubstText(hContact, ds_node->ds, rep, VALUE_LEN);
+ }
+
+ if(subst) {
+ int rep_len = (int)_tcslen(rep);
+ _tcsncpy(&dest[di], rep, min(rep_len, dest_len - di));
+ di += rep_len - 1; // -1 because we inc at bottom of loop
+ } else if(alt_subst) {
+ int alt_len = (int)_tcslen(alt);
+ _tcsncpy(&dest[di], alt, min(alt_len, dest_len - di));
+ di += alt_len - 1; // -1 because we inc at bottom of loop
+ } else
+ goto empty; // empty value
+
+ } else // no end % - error
+ goto error;
+
+ } else {
+ dest[di] = var_src[si];
+ }
+
+ si++;
+ di++;
+ }
+
+ free(var_src);
+ dest[di] = 0;
+
+ // check for a 'blank' string - just spaces etc
+ for(si = 0; si <= di; si++) {
+ if(dest[si] != 0 && dest[si] != _T(' ') && dest[si] != _T('\t') && dest[si] != _T('\r') && dest[si] != _T('\n'))
+ return true;
+ }
+
+ return false;
+
+empty:
+ free(var_src);
+ return false;
+
+error:
+ dest[0] = _T('*');
+ dest[1] = 0;
+ free(var_src);
+ return true;
+}
+
+bool GetLabelText(HANDLE hContact, const DisplayItem &di, TCHAR *buff, int bufflen) {
+ return ApplySubst(hContact, di.label, buff, bufflen);
+
+}
+
+bool GetValueText(HANDLE hContact, const DisplayItem &di, TCHAR *buff, int bufflen) {
+ return ApplySubst(hContact, di.value, buff, bufflen);
+}
+
+
+
diff --git a/plugins/tipper/subst.h b/plugins/tipper/subst.h
new file mode 100644
index 0000000000..755a587269
--- /dev/null
+++ b/plugins/tipper/subst.h
@@ -0,0 +1,18 @@
+#ifndef _SUBST_INC
+#define _SUBST_INC
+
+#include "options.h"
+#include "translations.h"
+
+//TCHAR *GetLastMessageText(HANDLE hContact);
+//TCHAR *GetStatusMessageText(HANDLE hContact);
+bool GetLabelText(HANDLE hContact, const DisplayItem &di, TCHAR *buff, int bufflen);
+bool GetValueText(HANDLE hContact, const DisplayItem &di, TCHAR *buff, int bufflen);
+
+void StripBBCodesInPlace(TCHAR *text);
+
+// can be used with hContact == 0 to get uid for a given proto
+bool uid_name(char *szProto, TCHAR *buff, int bufflen);
+bool uid(HANDLE hContact, char *proto, TCHAR *buff, int bufflen);
+
+#endif
diff --git a/plugins/tipper/tipper.cpp b/plugins/tipper/tipper.cpp
new file mode 100644
index 0000000000..98ca543942
--- /dev/null
+++ b/plugins/tipper/tipper.cpp
@@ -0,0 +1,277 @@
+// popups2.cpp : Defines the entry point for the DLL application.
+//
+
+#include "common.h"
+#include "tipper.h"
+#include "version.h"
+#include "message_pump.h"
+#include "options.h"
+#include "popwin.h"
+#include "str_utils.h"
+
+HMODULE hInst;
+
+FontIDT font_id_title, font_id_labels, font_id_values;
+ColourIDT colour_id_bg, colour_id_border, colour_id_divider, colour_id_sidebar;
+
+HFONT hFontTitle, hFontLabels, hFontValues;
+
+// hooked here so it's in the main thread
+HANDLE hAvChangeEvent, hAvContactChangeEvent, hShowTipEvent, hHideTipEvent;
+HANDLE hAckEvent, hFramesSBShow, hFramesSBHide, hSettingChangedEvent;
+HANDLE hShowTipService, hShowTipWService, hHideTipService;
+
+MM_INTERFACE mmi;
+TIME_API tmi;
+
+PLUGININFOEX pluginInfo={
+ sizeof(PLUGININFOEX),
+ __PLUGIN_NAME,
+ PLUGIN_MAKE_VERSION(__MAJOR_VERSION, __MINOR_VERSION, __RELEASE_NUM, __BUILD_NUM),
+ __DESC,
+ __AUTHOR,
+ __AUTHOREMAIL,
+ __COPYRIGHT,
+ __AUTHORWEB,
+ UNICODE_AWARE, //not transient
+ 0, //doesn't replace anything built-in
+
+#ifndef _UNICODE
+{ 0xedae7137, 0x1b6a, 0x4b8f, { 0xaa, 0xb0, 0x3b, 0x5a, 0x2f, 0x8, 0xf4, 0x62 } } // {EDAE7137-1B6A-4b8f-AAB0-3B5A2F08F462}
+#else
+{ 0x785c25e3, 0xc906, 0x434b, { 0x97, 0x23, 0xe2, 0x44, 0xe1, 0xbe, 0xca, 0x2 } } // {785C25E3-C906-434b-9723-E244E1BECA02}
+#endif
+};
+
+PLUGINLINK *pluginLink;
+
+extern "C" BOOL APIENTRY DllMain( HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
+{
+ hInst = hModule;
+ DisableThreadLibraryCalls(hInst);
+ return TRUE;
+}
+
+extern "C" __declspec(dllexport) PLUGININFOEX* MirandaPluginInfoEx(DWORD mirandaVersion)
+{
+ return &pluginInfo;
+}
+
+
+static const MUUID interfaces[] = {MIID_TOOLTIPS, MIID_LAST};
+extern "C" __declspec(dllexport) const MUUID* MirandaPluginInterfaces(void)
+{
+ return interfaces;
+}
+
+
+
+int ReloadFont(WPARAM wParam, LPARAM lParam) {
+
+ LOGFONT log_font;
+ if(hFontTitle) DeleteObject(hFontTitle);
+ options.title_col = CallService(MS_FONT_GETT, (WPARAM)&font_id_title, (LPARAM)&log_font);
+ hFontTitle = CreateFontIndirect(&log_font);
+ if(hFontLabels) DeleteObject(hFontLabels);
+ options.label_col = CallService(MS_FONT_GETT, (WPARAM)&font_id_labels, (LPARAM)&log_font);
+ hFontLabels = CreateFontIndirect(&log_font);
+ if(hFontValues) DeleteObject(hFontValues);
+ options.value_col = CallService(MS_FONT_GETT, (WPARAM)&font_id_values, (LPARAM)&log_font);
+ hFontValues = CreateFontIndirect(&log_font);
+
+ options.bg_col = CallService(MS_COLOUR_GETT, (WPARAM)&colour_id_bg, 0);
+ options.border_col = CallService(MS_COLOUR_GETT, (WPARAM)&colour_id_border, 0);
+ options.sidebar_col = CallService(MS_COLOUR_GETT, (WPARAM)&colour_id_sidebar, 0);
+ options.div_col = CallService(MS_COLOUR_GETT, (WPARAM)&colour_id_divider, 0);
+
+ return 0;
+}
+
+// hack to hide tip when clist hides from timeout
+int SettingChanged(WPARAM wParam, LPARAM lParam) {
+ DBCONTACTWRITESETTING *dcws = (DBCONTACTWRITESETTING *)lParam;
+ if(strcmp(dcws->szModule, "CList") != 0 || strcmp(dcws->szSetting, "State") != 0) return 0;
+
+ // clist hiding
+ if(dcws->value.type == DBVT_BYTE && dcws->value.bVal == 0) {
+ HideTip(0, 0);
+ }
+
+ return 0;
+}
+
+int ModulesLoaded(WPARAM wParam, LPARAM lParam)
+{
+ font_id_title.cbSize = sizeof(FontIDT);
+ font_id_title.flags = FIDF_ALLOWEFFECTS;
+ _tcscpy(font_id_title.group, LPGENT("Tooltips"));
+ _tcscpy(font_id_title.name, LPGENT("Title"));
+ strcpy(font_id_title.dbSettingsGroup, MODULE);
+ strcpy(font_id_title.prefix, "FontFirst");
+ font_id_title.order = 0;
+
+ font_id_title.deffontsettings.charset = DEFAULT_CHARSET;
+ font_id_title.deffontsettings.size = -14;
+ font_id_title.deffontsettings.style = DBFONTF_BOLD;
+ font_id_title.deffontsettings.colour = RGB(255, 0, 0);
+ font_id_title.flags |= FIDF_DEFAULTVALID;
+
+ font_id_labels.cbSize = sizeof(FontIDT);
+ font_id_labels.flags = FIDF_ALLOWEFFECTS;
+ _tcscpy(font_id_labels.group, LPGENT("Tooltips"));
+ _tcscpy(font_id_labels.name, LPGENT("Labels"));
+ strcpy(font_id_labels.dbSettingsGroup, MODULE);
+ strcpy(font_id_labels.prefix, "FontLabels");
+ font_id_labels.order = 1;
+
+ font_id_labels.deffontsettings.charset = DEFAULT_CHARSET;
+ font_id_labels.deffontsettings.size = -12;
+ font_id_labels.deffontsettings.style = DBFONTF_ITALIC;
+ font_id_labels.deffontsettings.colour = RGB(128, 128, 128);
+ font_id_labels.flags |= FIDF_DEFAULTVALID;
+
+ font_id_values.cbSize = sizeof(FontIDT);
+ font_id_values.flags = FIDF_ALLOWEFFECTS;
+ _tcscpy(font_id_values.group, LPGENT("Tooltips"));
+ _tcscpy(font_id_values.name, LPGENT("Values"));
+ strcpy(font_id_values.dbSettingsGroup, MODULE);
+ strcpy(font_id_values.prefix, "FontValues");
+ font_id_values.order = 2;
+
+ font_id_values.deffontsettings.charset = DEFAULT_CHARSET;
+ font_id_values.deffontsettings.size = -12;
+ font_id_values.deffontsettings.style = 0;
+ font_id_values.deffontsettings.colour = RGB(0, 0, 0);
+ font_id_values.flags |= FIDF_DEFAULTVALID;
+
+ CallService(MS_FONT_REGISTERT, (WPARAM)&font_id_title, 0);
+ CallService(MS_FONT_REGISTERT, (WPARAM)&font_id_labels, 0);
+ CallService(MS_FONT_REGISTERT, (WPARAM)&font_id_values, 0);
+
+ colour_id_bg.cbSize = sizeof(ColourIDT);
+ _tcscpy(colour_id_bg.group, LPGENT("Tooltips"));
+ _tcscpy(colour_id_bg.name, LPGENT("Background"));
+ strcpy(colour_id_bg.dbSettingsGroup, MODULE);
+ strcpy(colour_id_bg.setting, "ColourBg");
+ colour_id_bg.defcolour = RGB(219, 219, 219);
+ colour_id_bg.order = 0;
+
+ colour_id_border.cbSize = sizeof(ColourIDT);
+ _tcscpy(colour_id_border.group, LPGENT("Tooltips"));
+ _tcscpy(colour_id_border.name, LPGENT("Border"));
+ strcpy(colour_id_border.dbSettingsGroup, MODULE);
+ strcpy(colour_id_border.setting, "BorderCol");
+ colour_id_border.defcolour = 0;
+ colour_id_border.order = 0;
+
+ colour_id_divider.cbSize = sizeof(ColourIDT);
+ _tcscpy(colour_id_divider.group, LPGENT("Tooltips"));
+ _tcscpy(colour_id_divider.name, LPGENT("Dividers"));
+ strcpy(colour_id_divider.dbSettingsGroup, MODULE);
+ strcpy(colour_id_divider.setting, "DividerCol");
+ colour_id_divider.defcolour = 0;
+ colour_id_divider.order = 0;
+
+ colour_id_sidebar.cbSize = sizeof(ColourIDT);
+ _tcscpy(colour_id_sidebar.group, LPGENT("Tooltips"));
+ _tcscpy(colour_id_sidebar.name, LPGENT("Sidebar"));
+ strcpy(colour_id_sidebar.dbSettingsGroup, MODULE);
+ strcpy(colour_id_sidebar.setting, "SidebarCol");
+ colour_id_sidebar.defcolour = RGB(192, 192, 192);
+ colour_id_sidebar.order = 0;
+
+ CallService(MS_COLOUR_REGISTERT, (WPARAM)&colour_id_bg, 0);
+ CallService(MS_COLOUR_REGISTERT, (WPARAM)&colour_id_border, 0);
+ CallService(MS_COLOUR_REGISTERT, (WPARAM)&colour_id_divider, 0);
+ CallService(MS_COLOUR_REGISTERT, (WPARAM)&colour_id_sidebar, 0);
+
+ ReloadFont(0, 0);
+
+ HookEvent(ME_FONT_RELOAD, ReloadFont);
+
+ hAvChangeEvent = HookEvent(ME_AV_AVATARCHANGED, AvatarChanged);
+ hShowTipEvent = HookEvent(ME_CLC_SHOWINFOTIP, ShowTipHook);
+ hHideTipEvent = HookEvent(ME_CLC_HIDEINFOTIP, HideTipHook);
+ hAckEvent = HookEvent(ME_PROTO_ACK, ProtoAck);
+
+ hFramesSBShow = HookEvent(ME_CLIST_FRAMES_SB_SHOW_TOOLTIP, FramesShowSBTip);
+ hFramesSBHide = HookEvent(ME_CLIST_FRAMES_SB_HIDE_TOOLTIP, FramesHideSBTip);
+
+ LoadOptions();
+
+ // set 'time-in'
+ CallService(MS_CLC_SETINFOTIPHOVERTIME, options.time_in, 0);
+
+ return 0;
+}
+
+int Shutdown(WPARAM wParam, LPARAM lParam) {
+ if(hFramesSBShow) UnhookEvent(hFramesSBShow);
+ if(hFramesSBHide) UnhookEvent(hFramesSBHide);
+ if(hAvChangeEvent) UnhookEvent(hAvChangeEvent);
+ if(hAvContactChangeEvent) UnhookEvent(hAvContactChangeEvent);
+ if(hShowTipEvent) UnhookEvent(hShowTipEvent);
+ if(hHideTipEvent) UnhookEvent(hHideTipEvent);
+ if(hAckEvent) UnhookEvent(hAckEvent);
+
+ if(hShowTipService) DestroyServiceFunction(hShowTipService);
+ if(hShowTipWService) DestroyServiceFunction(hShowTipWService);
+ if(hHideTipService) DestroyServiceFunction(hHideTipService);
+
+ DeinitMessagePump();
+
+ return 0;
+}
+
+HANDLE hEventPreShutdown, hEventModulesLoaded;
+
+extern "C" int TIPPER_API Load(PLUGINLINK *link) {
+ pluginLink = link;
+ set_codepage();
+
+ mir_getMMI(&mmi);
+ mir_getTMI(&tmi);
+
+ // don't save status messages
+ CallService(MS_DB_SETSETTINGRESIDENT, (WPARAM)TRUE, (LPARAM)MODULE "/TempStatusMsg");
+
+ // Ensure that the common control DLL is loaded (for listview)
+ INITCOMMONCONTROLSEX icex;
+ icex.dwSize = sizeof(INITCOMMONCONTROLSEX);
+ icex.dwICC = ICC_LISTVIEW_CLASSES;
+ InitCommonControlsEx(&icex);
+
+ if(ServiceExists(MS_LANGPACK_GETCODEPAGE))
+ code_page = CallService(MS_LANGPACK_GETCODEPAGE, 0, 0);
+
+ InitTranslations();
+ InitMessagePump();
+ InitOptions();
+
+ // for compatibility with mToolTip status tooltips
+ hShowTipService = CreateServiceFunction("mToolTip/ShowTip", ShowTip);
+#ifdef _UNICODE
+ hShowTipWService = CreateServiceFunction("mToolTip/ShowTipW", ShowTipW);
+#endif
+ hHideTipService = CreateServiceFunction("mToolTip/HideTip", HideTip);
+
+ hEventPreShutdown = HookEvent(ME_SYSTEM_PRESHUTDOWN, Shutdown);
+ hEventModulesLoaded = HookEvent(ME_SYSTEM_MODULESLOADED, ModulesLoaded);
+
+ hSettingChangedEvent = HookEvent(ME_DB_CONTACT_SETTINGCHANGED, SettingChanged);
+
+ return 0;
+}
+
+extern "C" int TIPPER_API Unload() {
+ UnhookEvent(hSettingChangedEvent);
+ UnhookEvent(hEventPreShutdown);
+ UnhookEvent(hEventModulesLoaded);
+
+ DeinitOptions();
+ DeleteObject(hFontTitle);
+ DeleteObject(hFontLabels);
+ DeleteObject(hFontValues);
+ DeinitTranslations();
+ return 0;
+}
diff --git a/plugins/tipper/tipper.dep b/plugins/tipper/tipper.dep
new file mode 100644
index 0000000000..24f57bcceb
--- /dev/null
+++ b/plugins/tipper/tipper.dep
@@ -0,0 +1,7 @@
+# Microsoft Developer Studio Generated Dependency File, included by tipper.mak
+
+.\resource.rc : \
+ ".\tipper.rc"\
+ ".\version.h"\
+ ".\version.rc"\
+
diff --git a/plugins/tipper/tipper.dsp b/plugins/tipper/tipper.dsp
new file mode 100644
index 0000000000..31374164e4
--- /dev/null
+++ b/plugins/tipper/tipper.dsp
@@ -0,0 +1,245 @@
+# Microsoft Developer Studio Project File - Name="tipper" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=tipper - Win32 Debug Unicode
+!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 "tipper.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 "tipper.mak" CFG="tipper - Win32 Debug Unicode"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "tipper - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "tipper - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "tipper - Win32 Release Unicode" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "tipper - Win32 Debug Unicode" (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)" == "tipper - 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 1
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "tipper_EXPORTS" /YX /FD /c
+# ADD CPP /nologo /MD /W3 /Zi /O1 /I "../../../include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "TIPPER_EXPORTS" /FR /Yu"common.h" /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x419 /d "NDEBUG"
+# ADD RSC /l 0x419 /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 comctl32.lib comdlg32.lib /nologo /dll /map /debug /machine:I386 /filealign:512
+# SUBTRACT LINK32 /pdb:none /incremental:yes
+
+!ELSEIF "$(CFG)" == "tipper - 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 "tipper_EXPORTS" /YX /FD /GZ /c
+# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../../include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "TIPPER_EXPORTS" /FR /Yu"common.h" /FD /GZ /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x419 /d "_DEBUG"
+# ADD RSC /l 0x419 /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 comctl32.lib comdlg32.lib /nologo /dll /debug /machine:I386 /out:"../../bin/Debug/plugins/tipper.dll" /pdbtype:sept
+# SUBTRACT LINK32 /pdb:none /incremental:no
+
+!ELSEIF "$(CFG)" == "tipper - Win32 Release Unicode"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "tipper___Win32_Release_Unicode"
+# PROP BASE Intermediate_Dir "tipper___Win32_Release_Unicode"
+# PROP BASE Ignore_Export_Lib 0
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release_Unicode"
+# PROP Intermediate_Dir "Release_Unicode"
+# PROP Ignore_Export_Lib 1
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MD /W3 /GX /Zi /O1 /I "../../include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "NO_GZIP" /D "PNG_NO_STDIO" /D "PNG_NO_CONSOLE_IO" /FD /c
+# SUBTRACT BASE CPP /YX
+# ADD CPP /nologo /MD /W3 /Zi /O1 /I "../../../include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "UNICODE" /D "_USRDLL" /D "TIPPER_EXPORTS" /D MICROSOFT_LAYER_FOR_UNICODE=1 /Yu"common.h" /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x419 /d "NDEBUG"
+# ADD RSC /l 0x409 /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 /map /debug /machine:I386 /out:"../../bin/Release/Plugins/tipper.dll" /filealign:512
+# SUBTRACT BASE LINK32 /pdb:none /incremental:yes
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib comctl32.lib comdlg32.lib /nologo /dll /machine:I386 /filealign:512
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "tipper - Win32 Debug Unicode"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "tipper___Win32_Debug_Unicode"
+# PROP BASE Intermediate_Dir "tipper___Win32_Debug_Unicode"
+# PROP BASE Ignore_Export_Lib 0
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug_Unicode"
+# PROP Intermediate_Dir "Debug_Unicode"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../../include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "NO_GZIP" /D "PNG_NO_STDIO" /D "PNG_NO_CONSOLE_IO" /FR /YX /FD /GZ /c
+# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../../../include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "UNICODE" /D "_USRDLL" /D "TIPPER_EXPORTS" /FR /Yu"common.h" /FD /GZ /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x419 /d "_DEBUG"
+# ADD RSC /l 0x419 /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 /out:"../../bin/Debug/plugins/tipper.dll" /pdbtype:sept
+# SUBTRACT BASE LINK32 /pdb:none /incremental:no
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib comctl32.lib unicows.lib /nologo /dll /debug /machine:I386 /out:"../../bin/Debug Unicode/plugins/tipper.dll" /pdbtype:sept
+# SUBTRACT LINK32 /pdb:none /incremental:no
+
+!ENDIF
+
+# Begin Target
+
+# Name "tipper - Win32 Release"
+# Name "tipper - Win32 Debug"
+# Name "tipper - Win32 Release Unicode"
+# Name "tipper - Win32 Debug Unicode"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=.\message_pump.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\options.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\popwin.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\str_utils.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\subst.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\tipper.cpp
+# ADD CPP /Yc"common.h"
+# End Source File
+# Begin Source File
+
+SOURCE=.\translations.cpp
+# End Source File
+# End Group
+# Begin Group "Resource Files"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=.\resource.rc
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=.\common.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\m_tipper.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\message_pump.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\options.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\popwin.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\resource.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\str_utils.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\subst.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\tipper.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\translations.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\version.h
+# End Source File
+# End Group
+# End Target
+# End Project
diff --git a/plugins/tipper/tipper.dsw b/plugins/tipper/tipper.dsw
new file mode 100644
index 0000000000..c49f741c95
--- /dev/null
+++ b/plugins/tipper/tipper.dsw
@@ -0,0 +1,33 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "yapp"=.\tipper.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+ begin source code control
+ "$/Miranda/miranda/plugins/tipper", FLIAAAAA
+ .
+ end source code control
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --git a/plugins/tipper/tipper.h b/plugins/tipper/tipper.h
new file mode 100644
index 0000000000..94e4778891
--- /dev/null
+++ b/plugins/tipper/tipper.h
@@ -0,0 +1,12 @@
+// The following ifdef block is the standard way of creating macros which make exporting
+// from a DLL simpler. All files within this DLL are compiled with the POPUPS2_EXPORTS
+// symbol defined on the command line. this symbol should not be defined on any project
+// that uses this DLL. This way any other project whose source files include this file see
+// POPUPS2_API functions as being imported from a DLL, whereas this DLL sees symbols
+// defined with this macro as being exported.
+#ifdef TIPPER_EXPORTS
+#define TIPPER_API __declspec(dllexport)
+#else
+#define TIPPER_API __declspec(dllimport)
+#endif
+
diff --git a/plugins/tipper/tipper.mak b/plugins/tipper/tipper.mak
new file mode 100644
index 0000000000..a1c2cf085b
--- /dev/null
+++ b/plugins/tipper/tipper.mak
@@ -0,0 +1,555 @@
+# Microsoft Developer Studio Generated NMAKE File, Based on tipper.dsp
+!IF "$(CFG)" == ""
+CFG=tipper - Win32 Debug Unicode
+!MESSAGE No configuration specified. Defaulting to tipper - Win32 Debug Unicode.
+!ENDIF
+
+!IF "$(CFG)" != "tipper - Win32 Release" && "$(CFG)" != "tipper - Win32 Debug" && "$(CFG)" != "tipper - Win32 Release Unicode" && "$(CFG)" != "tipper - Win32 Debug Unicode"
+!MESSAGE Invalid configuration "$(CFG)" specified.
+!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 "tipper.mak" CFG="tipper - Win32 Debug Unicode"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "tipper - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "tipper - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "tipper - Win32 Release Unicode" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "tipper - Win32 Debug Unicode" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE
+!ERROR An invalid configuration is specified.
+!ENDIF
+
+!IF "$(OS)" == "Windows_NT"
+NULL=
+!ELSE
+NULL=nul
+!ENDIF
+
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "tipper - Win32 Release"
+
+OUTDIR=.\Release
+INTDIR=.\Release
+
+ALL : "..\..\bin\Release\Plugins\tipper.dll"
+
+
+CLEAN :
+ -@erase "$(INTDIR)\message_pump.obj"
+ -@erase "$(INTDIR)\options.obj"
+ -@erase "$(INTDIR)\popwin.obj"
+ -@erase "$(INTDIR)\resource.res"
+ -@erase "$(INTDIR)\str_utils.obj"
+ -@erase "$(INTDIR)\subst.obj"
+ -@erase "$(INTDIR)\tipper.obj"
+ -@erase "$(INTDIR)\tipper.pch"
+ -@erase "$(INTDIR)\translations.obj"
+ -@erase "$(INTDIR)\vc60.idb"
+ -@erase "$(INTDIR)\vc60.pdb"
+ -@erase "$(OUTDIR)\tipper.exp"
+ -@erase "$(OUTDIR)\tipper.lib"
+ -@erase "$(OUTDIR)\tipper.map"
+ -@erase "$(OUTDIR)\tipper.pdb"
+ -@erase "..\..\bin\Release\Plugins\tipper.dll"
+
+"$(OUTDIR)" :
+ if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
+
+CPP_PROJ=/nologo /MD /W3 /GX /Zi /O1 /I "../../include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "TIPPER_EXPORTS" /Fp"$(INTDIR)\tipper.pch" /Yu"common.h" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c
+MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32
+RSC_PROJ=/l 0x419 /fo"$(INTDIR)\resource.res" /d "NDEBUG"
+BSC32=bscmake.exe
+BSC32_FLAGS=/nologo /o"$(OUTDIR)\tipper.bsc"
+BSC32_SBRS= \
+
+LINK32=link.exe
+LINK32_FLAGS=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 wsock32.lib /nologo /dll /incremental:no /pdb:"$(OUTDIR)\tipper.pdb" /map:"$(INTDIR)\tipper.map" /debug /machine:I386 /out:"../../bin/Release/Plugins/tipper.dll" /implib:"$(OUTDIR)\tipper.lib" /filealign:512
+LINK32_OBJS= \
+ "$(INTDIR)\resource.res" \
+ "$(INTDIR)\translations.obj" \
+ "$(INTDIR)\message_pump.obj" \
+ "$(INTDIR)\options.obj" \
+ "$(INTDIR)\popwin.obj" \
+ "$(INTDIR)\str_utils.obj" \
+ "$(INTDIR)\subst.obj" \
+ "$(INTDIR)\tipper.obj"
+
+"..\..\bin\Release\Plugins\tipper.dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
+ $(LINK32) @<<
+ $(LINK32_FLAGS) $(LINK32_OBJS)
+<<
+
+!ELSEIF "$(CFG)" == "tipper - Win32 Debug"
+
+OUTDIR=.\Debug
+INTDIR=.\Debug
+# Begin Custom Macros
+OutDir=.\Debug
+# End Custom Macros
+
+ALL : "..\..\bin\Debug\plugins\tipper.dll" "$(OUTDIR)\tipper.bsc"
+
+
+CLEAN :
+ -@erase "$(INTDIR)\message_pump.obj"
+ -@erase "$(INTDIR)\message_pump.sbr"
+ -@erase "$(INTDIR)\options.obj"
+ -@erase "$(INTDIR)\options.sbr"
+ -@erase "$(INTDIR)\popwin.obj"
+ -@erase "$(INTDIR)\popwin.sbr"
+ -@erase "$(INTDIR)\resource.res"
+ -@erase "$(INTDIR)\str_utils.obj"
+ -@erase "$(INTDIR)\str_utils.sbr"
+ -@erase "$(INTDIR)\subst.obj"
+ -@erase "$(INTDIR)\subst.sbr"
+ -@erase "$(INTDIR)\tipper.obj"
+ -@erase "$(INTDIR)\tipper.pch"
+ -@erase "$(INTDIR)\tipper.sbr"
+ -@erase "$(INTDIR)\translations.obj"
+ -@erase "$(INTDIR)\translations.sbr"
+ -@erase "$(INTDIR)\vc60.idb"
+ -@erase "$(INTDIR)\vc60.pdb"
+ -@erase "$(OUTDIR)\tipper.bsc"
+ -@erase "$(OUTDIR)\tipper.exp"
+ -@erase "$(OUTDIR)\tipper.lib"
+ -@erase "$(OUTDIR)\tipper.pdb"
+ -@erase "..\..\bin\Debug\plugins\tipper.dll"
+ -@erase "..\..\bin\Debug\plugins\tipper.ilk"
+
+"$(OUTDIR)" :
+ if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
+
+CPP_PROJ=/nologo /MDd /W3 /Gm /GX /ZI /Od /I "../../include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "TIPPER_EXPORTS" /FR"$(INTDIR)\\" /Fp"$(INTDIR)\tipper.pch" /Yu"common.h" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /GZ /c
+MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32
+RSC_PROJ=/l 0x419 /fo"$(INTDIR)\resource.res" /d "_DEBUG"
+BSC32=bscmake.exe
+BSC32_FLAGS=/nologo /o"$(OUTDIR)\tipper.bsc"
+BSC32_SBRS= \
+ "$(INTDIR)\translations.sbr" \
+ "$(INTDIR)\message_pump.sbr" \
+ "$(INTDIR)\options.sbr" \
+ "$(INTDIR)\popwin.sbr" \
+ "$(INTDIR)\str_utils.sbr" \
+ "$(INTDIR)\subst.sbr" \
+ "$(INTDIR)\tipper.sbr"
+
+"$(OUTDIR)\tipper.bsc" : "$(OUTDIR)" $(BSC32_SBRS)
+ $(BSC32) @<<
+ $(BSC32_FLAGS) $(BSC32_SBRS)
+<<
+
+LINK32=link.exe
+LINK32_FLAGS=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 wsock32.lib /nologo /dll /incremental:yes /pdb:"$(OUTDIR)\tipper.pdb" /debug /machine:I386 /out:"../../bin/Debug/plugins/tipper.dll" /implib:"$(OUTDIR)\tipper.lib" /pdbtype:sept
+LINK32_OBJS= \
+ "$(INTDIR)\resource.res" \
+ "$(INTDIR)\translations.obj" \
+ "$(INTDIR)\message_pump.obj" \
+ "$(INTDIR)\options.obj" \
+ "$(INTDIR)\popwin.obj" \
+ "$(INTDIR)\str_utils.obj" \
+ "$(INTDIR)\subst.obj" \
+ "$(INTDIR)\tipper.obj"
+
+"..\..\bin\Debug\plugins\tipper.dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
+ $(LINK32) @<<
+ $(LINK32_FLAGS) $(LINK32_OBJS)
+<<
+
+!ELSEIF "$(CFG)" == "tipper - Win32 Release Unicode"
+
+OUTDIR=.\Release_Unicode
+INTDIR=.\Release_Unicode
+
+ALL : "..\..\bin\Release Unicode\Plugins\tipper.dll"
+
+
+CLEAN :
+ -@erase "$(INTDIR)\message_pump.obj"
+ -@erase "$(INTDIR)\options.obj"
+ -@erase "$(INTDIR)\popwin.obj"
+ -@erase "$(INTDIR)\resource.res"
+ -@erase "$(INTDIR)\str_utils.obj"
+ -@erase "$(INTDIR)\subst.obj"
+ -@erase "$(INTDIR)\tipper.obj"
+ -@erase "$(INTDIR)\tipper.pch"
+ -@erase "$(INTDIR)\translations.obj"
+ -@erase "$(INTDIR)\vc60.idb"
+ -@erase "$(INTDIR)\vc60.pdb"
+ -@erase "$(OUTDIR)\tipper.exp"
+ -@erase "$(OUTDIR)\tipper.lib"
+ -@erase "$(OUTDIR)\tipper.map"
+ -@erase "$(OUTDIR)\tipper.pdb"
+ -@erase "..\..\bin\Release Unicode\Plugins\tipper.dll"
+
+"$(OUTDIR)" :
+ if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
+
+CPP_PROJ=/nologo /MD /W3 /GX /Zi /O1 /I "../../include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "UNICODE" /D "_USRDLL" /D "TIPPER_EXPORTS" /Fp"$(INTDIR)\tipper.pch" /Yu"common.h" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c
+MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32
+RSC_PROJ=/l 0x419 /fo"$(INTDIR)\resource.res" /d "NDEBUG"
+BSC32=bscmake.exe
+BSC32_FLAGS=/nologo /o"$(OUTDIR)\tipper.bsc"
+BSC32_SBRS= \
+
+LINK32=link.exe
+LINK32_FLAGS=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 wsock32.lib /nologo /dll /incremental:no /pdb:"$(OUTDIR)\tipper.pdb" /map:"$(INTDIR)\tipper.map" /debug /machine:I386 /out:"../../bin/Release Unicode/Plugins/tipper.dll" /implib:"$(OUTDIR)\tipper.lib" /filealign:512
+LINK32_OBJS= \
+ "$(INTDIR)\resource.res" \
+ "$(INTDIR)\translations.obj" \
+ "$(INTDIR)\message_pump.obj" \
+ "$(INTDIR)\options.obj" \
+ "$(INTDIR)\popwin.obj" \
+ "$(INTDIR)\str_utils.obj" \
+ "$(INTDIR)\subst.obj" \
+ "$(INTDIR)\tipper.obj"
+
+"..\..\bin\Release Unicode\Plugins\tipper.dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
+ $(LINK32) @<<
+ $(LINK32_FLAGS) $(LINK32_OBJS)
+<<
+
+!ELSEIF "$(CFG)" == "tipper - Win32 Debug Unicode"
+
+OUTDIR=.\Debug_Unicode
+INTDIR=.\Debug_Unicode
+# Begin Custom Macros
+OutDir=.\Debug_Unicode
+# End Custom Macros
+
+ALL : "..\..\bin\Debug Unicode\plugins\tipper.dll" "$(OUTDIR)\tipper.bsc"
+
+
+CLEAN :
+ -@erase "$(INTDIR)\message_pump.obj"
+ -@erase "$(INTDIR)\message_pump.sbr"
+ -@erase "$(INTDIR)\options.obj"
+ -@erase "$(INTDIR)\options.sbr"
+ -@erase "$(INTDIR)\popwin.obj"
+ -@erase "$(INTDIR)\popwin.sbr"
+ -@erase "$(INTDIR)\resource.res"
+ -@erase "$(INTDIR)\str_utils.obj"
+ -@erase "$(INTDIR)\str_utils.sbr"
+ -@erase "$(INTDIR)\subst.obj"
+ -@erase "$(INTDIR)\subst.sbr"
+ -@erase "$(INTDIR)\tipper.obj"
+ -@erase "$(INTDIR)\tipper.pch"
+ -@erase "$(INTDIR)\tipper.sbr"
+ -@erase "$(INTDIR)\translations.obj"
+ -@erase "$(INTDIR)\translations.sbr"
+ -@erase "$(INTDIR)\vc60.idb"
+ -@erase "$(INTDIR)\vc60.pdb"
+ -@erase "$(OUTDIR)\tipper.bsc"
+ -@erase "$(OUTDIR)\tipper.exp"
+ -@erase "$(OUTDIR)\tipper.lib"
+ -@erase "$(OUTDIR)\tipper.pdb"
+ -@erase "..\..\bin\Debug Unicode\plugins\tipper.dll"
+ -@erase "..\..\bin\Debug Unicode\plugins\tipper.ilk"
+
+"$(OUTDIR)" :
+ if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
+
+CPP_PROJ=/nologo /MDd /W3 /Gm /GX /ZI /Od /I "../../include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "UNICODE" /D "_USRDLL" /D "TIPPER_EXPORTS" /FR"$(INTDIR)\\" /Fp"$(INTDIR)\tipper.pch" /Yu"common.h" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /GZ /c
+MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32
+RSC_PROJ=/l 0x419 /fo"$(INTDIR)\resource.res" /d "_DEBUG"
+BSC32=bscmake.exe
+BSC32_FLAGS=/nologo /o"$(OUTDIR)\tipper.bsc"
+BSC32_SBRS= \
+ "$(INTDIR)\translations.sbr" \
+ "$(INTDIR)\message_pump.sbr" \
+ "$(INTDIR)\options.sbr" \
+ "$(INTDIR)\popwin.sbr" \
+ "$(INTDIR)\str_utils.sbr" \
+ "$(INTDIR)\subst.sbr" \
+ "$(INTDIR)\tipper.sbr"
+
+"$(OUTDIR)\tipper.bsc" : "$(OUTDIR)" $(BSC32_SBRS)
+ $(BSC32) @<<
+ $(BSC32_FLAGS) $(BSC32_SBRS)
+<<
+
+LINK32=link.exe
+LINK32_FLAGS=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 wsock32.lib /nologo /dll /incremental:yes /pdb:"$(OUTDIR)\tipper.pdb" /debug /machine:I386 /out:"../../bin/Debug Unicode/plugins/tipper.dll" /implib:"$(OUTDIR)\tipper.lib" /pdbtype:sept
+LINK32_OBJS= \
+ "$(INTDIR)\resource.res" \
+ "$(INTDIR)\translations.obj" \
+ "$(INTDIR)\message_pump.obj" \
+ "$(INTDIR)\options.obj" \
+ "$(INTDIR)\popwin.obj" \
+ "$(INTDIR)\str_utils.obj" \
+ "$(INTDIR)\subst.obj" \
+ "$(INTDIR)\tipper.obj"
+
+"..\..\bin\Debug Unicode\plugins\tipper.dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
+ $(LINK32) @<<
+ $(LINK32_FLAGS) $(LINK32_OBJS)
+<<
+
+!ENDIF
+
+.c{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cpp{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cxx{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.c{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cpp{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cxx{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+
+!IF "$(NO_EXTERNAL_DEPS)" != "1"
+!IF EXISTS("tipper.dep")
+!INCLUDE "tipper.dep"
+!ELSE
+!MESSAGE Warning: cannot find "tipper.dep"
+!ENDIF
+!ENDIF
+
+
+!IF "$(CFG)" == "tipper - Win32 Release" || "$(CFG)" == "tipper - Win32 Debug" || "$(CFG)" == "tipper - Win32 Release Unicode" || "$(CFG)" == "tipper - Win32 Debug Unicode"
+SOURCE=.\message_pump.cpp
+
+!IF "$(CFG)" == "tipper - Win32 Release"
+
+
+"$(INTDIR)\message_pump.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\tipper.pch"
+
+
+!ELSEIF "$(CFG)" == "tipper - Win32 Debug"
+
+
+"$(INTDIR)\message_pump.obj" "$(INTDIR)\message_pump.sbr" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\tipper.pch"
+
+
+!ELSEIF "$(CFG)" == "tipper - Win32 Release Unicode"
+
+
+"$(INTDIR)\message_pump.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\tipper.pch"
+
+
+!ELSEIF "$(CFG)" == "tipper - Win32 Debug Unicode"
+
+
+"$(INTDIR)\message_pump.obj" "$(INTDIR)\message_pump.sbr" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\tipper.pch"
+
+
+!ENDIF
+
+SOURCE=.\options.cpp
+
+!IF "$(CFG)" == "tipper - Win32 Release"
+
+
+"$(INTDIR)\options.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\tipper.pch"
+
+
+!ELSEIF "$(CFG)" == "tipper - Win32 Debug"
+
+
+"$(INTDIR)\options.obj" "$(INTDIR)\options.sbr" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\tipper.pch"
+
+
+!ELSEIF "$(CFG)" == "tipper - Win32 Release Unicode"
+
+
+"$(INTDIR)\options.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\tipper.pch"
+
+
+!ELSEIF "$(CFG)" == "tipper - Win32 Debug Unicode"
+
+
+"$(INTDIR)\options.obj" "$(INTDIR)\options.sbr" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\tipper.pch"
+
+
+!ENDIF
+
+SOURCE=.\popwin.cpp
+
+!IF "$(CFG)" == "tipper - Win32 Release"
+
+
+"$(INTDIR)\popwin.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\tipper.pch"
+
+
+!ELSEIF "$(CFG)" == "tipper - Win32 Debug"
+
+
+"$(INTDIR)\popwin.obj" "$(INTDIR)\popwin.sbr" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\tipper.pch"
+
+
+!ELSEIF "$(CFG)" == "tipper - Win32 Release Unicode"
+
+
+"$(INTDIR)\popwin.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\tipper.pch"
+
+
+!ELSEIF "$(CFG)" == "tipper - Win32 Debug Unicode"
+
+
+"$(INTDIR)\popwin.obj" "$(INTDIR)\popwin.sbr" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\tipper.pch"
+
+
+!ENDIF
+
+SOURCE=.\str_utils.cpp
+
+!IF "$(CFG)" == "tipper - Win32 Release"
+
+
+"$(INTDIR)\str_utils.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\tipper.pch"
+
+
+!ELSEIF "$(CFG)" == "tipper - Win32 Debug"
+
+
+"$(INTDIR)\str_utils.obj" "$(INTDIR)\str_utils.sbr" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\tipper.pch"
+
+
+!ELSEIF "$(CFG)" == "tipper - Win32 Release Unicode"
+
+
+"$(INTDIR)\str_utils.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\tipper.pch"
+
+
+!ELSEIF "$(CFG)" == "tipper - Win32 Debug Unicode"
+
+
+"$(INTDIR)\str_utils.obj" "$(INTDIR)\str_utils.sbr" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\tipper.pch"
+
+
+!ENDIF
+
+SOURCE=.\subst.cpp
+
+!IF "$(CFG)" == "tipper - Win32 Release"
+
+
+"$(INTDIR)\subst.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\tipper.pch"
+
+
+!ELSEIF "$(CFG)" == "tipper - Win32 Debug"
+
+
+"$(INTDIR)\subst.obj" "$(INTDIR)\subst.sbr" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\tipper.pch"
+
+
+!ELSEIF "$(CFG)" == "tipper - Win32 Release Unicode"
+
+
+"$(INTDIR)\subst.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\tipper.pch"
+
+
+!ELSEIF "$(CFG)" == "tipper - Win32 Debug Unicode"
+
+
+"$(INTDIR)\subst.obj" "$(INTDIR)\subst.sbr" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\tipper.pch"
+
+
+!ENDIF
+
+SOURCE=.\tipper.cpp
+
+!IF "$(CFG)" == "tipper - Win32 Release"
+
+CPP_SWITCHES=/nologo /MD /W3 /GX /Zi /O1 /I "../../include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "TIPPER_EXPORTS" /Fp"$(INTDIR)\tipper.pch" /Yc"common.h" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c
+
+"$(INTDIR)\tipper.obj" "$(INTDIR)\tipper.pch" : $(SOURCE) "$(INTDIR)"
+ $(CPP) @<<
+ $(CPP_SWITCHES) $(SOURCE)
+<<
+
+
+!ELSEIF "$(CFG)" == "tipper - Win32 Debug"
+
+CPP_SWITCHES=/nologo /MDd /W3 /Gm /GX /ZI /Od /I "../../include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "TIPPER_EXPORTS" /FR"$(INTDIR)\\" /Fp"$(INTDIR)\tipper.pch" /Yc"common.h" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /GZ /c
+
+"$(INTDIR)\tipper.obj" "$(INTDIR)\tipper.sbr" "$(INTDIR)\tipper.pch" : $(SOURCE) "$(INTDIR)"
+ $(CPP) @<<
+ $(CPP_SWITCHES) $(SOURCE)
+<<
+
+
+!ELSEIF "$(CFG)" == "tipper - Win32 Release Unicode"
+
+CPP_SWITCHES=/nologo /MD /W3 /GX /Zi /O1 /I "../../include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "UNICODE" /D "_USRDLL" /D "TIPPER_EXPORTS" /Fp"$(INTDIR)\tipper.pch" /Yc"common.h" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c
+
+"$(INTDIR)\tipper.obj" "$(INTDIR)\tipper.pch" : $(SOURCE) "$(INTDIR)"
+ $(CPP) @<<
+ $(CPP_SWITCHES) $(SOURCE)
+<<
+
+
+!ELSEIF "$(CFG)" == "tipper - Win32 Debug Unicode"
+
+CPP_SWITCHES=/nologo /MDd /W3 /Gm /GX /ZI /Od /I "../../include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "UNICODE" /D "_USRDLL" /D "TIPPER_EXPORTS" /FR"$(INTDIR)\\" /Fp"$(INTDIR)\tipper.pch" /Yc"common.h" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /GZ /c
+
+"$(INTDIR)\tipper.obj" "$(INTDIR)\tipper.sbr" "$(INTDIR)\tipper.pch" : $(SOURCE) "$(INTDIR)"
+ $(CPP) @<<
+ $(CPP_SWITCHES) $(SOURCE)
+<<
+
+
+!ENDIF
+
+SOURCE=.\translations.cpp
+
+!IF "$(CFG)" == "tipper - Win32 Release"
+
+
+"$(INTDIR)\translations.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\tipper.pch"
+
+
+!ELSEIF "$(CFG)" == "tipper - Win32 Debug"
+
+
+"$(INTDIR)\translations.obj" "$(INTDIR)\translations.sbr" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\tipper.pch"
+
+
+!ELSEIF "$(CFG)" == "tipper - Win32 Release Unicode"
+
+
+"$(INTDIR)\translations.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\tipper.pch"
+
+
+!ELSEIF "$(CFG)" == "tipper - Win32 Debug Unicode"
+
+
+"$(INTDIR)\translations.obj" "$(INTDIR)\translations.sbr" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\tipper.pch"
+
+
+!ENDIF
+
+SOURCE=.\resource.rc
+
+"$(INTDIR)\resource.res" : $(SOURCE) "$(INTDIR)"
+ $(RSC) $(RSC_PROJ) $(SOURCE)
+
+
+
+!ENDIF
+
diff --git a/plugins/tipper/tipper.mdsp b/plugins/tipper/tipper.mdsp
new file mode 100644
index 0000000000..f7354b92bc
--- /dev/null
+++ b/plugins/tipper/tipper.mdsp
@@ -0,0 +1,118 @@
+[Project]
+name=tipper
+type=2
+defaultConfig=0
+
+
+[Debug]
+// compiler
+workingDirectory=
+arguments=
+intermediateFilesDirectory=Debug
+outputFilesDirectory=Debug
+compilerPreprocessor=UNICODE,_UNICODE,TIPPER_EXPORTS
+extraCompilerOptions=
+compilerIncludeDirectory=..\..\include
+noWarning=0
+defaultWarning=0
+allWarning=1
+extraWarning=0
+isoWarning=0
+warningsAsErrors=0
+debugType=1
+debugLevel=2
+exceptionEnabled=1
+runtimeTypeEnabled=1
+optimizeLevel=0
+
+// linker
+libraryPath=
+outputFilename=Debug\tipper.dll
+libraries=unicows,gdi32,comctl32,ws2_32,comdlg32
+extraLinkerOptions=
+ignoreStartupFile=0
+ignoreDefaultLibs=0
+stripExecutableFile=0
+
+// archive
+extraArchiveOptions=
+
+//resource
+resourcePreprocessor=
+resourceIncludeDirectory=
+extraResourceOptions=
+
+[Release]
+// compiler
+workingDirectory=
+arguments=
+intermediateFilesDirectory=Release
+outputFilesDirectory=Release
+compilerPreprocessor=UNICODE,_UNICODE,TIPPER_EXPORTS
+extraCompilerOptions=
+compilerIncludeDirectory=..\..\include
+noWarning=0
+defaultWarning=0
+allWarning=1
+extraWarning=0
+isoWarning=0
+warningAsErrors=0
+debugType=1
+debugLevel=2
+exceptionEnabled=0
+runtimeTypeEnabled=0
+optimizeLevel=4
+
+// linker
+libraryPath=
+outputFilename=Release\tipper.dll
+libraries=unicows,gdi32,comctl32,ws2_32,comdlg32
+extraLinkerOptions=
+ignoreStartupFile=0
+ignoreDefaultLibs=0
+stripExecutableFile=1
+
+// archive
+extraArchiveOptions=
+
+//resource
+resourcePreprocessor=
+resourceIncludeDirectory=
+extraResourceOptions=
+
+[Source]
+1=message_pump.cpp
+2=options.cpp
+3=popwin.cpp
+4=tipper.cpp
+5=translations.cpp
+6=subst.cpp
+7=str_utils.cpp
+[Header]
+1=m_tipper.h
+2=message_pump.h
+3=options.h
+4=popwin.h
+5=resource.h
+6=stdafx.h
+7=tipper.h
+8=translations.h
+9=version.h
+10=subst.h
+11=str_utils.h
+12=common.h
+[Resource]
+1=resource.rc
+[Other]
+[History]
+..\..\..\..\..\..\..\msys\include\wingdi.h,0
+..\..\..\..\..\..\..\msys\include\windows.h,0
+common.h,1362
+..\..\include\m_imgsrvc.h,1413
+message_pump.cpp,0
+tipper.cpp,1246
+popwin.cpp,4094
+m_tipper.h,760
+version.h,519
+options.cpp,637
+..\..\plugins\freeimage\Miranda\include\m_freeimage.h,4431
diff --git a/plugins/tipper/tipper.rc b/plugins/tipper/tipper.rc
new file mode 100644
index 0000000000..3ea64bdbac
--- /dev/null
+++ b/plugins/tipper/tipper.rc
@@ -0,0 +1,260 @@
+// Microsoft Visual C++ generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE
+BEGIN
+ "#include ""afxres.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE
+BEGIN
+ "\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+#endif // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+/////////////////////////////////////////////////////////////////////////////
+// English (Australia) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENA)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_AUS
+#pragma code_page(1252)
+#endif //_WIN32
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+IDD_OPT_LAYOUT DIALOGEX 0, 0, 259, 160
+STYLE DS_SETFONT | DS_FIXEDSYS | DS_CENTER | WS_CHILD
+EXSTYLE WS_EX_CONTROLPARENT
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+ COMBOBOX IDC_CMB_ICON,12,26,107,69,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
+ COMBOBOX IDC_CMB_AV,12,40,107,76,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
+ EDITTEXT IDC_ED_INDENT,209,10,35,12,ES_RIGHT | ES_AUTOHSCROLL | ES_NUMBER,WS_EX_RIGHT
+ CONTROL "",IDC_SPIN_INDENT,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS,240,10,12,12
+ RTEXT "Text indent:",IDC_STATIC,157,13,46,8
+ EDITTEXT IDC_ED_PADDING,209,24,35,12,ES_RIGHT | ES_AUTOHSCROLL | ES_NUMBER,WS_EX_RIGHT
+ CONTROL "",IDC_SPIN_PADDING,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS,240,24,12,12
+ RTEXT "General padding:",IDC_STATIC,142,26,60,8
+ COMBOBOX IDC_CMB_POS,12,12,107,69,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
+ GROUPBOX "Alignment",IDC_STATIC,7,65,137,44
+ COMBOBOX IDC_CMB_LV,49,75,43,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
+ COMBOBOX IDC_CMB_VV,49,91,43,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
+ COMBOBOX IDC_CMB_LH,96,75,43,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
+ COMBOBOX IDC_CMB_VH,96,91,43,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
+ RTEXT "Labels:",IDC_STATIC,11,78,34,8
+ RTEXT "Values:",IDC_STATIC,11,94,34,8
+ EDITTEXT IDC_ED_SBWIDTH,209,66,35,12,ES_RIGHT | ES_AUTOHSCROLL | ES_NUMBER,WS_EX_RIGHT
+ CONTROL "",IDC_SPIN_SBWIDTH,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS,241,66,11,12
+ RTEXT "Sidebar width:",IDC_STATIC,145,68,60,8
+ EDITTEXT IDC_ED_TEXTPADDING,209,38,35,12,ES_RIGHT | ES_AUTOHSCROLL | ES_NUMBER,WS_EX_RIGHT
+ CONTROL "",IDC_SPIN_TEXTPADDING,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS,241,38,12,12
+ RTEXT "Text padding:",IDC_STATIC,143,39,59,8
+ EDITTEXT IDC_ED_AVPADDING,209,52,35,12,ES_RIGHT | ES_AUTOHSCROLL | ES_NUMBER,WS_EX_RIGHT
+ CONTROL "",IDC_SPIN_AVPADDING,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS,241,52,12,12
+ RTEXT "Avatar padding:",IDC_STATIC,143,53,59,8
+ EDITTEXT IDC_ED_AVSIZE,209,96,35,12,ES_RIGHT | ES_AUTOHSCROLL | ES_NUMBER,WS_EX_RIGHT
+ CONTROL "",IDC_SPIN_AVSIZE,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS,242,96,11,12
+ RTEXT "Max avatar size:",IDC_STATIC,145,98,60,8,0,WS_EX_RIGHT
+ CONTROL "Keep original avatar size",IDC_CHK_NORESIZEAV,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,147,84,103,11
+ RTEXT "Background image:",IDC_STATIC,8,127,89,8
+ EDITTEXT IDC_ED_BGFN,100,125,96,12,ES_AUTOHSCROLL
+ PUSHBUTTON "Browse...",IDC_BTN_BROWSE,198,124,50,13
+ CONTROL "Stretch",IDC_CHK_STRETCHBG,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,100,141,95,10
+END
+
+IDD_SUBST DIALOGEX 0, 0, 253, 182
+STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "Substitution"
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+ RTEXT "Label:",IDC_STATIC,31,21,48,8,0,WS_EX_RIGHT
+ EDITTEXT IDC_ED_LABEL,84,19,115,14,ES_AUTOHSCROLL
+ CONTROL "Contact protocol module",IDC_CHK_PROTOMOD,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,61,52,141,10
+ RTEXT "Module:",IDC_STATIC,21,74,69,8,0,WS_EX_RIGHT
+ EDITTEXT IDC_ED_MODULE,95,71,115,14,ES_AUTOHSCROLL
+ RTEXT "Setting or prefix:",IDC_STATIC,21,92,69,8,0,WS_EX_RIGHT
+ EDITTEXT IDC_ED_SETTING,95,89,115,14,ES_AUTOHSCROLL
+ LTEXT "Translation:",IDC_STATIC,46,118,139,8
+ COMBOBOX IDC_CMB_TRANSLATE,7,134,239,104,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP
+ DEFPUSHBUTTON "OK",IDOK,72,161,50,14
+ PUSHBUTTON "Cancel",IDCANCEL,130,161,50,14
+END
+
+IDD_ITEM DIALOGEX 0, 0, 207, 178
+STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "Item"
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+ LTEXT "Label:",IDC_STATIC,32,17,52,8
+ LTEXT "Value:",IDC_STATIC,32,49,52,8
+ EDITTEXT IDC_ED_LABEL,36,30,136,13,ES_AUTOHSCROLL
+ EDITTEXT IDC_ED_VALUE,36,61,136,45,ES_MULTILINE | ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN
+ CONTROL "Draw a line above",IDC_CHK_LINEABOVE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,53,112,101,10
+ CONTROL "Value on a new line",IDC_CHK_VALNEWLINE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,53,127,101,10
+ DEFPUSHBUTTON "OK",IDOK,51,157,50,14
+ PUSHBUTTON "Cancel",IDCANCEL,107,157,50,14
+END
+
+IDD_OPT_CONTENT DIALOGEX 0, 0, 289, 179
+STYLE DS_SETFONT | DS_FIXEDSYS | DS_CENTER | WS_CHILD
+EXSTYLE WS_EX_CONTROLPARENT
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+ GROUPBOX "Items",IDC_STATIC,7,3,135,169
+ LISTBOX IDC_LST_ITEMS,12,13,78,153,LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP
+ PUSHBUTTON "Add...",IDC_BTN_ADD,92,13,48,15
+ PUSHBUTTON "Delete",IDC_BTN_REMOVE,92,30,48,15
+ PUSHBUTTON "Up",IDC_BTN_UP,92,47,48,15
+ PUSHBUTTON "Down",IDC_BTN_DOWN,92,64,48,15
+ GROUPBOX "Substitutions",IDC_STATIC,147,3,135,169
+ PUSHBUTTON "Edit...",IDC_BTN_EDIT,92,81,48,15
+ LISTBOX IDC_LST_SUBST,152,13,78,153,LBS_SORT | LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP
+ PUSHBUTTON "Add...",IDC_BTN_ADD2,232,13,48,15
+ PUSHBUTTON "Delete",IDC_BTN_REMOVE2,232,30,48,15
+ PUSHBUTTON "Edit...",IDC_BTN_EDIT2,232,81,48,15
+END
+
+IDD_OPT_WINDOW DIALOGEX 0, 0, 278, 140
+STYLE DS_SETFONT | DS_FIXEDSYS | DS_CENTER | WS_CHILD
+EXSTYLE WS_EX_CONTROLPARENT
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+ EDITTEXT IDC_ED_WIDTH,89,15,31,12,ES_RIGHT | ES_AUTOHSCROLL | ES_NUMBER,WS_EX_RIGHT
+ CONTROL "",IDC_SPIN_WIDTH,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS,119,15,11,12
+ EDITTEXT IDC_ED_MAXHEIGHT,89,42,31,12,ES_RIGHT | ES_AUTOHSCROLL | ES_NUMBER,WS_EX_RIGHT
+ CONTROL "",IDC_SPIN_MAXHEIGHT,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS,119,42,11,12
+ RTEXT "Max width:",IDC_STATIC,31,18,52,8,0,WS_EX_RIGHT
+ RTEXT "Max height:",IDC_STATIC,27,45,57,8,0,WS_EX_RIGHT
+ CONTROL "Show if list not focused",IDC_CHK_NOFOCUS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,169,96,84,11
+ EDITTEXT IDC_ED_HOVER,225,114,31,12,ES_RIGHT | ES_AUTOHSCROLL | ES_NUMBER,WS_EX_RIGHT
+ CONTROL "",IDC_SPIN_HOVER,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS,255,114,11,12
+ RTEXT "Hover time:",IDC_STATIC,163,116,57,8,0,WS_EX_RIGHT
+ EDITTEXT IDC_ED_MINWIDTH,89,29,31,12,ES_RIGHT | ES_AUTOHSCROLL | ES_NUMBER,WS_EX_RIGHT
+ CONTROL "",IDC_SPIN_MINWIDTH,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS,119,29,11,12
+ RTEXT "Min width:",IDC_STATIC,31,31,52,8,0,WS_EX_RIGHT
+ EDITTEXT IDC_ED_MINHEIGHT,89,57,31,12,ES_RIGHT | ES_AUTOHSCROLL | ES_NUMBER,WS_EX_RIGHT
+ CONTROL "",IDC_SPIN_MINHEIGHT,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS,119,57,11,13
+ RTEXT "Min height:",IDC_STATIC,25,58,57,8,0,WS_EX_RIGHT
+ EDITTEXT IDC_ED_TRANS,89,102,33,12,ES_RIGHT | ES_AUTOHSCROLL | ES_NUMBER,WS_EX_RIGHT
+ CONTROL "",IDC_SPIN_TRANS,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | UDS_NOTHOUSANDS,119,102,11,12
+ RTEXT "Opacity(%):",IDC_STATIC,15,105,69,8,0,WS_EX_RIGHT
+ CONTROL "Transparent background",IDC_CHK_TRANSBG,"Button",BS_AUTOCHECKBOX | BS_LEFTTEXT | WS_TABSTOP,15,119,116,10,WS_EX_RIGHT
+ GROUPBOX "XP+",IDC_STATIC,7,89,141,44
+ GROUPBOX "General",IDC_STATIC,156,7,115,126
+ CONTROL "Border",IDC_CHK_BORDER,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,169,44,84,9
+ CONTROL "Round corners (window)",IDC_CHK_ROUNDCORNERS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,169,57,100,9
+ CONTROL "Animate",IDC_CHK_ANIMATE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,169,83,84,9
+ CONTROL "Shadow",IDC_CHK_SHADOW,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,169,31,84,9
+ CONTROL "Status bar tips",IDC_CHK_SBAR,"Button",BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,169,18,85,9
+ CONTROL "Round corners (avatar)",IDC_CHK_ROUNDCORNERSAV,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,169,70,100,9
+ GROUPBOX "Dimensions",IDC_STATIC,7,7,140,73
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// DESIGNINFO
+//
+
+#ifdef APSTUDIO_INVOKED
+GUIDELINES DESIGNINFO
+BEGIN
+ IDD_OPT_LAYOUT, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 253
+ TOPMARGIN, 4
+ BOTTOMMARGIN, 153
+ END
+
+ IDD_SUBST, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 246
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 175
+ END
+
+ IDD_ITEM, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 200
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 171
+ END
+
+ IDD_OPT_CONTENT, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 282
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 172
+ END
+
+ IDD_OPT_WINDOW, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 271
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 133
+ END
+END
+#endif // APSTUDIO_INVOKED
+
+#endif // English (Australia) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
diff --git a/plugins/tipper/tipper.vcproj b/plugins/tipper/tipper.vcproj
new file mode 100644
index 0000000000..0a409fc49e
--- /dev/null
+++ b/plugins/tipper/tipper.vcproj
@@ -0,0 +1,382 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="7.10"
+ Name="tipper"
+ ProjectGUID="{2C818919-A38F-44FF-BD91-A6A204AC592A}"
+ RootNamespace="tipper"
+ Keyword="Win32Proj"
+ SccProjectName=""
+ SccLocalPath="">
+ <Platforms>
+ <Platform
+ Name="Win32"/>
+ </Platforms>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)/Plugins"
+ IntermediateDirectory="$(SolutionDir)$(ConfigurationName)/Obj/$(ProjectName)"
+ ConfigurationType="2"
+ CharacterSet="1">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="../../include"
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;TIPPER_EXPORTS;_UNICODE;UNICODE;MICROSOFT_LAYER_FOR_UNICODE=1"
+ MinimalRebuild="TRUE"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ BufferSecurityCheck="TRUE"
+ UsePrecompiledHeader="3"
+ PrecompiledHeaderThrough="common.h"
+ WarningLevel="3"
+ DebugInformationFormat="4"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="comctl32.lib ws2_32.lib"
+ LinkIncremental="2"
+ GenerateDebugInformation="TRUE"
+ SubSystem="2"
+ TargetMachine="1"/>
+ <Tool
+ Name="VCMIDLTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)/Plugins"
+ IntermediateDirectory="$(SolutionDir)$(ConfigurationName)/Obj/$(ProjectName)"
+ ConfigurationType="2"
+ CharacterSet="1"
+ WholeProgramOptimization="TRUE">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="3"
+ GlobalOptimizations="TRUE"
+ FavorSizeOrSpeed="2"
+ OmitFramePointers="TRUE"
+ AdditionalIncludeDirectories="../../include"
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;TIPPER_EXPORTS;_UNICODE;UNICODE;MICROSOFT_LAYER_FOR_UNICODE=1"
+ RuntimeLibrary="2"
+ UsePrecompiledHeader="3"
+ PrecompiledHeaderThrough="common.h"
+ WarningLevel="3"
+ DebugInformationFormat="3"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="vc7to6.lib comctl32.lib ws2_32.lib"
+ LinkIncremental="1"
+ AdditionalLibraryDirectories="../../lib"
+ IgnoreAllDefaultLibraries="TRUE"
+ IgnoreDefaultLibraryNames="Kernel32.lib Advapi32.lib User32.lib Gdi32.lib Shell32.lib Comdlg32.lib Version.lib Mpr.lib Rasapi32.lib Winmm.lib Winspool.lib Vfw32.lib Secur32.lib Oleacc.lib Oledlg.lib Sensapi.lib"
+ GenerateDebugInformation="TRUE"
+ SubSystem="2"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ OptimizeForWindows98="1"
+ TargetMachine="1"/>
+ <Tool
+ Name="VCMIDLTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ <Configuration
+ Name="Debug Unicode|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)/Plugins"
+ IntermediateDirectory="$(SolutionDir)$(ConfigurationName)/Obj/$(ProjectName)"
+ ConfigurationType="2"
+ CharacterSet="1">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="../../include"
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;TIPPER_EXPORTS;_UNICODE;UNICODE;MICROSOFT_LAYER_FOR_UNICODE=1"
+ MinimalRebuild="TRUE"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ BufferSecurityCheck="TRUE"
+ UsePrecompiledHeader="3"
+ PrecompiledHeaderThrough="common.h"
+ WarningLevel="3"
+ DebugInformationFormat="4"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ IgnoreImportLibrary="TRUE"
+ AdditionalDependencies="comctl32.lib ws2_32.lib"
+ LinkIncremental="2"
+ GenerateDebugInformation="TRUE"
+ SubSystem="2"
+ TargetMachine="1"/>
+ <Tool
+ Name="VCMIDLTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ <Configuration
+ Name="Release Unicode|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)/Plugins"
+ IntermediateDirectory="$(SolutionDir)$(ConfigurationName)/Obj/$(ProjectName)"
+ ConfigurationType="2"
+ CharacterSet="1"
+ WholeProgramOptimization="FALSE">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="3"
+ GlobalOptimizations="TRUE"
+ FavorSizeOrSpeed="2"
+ OmitFramePointers="FALSE"
+ OptimizeForProcessor="0"
+ AdditionalIncludeDirectories="../../include"
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;TIPPER_EXPORTS;_UNICODE;UNICODE;MICROSOFT_LAYER_FOR_UNICODE=1"
+ StringPooling="TRUE"
+ RuntimeLibrary="2"
+ BufferSecurityCheck="TRUE"
+ UsePrecompiledHeader="3"
+ PrecompiledHeaderThrough="common.h"
+ WarningLevel="3"
+ DebugInformationFormat="3"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ IgnoreImportLibrary="TRUE"
+ AdditionalDependencies="vc7to6.lib comctl32.lib ws2_32.lib"
+ AdditionalLibraryDirectories="../../lib"
+ IgnoreAllDefaultLibraries="TRUE"
+ IgnoreDefaultLibraryNames="Kernel32.lib Advapi32.lib User32.lib Gdi32.lib Shell32.lib Comdlg32.lib Version.lib Mpr.lib Rasapi32.lib Winmm.lib Winspool.lib Vfw32.lib Secur32.lib Oleacc.lib Oledlg.lib Sensapi.lib"
+ GenerateDebugInformation="TRUE"
+ GenerateMapFile="TRUE"
+ SubSystem="2"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ OptimizeForWindows98="1"
+ TargetMachine="1"/>
+ <Tool
+ Name="VCMIDLTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
+ <File
+ RelativePath=".\message_pump.cpp">
+ </File>
+ <File
+ RelativePath=".\options.cpp">
+ </File>
+ <File
+ RelativePath=".\popwin.cpp">
+ </File>
+ <File
+ RelativePath=".\str_utils.cpp">
+ </File>
+ <File
+ RelativePath=".\subst.cpp">
+ </File>
+ <File
+ RelativePath=".\tipper.cpp">
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="1"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="1"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug Unicode|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="1"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release Unicode|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="1"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\translations.cpp">
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
+ <File
+ RelativePath=".\common.h">
+ </File>
+ <File
+ RelativePath=".\message_pump.h">
+ </File>
+ <File
+ RelativePath=".\options.h">
+ </File>
+ <File
+ RelativePath=".\popwin.h">
+ </File>
+ <File
+ RelativePath=".\resource.h">
+ </File>
+ <File
+ RelativePath=".\str_utils.h">
+ </File>
+ <File
+ RelativePath=".\tipper.h">
+ </File>
+ <File
+ RelativePath=".\translations.h">
+ </File>
+ <File
+ RelativePath=".\version.h">
+ </File>
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}">
+ <File
+ RelativePath=".\resource.rc">
+ </File>
+ <File
+ RelativePath=".\tipper.rc">
+ <FileConfiguration
+ Name="Debug|Win32"
+ ExcludedFromBuild="TRUE">
+ <Tool
+ Name="VCResourceCompilerTool"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ ExcludedFromBuild="TRUE">
+ <Tool
+ Name="VCResourceCompilerTool"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug Unicode|Win32"
+ ExcludedFromBuild="TRUE">
+ <Tool
+ Name="VCResourceCompilerTool"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release Unicode|Win32"
+ ExcludedFromBuild="TRUE">
+ <Tool
+ Name="VCResourceCompilerTool"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\version.rc">
+ <FileConfiguration
+ Name="Debug|Win32"
+ ExcludedFromBuild="TRUE">
+ <Tool
+ Name="VCResourceCompilerTool"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ ExcludedFromBuild="TRUE">
+ <Tool
+ Name="VCResourceCompilerTool"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug Unicode|Win32"
+ ExcludedFromBuild="TRUE">
+ <Tool
+ Name="VCResourceCompilerTool"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release Unicode|Win32"
+ ExcludedFromBuild="TRUE">
+ <Tool
+ Name="VCResourceCompilerTool"/>
+ </FileConfiguration>
+ </File>
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/plugins/tipper/tipper_10.sln b/plugins/tipper/tipper_10.sln
new file mode 100644
index 0000000000..dd39c15ad8
--- /dev/null
+++ b/plugins/tipper/tipper_10.sln
@@ -0,0 +1,38 @@
+
+Microsoft Visual Studio Solution File, Format Version 11.00
+# Visual Studio 2010
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tipper", "tipper_10.vcxproj", "{2CFFE6E3-FD83-4E6E-9D7A-8DAA59CC9B18}"
+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
+ {2CFFE6E3-FD83-4E6E-9D7A-8DAA59CC9B18}.Debug Unicode|Win32.ActiveCfg = Debug Unicode|Win32
+ {2CFFE6E3-FD83-4E6E-9D7A-8DAA59CC9B18}.Debug Unicode|Win32.Build.0 = Debug Unicode|Win32
+ {2CFFE6E3-FD83-4E6E-9D7A-8DAA59CC9B18}.Debug Unicode|x64.ActiveCfg = Debug Unicode|x64
+ {2CFFE6E3-FD83-4E6E-9D7A-8DAA59CC9B18}.Debug Unicode|x64.Build.0 = Debug Unicode|x64
+ {2CFFE6E3-FD83-4E6E-9D7A-8DAA59CC9B18}.Debug|Win32.ActiveCfg = Debug|Win32
+ {2CFFE6E3-FD83-4E6E-9D7A-8DAA59CC9B18}.Debug|Win32.Build.0 = Debug|Win32
+ {2CFFE6E3-FD83-4E6E-9D7A-8DAA59CC9B18}.Debug|x64.ActiveCfg = Debug|x64
+ {2CFFE6E3-FD83-4E6E-9D7A-8DAA59CC9B18}.Debug|x64.Build.0 = Debug|x64
+ {2CFFE6E3-FD83-4E6E-9D7A-8DAA59CC9B18}.Release Unicode|Win32.ActiveCfg = Release Unicode|Win32
+ {2CFFE6E3-FD83-4E6E-9D7A-8DAA59CC9B18}.Release Unicode|Win32.Build.0 = Release Unicode|Win32
+ {2CFFE6E3-FD83-4E6E-9D7A-8DAA59CC9B18}.Release Unicode|x64.ActiveCfg = Release Unicode|x64
+ {2CFFE6E3-FD83-4E6E-9D7A-8DAA59CC9B18}.Release Unicode|x64.Build.0 = Release Unicode|x64
+ {2CFFE6E3-FD83-4E6E-9D7A-8DAA59CC9B18}.Release|Win32.ActiveCfg = Release|Win32
+ {2CFFE6E3-FD83-4E6E-9D7A-8DAA59CC9B18}.Release|Win32.Build.0 = Release|Win32
+ {2CFFE6E3-FD83-4E6E-9D7A-8DAA59CC9B18}.Release|x64.ActiveCfg = Release|x64
+ {2CFFE6E3-FD83-4E6E-9D7A-8DAA59CC9B18}.Release|x64.Build.0 = Release|x64
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/plugins/tipper/tipper_10.vcxproj b/plugins/tipper/tipper_10.vcxproj
new file mode 100644
index 0000000000..7e9b2243f8
--- /dev/null
+++ b/plugins/tipper/tipper_10.vcxproj
@@ -0,0 +1,429 @@
+<?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">
+ <ProjectName>tipper</ProjectName>
+ <ProjectGuid>{2CFFE6E3-FD83-4E6E-9D7A-8DAA59CC9B18}</ProjectGuid>
+ <RootNamespace>tipper</RootNamespace>
+ <Keyword>Win32Proj</Keyword>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <CharacterSet>Unicode</CharacterSet>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release Unicode|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release Unicode|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup>
+ <_ProjectFileVersion>10.0.30319.311</_ProjectFileVersion>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)$(Configuration)/Plugins\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)$(Configuration)/Obj/$(ProjectName)\</IntDir>
+ <IgnoreImportLibrary Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</IgnoreImportLibrary>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)$(Configuration)64/Plugins\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)$(Configuration)64/Obj/$(ProjectName)\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</LinkIncremental>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)$(Configuration)/Plugins\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)$(Configuration)/Obj/$(ProjectName)\</IntDir>
+ <IgnoreImportLibrary Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</IgnoreImportLibrary>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SolutionDir)$(Configuration)64/Plugins\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SolutionDir)$(Configuration)64/Obj/$(ProjectName)\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'">$(SolutionDir)$(Configuration)/Plugins\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'">$(SolutionDir)$(Configuration)/Obj/$(ProjectName)\</IntDir>
+ <IgnoreImportLibrary Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'">true</IgnoreImportLibrary>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|x64'">$(SolutionDir)$(Configuration)64/Plugins\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|x64'">$(SolutionDir)$(Configuration)64/Obj/$(ProjectName)\</IntDir>
+ <IgnoreImportLibrary Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|x64'">true</IgnoreImportLibrary>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|x64'">true</LinkIncremental>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'">$(SolutionDir)$(Configuration)/Plugins\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'">$(SolutionDir)$(Configuration)/Obj/$(ProjectName)\</IntDir>
+ <IgnoreImportLibrary Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'">true</IgnoreImportLibrary>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release Unicode|x64'">$(SolutionDir)$(Configuration)64/Plugins\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release Unicode|x64'">$(SolutionDir)$(Configuration)64/Obj/$(ProjectName)\</IntDir>
+ <IgnoreImportLibrary Condition="'$(Configuration)|$(Platform)'=='Release Unicode|x64'">true</IgnoreImportLibrary>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>../../include;..\..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_DEBUG;_USRDLL;TIPPER_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>true</MinimalRebuild>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <BufferSecurityCheck>true</BufferSecurityCheck>
+ <PrecompiledHeader>Use</PrecompiledHeader>
+ <PrecompiledHeaderFile>common.h</PrecompiledHeaderFile>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
+ <DisableSpecificWarnings>4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>comctl32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Windows</SubSystem>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <TargetMachine>MachineX86</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <Midl>
+ <TargetEnvironment>X64</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>../../include;..\..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_DEBUG;_USRDLL;TIPPER_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>true</MinimalRebuild>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <BufferSecurityCheck>true</BufferSecurityCheck>
+ <PrecompiledHeader>Use</PrecompiledHeader>
+ <PrecompiledHeaderFile>common.h</PrecompiledHeaderFile>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <DisableSpecificWarnings>4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>comctl32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Windows</SubSystem>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <TargetMachine>MachineX64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <Optimization>Full</Optimization>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <AdditionalIncludeDirectories>../../include;..\..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>NDEBUG;_USRDLL;TIPPER_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <ExceptionHandling>false</ExceptionHandling>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FloatingPointModel>Fast</FloatingPointModel>
+ <RuntimeTypeInfo>false</RuntimeTypeInfo>
+ <PrecompiledHeader>Use</PrecompiledHeader>
+ <PrecompiledHeaderFile>common.h</PrecompiledHeaderFile>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <DisableSpecificWarnings>4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>comctl32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <IgnoreSpecificDefaultLibraries>%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Windows</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ <TargetMachine>MachineX86</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <Midl>
+ <TargetEnvironment>X64</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <Optimization>Full</Optimization>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <AdditionalIncludeDirectories>../../include;..\..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>NDEBUG;_USRDLL;TIPPER_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <ExceptionHandling>false</ExceptionHandling>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FloatingPointModel>Fast</FloatingPointModel>
+ <RuntimeTypeInfo>false</RuntimeTypeInfo>
+ <PrecompiledHeader>Use</PrecompiledHeader>
+ <PrecompiledHeaderFile>common.h</PrecompiledHeaderFile>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <DisableSpecificWarnings>4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>comctl32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <IgnoreSpecificDefaultLibraries>%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Windows</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <TargetMachine>MachineX64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'">
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>../../include;..\..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_DEBUG;_USRDLL;TIPPER_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>true</MinimalRebuild>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <BufferSecurityCheck>true</BufferSecurityCheck>
+ <PrecompiledHeader>Use</PrecompiledHeader>
+ <PrecompiledHeaderFile>common.h</PrecompiledHeaderFile>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
+ <DisableSpecificWarnings>4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>comctl32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Windows</SubSystem>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ <TargetMachine>MachineX86</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|x64'">
+ <Midl>
+ <TargetEnvironment>X64</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>../../include;..\..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_DEBUG;_USRDLL;TIPPER_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>true</MinimalRebuild>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <PrecompiledHeader>Use</PrecompiledHeader>
+ <PrecompiledHeaderFile>common.h</PrecompiledHeaderFile>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <DisableSpecificWarnings>4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>comctl32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>c:\miranda im\plugins\$(ProjectName).dll</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Windows</SubSystem>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <TargetMachine>MachineX64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'">
+ <ClCompile>
+ <Optimization>Full</Optimization>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <AdditionalIncludeDirectories>../../include;..\..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>NDEBUG;_USRDLL;TIPPER_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <ExceptionHandling>false</ExceptionHandling>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <FloatingPointModel>Fast</FloatingPointModel>
+ <RuntimeTypeInfo>false</RuntimeTypeInfo>
+ <PrecompiledHeader>Use</PrecompiledHeader>
+ <PrecompiledHeaderFile>common.h</PrecompiledHeaderFile>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <DisableSpecificWarnings>4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>comctl32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <IgnoreSpecificDefaultLibraries>%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Windows</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ <TargetMachine>MachineX86</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release Unicode|x64'">
+ <Midl>
+ <TargetEnvironment>X64</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <Optimization>Full</Optimization>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <AdditionalIncludeDirectories>../../include;..\..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>NDEBUG;_USRDLL;TIPPER_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <ExceptionHandling>false</ExceptionHandling>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <FloatingPointModel>Fast</FloatingPointModel>
+ <RuntimeTypeInfo>false</RuntimeTypeInfo>
+ <PrecompiledHeader>Use</PrecompiledHeader>
+ <PrecompiledHeaderFile>common.h</PrecompiledHeaderFile>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <DisableSpecificWarnings>4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>comctl32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <IgnoreSpecificDefaultLibraries>%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Windows</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <TargetMachine>MachineX64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="message_pump.cpp" />
+ <ClCompile Include="options.cpp" />
+ <ClCompile Include="popwin.cpp" />
+ <ClCompile Include="str_utils.cpp" />
+ <ClCompile Include="subst.cpp" />
+ <ClCompile Include="tipper.cpp">
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'">Create</PrecompiledHeader>
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|x64'">Create</PrecompiledHeader>
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|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|Win32'">Create</PrecompiledHeader>
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="translations.cpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="common.h" />
+ <ClInclude Include="message_pump.h" />
+ <ClInclude Include="options.h" />
+ <ClInclude Include="popwin.h" />
+ <ClInclude Include="resource.h" />
+ <ClInclude Include="str_utils.h" />
+ <ClInclude Include="tipper.h" />
+ <ClInclude Include="translations.h" />
+ <ClInclude Include="version.h" />
+ </ItemGroup>
+ <ItemGroup>
+ <ResourceCompile Include="resource.rc" />
+ <ResourceCompile Include="tipper.rc">
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|x64'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release Unicode|x64'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
+ </ResourceCompile>
+ <ResourceCompile Include="version.rc">
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|x64'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release Unicode|x64'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
+ </ResourceCompile>
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/plugins/tipper/tipper_10.vcxproj.filters b/plugins/tipper/tipper_10.vcxproj.filters
new file mode 100644
index 0000000000..440766e4ef
--- /dev/null
+++ b/plugins/tipper/tipper_10.vcxproj.filters
@@ -0,0 +1,80 @@
+<?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>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
+ <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
+ </Filter>
+ <Filter Include="Header Files">
+ <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
+ <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
+ </Filter>
+ <Filter Include="Resource Files">
+ <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
+ <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav</Extensions>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="message_pump.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="options.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="popwin.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="str_utils.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="subst.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="tipper.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="translations.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="common.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="message_pump.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="options.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="popwin.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="resource.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="str_utils.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="tipper.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="translations.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="version.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ </ItemGroup>
+ <ItemGroup>
+ <ResourceCompile Include="resource.rc">
+ <Filter>Resource Files</Filter>
+ </ResourceCompile>
+ <ResourceCompile Include="tipper.rc">
+ <Filter>Resource Files</Filter>
+ </ResourceCompile>
+ <ResourceCompile Include="version.rc">
+ <Filter>Resource Files</Filter>
+ </ResourceCompile>
+ </ItemGroup>
+</Project> \ No newline at end of file
diff --git a/plugins/tipper/tipper_8.sln b/plugins/tipper/tipper_8.sln
new file mode 100644
index 0000000000..467d54a102
--- /dev/null
+++ b/plugins/tipper/tipper_8.sln
@@ -0,0 +1,23 @@
+
+Microsoft Visual Studio Solution File, Format Version 9.00
+# Visual Studio 2005
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tipper", "tipper_8.vcproj", "{2C818919-A38F-44FF-BD91-A6A204AC592A}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Win32 = Debug|Win32
+ Release (ansi)|Win32 = Release (ansi)|Win32
+ Release|Win32 = Release|Win32
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {2C818919-A38F-44FF-BD91-A6A204AC592A}.Debug|Win32.ActiveCfg = Debug|Win32
+ {2C818919-A38F-44FF-BD91-A6A204AC592A}.Debug|Win32.Build.0 = Debug|Win32
+ {2C818919-A38F-44FF-BD91-A6A204AC592A}.Release (ansi)|Win32.ActiveCfg = Release (ansi)|Win32
+ {2C818919-A38F-44FF-BD91-A6A204AC592A}.Release (ansi)|Win32.Build.0 = Release (ansi)|Win32
+ {2C818919-A38F-44FF-BD91-A6A204AC592A}.Release|Win32.ActiveCfg = Release|Win32
+ {2C818919-A38F-44FF-BD91-A6A204AC592A}.Release|Win32.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/plugins/tipper/tipper_8.vcproj b/plugins/tipper/tipper_8.vcproj
new file mode 100644
index 0000000000..494ca37458
--- /dev/null
+++ b/plugins/tipper/tipper_8.vcproj
@@ -0,0 +1,537 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="8,00"
+ Name="tipper"
+ ProjectGUID="{2C818919-A38F-44FF-BD91-A6A204AC592A}"
+ RootNamespace="tipper"
+ Keyword="Win32Proj"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)/Plugins"
+ IntermediateDirectory="$(SolutionDir)$(ConfigurationName)/Obj/$(ProjectName)"
+ ConfigurationType="2"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="../../include"
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;TIPPER_EXPORTS;_UNICODE;UNICODE;MICROSOFT_LAYER_FOR_UNICODE=1"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ BufferSecurityCheck="true"
+ PrecompiledHeaderThrough="common.h"
+ WarningLevel="3"
+ DebugInformationFormat="4"
+ DisableSpecificWarnings="4996"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="comctl32.lib ws2_32.lib"
+ LinkIncremental="2"
+ GenerateDebugInformation="true"
+ SubSystem="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)/Plugins"
+ IntermediateDirectory="$(SolutionDir)$(ConfigurationName)/Obj/$(ProjectName)"
+ ConfigurationType="2"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="3"
+ FavorSizeOrSpeed="2"
+ AdditionalIncludeDirectories="../../include"
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;TIPPER_EXPORTS;_UNICODE;UNICODE;MICROSOFT_LAYER_FOR_UNICODE=1"
+ RuntimeLibrary="2"
+ PrecompiledHeaderThrough="common.h"
+ WarningLevel="3"
+ DebugInformationFormat="3"
+ DisableSpecificWarnings="4996"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="comctl32.lib ws2_32.lib"
+ LinkIncremental="1"
+ IgnoreDefaultLibraryNames="Kernel32.lib Advapi32.lib User32.lib Gdi32.lib Shell32.lib Comdlg32.lib Version.lib Mpr.lib Rasapi32.lib Winmm.lib Winspool.lib Vfw32.lib Secur32.lib Oleacc.lib Oledlg.lib Sensapi.lib"
+ GenerateDebugInformation="true"
+ SubSystem="2"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ OptimizeForWindows98="1"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug Unicode|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)/Plugins"
+ IntermediateDirectory="$(SolutionDir)$(ConfigurationName)/Obj/$(ProjectName)"
+ ConfigurationType="2"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="../../include"
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;TIPPER_EXPORTS;_UNICODE;UNICODE;MICROSOFT_LAYER_FOR_UNICODE=1"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ BufferSecurityCheck="true"
+ PrecompiledHeaderThrough="common.h"
+ WarningLevel="3"
+ DebugInformationFormat="4"
+ DisableSpecificWarnings="4996"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ IgnoreImportLibrary="true"
+ AdditionalDependencies="comctl32.lib ws2_32.lib"
+ LinkIncremental="2"
+ GenerateDebugInformation="true"
+ SubSystem="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release Unicode|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)/Plugins"
+ IntermediateDirectory="$(SolutionDir)$(ConfigurationName)/Obj/$(ProjectName)"
+ ConfigurationType="2"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="3"
+ InlineFunctionExpansion="1"
+ FavorSizeOrSpeed="2"
+ WholeProgramOptimization="true"
+ AdditionalIncludeDirectories="../../include"
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;TIPPER_EXPORTS;_UNICODE;UNICODE;MICROSOFT_LAYER_FOR_UNICODE=1"
+ StringPooling="true"
+ RuntimeLibrary="2"
+ EnableFunctionLevelLinking="true"
+ PrecompiledHeaderThrough="common.h"
+ WarningLevel="3"
+ DebugInformationFormat="3"
+ DisableSpecificWarnings="4996"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ IgnoreImportLibrary="true"
+ AdditionalDependencies="comctl32.lib ws2_32.lib"
+ IgnoreDefaultLibraryNames="Kernel32.lib Advapi32.lib User32.lib Gdi32.lib Shell32.lib Comdlg32.lib Version.lib Mpr.lib Rasapi32.lib Winmm.lib Winspool.lib Vfw32.lib Secur32.lib Oleacc.lib Oledlg.lib Sensapi.lib"
+ GenerateDebugInformation="true"
+ GenerateMapFile="true"
+ SubSystem="2"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ OptimizeForWindows98="1"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
+ <File
+ RelativePath=".\message_pump.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\options.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\popwin.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\str_utils.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\subst.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\tipper.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="1"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="1"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug Unicode|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="1"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release Unicode|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="1"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\translations.cpp"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+ >
+ <File
+ RelativePath=".\common.h"
+ >
+ </File>
+ <File
+ RelativePath=".\message_pump.h"
+ >
+ </File>
+ <File
+ RelativePath=".\options.h"
+ >
+ </File>
+ <File
+ RelativePath=".\popwin.h"
+ >
+ </File>
+ <File
+ RelativePath=".\resource.h"
+ >
+ </File>
+ <File
+ RelativePath=".\str_utils.h"
+ >
+ </File>
+ <File
+ RelativePath=".\tipper.h"
+ >
+ </File>
+ <File
+ RelativePath=".\translations.h"
+ >
+ </File>
+ <File
+ RelativePath=".\version.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+ >
+ <File
+ RelativePath=".\resource.rc"
+ >
+ </File>
+ <File
+ RelativePath=".\tipper.rc"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug Unicode|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release Unicode|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\version.rc"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug Unicode|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release Unicode|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ </FileConfiguration>
+ </File>
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/plugins/tipper/tipper_9.sln b/plugins/tipper/tipper_9.sln
new file mode 100644
index 0000000000..df3470aeff
--- /dev/null
+++ b/plugins/tipper/tipper_9.sln
@@ -0,0 +1,38 @@
+
+Microsoft Visual Studio Solution File, Format Version 10.00
+# Visual Studio 2008
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tipper", "tipper_9.vcproj", "{2CFFE6E3-FD83-4E6E-9D7A-8DAA59CC9B18}"
+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
+ {2CFFE6E3-FD83-4E6E-9D7A-8DAA59CC9B18}.Debug Unicode|Win32.ActiveCfg = Debug Unicode|Win32
+ {2CFFE6E3-FD83-4E6E-9D7A-8DAA59CC9B18}.Debug Unicode|Win32.Build.0 = Debug Unicode|Win32
+ {2CFFE6E3-FD83-4E6E-9D7A-8DAA59CC9B18}.Debug Unicode|x64.ActiveCfg = Debug Unicode|x64
+ {2CFFE6E3-FD83-4E6E-9D7A-8DAA59CC9B18}.Debug Unicode|x64.Build.0 = Debug Unicode|x64
+ {2CFFE6E3-FD83-4E6E-9D7A-8DAA59CC9B18}.Debug|Win32.ActiveCfg = Debug|Win32
+ {2CFFE6E3-FD83-4E6E-9D7A-8DAA59CC9B18}.Debug|Win32.Build.0 = Debug|Win32
+ {2CFFE6E3-FD83-4E6E-9D7A-8DAA59CC9B18}.Debug|x64.ActiveCfg = Debug|x64
+ {2CFFE6E3-FD83-4E6E-9D7A-8DAA59CC9B18}.Debug|x64.Build.0 = Debug|x64
+ {2CFFE6E3-FD83-4E6E-9D7A-8DAA59CC9B18}.Release Unicode|Win32.ActiveCfg = Release Unicode|Win32
+ {2CFFE6E3-FD83-4E6E-9D7A-8DAA59CC9B18}.Release Unicode|Win32.Build.0 = Release Unicode|Win32
+ {2CFFE6E3-FD83-4E6E-9D7A-8DAA59CC9B18}.Release Unicode|x64.ActiveCfg = Release Unicode|x64
+ {2CFFE6E3-FD83-4E6E-9D7A-8DAA59CC9B18}.Release Unicode|x64.Build.0 = Release Unicode|x64
+ {2CFFE6E3-FD83-4E6E-9D7A-8DAA59CC9B18}.Release|Win32.ActiveCfg = Release|Win32
+ {2CFFE6E3-FD83-4E6E-9D7A-8DAA59CC9B18}.Release|Win32.Build.0 = Release|Win32
+ {2CFFE6E3-FD83-4E6E-9D7A-8DAA59CC9B18}.Release|x64.ActiveCfg = Release|x64
+ {2CFFE6E3-FD83-4E6E-9D7A-8DAA59CC9B18}.Release|x64.Build.0 = Release|x64
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/plugins/tipper/tipper_9.vcproj b/plugins/tipper/tipper_9.vcproj
new file mode 100644
index 0000000000..b60fdbc360
--- /dev/null
+++ b/plugins/tipper/tipper_9.vcproj
@@ -0,0 +1,981 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9.00"
+ Name="tipper"
+ ProjectGUID="{2CFFE6E3-FD83-4E6E-9D7A-8DAA59CC9B18}"
+ RootNamespace="tipper"
+ Keyword="Win32Proj"
+ TargetFrameworkVersion="131072"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ <Platform
+ Name="x64"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)/Plugins"
+ IntermediateDirectory="$(SolutionDir)$(ConfigurationName)/Obj/$(ProjectName)"
+ ConfigurationType="2"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="../../include;..\..\..\include"
+ PreprocessorDefinitions="_DEBUG;_USRDLL;TIPPER_EXPORTS"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ BufferSecurityCheck="true"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="common.h"
+ WarningLevel="3"
+ DebugInformationFormat="4"
+ DisableSpecificWarnings="4996"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ IgnoreImportLibrary="true"
+ AdditionalDependencies="comctl32.lib"
+ GenerateDebugInformation="true"
+ SubSystem="2"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug|x64"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)64/Plugins"
+ IntermediateDirectory="$(SolutionDir)$(ConfigurationName)64/Obj/$(ProjectName)"
+ ConfigurationType="2"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="../../include;..\..\..\include"
+ PreprocessorDefinitions="_DEBUG;_USRDLL;TIPPER_EXPORTS"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ BufferSecurityCheck="true"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="common.h"
+ WarningLevel="3"
+ DebugInformationFormat="3"
+ DisableSpecificWarnings="4996"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="comctl32.lib"
+ LinkIncremental="2"
+ GenerateDebugInformation="true"
+ SubSystem="2"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)/Plugins"
+ IntermediateDirectory="$(SolutionDir)$(ConfigurationName)/Obj/$(ProjectName)"
+ ConfigurationType="2"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="3"
+ InlineFunctionExpansion="1"
+ EnableIntrinsicFunctions="true"
+ FavorSizeOrSpeed="2"
+ WholeProgramOptimization="true"
+ AdditionalIncludeDirectories="../../include;..\..\..\include"
+ PreprocessorDefinitions="NDEBUG;_USRDLL;TIPPER_EXPORTS"
+ StringPooling="true"
+ ExceptionHandling="0"
+ RuntimeLibrary="2"
+ BufferSecurityCheck="false"
+ FloatingPointModel="2"
+ RuntimeTypeInfo="false"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="common.h"
+ WarningLevel="3"
+ DebugInformationFormat="3"
+ DisableSpecificWarnings="4996"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ IgnoreImportLibrary="true"
+ AdditionalDependencies="comctl32.lib"
+ IgnoreDefaultLibraryNames=""
+ GenerateDebugInformation="true"
+ SubSystem="2"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ OptimizeForWindows98="0"
+ LinkTimeCodeGeneration="1"
+ RandomizedBaseAddress="1"
+ ImportLibrary="$(IntDir)/$(TargetName).lib"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|x64"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)64/Plugins"
+ IntermediateDirectory="$(SolutionDir)$(ConfigurationName)64/Obj/$(ProjectName)"
+ ConfigurationType="2"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="3"
+ InlineFunctionExpansion="1"
+ EnableIntrinsicFunctions="true"
+ FavorSizeOrSpeed="2"
+ WholeProgramOptimization="true"
+ AdditionalIncludeDirectories="../../include;..\..\..\include"
+ PreprocessorDefinitions="NDEBUG;_USRDLL;TIPPER_EXPORTS"
+ StringPooling="true"
+ ExceptionHandling="0"
+ RuntimeLibrary="2"
+ BufferSecurityCheck="false"
+ FloatingPointModel="2"
+ RuntimeTypeInfo="false"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="common.h"
+ WarningLevel="3"
+ DebugInformationFormat="3"
+ DisableSpecificWarnings="4996"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="comctl32.lib"
+ LinkIncremental="1"
+ IgnoreDefaultLibraryNames=""
+ GenerateDebugInformation="true"
+ SubSystem="2"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ LinkTimeCodeGeneration="1"
+ RandomizedBaseAddress="1"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug Unicode|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)/Plugins"
+ IntermediateDirectory="$(SolutionDir)$(ConfigurationName)/Obj/$(ProjectName)"
+ ConfigurationType="2"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="../../include;..\..\..\include"
+ PreprocessorDefinitions="_DEBUG;_USRDLL;TIPPER_EXPORTS"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ BufferSecurityCheck="true"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="common.h"
+ WarningLevel="3"
+ DebugInformationFormat="4"
+ DisableSpecificWarnings="4996"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ IgnoreImportLibrary="true"
+ AdditionalDependencies="comctl32.lib"
+ GenerateDebugInformation="true"
+ SubSystem="2"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ ImportLibrary="$(IntDir)/$(TargetName).lib"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug Unicode|x64"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)64/Plugins"
+ IntermediateDirectory="$(SolutionDir)$(ConfigurationName)64/Obj/$(ProjectName)"
+ ConfigurationType="2"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="../../include;..\..\..\include"
+ PreprocessorDefinitions="_DEBUG;_USRDLL;TIPPER_EXPORTS"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="common.h"
+ WarningLevel="3"
+ DebugInformationFormat="3"
+ DisableSpecificWarnings="4996"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ IgnoreImportLibrary="true"
+ AdditionalDependencies="comctl32.lib"
+ OutputFile="\miranda im\plugins\$(ProjectName).dll"
+ LinkIncremental="2"
+ GenerateDebugInformation="true"
+ SubSystem="2"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release Unicode|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)/Plugins"
+ IntermediateDirectory="$(SolutionDir)$(ConfigurationName)/Obj/$(ProjectName)"
+ ConfigurationType="2"
+ CharacterSet="1"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="1"
+ InlineFunctionExpansion="1"
+ EnableIntrinsicFunctions="true"
+ FavorSizeOrSpeed="2"
+ WholeProgramOptimization="true"
+ AdditionalIncludeDirectories="../../include;..\..\..\include"
+ PreprocessorDefinitions="NDEBUG;_USRDLL;TIPPER_EXPORTS"
+ StringPooling="true"
+ ExceptionHandling="0"
+ RuntimeLibrary="2"
+ BufferSecurityCheck="false"
+ EnableFunctionLevelLinking="true"
+ FloatingPointModel="2"
+ RuntimeTypeInfo="false"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="common.h"
+ WarningLevel="3"
+ DisableSpecificWarnings="4996"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ IgnoreImportLibrary="true"
+ AdditionalDependencies="comctl32.lib"
+ IgnoreDefaultLibraryNames=""
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ LinkTimeCodeGeneration="1"
+ RandomizedBaseAddress="1"
+ ImportLibrary="$(IntDir)/$(TargetName).lib"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release Unicode|x64"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)64/Plugins"
+ IntermediateDirectory="$(SolutionDir)$(ConfigurationName)64/Obj/$(ProjectName)"
+ ConfigurationType="2"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="1"
+ InlineFunctionExpansion="1"
+ EnableIntrinsicFunctions="true"
+ FavorSizeOrSpeed="2"
+ WholeProgramOptimization="true"
+ AdditionalIncludeDirectories="../../include;..\..\..\include"
+ PreprocessorDefinitions="NDEBUG;_USRDLL;TIPPER_EXPORTS"
+ StringPooling="true"
+ ExceptionHandling="0"
+ RuntimeLibrary="2"
+ BufferSecurityCheck="false"
+ EnableFunctionLevelLinking="true"
+ FloatingPointModel="2"
+ RuntimeTypeInfo="false"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="common.h"
+ WarningLevel="3"
+ DisableSpecificWarnings="4996"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ IgnoreImportLibrary="true"
+ AdditionalDependencies="comctl32.lib"
+ IgnoreDefaultLibraryNames=""
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ LinkTimeCodeGeneration="1"
+ RandomizedBaseAddress="1"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
+ <File
+ RelativePath=".\message_pump.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\options.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\popwin.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\str_utils.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\subst.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\tipper.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="1"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="1"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="1"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="1"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug Unicode|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="1"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug Unicode|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="1"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release Unicode|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="1"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release Unicode|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="1"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\translations.cpp"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+ >
+ <File
+ RelativePath=".\common.h"
+ >
+ </File>
+ <File
+ RelativePath=".\message_pump.h"
+ >
+ </File>
+ <File
+ RelativePath=".\options.h"
+ >
+ </File>
+ <File
+ RelativePath=".\popwin.h"
+ >
+ </File>
+ <File
+ RelativePath=".\resource.h"
+ >
+ </File>
+ <File
+ RelativePath=".\str_utils.h"
+ >
+ </File>
+ <File
+ RelativePath=".\tipper.h"
+ >
+ </File>
+ <File
+ RelativePath=".\translations.h"
+ >
+ </File>
+ <File
+ RelativePath=".\version.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+ >
+ <File
+ RelativePath=".\resource.rc"
+ >
+ </File>
+ <File
+ RelativePath=".\tipper.rc"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug Unicode|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug Unicode|x64"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release Unicode|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release Unicode|x64"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\version.rc"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug Unicode|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug Unicode|x64"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release Unicode|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release Unicode|x64"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ </FileConfiguration>
+ </File>
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/plugins/tipper/translations.cpp b/plugins/tipper/translations.cpp
new file mode 100644
index 0000000000..8fae442bac
--- /dev/null
+++ b/plugins/tipper/translations.cpp
@@ -0,0 +1,598 @@
+#include "common.h"
+#include "translations.h"
+#include "str_utils.h"
+
+int num_tfuncs = 0;
+DBVTranslation *translations = 0;
+
+DWORD next_func_id;
+
+HANDLE hServiceAdd;
+
+void AddTranslation(DBVTranslation *new_trans) {
+ num_tfuncs++;
+
+ translations = (DBVTranslation *)realloc(translations, sizeof(DBVTranslation) * num_tfuncs);
+ translations[num_tfuncs - 1] = *new_trans;
+
+ char setting[256];
+#ifdef _UNICODE
+ WideCharToMultiByte(code_page, 0, new_trans->name, -1, setting, 256, 0, 0);
+#else
+ strncpy(setting, new_trans->name, 256);
+#endif
+
+ if(_tcscmp(new_trans->name, _T("[No translation]")) == 0)
+ translations[num_tfuncs - 1].id = 0;
+ else {
+ DWORD id = DBGetContactSettingDword(0, MODULE, setting, 0);
+ if(id != 0) {
+ translations[num_tfuncs - 1].id = id;
+ if(next_func_id <= id) next_func_id = id + 1;
+ } else {
+ translations[num_tfuncs - 1].id = next_func_id++;
+ DBWriteContactSettingDword(0, MODULE, setting, translations[num_tfuncs - 1].id);
+ }
+
+ DBWriteContactSettingDword(0, MODULE, "NextFuncId", next_func_id);
+ }
+}
+
+TCHAR *null_translation(HANDLE hContact, const char *module_name, const char *setting_name, TCHAR *buff, int bufflen) {
+ DBVARIANT dbv;
+
+ buff[0] = 0;
+
+ if (DBGetContactSettingTString(hContact, module_name, setting_name, &dbv))
+ return 0;
+
+ _tcsncpy(buff, dbv.ptszVal, bufflen);
+ buff[bufflen - 1] = 0;
+
+ DBFreeVariant(&dbv);
+
+ return buff[0] ? buff : NULL;
+}
+
+TCHAR *timestamp_to_short_date(HANDLE hContact, const char *module_name, const char *setting_name, TCHAR *buff, int bufflen) {
+ DWORD ts = DBGetContactSettingDword(hContact, module_name, setting_name, 0);
+ if(ts == 0) return 0;
+
+ DBTIMETOSTRINGT dbt = {0};
+ dbt.cbDest = bufflen;
+ dbt.szDest = buff;
+ dbt.szFormat = _T("d");
+ CallService(MS_DB_TIME_TIMESTAMPTOSTRINGT, (WPARAM)ts, (LPARAM)&dbt);
+
+ return buff;
+}
+
+TCHAR *timestamp_to_long_date(HANDLE hContact, const char *module_name, const char *setting_name, TCHAR *buff, int bufflen) {
+ DWORD ts = DBGetContactSettingDword(hContact, module_name, setting_name, 0);
+ if(ts == 0) return 0;
+
+ DBTIMETOSTRINGT dbt = {0};
+ dbt.cbDest = bufflen;
+ dbt.szDest = buff;
+ dbt.szFormat = _T("D");
+ CallService(MS_DB_TIME_TIMESTAMPTOSTRINGT, (WPARAM)ts, (LPARAM)&dbt);
+
+ return buff;
+}
+
+TCHAR *timestamp_to_time(HANDLE hContact, const char *module_name, const char *setting_name, TCHAR *buff, int bufflen) {
+ DWORD ts = DBGetContactSettingDword(hContact, module_name, setting_name, 0);
+ if(ts == 0) return 0;
+
+ DBTIMETOSTRINGT dbt = {0};
+ dbt.cbDest = bufflen;
+ dbt.szDest = buff;
+ dbt.szFormat = _T("s");
+ CallService(MS_DB_TIME_TIMESTAMPTOSTRINGT, (WPARAM)ts, (LPARAM)&dbt);
+
+ return buff;
+}
+
+TCHAR *timestamp_to_time_no_secs(HANDLE hContact, const char *module_name, const char *setting_name, TCHAR *buff, int bufflen) {
+ DWORD ts = DBGetContactSettingDword(hContact, module_name, setting_name, 0);
+ if(ts == 0) return 0;
+
+ DBTIMETOSTRINGT dbt = {0};
+ dbt.cbDest = bufflen;
+ dbt.szDest = buff;
+ dbt.szFormat = _T("t");
+ CallService(MS_DB_TIME_TIMESTAMPTOSTRINGT, (WPARAM)ts, (LPARAM)&dbt);
+
+ return buff;
+}
+
+TCHAR *timestamp_to_time_difference(HANDLE hContact, const char *module_name, const char *setting_name, TCHAR *buff, int bufflen) {
+ DWORD ts = DBGetContactSettingDword(hContact, module_name, setting_name, 0);
+ DWORD t = (DWORD)time(0);
+ if(ts == 0) return 0;
+
+ DWORD diff = (t - ts);
+ int d = (diff / 60 / 60 / 24);
+ int h = (diff - d * 60 * 60 * 24) / 60 / 60;
+ int m = (diff - d * 60 * 60 * 24 - h * 60 * 60) / 60;
+ if(d > 0)
+ mir_sntprintf(buff, bufflen, TranslateT("%dd %dh %dm"), d, h, m);
+ else if(h > 0)
+ mir_sntprintf(buff, bufflen, TranslateT("%dh %dm"), h, m);
+ else
+ mir_sntprintf(buff, bufflen, TranslateT("%dm"), m);
+
+ return buff;
+}
+
+TCHAR *seconds_to_time_difference(HANDLE hContact, const char *module_name, const char *setting_name, TCHAR *buff, int bufflen) {
+
+ DWORD diff = DBGetContactSettingDword(hContact, module_name, setting_name, 0);
+ int d = (diff / 60 / 60 / 24);
+ int h = (diff - d * 60 * 60 * 24) / 60 / 60;
+ int m = (diff - d * 60 * 60 * 24 - h * 60 * 60) / 60;
+ if(d > 0)
+ mir_sntprintf(buff, bufflen, TranslateT("%dd %dh %dm"), d, h, m);
+ else if(h > 0)
+ mir_sntprintf(buff, bufflen, TranslateT("%dh %dm"), h, m);
+ else
+ mir_sntprintf(buff, bufflen, TranslateT("%dm"), m);
+
+ return buff;
+}
+
+TCHAR *word_to_status_desc(HANDLE hContact, const char *module_name, const char *setting_name, TCHAR *buff, int bufflen) {
+ int status = DBGetContactSettingWord(hContact, module_name, setting_name, ID_STATUS_OFFLINE);
+ char *strptr = (char *)CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, (WPARAM)status, (LPARAM)0);
+ a2t(strptr, buff, bufflen);
+ buff[bufflen - 1] = 0;
+ return buff;
+}
+
+TCHAR *byte_to_yesno(HANDLE hContact, const char *module_name, const char *setting_name, TCHAR *buff, int bufflen) {
+ DBVARIANT dbv;
+ if(!DBGetContactSetting(hContact, module_name, setting_name, &dbv)) {
+ if(dbv.type == DBVT_BYTE) {
+ if(dbv.bVal != 0)
+ _tcsncpy(buff, _T("Yes"), bufflen);
+ else
+ _tcsncpy(buff, _T("No"), bufflen);
+ buff[bufflen - 1] = 0;
+ DBFreeVariant(&dbv);
+ return buff;
+ }
+ DBFreeVariant(&dbv);
+ }
+ return 0;
+}
+
+TCHAR *byte_to_mf(HANDLE hContact, const char *module_name, const char *setting_name, TCHAR *buff, int bufflen) {
+ BYTE val = (BYTE)DBGetContactSettingByte(hContact, module_name, setting_name, 0);
+ if(val == 'F')
+ _tcsncpy(buff, TranslateT("Female"), bufflen);
+ else if(val == 'M')
+ _tcsncpy(buff, TranslateT("Male"), bufflen);
+ else
+ return 0;
+
+ buff[bufflen - 1] = 0;
+ return buff;
+}
+
+TCHAR *word_to_country(HANDLE hContact, const char *module_name, const char *setting_name, TCHAR *buff, int bufflen) {
+ char *cname = 0;
+ WORD cid = (WORD)DBGetContactSettingWord(hContact, module_name, setting_name, (WORD)-1);
+ if(cid != (WORD)-1 && ServiceExists(MS_UTILS_GETCOUNTRYBYNUMBER) && (cname = (char *)CallService(MS_UTILS_GETCOUNTRYBYNUMBER, cid, 0)) != 0) {
+ if(strcmp(cname, "Unknown") == 0)
+ return 0;
+ a2t(cname, buff, bufflen);
+ buff[bufflen - 1] = 0;
+ return buff;
+ }
+ return 0;
+}
+
+TCHAR *dword_to_ip(HANDLE hContact, const char *module_name, const char *setting_name, TCHAR *buff, int bufflen) {
+ DWORD ip = DBGetContactSettingDword(hContact, module_name, setting_name, 0);
+ if (ip) {
+ unsigned char *ipc = (unsigned char*)&ip;
+ mir_sntprintf(buff, bufflen, _T("%u.%u.%u.%u"), ipc[3], ipc[2], ipc[1], ipc[0]);
+ return buff;
+ }
+ return 0;
+}
+
+bool GetInt(const DBVARIANT &dbv, int *val) {
+ if(!val) return false;
+
+ switch(dbv.type) {
+ case DBVT_BYTE:
+ if(val) *val = (int)dbv.bVal;
+ return true;
+ case DBVT_WORD:
+ if(val) *val = (int)dbv.wVal;
+ return true;
+ case DBVT_DWORD:
+ if(val) *val = (int)dbv.dVal;
+ return true;
+ }
+ return false;
+}
+
+TCHAR *day_month_year_to_date(HANDLE hContact, const char *module_name, const char *prefix, TCHAR *buff, int bufflen) {
+ DBVARIANT dbv;
+ char setting_name[256];
+ mir_snprintf(setting_name, 256, "%sDay", prefix);
+ if(!DBGetContactSetting(hContact, module_name, setting_name, &dbv)) {
+ int day = 0;
+ if(GetInt(dbv, &day)) {
+ DBFreeVariant(&dbv);
+ mir_snprintf(setting_name, 256, "%sMonth", prefix);
+ int month = 0;
+ if(!DBGetContactSetting(hContact, module_name, setting_name, &dbv)) {
+ if(GetInt(dbv, &month)) {
+ DBFreeVariant(&dbv);
+ mir_snprintf(setting_name, 256, "%sYear", prefix);
+ int year = 0;
+ if(!DBGetContactSetting(hContact, module_name, setting_name, &dbv)) {
+ if(GetInt(dbv, &year)) {
+ DBFreeVariant(&dbv);
+
+ SYSTEMTIME st = {0};
+ st.wDay = day;
+ st.wMonth = month;
+ st.wYear = year;
+
+ GetDateFormat(LOCALE_USER_DEFAULT, 0, &st, 0, buff, bufflen);
+ return buff;
+ } else
+ DBFreeVariant(&dbv);
+ }
+ } else
+ DBFreeVariant(&dbv);
+ }
+ } else
+ DBFreeVariant(&dbv);
+ }
+ return 0;
+}
+
+TCHAR *day_month_year_to_age(HANDLE hContact, const char *module_name, const char *prefix, TCHAR *buff, int bufflen) {
+ DBVARIANT dbv;
+ char setting_name[256];
+ mir_snprintf(setting_name, 256, "%sDay", prefix);
+ if(!DBGetContactSetting(hContact, module_name, setting_name, &dbv)) {
+ int day = 0;
+ if(GetInt(dbv, &day)) {
+ DBFreeVariant(&dbv);
+ mir_snprintf(setting_name, 256, "%sMonth", prefix);
+ int month = 0;
+ if(!DBGetContactSetting(hContact, module_name, setting_name, &dbv)) {
+ if(GetInt(dbv, &month)) {
+ DBFreeVariant(&dbv);
+ mir_snprintf(setting_name, 256, "%sYear", prefix);
+ int year = 0;
+ if(!DBGetContactSetting(hContact, module_name, setting_name, &dbv)) {
+ if(GetInt(dbv, &year)) {
+ DBFreeVariant(&dbv);
+
+ SYSTEMTIME now;
+ GetLocalTime(&now);
+
+ int age = now.wYear - year;
+ if(now.wMonth < month || (now.wMonth == month && now.wDay < day))
+ age--;
+ mir_sntprintf(buff, bufflen, _T("%d"), age);
+ return buff;
+ } else
+ DBFreeVariant(&dbv);
+ }
+ } else
+ DBFreeVariant(&dbv);
+ }
+ } else
+ DBFreeVariant(&dbv);
+ }
+ return 0;
+}
+
+TCHAR *hours_minutes_seconds_to_time(HANDLE hContact, const char *module_name, const char *prefix, TCHAR *buff, int bufflen) {
+ DBVARIANT dbv;
+ char setting_name[256];
+ mir_snprintf(setting_name, 256, "%sHours", prefix);
+ if(!DBGetContactSetting(hContact, module_name, setting_name, &dbv)) {
+ int hours = 0;
+ if(GetInt(dbv, &hours)) {
+ DBFreeVariant(&dbv);
+ mir_snprintf(setting_name, 256, "%sMinutes", prefix);
+ int minutes = 0;
+ if(!DBGetContactSetting(hContact, module_name, setting_name, &dbv)) {
+ if(GetInt(dbv, &minutes)) {
+ DBFreeVariant(&dbv);
+ mir_snprintf(setting_name, 256, "%sSeconds", prefix);
+ int seconds = 0;
+ if(!DBGetContactSetting(hContact, module_name, setting_name, &dbv)) {
+ GetInt(dbv, &seconds);
+ DBFreeVariant(&dbv);
+ }
+
+ SYSTEMTIME st = {0};
+ st.wHour = hours;
+ st.wMinute = minutes;
+ st.wSecond = seconds;
+
+ GetTimeFormat(LOCALE_USER_DEFAULT, 0, &st, 0, buff, bufflen);
+ return buff;
+ } else
+ DBFreeVariant(&dbv);
+ }
+ } else
+ DBFreeVariant(&dbv);
+ }
+ return 0;
+}
+
+TCHAR *hours_minutes_to_time(HANDLE hContact, const char *module_name, const char *prefix, TCHAR *buff, int bufflen) {
+ DBVARIANT dbv;
+ char setting_name[256];
+ mir_snprintf(setting_name, 256, "%sHours", prefix);
+ if(!DBGetContactSetting(hContact, module_name, setting_name, &dbv)) {
+ int hours = 0;
+ if(GetInt(dbv, &hours)) {
+ DBFreeVariant(&dbv);
+ mir_snprintf(setting_name, 256, "%sMinutes", prefix);
+ int minutes = 0;
+ if(!DBGetContactSetting(hContact, module_name, setting_name, &dbv)) {
+ if(GetInt(dbv, &minutes)) {
+ DBFreeVariant(&dbv);
+
+ SYSTEMTIME st = {0};
+ st.wHour = hours;
+ st.wMinute = minutes;
+
+ GetTimeFormat(LOCALE_USER_DEFAULT, TIME_NOSECONDS, &st, 0, buff, bufflen);
+ return buff;
+ } else
+ DBFreeVariant(&dbv);
+ }
+ } else
+ DBFreeVariant(&dbv);
+ }
+ return 0;
+}
+
+TCHAR *day_month_year_hours_minutes_seconds_to_time_difference(HANDLE hContact, const char *module_name, const char *prefix, TCHAR *buff, int bufflen) {
+ DBVARIANT dbv;
+ char setting_name[256];
+ mir_snprintf(setting_name, 256, "%sDay", prefix);
+ if(!DBGetContactSetting(hContact, module_name, setting_name, &dbv)) {
+ int day = 0;
+ if(GetInt(dbv, &day)) {
+ DBFreeVariant(&dbv);
+ mir_snprintf(setting_name, 256, "%sMonth", prefix);
+ int month = 0;
+ if(!DBGetContactSetting(hContact, module_name, setting_name, &dbv)) {
+ if(GetInt(dbv, &month)) {
+ DBFreeVariant(&dbv);
+ mir_snprintf(setting_name, 256, "%sYear", prefix);
+ int year = 0;
+ if(!DBGetContactSetting(hContact, module_name, setting_name, &dbv)) {
+ if(GetInt(dbv, &year)) {
+ DBFreeVariant(&dbv);
+ mir_snprintf(setting_name, 256, "%sHours", prefix);
+ if(!DBGetContactSetting(hContact, module_name, setting_name, &dbv)) {
+ int hours = 0;
+ if(GetInt(dbv, &hours)) {
+ DBFreeVariant(&dbv);
+ mir_snprintf(setting_name, 256, "%sMinutes", prefix);
+ int minutes = 0;
+ if(!DBGetContactSetting(hContact, module_name, setting_name, &dbv)) {
+ if(GetInt(dbv, &minutes)) {
+ DBFreeVariant(&dbv);
+ mir_snprintf(setting_name, 256, "%sSeconds", prefix);
+ int seconds = 0;
+ if(!DBGetContactSetting(hContact, module_name, setting_name, &dbv)) {
+ GetInt(dbv, &seconds);
+ DBFreeVariant(&dbv);
+ }
+
+ SYSTEMTIME st = {0}, st_now;
+ st.wDay = day;
+ st.wMonth = month;
+ st.wYear = year;
+ st.wHour = hours;
+ st.wMinute = minutes;
+ st.wSecond = seconds;
+ GetLocalTime(&st_now);
+
+ FILETIME ft, ft_now;
+ SystemTimeToFileTime(&st, &ft);
+ SystemTimeToFileTime(&st_now, &ft_now);
+
+ LARGE_INTEGER li, li_now;
+ li.HighPart = ft.dwHighDateTime; li.LowPart = ft.dwLowDateTime;
+ li_now.HighPart = ft_now.dwHighDateTime; li_now.LowPart = ft_now.dwLowDateTime;
+
+ long diff = (long)((li_now.QuadPart - li.QuadPart) / (LONGLONG)10000000L);
+ int y = diff / 60 / 60 / 24 / 365;
+ int d = (diff - y * 60 * 60 * 24 * 365) / 60 / 60 / 24;
+ int h = (diff - y * 60 * 60 * 24 * 365 - d * 60 * 60 * 24) / 60 / 60;
+ int m = (diff - y * 60 * 60 * 24 * 365 - d * 60 * 60 * 24 - h * 60 * 60) / 60;
+ if(y != 0)
+ mir_sntprintf(buff, bufflen, TranslateT("%dy %dd %dh %dm"), y, d, h, m);
+ else if(d != 0)
+ mir_sntprintf(buff, bufflen, TranslateT("%dd %dh %dm"), d, h, m);
+ else if(h != 0)
+ mir_sntprintf(buff, bufflen, TranslateT("%dh %dm"), h, m);
+ else
+ mir_sntprintf(buff, bufflen, TranslateT("%dm"), m);
+
+ return buff;
+ } else
+ DBFreeVariant(&dbv);
+ }
+ } else
+ DBFreeVariant(&dbv);
+ }
+ } else
+ DBFreeVariant(&dbv);
+ }
+ } else
+ DBFreeVariant(&dbv);
+ }
+ } else
+ DBFreeVariant(&dbv);
+ }
+ return 0;
+}
+
+TCHAR *empty_xStatus_name_to_default_name(HANDLE hContact, const char *module_name, const char *setting_name, TCHAR *buff, int bufflen) {
+ TCHAR szDefaultName[1024];
+ ICQ_CUSTOM_STATUS xstatus={0};
+
+ if(null_translation(hContact, module_name, setting_name, buff, bufflen))
+ return buff;
+
+ int status = (int)DBGetContactSettingByte(hContact, module_name, "XStatusId", 0);
+ if(!status) return 0;
+
+ xstatus.cbSize = sizeof(ICQ_CUSTOM_STATUS);
+ xstatus.flags = CSSF_MASK_NAME|CSSF_DEFAULT_NAME|CSSF_TCHAR;
+ xstatus.ptszName = szDefaultName;
+ xstatus.wParam = (WPARAM *)&status;
+ if(CallProtoService(module_name, PS_ICQ_GETCUSTOMSTATUSEX, 0, (LPARAM)&xstatus))
+ return 0;
+
+ _tcsncpy(buff, TranslateTS(szDefaultName), bufflen);
+ buff[bufflen - 1] = 0;
+
+ return buff;
+}
+
+TCHAR *timezone_to_time(HANDLE hContact, const char *module_name, const char *setting_name, TCHAR *buff, int bufflen) {
+ int timezone = DBGetContactSettingByte(hContact,module_name,setting_name,256);
+ if(timezone==256 || (char)timezone==-100) {
+ return 0;
+ }
+
+ TIME_ZONE_INFORMATION tzi;
+ FILETIME ft;
+ LARGE_INTEGER lift;
+ SYSTEMTIME st;
+
+ timezone=(char)timezone;
+ GetSystemTimeAsFileTime(&ft);
+ if(GetTimeZoneInformation(&tzi) == TIME_ZONE_ID_DAYLIGHT)
+ timezone += tzi.DaylightBias / 30;
+
+ lift.QuadPart = *(__int64*)&ft;
+ lift.QuadPart -= (__int64)timezone * BIGI(30) * BIGI(60) * BIGI(10000000);
+ *(__int64*)&ft = lift.QuadPart;
+ FileTimeToSystemTime(&ft, &st);
+ GetTimeFormat(LOCALE_USER_DEFAULT, TIME_NOSECONDS, &st, NULL, buff, bufflen);
+
+ return buff;
+}
+
+INT_PTR ServiceAddTranslation(WPARAM wParam, LPARAM lParam) {
+ if(!lParam) return 1;
+
+ DBVTranslation *trans = (DBVTranslation *)lParam;
+ AddTranslation(trans);
+
+ return 0;
+}
+
+void InitTranslations() {
+ next_func_id = DBGetContactSettingDword(0, MODULE, "NextFuncId", 1);
+
+#define INT_TRANS_COUNT 19
+ DBVTranslation internal_translations[INT_TRANS_COUNT] = {
+ {
+ (TranslateFunc*)null_translation,
+ _T("[No translation]"),
+ },
+ {
+ (TranslateFunc*)word_to_status_desc,
+ _T("WORD to status description")
+ },
+ {
+ (TranslateFunc*)timestamp_to_time,
+ _T("DWORD timestamp to time")
+ },
+ {
+ (TranslateFunc*)timestamp_to_time_difference,
+ _T("DWORD timestamp to time difference")
+ },
+ {
+ (TranslateFunc*)byte_to_yesno,
+ _T("BYTE to Yes/No")
+ },
+ {
+ (TranslateFunc*)byte_to_mf,
+ _T("BYTE to Male/Female (ICQ)")
+ },
+ {
+ (TranslateFunc*)word_to_country,
+ _T("WORD to country name")
+ },
+ {
+ (TranslateFunc*)dword_to_ip,
+ _T("DWORD to ip address")
+ },
+ {
+ (TranslateFunc*)day_month_year_to_date,
+ _T("<prefix>Day|Month|Year to date")
+ },
+ {
+ (TranslateFunc*)day_month_year_to_age,
+ _T("<prefix>Day|Month|Year to age")
+ },
+ {
+ (TranslateFunc*)hours_minutes_seconds_to_time,
+ _T("<prefix>Hours|Minutes|Seconds to time")
+ },
+ {
+ (TranslateFunc*)day_month_year_hours_minutes_seconds_to_time_difference,
+ _T("<prefix>Day|Month|Year|Hours|Minutes|Seconds to time difference")
+ },
+ {
+ (TranslateFunc*)timestamp_to_time_no_secs,
+ _T("DWORD timestamp to time (no seconds)")
+ },
+ {
+ (TranslateFunc*)hours_minutes_to_time,
+ _T("<prefix>Hours|Minutes to time")
+ },
+ {
+ (TranslateFunc*)timestamp_to_short_date,
+ _T("DWORD timestamp to date (short)")
+ },
+ {
+ (TranslateFunc*)timestamp_to_long_date,
+ _T("DWORD timestamp to date (long)")
+ },
+ {
+ (TranslateFunc*)empty_xStatus_name_to_default_name,
+ _T("xStatus: empty xStatus name to default name")
+ },
+ {
+ (TranslateFunc*)seconds_to_time_difference,
+ _T("DWORD seconds to time difference")
+ },
+ {
+ (TranslateFunc*)timezone_to_time,
+ _T("BYTE timezone to time")
+ }
+ };
+
+ for(int i = 0; i < INT_TRANS_COUNT; i++) AddTranslation(&internal_translations[i]);
+
+ hServiceAdd = CreateServiceFunction(MS_TIPPER_ADDTRANSLATION, ServiceAddTranslation);
+}
+
+void DeinitTranslations() {
+ DestroyServiceFunction(hServiceAdd);
+ free(translations);
+}
+
diff --git a/plugins/tipper/translations.h b/plugins/tipper/translations.h
new file mode 100644
index 0000000000..2b3abb15e5
--- /dev/null
+++ b/plugins/tipper/translations.h
@@ -0,0 +1,12 @@
+#ifndef _TRANSLATIONS_INC
+#define _TRANSLATIONS_INC
+
+#include "m_tipper.h"
+
+extern int num_tfuncs;
+extern DBVTranslation *translations;
+
+void InitTranslations();
+void DeinitTranslations();
+
+#endif
diff --git a/plugins/tipper/version.h b/plugins/tipper/version.h
new file mode 100644
index 0000000000..ce7c948bea
--- /dev/null
+++ b/plugins/tipper/version.h
@@ -0,0 +1,29 @@
+#ifndef __VERSION_H_INCLUDED
+#define __VERSION_H_INCLUDED
+
+#define __MAJOR_VERSION 0
+#define __MINOR_VERSION 4
+#define __RELEASE_NUM 1
+#define __BUILD_NUM 9
+
+#define __FILEVERSION_STRING __MAJOR_VERSION,__MINOR_VERSION,__RELEASE_NUM,__BUILD_NUM
+#define __FILEVERSION_STRING_DOTS __MAJOR_VERSION.__MINOR_VERSION.__RELEASE_NUM.__BUILD_NUM
+#define __STRINGIFY(x) #x
+#define __VERSION_STRING "0.4.1.9"
+
+#define __DESC "Tool Tip notification windows"
+#define __AUTHOR "Scott Ellis"
+#define __AUTHOREMAIL "mail@scottellis.com.au"
+#define __COPYRIGHT "© 2005,2006 Scott Ellis"
+#define __AUTHORWEB "http://www.scottellis.com.au"
+
+#ifdef _WIN64
+#define __PLUGIN_NAME "Tipper (x64)"
+#elif defined _UNICODE
+#define __PLUGIN_NAME "Tipper (Unicode)"
+#else
+#define __PLUGIN_NAME "Tipper (ANSI)"
+#endif
+#define __FILENAME "tipper.dll"
+
+#endif //__VERSION_H_INCLUDED
diff --git a/plugins/tipper/version.rc b/plugins/tipper/version.rc
new file mode 100644
index 0000000000..b6133928ab
--- /dev/null
+++ b/plugins/tipper/version.rc
@@ -0,0 +1,34 @@
+
+#include <windows.h>
+#include "version.h"
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION __FILEVERSION_STRING
+ PRODUCTVERSION __FILEVERSION_STRING
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x40004L
+ FILETYPE 0x1L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "000004b0"
+ BEGIN
+ VALUE "Author", __AUTHOR
+ VALUE "FileDescription", __DESC
+ VALUE "InternalName", __PLUGIN_NAME
+ VALUE "LegalCopyright", __COPYRIGHT
+ VALUE "OriginalFilename", __FILENAME
+ VALUE "FileVersion", __VERSION_STRING
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x0, 1200
+ END
+END