summaryrefslogtreecommitdiff
path: root/plugins/FloatingContacts
diff options
context:
space:
mode:
authorKirill Volinsky <mataes2007@gmail.com>2012-05-17 17:37:22 +0000
committerKirill Volinsky <mataes2007@gmail.com>2012-05-17 17:37:22 +0000
commit78d71d2cad6f243c6ff31d41380b8c5b58407de5 (patch)
treed0c05983b315352c5e66d23420da4b8fd8b5aff4 /plugins/FloatingContacts
parenta9e8daee448c229aa3f8ded0c5f5c0fe7aa42529 (diff)
added some plugins
git-svn-id: http://svn.miranda-ng.org/main/trunk@20 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c
Diffstat (limited to 'plugins/FloatingContacts')
-rw-r--r--plugins/FloatingContacts/FltCont_10.sln26
-rw-r--r--plugins/FloatingContacts/FltCont_10.vcxproj254
-rw-r--r--plugins/FloatingContacts/FltCont_10.vcxproj.filters76
-rw-r--r--plugins/FloatingContacts/Script.rc2
-rw-r--r--plugins/FloatingContacts/bitmap_funcs.cpp1239
-rw-r--r--plugins/FloatingContacts/bitmap_funcs.h127
-rw-r--r--plugins/FloatingContacts/docs/fltcontacts_langpack.txt68
-rw-r--r--plugins/FloatingContacts/docs/fltcontacts_readme.txt91
-rw-r--r--plugins/FloatingContacts/docs/fltcontacts_russian_langpack.txt70
-rw-r--r--plugins/FloatingContacts/filedrop.cpp368
-rw-r--r--plugins/FloatingContacts/filedrop.h26
-rw-r--r--plugins/FloatingContacts/fltcnt.rc232
-rw-r--r--plugins/FloatingContacts/fltcont.h191
-rw-r--r--plugins/FloatingContacts/hide.icobin0 -> 2550 bytes
-rw-r--r--plugins/FloatingContacts/main.cpp1331
-rw-r--r--plugins/FloatingContacts/options.cpp1179
-rw-r--r--plugins/FloatingContacts/resource.h75
-rw-r--r--plugins/FloatingContacts/show.icobin0 -> 2550 bytes
-rw-r--r--plugins/FloatingContacts/stdhdr.h64
-rw-r--r--plugins/FloatingContacts/thumbs.cpp1013
-rw-r--r--plugins/FloatingContacts/thumbs.h74
-rw-r--r--plugins/FloatingContacts/version.h29
-rw-r--r--plugins/FloatingContacts/version.rc36
23 files changed, 6571 insertions, 0 deletions
diff --git a/plugins/FloatingContacts/FltCont_10.sln b/plugins/FloatingContacts/FltCont_10.sln
new file mode 100644
index 0000000000..823e987bbd
--- /dev/null
+++ b/plugins/FloatingContacts/FltCont_10.sln
@@ -0,0 +1,26 @@
+
+Microsoft Visual Studio Solution File, Format Version 11.00
+# Visual Studio 2010
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FltCont", "FltCont_10.vcxproj", "{9290A9CC-3FDA-4FD6-A8A2-04AD4BA1C856}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug Unicode|Win32 = Debug Unicode|Win32
+ Debug|Win32 = Debug|Win32
+ Release Unicode|Win32 = Release Unicode|Win32
+ Release|Win32 = Release|Win32
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {9290A9CC-3FDA-4FD6-A8A2-04AD4BA1C856}.Debug Unicode|Win32.ActiveCfg = Debug Unicode|Win32
+ {9290A9CC-3FDA-4FD6-A8A2-04AD4BA1C856}.Debug Unicode|Win32.Build.0 = Debug Unicode|Win32
+ {9290A9CC-3FDA-4FD6-A8A2-04AD4BA1C856}.Debug|Win32.ActiveCfg = Debug|Win32
+ {9290A9CC-3FDA-4FD6-A8A2-04AD4BA1C856}.Debug|Win32.Build.0 = Debug|Win32
+ {9290A9CC-3FDA-4FD6-A8A2-04AD4BA1C856}.Release Unicode|Win32.ActiveCfg = Release Unicode|Win32
+ {9290A9CC-3FDA-4FD6-A8A2-04AD4BA1C856}.Release Unicode|Win32.Build.0 = Release Unicode|Win32
+ {9290A9CC-3FDA-4FD6-A8A2-04AD4BA1C856}.Release|Win32.ActiveCfg = Release|Win32
+ {9290A9CC-3FDA-4FD6-A8A2-04AD4BA1C856}.Release|Win32.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/plugins/FloatingContacts/FltCont_10.vcxproj b/plugins/FloatingContacts/FltCont_10.vcxproj
new file mode 100644
index 0000000000..a76fd934d2
--- /dev/null
+++ b/plugins/FloatingContacts/FltCont_10.vcxproj
@@ -0,0 +1,254 @@
+<?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|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release Unicode|Win32">
+ <Configuration>Release Unicode</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectName>FltCont</ProjectName>
+ <ProjectGuid>{9290A9CC-3FDA-4FD6-A8A2-04AD4BA1C856}</ProjectGuid>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ <CharacterSet>MultiByte</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" />
+ <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
+ </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" />
+ <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
+ </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" />
+ <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
+ </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" />
+ <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup>
+ <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)$(Configuration)/Plugins\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)$(Configuration)/Obj/$(ProjectName)\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)$(Configuration)/Plugins\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)$(Configuration)/Obj/$(ProjectName)\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">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>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'">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>
+ <TargetName Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'">fltcontacts</TargetName>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>../../include;../ExternalAPI;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>true</MinimalRebuild>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+ <PrecompiledHeader>Use</PrecompiledHeader>
+ <PrecompiledHeaderFile>stdhdr.h</PrecompiledHeaderFile>
+ <WarningLevel>Level4</WarningLevel>
+ <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
+ </ClCompile>
+ <ResourceCompile>
+ <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ResourceCompile>
+ <Link>
+ <AdditionalDependencies>Msimg32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <TargetMachine>MachineX86</TargetMachine>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <Optimization>Full</Optimization>
+ <FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
+ <AdditionalIncludeDirectories>../../include;../ExternalAPI;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>true</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeader>Use</PrecompiledHeader>
+ <PrecompiledHeaderFile>stdhdr.h</PrecompiledHeaderFile>
+ <WarningLevel>Level4</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ </ClCompile>
+ <ResourceCompile>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ResourceCompile>
+ <Link>
+ <AdditionalDependencies>Msimg32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <TargetMachine>MachineX86</TargetMachine>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ <LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'">
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>../../include;../ExternalAPI;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>true</MinimalRebuild>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+ <PrecompiledHeader>Use</PrecompiledHeader>
+ <PrecompiledHeaderFile>stdhdr.h</PrecompiledHeaderFile>
+ <WarningLevel>Level4</WarningLevel>
+ <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
+ </ClCompile>
+ <ResourceCompile>
+ <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ResourceCompile>
+ <Link>
+ <AdditionalDependencies>Msimg32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <TargetMachine>MachineX86</TargetMachine>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'">
+ <ClCompile>
+ <Optimization>Full</Optimization>
+ <FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
+ <AdditionalIncludeDirectories>../../include;../ExternalAPI;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>true</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeader>Use</PrecompiledHeader>
+ <PrecompiledHeaderFile>stdhdr.h</PrecompiledHeaderFile>
+ <WarningLevel>Level4</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ </ClCompile>
+ <ResourceCompile>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ResourceCompile>
+ <Link>
+ <AdditionalDependencies>Msimg32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <TargetMachine>MachineX86</TargetMachine>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ <LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="bitmap_funcs.cpp" />
+ <ClCompile Include="filedrop.cpp" />
+ <ClCompile Include="main.cpp">
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'">Create</PrecompiledHeader>
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'">Create</PrecompiledHeader>
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="options.cpp" />
+ <ClCompile Include="thumbs.cpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="bitmap_funcs.h" />
+ <ClInclude Include="filedrop.h" />
+ <ClInclude Include="fltcont.h" />
+ <ClInclude Include="resource.h" />
+ <ClInclude Include="stdhdr.h" />
+ <ClInclude Include="thumbs.h" />
+ <ClInclude Include="version.h" />
+ </ItemGroup>
+ <ItemGroup>
+ <ResourceCompile Include="fltcnt.rc">
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
+ </ResourceCompile>
+ <ResourceCompile Include="Script.rc" />
+ <ResourceCompile Include="version.rc">
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
+ </ResourceCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="hide.ico" />
+ <None Include="show.ico" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/plugins/FloatingContacts/FltCont_10.vcxproj.filters b/plugins/FloatingContacts/FltCont_10.vcxproj.filters
new file mode 100644
index 0000000000..4b33b8e646
--- /dev/null
+++ b/plugins/FloatingContacts/FltCont_10.vcxproj.filters
@@ -0,0 +1,76 @@
+<?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>{84999e29-bc79-471f-9875-ab09dde3a08a}</UniqueIdentifier>
+ <Extensions>cpp;c;cxx;rc;def;r;odl;idl;hpj;bat</Extensions>
+ </Filter>
+ <Filter Include="Header Files">
+ <UniqueIdentifier>{715cbea0-9043-4420-8266-8083bb9d03e1}</UniqueIdentifier>
+ <Extensions>h;hpp;hxx;hm;inl</Extensions>
+ </Filter>
+ <Filter Include="Resource Files">
+ <UniqueIdentifier>{fd5f5482-d8cc-42d5-b4e9-5055d6618caa}</UniqueIdentifier>
+ <Extensions>ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe</Extensions>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="bitmap_funcs.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="filedrop.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="main.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="options.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="thumbs.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="bitmap_funcs.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="filedrop.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="fltcont.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="resource.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="stdhdr.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="thumbs.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="version.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ </ItemGroup>
+ <ItemGroup>
+ <ResourceCompile Include="fltcnt.rc">
+ <Filter>Resource Files</Filter>
+ </ResourceCompile>
+ <ResourceCompile Include="Script.rc">
+ <Filter>Resource Files</Filter>
+ </ResourceCompile>
+ <ResourceCompile Include="version.rc">
+ <Filter>Resource Files</Filter>
+ </ResourceCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="hide.ico">
+ <Filter>Resource Files</Filter>
+ </None>
+ <None Include="show.ico">
+ <Filter>Resource Files</Filter>
+ </None>
+ </ItemGroup>
+</Project> \ No newline at end of file
diff --git a/plugins/FloatingContacts/Script.rc b/plugins/FloatingContacts/Script.rc
new file mode 100644
index 0000000000..b1bbc9db7b
--- /dev/null
+++ b/plugins/FloatingContacts/Script.rc
@@ -0,0 +1,2 @@
+#include "version.rc"
+#include "fltcnt.rc"
diff --git a/plugins/FloatingContacts/bitmap_funcs.cpp b/plugins/FloatingContacts/bitmap_funcs.cpp
new file mode 100644
index 0000000000..3d92e7a9d8
--- /dev/null
+++ b/plugins/FloatingContacts/bitmap_funcs.cpp
@@ -0,0 +1,1239 @@
+/*
+Popup Plus plugin for Miranda IM
+
+Copyright © 2002 Luca Santarelli,
+ © 2004-2007 Victor Pavlychko
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include "stdhdr.h"
+#include "bitmap_funcs.h"
+
+#include <m_png.h>
+#include <math.h>
+
+#define PU_FONT_THRESHOLD 96
+#define PU_BMP_ACCURATE_ARITHMETICS
+
+#ifdef PU_BMP_ACCURATE_ARITHMETICS
+ #define PU_DIV255(x) ((x)/255)
+ #define PU_DIV128(x) ((x)/128)
+ typedef float pu_koef;
+#else
+ #define PU_DIV255(x) ((x)>>8)
+ #define PU_DIV128(x) ((x)>>7)
+ typedef long pu_koef;
+#endif
+
+MyBitmap::MyBitmap()
+{
+ dcBmp = 0;
+ hBmp = 0;
+ bits = 0;
+ width = height = 0;
+ bitsSave = 0;
+}
+
+MyBitmap::MyBitmap(int w, int h)
+{
+ dcBmp = 0;
+ hBmp = 0;
+ bits = 0;
+ width = height = 0;
+ bitsSave = 0;
+ allocate(w,h);
+}
+
+MyBitmap::MyBitmap(const char *fn, const char *fnAlpha)
+{
+ dcBmp = 0;
+ hBmp = 0;
+ bits = 0;
+ width = height = 0;
+ bitsSave = 0;
+ loadFromFile(fn, fnAlpha);
+}
+
+MyBitmap::~MyBitmap()
+{
+ if (bitsSave)
+ delete [] bitsSave;
+ free();
+}
+
+void MyBitmap::setAlpha(BYTE level)
+{
+ if (!bits) return;
+
+ GdiFlush();
+ for (int i = 0; i < width*height; i++)
+ {
+ if (bits[i] & 0xff000000)
+ {
+ bits[i] = rgba(getr(bits[i])*level/255, getg(bits[i])*level/255, getb(bits[i])*level/255, geta(bits[i])*level/255);
+ } else
+ {
+ bits[i] = rgba(getr(bits[i])*level/255, getg(bits[i])*level/255, getb(bits[i])*level/255, level);
+ }
+ }
+}
+
+void MyBitmap::setAlphaRect(int x1, int y1, int x2, int y2, BYTE level)
+{
+ if (!bits) return;
+
+ GdiFlush();
+ for (int i = y1; i < y2; i++)
+ for (int j = x1; j < x2; j++)
+ {
+ int idx = i * width + j;
+ if (bits[idx] & 0xff000000)
+ {
+ bits[idx] = rgba(getr(bits[idx])*level/255, getg(bits[idx])*level/255, getb(bits[idx])*level/255, geta(bits[idx])*level/255);
+ } else
+ {
+ bits[idx] = rgba(getr(bits[idx])*level/255, getg(bits[idx])*level/255, getb(bits[idx])*level/255, level);
+ }
+ }
+}
+
+void MyBitmap::makeOpaque()
+{
+ if (!bits) return;
+
+ GdiFlush();
+ for (int i = 0; i < width*height; i++)
+ bits[i] |= 0xff000000;
+}
+
+void MyBitmap::makeOpaqueRect(int x1, int y1, int x2, int y2)
+{
+ if (!bits) return;
+
+ GdiFlush();
+ for (int i = y1; i < y2; i++)
+ for (int j = x1; j < x2; j++)
+ {
+ int idx = i * width + j;
+ bits[idx] |= 0xff000000;
+ }
+}
+
+void MyBitmap::saveAlpha(int x, int y, int w, int h)
+{
+ if (bitsSave)
+ delete [] bitsSave;
+
+ GdiFlush();
+
+ if (!w) w = width;
+ if (!h) h = height;
+
+ bitsSave = new COLOR32[w*h];
+ COLOR32 *p1 = bitsSave;
+
+ for (int i = 0; i < h; i++)
+ {
+ if (i+y < 0) continue;
+ if (i+y >= height) break;
+ COLOR32 *p2 = bits + (y+i)*width + x;
+ p1 = bitsSave + i*w;
+ for (int j = 0; j < w; j++)
+ {
+ if (j+x < 0) continue;
+ if (j+x >= width) break;
+ *p1++ = *p2++;
+ }
+ }
+}
+
+void MyBitmap::restoreAlpha(int x, int y, int w, int h)
+{
+ if (!bitsSave)
+ return;
+
+ GdiFlush();
+
+ if (!w) w = width;
+ if (!h) h = height;
+
+ COLOR32 *p1 = bitsSave;
+
+ for (int i = 0; i < h; i++)
+ {
+ if (i+y < 0) continue;
+ if (i+y >= height) break;
+ COLOR32 *p2 = bits + (y+i)*width + x;
+ p1 = bitsSave + i*w;
+ for (int j = 0; j < w; j++)
+ {
+ if (j+x < 0) continue;
+ if (j+x >= width) break;
+ if ((*p1&0x00ffffff) != (*p2&0x00ffffff))
+ {
+ *p2 |= 0xff000000;
+ } else
+ {
+ *p2 = (*p2&0x00ffffff) | (*p1&0xff000000);
+ }
+ ++p1;
+ ++p2;
+ }
+ }
+
+ delete [] bitsSave;
+ bitsSave = 0;
+}
+
+void MyBitmap::DrawBits(COLOR32 *inbits, int inw, int inh, int x, int y, int w, int h)
+{
+ if (!(bits && inbits)) return;
+
+ GdiFlush();
+
+ float kx = (float)inw / w;
+ float ky = (float)inh / h;
+
+ if (x+w >= this->getWidth())
+ w = this->getWidth() - x;
+ if (y+h >= this->getHeight())
+ h = this->getHeight() - y;
+
+ for (int i = 0; i < h; i++)
+ {
+ if (i+y < 0) continue;
+ if (i+y >= height) break;
+ for (int j = 0; j < w; j++)
+ {
+ if (j+x < 0) continue;
+ if (j+x >= width) break;
+ bits[(i+y)*width + (j+x)] = inbits[int(i*ky)*inw + int(j*kx)];
+ }
+ }
+}
+
+void MyBitmap::BlendBits(COLOR32 *inbits, int inw, int inh, int x, int y, int w, int h)
+{
+ if (!(bits && inbits)) return;
+
+ GdiFlush();
+
+ float kx = (float)inw / w;
+ float ky = (float)inh / h;
+
+ if (x+w >= this->getWidth())
+ w = this->getWidth() - x;
+ if (y+h >= this->getHeight())
+ h = this->getHeight() - y;
+
+ for (int i = 0; i < h; i++)
+ {
+ if (i+y < 0) continue;
+ if (i+y >= height) break;
+ for (int j = 0; j < w; j++)
+ {
+ if (j+x < 0) continue;
+ if (j+x >= width) break;
+ COLOR32 src = inbits[int(i*ky)*inw + int(j*kx)];
+ COLOR32 dst = bits[(i+y)*width + (j+x)];
+ long alpha = geta(src);
+ bits[(i+y)*width + (j+x)] = rgba(
+ getr(src)+PU_DIV255((255-alpha)*getr(dst)),
+ getg(src)+PU_DIV255((255-alpha)*getg(dst)),
+ getb(src)+PU_DIV255((255-alpha)*getb(dst)),
+ geta(src)+PU_DIV255((255-alpha)*geta(dst))
+ );
+ }
+ }
+}
+
+void MyBitmap::Blend(MyBitmap *bmp, int x, int y, int w, int h)
+{
+ if (!(bits && bmp && bmp->bits)) return;
+
+ GdiFlush();
+
+ if (!w) w = bmp->width;
+ if (!h) h = bmp->height;
+ float kx = (float)bmp->width / w;
+ float ky = (float)bmp->height / h;
+
+ if (x+w >= this->getWidth())
+ w = this->getWidth() - x;
+ if (y+h >= this->getHeight())
+ h = this->getHeight() - y;
+
+ for (int i = 0; i < h; i++)
+ {
+ if (i+y < 0) continue;
+ if (i+y >= height) break;
+ for (int j = 0; j < w; j++)
+ {
+ if (j+x < 0) continue;
+ if (j+x >= width) break;
+ COLOR32 src = bmp->bits[int(i*ky)*bmp->width + int(j*kx)];
+ COLOR32 dst = bits[(i+y)*width + (j+x)];
+ long alpha = geta(src);
+ bits[(i+y)*width + (j+x)] = rgba(
+ getr(src)+PU_DIV255((255-alpha)*getr(dst)),
+ getg(src)+PU_DIV255((255-alpha)*getg(dst)),
+ getb(src)+PU_DIV255((255-alpha)*getb(dst)),
+ geta(src)+PU_DIV255((255-alpha)*geta(dst))
+ );
+ }
+ }
+}
+
+void MyBitmap::Draw(MyBitmap *bmp, int x, int y, int w, int h)
+{
+ if (!(bits && bmp && bmp->bits)) return;
+
+ GdiFlush();
+
+ if (!w) w = bmp->width;
+ if (!h) h = bmp->height;
+
+ if (!x && !y && (w == width) && (h == height) && (w == bmp->width) && (h == bmp->height))
+ {
+ // fast bitmap copy is possible good for animated avatars
+ CopyMemory(bits, bmp->bits, width*height*sizeof(COLOR32));
+ return;
+ }
+
+ float kx = (float)bmp->width / w;
+ float ky = (float)bmp->height / h;
+
+ if (x+w >= this->getWidth())
+ w = this->getWidth() - x;
+ if (y+h >= this->getHeight())
+ h = this->getHeight() - y;
+
+ for (int i = 0; i < h; i++)
+ {
+ if (i+y < 0) continue;
+ if (i+y >= height) break;
+ for (int j = 0; j < w; j++)
+ {
+ if (j+x < 0) continue;
+ if (j+x >= width) break;
+ bits[(i+y)*width + (j+x)] = bmp->bits[int(i*ky)*bmp->width + int(j*kx)];
+ }
+ }
+}
+
+void MyBitmap::BlendColorized(MyBitmap *bmp, int x, int y, int w, int h, COLOR32 color)
+{
+ if (!(bits && bmp && bmp->bits)) return;
+
+ GdiFlush();
+
+ if (!w) w = bmp->width;
+ if (!h) h = bmp->height;
+ float kx = (float)bmp->width / w;
+ float ky = (float)bmp->height / h;
+
+ // we should swap B and R channels when working with win32 COLORREF
+ float koef1r = (255 - getb(color)) / 128.0f;
+ float koef1g = (255 - getg(color)) / 128.0f;
+ float koef1b = (255 - getr(color)) / 128.0f;
+
+ int br = - 255 + 2 * getb(color);
+ int bg = - 255 + 2 * getg(color);
+ int bb = - 255 + 2 * getr(color);
+
+ float koef2r = (getb(color)) / 128.0f;
+ float koef2g = (getg(color)) / 128.0f;
+ float koef2b = (getr(color)) / 128.0f;
+
+ for (int i = 0; i < h; i++)
+ {
+ if (i+y < 0) continue;
+ if (i+y >= height) break;
+ for (int j = 0; j < w; j++)
+ {
+ if (j+x < 0) continue;
+ if (j+x >= width) break;
+
+// COLOR32 cl = getr(bmp->bits[int(i*ky)*bmp->width + int(j*kx)]);
+// bits[(i+y)*width + (j+x)] = (cl > 128) ?
+// rgba(koef1r * cl + br, koef1g * cl + bg, koef1b * cl + bb, geta(bmp->bits[int(i*ky)*bmp->width + int(j*kx)])):
+// rgba(koef2r * cl, koef2g * cl, koef2b * cl, geta(bmp->bits[int(i*ky)*bmp->width + int(j*kx)]));
+
+ long alpha = geta(bmp->bits[int(i*ky)*bmp->width + int(j*kx)]);
+// COLOR32 cl = getr(bmp->bits[int(i*ky)*bmp->width + int(j*kx)]);
+ COLOR32 cl = alpha ? getr(bmp->bits[int(i*ky)*bmp->width + int(j*kx)])*255/alpha : 0;
+#pragma warning(push)
+#pragma warning(disable: 4244)
+ COLOR32 src = (cl > 128) ?
+ rgba(
+ PU_DIV255((koef1r * cl + br)*alpha),
+ PU_DIV255((koef1g * cl + bg)*alpha),
+ PU_DIV255((koef1b * cl + bb)*alpha),
+ alpha):
+ rgba(
+ PU_DIV255(koef2r * cl * alpha),
+ PU_DIV255(koef2g * cl * alpha),
+ PU_DIV255(koef2b * cl * alpha),
+ alpha);
+#pragma warning(pop)
+// COLOR32 cl = getr(bmp->bits[int(i*ky)*bmp->width + int(j*kx)]);
+// COLOR32 src = (cl > 128) ?
+// rgba(koef1r * cl + br, koef1g * cl + bg, koef1b * cl + bb, alpha):
+// rgba(koef2r * cl, koef2g * cl, koef2b * cl, alpha);
+ COLOR32 dst = bits[(i+y)*width + (j+x)];
+// long alpha = geta(src);
+ bits[(i+y)*width + (j+x)] = rgba(
+ getr(src)+PU_DIV255((255-alpha)*getr(dst)),
+ getg(src)+PU_DIV255((255-alpha)*getg(dst)),
+ getb(src)+PU_DIV255((255-alpha)*getb(dst)),
+ geta(src)+PU_DIV255((255-alpha)*geta(dst))
+ );
+
+ }
+ }
+}
+
+void MyBitmap::DrawColorized(MyBitmap *bmp, int x, int y, int w, int h, COLOR32 color)
+{
+ if (!(bits && bmp && bmp->bits)) return;
+
+ GdiFlush();
+
+ if (!w) w = bmp->width;
+ if (!h) h = bmp->height;
+ float kx = (float)bmp->width / w;
+ float ky = (float)bmp->height / h;
+
+ // we should swap B and R channels when working with win32 COLORREF
+ float koef1r = (255 - getb(color)) / 128.0f;
+ float koef1g = (255 - getg(color)) / 128.0f;
+ float koef1b = (255 - getr(color)) / 128.0f;
+
+ int br = - 255 + 2 * getb(color);
+ int bg = - 255 + 2 * getg(color);
+ int bb = - 255 + 2 * getr(color);
+
+ float koef2r = (getb(color)) / 128.0f;
+ float koef2g = (getg(color)) / 128.0f;
+ float koef2b = (getr(color)) / 128.0f;
+
+ for (int i = 0; i < h; i++)
+ {
+ if (i+y < 0) continue;
+ if (i+y >= height) break;
+ for (int j = 0; j < w; j++)
+ {
+ if (j+x < 0) continue;
+ if (j+x >= width) break;
+
+ long alpha = geta(bmp->bits[int(i*ky)*bmp->width + int(j*kx)]);
+// COLOR32 cl = getr(bmp->bits[int(i*ky)*bmp->width + int(j*kx)]);
+ COLOR32 cl = alpha ? getr(bmp->bits[int(i*ky)*bmp->width + int(j*kx)])*255/alpha : 0;
+#pragma warning(push)
+#pragma warning(disable: 4244)
+ bits[(i+y)*width + (j+x)] = (cl > 128) ?
+ rgba(
+ PU_DIV255((koef1r * cl + br)*alpha),
+ PU_DIV255((koef1g * cl + bg)*alpha),
+ PU_DIV255((koef1b * cl + bb)*alpha),
+ alpha):
+ rgba(
+ PU_DIV255(koef2r * cl * alpha),
+ PU_DIV255(koef2g * cl * alpha),
+ PU_DIV255(koef2b * cl * alpha),
+ alpha);
+#pragma warning(pop)
+// bits[(i+y)*width + (j+x)] = (cl > 128) ?
+// rgba(koef1r * cl + br, koef1g * cl + bg, koef1b * cl + bb, geta(bmp->bits[int(i*ky)*bmp->width + int(j*kx)])):
+// rgba(koef2r * cl, koef2g * cl, koef2b * cl, geta(bmp->bits[int(i*ky)*bmp->width + int(j*kx)]));
+ }
+ }
+}
+
+void MyBitmap::BlendPart(MyBitmap *bmp, int xin, int yin, int win, int hin, int x, int y, int w, int h)
+{
+ if (!(bits && bmp && bmp->bits)) return;
+ if (!win || !hin) return;
+
+ GdiFlush();
+
+ if (!w) w = win;
+ if (!h) h = hin;
+ float kx = (float)win / w;
+ float ky = (float)hin / h;
+
+ if (x+w >= this->getWidth())
+ w = this->getWidth() - x;
+ if (y+h >= this->getHeight())
+ h = this->getHeight() - y;
+
+ for (int i = 0; i < h; i++)
+ {
+ if (i+y < 0) continue;
+ if (i+y >= height) break;
+ for (int j = 0; j < w; j++)
+ {
+ if (j+x < 0) continue;
+ if (j+x >= width) break;
+ COLOR32 src = bmp->bits[int(yin+i*ky)*bmp->width + int(xin+j*kx)];
+ COLOR32 dst = bits[(i+y)*width + (j+x)];
+ long alpha = geta(src);
+ bits[(i+y)*width + (j+x)] = rgba(
+ getr(src)+PU_DIV255((255-alpha)*getr(dst)),
+ getg(src)+PU_DIV255((255-alpha)*getg(dst)),
+ getb(src)+PU_DIV255((255-alpha)*getb(dst)),
+ geta(src)+PU_DIV255((255-alpha)*geta(dst))
+ );
+// bits[(i+y)*width + (j+x)] = bmp->bits[int(yin+i*ky)*bmp->width + int(xin+j*kx)];
+ }
+ }
+}
+
+void MyBitmap::BlendPartColorized(MyBitmap *bmp, int xin, int yin, int win, int hin, int x, int y, int w, int h, COLOR32 color)
+{
+ if (!(bits && bmp && bmp->bits)) return;
+ if (!win || !hin) return;
+
+ GdiFlush();
+
+ if (!w) w = win;
+ if (!h) h = hin;
+ float kx = (float)win / w;
+ float ky = (float)hin / h;
+
+ if (x+w >= this->getWidth())
+ w = this->getWidth() - x;
+ if (y+h >= this->getHeight())
+ h = this->getHeight() - y;
+
+ // we should swap B and R channels when working with win32 COLORREF
+ float koef1r = (255 - getb(color)) / 128.0f;
+ float koef1g = (255 - getg(color)) / 128.0f;
+ float koef1b = (255 - getr(color)) / 128.0f;
+
+ int br = - 255 + 2 * getb(color);
+ int bg = - 255 + 2 * getg(color);
+ int bb = - 255 + 2 * getr(color);
+
+ float koef2r = (getb(color)) / 128.0f;
+ float koef2g = (getg(color)) / 128.0f;
+ float koef2b = (getr(color)) / 128.0f;
+
+ for (int i = 0; i < h; i++)
+ {
+ if (i+y < 0) continue;
+ if (i+y >= height) break;
+ for (int j = 0; j < w; j++)
+ {
+ if (j+x < 0) continue;
+ if (j+x >= width) break;
+
+ long alpha = geta(bmp->bits[int(yin+i*ky)*bmp->width + int(xin+j*kx)]);
+// COLOR32 cl = getr(bmp->bits[int(i*ky)*bmp->width + int(j*kx)]);
+ COLOR32 cl = alpha ? getr(bmp->bits[int(yin+i*ky)*bmp->width + int(xin+j*kx)])*255/alpha : 0;
+#pragma warning(push)
+#pragma warning(disable: 4244)
+ COLOR32 src = (cl > 128) ?
+ rgba(
+ PU_DIV255((koef1r * cl + br)*alpha),
+ PU_DIV255((koef1g * cl + bg)*alpha),
+ PU_DIV255((koef1b * cl + bb)*alpha),
+ alpha):
+ rgba(
+ PU_DIV255(koef2r * cl * alpha),
+ PU_DIV255(koef2g * cl * alpha),
+ PU_DIV255(koef2b * cl * alpha),
+ alpha);
+#pragma warning(pop)
+// COLOR32 cl = getr(bmp->bits[int(i*ky)*bmp->width + int(j*kx)]);
+// COLOR32 src = (cl > 128) ?
+// rgba(koef1r * cl + br, koef1g * cl + bg, koef1b * cl + bb, alpha):
+// rgba(koef2r * cl, koef2g * cl, koef2b * cl, alpha);
+ COLOR32 dst = bits[(i+y)*width + (j+x)];
+// long alpha = geta(src);
+ bits[(i+y)*width + (j+x)] = rgba(
+ getr(src)+PU_DIV255((255-alpha)*getr(dst)),
+ getg(src)+PU_DIV255((255-alpha)*getg(dst)),
+ getb(src)+PU_DIV255((255-alpha)*getb(dst)),
+ geta(src)+PU_DIV255((255-alpha)*geta(dst))
+ );
+
+/* COLOR32 src = bmp->bits[int(yin+i*ky)*bmp->width + int(xin+j*kx)];
+ COLOR32 dst = bits[(i+y)*width + (j+x)];
+ long alpha = geta(src);
+ bits[(i+y)*width + (j+x)] = rgba(
+ getr(src)+(255-alpha)*getr(dst)/255,
+ getg(src)+(255-alpha)*getg(dst)/255,
+ getb(src)+(255-alpha)*getb(dst)/255,
+ geta(src)+(255-alpha)*geta(dst)/255
+ );*/
+// bits[(i+y)*width + (j+x)] = bmp->bits[int(yin+i*ky)*bmp->width + int(xin+j*kx)];
+ }
+ }
+}
+
+void MyBitmap::DrawPart(MyBitmap *bmp, int xin, int yin, int win, int hin, int x, int y, int w, int h)
+{
+ if (!(bits && bmp && bmp->bits)) return;
+ if (!win || !hin) return;
+
+ GdiFlush();
+
+ if (!w) w = win;
+ if (!h) h = hin;
+ float kx = (float)win / w;
+ float ky = (float)hin / h;
+
+ if (x+w >= this->getWidth())
+ w = this->getWidth() - x;
+ if (y+h >= this->getHeight())
+ h = this->getHeight() - y;
+
+ for (int i = 0; i < h; i++)
+ {
+ if (i+y < 0) continue;
+ if (i+y >= height) break;
+ for (int j = 0; j < w; j++)
+ {
+ if (j+x < 0) continue;
+ if (j+x >= width) break;
+ bits[(i+y)*width + (j+x)] = bmp->bits[int(yin+i*ky)*bmp->width + int(xin+j*kx)];
+ }
+ }
+}
+
+void MyBitmap::DrawNoAlpha(MyBitmap *bmp, int x, int y, int w, int h)
+{
+ if (!(bits && bmp && bmp->bits)) return;
+
+ GdiFlush();
+
+ for (int i = 0; i < bmp->height; i++)
+ {
+ if (i+y < 0) continue;
+ if (i+y >= height) break;
+ for (int j = 0; j < bmp->width; j++)
+ {
+ if (j+x < 0) continue;
+ if (j+x >= width) break;
+ bits[(i+y)*width + (j+x)] = bmp->bits[i*bmp->width + j];
+ }
+ }
+}
+
+static __forceinline int ReadP(long *p, int w, int h, int x, int y, int k)
+{
+ if (x<0) x=0; else if (x>=w) x=w-1;
+ if (y<0) y=0; else if (y>=h) y=h-1;
+ return p[(x+y*w)*4+k];
+}
+
+void MyBitmap::Blur(int w, int h)
+{
+ if ((w <= 0) || (h <= 0)) return;
+
+ BYTE *buf_src = new BYTE[width*height*4];
+ long *buf_tmp = new long[width*height*4];
+ BYTE *buf_dst = (BYTE *)bits;
+ memcpy(buf_src, buf_dst, width*height*4);
+
+ BYTE *src, *dst;
+ long *tmp;
+
+ src = buf_src;
+ tmp = buf_tmp;
+ dst = buf_dst;
+
+ int y;
+
+ for (y = 0; y < height; ++y)
+ {
+ for (int x = 0; x < width; ++x)
+ {
+ for (int k = 0; k < 4; ++k)
+ {
+ int tot = src[0];
+ if (x > 0) tot += tmp[-4];
+ if (y > 0) tot += tmp[-width*4];
+ if (x > 0 && y > 0) tot -= tmp[-(width+1)*4];
+ *tmp = tot;
+
+ ++src;
+ ++tmp;
+ }
+ }
+ }
+
+ src = buf_src;
+ tmp = buf_tmp;
+ dst = buf_dst;
+
+ float mul = 1.f/((w*2+1)*(h*2+1));
+ for (y=0;y<height;y++)
+ {
+ for (int x=0;x<width;x++)
+ {
+ for (int k = 0; k < 4; ++k)
+ {
+ int tot = ReadP(tmp,width,height,x+w,y+h,k) +
+ ReadP(tmp,width,height,x-w,y-h,k) -
+ ReadP(tmp,width,height,x-w,y+h,k) -
+ ReadP(tmp,width,height,x+w,y-h,k);
+
+ *dst = BYTE(tot*mul);
+
+ ++dst;
+ ++src;
+ }
+ }
+ }
+
+ delete [] buf_src;
+ delete [] buf_tmp;
+}
+
+void MyBitmap::IncreaseAlpha(float q)
+{
+ BYTE *p = (BYTE *)bits;
+
+ for (int i = 0; i < height; ++i)
+ {
+ for (int j = 0; j < width; ++j)
+ {
+ if (!p[3])
+ {
+ p += 4;
+ continue;
+ }
+
+ float q1 = min(q, 255.f/p[3]);
+
+ for (int k = 0; k < 4; ++k)
+ {
+ *p = (BYTE)min(255, *p * q1);
+ ++p;
+ }
+ }
+ }
+}
+
+void MyBitmap::DrawIcon(HICON hic, int x, int y, int w, int h)
+{
+ GdiFlush();
+
+ ICONINFO info;
+ GetIconInfo(hic, &info);
+
+ BITMAP bmpColor, bmpMask;
+ GetObject(info.hbmMask, sizeof(bmpMask), &bmpMask);
+ GetObject(info.hbmColor, sizeof(bmpColor), &bmpColor);
+
+ if (!w) w = abs(bmpMask.bmWidth);
+ if (!h) h = abs(bmpMask.bmHeight);
+
+ if (bmpColor.bmBitsPixel == 32)
+ {
+ if ((w != abs(bmpMask.bmWidth)) || (h != abs(bmpMask.bmHeight)))
+ {
+ DeleteObject(info.hbmColor);
+ DeleteObject(info.hbmMask);
+ HICON hicTmp = (HICON)CopyImage(hic,IMAGE_ICON,w,h,LR_COPYFROMRESOURCE);
+ GetIconInfo(hicTmp, &info);
+ GetObject(info.hbmMask, sizeof(bmpMask), &bmpMask);
+ GetObject(info.hbmColor, sizeof(bmpColor), &bmpColor);
+ DestroyIcon(hicTmp);
+ }
+
+ BYTE *cbit = new BYTE[bmpColor.bmWidthBytes*bmpColor.bmHeight];
+ BYTE *mbit = new BYTE[bmpMask.bmWidthBytes*bmpMask.bmHeight];
+ GetBitmapBits(info.hbmColor, bmpColor.bmWidthBytes*bmpColor.bmHeight, cbit);
+ GetBitmapBits(info.hbmMask, bmpMask.bmWidthBytes*bmpMask.bmHeight, mbit);
+
+ for (int i = 0; i < bmpColor.bmHeight; i++)
+ {
+ for (int j = 0; j < bmpColor.bmWidth; j++)
+ {
+ BYTE *pixel = cbit + i*bmpColor.bmWidthBytes + j*4;
+ if (!pixel[3])
+ {
+ pixel[3] = (*(mbit + i*bmpMask.bmWidthBytes + j*bmpMask.bmBitsPixel/8) & (1<<(7-j%8))) ? 0 : 255;
+ }
+
+ if (pixel[3] != 255)
+ {
+ pixel[0] = PU_DIV255(pixel[0] * pixel[3]);
+ pixel[1] = PU_DIV255(pixel[1] * pixel[3]);
+ pixel[2] = PU_DIV255(pixel[2] * pixel[3]);
+ }
+ }
+ }
+
+ this->BlendBits((COLOR32 *)cbit, bmpColor.bmWidth, bmpColor.bmHeight, x, y, w, h);
+
+ delete [] mbit;
+ delete [] cbit;
+ } else
+ {
+ this->saveAlpha(x,y,w,h);
+ DrawIconEx(this->getDC(), x, y, hic, w, h, 0, NULL, DI_NORMAL);
+ this->restoreAlpha(x,y,w,h);
+ }
+
+ DeleteObject(info.hbmColor);
+ DeleteObject(info.hbmMask);
+}
+
+//Base on code by Artem Shpynov
+//from clist_modern plugin
+//slightly modified and integrated to MyBitmap class
+void MyBitmap::DrawText(TCHAR *str, int x, int y, int blur, int strength)
+{
+ SIZE sz; GetTextExtentPoint32(this->getDC(), str, lstrlen(str), &sz);
+ sz.cx += (blur+2)*2; sz.cy += (blur+2)*2;
+ x -= blur+2; y -= blur+2;
+
+ static BYTE pbGammaWeight[256]={0};
+ static BOOL bGammaWeightFilled=FALSE;
+
+ if (!bGammaWeightFilled)
+ {
+ int i;
+ for(i=0;i<256;i++)
+ {
+ double f;
+ double gamma=(double)700/1000;
+
+ f=(double)i/255;
+ f=pow(f,(1/gamma));
+
+ pbGammaWeight[i]=(BYTE)(255*f);
+ }
+ bGammaWeightFilled=1;
+ }
+
+ MyBitmap tmp(sz.cx, sz.cy);
+ HFONT hfnTmp = (HFONT)SelectObject(tmp.getDC(), GetCurrentObject(this->getDC(), OBJ_FONT));
+
+ RECT rc; SetRect(&rc, 0, 0, sz.cx, sz.cy);
+ SetTextColor(tmp.getDC(), RGB(255,255,255));
+ SetBkColor(tmp.getDC(), RGB(0,0,0));
+ ExtTextOutA(tmp.getDC(), 0, 0, ETO_OPAQUE, &rc, "", 0, NULL);
+ ::DrawText(tmp.getDC(), str, lstrlen(str), &rc, DT_CENTER|DT_NOPREFIX|DT_SINGLELINE|DT_VCENTER);
+ SelectObject(tmp.getDC(), hfnTmp);
+
+ GdiFlush();
+
+ if (blur)
+ {
+ for (int i = 0; i < sz.cy; i++)
+ {
+ COLOR32 *row_src = tmp.bits + i * tmp.width;
+
+ for (int j = 0; j < sz.cx; j++)
+ {
+ COLOR32 cl = row_src[j];
+ if (!cl) continue;
+
+ int a1 = (getr(cl) + getg(cl) + getb(cl)) / 3;
+ row_src[j] = rgba(a1, a1, a1, a1);
+ }
+ }
+ tmp.Blur(blur, blur);
+ tmp.IncreaseAlpha((float)(strength ? strength : blur));
+ }
+
+ // use Get*Value for COLORREF and get* for COLOR32
+ COLOR32 textColor = GetTextColor(this->getDC());
+ COLOR32 r = GetRValue(textColor);
+ COLOR32 g = GetGValue(textColor);
+ COLOR32 b = GetBValue(textColor);
+
+ int minx = max(0,-x);
+ int miny = max(0,-y);
+ int maxx = min(sz.cx, width-x);
+ int maxy = min(sz.cy, height-y);
+
+ for (int i = miny; i < maxy; i++)
+ {
+ COLOR32 *row_dst = bits + (i+y) * width + x;
+ COLOR32 *row_src = tmp.bits + i * tmp.width;
+
+ for (int j = minx; j < maxx; j++)
+ {
+ COLOR32 bx,rx,gx,mx;
+ {
+ bx=pbGammaWeight[getb(row_src[j])];
+ gx=pbGammaWeight[getg(row_src[j])];
+ rx=pbGammaWeight[getr(row_src[j])];
+ }
+
+ bx=(pbGammaWeight[bx]*(255-b)+bx*(b))/255;
+ gx=(pbGammaWeight[gx]*(255-g)+gx*(g))/255;
+ rx=(pbGammaWeight[rx]*(255-r)+rx*(r))/255;
+
+ mx=(BYTE)(max(max(bx,rx),gx));
+
+ if (1)
+ {
+ bx=(bx<mx)?(BYTE)(((WORD)bx*7+(WORD)mx)>>3):bx;
+ rx=(rx<mx)?(BYTE)(((WORD)rx*7+(WORD)mx)>>3):rx;
+ gx=(gx<mx)?(BYTE)(((WORD)gx*7+(WORD)mx)>>3):gx;
+ // reduce boldeness at white fonts
+ }
+ COLOR32 cl = row_dst[j];
+ if (mx)
+ {
+ COLOR32 rrx,grx,brx;
+ COLOR32 rlx,glx,blx;
+ COLOR32 axx=geta(cl);
+ COLOR32 mmx=(bx+gx+rx)/3;
+ COLOR32 nx=mmx;;//pbGammaWeight[mx];//
+ {
+ //Normalize components to alpha level
+ bx=(nx*(255-axx)+bx*axx)/255;
+ gx=(nx*(255-axx)+gx*axx)/255;
+ rx=(nx*(255-axx)+rx*axx)/255;
+ mx=(nx*(255-axx)+mmx*axx)/255;
+ }
+ {
+ blx = getb(cl);
+ glx = getg(cl);
+ rlx = getr(cl);
+
+ brx=(b-blx)*bx/255;
+ grx=(g-glx)*gx/255;
+ rrx=(r-rlx)*rx/255;
+ row_dst[j] = rgba(rlx+rrx, glx+grx, blx+brx, mx+(255-mx)*axx/255);
+ }
+ }
+ }
+ }
+}
+
+// based on code by Yuriy Zaporozhets from:
+// http://www.codeproject.com/gdi/coolrgn.asp?df=100&forumid=739&exp=0&select=6341
+// slightly modified to integrate with MyBitmap class.
+HRGN MyBitmap::buildOpaqueRgn(int level, bool opaque)
+{
+ GdiFlush();
+
+ const int addRectsCount = 64;
+ int rectsCount = addRectsCount;
+ PRGNDATA pRgnData = (PRGNDATA)(new BYTE[sizeof(RGNDATAHEADER) + (rectsCount)*sizeof(RECT)]);
+ LPRECT pRects = (LPRECT)(&pRgnData->Buffer);
+
+ memset(pRgnData, 0, sizeof(RGNDATAHEADER) + (rectsCount)*sizeof(RECT));
+ pRgnData->rdh.dwSize = sizeof(RGNDATAHEADER);
+ pRgnData->rdh.iType = RDH_RECTANGLES;
+
+ int first = 0;
+ bool wasfirst = false;
+ bool ismask = false;
+ for (int i = 0; i < height; i++)
+ {
+ int j; // we will need j after the loop!
+ for (j = 0; j < width; j++)
+ {
+ ismask = opaque ? (int)geta(this->getRow(i)[j]) > level : (int)geta(this->getRow(i)[j]) < level;
+ if (wasfirst)
+ {
+ if (!ismask)
+ {
+ SetRect(&pRects[pRgnData->rdh.nCount++], first, i, j, i+1);
+ if ((int)(pRgnData->rdh.nCount) >= rectsCount)
+ {
+ rectsCount += addRectsCount;
+ LPRGNDATA pRgnDataNew = (LPRGNDATA)(new BYTE[sizeof(RGNDATAHEADER) + (rectsCount)*sizeof(RECT)]);
+ memcpy(pRgnDataNew, pRgnData, sizeof(RGNDATAHEADER) + pRgnData->rdh.nCount * sizeof(RECT));
+ delete pRgnData;
+ pRgnData = pRgnDataNew;
+ pRects = (LPRECT)(&pRgnData->Buffer);
+ }
+ wasfirst = false;
+ }
+ } else
+ if (ismask) // set wasfirst when mask is found
+ {
+ first = j;
+ wasfirst = true;
+ }
+ }
+
+ if (wasfirst && ismask)
+ {
+ SetRect(&pRects[pRgnData->rdh.nCount++], first, i, j, i+1);
+ if ((int)(pRgnData->rdh.nCount) >= rectsCount)
+ {
+ rectsCount += addRectsCount;
+ LPRGNDATA pRgnDataNew = (LPRGNDATA)(new BYTE[sizeof(RGNDATAHEADER) + (rectsCount)*sizeof(RECT)]);
+ memcpy(pRgnDataNew, pRgnData, sizeof(RGNDATAHEADER) + pRgnData->rdh.nCount * sizeof(RECT));
+ delete pRgnData;
+ pRgnData = pRgnDataNew;
+ pRects = (LPRECT)(&pRgnData->Buffer);
+ }
+ wasfirst = false;
+ }
+
+ }
+
+ HRGN hRgn = ExtCreateRegion(NULL, sizeof(RGNDATAHEADER) + pRgnData->rdh.nCount*sizeof(RECT), (LPRGNDATA)pRgnData);
+ delete pRgnData;
+ return hRgn;
+}
+
+static int hex2dec(char hex)
+{
+ if ((hex >= '0') && (hex <= '9'))
+ return hex - '0';
+ if ((hex >= 'a') && (hex <= 'f'))
+ return hex - 'a' + 0xa;
+ if ((hex >= 'A') && (hex <= 'F'))
+ return hex - 'A' + 0xa;
+ return 0;
+}
+
+bool MyBitmap::loadFromFile_pixel(const char *fn, const char *fnAlpha)
+{
+ allocate(1,1);
+ int r, g, b, a=255;
+ const char *p = fn + lstrlenA("pixel:");
+ r = (hex2dec(p[0]) << 4) + hex2dec(p[1]);
+ g = (hex2dec(p[2]) << 4) + hex2dec(p[3]);
+ b = (hex2dec(p[4]) << 4) + hex2dec(p[5]);
+ *bits = rgba(r,g,b,a);
+ return true;
+}
+
+bool MyBitmap::loadFromFile_gradient(const char *fn, const char *fnAlpha)
+{
+ const char *p = fn + lstrlenA("gradient:");
+
+ if (*p == 'h') allocate(256,1);
+ else allocate(1,256);
+
+ int r, g, b, a=255;
+
+ p += 2;
+ r = (hex2dec(p[0]) << 4) + hex2dec(p[1]);
+ g = (hex2dec(p[2]) << 4) + hex2dec(p[3]);
+ b = (hex2dec(p[4]) << 4) + hex2dec(p[5]);
+ COLOR32 from = rgba(r,g,b,a);
+
+ p += 7;
+ r = (hex2dec(p[0]) << 4) + hex2dec(p[1]);
+ g = (hex2dec(p[2]) << 4) + hex2dec(p[3]);
+ b = (hex2dec(p[4]) << 4) + hex2dec(p[5]);
+ COLOR32 to = rgba(r,g,b,a);
+
+ for (int i = 0; i < 256; ++i)
+ {
+ bits[i] = rgba(
+ ((255-i) * getr(from) + i * getr(to)) / 255,
+ ((255-i) * getg(from) + i * getg(to)) / 255,
+ ((255-i) * getb(from) + i * getb(to)) / 255,
+ 255
+ );
+ }
+
+ return true;
+}
+
+bool MyBitmap::loadFromFile_png(const char *fn, const char *fnAlpha)
+{
+ if (ServiceExists(MS_PNG2DIB))
+ {
+ HANDLE hFile, hMap = 0;
+ BYTE *ppMap = 0;
+ long cbFileSize = 0;
+ BITMAPINFOHEADER *pDib;
+ BYTE *pDibBits;
+ if ((hFile = CreateFileA(fn, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL)) != INVALID_HANDLE_VALUE)
+ if ((hMap = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL)) != NULL)
+ if ((ppMap = (BYTE*)MapViewOfFile( hMap, FILE_MAP_READ, 0, 0, 0 )) != NULL)
+ cbFileSize = GetFileSize(hFile, NULL);
+ if (cbFileSize)
+ {
+ PNG2DIB param;
+ param.pSource = ppMap;
+ param.cbSourceSize = cbFileSize;
+ param.pResult = &pDib;
+ if (CallService(MS_PNG2DIB, 0, (LPARAM)&param))
+ pDibBits = (BYTE*)(pDib+1);
+ else
+ cbFileSize = 0;
+ }
+
+ if (ppMap) UnmapViewOfFile(ppMap);
+ if (hMap) CloseHandle(hMap);
+ if (hFile) CloseHandle(hFile);
+
+ if (!cbFileSize) return false;
+
+ BITMAPINFO *bi=(BITMAPINFO*)pDib;
+ BYTE *pt=(BYTE*)bi;
+ pt+=bi->bmiHeader.biSize;
+
+ if (bi->bmiHeader.biBitCount != 32)
+ {
+ allocate(abs(bi->bmiHeader.biWidth), abs(bi->bmiHeader.biHeight));
+ HDC hdcTmp = CreateCompatibleDC(getDC());
+ HBITMAP hBitmap = CreateDIBitmap(getDC(), pDib, CBM_INIT, pDibBits, bi, DIB_PAL_COLORS);
+ SelectObject(hdcTmp, hBitmap);
+ BitBlt(this->getDC(), 0, 0, abs(bi->bmiHeader.biWidth), abs(bi->bmiHeader.biHeight), hdcTmp, 0, 0, SRCCOPY);
+ this->makeOpaque();
+ DeleteDC(hdcTmp);
+ DeleteObject(hBitmap);
+ } else
+ {
+ allocate(abs(bi->bmiHeader.biWidth), abs(bi->bmiHeader.biHeight));
+ BYTE *p2=(BYTE *)pt;
+ for (int y=0; y<bi->bmiHeader.biHeight; ++y)
+ {
+ BYTE *p1=(BYTE *)bits + (bi->bmiHeader.biHeight-y-1)*bi->bmiHeader.biWidth*4;
+ for (int x=0; x<bi->bmiHeader.biWidth; ++x)
+ {
+ p1[0]= p2[0];
+ p1[1]= p2[1];
+ p1[2]= p2[2];
+ p1[3]= p2[3];
+ p1 += 4;
+ p2 += 4;
+ }
+ }
+// memcpy(bits, pt, bi->bmiHeader.biSizeImage);
+ premultipleChannels();
+ }
+
+ GlobalFree(pDib);
+ return true;
+ } else
+ {
+// MessageBox(NULL, Translate("You need the png2dib plugin v. 0.1.3.x or later to process PNG images"), Translate("Error"), MB_OK);
+ return false;
+ }
+}
+
+bool MyBitmap::loadFromFile_default(const char *fn, const char *fnAlpha)
+{
+ SIZE sz;
+ HBITMAP hBmpLoaded = (HBITMAP)LoadImageA(NULL, fn, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
+ if (!hBmpLoaded)
+ return false;
+
+ BITMAP bm; GetObject(hBmpLoaded, sizeof(bm), &bm);
+ SetBitmapDimensionEx(hBmpLoaded, bm.bmWidth, bm.bmHeight, NULL);
+
+ HDC dcTmp = CreateCompatibleDC(0);
+ GetBitmapDimensionEx(hBmpLoaded, &sz);
+ HBITMAP hBmpDcSave = (HBITMAP)SelectObject(dcTmp, hBmpLoaded);
+
+ allocate(sz.cx, sz.cy);
+ BitBlt(dcBmp, 0, 0, width, height, dcTmp, 0, 0, SRCCOPY);
+
+ DeleteObject(SelectObject(dcTmp, hBmpDcSave));
+ DeleteDC(dcTmp);
+
+ MyBitmap alpha;
+ if (fnAlpha && alpha.loadFromFile(fnAlpha) &&
+ (alpha.getWidth() == width) &&
+ (alpha.getHeight() == height) )
+ {
+ for (int i = 0; i < width*height; i++)
+ bits[i] = (bits[i] & 0x00ffffff) | ( (alpha.bits[i] & 0x000000ff) << 24 );
+ premultipleChannels();
+ } else
+ {
+ makeOpaque();
+ }
+ return true;
+}
+
+bool MyBitmap::loadFromFile(const char *fn, const char *fnAlpha)
+{
+ if (bits) free();
+
+ if (!strncmp(fn, "pixel:", lstrlenA("pixel:")))
+ {
+ return loadFromFile_pixel(fn, fnAlpha);
+ } else
+ if (!strncmp(fn, "gradient:", lstrlenA("gradient:")))
+ {
+ return loadFromFile_gradient(fn, fnAlpha);
+ } else
+ {
+ char ext[5];
+ memcpy(ext,fn+(strlen(fn)-4),5);
+ if (!lstrcmpiA(ext,".png"))
+ {
+ return loadFromFile_png(fn, fnAlpha);
+ } else
+ {
+ return loadFromFile_default(fn, fnAlpha);
+ }
+ }
+ // unreachable place
+ return false;
+}
+
+void MyBitmap::allocate(int w, int h)
+{
+ if (dcBmp && (width == w) && (height == h)) return;
+
+ width = w;
+ height = h;
+
+ BITMAPINFO bi;
+
+ bi.bmiHeader.biSize = sizeof(bi.bmiHeader);
+ bi.bmiHeader.biWidth = w;
+ bi.bmiHeader.biHeight = -h;
+ bi.bmiHeader.biPlanes = 1;
+ bi.bmiHeader.biBitCount = 32;
+ bi.bmiHeader.biCompression = BI_RGB;
+
+ if (dcBmp)
+ {
+ DeleteObject(SelectObject(dcBmp, hBmpSave));
+ DeleteDC(dcBmp);
+ }
+
+ hBmp = (HBITMAP)CreateDIBSection(0, &bi, DIB_RGB_COLORS, (void **)&bits, 0, 0);
+ dcBmp = CreateCompatibleDC(0);
+ hBmpSave = (HBITMAP)SelectObject(dcBmp, hBmp);
+
+ GdiFlush();
+}
+
+void MyBitmap::free()
+{
+ GdiFlush();
+
+ DeleteObject(SelectObject(dcBmp, hBmpSave));
+ DeleteDC(dcBmp);
+
+ dcBmp = 0;
+ hBmp = 0;
+ bits = 0;
+ width = height = 0;
+}
+
+void MyBitmap::premultipleChannels()
+{
+ GdiFlush();
+
+ for (int i = 0; i < width*height; i++)
+ bits[i] = rgba(getr(bits[i])*geta(bits[i])/255, getg(bits[i])*geta(bits[i])/255, getb(bits[i])*geta(bits[i])/255, geta(bits[i]));
+}
diff --git a/plugins/FloatingContacts/bitmap_funcs.h b/plugins/FloatingContacts/bitmap_funcs.h
new file mode 100644
index 0000000000..b7f55a43d7
--- /dev/null
+++ b/plugins/FloatingContacts/bitmap_funcs.h
@@ -0,0 +1,127 @@
+/*
+Popup Plus plugin for Miranda IM
+
+Copyright © 2002 Luca Santarelli,
+ © 2004-2007 Victor Pavlychko
+
+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 __bitmap_funcs_h__
+#define __bitmap_funcs_h__
+
+// This should make bitmap manipulations much easier...
+class MyBitmap
+{
+public:
+ typedef unsigned long COLOR32;
+ static inline COLOR32 RGBA(unsigned char r, unsigned char g, unsigned char b, unsigned char a = 0xff)
+ {
+ return (a << 24) | (r << 16) | (g << 8) | b;
+ };
+
+private:
+ HBITMAP hBmpSave, hBmp;
+ HDC dcBmp;
+ COLOR32 *bits;
+ COLOR32 *bitsSave;
+ int width, height;
+
+ void free();
+
+ bool loadFromFile_pixel(const char *fn, const char *fnAlpha = 0);
+ bool loadFromFile_gradient(const char *fn, const char *fnAlpha = 0);
+ bool loadFromFile_png(const char *fn, const char *fnAlpha = 0);
+ bool loadFromFile_default(const char *fn, const char *fnAlpha = 0);
+ void premultipleChannels();
+
+public:
+ MyBitmap();
+ MyBitmap(int w, int h);
+ MyBitmap(const char *fn, const char *fnAlpha = 0);
+ ~MyBitmap();
+ void allocate(int w, int h);
+
+ bool loadFromFile(const char *fn, const char *fnAlpha = 0);
+
+ int getWidth() { return width; }
+ int getHeight() { return height; }
+
+ HDC getDC() { return dcBmp; }
+ HBITMAP getBitmap() { return hBmp; }
+
+ void setAlpha(BYTE level);
+ void setAlphaRect(int x1, int y1, int x2, int y2, BYTE level);
+ void setAlphaRect(RECT rc, BYTE level) { setAlphaRect(rc.left, rc.top, rc.right, rc.bottom, level); }
+
+ void makeOpaque();
+ void makeOpaqueRect(int x1, int y1, int x2, int y2);
+ void makeOpaqueRect(RECT rc) { makeOpaqueRect(rc.left, rc.top, rc.right, rc.bottom); }
+
+ void saveAlpha(int x = 0, int y = 0, int w = 0, int h = 0);
+ void restoreAlpha(int x = 0, int y = 0, int w = 0, int h = 0);
+
+ void DrawBits(COLOR32 *inbits, int inw, int inh, int x, int y, int w, int h);
+ void BlendBits(COLOR32 *inbits, int inw, int inh, int x, int y, int w, int h);
+
+ void DrawNoAlpha(MyBitmap *bmp, int x, int y, int w, int h);
+
+ void Blend(MyBitmap *bmp, int x, int y, int w, int h);
+ void Draw(MyBitmap *bmp, int x, int y, int w, int h);
+
+ void BlendColorized(MyBitmap *bmp, int x, int y, int w, int h, COLOR32 color);
+ void DrawColorized(MyBitmap *bmp, int x, int y, int w, int h, COLOR32 color);
+
+ void BlendPart(MyBitmap *bmp, int xin, int yin, int win, int hin, int x, int y, int w, int h);
+ void BlendPartColorized(MyBitmap *bmp, int xin, int yin, int win, int hin, int x, int y, int w, int h, COLOR32 color);
+ void DrawPart(MyBitmap *bmp, int xin, int yin, int win, int hin, int x, int y, int w, int h);
+// void DrawPartNoAlpha(MyBitmap *bmp, int x, int y, int w, int h);
+// void DrawPartColorized(MyBitmap *bmp, int x, int y, int w, int h, COLOR32 color);
+
+ void Blur(int w, int h);
+ void IncreaseAlpha(float q);
+
+ void DrawIcon(HICON hic, int x, int y, int w = 0, int h = 0);
+ void DrawText(TCHAR *str, int x, int y, int blur=0, int strength = 0);
+
+ __forceinline COLOR32 *getBits() { return bits; }
+ __forceinline COLOR32 *getRow(int row) { return bits + row * width; }
+ __forceinline COLOR32 *operator[] (int row) { return bits + row * width; }
+
+ static __forceinline COLOR32 rgba(COLOR32 r, COLOR32 g, COLOR32 b, COLOR32 a)
+ {
+ return ((a & 0xff) << 24) | ((r & 0xff) << 16) | ((g & 0xff) << 8) | (b & 0xff);
+ }
+ static __forceinline COLOR32 getr(COLOR32 c)
+ {
+ return (c >> 16) & 0xff;
+ }
+ static __forceinline COLOR32 getg(COLOR32 c)
+ {
+ return (c >> 8) & 0xff;
+ }
+ static __forceinline COLOR32 getb(COLOR32 c)
+ {
+ return c & 0xff;
+ }
+ static __forceinline COLOR32 geta(COLOR32 c)
+ {
+ return (c >> 24) & 0xff;
+ }
+
+ HRGN buildOpaqueRgn(int level = 64, bool opaque = true);
+};
+
+#endif // __bitmap_funcs_h__
diff --git a/plugins/FloatingContacts/docs/fltcontacts_langpack.txt b/plugins/FloatingContacts/docs/fltcontacts_langpack.txt
new file mode 100644
index 0000000000..4aba1cd0db
--- /dev/null
+++ b/plugins/FloatingContacts/docs/fltcontacts_langpack.txt
@@ -0,0 +1,68 @@
+;============================================================
+; Module: fltcontacts.dll
+; Plugin: Floating Ñontacts
+; Versions: 0.1.1.9
+; URL: http://www.miranda-im.org/
+;============================================================
+
+[Floating Contacts]
+
+
+;Menu
+[Remove thumb]
+
+[Hide all thumbs]
+
+[Show all thumbs]
+
+
+;Hotkeys
+[Show/Hide all thumbs]
+
+
+;Properties
+;Main Features
+[Main Features]
+
+[Hiding contacts]
+
+[Hide offline contacts]
+
+[Hide all contacts]
+
+[Hide when a fulscreen app is active]
+
+[Hide when contact list is shown]
+
+[Stick together]
+
+[Use fixed width]
+
+[Show tooltips]
+
+[Miscellaneous]
+
+[0 = Default]
+
+[requires mToolTip or Tipper plugin]
+
+[Bring to front]
+
+[Bring to front every]
+
+
+;Appearance
+[<Contact List Text>]
+
+[Opacity:]
+
+[Floating Contacts Background]
+
+[Draw border]
+
+[Left-top edges color:]
+
+[Right-bottom eges color:]
+
+
+;End (Floating Ñontacts) \ No newline at end of file
diff --git a/plugins/FloatingContacts/docs/fltcontacts_readme.txt b/plugins/FloatingContacts/docs/fltcontacts_readme.txt
new file mode 100644
index 0000000000..b62a9c7ff6
--- /dev/null
+++ b/plugins/FloatingContacts/docs/fltcontacts_readme.txt
@@ -0,0 +1,91 @@
+******************
+Floating Contacts
+******************
+
+Description
+===========
+This plugin is further development of Floating contacts plugin v1.0.0.7 from Iavor Vajarov (thx).
+
+New features
+************
+- Showing a tooltip when mouse's hovering over a floating contact's window.
+- Support MUID inteface of Miranda v0.8.0.0 and higher.
+- Unicode aware.
+- True alpha channel support on windows 2000+.
+- "Bring to front" feature allows bring to front floating windows every x seconds.
+ With a lot of window may get backside effect, in this case set greater interval.
+- And various other features.
+
+Requirements
+************
+- Miranda v0.6.0.0 or higher.
+- Tipper or mToolTip plugin for tooltip show.
+
+Changelog
+=========
+
++ Relative coordinates.
+
+---1.0.2.2---
+! Fixed gdi leak.
+! Fixed possible crash.
+! Fixed drawing 8-bit status icons.
+! Show floating contacts on startup when "Hide when contact list is shown" option is checked.
+
+---1.0.2.1---
+! Wrong detection of hiding CList behind display border.
+* Changed "Mouse In" highlight (must resolve some problem).
+! Fixed "Single click" feature.
+! Fixed memory leak.
+
+----1.0.2.0---
++ True alpha channel support on windows 2000+.
+! Minor fixed.
+* Converted to C++.
+
+----1.0.1.1---
++ Added "Dim idle contacts" feature.
+! Fixed menu.
+* Updated icons (added 256 colors icons).
+* Changed painting.
+* Changed moving.
+
+----1.0.1.0---
++ Unicode aware.
++ Added russian langpack.
+* Updated langpack.
+! Fixed showing of nicks, containing "&".
++ Added feature "Single click interface".
++ Added hotkeys for "Show/Hide all thumbs" and "Hide when contact list is showing".
+! Fixed refresh icon.
++ Added "Hide when contact list is showing" feature.
+
+----1.0.0.9---
+! Fixed show of floating contact's windows if check "Hide all contacts".
++ Added "Bring to front" feature. The feature provide keeping floating contact's windows on top.
+* Unified plugin name in service, db setting and db contacts settings.
+ To keep your old settings just rename module settings branch "Floating contacts" in database to "FloatingContacts" (use DBE++).
+! Fixed font size.
+* Reformed options.
+- Deleted support Miranda version lower then 0.6.0.0.
++ Added MUID.
+* New icons.
+
+----1.0.0.8---
+! Fixed coordinate floating contact's window when it is dragged.
+! Fixed name change.
++ Added showing of tooltip when mouse's hovering over a floating contact's window (requires Tipper or mToolTip plugin).
+
+Symbols used in changelog
+--------------
++ : new feature
+* : changed
+! : bufgix
+- : feature removed or disabled because of pending bugs
+--------------
+
+Author
+======
+Created by Iavor Vajarov ( ivajarov <at> code <dot> bg ).
+Further development by Kosh&chka ( ell-6 <at> ya <dot> ru ).
+
diff --git a/plugins/FloatingContacts/docs/fltcontacts_russian_langpack.txt b/plugins/FloatingContacts/docs/fltcontacts_russian_langpack.txt
new file mode 100644
index 0000000000..2ae3442f7a
--- /dev/null
+++ b/plugins/FloatingContacts/docs/fltcontacts_russian_langpack.txt
@@ -0,0 +1,70 @@
+;============================================================
+; Module: fltcontacts.dll
+; Plugin: Floating Ñontacts
+; Versions: 0.1.1.9
+; Translators: SAOPP
+; URL: http://www.miranda-im.org/
+;============================================================
+[Floating Contacts]
+Ïëàâàþùèå êîíòàêòû
+
+;Menu
+[Remove thumb]
+Óáðàòü ïëàâàþùèé êîíòàêò
+[Hide all thumbs]
+Ñêðûòü ïëàâàþùèå êîíòàêòû
+[Show all thumbs]
+Ïîêàçàòü ïëàâàþùèå êîíòàêòû
+
+;Hotkeys
+[Show/Hide all thumbs]
+Ïîêàçàòü/Ñêðûòü âñå êîíòàêòû
+
+;Properties
+;Main Features
+[Main Features]
+Ãëàâíîå
+[Hiding contacts]
+Ñêðûòèå êîíòàêòîâ
+[Hide offline contacts]
+Ïðÿòàòü îôôëàéí êîíòàêòû
+[Hide all contacts]
+Ïðÿòàòü âñå êîíòàêòû
+[Hide when a fulscreen app is active]
+Ïðÿòàòü êîãäà ïðèëîæåíèå ðàçâåðíóòî
+[Hide when contact list is shown]
+Ïðÿòàòü êîãäà ñïèñîê êîíòàêòîâ âèäåí
+[Stick together]
+Ñêëåèâàòü êîíòàêòû
+[Use fixed width]
+Øèðèíà
+[Show tooltips]
+Ïîäñêàçêè
+[Miscellaneous]
+Ïðî÷åå
+[0 = Default]
+0=Óìîë÷àíèå
+[requires mToolTip or Tipper plugin]
+òðåáóåòñÿ ìîäóëü mToolTip èëè Tipper
+[Bring to front]
+Íà ïåðåäíèé ïëàí
+[Bring to front every]
+Ïåðåìåùàòü íà ââåðõ êàæäûå
+
+;Appearance
+[<Contact List Text>]
+Øðèôò â ñïèñêå êîíòàêòîâ
+[Opacity:]
+Ïðîçðà÷íîñòü:
+[Floating Contacts Background]
+Ïëàâàþùèå êîíòàêòû: ôîí
+[Draw border]
+Ïîêàçûâàòü ðàìêó
+[Left-top edges color:]
+Öâåò ñëåâà-ñâåðõó:
+[Right-bottom eges color:]
+Öâåò ñïðàâà-ñíèçó:
+
+;End (Floating Ñontacts)
+
+
diff --git a/plugins/FloatingContacts/filedrop.cpp b/plugins/FloatingContacts/filedrop.cpp
new file mode 100644
index 0000000000..09fe2dace2
--- /dev/null
+++ b/plugins/FloatingContacts/filedrop.cpp
@@ -0,0 +1,368 @@
+#include "stdhdr.h"
+
+static void ProcessDroppedItems ( char **ppDroppedItems, int nCount, char **ppFiles );
+static int CountDroppedFiles ( char **ppDroppedItems, int nCount );
+static BOOL OnDropFiles ( HDROP hDrop, ThumbInfo *pThumb );
+
+HRESULT STDMETHODCALLTYPE CDropTarget::QueryInterface(REFIID riid,LPVOID *ppvObj)
+{
+ if ( IsEqualIID( riid, IID_IDropTarget ) )
+ {
+ *ppvObj = this;
+ this->AddRef();
+ return S_OK;
+ }
+
+ *ppvObj=NULL;
+
+ return ( E_NOINTERFACE );
+}
+
+ULONG STDMETHODCALLTYPE CDropTarget::AddRef( )
+{
+ return ++this->refCount;
+}
+
+ULONG STDMETHODCALLTYPE CDropTarget::Release( )
+{
+ int res = --this->refCount;
+ if (!res) delete this;
+ return res;
+}
+
+
+HRESULT STDMETHODCALLTYPE CDropTarget::DragOver( DWORD fKeyState, POINTL pt, DWORD *pdwEffect )
+{
+ *pdwEffect = 0;
+
+ if( hwndCurDrag == NULL )
+ {
+ *pdwEffect = DROPEFFECT_NONE;
+ }
+ else
+ {
+ *pdwEffect |= DROPEFFECT_COPY;
+ }
+ return S_OK;
+}
+
+
+HRESULT STDMETHODCALLTYPE CDropTarget::DragEnter( IDataObject *pData, DWORD fKeyState, POINTL pt, DWORD *pdwEffect)
+{
+ HWND hwnd = NULL;
+ POINT shortPt;
+ FORMATETC feFile = { CF_HDROP, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
+ FORMATETC feText = { CF_TEXT, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
+ ThumbInfo *pThumb;
+
+ if ( S_OK == pData->QueryGetData( &feFile ) ||
+ S_OK == pData->QueryGetData( &feText ) )
+ {
+ shortPt.x = pt.x;
+ shortPt.y = pt.y;
+
+ hwnd = WindowFromPoint( shortPt );
+
+ if ( pThumb = thumbList.FindThumb( hwnd ) )
+ {
+ hwndCurDrag = hwnd;
+ pThumb->ThumbSelect( TRUE );
+ }
+ }
+
+ return DragOver( fKeyState, pt, pdwEffect);
+}
+
+
+HRESULT STDMETHODCALLTYPE CDropTarget::DragLeave( )
+{
+ ThumbInfo *pThumb = thumbList.FindThumb( hwndCurDrag );
+
+ if ( NULL != pThumb )
+ {
+ pThumb->ThumbDeselect( TRUE );
+ }
+
+ hwndCurDrag = NULL;
+
+ return S_OK;
+}
+
+
+HRESULT STDMETHODCALLTYPE CDropTarget::Drop( IDataObject *pData,DWORD fKeyState,POINTL pt,DWORD *pdwEffect)
+{
+ FORMATETC fe = { CF_HDROP, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
+ STGMEDIUM stg;
+ HDROP hDrop = NULL;
+ ThumbInfo *pThumb = NULL;
+ char *pText = NULL;
+ BOOL bFormatText = FALSE;
+
+ *pdwEffect = DROPEFFECT_NONE;
+
+
+ if( hwndCurDrag == NULL ) return( S_OK );
+
+ pThumb = (ThumbInfo*)GetWindowLong( hwndCurDrag, GWL_USERDATA );
+ if ( pThumb == NULL ) return( S_OK );
+
+ if ( S_OK != pData->GetData( &fe,&stg ) )
+ {
+ fe.cfFormat = CF_TEXT;
+
+ if ( S_OK != pData->GetData( &fe,&stg ) )
+ {
+ return( S_OK );
+ }
+ else
+ {
+ bFormatText = TRUE;
+ }
+ }
+
+
+
+ if ( !bFormatText )
+ {
+ hDrop = (HDROP)stg.hGlobal;
+
+ if ( hDrop != NULL )
+ {
+ OnDropFiles( hDrop, pThumb );
+ }
+ }
+ else
+ {
+ pText = (char*)GlobalLock( stg.hGlobal );
+
+ if ( pText != NULL )
+ {
+ SendMsgDialog( hwndCurDrag, pText );
+ GlobalUnlock( stg.hGlobal );
+ }
+ }
+
+ if( stg.pUnkForRelease != NULL )
+ {
+ stg.pUnkForRelease->Release( );
+ }
+ else
+ {
+ GlobalFree( stg.hGlobal );
+ }
+
+ DragLeave( );
+
+ return S_OK;
+}
+
+///////////////////////////////////////////////////////
+// Send files processing
+
+BOOL OnDropFiles( HDROP hDrop, ThumbInfo *pThumb )
+{
+ BOOL bSuccess = FALSE;
+ UINT nFilesCount = 0;
+ UINT iItem = 0;
+ char **ppFiles = NULL;
+ char **ppDroppedItems = NULL;
+ UINT nDroppedItemsCount = 0;
+ char szFilename[ MAX_PATH ];
+
+
+ nDroppedItemsCount = DragQueryFile( hDrop, 0xFFFFFFFF, NULL, 0 );
+
+ ppDroppedItems = ( char** )malloc( sizeof(char*)*( nDroppedItemsCount + 1 ) );
+
+ if ( ppDroppedItems == NULL )
+ {
+ return( FALSE );
+ }
+
+ ppDroppedItems[ nDroppedItemsCount ] = NULL;
+
+ for( iItem = 0; iItem < nDroppedItemsCount; ++iItem )
+ {
+ DragQueryFileA( hDrop, iItem, szFilename, sizeof( szFilename ) );
+ ppDroppedItems[ iItem ] = _strdup( szFilename );
+ }
+
+ nFilesCount = CountDroppedFiles( ppDroppedItems, nDroppedItemsCount );
+
+ ppFiles = ( char** )malloc( sizeof( char *)* ( nFilesCount+1 ) );
+
+ if ( ppFiles == NULL )
+ {
+ return( FALSE );
+ }
+
+ ppFiles[ nFilesCount] = NULL;
+
+ ProcessDroppedItems( ppDroppedItems, nDroppedItemsCount, ppFiles );
+
+ bSuccess = (BOOL)CallService( MS_CLIST_CONTACTFILESDROPPED, (WPARAM)pThumb->hContact, (LPARAM)ppFiles );
+
+ // Cleanup
+ for( iItem = 0; ppDroppedItems[ iItem ]; ++iItem )
+ {
+ free( ppDroppedItems[ iItem ] );
+ }
+
+ free( ppDroppedItems );
+
+ for( iItem = 0; iItem < nFilesCount ; ++iItem )
+ {
+ free( ppFiles[ iItem ] );
+ }
+
+ free( ppFiles );
+
+ return( bSuccess );
+}
+
+
+static int CountFiles( char *szItem )
+{
+ int nCount = 0;
+ WIN32_FIND_DATAA fd;
+
+ HANDLE hFind = FindFirstFileA( szItem, &fd );
+
+ if ( hFind != INVALID_HANDLE_VALUE )
+ {
+ do
+ {
+ if ( fd.dwFileAttributes == FILE_ATTRIBUTE_DIRECTORY )
+ {
+ // Skip parent directories
+ if ( ( 0 != strcmp( fd.cFileName, "." ) ) &&
+ ( 0 != strcmp( fd.cFileName, ".." ) ) )
+ {
+ char szDirName[ MAX_PATH ];
+ strncpy( szDirName, szItem, MAX_PATH - 1 );
+
+ if ( NULL != strstr( szItem, "*.*" ) )
+ {
+ sprintf( szDirName + strlen( szDirName ) - 3, "%s\0", fd.cFileName );
+ }
+
+ ++nCount;
+ strcat( szDirName, "\\*.*" );
+ nCount += CountFiles( szDirName );
+ }
+ }
+ else
+ {
+ ++nCount;
+ }
+ }
+ while( FALSE != FindNextFileA( hFind, &fd ) );
+ }
+
+ return( nCount );
+}
+
+
+
+static void SaveFiles( char *szItem, char **ppFiles, int *pnCount )
+{
+
+ WIN32_FIND_DATAA fd;
+
+ HANDLE hFind = FindFirstFileA( szItem, &fd );
+
+ if ( hFind != INVALID_HANDLE_VALUE )
+ {
+ do
+ {
+ if ( fd.dwFileAttributes == FILE_ATTRIBUTE_DIRECTORY )
+ {
+ // Skip parent directories
+ if ( ( 0 != strcmp( fd.cFileName, "." ) ) &&
+ ( 0 != strcmp( fd.cFileName, ".." ) ) )
+ {
+ char szDirName[ MAX_PATH ];
+ strncpy( szDirName, szItem, MAX_PATH - 1 );
+
+ if ( NULL != strstr( szItem, "*.*" ) )
+ {
+ sprintf( szDirName + strlen( szDirName ) - 3, "%s\0", fd.cFileName );
+ }
+
+ ppFiles[ *pnCount ] = _strdup( szDirName );
+ ++( *pnCount );
+
+ strcat( szDirName, "\\*.*" );
+ SaveFiles( szDirName, ppFiles, pnCount );
+
+ }
+ }
+ else
+ {
+ int nSize = sizeof(char) * ( strlen( szItem ) + strlen( fd.cFileName ) + sizeof( char ) );
+ char *szFile = (char*) malloc( nSize ) ;
+
+ strncpy( szFile, szItem, nSize - 1 );
+
+ if ( NULL != strstr( szFile, "*.*" ) )
+ {
+ szFile[ strlen( szFile ) - 3 ] = '\0';
+ strncat( szFile, fd.cFileName, MAX_PATH - 1 );
+ }
+
+ ppFiles[ *pnCount ] = szFile;
+ ++( *pnCount );
+ }
+ }
+ while( FALSE != FindNextFileA( hFind, &fd ) );
+ }
+}
+
+
+static void ProcessDroppedItems( char **ppDroppedItems, int nCount, char **ppFiles )
+{
+ int i;
+ int fileCount = 0;
+
+ for( i = 0; i < nCount; ++i )
+ {
+ SaveFiles( ppDroppedItems[ i ], ppFiles, &fileCount );
+ }
+}
+
+
+static int CountDroppedFiles( char **ppDroppedItems, int nCount )
+{
+ int fileCount = 0;
+ int i;
+
+ for( i = 0; i < nCount; ++i )
+ {
+ fileCount += CountFiles( ppDroppedItems[ i ] );
+ }
+
+ return( fileCount );
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+// Init/destroy
+void InitFileDropping()
+{
+ OleInitialize( NULL );
+}
+
+void FreeFileDropping(void)
+{
+ OleUninitialize();
+}
+
+void RegisterFileDropping( HWND hwnd, CDropTarget* pdropTarget )
+{
+ RegisterDragDrop( hwnd, (IDropTarget*)pdropTarget );
+}
+
+void UnregisterFileDropping( HWND hwnd )
+{
+ RevokeDragDrop( hwnd );
+}
diff --git a/plugins/FloatingContacts/filedrop.h b/plugins/FloatingContacts/filedrop.h
new file mode 100644
index 0000000000..ed03cdbf68
--- /dev/null
+++ b/plugins/FloatingContacts/filedrop.h
@@ -0,0 +1,26 @@
+/* This file is a modification of clcfiledrop.h originally
+ written by Richard Hughes*/
+
+static HWND hwndCurDrag = NULL;
+
+class CDropTarget: public IDropTarget
+{
+private:
+ unsigned long refCount;
+
+public:
+ CDropTarget(): refCount(0) {}
+
+ HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid,LPVOID *ppvObj);
+ ULONG STDMETHODCALLTYPE AddRef();
+ ULONG STDMETHODCALLTYPE Release();
+ HRESULT STDMETHODCALLTYPE DragOver(DWORD fKeyState, POINTL pt, DWORD *pdwEffect);
+ HRESULT STDMETHODCALLTYPE DragEnter(IDataObject *pData, DWORD fKeyState, POINTL pt, DWORD *pdwEffect);
+ HRESULT STDMETHODCALLTYPE DragLeave();
+ HRESULT STDMETHODCALLTYPE Drop(IDataObject *pData,DWORD fKeyState,POINTL pt,DWORD *pdwEffect);
+};
+
+void InitFileDropping();
+void FreeFileDropping(void);
+void RegisterFileDropping( HWND hwnd, CDropTarget* pdropTarget );
+void UnregisterFileDropping( HWND hwnd );
diff --git a/plugins/FloatingContacts/fltcnt.rc b/plugins/FloatingContacts/fltcnt.rc
new file mode 100644
index 0000000000..c341a349cc
--- /dev/null
+++ b/plugins/FloatingContacts/fltcnt.rc
@@ -0,0 +1,232 @@
+// 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_NEUTRAL, SUBLANG_DEFAULT
+#pragma code_page(1251)
+#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
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+IDD_OPT_FLTCONT DIALOGEX 0, 0, 277, 229
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD
+EXSTYLE WS_EX_CONTROLPARENT
+FONT 8, "MS Shell Dlg", 400, 0, 0xCC
+BEGIN
+ GROUPBOX "Hiding contacts",IDC_STATIC,4,4,269,52
+ CONTROL "Hide offline contacts",IDC_CHK_HIDE_OFFLINE,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,12,16,133,10
+ CONTROL "Stick together",IDC_CHK_STICK,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,12,89,95,11
+ CONTROL "Use fixed width",IDC_CHK_WIDTH,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,12,74,62,12
+ EDITTEXT IDC_TXT_WIDTH,77,74,30,12,ES_RIGHT | ES_AUTOHSCROLL |
+ ES_NUMBER
+ CONTROL "",IDC_WIDTHSPIN,"msctls_updown32",UDS_SETBUDDYINT |
+ UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS |
+ UDS_NOTHOUSANDS | UDS_HOTTRACK,96,73,11,14
+ LTEXT "pixels",IDC_LBL_WIDTH,111,75,27,8
+ CONTROL "Hide all contacts",IDC_CHK_HIDE_ALL,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,151,14,115,13
+ CONTROL "Hide when a fulscreen app is active",
+ IDC_CHK_HIDE_WHEN_FULSCREEN,"Button",BS_AUTOCHECKBOX |
+ BS_MULTILINE | WS_TABSTOP,12,28,137,22
+ CONTROL "Show tooltips",IDC_CHK_TIP,"Button",BS_AUTOCHECKBOX |
+ BS_MULTILINE | WS_TABSTOP,152,72,60,14
+ EDITTEXT IDC_TXT_TIMEIN,214,73,35,12,ES_RIGHT | ES_AUTOHSCROLL |
+ ES_NUMBER
+ CONTROL "",IDC_TIMEINSPIN,"msctls_updown32",UDS_SETBUDDYINT |
+ UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS |
+ UDS_NOTHOUSANDS | UDS_HOTTRACK,242,72,11,14
+ LTEXT "ms",IDC_LBL_TIMEIN,256,75,10,8
+ GROUPBOX "Tooltips",IDC_STATIC,142,62,131,58
+ GROUPBOX "Miscellaneous",IDC_STATIC,4,62,132,58
+ LTEXT "0 = Default",IDC_LBL_TIMEIN_CMT,217,89,51,8
+ LTEXT "requires mToolTip or Tipper plugin",IDC_STATIC,153,88,
+ 56,27
+ GROUPBOX "Bring to front",IDC_STATIC,4,126,132,40
+ CONTROL "Bring to front every",IDC_CHK_TOTOP,"Button",
+ BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,12,135,56,28
+ EDITTEXT IDC_TXT_TOTOPTIME,68,142,30,12,ES_RIGHT | ES_AUTOHSCROLL |
+ ES_NUMBER
+ CONTROL "",IDC_TOTOPTIMESPIN,"msctls_updown32",UDS_SETBUDDYINT |
+ UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS |
+ UDS_NOTHOUSANDS | UDS_HOTTRACK,85,141,11,14
+ LTEXT "seconds",IDC_LBL_TOTOP,100,144,34,8
+ CONTROL "Hide when contact list is shown",
+ IDC_CHK_HIDE_WHEN_CLISTSHOW,"Button",BS_AUTOCHECKBOX |
+ BS_MULTILINE | WS_TABSTOP,152,28,114,22
+ CONTROL "Single click interface",IDC_CHK_SINGLECLK,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,12,103,120,10
+ CONTROL "Dim idle contacts",IDC_CHK_SHOWIDLE,"Button",
+ BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,152,138,116,
+ 20
+END
+
+IDD_OPT_SKIN DIALOGEX 0, 0, 277, 229
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD
+EXSTYLE WS_EX_CONTROLPARENT
+FONT 8, "MS Shell Dlg", 400, 0, 0xCC
+BEGIN
+ GROUPBOX "Fonts",IDC_STATIC,4,2,269,113
+ COMBOBOX IDC_FONTID,12,15,253,87,CBS_DROPDOWNLIST | WS_VSCROLL |
+ WS_TABSTOP
+ LTEXT "same",IDC_STSAMETEXT,19,29,45,10,SS_CENTERIMAGE
+ CONTROL "Typeface",IDC_SAMETYPE,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,64,29,52,10
+ CONTROL "Size",IDC_SAMESIZE,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,117,29,45,10
+ CONTROL "Style",IDC_SAMESTYLE,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,163,29,48,10
+ CONTROL "Colour",IDC_SAMECOLOUR,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,212,29,53,10
+ LTEXT "as:",IDC_STASTEXT,19,45,45,10,SS_CENTERIMAGE
+ COMBOBOX IDC_SAMEAS,64,42,201,88,CBS_DROPDOWNLIST | WS_VSCROLL |
+ WS_TABSTOP
+ CONTROL "",IDC_STHORZBAR,"Static",SS_ETCHEDHORZ,9,59,256,1
+ COMBOBOX IDC_TYPEFACE,12,64,136,182,CBS_DROPDOWN | CBS_SORT |
+ WS_VSCROLL | WS_TABSTOP
+ COMBOBOX IDC_SCRIPT,156,64,60,68,CBS_DROPDOWNLIST | WS_VSCROLL |
+ WS_TABSTOP
+ COMBOBOX IDC_FONTSIZE,226,64,40,69,CBS_DROPDOWN | WS_VSCROLL |
+ WS_TABSTOP
+ CONTROL "Bold",IDC_BOLD,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,
+ 78,45,10
+ CONTROL "Italic",IDC_ITALIC,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,65,78,52,10
+ CONTROL "Underline",IDC_UNDERLINE,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,117,78,66,10
+ CONTROL "",IDC_COLOUR,"ColourPicker",WS_TABSTOP,206,80,59,11
+ EDITTEXT IDC_SAMPLE,63,94,151,16,ES_CENTER | ES_READONLY | NOT
+ WS_TABSTOP
+ CONTROL "Slider1",IDC_SLIDER_OPACITY,"msctls_trackbar32",TBS_TOP |
+ TBS_NOTICKS | WS_TABSTOP,178,162,67,16
+ CTEXT "100 %",IDC_OPACITY,245,166,25,8
+ GROUPBOX "Border",IDC_STATIC,4,116,269,38
+ CONTROL "Draw border",IDC_DRAWBORDER,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,11,126,81,10
+ LTEXT "Left-top edges color:",IDC_STATIC,11,139,76,8,NOT
+ WS_GROUP
+ CONTROL "",IDC_LTEDGESCOLOR,"ColourPicker",WS_TABSTOP,87,138,32,
+ 10
+ LTEXT "Right-bottom eges color:",IDC_STATIC,128,139,87,8,NOT
+ WS_GROUP
+ CONTROL "",IDC_RBEDGESCOLOR,"ColourPicker",WS_TABSTOP,217,138,32,
+ 10
+ GROUPBOX "Background",IDC_STATIC,4,156,269,70
+ LTEXT "Background colour:",IDC_STATIC,13,166,72,8,NOT WS_GROUP
+ CONTROL "",IDC_BKGCOLOUR,"ColourPicker",WS_TABSTOP,87,166,32,10
+ CONTROL "Use background bitmap",IDC_BITMAP,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,13,179,115,10
+ EDITTEXT IDC_FILENAME,131,179,111,12,ES_AUTOHSCROLL
+ PUSHBUTTON "...",IDC_BROWSE,245,179,15,11
+ CONTROL "Stretch to width",IDC_STRETCHH,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,13,201,100,10
+ CONTROL "Stretch to height",IDC_STRETCHV,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,131,201,101,10
+ CONTROL "Tile horizontally",IDC_TILEH,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,13,212,102,10
+ CONTROL "Tile vertically",IDC_TILEV,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,131,212,101,10
+ CONTROL "Stretch proportionally",IDC_PROPORTIONAL,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,13,190,101,10
+ LTEXT "Opacity:",IDC_STATIC,129,166,52,8
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// DESIGNINFO
+//
+
+#ifdef APSTUDIO_INVOKED
+GUIDELINES DESIGNINFO
+BEGIN
+ IDD_OPT_FLTCONT, DIALOG
+ BEGIN
+ LEFTMARGIN, 4
+ RIGHTMARGIN, 273
+ VERTGUIDE, 12
+ VERTGUIDE, 22
+ TOPMARGIN, 4
+ BOTTOMMARGIN, 225
+ HORZGUIDE, 18
+ END
+
+ IDD_OPT_SKIN, DIALOG
+ BEGIN
+ BOTTOMMARGIN, 226
+ END
+END
+#endif // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Icon
+//
+
+// Icon with lowest ID value placed first to ensure application icon
+// remains consistent on all systems.
+IDI_HIDE ICON "hide.ico"
+IDI_SHOW ICON "show.ico"
+
+#endif // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
diff --git a/plugins/FloatingContacts/fltcont.h b/plugins/FloatingContacts/fltcont.h
new file mode 100644
index 0000000000..3d725d71bc
--- /dev/null
+++ b/plugins/FloatingContacts/fltcont.h
@@ -0,0 +1,191 @@
+
+#ifndef __FLTCONT_H__
+#define __FLTCONT_H__
+
+#if _MSC_VER >= 1000
+#pragma once
+#endif // _MSC_VER >= 1000
+
+/////////////////////////////////////////////////////////////////////////////
+//
+
+#define WND_CLASS _T("MirandaThumbsWnd")
+#define WM_REFRESH_CONTACT WM_USER + 0x100
+
+#ifndef WS_EX_LAYERED
+ #define WS_EX_LAYERED 0x00080000
+#endif
+
+#ifndef LWA_ALPHA
+ #define LWA_ALPHA 0x00000002
+#endif
+
+#ifndef ULW_ALPHA
+ #define ULW_ALPHA 0x00000002
+#endif
+
+#define TIMERID_SELECT_T 1
+#define TIMERID_HOVER_T 2
+#define TIMERID_TOTOP_T 3
+#define TIMERID_LEAVE_T 4
+
+
+#if WINVER < 0x0500
+ #define SM_XVIRTUALSCREEN 76
+ #define SM_YVIRTUALSCREEN 77
+ #define SM_CXVIRTUALSCREEN 78
+ #define SM_CYVIRTUALSCREEN 79
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+//
+
+enum
+{
+ FLT_FONTID_CONTACTS,
+ FLT_FONTID_INVIS,
+ FLT_FONTID_OFFLINE,
+ FLT_FONTID_OFFINVIS,
+ FLT_FONTID_NOTONLIST,
+ FLT_FONTIDS,
+};
+
+#define DBFONTF_BOLD 1
+#define DBFONTF_ITALIC 2
+#define DBFONTF_UNDERLINE 4
+
+/////////////////////////////////////////////////////////////////////////////
+//
+
+#define FLT_DEFAULT_DRAWBORDER TRUE
+#define FLT_DEFAULT_LTEDGESCOLOR GetSysColor(COLOR_3DHILIGHT)
+#define FLT_DEFAULT_RBEDGESCOLOR GetSysColor(COLOR_3DDKSHADOW)
+#define FLT_DEFAULT_BKGNDCOLOR GetSysColor(COLOR_3DFACE)
+#define FLT_DEFAULT_BKGNDUSEBITMAP FALSE
+#define FLT_DEFAULT_BKGNDBITMAPOPT CLB_STRETCH
+
+/////////////////////////////////////////////////////////////////////////////
+//
+
+#define sModule "FloatingContacts"
+
+#define TOTOPTIME_P 1000
+#define TOTOPTIME_MAX (15*(60000/TOTOPTIME_P))
+#define TOTOPTIME_DEF (3*(60000/TOTOPTIME_P))
+
+#define MAXRCOOR 32767.0
+#define DB_POS_GETX(pos) (short)(((float)(short)(LOWORD(pos))*(float)GetSystemMetrics(SM_CXSCREEN))/MAXRCOOR+0.5)
+#define DB_POS_GETY(pos) (short)(((float)(short)(HIWORD(pos))*(float)GetSystemMetrics(SM_CYSCREEN))/MAXRCOOR+0.5)
+#define DB_POS_MAKE_XY(x, y) MAKELONG((short)(((float)x*MAXRCOOR)/(float)GetSystemMetrics(SM_CXSCREEN)+0.5), (short)(((float)y*MAXRCOOR)/(float)GetSystemMetrics(SM_CYSCREEN)+0.5))
+
+extern HINSTANCE hInst;
+extern BOOL bNT;
+//extern BOOL bHideOffline;
+//extern BOOL bHideAll;
+//extern BOOL bHideWhenFullscreen;
+//extern BOOL bMoveTogether;
+//extern BOOL bFixedWidth;
+//extern int nThumbWidth;
+//extern BYTE thumbAlpha;
+//extern BOOL bShowTip;
+extern BOOL bEnableTip;
+//extern WORD TimeIn;
+//extern BOOL bToTop;
+//extern WORD ToTopTime;
+//extern BOOL bHideWhenCListShow;
+
+extern BOOL bIsCListShow;
+extern HWND hwndMiranda;
+extern HIMAGELIST himl;
+extern RECT rcScreen;
+
+extern HFONT hFont[FLT_FONTIDS];
+extern COLORREF tColor[FLT_FONTIDS];
+
+extern HPEN hLTEdgesPen;
+extern HPEN hRBEdgesPen;
+extern HBRUSH hBkBrush;
+extern DWORD bkColor;
+extern HBITMAP hBmpBackground;
+extern WORD nBackgroundBmpUse;
+
+
+
+typedef struct _FCOptions
+{
+ BYTE thumbAlpha;
+ BOOL bHideOffline;
+ BOOL bHideAll;
+ BOOL bHideWhenFullscreen;
+ BOOL bMoveTogether;
+ BOOL bFixedWidth;
+ int nThumbWidth;
+ BOOL bShowTip;
+ WORD TimeIn;
+ BOOL bToTop;
+ WORD ToTopTime;
+ BOOL bHideWhenCListShow;
+ BOOL bUseSingleClick;
+ BOOL bShowIdle;
+}
+FCOptions;
+
+extern FCOptions fcOpt;
+
+extern BOOL (WINAPI *pSetLayeredWindowAttributes)(HWND,COLORREF,BYTE,DWORD);
+extern BOOL (WINAPI *pUpdateLayeredWindow)
+ (HWND hwnd, HDC hdcDST, POINT *pptDst, SIZE *psize, HDC hdcSrc, POINT *pptSrc,
+ COLORREF crKey, BLENDFUNCTION *pblend, DWORD dwFlags);
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+
+static __forceinline BOOL ImageList_GetIconSize_my(HIMAGELIST himl, SIZE &sz)
+{
+ int cx, cy;
+ BOOL res = ImageList_GetIconSize(himl, &cx, &cy);
+ sz.cx = cx; sz.cy = cy;
+ return res;
+}
+
+void RegHotkey ( HANDLE hContact, HWND hwnd );
+BOOL IsStatusVisible ( int status );
+BOOL HideOnFullScreen ();
+void SendMsgDialog ( HWND hwnd, char *pText );
+void SaveContactsPos ( void );
+
+/////////////////////////////////////////////////////////////////////////////
+//
+
+void
+GetFontSetting
+ ( IN BOOL bFltContacts
+ , IN int nFontId
+ , IN LOGFONTA* lf
+ , IN COLORREF* colour
+ );
+
+void
+ApplyOptionsChanges();
+
+void
+OnStatusChanged();
+
+void
+SetThumbsOpacity
+ ( IN BYTE btAlpha
+ );
+
+int
+OnOptionsInitialize
+ ( IN WPARAM wParam
+ , IN LPARAM lParam
+ );
+
+/////////////////////////////////////////////////////////////////////////////
+
+#endif // #ifndef __FLTCONT_H__
+
+/////////////////////////////////////////////////////////////////////////////
+// End Of File fltcont.h
diff --git a/plugins/FloatingContacts/hide.ico b/plugins/FloatingContacts/hide.ico
new file mode 100644
index 0000000000..941da6aeb9
--- /dev/null
+++ b/plugins/FloatingContacts/hide.ico
Binary files differ
diff --git a/plugins/FloatingContacts/main.cpp b/plugins/FloatingContacts/main.cpp
new file mode 100644
index 0000000000..9246e6f2b2
--- /dev/null
+++ b/plugins/FloatingContacts/main.cpp
@@ -0,0 +1,1331 @@
+/*
+Miranda Floating Contacts plugin, created by Iavor Vajarov ( ivajarov@code.bg )
+http://miranda-icq.sourceforge.net/
+
+Miranda fonts and colors settings by Ranger.
+Extended bonts and backgrounds settings by Oleksiy Shurubura
+
+
+This file is placed in the public domain. Anybody is free to use or
+modify it as they wish with no restriction.
+
+This plugin has been tested to work under Windows ME, 2000 and XP.
+
+No warranty for any misbehaviour.
+*/
+
+#include "stdhdr.h"
+#include "shlwapi.h"
+
+#include "version.h"
+
+#pragma comment ( lib, "comctl32.lib" )
+#pragma comment ( lib, "shlwapi.lib" )
+
+#pragma warning ( default : 4201 )
+
+//#define DB_POS_GETX(pos) LOWORD(pos)
+//#define DB_POS_GETY(pos) HIWORD(pos)
+//#define DB_POS_MAKE_XY(x, y) MAKELONG(x, y)
+
+BOOL (WINAPI *pSetLayeredWindowAttributes)(HWND,COLORREF,BYTE,DWORD);
+BOOL (WINAPI *pUpdateLayeredWindow)
+ (HWND hwnd, HDC hdcDST, POINT *pptDst, SIZE *psize, HDC hdcSrc, POINT *pptSrc,
+ COLORREF crKey, BLENDFUNCTION *pblend, DWORD dwFlags);
+
+// Globals
+
+// TODO: move to some more approriate place, probably part of Thumbs manager
+static void LoadContacts ( void );
+static void LoadContact ( HANDLE hContact );
+
+// Internal funcs
+static void RepaintWindow ( HWND hwnd, HDC hdc );
+static void LoadMenus ();
+static void CreateThumbWnd ( TCHAR *ptszName, HANDLE hContact, int nX, int nY );
+static void RegisterWindowClass ( void );
+static void UnregisterWindowClass ( void );
+static void CleanUp ( void );
+static BOOL GetOSPlatform ( void );
+static void LoadDBSettings ( void );
+static void CreateThumbsFont ( void );
+static void CreateBackgroundBrush ( void );
+static int GetContactStatus ( HANDLE hContact );
+static void GetScreenRect ( void );
+extern void SetThumbsOpacity ( BYTE btAlpha );
+static int ClcStatusToPf2 ( int status );
+
+static LRESULT __stdcall CommWndProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam );
+static LRESULT __stdcall newMirandaWndProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam );
+
+static int OnContactDeleted ( WPARAM wParam,LPARAM lParam );
+static int OnContactIconChanged ( WPARAM wParam, LPARAM lParam );
+static int OnContactDrag ( WPARAM wParam, LPARAM lParam );
+static int OnContactDrop ( WPARAM wParam, LPARAM lParam );
+static int OnContactDragStop ( WPARAM wParam, LPARAM lParam );
+static int OnSkinIconsChanged ( WPARAM wParam, LPARAM lParam );
+static int OnContactSettingChanged ( WPARAM wParam, LPARAM lParam );
+static int OnStatusModeChange ( WPARAM wParam, LPARAM lParam );
+static int OnModulesLoded ( WPARAM wParam, LPARAM lParam );
+static int OnPrebuildContactMenu ( WPARAM wParam, LPARAM lParam );
+
+static int OnContactMenu_Remove ( WPARAM wParam,LPARAM lParam );
+//static int OnContactMenu_HideAll ( WPARAM wParam,LPARAM lParam );
+static int OnMainMenu_HideAll ( WPARAM wParam,LPARAM lParam );
+static int OnHotKey_HideWhenCListShow( WPARAM wParam,LPARAM lParam );
+static VOID CALLBACK ToTopTimerProc ( HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime);
+
+WNDPROC oldMirandaWndProc;
+
+
+HINSTANCE hInst = NULL;
+HMODULE hUserDll = NULL;
+PLUGINLINK *pluginLink = NULL;
+LIST_INTERFACE li = {0};
+HFONT hFont[FLT_FONTIDS] = {NULL};
+COLORREF tColor[FLT_FONTIDS] = {0};
+HIMAGELIST himl = NULL;
+HANDLE hevContactIcon = NULL;
+HANDLE hevContactDrop = NULL;
+HANDLE hevContactDragStop = NULL;
+HANDLE hevSkinIcons = NULL;
+HANDLE hevContactDrag = NULL;
+HANDLE hevContactSetting = NULL;
+HANDLE hevContactDeleted = NULL;
+HANDLE hevOptionsInit = NULL;
+HANDLE hevStatusMode = NULL;
+HANDLE hevModules = NULL;
+HANDLE hevPrebuildMenu = NULL;
+HANDLE hNewContact = NULL;
+
+HPEN hLTEdgesPen = NULL;
+HPEN hRBEdgesPen = NULL;
+HBRUSH hBkBrush = NULL;
+DWORD bkColor = 0;
+HBITMAP hBmpBackground = NULL;
+WORD nBackgroundBmpUse = CLB_STRETCH;
+
+HWND hwndMiranda = NULL;
+BOOL bVersionOK = FALSE;
+BOOL bNT = FALSE;
+BOOL bDockHorz = TRUE;
+//UINT nStatus = 0;
+HMENU hContactMenu = NULL;
+HANDLE hMenuItemRemove = NULL;
+HANDLE hMenuItemHideAll = NULL;
+HANDLE hMainMenuItemHideAll = NULL;
+RECT rcScreen;
+DWORD dwOfflineModes = 0;
+BOOL bEnableTip = FALSE;
+UINT_PTR ToTopTimerID = 0;
+BOOL bIsCListShow = TRUE;
+
+HANDLE hRemoveThumb = NULL;
+HANDLE hMainHideAllThumbs = NULL;
+HANDLE hHideWhenCListShow = NULL;
+
+//Options
+
+FCOptions fcOpt = {0};
+
+static void InitOptions(){
+ fcOpt.thumbAlpha = 255;
+ fcOpt.bHideOffline = FALSE;
+ fcOpt.bHideAll = FALSE;
+ fcOpt.bHideWhenFullscreen = FALSE;
+ fcOpt.bMoveTogether = FALSE;
+ fcOpt.bFixedWidth = FALSE;
+ fcOpt.nThumbWidth = 0;
+ fcOpt.bShowTip = TRUE;
+ fcOpt.TimeIn = 0;
+ fcOpt.bToTop = TRUE;
+ fcOpt.ToTopTime = TOTOPTIME_DEF;
+ fcOpt.bHideWhenCListShow = FALSE;
+ fcOpt.bUseSingleClick = FALSE;
+ fcOpt.bShowIdle = TRUE;
+}
+
+
+PLUGININFO pluginInfo ={
+ sizeof(PLUGININFO),
+ __PLUGIN_NAME,
+ 0,
+ __DESC,
+ __AUTHOR,
+ __AUTHOREMAIL,
+ __COPYRIGHT,
+ __AUTHORWEB,
+ UNICODE_AWARE,
+ 0
+};
+
+// {53C715A8-EB01-4136-A73C-441868610074}
+#define MIID_FLTCONT { 0x53c715a8, 0xeb01, 0x4136, { 0xa7, 0x3c, 0x44, 0x18, 0x68, 0x61, 0x0, 0x74 } }
+
+static const MUUID interfaces[] = {MIID_FLTCONT, MIID_LAST};
+
+extern "C" __declspec(dllexport) const MUUID * MirandaPluginInterfaces(void)
+{
+ return interfaces;
+}
+
+PLUGININFOEX pluginInfoEx ={
+ sizeof(PLUGININFOEX),
+ __PLUGIN_NAME,
+ 0,
+ __DESC,
+ __AUTHOR,
+ __AUTHOREMAIL,
+ __COPYRIGHT,
+ __AUTHORWEB,
+ UNICODE_AWARE,
+ 0,
+ MIID_FLTCONT
+};
+
+_inline unsigned int MakeVer(int a,int b,int c,int d)
+{
+ return PLUGIN_MAKE_VERSION(a,b,c,d);
+}
+
+extern "C" __declspec(dllexport) PLUGININFOEX* MirandaPluginInfoEx(DWORD mirandaVersion) {
+
+ if( mirandaVersion < MakeVer(MINIMAL_COREVERSION) ) return NULL;
+ pluginInfoEx.version=MakeVer(PRODUCT_VERSION);
+ return &pluginInfoEx;
+}
+
+
+///////////////////////////////////////////////////////
+// Load / unload
+BOOL WINAPI DllMain( HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved )
+{
+ hInst = hinstDLL;
+
+ switch ( fdwReason )
+ {
+ case DLL_PROCESS_ATTACH:
+ break;
+
+ case DLL_PROCESS_DETACH:
+ break;
+ }
+
+ return( TRUE );
+}
+
+
+
+extern "C" __declspec(dllexport) PLUGININFO* MirandaPluginInfo( DWORD mirandaVersion )
+{
+ if( mirandaVersion < MakeVer(MINIMAL_COREVERSION) ) return NULL;
+ pluginInfo.version=MakeVer(PRODUCT_VERSION);
+ return &pluginInfo;
+}
+
+
+
+extern "C" int __declspec(dllexport) Load( PLUGINLINK *link )
+{
+ SetLastError( 0 );
+ InitOptions();
+ pluginLink = link;
+
+ mir_getLI(&li);
+
+ hevModules = HookEvent( ME_SYSTEM_MODULESLOADED, OnModulesLoded );
+ bNT = GetOSPlatform();
+
+ if (hUserDll = LoadLibrary(_T("user32.dll")))
+ {
+ pSetLayeredWindowAttributes =
+ (BOOL (WINAPI *)(HWND,COLORREF,BYTE,DWORD))
+ GetProcAddress(hUserDll, "SetLayeredWindowAttributes");
+ pUpdateLayeredWindow =
+ (BOOL (WINAPI *)(HWND, HDC, POINT *, SIZE *, HDC, POINT *, COLORREF, BLENDFUNCTION *, DWORD))
+ GetProcAddress(hUserDll, "UpdateLayeredWindow");
+ } else
+ {
+ pSetLayeredWindowAttributes = NULL;
+ pUpdateLayeredWindow = NULL;
+ }
+
+ return 0;
+}
+
+
+
+extern "C" int __declspec(dllexport) Unload()
+{
+ CleanUp();
+ return 0;
+}
+
+
+
+static void CleanUp()
+{
+ int nFontId;
+
+ UnhookEvent( hevContactIcon );
+ UnhookEvent( hevContactDrag );
+ UnhookEvent( hevContactDrop );
+ UnhookEvent( hevContactDragStop );
+ UnhookEvent( hevSkinIcons );
+ UnhookEvent( hevContactDeleted );
+ UnhookEvent( hevContactSetting );
+ UnhookEvent( hevOptionsInit );
+ UnhookEvent( hevStatusMode );
+ UnhookEvent( hevModules );
+ UnhookEvent( hevPrebuildMenu );
+
+ if(hRemoveThumb)
+ DestroyServiceFunction(hRemoveThumb);
+ if(hMainHideAllThumbs)
+ DestroyServiceFunction(hMainHideAllThumbs);
+ if(hHideWhenCListShow)
+ DestroyServiceFunction(hHideWhenCListShow);
+
+// while( pThumbsList != NULL )
+// RemoveThumb( pThumbsList );
+
+ if(ServiceExists(MS_HOTKEY_UNREGISTER)){
+ CallService(MS_HOTKEY_UNREGISTER, 0, (LPARAM)(sModule "/MainHideAllThumbs"));
+ CallService(MS_HOTKEY_UNREGISTER, 0, (LPARAM)(sModule "/HideWhenCListShow"));
+ }
+
+ if (NULL != hLTEdgesPen)
+ DeleteObject(hLTEdgesPen);
+ if (NULL != hRBEdgesPen)
+ DeleteObject(hRBEdgesPen);
+ if (NULL != hBmpBackground)
+ DeleteObject(hBmpBackground);
+ if (NULL != hBkBrush)
+ {
+ SetClassLong((HWND)WND_CLASS, GCL_HBRBACKGROUND, (LONG)NULL);
+ DeleteObject(hBkBrush);
+ hBkBrush=NULL;
+ }
+
+ for (nFontId = 0; nFontId < FLT_FONTIDS; nFontId++)
+ if (NULL != hFont[nFontId])
+ DeleteObject(hFont[nFontId]);
+
+ UnregisterWindowClass();
+
+ FreeFileDropping();
+
+ if ( hUserDll != NULL )
+ {
+ FreeLibrary( hUserDll );
+ }
+}
+
+
+
+///////////////////////////////////////////////////////
+// Hooked events
+static int OnModulesLoded( WPARAM wParam, LPARAM lParam )
+{
+ hevContactIcon = HookEvent( ME_CLIST_CONTACTICONCHANGED, OnContactIconChanged );
+ hevSkinIcons = HookEvent( ME_SKIN_ICONSCHANGED, OnSkinIconsChanged );
+ hevContactDrag = HookEvent( ME_CLUI_CONTACTDRAGGING, OnContactDrag );
+ hevContactDrop = HookEvent( ME_CLUI_CONTACTDROPPED, OnContactDrop );
+ hevContactDragStop = HookEvent( ME_CLUI_CONTACTDRAGSTOP, OnContactDragStop );
+ hevContactSetting = HookEvent( ME_DB_CONTACT_SETTINGCHANGED, OnContactSettingChanged );
+ hevContactDeleted = HookEvent( ME_DB_CONTACT_DELETED, OnContactDeleted );
+ hevOptionsInit = HookEvent( ME_OPT_INITIALISE, OnOptionsInitialize );
+ hevStatusMode = HookEvent( ME_CLIST_STATUSMODECHANGE, OnStatusModeChange );
+ hevPrebuildMenu = HookEvent( ME_CLIST_PREBUILDCONTACTMENU, OnPrebuildContactMenu );
+ hwndMiranda = (HWND)CallService( MS_CLUI_GETHWND, 0, 0 );
+
+ oldMirandaWndProc = (WNDPROC)SetWindowLong( hwndMiranda, GWL_WNDPROC, (LONG)newMirandaWndProc);
+
+
+
+ // No thumbs yet
+// pThumbsList = NULL;
+ bEnableTip = ServiceExists("mToolTip/ShowTip");
+
+ RegisterWindowClass();
+ InitFileDropping();
+ GetScreenRect();
+ LoadDBSettings();
+ CreateBackgroundBrush();
+ CreateThumbsFont();
+ LoadContacts();
+ LoadMenus();
+
+ if(fcOpt.bToTop){
+ fcOpt.ToTopTime = (fcOpt.ToTopTime<1)?1:fcOpt.ToTopTime;
+ fcOpt.ToTopTime = (fcOpt.ToTopTime>TOTOPTIME_MAX)?TOTOPTIME_MAX:fcOpt.ToTopTime;
+ ToTopTimerID=SetTimer(NULL, 0, fcOpt.ToTopTime*TOTOPTIME_P, ToTopTimerProc);
+ }
+ return( 0 );
+}
+
+
+static int OnContactDeleted( WPARAM wParam, LPARAM lParam )
+{
+ HANDLE hContact = ( HANDLE )wParam;
+ ThumbInfo *pThumb = thumbList.FindThumbByContact( hContact );
+ if (!pThumb) return 0;
+
+ pThumb->DeleteContactPos();
+ thumbList.RemoveThumb(pThumb);
+
+ return 0;
+}
+
+
+static int OnContactIconChanged( WPARAM wParam, LPARAM lParam )
+{
+ HANDLE hContact = ( HANDLE )wParam;
+ ThumbInfo *pThumb = thumbList.FindThumbByContact( hContact );
+
+ if ( pThumb )
+ {
+ pThumb->RefreshContactIcon( ( int )lParam );
+ //pThumb->ThumbSelect( FALSE );
+ //SetTimer( pThumb->hwnd, TIMERID_SELECT_T, 1000, NULL );
+ }
+
+ return 0;
+}
+
+
+static int OnContactDrag( WPARAM wParam, LPARAM lParam )
+{
+ ThumbInfo *pNewThumb = NULL;
+ HANDLE hContact = ( HANDLE )wParam;
+ ThumbInfo *pThumb = thumbList.FindThumbByContact( hContact );
+ TCHAR *ptName = (TCHAR*)CallService( MS_CLIST_GETCONTACTDISPLAYNAME, wParam, (LPARAM)GCDNF_TCHAR );
+ int idStatus = ID_STATUS_OFFLINE;
+ POINT pt;
+ GetCursorPos(&pt);
+
+ if ( pThumb == NULL )
+ {
+ idStatus = GetContactStatus( hContact );
+
+ if ( !fcOpt.bHideAll && !HideOnFullScreen() && ( !fcOpt.bHideOffline || IsStatusVisible( idStatus ) ) && (!fcOpt.bHideWhenCListShow || !bIsCListShow) )
+ {
+// CreateThumbWnd( pName, hContact, LOWORD( lParam ), HIWORD( lParam ) );
+ CreateThumbWnd( ptName, hContact, pt.x, pt.y );
+ pNewThumb = thumbList.FindThumbByContact( hContact );
+ ShowWindow( pNewThumb->hwnd, SW_SHOWNA );
+ hNewContact = hContact;
+
+ OnStatusChanged();
+ }
+ }
+ else if ( hContact == hNewContact )
+ {
+// PositionThumb( pThumb, (short)( LOWORD( lParam ) - 5 ), (short)( HIWORD( lParam ) - 5 ) );
+ pThumb->PositionThumb( (short)( pt.x - 5 ), (short)( pt.y - 5 ) );
+ }
+
+ return( hNewContact != NULL ? 1 : 0 );
+}
+
+
+
+static int OnContactDrop( WPARAM wParam, LPARAM lParam )
+{
+ RECT rcMiranda;
+ RECT rcThumb;
+// RECT rcOverlap;
+
+ HANDLE hContact = ( HANDLE )wParam;
+ ThumbInfo *pThumb = thumbList.FindThumbByContact( hContact );
+
+ if ( ( hNewContact == hContact ) && ( pThumb != NULL ) )
+ {
+ hNewContact = NULL;
+
+ GetWindowRect( hwndMiranda, &rcMiranda );
+ pThumb->GetThumbRect( &rcThumb );
+
+ //if ( IntersectRect( &rcOverlap, &rcThumb, &rcMiranda ) )
+ //{
+ // pThumb->OnLButtonDown( (short)(rcThumb.left + 5), (short)(rcThumb.top + 5) );
+ //}
+ }
+
+ SaveContactsPos();
+
+ return( 1 );
+}
+
+
+static int OnContactDragStop( WPARAM wParam, LPARAM lParam )
+{
+ HANDLE hContact = ( HANDLE )wParam;
+ ThumbInfo *pThumb = thumbList.FindThumbByContact( hContact );
+
+ if ( ( pThumb != NULL ) && ( hNewContact == hContact ) )
+ {
+ thumbList.RemoveThumb( pThumb );
+ hNewContact = NULL;
+ }
+
+ return( 0 );
+}
+
+
+static int OnSkinIconsChanged( WPARAM wParam, LPARAM lParam )
+{
+ // Get handle to the image list
+ himl = ( HIMAGELIST )CallService( MS_CLIST_GETICONSIMAGELIST, 0, 0 );
+
+ // Update thumbs
+ for (int i = 0; i < thumbList.getCount(); ++i)
+ thumbList[i]->UpdateContent();
+
+ return( 0 );
+}
+
+
+
+static int OnContactSettingChanged( WPARAM wParam, LPARAM lParam )
+{
+ HANDLE hContact = ( HANDLE )wParam;
+ ThumbInfo *pThumb = thumbList.FindThumbByContact( hContact );
+ int idStatus = ID_STATUS_OFFLINE;
+ BOOL bRefresh = TRUE;
+ DBCONTACTWRITESETTING* pdbcws = ( DBCONTACTWRITESETTING* )lParam;
+
+
+ if ( hContact == NULL )
+ {
+ if(( 0 == stricmp( pdbcws->szModule, "CLC" ) ) || ( 0 == stricmp( pdbcws->szModule, sModule ) ) ){
+ LoadDBSettings();
+ ApplyOptionsChanges();
+ }
+
+ return( 0 );
+ }
+
+ if ( pThumb == NULL ) return( 0 );
+
+ // Only on these 2 events we need to refresh
+ if( 0 == stricmp( pdbcws->szSetting, "Status" ) )
+ {
+ idStatus = pdbcws->value.wVal;
+ }
+ else if ( 0 == stricmp( pdbcws->szSetting, "Nick" ) )
+ {
+ idStatus = GetContactStatus( hContact );
+ }
+ else if ( 0 == stricmp( pdbcws->szSetting, "MyHandle" ) )
+ {
+ idStatus = GetContactStatus( hContact );
+ }
+ else if ( fcOpt.bShowIdle && 0 == stricmp( pdbcws->szSetting, "IdleTS" ))
+ {
+ idStatus = GetContactStatus( hContact );
+ }
+ else
+ {
+ bRefresh = FALSE;
+ }
+
+ if ( bRefresh )
+ {
+ // Detach call
+ PostMessage( pThumb->hwnd, WM_REFRESH_CONTACT, 0, idStatus );
+ }
+
+ return( 0 );
+}
+
+
+static int OnStatusModeChange( WPARAM wParam, LPARAM lParam )
+{
+ int idStatus;
+
+ //nStatus = (int)wParam;
+
+ for (int i = 0; i < thumbList.getCount(); ++i)
+ {
+ idStatus = GetContactStatus( thumbList[i]->hContact );
+ thumbList[i]->RefreshContactStatus( idStatus );
+ }
+ if ( wParam == ID_STATUS_OFFLINE )
+ {
+ // Floating status window will use this
+ }
+
+ return( 0 );
+}
+
+
+
+static int OnPrebuildContactMenu( WPARAM wParam, LPARAM lParam )
+{
+ ThumbInfo *pThumb = thumbList.FindThumbByContact( (HANDLE) wParam );
+ CLISTMENUITEM clmi;
+
+ ZeroMemory( &clmi, sizeof( clmi ) );
+ clmi.cbSize = sizeof( clmi );
+
+ clmi.flags = ( pThumb == NULL ) ? CMIM_FLAGS | CMIF_HIDDEN : CMIM_FLAGS &~CMIF_HIDDEN;
+ CallService( MS_CLIST_MODIFYMENUITEM, (WPARAM)hMenuItemRemove, (LPARAM)&clmi );
+
+ clmi.flags = fcOpt.bHideAll ? CMIM_FLAGS | CMIF_HIDDEN : CMIM_FLAGS &~CMIF_HIDDEN;
+ CallService( MS_CLIST_MODIFYMENUITEM, (WPARAM)hMenuItemHideAll, (LPARAM)&clmi );
+
+ return( 0 );
+}
+
+
+
+
+///////////////////////////////////////////////////////
+// General functions
+
+static void LoadDBSettings()
+{
+ fcOpt.thumbAlpha = (BYTE)((double)DBGetContactSettingByte( NULL, sModule, "Opacity", 100 ) * 2.55 );
+ fcOpt.bHideOffline = (BOOL)DBGetContactSettingByte( NULL, sModule, "HideOffline", 0 );
+ fcOpt.bHideAll = (BOOL)DBGetContactSettingByte( NULL, sModule, "HideAll", 0 );
+ fcOpt.bHideWhenFullscreen = (BOOL)DBGetContactSettingByte( NULL, sModule, "HideWhenFullscreen", 0 );
+ fcOpt.bMoveTogether = (BOOL)DBGetContactSettingByte( NULL, sModule, "MoveTogether", 0 );
+ fcOpt.bFixedWidth = (BOOL)DBGetContactSettingByte( NULL, sModule, "FixedWidth", 0 );
+ fcOpt.nThumbWidth = (DWORD)DBGetContactSettingDword( NULL, sModule, "Width", 0 );
+ dwOfflineModes = DBGetContactSettingDword( NULL, "CLC","OfflineModes", CLCDEFAULT_OFFLINEMODES );
+ fcOpt.bShowTip = (BOOL)DBGetContactSettingByte( NULL, sModule, "ShowTip", 1 );
+ fcOpt.TimeIn = (WORD)DBGetContactSettingWord( NULL, sModule, "TimeIn", 0 );
+ fcOpt.bToTop = (BOOL)DBGetContactSettingByte( NULL, sModule, "ToTop", 0 );
+ fcOpt.ToTopTime = (WORD)DBGetContactSettingWord( NULL, sModule, "ToTopTime", TOTOPTIME_DEF );
+ fcOpt.bHideWhenCListShow = (BOOL)DBGetContactSettingByte( NULL, sModule, "HideWhenCListShow", 0 );
+ fcOpt.bUseSingleClick = (BOOL)DBGetContactSettingByte( NULL, sModule, "UseSingleClick", 0 );
+ fcOpt.bShowIdle = (BOOL)DBGetContactSettingByte( NULL, sModule, "ShowIdle", 0 );
+
+ if(DBGetContactSettingByte(NULL, "ModernData", "HideBehind", 0))
+ bIsCListShow = (DBGetContactSettingByte(NULL, "ModernData", "BehindEdge", 0)==0);
+ else
+ bIsCListShow = (DBGetContactSettingByte(NULL,"CList","State",0)==2);
+}
+
+void SendMsgDialog( HWND hwnd, char *pText )
+{
+ ThumbInfo *pThumb = thumbList.FindThumb( hwnd );
+
+ if ( pThumb != NULL )
+ CallService( MS_MSG_SENDMESSAGE, (WPARAM)pThumb->hContact, (LPARAM)pText );
+}
+
+
+static void ShowContactMenu( HWND hwnd, POINT pt )
+{
+ ThumbInfo *pThumb = thumbList.FindThumb( hwnd );
+ int idCommand = 0;
+
+ if ( pThumb != NULL )
+ {
+ hContactMenu = (HMENU)CallService( MS_CLIST_MENUBUILDCONTACT, (WPARAM)pThumb->hContact, (LPARAM)0 );
+
+ if ( hContactMenu == NULL ) return;
+
+ idCommand = TrackPopupMenu( hContactMenu, TPM_RIGHTALIGN | TPM_TOPALIGN | TPM_RETURNCMD, pt.x, pt.y, 0 , hwnd, NULL );
+ CallService( MS_CLIST_MENUPROCESSCOMMAND, MAKEWPARAM( idCommand ,MPCF_CONTACTMENU), (LPARAM)pThumb->hContact );
+ }
+}
+
+static LRESULT __stdcall CommWndProc( HWND hwnd,
+ UINT uMsg,
+ WPARAM wParam,
+ LPARAM lParam )
+{
+ LRESULT lResult = 0;
+ ThumbInfo *pThumb = thumbList.FindThumb( hwnd );
+
+ switch( uMsg )
+ {
+ case WM_RBUTTONUP:
+ {
+ POINT pt;
+ pt.x = LOWORD( lParam );
+ pt.y = HIWORD( lParam );
+
+ if (pThumb) pThumb->ThumbDeselect( TRUE );
+
+ ClientToScreen(hwnd,&pt);
+ ShowContactMenu( hwnd, pt );
+ }
+
+ break;
+
+//#if 0
+ case WM_NCPAINT:
+ if(pThumb){
+ HDC hdc = GetWindowDC( hwnd );
+ BitBlt(hdc, 0, 0, pThumb->bmpContent.getWidth(), pThumb->bmpContent.getHeight(), pThumb->bmpContent.getDC(), 0, 0, SRCCOPY);
+ //RepaintWindow( hwnd, hdc );
+ ReleaseDC( hwnd, hdc );
+ ValidateRect( hwnd, NULL );
+ return 0;
+ }
+
+ case WM_PAINT:
+ if(pThumb){
+ PAINTSTRUCT ps;
+ HDC hdc = BeginPaint(hwnd, &ps);
+ BitBlt(hdc, 0, 0, pThumb->bmpContent.getWidth(), pThumb->bmpContent.getHeight(), pThumb->bmpContent.getDC(), 0, 0, SRCCOPY);
+ //RepaintWindow( hwnd, hdc );
+ EndPaint(hwnd, &ps);
+ break;
+ }
+
+ case WM_PRINT:
+ case WM_PRINTCLIENT:
+ if(pThumb){
+ BitBlt((HDC)wParam, 0, 0, pThumb->bmpContent.getWidth(), pThumb->bmpContent.getHeight(), pThumb->bmpContent.getDC(), 0, 0, SRCCOPY);
+ //RepaintWindow(hwnd, (HDC)wParam);
+ break;
+ }
+//#endif
+
+ case WM_MEASUREITEM:
+ lResult = CallService( MS_CLIST_MENUMEASUREITEM,wParam,lParam );
+ break;
+
+ case WM_DRAWITEM:
+ lResult = CallService( MS_CLIST_MENUDRAWITEM,wParam,lParam );
+ break;
+
+ case WM_LBUTTONDOWN:
+ if (pThumb) pThumb->OnLButtonDown( (short)LOWORD( lParam ), (short)HIWORD( lParam ) );
+ break;
+
+ case WM_MOUSEMOVE:
+ if (pThumb) pThumb->OnMouseMove( (short)LOWORD( lParam ), (short)HIWORD( lParam ), wParam);
+ break;
+
+ case WM_LBUTTONUP:
+ if (pThumb) pThumb->OnLButtonUp();
+ //if (bMouseMoved || !DBGetContactSettingByte(NULL, "CList", "Tray1Click", SETTING_TRAY1CLICK_DEFAULT))
+ break;
+ // FALL THRU
+
+ case WM_LBUTTONDBLCLK:
+ // Popup message dialog
+ //if (pThumb) pThumb->ThumbDeselect( TRUE );
+ if(!fcOpt.bUseSingleClick && pThumb)
+ pThumb->PopUpMessageDialog();
+ break;
+
+ case WM_RBUTTONDOWN:
+ if(bEnableTip && fcOpt.bShowTip && pThumb) pThumb->KillTip();
+ break;
+ case WM_REFRESH_CONTACT:
+ if (pThumb)
+ {
+ _tcsncpy( pThumb->ptszName, (TCHAR*)CallService( MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)pThumb->hContact, (LPARAM)GCDNF_TCHAR ), USERNAME_LEN - 1 );
+ pThumb->RefreshContactStatus( (int)lParam );
+ pThumb->ResizeThumb();
+ }
+ break;
+
+ case WM_TIMER:
+ if(pThumb)pThumb->OnTimer(wParam);
+ break;
+
+ case WM_HOTKEY:
+ {
+ ThumbInfo *pThumb = thumbList.FindThumb( ( HWND )wParam );
+
+ if (pThumb) pThumb->PopUpMessageDialog();
+ }
+
+ default:
+ break;
+ }
+
+ lResult = DefWindowProc( hwnd, uMsg, wParam, lParam );
+
+ return( lResult );
+}
+
+
+
+extern void SetThumbsOpacity( BYTE btAlpha )
+{
+ for (int i = 0; i < thumbList.getCount(); ++i)
+ thumbList[i]->SetThumbOpacity( btAlpha );
+}
+
+
+
+static void GetScreenRect()
+{
+ rcScreen.left = GetSystemMetrics( SM_XVIRTUALSCREEN );
+ rcScreen.top = GetSystemMetrics( SM_YVIRTUALSCREEN );
+ rcScreen.right = GetSystemMetrics( SM_CXVIRTUALSCREEN ) + rcScreen.left;
+ rcScreen.bottom = GetSystemMetrics( SM_CYVIRTUALSCREEN ) + rcScreen.top;
+}
+
+
+
+void OnStatusChanged()
+{
+ int idStatus = ID_STATUS_OFFLINE;
+
+ for (int i = 0; i < thumbList.getCount(); ++i)
+ {
+ idStatus = GetContactStatus( thumbList[i]->hContact );
+ thumbList[i]->RefreshContactStatus( idStatus );
+ }
+}
+
+
+
+void ApplyOptionsChanges()
+{
+ CreateThumbsFont();
+ CreateBackgroundBrush();
+
+// dwOfflineModes = DBGetContactSettingDword( NULL, "CLC","OfflineModes", CLCDEFAULT_OFFLINEMODES );
+ if(!fcOpt.bToTop && ToTopTimerID){
+ KillTimer(NULL, ToTopTimerID);
+ ToTopTimerID = 0;
+ }
+ if(fcOpt.bToTop){
+ if (ToTopTimerID) KillTimer(NULL, ToTopTimerID);
+ fcOpt.ToTopTime = (fcOpt.ToTopTime<1)?1:fcOpt.ToTopTime;
+ fcOpt.ToTopTime = (fcOpt.ToTopTime>TOTOPTIME_MAX)?TOTOPTIME_MAX:fcOpt.ToTopTime;
+ ToTopTimerID = SetTimer(NULL, 0, fcOpt.ToTopTime*TOTOPTIME_P, ToTopTimerProc);
+ }
+
+ OnStatusChanged();
+
+ for (int i = 0; i < thumbList.getCount(); ++i)
+ thumbList[i]->ResizeThumb();
+}
+
+
+
+///////////////////////////////////////////////////////
+// Window creation
+static void RegisterWindowClass()
+{
+ WNDCLASSEX wcx;
+ ZeroMemory( &wcx, sizeof( wcx ) );
+
+ wcx.cbSize = sizeof( WNDCLASSEX );
+ wcx.style = CS_VREDRAW | CS_HREDRAW | CS_DBLCLKS;
+ wcx.lpfnWndProc = CommWndProc;
+ wcx.cbClsExtra = 0;
+ wcx.cbWndExtra = 0;
+ wcx.hInstance = hInst;
+ wcx.hIcon = NULL;
+ wcx.hCursor = NULL;
+ wcx.hbrBackground = GetSysColorBrush(COLOR_3DFACE);
+ wcx.lpszMenuName = NULL;
+ wcx.lpszClassName = WND_CLASS;
+ wcx.hIconSm = NULL;
+
+ SetLastError( 0 );
+
+ RegisterClassEx( &wcx );
+}
+
+
+
+static void UnregisterWindowClass()
+{
+ UnregisterClass( WND_CLASS, hInst );
+}
+
+
+
+static void CreateThumbWnd( TCHAR *ptszName, HANDLE hContact, int nX, int nY )
+{
+ HWND hwnd = NULL;
+ ThumbInfo *pThumb = thumbList.FindThumbByContact( hContact );
+
+ // Prepare for window creation
+ if ( pThumb == NULL )
+ {
+ hwnd = CreateWindowEx( WS_EX_TOOLWINDOW | WS_EX_TOPMOST,
+ WND_CLASS,
+ ptszName,
+ WS_POPUP,
+ nX,
+ nY,
+ 50,
+ 20,
+ NULL /*hwndMiranda*/,
+ NULL,
+ hInst,
+ NULL
+ );
+
+ if ( hwnd != NULL )
+ {
+ pThumb = thumbList.AddThumb( hwnd, ptszName, hContact );
+ SetWindowLong( hwnd, GWL_USERDATA, (long)pThumb );
+ pThumb->ResizeThumb();
+
+ pThumb->SetThumbOpacity( fcOpt.thumbAlpha );
+ ShowWindow( hwnd, ( fcOpt.bHideAll || HideOnFullScreen() || fcOpt.bHideOffline || (fcOpt.bHideWhenCListShow && bIsCListShow) )? SW_HIDE : SW_SHOWNA );
+ pThumb->PositionThumb( (short)nX, (short)nY );
+
+ // force repaint
+ pThumb->UpdateContent();
+ }
+ }
+}
+
+
+
+static BOOL GetOSPlatform()
+{
+ OSVERSIONINFO VersionInfo;
+
+ // Get OS platform
+ ZeroMemory( &VersionInfo, sizeof( VersionInfo ) );
+ VersionInfo.dwOSVersionInfoSize = sizeof( VersionInfo );
+
+ GetVersionEx( &VersionInfo );
+ return( VersionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT );
+}
+
+
+
+static void CreateThumbsFont()
+{
+ int nFontId;
+ LOGFONTA lf;
+
+ for (nFontId = 0; nFontId < FLT_FONTIDS; nFontId++)
+ {
+ if (NULL != hFont[nFontId])
+ {
+ DeleteObject(hFont[nFontId]);
+ hFont[nFontId] = NULL;
+ }
+ GetFontSetting(TRUE, nFontId, &lf, &tColor[nFontId]);
+ {
+ LONG height;
+ HDC hdc=GetDC(NULL);
+ height=lf.lfHeight;
+ lf.lfHeight=-MulDiv(lf.lfHeight, GetDeviceCaps(hdc, LOGPIXELSY), 72);
+ ReleaseDC(NULL,hdc);
+
+ hFont[nFontId] = CreateFontIndirectA(&lf);
+
+ lf.lfHeight=height;
+ }
+ }
+}
+
+
+
+static void CreateBackgroundBrush()
+{
+// LOGBRUSH lb;
+ bkColor = DBGetContactSettingDword(NULL, sModule, "BkColor", FLT_DEFAULT_BKGNDCOLOR);
+
+
+ if (NULL != hLTEdgesPen)
+ {
+ DeleteObject(hLTEdgesPen);
+ hLTEdgesPen = NULL;
+ }
+ if (NULL != hRBEdgesPen)
+ {
+ DeleteObject(hRBEdgesPen);
+ hRBEdgesPen = NULL;
+ }
+ if (NULL != hBmpBackground)
+ {
+ DeleteObject(hBmpBackground);
+ hBmpBackground = NULL;
+ }
+ if (NULL != hBkBrush)
+ {
+ SetClassLong((HWND)WND_CLASS, GCL_HBRBACKGROUND, (LONG)NULL);
+ DeleteObject( hBkBrush );
+ hBkBrush = NULL;
+ }
+
+ if (DBGetContactSettingByte(NULL, sModule, "DrawBorder", FLT_DEFAULT_DRAWBORDER))
+ {
+ COLORREF cr;
+
+ cr = (COLORREF)DBGetContactSettingDword(NULL, sModule, "LTEdgesColor", FLT_DEFAULT_LTEDGESCOLOR);
+ hLTEdgesPen = CreatePen(PS_SOLID, 1, cr);
+ cr = (COLORREF)DBGetContactSettingDword(NULL, sModule, "RBEdgesColor", FLT_DEFAULT_RBEDGESCOLOR);
+ hRBEdgesPen = CreatePen(PS_SOLID, 1, cr);
+ }
+ if (DBGetContactSettingByte(NULL, sModule, "BkUseBitmap", FLT_DEFAULT_BKGNDUSEBITMAP))
+ {
+ DBVARIANT dbv;
+
+ if (!DBGetContactSetting(NULL, sModule, "BkBitmap", &dbv))
+ {
+ hBmpBackground = (HBITMAP)CallService(MS_UTILS_LOADBITMAP, 0, (LPARAM)dbv.pszVal);
+ DBFreeVariant(&dbv);
+ }
+ }
+ nBackgroundBmpUse = (WORD)DBGetContactSettingWord(NULL, sModule, "BkBitmapOpt", FLT_DEFAULT_BKGNDBITMAPOPT);
+
+ // Create brush
+ hBkBrush = CreateSolidBrush(bkColor);
+
+ // Attach brush to the window
+ SetClassLong((HWND)WND_CLASS, GCL_HBRBACKGROUND, (LONG)hBkBrush);
+}
+
+
+static int GetContactStatus( HANDLE hContact )
+{
+ char *szProto = NULL;
+ int idStatus = ID_STATUS_OFFLINE;
+
+ if ( hContact == NULL )
+ {
+ assert( !"Contact is NULL" );
+ return( 0 );
+ }
+
+ szProto = ( char* )CallService( "Proto/GetContactBaseProto", (WPARAM)hContact, 0 );
+
+ if ( NULL != szProto )
+ {
+ idStatus = DBGetContactSettingWord( hContact, szProto, "Status", ID_STATUS_OFFLINE );
+ }
+
+
+ return( idStatus );
+}
+
+
+static int ClcStatusToPf2( int status )
+{
+ switch(status) {
+ case ID_STATUS_ONLINE: return PF2_ONLINE;
+ case ID_STATUS_AWAY: return PF2_SHORTAWAY;
+ case ID_STATUS_DND: return PF2_HEAVYDND;
+ case ID_STATUS_NA: return PF2_LONGAWAY;
+ case ID_STATUS_OCCUPIED: return PF2_LIGHTDND;
+ case ID_STATUS_FREECHAT: return PF2_FREECHAT;
+ case ID_STATUS_INVISIBLE: return PF2_INVISIBLE;
+ case ID_STATUS_ONTHEPHONE: return PF2_ONTHEPHONE;
+ case ID_STATUS_OUTTOLUNCH: return PF2_OUTTOLUNCH;
+ case ID_STATUS_OFFLINE: return MODEF_OFFLINE;
+ }
+ return 0;
+}
+
+BOOL IsStatusVisible( int status )
+{
+ return ( 0 == ( dwOfflineModes & ClcStatusToPf2( status ) ) );
+}
+
+
+
+void RegHotkey( HANDLE hContact, HWND hwnd )
+{
+ char szBuf[ MAX_PATH ]= {0};
+/* char szPath[ MAX_PATH ]= {0};
+
+ GetModuleFileName( NULL, szPath, MAX_PATH );
+ PathRemoveFileSpec( szPath );
+ strcat( szPath, "\\Thumbs.ini" );
+ GetPrivateProfileString( "Hotkeys", szName, "", szBuf, MAX_PATH - 1, szPath );*/
+ DBVARIANT dbv;
+ if(DBGetContactSettingString ( hContact, sModule, "Hotkey", &dbv)) return;
+ strncpy(szBuf, dbv.pszVal, MAX_PATH - 1);
+ DBFreeVariant( &dbv );
+
+ if ( 0 != strlen( szBuf ) )
+ {
+ UINT nModifiers = 0;
+ char chKey = 0;
+ char szMod[ 2 ][ 20 ] = {0};
+ char szKey[ 20 ] = {0};
+ int i = 0;
+
+ sscanf( szBuf, "%[^'+']+%[^'+']+%[^'+']", szMod[ 0 ], szMod[ 1 ], szKey );
+
+ for ( i = 0; i < 2; ++i )
+ {
+ if( 0 == strncmp( szMod[ i ], "ALT", 19 ) )
+ {
+ nModifiers = nModifiers | MOD_ALT;
+ }
+ else if( 0 == strncmp( szMod[ i ], "CTRL", 19 ) )
+ {
+ nModifiers = nModifiers | MOD_CONTROL;
+ }
+ else if( 0 == strncmp( szMod[ i ], "SHIFT", 19 ) )
+ {
+ nModifiers = nModifiers | MOD_SHIFT;
+ }
+ }
+
+ chKey = szKey[ 0 ];
+
+ RegisterHotKey( hwnd, (int)hwnd, nModifiers, VkKeyScan( chKey ) );
+ }
+}
+
+
+
+///////////////////////////////////////////////////////
+// Contact sttings
+
+void SaveContactsPos()
+{
+ RECT rc;
+
+ for (int i = 0; i < thumbList.getCount(); ++i)
+ {
+ SetLastError( 0 );
+
+ thumbList[i]->GetThumbRect( &rc );
+
+ if( 0 == GetLastError() )
+ DBWriteContactSettingDword( thumbList[i]->hContact, sModule, "ThumbsPos", DB_POS_MAKE_XY(rc.left,rc.top) );
+ }
+}
+
+
+static void LoadContacts()
+{
+ HANDLE hContact = (HANDLE)CallService( MS_DB_CONTACT_FINDFIRST, 0, 0) ;
+
+ while( hContact != NULL )
+ {
+ LoadContact( hContact );
+
+ hContact = (HANDLE)CallService( MS_DB_CONTACT_FINDNEXT, ( WPARAM ) hContact, 0 );
+ }
+}
+
+
+
+
+static void LoadMenus()
+{
+ CLISTMENUITEM mi;
+
+ // Remove thumb menu item
+ hRemoveThumb = CreateServiceFunction( sModule "/RemoveThumb",OnContactMenu_Remove );
+ ZeroMemory( &mi,sizeof( mi ) );
+
+ mi.cbSize = sizeof( mi );
+ mi.position = 0xFFFFF;
+ mi.flags = CMIF_TCHAR;
+ mi.hIcon = LoadIcon( hInst, MAKEINTRESOURCE( IDI_HIDE ) );
+ mi.ptszName = _T("Remove thumb");
+ mi.pszService = sModule "/RemoveThumb";
+ hMenuItemRemove = (HANDLE)CallService( MS_CLIST_ADDCONTACTMENUITEM,0, ( LPARAM )&mi );
+
+ // Hide all thumbs main menu item
+ hMainHideAllThumbs = CreateServiceFunction( sModule "/MainHideAllThumbs",OnMainMenu_HideAll );
+ ZeroMemory( &mi,sizeof( mi ) );
+
+ mi.cbSize = sizeof( mi );
+ mi.position = 0xFFFFF;
+ mi.flags = CMIF_TCHAR;
+ mi.hIcon = LoadIcon( hInst, MAKEINTRESOURCE( fcOpt.bHideAll ? IDI_SHOW : IDI_HIDE ) );
+ mi.ptszName = fcOpt.bHideAll ? _T("Show all thumbs") : _T("Hide all thumbs");
+ mi.pszService = sModule "/MainHideAllThumbs";
+ hMainMenuItemHideAll = (HANDLE)CallService( MS_CLIST_ADDMAINMENUITEM,0, ( LPARAM )&mi );
+
+ if(ServiceExists(MS_HOTKEY_REGISTER)){
+ HOTKEYDESC hkd={0};
+
+ hkd.cbSize = sizeof(hkd);
+ hkd.pszSection = "Floating Contacts";
+
+ hkd.pszName = sModule "/MainHideAllThumbs";
+ hkd.pszDescription = "Show/Hide all thumbs";
+ hkd.pszService = sModule "/MainHideAllThumbs";
+ CallService(MS_HOTKEY_REGISTER, 0, (LPARAM)&hkd);
+
+ hHideWhenCListShow = CreateServiceFunction( sModule "/HideWhenCListShow",OnHotKey_HideWhenCListShow );
+ hkd.pszName = sModule "/HideWhenCListShow";
+ hkd.pszDescription = "Hide when contact list is shown";
+ hkd.pszService = sModule "/HideWhenCListShow";
+ CallService(MS_HOTKEY_REGISTER, 0, (LPARAM)&hkd);
+ }
+}
+
+
+static void LoadContact( HANDLE hContact )
+{
+ DWORD dwPos = (DWORD)-1;
+ TCHAR *ptName = NULL;
+ ThumbInfo *pThumb = thumbList.FindThumbByContact( hContact );
+ int nX, nY;
+
+
+ if ( hContact == NULL ) return;
+
+ dwPos = DBGetContactSettingDword( hContact, sModule, "ThumbsPos", (DWORD)-1 );
+
+ if ( dwPos != -1 )
+ {
+ ptName = (TCHAR*)CallService( MS_CLIST_GETCONTACTDISPLAYNAME, ( WPARAM )hContact, (LPARAM)GCDNF_TCHAR );
+
+ if ( ptName != NULL )
+ {
+ nX = DB_POS_GETX( dwPos );
+ nY = DB_POS_GETY( dwPos );
+
+ CreateThumbWnd( ptName, hContact, nX, nY );
+ pThumb->PositionThumb( (short)nX, (short)nY );
+ }
+ }
+}
+
+
+BOOL HideOnFullScreen()
+{
+ BOOL bFullscreen = FALSE;
+ HWND hWnd = 0;
+
+ if ( fcOpt.bHideWhenFullscreen )
+ {
+ int w = GetSystemMetrics(SM_CXSCREEN);
+ int h = GetSystemMetrics(SM_CYSCREEN);
+
+ hWnd = GetForegroundWindow();
+
+ while (GetWindowLong(hWnd, GWL_EXSTYLE) & WS_EX_TOPMOST)
+ {
+ RECT WindowRect;
+ GetWindowRect(hWnd, &WindowRect);
+
+ if ( (w == (WindowRect.right - WindowRect.left) ) &&
+ (h == (WindowRect.bottom - WindowRect.top)))
+ {
+ bFullscreen = TRUE;
+ break;
+ }
+
+ hWnd = GetNextWindow( hWnd, GW_HWNDNEXT );
+ }
+ }
+
+ return bFullscreen && fcOpt.bHideWhenFullscreen;
+}
+
+
+static int OnContactMenu_Remove( WPARAM wParam,LPARAM lParam )
+{
+ HANDLE hContact = ( HANDLE )wParam;
+ ThumbInfo *pThumb = thumbList.FindThumbByContact( hContact );
+
+ if (pThumb)
+ {
+ pThumb->DeleteContactPos();
+ thumbList.RemoveThumb(pThumb);
+ }
+
+ DestroyMenu( hContactMenu );
+
+ return 0;
+}
+
+static int OnHotKey_HideWhenCListShow( WPARAM wParam,LPARAM lParam )
+{
+ fcOpt.bHideWhenCListShow=!fcOpt.bHideWhenCListShow;
+ DBWriteContactSettingByte(NULL, sModule, "HideWhenCListShow", (BYTE)fcOpt.bHideWhenCListShow);
+ OnStatusChanged();
+ return 0;
+}
+
+
+static int OnMainMenu_HideAll( WPARAM wParam,LPARAM lParam )
+{
+ CLISTMENUITEM clmi = {0};
+ int b;
+
+ fcOpt.bHideAll = !fcOpt.bHideAll;
+ DBWriteContactSettingByte(NULL, sModule, "HideAll", (BYTE)fcOpt.bHideAll);
+ OnStatusChanged();
+
+ clmi.cbSize = sizeof( clmi );
+ clmi.flags = CMIM_NAME | CMIM_ICON|CMIF_TCHAR;
+ clmi.hIcon = LoadIcon( hInst, MAKEINTRESOURCE( fcOpt.bHideAll ? IDI_SHOW : IDI_HIDE ) );
+ clmi.ptszName = fcOpt.bHideAll ? _T("Show all thumbs") : _T("Hide all thumbs");
+ b = CallService( MS_CLIST_MODIFYMENUITEM, ( WPARAM )hMainMenuItemHideAll, ( LPARAM )&clmi );
+ return 0;
+}
+
+static VOID CALLBACK ToTopTimerProc ( HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime)
+{
+ for (int i = 0; i < thumbList.getCount(); ++i)
+ {
+ SetWindowPos(thumbList[i]->hwnd,
+ HWND_TOPMOST,
+ 0,
+ 0,
+ 0,
+ 0,
+ SWP_NOSIZE | SWP_NOMOVE | /*SWP_NOZORDER |*/ SWP_NOACTIVATE);
+ }
+}
+
+void ShowThumbsOnHideCList()
+{
+ if(!fcOpt.bHideWhenCListShow || fcOpt.bHideAll || HideOnFullScreen())return;
+ for (int i = 0; i < thumbList.getCount(); ++i)
+ {
+ if ( !fcOpt.bHideOffline || IsStatusVisible( GetContactStatus(thumbList[i]->hContact) ) )
+ {
+ ShowWindow( thumbList[i]->hwnd, SW_SHOWNA );
+ }
+ }
+}
+
+
+void HideThumbsOnShowCList()
+{
+ if(!fcOpt.bHideWhenCListShow || fcOpt.bHideAll || HideOnFullScreen())return;
+ for (int i = 0; i < thumbList.getCount(); ++i)
+ ShowWindow( thumbList[i]->hwnd, SW_HIDE );
+}
+
+static LRESULT __stdcall newMirandaWndProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
+{
+ if( uMsg == WM_WINDOWPOSCHANGED)
+ {
+ WINDOWPOS *wp = (WINDOWPOS *)lParam;
+ if(wp->flags&SWP_HIDEWINDOW) {
+ bIsCListShow = FALSE;
+ ShowThumbsOnHideCList();
+ }
+ else if(wp->flags&SWP_SHOWWINDOW){
+ bIsCListShow = TRUE;
+ HideThumbsOnShowCList();
+ }
+ else if(!(wp->flags&SWP_NOMOVE)){
+ BYTE method=DBGetContactSettingByte(NULL, "ModernData", "HideBehind", 0);
+ if(method) {
+ WORD wBehindEdgeBorderSize=DBGetContactSettingWord(NULL, "ModernData", "HideBehindBorderSize", 0);
+ RECT rc = {wp->x, wp->y, wp->x+wp->cx, wp->y+wp->cy};
+ RECT rcScreen = {wBehindEdgeBorderSize*(2-method), 0, GetSystemMetrics(SM_CXSCREEN)-wBehindEdgeBorderSize*(method-1), GetSystemMetrics(SM_CYSCREEN)};
+ RECT rcOverlap;
+ BOOL isIntersect;
+
+ isIntersect = IntersectRect( &rcOverlap, &rc, &rcScreen );
+ if ( !isIntersect && bIsCListShow ){
+ bIsCListShow = FALSE;
+ ShowThumbsOnHideCList();
+ }
+ else if ( isIntersect && !bIsCListShow ){
+ bIsCListShow = TRUE;
+ HideThumbsOnShowCList();
+ }
+ }
+ }
+ }
+ return( CallWindowProc(oldMirandaWndProc, hwnd, uMsg, wParam, lParam) );
+}
diff --git a/plugins/FloatingContacts/options.cpp b/plugins/FloatingContacts/options.cpp
new file mode 100644
index 0000000000..be257e7456
--- /dev/null
+++ b/plugins/FloatingContacts/options.cpp
@@ -0,0 +1,1179 @@
+
+#include "stdhdr.h"
+
+#include "resource.h"
+#include "fltcont.h"
+
+/////////////////////////////////////////////////////////////////////////////
+//
+
+#define SAMEASF_FACE 1
+#define SAMEASF_SIZE 2
+#define SAMEASF_STYLE 4
+#define SAMEASF_COLOUR 8
+
+typedef struct _SFontSettings
+{
+ BYTE sameAsFlags,sameAs;
+ COLORREF colour;
+ char size;
+ BYTE style;
+ BYTE charset;
+ char szFace[LF_FACESIZE];
+} SFontSettings;
+
+static SFontSettings s_rgFontSettings[FLT_FONTIDS];
+static SFontSettings s_rgFontSettingsMiranda[FLT_FONTIDS];
+
+#define FLT_SAME_AS_NONE ((BYTE)0xFF)
+#define FLT_SAME_AS_MIRANDA ((BYTE)0xFE)
+
+static char* s_rgszFontSizes[]={"8","10","14","16","18","20","24","28"};
+
+static const TCHAR* s_rgszFontIdDescr[FLT_FONTIDS] =
+{
+ _T("Standard contacts"),
+ _T("Online contacts to whom you have a different visibility"),
+ _T("Offline contacts"),
+ _T("Offline contacts to whom you have a different visibility"),
+ _T("Contacts which are 'not on list'"),
+};
+
+static WORD s_rgwFontSameAsDefault[FLT_FONTIDS] =
+{
+ MAKEWORD(FLT_SAME_AS_MIRANDA, 0x0F),
+ MAKEWORD(FLT_SAME_AS_MIRANDA, 0x0F),
+ MAKEWORD(FLT_SAME_AS_MIRANDA, 0x0F),
+ MAKEWORD(FLT_SAME_AS_MIRANDA, 0x0F),
+ MAKEWORD(FLT_SAME_AS_MIRANDA, 0x0F),
+};
+
+static int s_rgnMirandaFontId[FLT_FONTIDS] =
+{
+ FONTID_CONTACTS,
+ FONTID_INVIS,
+ FONTID_OFFLINE,
+ FONTID_OFFINVIS,
+ FONTID_NOTONLIST
+};
+
+#define M_REBUILDFONTGROUP (WM_USER + 10)
+#define M_REMAKESAMPLE (WM_USER + 11)
+#define M_RECALCONEFONT (WM_USER + 12)
+#define M_RECALCOTHERFONTS (WM_USER + 13)
+#define M_SAVEFONT (WM_USER + 14)
+#define M_REFRESHSAMEASBOXES (WM_USER + 15)
+#define M_FILLSCRIPTCOMBO (WM_USER + 16)
+#define M_LOADFONT (WM_USER + 17)
+#define M_GUESSSAMEASBOXES (WM_USER + 18)
+#define M_SETSAMEASBOXES (WM_USER + 19)
+
+#define M_REFRESHBKGBOXES (WM_USER + 20)
+#define M_REFRESHBORDERPICKERS (WM_USER + 21)
+
+/////////////////////////////////////////////////////////////////////////////
+//
+
+static
+LRESULT
+APIENTRY
+OptWndProc
+ ( IN HWND hwndDlg
+ , IN UINT uMsg
+ , IN WPARAM wParam
+ , IN LPARAM lParam
+ );
+
+static
+LRESULT
+APIENTRY
+OptSknWndProc
+ ( IN HWND hwndDlg
+ , IN UINT uMsg
+ , IN WPARAM wParam
+ , IN LPARAM lParam
+ );
+
+/////////////////////////////////////////////////////////////////////////////
+//
+
+int
+OnOptionsInitialize
+ ( IN WPARAM wParam
+ , IN LPARAM lParam
+ )
+{
+ OPTIONSDIALOGPAGE odp;
+
+ ZeroMemory(&odp, sizeof(odp));
+ odp.cbSize = sizeof(odp);
+ odp.hInstance = hInst;
+ odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPT_FLTCONT);
+ odp.ptszTitle = _T("Floating Contacts");
+ odp.ptszGroup = _T("Plugins");
+ odp.ptszTab = _T("Main Features");
+ odp.flags = ODPF_BOLDGROUPS|ODPF_TCHAR;
+ odp.pfnDlgProc = (DLGPROC)OptWndProc;
+ CallService(MS_OPT_ADDPAGE, wParam, (LPARAM)&odp);
+
+ ZeroMemory(&odp, sizeof(odp));
+ odp.cbSize = sizeof(odp);
+ odp.hInstance = hInst;
+ odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPT_SKIN);
+ odp.ptszTitle = _T("Floating Contacts");
+ odp.ptszGroup = _T("Plugins");
+ odp.ptszTab = _T("Appearance");
+ odp.flags = ODPF_BOLDGROUPS|ODPF_TCHAR;
+ odp.pfnDlgProc = (DLGPROC)OptSknWndProc;
+ CallService(MS_OPT_ADDPAGE, wParam, (LPARAM)&odp);
+
+ return 0;
+}
+
+static
+int
+CALLBACK
+EnumFontsProc
+ ( IN ENUMLOGFONTEXA* lpelfe
+ , IN NEWTEXTMETRICEXA* lpntme
+ , IN int FontType
+ , IN LPARAM lParam
+ )
+{
+ if (IsWindow((HWND)lParam))
+ {
+ if (CB_ERR == SendMessageA((HWND)lParam, CB_FINDSTRINGEXACT, (WPARAM)-1, (LPARAM)lpelfe->elfLogFont.lfFaceName))
+ SendMessageA((HWND)lParam, CB_ADDSTRING, 0, (LPARAM)lpelfe->elfLogFont.lfFaceName);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+void
+FillFontListThread
+ ( IN HWND hwndDlg
+ )
+{
+ LOGFONTA lf = {0};
+ HDC hdc = GetDC(hwndDlg);
+
+ lf.lfCharSet = DEFAULT_CHARSET;
+ lf.lfFaceName[0] = 0;
+ lf.lfPitchAndFamily = 0;
+ EnumFontFamiliesExA(hdc, &lf, (FONTENUMPROCA)EnumFontsProc, (LPARAM)GetDlgItem(hwndDlg,IDC_TYPEFACE), 0);
+ ReleaseDC(hwndDlg, hdc);
+ return;
+}
+
+static
+int
+CALLBACK
+EnumFontScriptsProc
+ ( IN ENUMLOGFONTEX* lpelfe
+ , IN NEWTEXTMETRICEX* lpntme
+ , IN int FontType
+ , IN LPARAM lParam
+ )
+{
+ if (CB_ERR == SendMessage((HWND)lParam, CB_FINDSTRINGEXACT, (WPARAM)-1, (LPARAM)lpelfe->elfScript))
+ {
+ int i = SendMessage((HWND)lParam, CB_ADDSTRING, 0, (LPARAM)lpelfe->elfScript);
+ SendMessage((HWND)lParam, CB_SETITEMDATA, i, lpelfe->elfLogFont.lfCharSet);
+ }
+ return TRUE;
+}
+
+static
+void
+GetDefaultFontSetting
+ ( IN BOOL bFltContacts
+ , IN int nFontId
+ , IN LOGFONTA* lf
+ , IN COLORREF* colour
+ )
+{
+ SystemParametersInfoA(SPI_GETICONTITLELOGFONT, sizeof(LOGFONTA), lf, FALSE);
+ *colour = GetSysColor(COLOR_WINDOWTEXT);
+ if (bFltContacts)
+ {
+ switch (nFontId)
+ {
+ case FLT_FONTID_OFFINVIS:
+ case FLT_FONTID_INVIS:
+ lf->lfItalic = !lf->lfItalic;
+ break;
+
+ case FLT_FONTID_NOTONLIST:
+ *colour = GetSysColor(COLOR_3DSHADOW);
+ break;
+ }
+ }
+ else
+ {
+ switch (s_rgnMirandaFontId[nFontId])
+ {
+ case FONTID_OFFINVIS:
+ case FONTID_INVIS:
+ lf->lfItalic = !lf->lfItalic;
+ break;
+
+ case FONTID_NOTONLIST:
+ *colour = GetSysColor(COLOR_3DSHADOW);
+ break;
+ }
+ }
+}
+
+void
+GetFontSetting
+ ( IN BOOL bFltContacts
+ , IN int nFontId
+ , IN LOGFONTA* lf
+ , IN COLORREF* colour
+ )
+{
+ DBVARIANT dbv;
+ char idstr[10];
+ BYTE style;
+ const char* pModule = (bFltContacts ? sModule : "CLC");
+
+ GetDefaultFontSetting(bFltContacts, nFontId, lf, colour);
+ if (!bFltContacts)
+ nFontId = s_rgnMirandaFontId[nFontId];
+ wsprintfA(idstr, "Font%dName", nFontId);
+ if (!DBGetContactSetting(NULL, pModule, idstr, &dbv))
+ {
+ lstrcpyA(lf->lfFaceName, dbv.pszVal);
+ DBFreeVariant(&dbv);
+ }
+
+ wsprintfA(idstr, "Font%dCol", nFontId);
+ *colour = DBGetContactSettingDword(NULL, pModule, idstr, *colour);
+
+ wsprintfA(idstr, "Font%dSize", nFontId);
+ lf->lfHeight = (char)DBGetContactSettingByte(NULL, pModule, idstr, lf->lfHeight);
+
+ wsprintfA(idstr, "Font%dSty", nFontId);
+ style = (BYTE)DBGetContactSettingByte(NULL, pModule, idstr
+ , (lf->lfWeight == FW_NORMAL ? 0 : DBFONTF_BOLD)
+ | (lf->lfItalic ? DBFONTF_ITALIC : 0)
+ | (lf->lfUnderline ? DBFONTF_UNDERLINE : 0)
+ );
+ lf->lfWidth = lf->lfEscapement = lf->lfOrientation = 0;
+ lf->lfWeight = ((style & DBFONTF_BOLD) ? FW_BOLD : FW_NORMAL);
+ lf->lfItalic = (0 != (style & DBFONTF_ITALIC));
+ lf->lfUnderline = (0 != (style & DBFONTF_UNDERLINE));
+ lf->lfStrikeOut = 0;
+
+ wsprintfA(idstr, "Font%dSet", nFontId);
+ lf->lfCharSet = (BYTE)DBGetContactSettingByte(NULL, pModule, idstr, lf->lfCharSet);
+ lf->lfOutPrecision = OUT_DEFAULT_PRECIS;
+ lf->lfClipPrecision = CLIP_DEFAULT_PRECIS;
+ lf->lfQuality = DEFAULT_QUALITY;
+ lf->lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE;
+
+ if (bFltContacts)
+ {
+ WORD wSameAs;
+ BYTE bySameAs;
+ BYTE bySameAsFlags;
+
+ wsprintfA(idstr, "Font%dAs", nFontId);
+ wSameAs = (WORD)DBGetContactSettingWord(NULL, sModule, idstr, s_rgwFontSameAsDefault[nFontId]);
+ bySameAs=LOBYTE(wSameAs);
+ bySameAsFlags=HIBYTE(wSameAs);
+
+ if (FLT_SAME_AS_MIRANDA == bySameAs)
+ {
+ LOGFONTA lfMiranda;
+ COLORREF colourMiranda;
+
+ GetFontSetting(FALSE, nFontId, &lfMiranda, &colourMiranda);
+ if (bySameAsFlags & SAMEASF_FACE)
+ {
+ lstrcpyA(lf->lfFaceName, lfMiranda.lfFaceName);
+ lf->lfCharSet = lfMiranda.lfCharSet;
+ }
+ if (bySameAsFlags & SAMEASF_SIZE)
+ lf->lfHeight = lfMiranda.lfHeight;
+ if (bySameAsFlags & SAMEASF_STYLE)
+ {
+ lf->lfWeight = lfMiranda.lfWeight;
+ lf->lfItalic = lfMiranda.lfItalic;
+ lf->lfUnderline = lfMiranda.lfUnderline;
+ }
+ if (bySameAsFlags & SAMEASF_COLOUR)
+ *colour = colourMiranda;
+ }
+ }
+}
+
+static
+LRESULT
+APIENTRY
+OptWndProc
+ ( IN HWND hwndDlg
+ , IN UINT uMsg
+ , IN WPARAM wParam
+ , IN LPARAM lParam
+ )
+{
+ switch ( uMsg )
+ {
+ case WM_INITDIALOG:
+ {
+ TranslateDialogDefault(hwndDlg);
+
+ // Properties
+ CheckDlgButton(hwndDlg, IDC_CHK_HIDE_OFFLINE, (fcOpt.bHideOffline ? BST_CHECKED : BST_UNCHECKED));
+ CheckDlgButton(hwndDlg, IDC_CHK_HIDE_ALL, (fcOpt.bHideAll ? BST_CHECKED : BST_UNCHECKED));
+ CheckDlgButton(hwndDlg, IDC_CHK_HIDE_WHEN_FULSCREEN, (fcOpt.bHideWhenFullscreen ? BST_CHECKED : BST_UNCHECKED));
+ CheckDlgButton(hwndDlg, IDC_CHK_STICK, (fcOpt.bMoveTogether ? BST_CHECKED : BST_UNCHECKED));
+ CheckDlgButton(hwndDlg, IDC_CHK_WIDTH, (fcOpt.bFixedWidth ? BST_CHECKED : BST_UNCHECKED));
+
+ EnableWindow(GetDlgItem(hwndDlg, IDC_LBL_WIDTH), fcOpt.bFixedWidth);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_TXT_WIDTH), fcOpt.bFixedWidth);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_WIDTHSPIN), fcOpt.bFixedWidth);
+
+ SendDlgItemMessage(hwndDlg, IDC_WIDTHSPIN, UDM_SETRANGE, 0, MAKELONG(255,0));
+ SendDlgItemMessage(hwndDlg, IDC_WIDTHSPIN, UDM_SETPOS, 0, fcOpt.nThumbWidth);
+
+ CheckDlgButton(hwndDlg, IDC_CHK_TIP, (fcOpt.bShowTip ? BST_CHECKED : BST_UNCHECKED));
+
+ EnableWindow(GetDlgItem(hwndDlg, IDC_CHK_TIP), bEnableTip);
+
+ EnableWindow(GetDlgItem(hwndDlg, IDC_LBL_TIMEIN), bEnableTip && fcOpt.bShowTip);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_LBL_TIMEIN_CMT), bEnableTip && fcOpt.bShowTip);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_TXT_TIMEIN), bEnableTip && fcOpt.bShowTip);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_TIMEINSPIN), bEnableTip && fcOpt.bShowTip);
+
+ SendDlgItemMessage(hwndDlg, IDC_TIMEINSPIN, UDM_SETRANGE, 0, MAKELONG(5000,0));
+ SendDlgItemMessage(hwndDlg, IDC_TIMEINSPIN, UDM_SETPOS, 0, fcOpt.TimeIn);
+
+ CheckDlgButton(hwndDlg, IDC_CHK_TOTOP, (fcOpt.bToTop ? BST_CHECKED : BST_UNCHECKED));
+
+ EnableWindow(GetDlgItem(hwndDlg, IDC_LBL_TOTOP), fcOpt.bToTop);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_TXT_TOTOPTIME), fcOpt.bToTop);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_TOTOPTIMESPIN), fcOpt.bToTop);
+
+ SendDlgItemMessage(hwndDlg, IDC_TOTOPTIMESPIN, UDM_SETRANGE, 0, MAKELONG(TOTOPTIME_MAX,1));
+ SendDlgItemMessage(hwndDlg, IDC_TOTOPTIMESPIN, UDM_SETPOS, 0, fcOpt.ToTopTime);
+
+ CheckDlgButton(hwndDlg, IDC_CHK_HIDE_WHEN_CLISTSHOW, (fcOpt.bHideWhenCListShow ? BST_CHECKED : BST_UNCHECKED));
+ CheckDlgButton(hwndDlg, IDC_CHK_SINGLECLK, (fcOpt.bUseSingleClick ? BST_CHECKED : BST_UNCHECKED));
+ CheckDlgButton(hwndDlg, IDC_CHK_SHOWIDLE, (fcOpt.bShowIdle ? BST_CHECKED : BST_UNCHECKED));
+
+ return TRUE;
+ }
+ case WM_COMMAND:
+ {
+ switch (LOWORD(wParam))
+ {
+ case IDC_CHK_WIDTH:
+ {
+ if (BN_CLICKED == HIWORD(wParam))
+ {
+ BOOL bChecked = (BOOL)IsDlgButtonChecked(hwndDlg, IDC_CHK_WIDTH);
+
+ EnableWindow(GetDlgItem(hwndDlg, IDC_LBL_WIDTH ), bChecked);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_TXT_WIDTH ), bChecked);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_WIDTHSPIN), bChecked);
+ }
+ break;
+ }
+ case IDC_TXT_WIDTH:
+ {
+ if (EN_CHANGE != HIWORD(wParam) || (HWND)lParam != GetFocus())
+ return 0;
+ break;
+ }
+ case IDC_CHK_TIP:
+ {
+ if (BN_CLICKED == HIWORD(wParam))
+ {
+ BOOL bChecked = (BOOL)IsDlgButtonChecked(hwndDlg, IDC_CHK_TIP);
+
+ EnableWindow(GetDlgItem(hwndDlg, IDC_LBL_TIMEIN ), bChecked);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_LBL_TIMEIN_CMT ), bChecked);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_TXT_TIMEIN ), bChecked);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_TIMEINSPIN), bChecked);
+ }
+ break;
+ }
+ case IDC_TXT_TIMEIN:
+ {
+ if (EN_CHANGE != HIWORD(wParam) || (HWND)lParam != GetFocus())
+ return 0;
+ break;
+ }
+ case IDC_CHK_TOTOP:
+ {
+ if (BN_CLICKED == HIWORD(wParam))
+ {
+ BOOL bChecked = (BOOL)IsDlgButtonChecked(hwndDlg, IDC_CHK_TOTOP);
+
+ EnableWindow(GetDlgItem(hwndDlg, IDC_LBL_TOTOP ), bChecked);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_TXT_TOTOPTIME ), bChecked);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_TOTOPTIMESPIN), bChecked);
+ }
+ break;
+ }
+ case IDC_TXT_TOTOPTIME:
+ {
+ if (EN_CHANGE != HIWORD(wParam) || (HWND)lParam != GetFocus())
+ return 0;
+ break;
+ }
+ }
+ SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
+ break;
+ }
+ case WM_NOTIFY:
+ {
+ LPNMHDR phdr = (LPNMHDR)(lParam);
+
+ if (0 == phdr->idFrom)
+ {
+ switch (phdr->code)
+ {
+ case PSN_APPLY:
+ {
+ BOOL bSuccess = FALSE;
+
+ fcOpt.bHideOffline = (BOOL)IsDlgButtonChecked(hwndDlg, IDC_CHK_HIDE_OFFLINE);
+ DBWriteContactSettingByte(NULL, sModule, "HideOffline", (BYTE)fcOpt.bHideOffline);
+
+ fcOpt.bHideAll = (BOOL)IsDlgButtonChecked(hwndDlg, IDC_CHK_HIDE_ALL);
+ DBWriteContactSettingByte(NULL, sModule, "HideAll", (BYTE)fcOpt.bHideAll);
+
+ fcOpt.bHideWhenFullscreen = (BOOL)IsDlgButtonChecked(hwndDlg, IDC_CHK_HIDE_WHEN_FULSCREEN);
+ DBWriteContactSettingByte(NULL, sModule, "HideWhenFullscreen", (BYTE)fcOpt.bHideWhenFullscreen);
+
+ fcOpt.bMoveTogether = (BOOL)IsDlgButtonChecked(hwndDlg, IDC_CHK_STICK);
+ DBWriteContactSettingByte(NULL, sModule, "MoveTogether", (BYTE)fcOpt.bMoveTogether);
+
+ fcOpt.bFixedWidth = (BOOL)IsDlgButtonChecked(hwndDlg, IDC_CHK_WIDTH);
+ DBWriteContactSettingByte(NULL, sModule, "FixedWidth", (BYTE)fcOpt.bFixedWidth);
+ fcOpt.nThumbWidth = GetDlgItemInt(hwndDlg, IDC_TXT_WIDTH, &bSuccess, FALSE);
+ DBWriteContactSettingDword(NULL, sModule, "Width", fcOpt.nThumbWidth );
+
+ if(bEnableTip)
+ {
+ fcOpt.bShowTip = (BOOL)IsDlgButtonChecked(hwndDlg, IDC_CHK_TIP);
+ DBWriteContactSettingByte(NULL, sModule, "ShowTip", (BYTE)fcOpt.bShowTip);
+ fcOpt.TimeIn = GetDlgItemInt(hwndDlg, IDC_TXT_TIMEIN, &bSuccess, FALSE);
+ DBWriteContactSettingWord(NULL, sModule, "TimeIn", fcOpt.TimeIn );
+ }
+
+ fcOpt.bToTop = (BOOL)IsDlgButtonChecked(hwndDlg, IDC_CHK_TOTOP);
+ DBWriteContactSettingByte(NULL, sModule, "ToTop", (BYTE)fcOpt.bToTop);
+ fcOpt.ToTopTime = GetDlgItemInt(hwndDlg, IDC_TXT_TOTOPTIME, &bSuccess, FALSE);
+ DBWriteContactSettingWord(NULL, sModule, "ToTopTime", fcOpt.ToTopTime );
+
+ fcOpt.bHideWhenCListShow = (BOOL)IsDlgButtonChecked(hwndDlg, IDC_CHK_HIDE_WHEN_CLISTSHOW);
+ DBWriteContactSettingByte(NULL, sModule, "HideWhenCListShow", (BYTE)fcOpt.bHideWhenCListShow);
+
+ fcOpt.bUseSingleClick = (BOOL)IsDlgButtonChecked(hwndDlg, IDC_CHK_SINGLECLK);
+ DBWriteContactSettingByte(NULL, sModule, "UseSingleClick", (BYTE)fcOpt.bUseSingleClick);
+
+ fcOpt.bShowIdle = (BOOL)IsDlgButtonChecked(hwndDlg, IDC_CHK_SHOWIDLE);
+ DBWriteContactSettingByte(NULL, sModule, "ShowIdle", (BYTE)fcOpt.bShowIdle);
+
+ ApplyOptionsChanges();
+ OnStatusChanged();
+ return TRUE;
+ }
+ }
+ }
+ break;
+ }
+ }
+ return FALSE;
+}
+
+static
+LRESULT
+APIENTRY
+OptSknWndProc
+ ( IN HWND hwndDlg
+ , IN UINT uMsg
+ , IN WPARAM wParam
+ , IN LPARAM lParam
+ )
+{
+ static HFONT hFontSample;
+
+ switch ( uMsg )
+ {
+ case WM_INITDIALOG:
+ {
+ BYTE btOpacity;
+ char szPercent[20];
+
+ TranslateDialogDefault(hwndDlg);
+
+ // Border
+ CheckDlgButton(hwndDlg, IDC_DRAWBORDER
+ , DBGetContactSettingByte(NULL, sModule, "DrawBorder", FLT_DEFAULT_DRAWBORDER)
+ ? BST_CHECKED : BST_UNCHECKED
+ );
+ SendMessage(hwndDlg, M_REFRESHBORDERPICKERS, 0, 0);
+ SendDlgItemMessage(hwndDlg, IDC_LTEDGESCOLOR, CPM_SETDEFAULTCOLOUR, 0, FLT_DEFAULT_LTEDGESCOLOR);
+ SendDlgItemMessage(hwndDlg, IDC_LTEDGESCOLOR, CPM_SETCOLOUR, 0
+ , DBGetContactSettingDword(NULL, sModule, "LTEdgesColor", FLT_DEFAULT_LTEDGESCOLOR)
+ );
+ SendDlgItemMessage(hwndDlg, IDC_RBEDGESCOLOR, CPM_SETDEFAULTCOLOUR, 0, FLT_DEFAULT_RBEDGESCOLOR);
+ SendDlgItemMessage(hwndDlg, IDC_RBEDGESCOLOR, CPM_SETCOLOUR, 0
+ , DBGetContactSettingDword(NULL, sModule, "RBEdgesColor", FLT_DEFAULT_RBEDGESCOLOR)
+ );
+
+ // Background
+ CheckDlgButton(hwndDlg, IDC_CHK_WIDTH, (fcOpt.bFixedWidth ? BST_CHECKED : BST_UNCHECKED));
+
+ SendDlgItemMessage(hwndDlg, IDC_BKGCOLOUR, CPM_SETDEFAULTCOLOUR, 0, FLT_DEFAULT_BKGNDCOLOR);
+ SendDlgItemMessage(hwndDlg, IDC_BKGCOLOUR, CPM_SETCOLOUR, 0
+ , DBGetContactSettingDword(NULL, sModule, "BkColor", FLT_DEFAULT_BKGNDCOLOR)
+ );
+ CheckDlgButton(hwndDlg, IDC_BITMAP
+ , DBGetContactSettingByte(NULL, sModule, "BkUseBitmap", FLT_DEFAULT_BKGNDUSEBITMAP)
+ ? BST_CHECKED : BST_UNCHECKED
+ );
+ SendMessage(hwndDlg, M_REFRESHBKGBOXES, 0, 0);
+ {
+ DBVARIANT dbv;
+
+ if (!DBGetContactSetting(NULL, sModule, "BkBitmap", &dbv))
+ {
+ SetDlgItemTextA(hwndDlg, IDC_FILENAME, dbv.pszVal);
+ DBFreeVariant(&dbv);
+ }
+ }
+ {
+ WORD bmpUse = (WORD)DBGetContactSettingWord(NULL, sModule, "BkBitmapOpt", FLT_DEFAULT_BKGNDBITMAPOPT);
+
+ CheckDlgButton(hwndDlg, IDC_STRETCHH, ((bmpUse & CLB_STRETCHH) ? BST_CHECKED : BST_UNCHECKED));
+ CheckDlgButton(hwndDlg, IDC_STRETCHV, ((bmpUse & CLB_STRETCHV) ? BST_CHECKED : BST_UNCHECKED));
+ CheckDlgButton(hwndDlg, IDC_TILEH, ((bmpUse & CLBF_TILEH) ? BST_CHECKED : BST_UNCHECKED));
+ CheckDlgButton(hwndDlg, IDC_TILEV, ((bmpUse & CLBF_TILEV) ? BST_CHECKED : BST_UNCHECKED));
+ CheckDlgButton(hwndDlg, IDC_PROPORTIONAL, ((bmpUse & CLBF_PROPORTIONAL) ? BST_CHECKED : BST_UNCHECKED));
+ }
+ {
+ HRESULT (STDAPICALLTYPE *MySHAutoComplete)(HWND,DWORD);
+
+ MySHAutoComplete = (HRESULT (STDAPICALLTYPE*)(HWND,DWORD))GetProcAddress(GetModuleHandle(_T("shlwapi")), "SHAutoComplete");
+ if (MySHAutoComplete)
+ MySHAutoComplete(GetDlgItem(hwndDlg, IDC_FILENAME), 1);
+ }
+
+ // Windows 2K/XP
+ btOpacity = (BYTE)DBGetContactSettingByte(NULL, sModule, "Opacity", 100);
+ SendDlgItemMessage(hwndDlg, IDC_SLIDER_OPACITY, TBM_SETRANGE, TRUE, MAKELONG(0, 100));
+ SendDlgItemMessage(hwndDlg, IDC_SLIDER_OPACITY, TBM_SETPOS, TRUE, btOpacity);
+
+ wsprintfA(szPercent, "%d%%", btOpacity);
+ SetDlgItemTextA(hwndDlg, IDC_OPACITY, szPercent);
+
+ EnableWindow(GetDlgItem(hwndDlg, IDC_SLIDER_OPACITY), (NULL != pSetLayeredWindowAttributes));
+ EnableWindow(GetDlgItem(hwndDlg, IDC_OPACITY), (NULL != pSetLayeredWindowAttributes));
+
+ // Fonts
+ hFontSample = NULL;
+ SetDlgItemText(hwndDlg, IDC_SAMPLE, TranslateT("Sample"));
+ FillFontListThread(hwndDlg);
+ {
+ int i;
+ int itemId;
+ LOGFONTA lf;
+ COLORREF colour;
+ WORD sameAs;
+ char str[32];
+
+ for (i = 0; i < FLT_FONTIDS; i++)
+ {
+ // Floating contacts fonts
+ GetFontSetting(TRUE, i, &lf, &colour);
+ wsprintfA(str, "Font%dAs", i);
+ sameAs = (WORD)DBGetContactSettingWord(NULL, sModule, str, s_rgwFontSameAsDefault[i]);
+ s_rgFontSettings[i].sameAs = LOBYTE(sameAs);
+ s_rgFontSettings[i].sameAsFlags = HIBYTE(sameAs);
+ s_rgFontSettings[i].style = (FW_NORMAL == lf.lfWeight? 0 : DBFONTF_BOLD)
+ | (lf.lfItalic ? DBFONTF_ITALIC : 0)
+ | (lf.lfUnderline ? DBFONTF_UNDERLINE : 0);
+ if (lf.lfHeight < 0)
+ {
+ HDC hdc;
+ SIZE size;
+ HFONT hFont = CreateFontIndirectA(&lf);
+
+ hdc=GetDC(hwndDlg);
+ SelectObject(hdc, hFont);
+ GetTextExtentPoint32A(hdc, "x", 1, &size);
+ ReleaseDC(hwndDlg, hdc);
+ DeleteObject(hFont);
+ s_rgFontSettings[i].size = (char)size.cy;
+ }
+ else
+ s_rgFontSettings[i].size = (char)lf.lfHeight;
+ s_rgFontSettings[i].charset = lf.lfCharSet;
+ s_rgFontSettings[i].colour = colour;
+ lstrcpyA(s_rgFontSettings[i].szFace, lf.lfFaceName);
+ itemId = SendDlgItemMessage(hwndDlg, IDC_FONTID, CB_ADDSTRING, 0, (LPARAM)TranslateTS(s_rgszFontIdDescr[i]));
+ SendDlgItemMessage(hwndDlg, IDC_FONTID, CB_SETITEMDATA, itemId, i);
+
+ // Miranda contact list fonts
+ GetFontSetting(FALSE, i, &lf, &colour);
+ s_rgFontSettingsMiranda[i].sameAs = 0;
+ s_rgFontSettingsMiranda[i].sameAsFlags = 0;
+ lstrcpyA(s_rgFontSettingsMiranda[i].szFace, lf.lfFaceName);
+ s_rgFontSettingsMiranda[i].charset = lf.lfCharSet;
+ s_rgFontSettingsMiranda[i].style = (FW_NORMAL == lf.lfWeight? 0 : DBFONTF_BOLD)
+ | (lf.lfItalic ? DBFONTF_ITALIC : 0)
+ | (lf.lfUnderline ? DBFONTF_UNDERLINE : 0);
+ if (lf.lfHeight < 0)
+ {
+ HDC hdc;
+ SIZE size;
+ HFONT hFont = CreateFontIndirectA(&lf);
+
+ hdc = GetDC(hwndDlg);
+ SelectObject(hdc, hFont);
+ GetTextExtentPoint32A(hdc, "x", 1, &size);
+ ReleaseDC(hwndDlg, hdc);
+ DeleteObject(hFont);
+ s_rgFontSettingsMiranda[i].size = (char)size.cy;
+ }
+ else
+ s_rgFontSettingsMiranda[i].size = (char)lf.lfHeight;
+ s_rgFontSettingsMiranda[i].colour = colour;
+ }
+ SendDlgItemMessage(hwndDlg, IDC_FONTID, CB_SETCURSEL, 0, 0);
+ for (i = 0; i < sizeof(s_rgszFontSizes)/sizeof(s_rgszFontSizes[0]); i++)
+ SendDlgItemMessageA(hwndDlg, IDC_FONTSIZE, CB_ADDSTRING, 0, (LPARAM)s_rgszFontSizes[i]);
+ }
+ SendMessage(hwndDlg, M_REBUILDFONTGROUP, 0, 0);
+ SendMessage(hwndDlg, M_SAVEFONT, 0, 0);
+ return TRUE;
+ }
+ case M_REFRESHBKGBOXES:
+ {
+ BOOL bEnable = IsDlgButtonChecked(hwndDlg, IDC_BITMAP);
+
+ EnableWindow(GetDlgItem(hwndDlg, IDC_FILENAME), bEnable);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_BROWSE), bEnable);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_STRETCHH), bEnable);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_STRETCHV), bEnable);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_TILEH), bEnable);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_TILEV), bEnable);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_PROPORTIONAL), bEnable);
+ break;
+ }
+ case M_REFRESHBORDERPICKERS:
+ {
+ BOOL bEnable = IsDlgButtonChecked(hwndDlg, IDC_DRAWBORDER);
+
+ EnableWindow(GetDlgItem(hwndDlg, IDC_LTEDGESCOLOR), bEnable);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_RBEDGESCOLOR), bEnable);
+ break;
+ }
+ // remake all the needed controls when the user changes the font selector at the top
+ case M_REBUILDFONTGROUP:
+ {
+ int i = SendDlgItemMessage(hwndDlg, IDC_FONTID, CB_GETCURSEL, 0, 0);
+ int j;
+ int itemId;
+ int nSameAs = FLT_SAME_AS_NONE;
+ char szText[256];
+
+ SendDlgItemMessage(hwndDlg, IDC_SAMEAS, CB_RESETCONTENT, 0, 0);
+ itemId = SendDlgItemMessage(hwndDlg, IDC_SAMEAS, CB_ADDSTRING, 0, (LPARAM)TranslateT("<none>"));
+ SendDlgItemMessage(hwndDlg, IDC_SAMEAS, CB_SETITEMDATA, itemId, FLT_SAME_AS_NONE);
+ SendDlgItemMessage(hwndDlg, IDC_SAMEAS, CB_SETCURSEL, itemId, 0);
+ itemId = SendDlgItemMessage(hwndDlg, IDC_SAMEAS, CB_ADDSTRING, 0, (LPARAM)TranslateT("<Contact List Text>"));
+ SendDlgItemMessage(hwndDlg, IDC_SAMEAS, CB_SETITEMDATA, itemId, FLT_SAME_AS_MIRANDA);
+ if (FLT_SAME_AS_MIRANDA == s_rgFontSettings[i].sameAs)
+ {
+ SendDlgItemMessage(hwndDlg, IDC_SAMEAS, CB_SETCURSEL, itemId, 0);
+ nSameAs = FLT_SAME_AS_MIRANDA;
+ }
+ for (j = 0; j < FLT_FONTIDS; j++)
+ {
+ int nDependsOn = j;
+
+ while (nDependsOn != i)
+ {
+ if (FLT_SAME_AS_NONE == nDependsOn || FLT_SAME_AS_MIRANDA == nDependsOn)
+ {
+ SendDlgItemMessage(hwndDlg, IDC_FONTID, CB_GETLBTEXT, j, (LPARAM)szText);
+ itemId = SendDlgItemMessage(hwndDlg, IDC_SAMEAS, CB_ADDSTRING, 0, (LPARAM)szText);
+ SendDlgItemMessage(hwndDlg, IDC_SAMEAS, CB_SETITEMDATA, itemId, j);
+ if (j == s_rgFontSettings[i].sameAs)
+ {
+ SendDlgItemMessage(hwndDlg, IDC_SAMEAS, CB_SETCURSEL, itemId, 0);
+ nSameAs = j;
+ }
+ break;
+ }
+ else
+ nDependsOn = s_rgFontSettings[nDependsOn].sameAs;
+ }
+ }
+ if (FLT_SAME_AS_NONE == nSameAs)
+ s_rgFontSettings[i].sameAsFlags = 0;
+
+ SendMessage(hwndDlg, M_LOADFONT, i, 0);
+ SendMessage(hwndDlg, M_SETSAMEASBOXES, i, 0);
+ SendMessage(hwndDlg, M_REFRESHSAMEASBOXES, i, 0);
+ SendMessage(hwndDlg, M_REMAKESAMPLE, 0, 0);
+ break;
+ }
+ //fill the script combo box and set the selection to the value for fontid wParam
+ case M_FILLSCRIPTCOMBO:
+ {
+ int i;
+ HDC hdc = GetDC(hwndDlg);
+ LOGFONT lf = {0};
+
+ lf.lfCharSet = DEFAULT_CHARSET;
+ lf.lfPitchAndFamily = 0;
+ GetDlgItemText(hwndDlg, IDC_TYPEFACE, lf.lfFaceName, sizeof(lf.lfFaceName));
+ SendDlgItemMessage(hwndDlg, IDC_SCRIPT, CB_RESETCONTENT, 0, 0);
+ EnumFontFamiliesEx(hdc, &lf, (FONTENUMPROC)EnumFontScriptsProc, (LPARAM)GetDlgItem(hwndDlg, IDC_SCRIPT), 0);
+ ReleaseDC(hwndDlg, hdc);
+ for (i = SendDlgItemMessage(hwndDlg, IDC_SCRIPT, CB_GETCOUNT, 0, 0) - 1; i >= 0; i--)
+ {
+ if (SendDlgItemMessage(hwndDlg, IDC_SCRIPT, CB_GETITEMDATA, i, 0) == s_rgFontSettings[wParam].charset)
+ {
+ SendDlgItemMessage(hwndDlg, IDC_SCRIPT, CB_SETCURSEL, i, 0);
+ break;
+ }
+ }
+ if (i < 0)
+ SendDlgItemMessage(hwndDlg, IDC_SCRIPT, CB_SETCURSEL, 0, 0);
+ break;
+ }
+ // set the check mark in the 'same as' boxes to the right value for fontid wParam
+ case M_SETSAMEASBOXES:
+ {
+ CheckDlgButton(hwndDlg, IDC_SAMETYPE, (s_rgFontSettings[wParam].sameAsFlags & SAMEASF_FACE ? BST_CHECKED : BST_UNCHECKED));
+ CheckDlgButton(hwndDlg, IDC_SAMESIZE, (s_rgFontSettings[wParam].sameAsFlags & SAMEASF_SIZE ? BST_CHECKED : BST_UNCHECKED));
+ CheckDlgButton(hwndDlg, IDC_SAMESTYLE, (s_rgFontSettings[wParam].sameAsFlags & SAMEASF_STYLE ? BST_CHECKED : BST_UNCHECKED));
+ CheckDlgButton(hwndDlg, IDC_SAMECOLOUR, (s_rgFontSettings[wParam].sameAsFlags & SAMEASF_COLOUR ? BST_CHECKED : BST_UNCHECKED));
+ break;
+ }
+ // set the disabled flag on the 'same as' checkboxes to the values for fontid wParam
+ case M_REFRESHSAMEASBOXES:
+ {
+ BOOL bSameAsNone = (FLT_SAME_AS_NONE == s_rgFontSettings[wParam].sameAs);
+
+ EnableWindow(GetDlgItem(hwndDlg, IDC_SAMETYPE), !bSameAsNone);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_SAMESIZE), !bSameAsNone);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_SAMESTYLE), !bSameAsNone);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_SAMECOLOUR), !bSameAsNone);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_TYPEFACE), bSameAsNone || !(s_rgFontSettings[wParam].sameAsFlags & SAMEASF_FACE));
+ EnableWindow(GetDlgItem(hwndDlg, IDC_SCRIPT), bSameAsNone || !(s_rgFontSettings[wParam].sameAsFlags & SAMEASF_FACE));
+ EnableWindow(GetDlgItem(hwndDlg, IDC_FONTSIZE), bSameAsNone || !(s_rgFontSettings[wParam].sameAsFlags & SAMEASF_SIZE));
+ EnableWindow(GetDlgItem(hwndDlg, IDC_BOLD), bSameAsNone || !(s_rgFontSettings[wParam].sameAsFlags & SAMEASF_STYLE));
+ EnableWindow(GetDlgItem(hwndDlg, IDC_ITALIC), bSameAsNone || !(s_rgFontSettings[wParam].sameAsFlags & SAMEASF_STYLE));
+ EnableWindow(GetDlgItem(hwndDlg, IDC_UNDERLINE), bSameAsNone || !(s_rgFontSettings[wParam].sameAsFlags & SAMEASF_STYLE));
+ EnableWindow(GetDlgItem(hwndDlg, IDC_COLOUR), bSameAsNone || !(s_rgFontSettings[wParam].sameAsFlags & SAMEASF_COLOUR));
+ break;
+ }
+ // remake the sample edit box font based on the settings in the controls
+ case M_REMAKESAMPLE:
+ {
+ LOGFONTA lf;
+
+ if (hFontSample)
+ {
+ SendDlgItemMessage(hwndDlg, IDC_SAMPLE, WM_SETFONT, SendDlgItemMessage(hwndDlg, IDC_FONTID, WM_GETFONT, 0, 0), 0);
+ DeleteObject(hFontSample);
+ }
+ lf.lfHeight = GetDlgItemInt(hwndDlg, IDC_FONTSIZE, NULL, FALSE);
+ {
+ HDC hdc=GetDC(NULL);
+ lf.lfHeight=-MulDiv(lf.lfHeight, GetDeviceCaps(hdc, LOGPIXELSY), 72);
+ ReleaseDC(NULL,hdc);
+ }
+ lf.lfWidth = 0;
+ lf.lfEscapement = 0;
+ lf.lfOrientation = 0;
+ lf.lfWeight = (IsDlgButtonChecked(hwndDlg, IDC_BOLD) ? FW_BOLD : FW_NORMAL);
+ lf.lfItalic = (BYTE)IsDlgButtonChecked(hwndDlg, IDC_ITALIC);
+ lf.lfUnderline = (BYTE)IsDlgButtonChecked(hwndDlg, IDC_UNDERLINE);
+ lf.lfStrikeOut = 0;
+ lf.lfCharSet = (BYTE)SendDlgItemMessage(hwndDlg, IDC_SCRIPT, CB_GETITEMDATA, SendDlgItemMessage(hwndDlg, IDC_SCRIPT, CB_GETCURSEL, 0, 0), 0);
+ lf.lfOutPrecision = OUT_DEFAULT_PRECIS;
+ lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
+ lf.lfQuality = DEFAULT_QUALITY;
+ lf.lfPitchAndFamily = (DEFAULT_PITCH | FF_DONTCARE);
+ GetDlgItemTextA(hwndDlg, IDC_TYPEFACE, lf.lfFaceName, sizeof(lf.lfFaceName));
+ if (NULL != (hFontSample = CreateFontIndirectA(&lf)))
+ SendDlgItemMessage(hwndDlg, IDC_SAMPLE, WM_SETFONT, (WPARAM)hFontSample, TRUE);
+ break;
+ }
+ // copy the 'same as' settings for fontid wParam from their sources
+ case M_RECALCONEFONT:
+ {
+ if (FLT_SAME_AS_NONE != s_rgFontSettings[wParam].sameAs)
+ {
+ SFontSettings* pSameAs = ((FLT_SAME_AS_MIRANDA == s_rgFontSettings[wParam].sameAs)
+ ? &s_rgFontSettingsMiranda[wParam]
+ : &s_rgFontSettings[s_rgFontSettings[wParam].sameAs]
+ );
+
+ if (s_rgFontSettings[wParam].sameAsFlags & SAMEASF_FACE)
+ {
+ lstrcpyA(s_rgFontSettings[wParam].szFace, pSameAs->szFace);
+ s_rgFontSettings[wParam].charset = pSameAs->charset;
+ }
+ if (s_rgFontSettings[wParam].sameAsFlags & SAMEASF_SIZE)
+ s_rgFontSettings[wParam].size = pSameAs->size;
+ if (s_rgFontSettings[wParam].sameAsFlags & SAMEASF_STYLE)
+ s_rgFontSettings[wParam].style = pSameAs->style;
+ if (s_rgFontSettings[wParam].sameAsFlags & SAMEASF_COLOUR)
+ s_rgFontSettings[wParam].colour = pSameAs->colour;
+ }
+ break;
+ }
+ // recalculate the 'same as' settings for all fonts but wParam
+ case M_RECALCOTHERFONTS:
+ {
+ int nFont;
+ int nDepth;
+ int nRecalcedFonts = 1;
+ int nRecalcDepth;
+ int nFontId = (int)wParam;
+ int nSameAs;
+
+ for (nRecalcDepth = 0; nRecalcedFonts < FLT_FONTIDS && nRecalcDepth < FLT_FONTIDS; nRecalcDepth++)
+ {
+ for (nFont = 0; nFont < FLT_FONTIDS; nFont++)
+ {
+ if (nFontId == nFont)
+ continue;
+
+ nSameAs = s_rgFontSettings[nFont].sameAs;
+ for (nDepth = 0; nDepth < nRecalcDepth; nDepth++)
+ {
+ if (FLT_SAME_AS_NONE == nSameAs || FLT_SAME_AS_MIRANDA == nSameAs || nFontId == nSameAs)
+ break;
+
+ nSameAs = s_rgFontSettings[nSameAs].sameAs;
+ }
+ if (nDepth == nRecalcDepth)
+ {
+ if (nFontId == nSameAs)
+ {
+ SendMessage(hwndDlg, M_RECALCONEFONT, nFont, 0);
+ nRecalcedFonts++;
+ }
+ else if (FLT_SAME_AS_NONE == nSameAs || FLT_SAME_AS_MIRANDA == nSameAs)
+ nRecalcedFonts++;
+ }
+ }
+ }
+ break;
+ }
+ //save the font settings from the controls to font wParam
+ case M_SAVEFONT:
+ {
+ s_rgFontSettings[wParam].sameAsFlags = (IsDlgButtonChecked(hwndDlg, IDC_SAMETYPE) ? SAMEASF_FACE : 0)
+ | (IsDlgButtonChecked(hwndDlg, IDC_SAMESIZE) ? SAMEASF_SIZE : 0)
+ | (IsDlgButtonChecked(hwndDlg, IDC_SAMESTYLE) ? SAMEASF_STYLE : 0)
+ | (IsDlgButtonChecked(hwndDlg, IDC_SAMECOLOUR) ? SAMEASF_COLOUR : 0);
+ s_rgFontSettings[wParam].sameAs = (BYTE)SendDlgItemMessage(hwndDlg
+ , IDC_SAMEAS
+ , CB_GETITEMDATA
+ , SendDlgItemMessage(hwndDlg, IDC_SAMEAS, CB_GETCURSEL, 0, 0)
+ , 0
+ );
+ GetDlgItemTextA(hwndDlg, IDC_TYPEFACE, s_rgFontSettings[wParam].szFace, sizeof(s_rgFontSettings[wParam].szFace));
+ s_rgFontSettings[wParam].charset = (BYTE)SendDlgItemMessage(hwndDlg
+ , IDC_SCRIPT
+ , CB_GETITEMDATA
+ , SendDlgItemMessage(hwndDlg, IDC_SCRIPT, CB_GETCURSEL, 0, 0)
+ , 0
+ );
+ s_rgFontSettings[wParam].size = (char)GetDlgItemInt(hwndDlg, IDC_FONTSIZE, NULL, FALSE);
+ s_rgFontSettings[wParam].style= (IsDlgButtonChecked(hwndDlg, IDC_BOLD) ? DBFONTF_BOLD : 0)
+ | (IsDlgButtonChecked(hwndDlg, IDC_ITALIC) ? DBFONTF_ITALIC : 0)
+ | (IsDlgButtonChecked(hwndDlg, IDC_UNDERLINE) ? DBFONTF_UNDERLINE : 0);
+ s_rgFontSettings[wParam].colour = SendDlgItemMessage(hwndDlg, IDC_COLOUR, CPM_GETCOLOUR, 0, 0);
+ break;
+ }
+ // load font wParam into the controls
+ case M_LOADFONT:
+ {
+ LOGFONTA lf;
+ COLORREF colour;
+
+ SetDlgItemTextA(hwndDlg, IDC_TYPEFACE, s_rgFontSettings[wParam].szFace);
+ SendMessage(hwndDlg, M_FILLSCRIPTCOMBO, wParam, 0);
+ SetDlgItemInt(hwndDlg, IDC_FONTSIZE, s_rgFontSettings[wParam].size, FALSE);
+ CheckDlgButton(hwndDlg, IDC_BOLD, ((s_rgFontSettings[wParam].style & DBFONTF_BOLD) ? BST_CHECKED : BST_UNCHECKED));
+ CheckDlgButton(hwndDlg, IDC_ITALIC, ((s_rgFontSettings[wParam].style & DBFONTF_ITALIC) ? BST_CHECKED : BST_UNCHECKED));
+ CheckDlgButton(hwndDlg, IDC_UNDERLINE, ((s_rgFontSettings[wParam].style & DBFONTF_UNDERLINE) ? BST_CHECKED : BST_UNCHECKED));
+ GetDefaultFontSetting(TRUE, wParam, &lf, &colour);
+ SendDlgItemMessage(hwndDlg, IDC_COLOUR, CPM_SETDEFAULTCOLOUR, 0, colour);
+ SendDlgItemMessage(hwndDlg, IDC_COLOUR, CPM_SETCOLOUR, 0, s_rgFontSettings[wParam].colour);
+ break;
+ }
+ // guess suitable values for the 'same as' checkboxes for fontId wParam
+ case M_GUESSSAMEASBOXES:
+ {
+ s_rgFontSettings[wParam].sameAsFlags = 0;
+ if (FLT_SAME_AS_NONE != s_rgFontSettings[wParam].sameAs)
+ {
+ SFontSettings* pSameAs = ((FLT_SAME_AS_MIRANDA == s_rgFontSettings[wParam].sameAs)
+ ? &s_rgFontSettingsMiranda[wParam]
+ : &s_rgFontSettings[s_rgFontSettings[wParam].sameAs]
+ );
+
+ if (!lstrcmpA(s_rgFontSettings[wParam].szFace, pSameAs->szFace) && s_rgFontSettings[wParam].charset == pSameAs->charset)
+ s_rgFontSettings[wParam].sameAsFlags |= SAMEASF_FACE;
+ if (s_rgFontSettings[wParam].size == pSameAs->size)
+ s_rgFontSettings[wParam].sameAsFlags |= SAMEASF_SIZE;
+ if (s_rgFontSettings[wParam].style == pSameAs->style)
+ s_rgFontSettings[wParam].sameAsFlags |= SAMEASF_STYLE;
+ if (s_rgFontSettings[wParam].colour == pSameAs->colour)
+ s_rgFontSettings[wParam].sameAsFlags |= SAMEASF_COLOUR;
+ SendMessage(hwndDlg,M_SETSAMEASBOXES,wParam,0);
+ }
+ break;
+ }
+ case WM_CTLCOLORSTATIC:
+ {
+ if ((HWND)lParam == GetDlgItem(hwndDlg, IDC_SAMPLE))
+ {
+ SetTextColor((HDC)wParam, SendDlgItemMessage(hwndDlg, IDC_COLOUR, CPM_GETCOLOUR, 0, 0));
+ SetBkColor((HDC)wParam, GetSysColor(COLOR_3DFACE));
+ return (BOOL)GetSysColorBrush(COLOR_3DFACE);
+ }
+ break;
+ }
+ case WM_HSCROLL:
+ {
+ if (wParam != TB_ENDTRACK)
+ {
+ int nPos;
+ char szPercent[20];
+
+ nPos = (BYTE)SendDlgItemMessage(hwndDlg, IDC_SLIDER_OPACITY, TBM_GETPOS, 0, 0);
+ fcOpt.thumbAlpha = (BYTE)(( nPos * 255 ) / 100 );
+ SetThumbsOpacity(fcOpt.thumbAlpha);
+
+ wsprintfA(szPercent, "%d%%", nPos);
+ SetDlgItemTextA(hwndDlg, IDC_OPACITY, szPercent);
+ SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
+ }
+ break;
+ }
+ case WM_COMMAND:
+ {
+ int nFontId = SendDlgItemMessage(hwndDlg, IDC_FONTID, CB_GETITEMDATA
+ , SendDlgItemMessage(hwndDlg, IDC_FONTID, CB_GETCURSEL, 0, 0)
+ , 0
+ );
+
+ switch (LOWORD(wParam))
+ {
+ case IDC_DRAWBORDER:
+ {
+ SendMessage(hwndDlg, M_REFRESHBORDERPICKERS, 0, 0);
+ break;
+ }
+ case IDC_BROWSE:
+ {
+ char str[MAX_PATH];
+ OPENFILENAMEA ofn={0};
+ char filter[512];
+
+ GetDlgItemTextA(hwndDlg, IDC_FILENAME, str, sizeof(str));
+ ofn.lStructSize = sizeof(OPENFILENAMEA);
+ ofn.hwndOwner = hwndDlg;
+ ofn.hInstance = NULL;
+ CallService(MS_UTILS_GETBITMAPFILTERSTRINGS, sizeof(filter), (LPARAM)filter);
+ ofn.lpstrFilter = filter;
+ ofn.lpstrFile = str;
+ ofn.Flags = OFN_FILEMUSTEXIST | OFN_HIDEREADONLY;
+ ofn.nMaxFile = sizeof(str);
+ ofn.nMaxFileTitle = MAX_PATH;
+ ofn.lpstrDefExt = "bmp";
+ if (!GetOpenFileNameA(&ofn))
+ return FALSE;
+ SetDlgItemTextA(hwndDlg, IDC_FILENAME, str);
+ break;
+ }
+ case IDC_FILENAME:
+ {
+ if (EN_CHANGE != HIWORD(wParam) || (HWND)lParam != GetFocus())
+ return FALSE;
+ break;
+ }
+ case IDC_BITMAP:
+ {
+ SendMessage(hwndDlg, M_REFRESHBKGBOXES, 0, 0);
+ break;
+ }
+ case IDC_FONTID:
+ {
+ if (CBN_SELCHANGE == HIWORD(wParam))
+ SendMessage(hwndDlg, M_REBUILDFONTGROUP, 0, 0);
+ return FALSE;
+ }
+ case IDC_SAMETYPE:
+ case IDC_SAMESIZE:
+ case IDC_SAMESTYLE:
+ case IDC_SAMECOLOUR:
+ {
+ SendMessage(hwndDlg, M_SAVEFONT, nFontId, 0);
+ SendMessage(hwndDlg, M_RECALCONEFONT, nFontId, 0);
+ SendMessage(hwndDlg, M_RECALCOTHERFONTS, nFontId, 0);
+ SendMessage(hwndDlg, M_LOADFONT, nFontId, 0);
+ SendMessage(hwndDlg, M_REFRESHSAMEASBOXES, nFontId, 0);
+ SendMessage(hwndDlg, M_REMAKESAMPLE, 0, 0);
+ break;
+ }
+ case IDC_SAMEAS:
+ {
+ if (CBN_SELCHANGE != HIWORD(wParam))
+ return FALSE;
+ SendMessage(hwndDlg, M_SAVEFONT, nFontId, 0);
+ SendMessage(hwndDlg, M_GUESSSAMEASBOXES, nFontId, 0);
+ SendMessage(hwndDlg, M_REFRESHSAMEASBOXES, nFontId, 0);
+ break;
+ }
+ case IDC_TYPEFACE:
+ case IDC_SCRIPT:
+ case IDC_FONTSIZE:
+ {
+ if (CBN_EDITCHANGE != HIWORD(wParam) && CBN_SELCHANGE != HIWORD(wParam))
+ return FALSE;
+ if (CBN_SELCHANGE == HIWORD(wParam))
+ SendDlgItemMessage(hwndDlg, LOWORD(wParam), CB_SETCURSEL, SendDlgItemMessage(hwndDlg, LOWORD(wParam), CB_GETCURSEL, 0, 0), 0);
+ if (IDC_TYPEFACE == LOWORD(wParam))
+ SendMessage(hwndDlg, M_FILLSCRIPTCOMBO, nFontId, 0);
+ // FALL THRU
+ }
+ case IDC_BOLD:
+ case IDC_ITALIC:
+ case IDC_UNDERLINE:
+ case IDC_COLOUR:
+ {
+ SendMessage(hwndDlg, M_SAVEFONT, nFontId, 0);
+ //SendMessage(hwndDlg, M_GUESSSAMEASBOXES, nFontId, 0);
+ //SendMessage(hwndDlg, M_REFRESHSAMEASBOXES, nFontId, 0);
+ SendMessage(hwndDlg, M_RECALCOTHERFONTS, nFontId, 0);
+ SendMessage(hwndDlg, M_REMAKESAMPLE, 0, 0);
+ break;
+ }
+ case IDC_SAMPLE:
+ return 0;
+ }
+ SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
+ break;
+ }
+ case WM_NOTIFY:
+ {
+ LPNMHDR phdr = (LPNMHDR)(lParam);
+
+ if (0 == phdr->idFrom)
+ {
+ switch (phdr->code)
+ {
+ case PSN_APPLY:
+ {
+ int i;
+ char str[20];
+ //BOOL bSuccess = FALSE;
+
+ // Border
+ DBWriteContactSettingByte(NULL, sModule, "DrawBorder", (BYTE)IsDlgButtonChecked(hwndDlg, IDC_DRAWBORDER));
+ {
+ COLORREF col;
+
+ col = SendDlgItemMessage(hwndDlg, IDC_LTEDGESCOLOR, CPM_GETCOLOUR, 0, 0);
+ DBWriteContactSettingDword(NULL, sModule, "LTEdgesColor", col);
+ col = SendDlgItemMessage(hwndDlg, IDC_RBEDGESCOLOR, CPM_GETCOLOUR, 0, 0);
+ DBWriteContactSettingDword(NULL, sModule, "RBEdgesColor", col);
+ }
+
+ // Backgroud
+ {
+ COLORREF col;
+
+ col = SendDlgItemMessage(hwndDlg, IDC_BKGCOLOUR, CPM_GETCOLOUR, 0, 0);
+ DBWriteContactSettingDword(NULL, sModule, "BkColor", col);
+ }
+ DBWriteContactSettingByte(NULL, sModule, "BkUseBitmap", (BYTE)IsDlgButtonChecked(hwndDlg, IDC_BITMAP));
+ {
+ char str[MAX_PATH];
+
+ GetDlgItemTextA(hwndDlg, IDC_FILENAME, str, sizeof(str));
+ DBWriteContactSettingString(NULL, sModule, "BkBitmap", str);
+ }
+ {
+ WORD flags = 0;
+
+ if (IsDlgButtonChecked(hwndDlg, IDC_STRETCHH))
+ flags |= CLB_STRETCHH;
+ if (IsDlgButtonChecked(hwndDlg, IDC_STRETCHV))
+ flags |= CLB_STRETCHV;
+ if (IsDlgButtonChecked(hwndDlg, IDC_TILEH))
+ flags |= CLBF_TILEH;
+ if (IsDlgButtonChecked(hwndDlg, IDC_TILEV))
+ flags |= CLBF_TILEV;
+ if (IsDlgButtonChecked(hwndDlg, IDC_PROPORTIONAL))
+ flags |= CLBF_PROPORTIONAL;
+ DBWriteContactSettingWord(NULL, sModule, "BkBitmapOpt", flags);
+ }
+
+ DBWriteContactSettingByte(NULL, sModule, "Opacity"
+ , (BYTE)SendDlgItemMessage(hwndDlg, IDC_SLIDER_OPACITY, TBM_GETPOS, 0, 0)
+ );
+
+ for (i = 0; i < FLT_FONTIDS; i++)
+ {
+ wsprintfA(str, "Font%dName", i);
+ DBWriteContactSettingString(NULL, sModule, str, s_rgFontSettings[i].szFace);
+ wsprintfA(str, "Font%dSet", i);
+ DBWriteContactSettingByte(NULL, sModule, str, s_rgFontSettings[i].charset);
+ wsprintfA(str, "Font%dSize", i);
+ DBWriteContactSettingByte(NULL, sModule, str, s_rgFontSettings[i].size);
+ wsprintfA(str, "Font%dSty", i);
+ DBWriteContactSettingByte(NULL, sModule, str, s_rgFontSettings[i].style);
+ wsprintfA(str, "Font%dCol", i);
+ DBWriteContactSettingDword(NULL, sModule, str, s_rgFontSettings[i].colour);
+ wsprintfA(str, "Font%dAs", i);
+ DBWriteContactSettingWord(NULL, sModule, str, MAKEWORD(s_rgFontSettings[i].sameAs, s_rgFontSettings[i].sameAsFlags));
+ }
+
+ ApplyOptionsChanges();
+ OnStatusChanged();
+ return TRUE;
+ }
+ case PSN_RESET:
+ //case PSN_KILLACTIVE:
+ {
+ fcOpt.thumbAlpha = (BYTE)((double)DBGetContactSettingByte(NULL, sModule, "Opacity", 100) * 2.55);
+ SetThumbsOpacity(fcOpt.thumbAlpha);
+ break;
+ }
+ }
+ }
+ break;
+ }
+ case WM_DESTROY:
+ {
+ if (hFontSample)
+ {
+ SendDlgItemMessage(hwndDlg, IDC_SAMPLE, WM_SETFONT, SendDlgItemMessage(hwndDlg, IDC_FONTID, WM_GETFONT, 0, 0), 0);
+ DeleteObject(hFontSample);
+ }
+ break;
+ }
+
+ }
+ return FALSE;
+}
+
diff --git a/plugins/FloatingContacts/resource.h b/plugins/FloatingContacts/resource.h
new file mode 100644
index 0000000000..fec93538d8
--- /dev/null
+++ b/plugins/FloatingContacts/resource.h
@@ -0,0 +1,75 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by Script.rc
+//
+#define IDD_OPT_FLTCONT 101
+#define IDI_ICON1 103
+#define IDI_HIDE 103
+#define IDI_SHOW 105
+#define IDD_OPT_FNT 106
+#define IDD_OPT_SKIN 106
+#define IDC_SLIDER_OPACITY 1001
+#define IDC_OPACITY 1002
+#define IDC_CHK_HIDE_OFFLINE 1003
+#define IDC_CHK_STICK 1004
+#define IDC_CHK_WIDTH 1005
+#define IDC_LBL_WIDTH 1006
+#define IDC_TXT_WIDTH 1007
+#define IDC_WIDTHSPIN 1008
+#define IDC_TXT_TIMEIN 1009
+#define IDC_TIMEINSPIN 1010
+#define IDC_TXT_TOTOPTIME 1011
+#define IDC_CHK_HIDE_ALL 1012
+#define IDC_CHK_DEF_BACKGROUND 1013
+#define IDC_TOTOPTIMESPIN 1013
+#define IDC_CHK_HIDE_WHEN_FULSCREEN 1014
+#define IDC_CHK_TIP 1015
+#define IDC_LBL_TIMEIN 1016
+#define IDC_CHK_TOTOP 1017
+#define IDC_LBL_TOTOP 1018
+#define IDC_CHK_HIDE_WHEN_CLISTSHOW 1019
+#define IDC_CHECK1 1020
+#define IDC_CHK_SINGLECLK 1020
+#define IDC_CHECK2 1021
+#define IDC_CHK_SHOWIDLE 1021
+#define IDC_FONTID 1100
+#define IDC_SAMEAS 1101
+#define IDC_LBL_TIMEIN_CMT 1101
+#define IDC_SAMETYPE 1102
+#define IDC_SAMESIZE 1103
+#define IDC_SAMESTYLE 1104
+#define IDC_SAMECOLOUR 1105
+#define IDC_TYPEFACE 1106
+#define IDC_SCRIPT 1107
+#define IDC_FONTSIZE 1108
+#define IDC_BOLD 1109
+#define IDC_ITALIC 1110
+#define IDC_UNDERLINE 1111
+#define IDC_COLOUR 1112
+#define IDC_SAMPLE 1113
+#define IDC_STSAMETEXT 1114
+#define IDC_STASTEXT 1115
+#define IDC_STHORZBAR 1116
+#define IDC_BKGCOLOUR 1200
+#define IDC_BITMAP 1201
+#define IDC_FILENAME 1202
+#define IDC_BROWSE 1203
+#define IDC_STRETCHH 1204
+#define IDC_STRETCHV 1205
+#define IDC_TILEH 1206
+#define IDC_TILEV 1207
+#define IDC_PROPORTIONAL 1208
+#define IDC_DRAWBORDER 1209
+#define IDC_LTEDGESCOLOR 1210
+#define IDC_RBEDGESCOLOR 1211
+
+// 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 1022
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/plugins/FloatingContacts/show.ico b/plugins/FloatingContacts/show.ico
new file mode 100644
index 0000000000..f924c12891
--- /dev/null
+++ b/plugins/FloatingContacts/show.ico
Binary files differ
diff --git a/plugins/FloatingContacts/stdhdr.h b/plugins/FloatingContacts/stdhdr.h
new file mode 100644
index 0000000000..95e5c6cca7
--- /dev/null
+++ b/plugins/FloatingContacts/stdhdr.h
@@ -0,0 +1,64 @@
+
+#ifndef __STDHDR_H__
+#define __STDHDR_H__
+
+// disable security warnings about "*_s" functions
+#define _CRT_SECURE_NO_DEPRECATE
+
+// disable warnings about underscore in stdc functions
+#pragma warning(disable: 4996)
+
+// Unreferenced formal parameter
+#pragma warning(disable: 4100)
+
+#if _MSC_VER >= 1000
+#pragma once
+#endif // _MSC_VER >= 1000
+
+/////////////////////////////////////////////////////////////////////////////
+//
+
+#define STRICT
+
+#include <windows.h>
+#include <stdio.h>
+#include <assert.h>
+
+#pragma warning ( disable : 4201 ) //nonstandard extension used : nameless struct/union
+#include <commctrl.h>
+
+#define MIRANDA_VER 0x600
+
+#include <newpluginapi.h>
+#include <m_system.h>
+#include <m_system_cpp.h>
+#include <m_skin.h>
+#include <m_utils.h>
+#include <m_langpack.h>
+#include <m_protocols.h>
+#include <m_protosvc.h>
+#include <m_database.h>
+#include <m_message.h>
+//#include "../../include/msgs.h"
+#include <m_file.h>
+#include <m_clist.h>
+#include <m_clui.h>
+#include <m_options.h>
+#include <m_clc.h>
+//#include "../../include/clc.h"
+#include <m_clistint.h>
+#include <m_hotkeys.h>
+
+#include "bitmap_funcs.h"
+
+#include "fltcont.h"
+#include "thumbs.h"
+#include "filedrop.h"
+#include "resource.h"
+
+/////////////////////////////////////////////////////////////////////////////
+
+#endif // #ifndef __STDHDR_H__
+
+/////////////////////////////////////////////////////////////////////////////
+// End Of File stdhdr.h
diff --git a/plugins/FloatingContacts/thumbs.cpp b/plugins/FloatingContacts/thumbs.cpp
new file mode 100644
index 0000000000..ad08865f01
--- /dev/null
+++ b/plugins/FloatingContacts/thumbs.cpp
@@ -0,0 +1,1013 @@
+#include "stdhdr.h"
+#include "Wingdi.h"
+
+ThumbList thumbList;
+
+/////////////////////////////////////////////////////////////////////////////
+// ThumbInfo
+static POINT ptOld;
+static BOOL bMouseDown = FALSE;
+static BOOL bMouseIn = FALSE;
+static BOOL bMouseMoved = FALSE;
+static short nLeft = 0;
+static short nTop = 0;
+static int nOffs = 5;
+static ThumbInfo *pThumbMouseIn = NULL;
+
+static void SnapToScreen( RECT rcThumb, int nX, int nY, int *pX, int *pY )
+{
+ int nWidth;
+ int nHeight;
+
+ assert( NULL != pX );
+ assert( NULL != pY );
+
+ nWidth = rcThumb.right - rcThumb.left;
+ nHeight = rcThumb.bottom - rcThumb.top;
+
+ *pX = nX < ( nOffs + rcScreen.left ) ? rcScreen.left : nX;
+ *pY = nY < ( nOffs + rcScreen.top ) ? rcScreen.top : nY;
+ *pX = *pX > ( rcScreen.right - nWidth - nOffs ) ? ( rcScreen.right - nWidth ) : *pX;
+ *pY = *pY > ( rcScreen.bottom - nHeight - nOffs ) ? ( rcScreen.bottom - nHeight ) : *pY;
+}
+
+ThumbInfo::ThumbInfo()
+{
+ dropTarget = new CDropTarget;
+ dropTarget->AddRef();
+ btAlpha = 255;
+}
+
+ThumbInfo::~ThumbInfo()
+{
+ if(pThumbMouseIn==this){
+ pThumbMouseIn=NULL;
+ KillTimer(hwnd, TIMERID_LEAVE_T);
+ }
+ dropTarget->Release();
+}
+
+void ThumbInfo::GetThumbRect(RECT *rc)
+{
+ rc->left = ptPos.x;
+ rc->top = ptPos.y;
+ rc->right = ptPos.x + szSize.cx;
+ rc->bottom = ptPos.y + szSize.cy;
+}
+
+void ThumbInfo::PositionThumb(short nX, short nY)
+{
+ POINT pos = { nX, nY };
+ HDWP hdwp;
+
+ hdwp = BeginDeferWindowPos(1);
+
+ ThumbInfo *pThumb = this;
+ while (pThumb)
+ {
+ pThumb->PositionThumbWorker( (short)pos.x, (short)pos.y, &pos );
+
+ DeferWindowPos( hdwp,
+ pThumb->hwnd,
+ HWND_TOPMOST,
+ pos.x,
+ pos.y,
+ 0,
+ 0,
+ SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE );
+
+ pThumb->ptPos = pos;
+ pos.x += pThumb->szSize.cx;
+
+ pThumb = fcOpt.bMoveTogether ? thumbList.FindThumb( pThumb->dockOpt.hwndRight ) : NULL;
+ }
+
+ EndDeferWindowPos(hdwp);
+}
+
+void ThumbInfo::PositionThumbWorker(short nX, short nY, POINT *newPos)
+{
+ RECT rc;
+ RECT rcThumb;
+ int nNewX;
+ int nNewY;
+ int nWidth;
+ int nHeight;
+ POINT pt;
+ RECT rcLeft;
+ RECT rcTop;
+ RECT rcRight;
+ RECT rcBottom;
+ BOOL bDocked;
+ BOOL bDockedLeft;
+ BOOL bDockedRight;
+ BOOL bLeading;
+
+ // Get thumb dimnsions
+ GetThumbRect( &rcThumb );
+ nWidth = rcThumb.right - rcThumb.left;
+ nHeight = rcThumb.bottom - rcThumb.top;
+
+ // Docking and screen boundaries check
+ SnapToScreen( rcThumb, nX, nY, &nNewX, &nNewY );
+
+ bLeading = dockOpt.hwndRight != NULL;
+
+ if ( fcOpt.bMoveTogether )
+ {
+ UndockThumbs( this, thumbList.FindThumb( dockOpt.hwndLeft ) );
+ }
+
+
+ for (int i = 0; i < thumbList.getCount(); ++i)
+ {
+ ThumbInfo *pCurThumb = thumbList[i];
+
+ if ( pCurThumb != this )
+ {
+ GetThumbRect( &rcThumb );
+ OffsetRect( &rcThumb, nX - rcThumb.left, nY - rcThumb.top );
+
+ pCurThumb->GetThumbRect( &rc );
+
+ // These are rects we will dock into
+
+ rcLeft.left = rc.left - nOffs;
+ rcLeft.top = rc.top - nOffs;
+ rcLeft.right = rc.left + nOffs;
+ rcLeft.bottom = rc.bottom + nOffs;
+
+ rcTop.left = rc.left - nOffs;
+ rcTop.top = rc.top - nOffs;
+ rcTop.right = rc.right + nOffs;
+ rcTop.bottom = rc.top + nOffs;
+
+ rcRight.left = rc.right - nOffs;
+ rcRight.top = rc.top - nOffs;
+ rcRight.right = rc.right + nOffs;
+ rcRight.bottom = rc.bottom + nOffs;
+
+ rcBottom.left = rc.left - nOffs;
+ rcBottom.top = rc.bottom - nOffs;
+ rcBottom.right = rc.right + nOffs;
+ rcBottom.bottom = rc.bottom + nOffs;
+
+
+ bDockedLeft = FALSE;
+ bDockedRight = FALSE;
+
+ // Upper-left
+ pt.x = rcThumb.left;
+ pt.y = rcThumb.top;
+ bDocked = FALSE;
+
+ if ( PtInRect( &rcRight, pt ) )
+ {
+ nNewX = rc.right;
+ bDocked = TRUE;
+ }
+
+ if ( PtInRect( &rcBottom, pt ) )
+ {
+ nNewY = rc.bottom;
+
+ if ( PtInRect( &rcLeft, pt ) )
+ {
+ nNewX = rc.left;
+ }
+ }
+
+ if ( PtInRect( &rcTop, pt ) )
+ {
+ nNewY = rc.top;
+ bDockedLeft = bDocked;
+ }
+
+ // Upper-right
+ pt.x = rcThumb.right;
+ pt.y = rcThumb.top;
+ bDocked = FALSE;
+
+ if ( !bLeading && PtInRect( &rcLeft, pt ) )
+ {
+ if ( !bDockedLeft )
+ {
+ nNewX = rc.left - nWidth;
+ bDocked = TRUE;
+ }
+ else if ( rc.right == rcThumb.left )
+ {
+ bDocked = TRUE;
+ }
+ }
+
+
+ if ( PtInRect( &rcBottom, pt ) )
+ {
+ nNewY = rc.bottom;
+
+ if ( PtInRect( &rcRight, pt ) )
+ {
+ nNewX = rc.right - nWidth;
+ }
+ }
+
+ if ( !bLeading && PtInRect( &rcTop, pt ) )
+ {
+ nNewY = rc.top;
+ bDockedRight = bDocked;
+ }
+
+ if ( fcOpt.bMoveTogether )
+ {
+ if ( bDockedRight )
+ {
+ DockThumbs( this, pCurThumb, TRUE );
+ }
+
+ if ( bDockedLeft )
+ {
+ DockThumbs( pCurThumb, this, FALSE );
+ }
+ }
+
+ // Lower-left
+ pt.x = rcThumb.left;
+ pt.y = rcThumb.bottom;
+
+ if ( PtInRect( &rcRight, pt ) )
+ {
+ nNewX = rc.right;
+ }
+
+ if ( PtInRect( &rcTop, pt ) )
+ {
+ nNewY = rc.top - nHeight;
+
+ if ( PtInRect( &rcLeft, pt ) )
+ {
+ nNewX = rc.left;
+ }
+ }
+
+
+ // Lower-right
+ pt.x = rcThumb.right;
+ pt.y = rcThumb.bottom;
+
+ if ( !bLeading && PtInRect( &rcLeft, pt ) )
+ {
+ nNewX = rc.left - nWidth;
+ }
+
+ if ( !bLeading && PtInRect( &rcTop, pt ) )
+ {
+ nNewY = rc.top - nHeight;
+
+ if ( PtInRect( &rcRight, pt ) )
+ {
+ nNewX = rc.right - nWidth;
+ }
+ }
+ }
+ }
+
+ // Adjust coords once again
+ SnapToScreen( rcThumb, nNewX, nNewY, &nNewX, &nNewY );
+
+ newPos->x = nNewX;
+ newPos->y = nNewY;
+}
+
+void ThumbInfo::ResizeThumb()
+{
+ HDC hdc = NULL;
+ HFONT hOldFont = NULL;
+ POINT ptText;
+ SIZEL sizeIcon;
+ SIZEL sizeText;
+ RECT rcThumb;
+ int index = FLT_FONTID_NOTONLIST;
+
+ ThumbInfo *pNextThumb = NULL;
+
+ himl = ( HIMAGELIST )CallService( MS_CLIST_GETICONSIMAGELIST, 0, 0 );
+
+ if ( himl == NULL ) return;
+
+ ImageList_GetIconSize_my(himl, sizeIcon);
+
+ hdc = GetWindowDC(hwnd);
+
+ if (!DBGetContactSettingByte(hContact, "CList", "NotOnList", 0))
+ {
+ int nStatus;
+ int nContactStatus;
+ int nApparentMode;
+ char* szProto;
+
+ szProto = (char*)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0);
+
+ if ( NULL != szProto )
+ {
+ nStatus = CallProtoService(szProto, PS_GETSTATUS, 0, 0);
+ nContactStatus = DBGetContactSettingWord(hContact, szProto, "Status", ID_STATUS_OFFLINE);
+ nApparentMode = DBGetContactSettingWord(hContact, szProto, "ApparentMode", 0);
+
+ if ( (nStatus == ID_STATUS_INVISIBLE && nApparentMode == ID_STATUS_ONLINE)
+ || (nStatus != ID_STATUS_INVISIBLE && nApparentMode == ID_STATUS_OFFLINE)
+ )
+ {
+ if (ID_STATUS_OFFLINE == nContactStatus)
+ {
+ index = FLT_FONTID_OFFINVIS;
+ }
+ else
+ {
+ index = FLT_FONTID_INVIS;
+ }
+ }
+ else if (ID_STATUS_OFFLINE == nContactStatus)
+ {
+ index = FLT_FONTID_OFFLINE;
+ }
+ else
+ {
+ index = FLT_FONTID_CONTACTS;
+ }
+ }
+ }
+ else
+ {
+ index = FLT_FONTID_NOTONLIST;
+ }
+
+ hOldFont = (HFONT)SelectObject( hdc, hFont[ index ] );
+
+ // Get text and icon sizes
+ GetTextExtentPoint32( hdc, ptszName, _tcslen( ptszName ), &sizeText );
+
+
+ SelectObject( hdc, hOldFont );
+
+ // Transform text size
+ ptText.x = sizeText.cx;
+ ptText.y = sizeText.cy;
+ LPtoDP( hdc, &ptText, 1 );
+
+
+ szSize.cx = fcOpt.bFixedWidth ? fcOpt.nThumbWidth : sizeIcon.cx + ptText.x + 10;
+ szSize.cy = ( ( sizeIcon.cy > ptText.y ) ? sizeIcon.cy : ptText.y ) + 4;
+
+ SetWindowPos( hwnd,
+ HWND_TOPMOST,
+ 0,
+ 0,
+ szSize.cx,
+ szSize.cy,
+ SWP_NOMOVE | /*SWP_NOZORDER |*/ SWP_NOACTIVATE );
+
+ RefreshContactIcon(0xFFFFFFFF);
+
+ ReleaseDC( hwnd, hdc );
+
+ // Move the docked widnow if needed
+ if (pNextThumb = thumbList.FindThumb(dockOpt.hwndRight))
+ {
+ GetThumbRect( &rcThumb );
+ pNextThumb->PositionThumb( (short)rcThumb.right, (short)rcThumb.top );
+ }
+}
+
+void ThumbInfo::RefreshContactIcon(int iIcon)
+{
+ if ( iIcon == 0xFFFFFFFF || ImageList_GetImageCount(himl)<=iIcon )
+ {
+ this->iIcon = CallService( MS_CLIST_GETCONTACTICON, (WPARAM)hContact, 0 );
+ }
+ else
+ {
+ this->iIcon = iIcon;
+ }
+
+ UpdateContent();
+}
+
+void ThumbInfo::RefreshContactStatus(int idStatus)
+{
+ if ( IsStatusVisible( idStatus ) )
+ {
+ RegisterFileDropping( hwnd, dropTarget );
+ }
+ else
+ {
+ UnregisterFileDropping( hwnd );
+ }
+
+ ShowWindow( hwnd, fcOpt.bHideAll || HideOnFullScreen() || ( fcOpt.bHideOffline && ( !IsStatusVisible( idStatus ) ) ) || (fcOpt.bHideWhenCListShow && bIsCListShow) ? SW_HIDE : SW_SHOWNA );
+}
+
+void ThumbInfo::DeleteContactPos()
+{
+ DBDeleteContactSetting( hContact, sModule, "ThumbsPos" );
+}
+
+void ThumbInfo::OnLButtonDown(short nX, short nY)
+{
+ RECT rc;
+
+ if(bEnableTip && fcOpt.bShowTip) KillTip();
+
+// ptOld.x = nX;
+// ptOld.y = nY;
+
+// ClientToScreen( hwnd, &ptOld );
+
+ GetCursorPos(&ptOld);
+ GetThumbRect(&rc);
+
+ nLeft = (short)rc.left;
+ nTop = (short)rc.top;
+
+ //bMouseIn = FALSE;
+ bMouseDown = TRUE;
+ bMouseMoved = FALSE;
+
+// SetCapture(hwnd);
+}
+
+void ThumbInfo::OnLButtonUp()
+{
+ RECT rcMiranda;
+ RECT rcThumb;
+ RECT rcOverlap;
+
+ if (!bMouseMoved && fcOpt.bUseSingleClick && bMouseIn){
+ PopUpMessageDialog();
+ }
+
+ //ThumbDeselect( TRUE );
+
+ if ( bMouseDown )
+ {
+ bMouseDown = FALSE;
+ SetCursor( LoadCursor( NULL, IDC_ARROW ) );
+
+ // Check whether we shoud remove the window
+ GetWindowRect( hwndMiranda, &rcMiranda );
+ GetThumbRect( &rcThumb );
+
+ if ( IntersectRect( &rcOverlap, &rcMiranda, &rcThumb ) )
+ {
+ if( IsWindowVisible( hwndMiranda ) )
+ {
+ DeleteContactPos( );
+ thumbList.RemoveThumb( this );
+ }
+ }
+ }
+
+ SaveContactsPos();
+}
+
+void ThumbInfo::OnMouseMove(short nX, short nY, WPARAM wParam)
+{
+// if (bMouseDown && !wParam&MK_LBUTTON) OnLButtonUp();
+
+ int dX;
+ int dY;
+ POINT ptNew;
+
+ // Position thumb
+
+ if( bMouseDown )
+ {
+
+ ptNew.x = nX;
+ ptNew.y = nY;
+
+ ClientToScreen( hwnd, &ptNew );
+
+ dX = ptNew.x - ptOld.x;
+ dY = ptNew.y - ptOld.y;
+
+ if(dX || dY){
+ bMouseMoved = TRUE;
+
+ nLeft += (short)dX;
+ nTop += (short)dY;
+
+ PositionThumb( nLeft, nTop );
+ }
+
+ ptOld = ptNew;
+ }
+ else
+ {
+ SetCursor( LoadCursor( NULL, IDC_ARROW ) );
+ }
+
+ // Update selection status
+ if ( !pThumbMouseIn )//
+ {
+ SetTimer( hwnd, TIMERID_LEAVE_T, 10, NULL );
+ pThumbMouseIn=this;
+
+ ThumbSelect( TRUE );
+ }
+ if(bEnableTip && fcOpt.bShowTip && !bMouseDown){
+ WORD tmpTimeIn;
+ POINT pt;
+ RECT rc;
+
+ GetCursorPos(&pt);
+ GetThumbRect(&rc);
+ if(!PtInRect(&rc,pt)){
+ KillTip();
+ return;
+ }
+ if(fTipTimerActive && abs(pt.x-ptTipSt.x)<5 && abs(pt.y-ptTipSt.x)<5){
+ return;
+ }
+ ptTipSt=pt;
+
+ if (fTipTimerActive) {
+ KillTimer(hwnd, TIMERID_HOVER_T);
+ }
+ if (fTipActive) {
+ return;
+ }
+
+ tmpTimeIn = (fcOpt.TimeIn>0)?fcOpt.TimeIn:CallService(MS_CLC_GETINFOTIPHOVERTIME, 0, 0);
+ SetTimer(hwnd, TIMERID_HOVER_T, tmpTimeIn, 0);
+ fTipTimerActive = TRUE;
+ }
+}
+
+void ThumbInfo::ThumbSelect(BOOL bMouse)
+{
+ if ( bMouse )
+ {
+ bMouseIn = TRUE;
+ SetCapture( hwnd );
+ }
+
+ SetThumbOpacity( 255 );
+}
+
+void ThumbInfo::ThumbDeselect(BOOL bMouse)
+{
+ if ( bMouse )
+ {
+ bMouseIn = FALSE;
+ ReleaseCapture();
+ }
+
+ SetThumbOpacity( fcOpt.thumbAlpha );
+}
+
+void ThumbInfo::SetThumbOpacity(BYTE bAlpha)
+{
+ if ( pUpdateLayeredWindow && (bAlpha != btAlpha) )
+ {
+ btAlpha = bAlpha;
+ UpdateContent();
+ }
+}
+
+void ThumbInfo::KillTip()
+{
+ if (fTipTimerActive)
+ {
+ KillTimer(hwnd, TIMERID_HOVER_T);
+ fTipTimerActive = FALSE;
+ }
+
+ if (fTipActive)
+ {
+ CallService("mToolTip/HideTip", 0, 0);
+ fTipActive = FALSE;
+ }
+}
+
+void ThumbInfo::UpdateContent()
+{
+ bmpContent.allocate(szSize.cx, szSize.cy);
+
+ HFONT hOldFont;
+ SIZE size;
+ RECT rc;
+ RECT rcText;
+ DWORD oldColor;
+ int oldBkMode, index = 0;// nStatus;
+ UINT fStyle = ILD_NORMAL;
+
+ HDC hdcDraw = bmpContent.getDC();
+ SetRect(&rc, 0, 0, szSize.cx, szSize.cy);
+
+ if ( NULL != hBmpBackground )
+ {
+ RECT rcBkgnd;
+ BITMAP bmp;
+ HDC hdcBmp;
+ HBITMAP hbmTmp;
+ int x,y;
+ int maxx,maxy;
+ int destw,desth;
+ int width;
+ int height;
+
+ SetRect(&rcBkgnd, 0, 0, szSize.cx, szSize.cy);
+ if (NULL != hLTEdgesPen)
+ InflateRect(&rcBkgnd, -1, -1);
+ width = rcBkgnd.right - rcBkgnd.left;
+ height = rcBkgnd.bottom - rcBkgnd.top;
+
+ GetObject(hBmpBackground, sizeof(bmp), &bmp);
+ hdcBmp = CreateCompatibleDC( hdcDraw );
+ hbmTmp = (HBITMAP)SelectObject( hdcBmp, hBmpBackground );
+
+ maxx = (0 != (nBackgroundBmpUse & CLBF_TILEH) ? rcBkgnd.right : rcBkgnd.left + 1);
+ maxy = (0 != (nBackgroundBmpUse & CLBF_TILEV) ? rcBkgnd.bottom : rcBkgnd.top + 1);
+ switch (nBackgroundBmpUse & CLBM_TYPE)
+ {
+ case CLB_STRETCH:
+ if (0 != (nBackgroundBmpUse & CLBF_PROPORTIONAL))
+ {
+ if (width * bmp.bmHeight < height * bmp.bmWidth)
+ {
+ desth = height;
+ destw = desth * bmp.bmWidth / bmp.bmHeight;
+ }
+ else
+ {
+ destw = width;
+ desth = destw * bmp.bmHeight / bmp.bmWidth;
+ }
+ }
+ else
+ {
+ destw = width;
+ desth = height;
+ }
+ break;
+
+ case CLB_STRETCHH:
+ destw = width;
+ if (0 != (nBackgroundBmpUse & CLBF_PROPORTIONAL))
+ desth = destw * bmp.bmHeight / bmp.bmWidth;
+ else
+ desth = bmp.bmHeight;
+ break;
+
+ case CLB_STRETCHV:
+ desth = height;
+ if (0 != (nBackgroundBmpUse & CLBF_PROPORTIONAL))
+ destw = desth * bmp.bmWidth / bmp.bmHeight;
+ else
+ destw = bmp.bmWidth;
+ break;
+
+ default: //clb_topleft
+ destw = bmp.bmWidth;
+ desth = bmp.bmHeight;
+ break;
+ }
+ SetStretchBltMode(hdcBmp, STRETCH_HALFTONE);
+
+ for (x = rcBkgnd.left; x < maxx; x += destw)
+ {
+ for (y = rcBkgnd.top; y < maxy; y += desth)
+ {
+ StretchBlt( hdcDraw, x, y, destw, desth, hdcBmp, 0, 0, bmp.bmWidth, bmp.bmHeight, SRCCOPY );
+ }
+ }
+
+ SelectObject( hdcBmp, hbmTmp );
+ DeleteDC( hdcBmp );
+ }
+ else
+ {
+ FillRect( hdcDraw, &rc, hBkBrush );
+ }
+
+ if (NULL != hLTEdgesPen)
+ {
+ HPEN hOldPen = (HPEN)SelectObject( hdcDraw, hLTEdgesPen );
+
+ MoveToEx(hdcDraw, 0, 0, NULL);
+ LineTo(hdcDraw, szSize.cx, 0);
+ MoveToEx(hdcDraw, 0, 0, NULL);
+ LineTo(hdcDraw, 0, szSize.cy);
+
+ SelectObject(hdcDraw, hRBEdgesPen);
+
+ MoveToEx(hdcDraw, 0, szSize.cy - 1, NULL);
+ LineTo(hdcDraw, szSize.cx - 1, szSize.cy - 1);
+ MoveToEx(hdcDraw, szSize.cx - 1, szSize.cy - 1, NULL);
+ LineTo(hdcDraw, szSize.cx - 1, 0);
+
+ SelectObject(hdcDraw, hOldPen);
+ //InflateRect(&rc, -1, -1);
+ }
+
+ bmpContent.setAlpha(btAlpha);
+
+ ImageList_GetIconSize_my( himl, size );
+
+ oldBkMode = SetBkMode( hdcDraw, TRANSPARENT );
+
+ if (!DBGetContactSettingByte(hContact, "CList", "NotOnList", 0))
+ {
+ int nStatus;
+ int nContactStatus;
+ int nApparentMode;
+ char* szProto;
+
+
+ szProto = (char*)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0);
+
+ if ( NULL != szProto )
+ {
+ nStatus = CallProtoService(szProto, PS_GETSTATUS, 0, 0);
+ nContactStatus = DBGetContactSettingWord(hContact, szProto, "Status", ID_STATUS_OFFLINE);
+ nApparentMode = DBGetContactSettingWord(hContact, szProto, "ApparentMode", 0);
+
+ if ( (nStatus == ID_STATUS_INVISIBLE && nApparentMode == ID_STATUS_ONLINE) ||
+ (nStatus != ID_STATUS_INVISIBLE && nApparentMode == ID_STATUS_OFFLINE) )
+ {
+ if (ID_STATUS_OFFLINE == nContactStatus)
+ {
+ index = FLT_FONTID_OFFINVIS;
+ }
+ else
+ {
+ index = FLT_FONTID_INVIS;
+ if(fcOpt.bShowIdle && DBGetContactSettingDword(hContact, szProto, "IdleTS", 0)){
+ fStyle|=ILD_BLEND50;
+ }
+ }
+ }
+ else if (ID_STATUS_OFFLINE == nContactStatus)
+ {
+ index = FLT_FONTID_OFFLINE;
+ }
+ else
+ {
+ index = FLT_FONTID_CONTACTS;
+ if(fcOpt.bShowIdle && DBGetContactSettingDword(hContact, szProto, "IdleTS", 0)){
+ fStyle|=ILD_BLEND50;
+ }
+ }
+
+ }
+ }
+ else
+ {
+ index = FLT_FONTID_NOTONLIST;
+ fStyle|=ILD_BLEND50;
+ }
+
+ oldColor = SetTextColor( hdcDraw, tColor[ index ] );
+
+/* ImageList_DrawEx( himl,
+ iIcon,
+ hdcDraw,
+ 2,
+ ( szSize.cy - size.cx ) / 2,
+ 0,
+ 0,
+ CLR_NONE,
+ CLR_NONE,
+ fStyle);
+*/
+ {
+ HICON icon = ImageList_GetIcon(himl, iIcon, ILD_NORMAL);
+ MyBitmap bmptmp(size.cx, size.cy);
+ bmptmp.DrawIcon(icon,0,0);//bmpContent
+ BLENDFUNCTION blend;
+ blend.BlendOp = AC_SRC_OVER;
+ blend.BlendFlags = 0;
+ blend.SourceConstantAlpha = (fStyle&ILD_BLEND50)?128:255;
+ blend.AlphaFormat = AC_SRC_ALPHA;
+ AlphaBlend(hdcDraw, 2,( szSize.cy - size.cx ) / 2, bmptmp.getWidth(), bmptmp.getHeight(), bmptmp.getDC(), 0, 0, bmptmp.getWidth(), bmptmp.getHeight(), blend);
+ DestroyIcon(icon);
+ }
+ SetRect(&rcText, 0, 0, szSize.cx, szSize.cy);
+ rcText.left += size.cx + 4;
+
+ hOldFont = (HFONT)SelectObject( hdcDraw, hFont[ index ] );
+
+ SIZE szText;
+ GetTextExtentPoint32(hdcDraw, ptszName, _tcslen(ptszName), &szText);
+ SetTextColor(hdcDraw, bkColor);
+
+ // simple border
+ bmpContent.DrawText(ptszName, rcText.left-1, (rcText.top + rcText.bottom - szText.cy)/2);
+ bmpContent.DrawText(ptszName, rcText.left+1, (rcText.top + rcText.bottom - szText.cy)/2);
+ bmpContent.DrawText(ptszName, rcText.left, (rcText.top + rcText.bottom - szText.cy)/2-1);
+ bmpContent.DrawText(ptszName, rcText.left, (rcText.top + rcText.bottom - szText.cy)/2+1);
+
+ // blurred border
+ // bmpContent.DrawText(ptszName, rcText.left, (rcText.top + rcText.bottom - szText.cy)/2, 3);
+
+ // text itself
+ SetTextColor(hdcDraw, tColor[index]);
+ bmpContent.DrawText(ptszName, rcText.left, (rcText.top + rcText.bottom - szText.cy)/2);
+
+ SelectObject( hdcDraw, hOldFont );
+
+ SetTextColor( hdcDraw, oldColor );
+ SetBkMode( hdcDraw, oldBkMode );
+
+ if (pUpdateLayeredWindow)
+ {
+ SetWindowLong( hwnd, GWL_EXSTYLE, GetWindowLong(hwnd, GWL_EXSTYLE) | WS_EX_LAYERED );
+
+ RECT rc; GetWindowRect(hwnd, &rc);
+ POINT ptDst = {rc.left, rc.top};
+ POINT ptSrc = {0, 0};
+
+ BLENDFUNCTION blend;
+ blend.BlendOp = AC_SRC_OVER;
+ blend.BlendFlags = 0;
+ blend.SourceConstantAlpha = 255;
+ blend.AlphaFormat = AC_SRC_ALPHA;
+
+ pUpdateLayeredWindow(hwnd, NULL, &ptDst, &szSize, bmpContent.getDC(), &ptSrc, 0xffffffff, &blend, ULW_ALPHA);
+ } else
+ {
+ RedrawWindow(hwnd, NULL, NULL, RDW_INVALIDATE);
+ UpdateWindow(hwnd);
+ }
+}
+
+void ThumbInfo::PopUpMessageDialog( )
+{
+ CallService( MS_CLIST_CONTACTDOUBLECLICKED, (WPARAM)hContact, (LPARAM)0 );
+}
+
+void ThumbInfo::OnTimer(BYTE idTimer)
+{
+ if(idTimer == TIMERID_SELECT_T){
+ KillTimer( hwnd, TIMERID_SELECT_T );
+ ThumbDeselect( FALSE );
+ }
+ if(idTimer == TIMERID_LEAVE_T && !bMouseDown){
+ POINT pt;
+ RECT rc;
+
+ GetCursorPos(&pt);
+ GetThumbRect(&rc);
+ if(!PtInRect(&rc, pt)){
+ KillTimer( hwnd, TIMERID_LEAVE_T );
+ pThumbMouseIn = NULL;
+ ThumbDeselect( TRUE );
+ }
+ }
+ if(bEnableTip && fcOpt.bShowTip && idTimer == TIMERID_HOVER_T){
+ POINT pt;
+ CLCINFOTIP ti = {0};
+ ti.cbSize = sizeof(ti);
+
+ KillTimer(hwnd, TIMERID_HOVER_T);
+ fTipTimerActive = FALSE;
+ GetCursorPos(&pt);
+ if(abs(pt.x-ptTipSt.x)<5 && abs(pt.y-ptTipSt.y)<5){
+ ti.ptCursor = pt;
+
+ fTipActive = TRUE;
+ ti.isGroup = 0;
+ ti.hItem = hContact;
+ ti.isTreeFocused = 0;
+ CallService("mToolTip/ShowTip", 0, (LPARAM)&ti);
+ }
+ }
+}
+
+void DockThumbs( ThumbInfo *pThumbLeft, ThumbInfo *pThumbRight, BOOL bMoveLeft )
+{
+ if ( ( pThumbRight->dockOpt.hwndLeft == NULL ) && ( pThumbLeft->dockOpt.hwndRight == NULL ) )
+ {
+ pThumbRight->dockOpt.hwndLeft = pThumbLeft->hwnd;
+ pThumbLeft->dockOpt.hwndRight = pThumbRight->hwnd;
+ }
+}
+
+
+void UndockThumbs( ThumbInfo *pThumb1, ThumbInfo *pThumb2 )
+{
+ if ( ( pThumb1 == NULL ) || ( pThumb2 == NULL ) )
+ {
+ return;
+ }
+
+ if ( pThumb1->dockOpt.hwndRight == pThumb2->hwnd )
+ {
+ pThumb1->dockOpt.hwndRight = NULL;
+ }
+
+ if ( pThumb1->dockOpt.hwndLeft == pThumb2->hwnd )
+ {
+ pThumb1->dockOpt.hwndLeft = NULL;
+ }
+
+ if ( pThumb2->dockOpt.hwndRight == pThumb1->hwnd )
+ {
+ pThumb2->dockOpt.hwndRight = NULL;
+ }
+
+ if ( pThumb2->dockOpt.hwndLeft == pThumb1->hwnd )
+ {
+ pThumb2->dockOpt.hwndLeft = NULL;
+ }
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// ThumbList
+ThumbList::ThumbList(): LIST<ThumbInfo>(1, cmp)
+{
+}
+
+ThumbList::~ThumbList()
+{
+ for (int i = 0; i < getCount(); ++i)
+ delete (*this)[i];
+ destroy();
+}
+
+ThumbInfo *ThumbList::AddThumb(HWND hwnd, TCHAR *ptszName, HANDLE hContact)
+{
+ ThumbInfo *pThumb = NULL;
+
+ if ( ptszName == NULL ) return( NULL );
+ if ( hContact == NULL ) return( NULL );
+ if ( hwnd == NULL ) return( NULL );
+
+ pThumb = new ThumbInfo;
+
+ if ( pThumb != NULL )
+ {
+ _tcsncpy( pThumb->ptszName, ptszName, USERNAME_LEN - 1 );
+ pThumb->hContact = hContact;
+ pThumb->hwnd = hwnd;
+
+ pThumb->dockOpt.hwndLeft = NULL;
+ pThumb->dockOpt.hwndRight = NULL;
+
+ pThumb->fTipActive = FALSE;
+
+// RegHotkey(szName, hwnd);
+ RegHotkey(hContact, hwnd);
+ }
+
+ insert(pThumb);
+
+ return( pThumb );
+}
+
+void ThumbList::RemoveThumb(ThumbInfo *pThumb)
+{
+ if (!pThumb) return;
+
+ if (fcOpt.bMoveTogether)
+ {
+ UndockThumbs(pThumb, FindThumb(pThumb->dockOpt.hwndLeft));
+ UndockThumbs(pThumb, FindThumb(pThumb->dockOpt.hwndRight));
+ }
+
+ remove(pThumb);
+
+ UnregisterFileDropping( pThumb->hwnd );
+ DestroyWindow( pThumb->hwnd );
+ delete pThumb;
+}
+
+ThumbInfo *ThumbList::FindThumb(HWND hwnd)
+{
+ if (!hwnd) return NULL;
+
+ for (int i = 0; i < getCount(); ++i)
+ if ((*this)[i]->hwnd == hwnd)
+ return (*this)[i];
+
+ return NULL;
+}
+
+ThumbInfo *ThumbList::FindThumbByContact(HANDLE hContact)
+{
+ if (!hContact) return NULL;
+
+ for (int i = 0; i < getCount(); ++i)
+ if ((*this)[i]->hContact == hContact)
+ return (*this)[i];
+
+ return NULL;
+}
+
+int ThumbList::cmp(const ThumbInfo *p1, const ThumbInfo *p2)
+{
+ if ((DWORD)p1->hContact < (DWORD)p2->hContact) return -1;
+ if ((DWORD)p1->hContact > (DWORD)p2->hContact) return +1;
+ return 0;
+}
diff --git a/plugins/FloatingContacts/thumbs.h b/plugins/FloatingContacts/thumbs.h
new file mode 100644
index 0000000000..ee6db80097
--- /dev/null
+++ b/plugins/FloatingContacts/thumbs.h
@@ -0,0 +1,74 @@
+/////////////////////////////////////////////////////////////////////////////
+//
+#define USERNAME_LEN 50
+class CDropTarget;
+
+typedef struct _DockOpt
+{
+ HWND hwndLeft;
+ HWND hwndRight;
+}
+DockOpt;
+
+struct ThumbInfo
+{
+public: // TODO: make private
+ HWND hwnd;
+ TCHAR ptszName[ USERNAME_LEN ];
+ HANDLE hContact;
+ int iIcon;
+ CDropTarget * dropTarget;
+ DockOpt dockOpt;
+ BOOL fTipActive;
+ BOOL fTipTimerActive;
+ POINT ptTipSt;
+
+ BYTE btAlpha;
+ MyBitmap bmpContent;
+
+ POINT ptPos;
+ SIZE szSize;
+
+public:
+ ThumbInfo();
+ ~ThumbInfo();
+
+ void GetThumbRect (RECT *rc);
+ void PositionThumb (short nX, short nY);
+ void PositionThumbWorker (short nX, short nY, POINT *rcNewPos);
+ void ResizeThumb ();
+ void RefreshContactIcon (int iIcon);
+ void RefreshContactStatus (int idStatus);
+ void DeleteContactPos ();
+ void OnLButtonDown (short nX, short nY);
+ void OnLButtonUp ();
+ void OnMouseMove (short nX, short nY, WPARAM wParam);
+ void ThumbSelect (BOOL bMouse);
+ void ThumbDeselect (BOOL bMouse);
+ void SetThumbOpacity (BYTE btAlpha);
+ void KillTip ();
+ void UpdateContent ();
+ void PopUpMessageDialog ();
+ void OnTimer (BYTE idTimer);
+};
+
+void UndockThumbs ( ThumbInfo *pThumb1, ThumbInfo *pThumb2 );
+void DockThumbs ( ThumbInfo *pThumbLeft, ThumbInfo *pThumbRight, BOOL bMoveLeft );
+
+class ThumbList: public LIST<ThumbInfo>
+{
+public:
+ ThumbList();
+ ~ThumbList();
+
+ ThumbInfo* AddThumb (HWND hwnd, TCHAR *ptszName, HANDLE hContact);
+ void RemoveThumb (ThumbInfo *pThumb);
+
+ ThumbInfo* FindThumb (HWND hwnd);
+ ThumbInfo* FindThumbByContact (HANDLE hContact);
+
+private:
+ static int cmp(const ThumbInfo *p1, const ThumbInfo *p2);
+};
+
+extern ThumbList thumbList;
diff --git a/plugins/FloatingContacts/version.h b/plugins/FloatingContacts/version.h
new file mode 100644
index 0000000000..2bc7b1cc21
--- /dev/null
+++ b/plugins/FloatingContacts/version.h
@@ -0,0 +1,29 @@
+#define BUILD_NUM 2
+#define BUILD_NUM_STR "2"
+#define REVISION "$Revision: 1136 $"
+
+#define COREVERSION_NUM 1, 0, 2,
+#define COREVERSION_NUM_STR "1, 0, 2"
+
+#define MINIMAL_COREVERSION 0, 6, 0, 0
+#define MINIMAL_COREVERSION_STR "0, 6, 0, 0"
+
+#ifdef UNICODE
+#define UNICODE_AWARE_STR " (Unicode)"
+#else
+#define UNICODE_AWARE_STR " (Ansi)"
+#endif
+
+#define FILE_VERSION COREVERSION_NUM BUILD_NUM
+#define FILE_VERSION_STR COREVERSION_NUM_STR UNICODE_AWARE_STR " build " BUILD_NUM_STR " " REVISION
+
+#define PRODUCT_VERSION FILE_VERSION
+#define PRODUCT_VERSION_STR FILE_VERSION_STR
+
+#define __PLUGIN_NAME "Floating Contacts" UNICODE_AWARE_STR
+#define __FILENAME "FltContacts.dll"
+#define __DESC "Floating Contacts plugin for Miranda"
+#define __AUTHOR "Iavor Vajarov, Kosh&chka, Victor Pavlychko"
+#define __AUTHOREMAIL "ell-6@ya.ru"
+#define __AUTHORWEB "http://www.miranda-im.org/"
+#define __COPYRIGHT "© 2002-2004 I. Vajarov (ivajarov@code.bg), © 2008 Kosh&chka, V. Pavlychko"
diff --git a/plugins/FloatingContacts/version.rc b/plugins/FloatingContacts/version.rc
new file mode 100644
index 0000000000..8214739c31
--- /dev/null
+++ b/plugins/FloatingContacts/version.rc
@@ -0,0 +1,36 @@
+
+#include <windows.h>
+#include "version.h"
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION FILE_VERSION
+ PRODUCTVERSION PRODUCT_VERSION
+ 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 "FileVersion", FILE_VERSION_STR
+ VALUE "InternalName", __PLUGIN_NAME
+ VALUE "LegalCopyright", __COPYRIGHT
+ VALUE "OriginalFilename", __FILENAME
+ VALUE "ProductName", __PLUGIN_NAME
+ VALUE "ProductVersion", PRODUCT_VERSION_STR
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x0, 1200
+ END
+END