diff --git a/Builds/VisualStudio2010/open-ephys.sln b/Builds/VisualStudio2010/open-ephys.sln
new file mode 100644
index 0000000000000000000000000000000000000000..268aaf6708c52d449fae1c50e70b19cbfcef854a
--- /dev/null
+++ b/Builds/VisualStudio2010/open-ephys.sln
@@ -0,0 +1,18 @@
+Microsoft Visual Studio Solution File, Format Version 11.00
+Project("{8FA1AFF1-2558-DDD8-66E3-3288408D9CDF}") = "open-ephys", "open-ephys.vcxproj", "{92D8FACB-6E9B-1810-EC14-AD5A7FE1CD78}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Win32 = Debug|Win32
+		Release|Win32 = Release|Win32
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{92D8FACB-6E9B-1810-EC14-AD5A7FE1CD78}.Debug|Win32.ActiveCfg = Debug|Win32
+		{92D8FACB-6E9B-1810-EC14-AD5A7FE1CD78}.Debug|Win32.Build.0 = Debug|Win32
+		{92D8FACB-6E9B-1810-EC14-AD5A7FE1CD78}.Release|Win32.ActiveCfg = Release|Win32
+		{92D8FACB-6E9B-1810-EC14-AD5A7FE1CD78}.Release|Win32.Build.0 = Release|Win32
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+EndGlobal
diff --git a/Builds/VisualStudio2010/open-ephys.vcxproj b/Builds/VisualStudio2010/open-ephys.vcxproj
new file mode 100644
index 0000000000000000000000000000000000000000..11963816d598739a17e00e59ab1f04285a3e9feb
--- /dev/null
+++ b/Builds/VisualStudio2010/open-ephys.vcxproj
@@ -0,0 +1,344 @@
+<?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|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectGuid>{92D8FACB-6E9B-1810-EC14-AD5A7FE1CD78}</ProjectGuid>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseOfMfc>false</UseOfMfc>
+    <CharacterSet>MultiByte</CharacterSet>
+    <PlatformToolset>v100</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseOfMfc>false</UseOfMfc>
+    <CharacterSet>MultiByte</CharacterSet>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <PlatformToolset>v100</PlatformToolset>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings" />
+  <ImportGroup Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup>
+    <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">.\Debug\bin\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">.\Debug\</IntDir>
+    <TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">open-ephys</TargetName>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">.\Release\bin\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">.\Release\</IntDir>
+    <TargetName Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">open-ephys</TargetName>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <IncludePath>..\..\windeps\include;$(VCInstallDir)include;$(VCInstallDir)atlmfc\include;$(WindowsSDK_IncludePath);</IncludePath>
+    <LibraryPath>..\..\windeps\lib;$(VCInstallDir)lib;$(VCInstallDir)atlmfc\lib;$(WindowsSDK_LibraryPath_x86);</LibraryPath>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <IncludePath>..\..\windeps\include;$(VCInstallDir)include;$(VCInstallDir)atlmfc\include;$(WindowsSDK_IncludePath);</IncludePath>
+    <LibraryPath>..\..\windeps\lib;$(VCInstallDir)lib;$(VCInstallDir)atlmfc\lib;$(WindowsSDK_LibraryPath_x86);</LibraryPath>
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <Midl>
+      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <MkTypLibCompatible>true</MkTypLibCompatible>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <TargetEnvironment>Win32</TargetEnvironment>
+      <HeaderFileName />
+    </Midl>
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
+      <AdditionalIncludeDirectories>C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>NOMINMAX;_WIN32;WIN32;_WINDOWS;DEBUG;_DEBUG;JUCER_VS2010_78A501D=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+      <RuntimeTypeInfo>true</RuntimeTypeInfo>
+      <PrecompiledHeader />
+      <AssemblerListingLocation>.\Debug\</AssemblerListingLocation>
+      <ObjectFileName>.\Debug\</ObjectFileName>
+      <ProgramDataBaseFileName>.\Debug\</ProgramDataBaseFileName>
+      <WarningLevel>Level3</WarningLevel>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <DisableSpecificWarnings>4716</DisableSpecificWarnings>
+    </ClCompile>
+    <ResourceCompile>
+      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ResourceCompile>
+    <Link>
+      <OutputFile>.\Debug\bin\open-ephys.exe</OutputFile>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <IgnoreSpecificDefaultLibraries>libcmt.lib; msvcrt.lib;;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <ProgramDatabaseFile>.\Debug\open-ephys.pdb</ProgramDatabaseFile>
+      <SubSystem>Windows</SubSystem>
+      <TargetMachine>MachineX86</TargetMachine>
+      <AdditionalDependencies>setupapi.lib;opengl32.lib;glu32.lib;ftgl.lib;libftdi.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalLibraryDirectories>C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Lib</AdditionalLibraryDirectories>
+    </Link>
+    <Bscmake>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <OutputFile>.\Debug\open-ephys.bsc</OutputFile>
+    </Bscmake>
+    <PostBuildEvent>
+      <Command>copy ..\..\windeps\dll\* .\Debug\bin\</Command>
+    </PostBuildEvent>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <Midl>
+      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <MkTypLibCompatible>true</MkTypLibCompatible>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <TargetEnvironment>Win32</TargetEnvironment>
+      <HeaderFileName />
+    </Midl>
+    <ClCompile>
+      <Optimization>MaxSpeed</Optimization>
+      <AdditionalIncludeDirectories>C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>NOMINMAX;_WIN32;WIN32;_WINDOWS;NDEBUG;JUCER_VS2010_78A501D=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <RuntimeTypeInfo>true</RuntimeTypeInfo>
+      <PrecompiledHeader />
+      <AssemblerListingLocation>.\Release\</AssemblerListingLocation>
+      <ObjectFileName>.\Release\</ObjectFileName>
+      <ProgramDataBaseFileName>.\Release\</ProgramDataBaseFileName>
+      <WarningLevel>Level3</WarningLevel>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <DisableSpecificWarnings>4716</DisableSpecificWarnings>
+    </ClCompile>
+    <ResourceCompile>
+      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ResourceCompile>
+    <Link>
+      <OutputFile>.\Release\bin\open-ephys.exe</OutputFile>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <IgnoreSpecificDefaultLibraries>%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
+      <GenerateDebugInformation>false</GenerateDebugInformation>
+      <ProgramDatabaseFile>.\Release\open-ephys.pdb</ProgramDatabaseFile>
+      <SubSystem>Windows</SubSystem>
+      <TargetMachine>MachineX86</TargetMachine>
+      <OptimizeReferences>true</OptimizeReferences>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <AdditionalDependencies>setupapi.lib;opengl32.lib;glu32.lib;ftgl.lib;libftdi.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalLibraryDirectories>C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Lib</AdditionalLibraryDirectories>
+    </Link>
+    <Bscmake>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <OutputFile>.\Release\open-ephys.bsc</OutputFile>
+    </Bscmake>
+    <PostBuildEvent>
+      <Command>copy ..\..\windeps\dll\* .\Release\bin\</Command>
+    </PostBuildEvent>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <ClCompile Include="..\..\Source\AccessClass.cpp" />
+    <ClCompile Include="..\..\Source\Network\PracticalSocket.cpp" />
+    <ClCompile Include="..\..\Source\Dsp\Bessel.cpp" />
+    <ClCompile Include="..\..\Source\Dsp\Biquad.cpp" />
+    <ClCompile Include="..\..\Source\Dsp\Butterworth.cpp" />
+    <ClCompile Include="..\..\Source\Dsp\Cascade.cpp" />
+    <ClCompile Include="..\..\Source\Dsp\ChebyshevI.cpp" />
+    <ClCompile Include="..\..\Source\Dsp\ChebyshevII.cpp" />
+    <ClCompile Include="..\..\Source\Dsp\Custom.cpp" />
+    <ClCompile Include="..\..\Source\Dsp\Design.cpp" />
+    <ClCompile Include="..\..\Source\Dsp\Documentation.cpp" />
+    <ClCompile Include="..\..\Source\Dsp\Elliptic.cpp" />
+    <ClCompile Include="..\..\Source\Dsp\Filter.cpp" />
+    <ClCompile Include="..\..\Source\Dsp\Legendre.cpp" />
+    <ClCompile Include="..\..\Source\Dsp\Param.cpp" />
+    <ClCompile Include="..\..\Source\Dsp\PoleFilter.cpp" />
+    <ClCompile Include="..\..\Source\Dsp\RBJ.cpp" />
+    <ClCompile Include="..\..\Source\Dsp\RootFinder.cpp" />
+    <ClCompile Include="..\..\Source\Dsp\State.cpp" />
+    <ClCompile Include="..\..\Source\Audio\AudioComponent.cpp" />
+    <ClCompile Include="..\..\Source\Processors\ArduinoOutput.cpp" />
+    <ClCompile Include="..\..\Source\Processors\EventDetector.cpp" />
+    <ClCompile Include="..\..\Source\Processors\FPGAOutput.cpp" />
+    <ClCompile Include="..\..\Source\Processors\Parameter.cpp" />
+    <ClCompile Include="..\..\Source\Processors\Serial\ofArduino.cpp" />
+    <ClCompile Include="..\..\Source\Processors\Serial\ofSerial.cpp" />
+    <ClCompile Include="..\..\Source\Processors\SpikeDisplayNode.cpp" />
+    <ClCompile Include="..\..\Source\Processors\WiFiOutput.cpp" />
+    <ClCompile Include="..\..\Source\Processors\LfpDisplayNode.cpp" />
+    <ClCompile Include="..\..\Source\Processors\Utilities\Merger.cpp" />
+    <ClCompile Include="..\..\Source\Processors\Utilities\Splitter.cpp" />
+    <ClCompile Include="..\..\Source\Processors\Visualization\SpikePlotting\SpikePlot.cpp" />
+    <ClCompile Include="..\..\Source\Processors\Visualization\SpikePlotting\BaseUIElement.cpp" />
+    <ClCompile Include="..\..\Source\Processors\Visualization\SpikePlotting\GenericAxes.cpp" />
+    <ClCompile Include="..\..\Source\Processors\Visualization\SpikePlotting\PlotUtils.cpp" />
+    <ClCompile Include="..\..\Source\Processors\Visualization\SpikePlotting\ProjectionAxes.cpp" />
+    <ClCompile Include="..\..\Source\Processors\Visualization\SpikePlotting\WaveAxes.cpp" />
+    <ClCompile Include="..\..\Source\Processors\Visualization\SpikeObject.cpp" />
+    <ClCompile Include="..\..\Source\Processors\Visualization\SpikeDisplayCanvas.cpp" />
+    <ClCompile Include="..\..\Source\Processors\Visualization\DataWindow.cpp" />
+    <ClCompile Include="..\..\Source\Processors\Visualization\LfpDisplayCanvas.cpp" />
+    <ClCompile Include="..\..\Source\Processors\Visualization\OpenGLCanvas.cpp" />
+    <ClCompile Include="..\..\Source\Processors\SpikeDetector.cpp" />
+    <ClCompile Include="..\..\Source\Processors\AudioNode.cpp" />
+    <ClCompile Include="..\..\Source\Processors\EventNode.cpp" />
+    <ClCompile Include="..\..\Source\Processors\Editors\FPGAOutputEditor.cpp" />
+    <ClCompile Include="..\..\Source\Processors\Editors\ArduinoOutputEditor.cpp" />
+    <ClCompile Include="..\..\Source\Processors\Editors\ChannelSelector.cpp" />
+    <ClCompile Include="..\..\Source\Processors\Editors\ParameterEditor.cpp" />
+    <ClCompile Include="..\..\Source\Processors\Editors\SpikeDisplayEditor.cpp" />
+    <ClCompile Include="..\..\Source\Processors\Editors\VisualizerEditor.cpp" />
+    <ClCompile Include="..\..\Source\Processors\Editors\MergerEditor.cpp" />
+    <ClCompile Include="..\..\Source\Processors\Editors\ImageIcon.cpp" />
+    <ClCompile Include="..\..\Source\Processors\Editors\WiFiOutputEditor.cpp" />
+    <ClCompile Include="..\..\Source\Processors\Editors\EventNodeEditor.cpp" />
+    <ClCompile Include="..\..\Source\Processors\Editors\SignalGeneratorEditor.cpp" />
+    <ClCompile Include="..\..\Source\Processors\Editors\LfpDisplayEditor.cpp" />
+    <ClCompile Include="..\..\Source\Processors\Editors\SourceNodeEditor.cpp" />
+    <ClCompile Include="..\..\Source\Processors\Editors\SplitterEditor.cpp" />
+    <ClCompile Include="..\..\Source\Processors\Editors\SpikeDetectorEditor.cpp" />
+    <ClCompile Include="..\..\Source\Processors\Editors\AudioEditor.cpp" />
+    <ClCompile Include="..\..\Source\Processors\Editors\FilterEditor.cpp" />
+    <ClCompile Include="..\..\Source\Processors\Editors\GenericEditor.cpp" />
+    <ClCompile Include="..\..\Source\Processors\DataThreads\FileReaderThread.cpp" />
+    <ClCompile Include="..\..\Source\Processors\DataThreads\okFrontPanelDLL.cpp" />
+    <ClCompile Include="..\..\Source\Processors\DataThreads\NetworkThread.cpp" />
+    <ClCompile Include="..\..\Source\Processors\DataThreads\FPGAThread.cpp" />
+    <ClCompile Include="..\..\Source\Processors\DataThreads\DataBuffer.cpp" />
+    <ClCompile Include="..\..\Source\Processors\DataThreads\IntanThread.cpp" />
+    <ClCompile Include="..\..\Source\Processors\DataThreads\DataThread.cpp" />
+    <ClCompile Include="..\..\Source\Processors\RecordNode.cpp" />
+    <ClCompile Include="..\..\Source\Processors\SignalGenerator.cpp" />
+    <ClCompile Include="..\..\Source\Processors\ResamplingNode.cpp" />
+    <ClCompile Include="..\..\Source\Processors\FilterNode.cpp" />
+    <ClCompile Include="..\..\Source\Processors\SourceNode.cpp" />
+    <ClCompile Include="..\..\Source\Processors\GenericProcessor.cpp" />
+    <ClCompile Include="..\..\Source\Processors\ProcessorGraph.cpp" />
+    <ClCompile Include="..\..\Source\UI\EditorViewportButtons.cpp" />
+    <ClCompile Include="..\..\Source\UI\SignalChainManager.cpp" />
+    <ClCompile Include="..\..\Source\UI\EditorViewport.cpp" />
+    <ClCompile Include="..\..\Source\UI\ProcessorList.cpp" />
+    <ClCompile Include="..\..\Source\UI\CustomLookAndFeel.cpp" />
+    <ClCompile Include="..\..\Source\UI\InfoLabel.cpp" />
+    <ClCompile Include="..\..\Source\UI\DataViewport.cpp" />
+    <ClCompile Include="..\..\Source\UI\MessageCenter.cpp" />
+    <ClCompile Include="..\..\Source\UI\ControlPanel.cpp" />
+    <ClCompile Include="..\..\Source\UI\UIComponent.cpp" />
+    <ClCompile Include="..\..\Source\MainWindow.cpp" />
+    <ClCompile Include="..\..\Source\Main.cpp" />
+    <ClCompile Include="..\..\JuceLibraryCode\BinaryData.cpp" />
+    <ClCompile Include="..\..\JuceLibraryCode\JuceLibraryCode1.cpp" />
+    <ClCompile Include="..\..\JuceLibraryCode\JuceLibraryCode2.cpp" />
+    <ClCompile Include="..\..\JuceLibraryCode\JuceLibraryCode3.cpp" />
+    <ClCompile Include="..\..\JuceLibraryCode\JuceLibraryCode4.cpp" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="..\..\Source\AccessClass.h" />
+    <ClInclude Include="..\..\Source\Network\PracticalSocket.h" />
+    <ClInclude Include="..\..\Source\Dsp\Bessel.h" />
+    <ClInclude Include="..\..\Source\Dsp\Biquad.h" />
+    <ClInclude Include="..\..\Source\Dsp\Butterworth.h" />
+    <ClInclude Include="..\..\Source\Dsp\Cascade.h" />
+    <ClInclude Include="..\..\Source\Dsp\ChebyshevI.h" />
+    <ClInclude Include="..\..\Source\Dsp\ChebyshevII.h" />
+    <ClInclude Include="..\..\Source\Dsp\Common.h" />
+    <ClInclude Include="..\..\Source\Dsp\Custom.h" />
+    <ClInclude Include="..\..\Source\Dsp\Design.h" />
+    <ClInclude Include="..\..\Source\Dsp\Dsp.h" />
+    <ClInclude Include="..\..\Source\Dsp\Elliptic.h" />
+    <ClInclude Include="..\..\Source\Dsp\Filter.h" />
+    <ClInclude Include="..\..\Source\Dsp\Layout.h" />
+    <ClInclude Include="..\..\Source\Dsp\Legendre.h" />
+    <ClInclude Include="..\..\Source\Dsp\MathSupplement.h" />
+    <ClInclude Include="..\..\Source\Dsp\Params.h" />
+    <ClInclude Include="..\..\Source\Dsp\PoleFilter.h" />
+    <ClInclude Include="..\..\Source\Dsp\RBJ.h" />
+    <ClInclude Include="..\..\Source\Dsp\RootFinder.h" />
+    <ClInclude Include="..\..\Source\Dsp\SmoothedFilter.h" />
+    <ClInclude Include="..\..\Source\Dsp\State.h" />
+    <ClInclude Include="..\..\Source\Dsp\Types.h" />
+    <ClInclude Include="..\..\Source\Dsp\Utilities.h" />
+    <ClInclude Include="..\..\Source\Audio\AudioComponent.h" />
+    <ClInclude Include="..\..\Source\Processors\ArduinoOutput.h" />
+    <ClInclude Include="..\..\Source\Processors\EventDetector.h" />
+    <ClInclude Include="..\..\Source\Processors\FPGAOutput.h" />
+    <ClInclude Include="..\..\Source\Processors\Parameter.h" />
+    <ClInclude Include="..\..\Source\Processors\Serial\ofArduino.h" />
+    <ClInclude Include="..\..\Source\Processors\Serial\ofConstants.h" />
+    <ClInclude Include="..\..\Source\Processors\Serial\ofSerial.h" />
+    <ClInclude Include="..\..\Source\Processors\SpikeDisplayNode.h" />
+    <ClInclude Include="..\..\Source\Processors\WiFiOutput.h" />
+    <ClInclude Include="..\..\Source\Processors\LfpDisplayNode.h" />
+    <ClInclude Include="..\..\Source\Processors\Utilities\Merger.h" />
+    <ClInclude Include="..\..\Source\Processors\Utilities\Splitter.h" />
+    <ClInclude Include="..\..\Source\Processors\Visualization\SpikePlotting\SpikePlot.h" />
+    <ClInclude Include="..\..\Source\Processors\Visualization\SpikePlotting\BaseUIElement.h" />
+    <ClInclude Include="..\..\Source\Processors\Visualization\SpikePlotting\GenericAxes.h" />
+    <ClInclude Include="..\..\Source\Processors\Visualization\SpikePlotting\PlotUtils.h" />
+    <ClInclude Include="..\..\Source\Processors\Visualization\SpikePlotting\ProjectionAxes.h" />
+    <ClInclude Include="..\..\Source\Processors\Visualization\SpikePlotting\SimpleKeyEvent.h" />
+    <ClInclude Include="..\..\Source\Processors\Visualization\SpikePlotting\WaveAxes.h" />
+    <ClInclude Include="..\..\Source\Processors\Visualization\SpikeObject.h" />
+    <ClInclude Include="..\..\Source\Processors\Visualization\SpikeDisplayCanvas.h" />
+    <ClInclude Include="..\..\Source\Processors\Visualization\Visualizer.h" />
+    <ClInclude Include="..\..\Source\Processors\Visualization\DataWindow.h" />
+    <ClInclude Include="..\..\Source\Processors\Visualization\LfpDisplayCanvas.h" />
+    <ClInclude Include="..\..\Source\Processors\Visualization\OpenGLCanvas.h" />
+    <ClInclude Include="..\..\Source\Processors\SpikeDetector.h" />
+    <ClInclude Include="..\..\Source\Processors\AudioNode.h" />
+    <ClInclude Include="..\..\Source\Processors\EventNode.h" />
+    <ClInclude Include="..\..\Source\Processors\Editors\FPGAOutputEditor.h" />
+    <ClInclude Include="..\..\Source\Processors\Editors\ArduinoOutputEditor.h" />
+    <ClInclude Include="..\..\Source\Processors\Editors\ChannelSelector.h" />
+    <ClInclude Include="..\..\Source\Processors\Editors\ParameterEditor.h" />
+    <ClInclude Include="..\..\Source\Processors\Editors\SpikeDisplayEditor.h" />
+    <ClInclude Include="..\..\Source\Processors\Editors\VisualizerEditor.h" />
+    <ClInclude Include="..\..\Source\Processors\Editors\MergerEditor.h" />
+    <ClInclude Include="..\..\Source\Processors\Editors\ImageIcon.h" />
+    <ClInclude Include="..\..\Source\Processors\Editors\WiFiOutputEditor.h" />
+    <ClInclude Include="..\..\Source\Processors\Editors\EventNodeEditor.h" />
+    <ClInclude Include="..\..\Source\Processors\Editors\SignalGeneratorEditor.h" />
+    <ClInclude Include="..\..\Source\Processors\Editors\LfpDisplayEditor.h" />
+    <ClInclude Include="..\..\Source\Processors\Editors\SourceNodeEditor.h" />
+    <ClInclude Include="..\..\Source\Processors\Editors\SplitterEditor.h" />
+    <ClInclude Include="..\..\Source\Processors\Editors\SpikeDetectorEditor.h" />
+    <ClInclude Include="..\..\Source\Processors\Editors\AudioEditor.h" />
+    <ClInclude Include="..\..\Source\Processors\Editors\FilterEditor.h" />
+    <ClInclude Include="..\..\Source\Processors\Editors\GenericEditor.h" />
+    <ClInclude Include="..\..\Source\Processors\DataThreads\FileReaderThread.h" />
+    <ClInclude Include="..\..\Source\Processors\DataThreads\okFrontPanelDLL.h" />
+    <ClInclude Include="..\..\Source\Processors\DataThreads\NetworkThread.h" />
+    <ClInclude Include="..\..\Source\Processors\DataThreads\FPGAThread.h" />
+    <ClInclude Include="..\..\Source\Processors\DataThreads\DataBuffer.h" />
+    <ClInclude Include="..\..\Source\Processors\DataThreads\IntanThread.h" />
+    <ClInclude Include="..\..\Source\Processors\DataThreads\DataThread.h" />
+    <ClInclude Include="..\..\Source\Processors\RecordNode.h" />
+    <ClInclude Include="..\..\Source\Processors\SignalGenerator.h" />
+    <ClInclude Include="..\..\Source\Processors\ResamplingNode.h" />
+    <ClInclude Include="..\..\Source\Processors\FilterNode.h" />
+    <ClInclude Include="..\..\Source\Processors\SourceNode.h" />
+    <ClInclude Include="..\..\Source\Processors\GenericProcessor.h" />
+    <ClInclude Include="..\..\Source\Processors\ProcessorGraph.h" />
+    <ClInclude Include="..\..\Source\UI\EditorViewportButtons.h" />
+    <ClInclude Include="..\..\Source\UI\SignalChainManager.h" />
+    <ClInclude Include="..\..\Source\UI\EditorViewport.h" />
+    <ClInclude Include="..\..\Source\UI\ProcessorList.h" />
+    <ClInclude Include="..\..\Source\UI\CustomLookAndFeel.h" />
+    <ClInclude Include="..\..\Source\UI\InfoLabel.h" />
+    <ClInclude Include="..\..\Source\UI\DataViewport.h" />
+    <ClInclude Include="..\..\Source\UI\MessageCenter.h" />
+    <ClInclude Include="..\..\Source\UI\ControlPanel.h" />
+    <ClInclude Include="..\..\Source\UI\UIComponent.h" />
+    <ClInclude Include="..\..\Source\MainWindow.h" />
+    <ClInclude Include="..\..\JuceLibraryCode\AppConfig.h" />
+    <ClInclude Include="..\..\JuceLibraryCode\JuceHeader.h" />
+    <ClInclude Include="..\..\JuceLibraryCode\BinaryData.h" />
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets" />
+</Project>
\ No newline at end of file
diff --git a/Builds/VisualStudio2010/open-ephys.vcxproj.filters b/Builds/VisualStudio2010/open-ephys.vcxproj.filters
new file mode 100644
index 0000000000000000000000000000000000000000..eccf8853b1214bfc951a1a00d2b4958fdbff2dc3
--- /dev/null
+++ b/Builds/VisualStudio2010/open-ephys.vcxproj.filters
@@ -0,0 +1,651 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup>
+    <Filter Include="open-ephys">
+      <UniqueIdentifier>{B78BD5C6-A89B-0111-0C5E-ACFD94B107C9}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="open-ephys\Resources">
+      <UniqueIdentifier>{54A5F0A2-18D0-77C1-C41D-FCD97E8C369F}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="open-ephys\Resources\Fonts">
+      <UniqueIdentifier>{4DF2CF07-8CD2-BEA6-2E97-90F31E36F399}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="open-ephys\Resources\Images">
+      <UniqueIdentifier>{262DCEB9-919C-F953-B756-B3E5D4A192BD}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="open-ephys\Resources\Images\Icons">
+      <UniqueIdentifier>{2442E922-1933-9371-14A7-B72EFCB63769}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="open-ephys\Resources\Images\Buttons">
+      <UniqueIdentifier>{48C052A5-026C-7C55-D992-4AA64B68EC6D}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="open-ephys\Source">
+      <UniqueIdentifier>{26871150-DC43-ADFC-0CD8-F18B3EF18ED3}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="open-ephys\Source\Plugins">
+      <UniqueIdentifier>{1D172B45-BC84-A080-B9A6-AEDBCF2FF9E1}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="open-ephys\Source\Network">
+      <UniqueIdentifier>{3C9DBE75-8CDA-3DF5-6D37-AB0501C055F9}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="open-ephys\Source\Dsp">
+      <UniqueIdentifier>{8A26D3EE-21DD-86F1-A447-8BEC62871365}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="open-ephys\Source\Audio">
+      <UniqueIdentifier>{2D549BF5-A738-8204-8C93-0E494C58DAB2}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="open-ephys\Source\Processors">
+      <UniqueIdentifier>{3B2598F1-7B02-E3D4-A09B-367B20D97672}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="open-ephys\Source\Processors\Serial">
+      <UniqueIdentifier>{BE825C10-A046-0824-C18C-358D08C18D78}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="open-ephys\Source\Processors\Utilities">
+      <UniqueIdentifier>{A81F416A-5186-4D5E-E159-A4E41A74C9AB}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="open-ephys\Source\Processors\Visualization">
+      <UniqueIdentifier>{84AAFE68-C197-9A6B-4524-27E33F7D77DE}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="open-ephys\Source\Processors\Visualization\SpikePlotting">
+      <UniqueIdentifier>{9281EF66-B5A5-2D7E-4735-B2D27AE862E9}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="open-ephys\Source\Processors\Editors">
+      <UniqueIdentifier>{B226D1DC-8127-60DF-F9CE-61461D82968B}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="open-ephys\Source\Processors\DataThreads">
+      <UniqueIdentifier>{9504915A-A697-5C7F-E059-D7DAD23F3320}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="open-ephys\Source\UI">
+      <UniqueIdentifier>{3AB2454E-6609-8229-51CB-D99A79A068ED}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Juce Library Code">
+      <UniqueIdentifier>{F7048EA6-F4B2-F31B-E402-E05D678A1111}</UniqueIdentifier>
+    </Filter>
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="..\..\Source\AccessClass.cpp">
+      <Filter>open-ephys\Source</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\Source\Network\PracticalSocket.cpp">
+      <Filter>open-ephys\Source\Network</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\Source\Dsp\Bessel.cpp">
+      <Filter>open-ephys\Source\Dsp</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\Source\Dsp\Biquad.cpp">
+      <Filter>open-ephys\Source\Dsp</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\Source\Dsp\Butterworth.cpp">
+      <Filter>open-ephys\Source\Dsp</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\Source\Dsp\Cascade.cpp">
+      <Filter>open-ephys\Source\Dsp</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\Source\Dsp\ChebyshevI.cpp">
+      <Filter>open-ephys\Source\Dsp</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\Source\Dsp\ChebyshevII.cpp">
+      <Filter>open-ephys\Source\Dsp</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\Source\Dsp\Custom.cpp">
+      <Filter>open-ephys\Source\Dsp</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\Source\Dsp\Design.cpp">
+      <Filter>open-ephys\Source\Dsp</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\Source\Dsp\Documentation.cpp">
+      <Filter>open-ephys\Source\Dsp</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\Source\Dsp\Elliptic.cpp">
+      <Filter>open-ephys\Source\Dsp</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\Source\Dsp\Filter.cpp">
+      <Filter>open-ephys\Source\Dsp</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\Source\Dsp\Legendre.cpp">
+      <Filter>open-ephys\Source\Dsp</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\Source\Dsp\Param.cpp">
+      <Filter>open-ephys\Source\Dsp</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\Source\Dsp\PoleFilter.cpp">
+      <Filter>open-ephys\Source\Dsp</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\Source\Dsp\RBJ.cpp">
+      <Filter>open-ephys\Source\Dsp</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\Source\Dsp\RootFinder.cpp">
+      <Filter>open-ephys\Source\Dsp</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\Source\Dsp\State.cpp">
+      <Filter>open-ephys\Source\Dsp</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\Source\Audio\AudioComponent.cpp">
+      <Filter>open-ephys\Source\Audio</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\Source\Processors\Parameter.cpp">
+      <Filter>open-ephys\Source\Processors</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\Source\Processors\SpikeDisplayNode.cpp">
+      <Filter>open-ephys\Source\Processors</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\Source\Processors\WiFiOutput.cpp">
+      <Filter>open-ephys\Source\Processors</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\Source\Processors\LfpDisplayNode.cpp">
+      <Filter>open-ephys\Source\Processors</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\Source\Processors\Utilities\Merger.cpp">
+      <Filter>open-ephys\Source\Processors\Utilities</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\Source\Processors\Utilities\Splitter.cpp">
+      <Filter>open-ephys\Source\Processors\Utilities</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\Source\Processors\Visualization\SpikePlotting\SpikePlot.cpp">
+      <Filter>open-ephys\Source\Processors\Visualization\SpikePlotting</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\Source\Processors\Visualization\SpikePlotting\BaseUIElement.cpp">
+      <Filter>open-ephys\Source\Processors\Visualization\SpikePlotting</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\Source\Processors\Visualization\SpikePlotting\GenericAxes.cpp">
+      <Filter>open-ephys\Source\Processors\Visualization\SpikePlotting</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\Source\Processors\Visualization\SpikePlotting\PlotUtils.cpp">
+      <Filter>open-ephys\Source\Processors\Visualization\SpikePlotting</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\Source\Processors\Visualization\SpikePlotting\ProjectionAxes.cpp">
+      <Filter>open-ephys\Source\Processors\Visualization\SpikePlotting</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\Source\Processors\Visualization\SpikePlotting\WaveAxes.cpp">
+      <Filter>open-ephys\Source\Processors\Visualization\SpikePlotting</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\Source\Processors\Visualization\SpikeObject.cpp">
+      <Filter>open-ephys\Source\Processors\Visualization</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\Source\Processors\Visualization\SpikeDisplayCanvas.cpp">
+      <Filter>open-ephys\Source\Processors\Visualization</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\Source\Processors\Visualization\DataWindow.cpp">
+      <Filter>open-ephys\Source\Processors\Visualization</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\Source\Processors\Visualization\LfpDisplayCanvas.cpp">
+      <Filter>open-ephys\Source\Processors\Visualization</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\Source\Processors\Visualization\OpenGLCanvas.cpp">
+      <Filter>open-ephys\Source\Processors\Visualization</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\Source\Processors\SpikeDetector.cpp">
+      <Filter>open-ephys\Source\Processors</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\Source\Processors\AudioNode.cpp">
+      <Filter>open-ephys\Source\Processors</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\Source\Processors\EventNode.cpp">
+      <Filter>open-ephys\Source\Processors</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\Source\Processors\Editors\FPGAOutputEditor.cpp">
+      <Filter>open-ephys\Source\Processors\Editors</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\Source\Processors\Editors\ArduinoOutputEditor.cpp">
+      <Filter>open-ephys\Source\Processors\Editors</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\Source\Processors\Editors\ChannelSelector.cpp">
+      <Filter>open-ephys\Source\Processors\Editors</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\Source\Processors\Editors\ParameterEditor.cpp">
+      <Filter>open-ephys\Source\Processors\Editors</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\Source\Processors\Editors\SpikeDisplayEditor.cpp">
+      <Filter>open-ephys\Source\Processors\Editors</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\Source\Processors\Editors\VisualizerEditor.cpp">
+      <Filter>open-ephys\Source\Processors\Editors</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\Source\Processors\Editors\MergerEditor.cpp">
+      <Filter>open-ephys\Source\Processors\Editors</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\Source\Processors\Editors\ImageIcon.cpp">
+      <Filter>open-ephys\Source\Processors\Editors</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\Source\Processors\Editors\WiFiOutputEditor.cpp">
+      <Filter>open-ephys\Source\Processors\Editors</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\Source\Processors\Editors\EventNodeEditor.cpp">
+      <Filter>open-ephys\Source\Processors\Editors</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\Source\Processors\Editors\SignalGeneratorEditor.cpp">
+      <Filter>open-ephys\Source\Processors\Editors</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\Source\Processors\Editors\LfpDisplayEditor.cpp">
+      <Filter>open-ephys\Source\Processors\Editors</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\Source\Processors\Editors\SourceNodeEditor.cpp">
+      <Filter>open-ephys\Source\Processors\Editors</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\Source\Processors\Editors\SplitterEditor.cpp">
+      <Filter>open-ephys\Source\Processors\Editors</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\Source\Processors\Editors\SpikeDetectorEditor.cpp">
+      <Filter>open-ephys\Source\Processors\Editors</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\Source\Processors\Editors\AudioEditor.cpp">
+      <Filter>open-ephys\Source\Processors\Editors</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\Source\Processors\Editors\FilterEditor.cpp">
+      <Filter>open-ephys\Source\Processors\Editors</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\Source\Processors\Editors\GenericEditor.cpp">
+      <Filter>open-ephys\Source\Processors\Editors</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\Source\Processors\DataThreads\FileReaderThread.cpp">
+      <Filter>open-ephys\Source\Processors\DataThreads</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\Source\Processors\DataThreads\okFrontPanelDLL.cpp">
+      <Filter>open-ephys\Source\Processors\DataThreads</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\Source\Processors\DataThreads\NetworkThread.cpp">
+      <Filter>open-ephys\Source\Processors\DataThreads</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\Source\Processors\DataThreads\FPGAThread.cpp">
+      <Filter>open-ephys\Source\Processors\DataThreads</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\Source\Processors\DataThreads\DataBuffer.cpp">
+      <Filter>open-ephys\Source\Processors\DataThreads</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\Source\Processors\DataThreads\IntanThread.cpp">
+      <Filter>open-ephys\Source\Processors\DataThreads</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\Source\Processors\DataThreads\DataThread.cpp">
+      <Filter>open-ephys\Source\Processors\DataThreads</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\Source\Processors\RecordNode.cpp">
+      <Filter>open-ephys\Source\Processors</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\Source\Processors\SignalGenerator.cpp">
+      <Filter>open-ephys\Source\Processors</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\Source\Processors\ResamplingNode.cpp">
+      <Filter>open-ephys\Source\Processors</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\Source\Processors\FilterNode.cpp">
+      <Filter>open-ephys\Source\Processors</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\Source\Processors\SourceNode.cpp">
+      <Filter>open-ephys\Source\Processors</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\Source\Processors\GenericProcessor.cpp">
+      <Filter>open-ephys\Source\Processors</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\Source\Processors\ProcessorGraph.cpp">
+      <Filter>open-ephys\Source\Processors</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\Source\UI\EditorViewportButtons.cpp">
+      <Filter>open-ephys\Source\UI</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\Source\UI\SignalChainManager.cpp">
+      <Filter>open-ephys\Source\UI</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\Source\UI\EditorViewport.cpp">
+      <Filter>open-ephys\Source\UI</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\Source\UI\ProcessorList.cpp">
+      <Filter>open-ephys\Source\UI</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\Source\UI\CustomLookAndFeel.cpp">
+      <Filter>open-ephys\Source\UI</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\Source\UI\InfoLabel.cpp">
+      <Filter>open-ephys\Source\UI</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\Source\UI\DataViewport.cpp">
+      <Filter>open-ephys\Source\UI</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\Source\UI\MessageCenter.cpp">
+      <Filter>open-ephys\Source\UI</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\Source\UI\ControlPanel.cpp">
+      <Filter>open-ephys\Source\UI</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\Source\UI\UIComponent.cpp">
+      <Filter>open-ephys\Source\UI</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\Source\MainWindow.cpp">
+      <Filter>open-ephys\Source</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\Source\Main.cpp">
+      <Filter>open-ephys\Source</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\JuceLibraryCode\BinaryData.cpp">
+      <Filter>Juce Library Code</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\JuceLibraryCode\JuceLibraryCode1.cpp">
+      <Filter>Juce Library Code</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\JuceLibraryCode\JuceLibraryCode2.cpp">
+      <Filter>Juce Library Code</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\JuceLibraryCode\JuceLibraryCode3.cpp">
+      <Filter>Juce Library Code</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\JuceLibraryCode\JuceLibraryCode4.cpp">
+      <Filter>Juce Library Code</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\Source\Processors\ArduinoOutput.cpp">
+      <Filter>open-ephys\Source\Processors</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\Source\Processors\Serial\ofArduino.cpp">
+      <Filter>open-ephys\Source\Processors\Serial</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\Source\Processors\Serial\ofSerial.cpp">
+      <Filter>open-ephys\Source\Processors\Serial</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\Source\Processors\EventDetector.cpp">
+      <Filter>open-ephys\Source\Processors</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\Source\Processors\FPGAOutput.cpp">
+      <Filter>open-ephys\Source\Processors</Filter>
+    </ClCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="..\..\Source\AccessClass.h">
+      <Filter>open-ephys\Source</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\Source\Network\PracticalSocket.h">
+      <Filter>open-ephys\Source\Network</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\Source\Dsp\Bessel.h">
+      <Filter>open-ephys\Source\Dsp</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\Source\Dsp\Biquad.h">
+      <Filter>open-ephys\Source\Dsp</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\Source\Dsp\Butterworth.h">
+      <Filter>open-ephys\Source\Dsp</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\Source\Dsp\Cascade.h">
+      <Filter>open-ephys\Source\Dsp</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\Source\Dsp\ChebyshevI.h">
+      <Filter>open-ephys\Source\Dsp</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\Source\Dsp\ChebyshevII.h">
+      <Filter>open-ephys\Source\Dsp</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\Source\Dsp\Common.h">
+      <Filter>open-ephys\Source\Dsp</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\Source\Dsp\Custom.h">
+      <Filter>open-ephys\Source\Dsp</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\Source\Dsp\Design.h">
+      <Filter>open-ephys\Source\Dsp</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\Source\Dsp\Dsp.h">
+      <Filter>open-ephys\Source\Dsp</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\Source\Dsp\Elliptic.h">
+      <Filter>open-ephys\Source\Dsp</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\Source\Dsp\Filter.h">
+      <Filter>open-ephys\Source\Dsp</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\Source\Dsp\Layout.h">
+      <Filter>open-ephys\Source\Dsp</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\Source\Dsp\Legendre.h">
+      <Filter>open-ephys\Source\Dsp</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\Source\Dsp\MathSupplement.h">
+      <Filter>open-ephys\Source\Dsp</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\Source\Dsp\Params.h">
+      <Filter>open-ephys\Source\Dsp</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\Source\Dsp\PoleFilter.h">
+      <Filter>open-ephys\Source\Dsp</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\Source\Dsp\RBJ.h">
+      <Filter>open-ephys\Source\Dsp</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\Source\Dsp\RootFinder.h">
+      <Filter>open-ephys\Source\Dsp</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\Source\Dsp\SmoothedFilter.h">
+      <Filter>open-ephys\Source\Dsp</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\Source\Dsp\State.h">
+      <Filter>open-ephys\Source\Dsp</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\Source\Dsp\Types.h">
+      <Filter>open-ephys\Source\Dsp</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\Source\Dsp\Utilities.h">
+      <Filter>open-ephys\Source\Dsp</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\Source\Audio\AudioComponent.h">
+      <Filter>open-ephys\Source\Audio</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\Source\Processors\Parameter.h">
+      <Filter>open-ephys\Source\Processors</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\Source\Processors\SpikeDisplayNode.h">
+      <Filter>open-ephys\Source\Processors</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\Source\Processors\WiFiOutput.h">
+      <Filter>open-ephys\Source\Processors</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\Source\Processors\LfpDisplayNode.h">
+      <Filter>open-ephys\Source\Processors</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\Source\Processors\Utilities\Merger.h">
+      <Filter>open-ephys\Source\Processors\Utilities</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\Source\Processors\Utilities\Splitter.h">
+      <Filter>open-ephys\Source\Processors\Utilities</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\Source\Processors\Visualization\SpikePlotting\SpikePlot.h">
+      <Filter>open-ephys\Source\Processors\Visualization\SpikePlotting</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\Source\Processors\Visualization\SpikePlotting\BaseUIElement.h">
+      <Filter>open-ephys\Source\Processors\Visualization\SpikePlotting</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\Source\Processors\Visualization\SpikePlotting\GenericAxes.h">
+      <Filter>open-ephys\Source\Processors\Visualization\SpikePlotting</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\Source\Processors\Visualization\SpikePlotting\PlotUtils.h">
+      <Filter>open-ephys\Source\Processors\Visualization\SpikePlotting</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\Source\Processors\Visualization\SpikePlotting\ProjectionAxes.h">
+      <Filter>open-ephys\Source\Processors\Visualization\SpikePlotting</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\Source\Processors\Visualization\SpikePlotting\SimpleKeyEvent.h">
+      <Filter>open-ephys\Source\Processors\Visualization\SpikePlotting</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\Source\Processors\Visualization\SpikePlotting\WaveAxes.h">
+      <Filter>open-ephys\Source\Processors\Visualization\SpikePlotting</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\Source\Processors\Visualization\SpikeObject.h">
+      <Filter>open-ephys\Source\Processors\Visualization</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\Source\Processors\Visualization\SpikeDisplayCanvas.h">
+      <Filter>open-ephys\Source\Processors\Visualization</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\Source\Processors\Visualization\Visualizer.h">
+      <Filter>open-ephys\Source\Processors\Visualization</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\Source\Processors\Visualization\DataWindow.h">
+      <Filter>open-ephys\Source\Processors\Visualization</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\Source\Processors\Visualization\LfpDisplayCanvas.h">
+      <Filter>open-ephys\Source\Processors\Visualization</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\Source\Processors\Visualization\OpenGLCanvas.h">
+      <Filter>open-ephys\Source\Processors\Visualization</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\Source\Processors\SpikeDetector.h">
+      <Filter>open-ephys\Source\Processors</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\Source\Processors\AudioNode.h">
+      <Filter>open-ephys\Source\Processors</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\Source\Processors\EventNode.h">
+      <Filter>open-ephys\Source\Processors</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\Source\Processors\Editors\FPGAOutputEditor.h">
+      <Filter>open-ephys\Source\Processors\Editors</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\Source\Processors\Editors\ArduinoOutputEditor.h">
+      <Filter>open-ephys\Source\Processors\Editors</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\Source\Processors\Editors\ChannelSelector.h">
+      <Filter>open-ephys\Source\Processors\Editors</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\Source\Processors\Editors\ParameterEditor.h">
+      <Filter>open-ephys\Source\Processors\Editors</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\Source\Processors\Editors\SpikeDisplayEditor.h">
+      <Filter>open-ephys\Source\Processors\Editors</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\Source\Processors\Editors\VisualizerEditor.h">
+      <Filter>open-ephys\Source\Processors\Editors</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\Source\Processors\Editors\MergerEditor.h">
+      <Filter>open-ephys\Source\Processors\Editors</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\Source\Processors\Editors\ImageIcon.h">
+      <Filter>open-ephys\Source\Processors\Editors</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\Source\Processors\Editors\WiFiOutputEditor.h">
+      <Filter>open-ephys\Source\Processors\Editors</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\Source\Processors\Editors\EventNodeEditor.h">
+      <Filter>open-ephys\Source\Processors\Editors</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\Source\Processors\Editors\SignalGeneratorEditor.h">
+      <Filter>open-ephys\Source\Processors\Editors</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\Source\Processors\Editors\LfpDisplayEditor.h">
+      <Filter>open-ephys\Source\Processors\Editors</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\Source\Processors\Editors\SourceNodeEditor.h">
+      <Filter>open-ephys\Source\Processors\Editors</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\Source\Processors\Editors\SplitterEditor.h">
+      <Filter>open-ephys\Source\Processors\Editors</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\Source\Processors\Editors\SpikeDetectorEditor.h">
+      <Filter>open-ephys\Source\Processors\Editors</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\Source\Processors\Editors\AudioEditor.h">
+      <Filter>open-ephys\Source\Processors\Editors</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\Source\Processors\Editors\FilterEditor.h">
+      <Filter>open-ephys\Source\Processors\Editors</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\Source\Processors\Editors\GenericEditor.h">
+      <Filter>open-ephys\Source\Processors\Editors</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\Source\Processors\DataThreads\FileReaderThread.h">
+      <Filter>open-ephys\Source\Processors\DataThreads</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\Source\Processors\DataThreads\okFrontPanelDLL.h">
+      <Filter>open-ephys\Source\Processors\DataThreads</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\Source\Processors\DataThreads\NetworkThread.h">
+      <Filter>open-ephys\Source\Processors\DataThreads</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\Source\Processors\DataThreads\FPGAThread.h">
+      <Filter>open-ephys\Source\Processors\DataThreads</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\Source\Processors\DataThreads\DataBuffer.h">
+      <Filter>open-ephys\Source\Processors\DataThreads</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\Source\Processors\DataThreads\IntanThread.h">
+      <Filter>open-ephys\Source\Processors\DataThreads</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\Source\Processors\DataThreads\DataThread.h">
+      <Filter>open-ephys\Source\Processors\DataThreads</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\Source\Processors\RecordNode.h">
+      <Filter>open-ephys\Source\Processors</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\Source\Processors\SignalGenerator.h">
+      <Filter>open-ephys\Source\Processors</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\Source\Processors\ResamplingNode.h">
+      <Filter>open-ephys\Source\Processors</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\Source\Processors\FilterNode.h">
+      <Filter>open-ephys\Source\Processors</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\Source\Processors\SourceNode.h">
+      <Filter>open-ephys\Source\Processors</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\Source\Processors\GenericProcessor.h">
+      <Filter>open-ephys\Source\Processors</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\Source\Processors\ProcessorGraph.h">
+      <Filter>open-ephys\Source\Processors</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\Source\UI\EditorViewportButtons.h">
+      <Filter>open-ephys\Source\UI</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\Source\UI\SignalChainManager.h">
+      <Filter>open-ephys\Source\UI</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\Source\UI\EditorViewport.h">
+      <Filter>open-ephys\Source\UI</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\Source\UI\ProcessorList.h">
+      <Filter>open-ephys\Source\UI</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\Source\UI\CustomLookAndFeel.h">
+      <Filter>open-ephys\Source\UI</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\Source\UI\InfoLabel.h">
+      <Filter>open-ephys\Source\UI</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\Source\UI\DataViewport.h">
+      <Filter>open-ephys\Source\UI</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\Source\UI\MessageCenter.h">
+      <Filter>open-ephys\Source\UI</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\Source\UI\ControlPanel.h">
+      <Filter>open-ephys\Source\UI</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\Source\UI\UIComponent.h">
+      <Filter>open-ephys\Source\UI</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\Source\MainWindow.h">
+      <Filter>open-ephys\Source</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\JuceLibraryCode\AppConfig.h">
+      <Filter>Juce Library Code</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\JuceLibraryCode\JuceHeader.h">
+      <Filter>Juce Library Code</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\JuceLibraryCode\BinaryData.h">
+      <Filter>Juce Library Code</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\Source\Processors\ArduinoOutput.h">
+      <Filter>open-ephys\Source\Processors</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\Source\Processors\Serial\ofArduino.h">
+      <Filter>open-ephys\Source\Processors\Serial</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\Source\Processors\Serial\ofConstants.h">
+      <Filter>open-ephys\Source\Processors\Serial</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\Source\Processors\Serial\ofSerial.h">
+      <Filter>open-ephys\Source\Processors\Serial</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\Source\Processors\EventDetector.h">
+      <Filter>open-ephys\Source\Processors</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\Source\Processors\FPGAOutput.h">
+      <Filter>open-ephys\Source\Processors</Filter>
+    </ClInclude>
+  </ItemGroup>
+</Project>
\ No newline at end of file
diff --git a/JuceLibraryCode/src/native/windows/juce_win32_Windowing.cpp b/JuceLibraryCode/src/native/windows/juce_win32_Windowing.cpp
index 94c9d1a0d27f8d8975b33ed3de803f2b0a3b2573..c423dcd5c53817208f1305434b4896751b66ea99 100755
--- a/JuceLibraryCode/src/native/windows/juce_win32_Windowing.cpp
+++ b/JuceLibraryCode/src/native/windows/juce_win32_Windowing.cpp
@@ -1,2969 +1,2971 @@
-/*
-  ==============================================================================
-
-   This file is part of the JUCE library - "Jules' Utility Class Extensions"
-   Copyright 2004-10 by Raw Material Software Ltd.
-
-  ------------------------------------------------------------------------------
-
-   JUCE can be redistributed and/or modified under the terms of the GNU General
-   Public License (Version 2), as published by the Free Software Foundation.
-   A copy of the license is included in the JUCE distribution, or can be found
-   online at www.gnu.org/licenses.
-
-   JUCE 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.
-
-  ------------------------------------------------------------------------------
-
-   To release a closed-source product which uses JUCE, commercial licenses are
-   available: visit www.rawmaterialsoftware.com/juce for more information.
-
-  ==============================================================================
-*/
-
-// (This file gets included by juce_win32_NativeCode.cpp, rather than being
-// compiled on its own).
-#if JUCE_INCLUDED_FILE
-
-
-//==============================================================================
-#undef GetSystemMetrics // multimon overrides this for some reason and causes a mess..
-
-// these are in the windows SDK, but need to be repeated here for GCC..
-#ifndef GET_APPCOMMAND_LPARAM
-  #define FAPPCOMMAND_MASK                  0xF000
-  #define GET_APPCOMMAND_LPARAM(lParam)     ((short) (HIWORD (lParam) & ~FAPPCOMMAND_MASK))
-  #define APPCOMMAND_MEDIA_NEXTTRACK        11
-  #define APPCOMMAND_MEDIA_PREVIOUSTRACK    12
-  #define APPCOMMAND_MEDIA_STOP             13
-  #define APPCOMMAND_MEDIA_PLAY_PAUSE       14
-  #define WM_APPCOMMAND                     0x0319
-#endif
-
-extern void juce_repeatLastProcessPriority(); // in juce_win32_Threads.cpp
-extern void juce_CheckCurrentlyFocusedTopLevelWindow();  // in juce_TopLevelWindow.cpp
-extern bool juce_IsRunningInWine();
-
-#ifndef ULW_ALPHA
-  #define ULW_ALPHA     0x00000002
-#endif
-
-#ifndef AC_SRC_ALPHA
-  #define AC_SRC_ALPHA  0x01
-#endif
-
-static HPALETTE palette = 0;
-static bool createPaletteIfNeeded = true;
-static bool shouldDeactivateTitleBar = true;
-
-#define WM_TRAYNOTIFY WM_USER + 100
-
-using ::abs;
-
-//==============================================================================
-typedef BOOL (WINAPI* UpdateLayeredWinFunc) (HWND, HDC, POINT*, SIZE*, HDC, POINT*, COLORREF, BLENDFUNCTION*, DWORD);
-static UpdateLayeredWinFunc updateLayeredWindow = 0;
-
-bool Desktop::canUseSemiTransparentWindows() throw()
-{
-    if (updateLayeredWindow == 0)
-    {
-        if (! juce_IsRunningInWine())
-        {
-            HMODULE user32Mod = GetModuleHandle (_T("user32.dll"));
-            updateLayeredWindow = (UpdateLayeredWinFunc) GetProcAddress (user32Mod, "UpdateLayeredWindow");
-        }
-    }
-
-    return updateLayeredWindow != 0;
-}
-
-Desktop::DisplayOrientation Desktop::getCurrentOrientation() const
-{
-    return upright;
-}
-
-//==============================================================================
-const int extendedKeyModifier               = 0x10000;
-
-const int KeyPress::spaceKey                = VK_SPACE;
-const int KeyPress::returnKey               = VK_RETURN;
-const int KeyPress::escapeKey               = VK_ESCAPE;
-const int KeyPress::backspaceKey            = VK_BACK;
-const int KeyPress::deleteKey               = VK_DELETE         | extendedKeyModifier;
-const int KeyPress::insertKey               = VK_INSERT         | extendedKeyModifier;
-const int KeyPress::tabKey                  = VK_TAB;
-const int KeyPress::leftKey                 = VK_LEFT           | extendedKeyModifier;
-const int KeyPress::rightKey                = VK_RIGHT          | extendedKeyModifier;
-const int KeyPress::upKey                   = VK_UP             | extendedKeyModifier;
-const int KeyPress::downKey                 = VK_DOWN           | extendedKeyModifier;
-const int KeyPress::homeKey                 = VK_HOME           | extendedKeyModifier;
-const int KeyPress::endKey                  = VK_END            | extendedKeyModifier;
-const int KeyPress::pageUpKey               = VK_PRIOR          | extendedKeyModifier;
-const int KeyPress::pageDownKey             = VK_NEXT           | extendedKeyModifier;
-const int KeyPress::F1Key                   = VK_F1             | extendedKeyModifier;
-const int KeyPress::F2Key                   = VK_F2             | extendedKeyModifier;
-const int KeyPress::F3Key                   = VK_F3             | extendedKeyModifier;
-const int KeyPress::F4Key                   = VK_F4             | extendedKeyModifier;
-const int KeyPress::F5Key                   = VK_F5             | extendedKeyModifier;
-const int KeyPress::F6Key                   = VK_F6             | extendedKeyModifier;
-const int KeyPress::F7Key                   = VK_F7             | extendedKeyModifier;
-const int KeyPress::F8Key                   = VK_F8             | extendedKeyModifier;
-const int KeyPress::F9Key                   = VK_F9             | extendedKeyModifier;
-const int KeyPress::F10Key                  = VK_F10            | extendedKeyModifier;
-const int KeyPress::F11Key                  = VK_F11            | extendedKeyModifier;
-const int KeyPress::F12Key                  = VK_F12            | extendedKeyModifier;
-const int KeyPress::F13Key                  = VK_F13            | extendedKeyModifier;
-const int KeyPress::F14Key                  = VK_F14            | extendedKeyModifier;
-const int KeyPress::F15Key                  = VK_F15            | extendedKeyModifier;
-const int KeyPress::F16Key                  = VK_F16            | extendedKeyModifier;
-const int KeyPress::numberPad0              = VK_NUMPAD0        | extendedKeyModifier;
-const int KeyPress::numberPad1              = VK_NUMPAD1        | extendedKeyModifier;
-const int KeyPress::numberPad2              = VK_NUMPAD2        | extendedKeyModifier;
-const int KeyPress::numberPad3              = VK_NUMPAD3        | extendedKeyModifier;
-const int KeyPress::numberPad4              = VK_NUMPAD4        | extendedKeyModifier;
-const int KeyPress::numberPad5              = VK_NUMPAD5        | extendedKeyModifier;
-const int KeyPress::numberPad6              = VK_NUMPAD6        | extendedKeyModifier;
-const int KeyPress::numberPad7              = VK_NUMPAD7        | extendedKeyModifier;
-const int KeyPress::numberPad8              = VK_NUMPAD8        | extendedKeyModifier;
-const int KeyPress::numberPad9              = VK_NUMPAD9        | extendedKeyModifier;
-const int KeyPress::numberPadAdd            = VK_ADD            | extendedKeyModifier;
-const int KeyPress::numberPadSubtract       = VK_SUBTRACT       | extendedKeyModifier;
-const int KeyPress::numberPadMultiply       = VK_MULTIPLY       | extendedKeyModifier;
-const int KeyPress::numberPadDivide         = VK_DIVIDE         | extendedKeyModifier;
-const int KeyPress::numberPadSeparator      = VK_SEPARATOR      | extendedKeyModifier;
-const int KeyPress::numberPadDecimalPoint   = VK_DECIMAL        | extendedKeyModifier;
-const int KeyPress::numberPadEquals         = 0x92 /*VK_OEM_NEC_EQUAL*/  | extendedKeyModifier;
-const int KeyPress::numberPadDelete         = VK_DELETE         | extendedKeyModifier;
-const int KeyPress::playKey                 = 0x30000;
-const int KeyPress::stopKey                 = 0x30001;
-const int KeyPress::fastForwardKey          = 0x30002;
-const int KeyPress::rewindKey               = 0x30003;
-
-
-//==============================================================================
-class WindowsBitmapImage  : public Image::SharedImage
-{
-public:
-    //==============================================================================
-    HBITMAP hBitmap;
-    BITMAPV4HEADER bitmapInfo;
-    HDC hdc;
-    unsigned char* bitmapData;
-
-    //==============================================================================
-    WindowsBitmapImage (const Image::PixelFormat format_,
-                        const int w, const int h, const bool clearImage)
-        : Image::SharedImage (format_, w, h)
-    {
-        jassert (format_ == Image::RGB || format_ == Image::ARGB);
-
-        pixelStride = (format_ == Image::RGB) ? 3 : 4;
-
-        zerostruct (bitmapInfo);
-        bitmapInfo.bV4Size = sizeof (BITMAPV4HEADER);
-        bitmapInfo.bV4Width = w;
-        bitmapInfo.bV4Height = h;
-        bitmapInfo.bV4Planes = 1;
-        bitmapInfo.bV4CSType = 1;
-        bitmapInfo.bV4BitCount = (unsigned short) (pixelStride * 8);
-
-        if (format_ == Image::ARGB)
-        {
-            bitmapInfo.bV4AlphaMask        = 0xff000000;
-            bitmapInfo.bV4RedMask          = 0xff0000;
-            bitmapInfo.bV4GreenMask        = 0xff00;
-            bitmapInfo.bV4BlueMask         = 0xff;
-            bitmapInfo.bV4V4Compression    = BI_BITFIELDS;
-        }
-        else
-        {
-            bitmapInfo.bV4V4Compression    = BI_RGB;
-        }
-
-        lineStride = -((w * pixelStride + 3) & ~3);
-
-        HDC dc = GetDC (0);
-        hdc = CreateCompatibleDC (dc);
-        ReleaseDC (0, dc);
-
-        SetMapMode (hdc, MM_TEXT);
-
-        hBitmap = CreateDIBSection (hdc,
-                                    (BITMAPINFO*) &(bitmapInfo),
-                                    DIB_RGB_COLORS,
-                                    (void**) &bitmapData,
-                                    0, 0);
-
-        SelectObject (hdc, hBitmap);
-
-        if (format_ == Image::ARGB && clearImage)
-            zeromem (bitmapData, abs (h * lineStride));
-
-        imageData = bitmapData - (lineStride * (h - 1));
-    }
-
-    ~WindowsBitmapImage()
-    {
-        DeleteDC (hdc);
-        DeleteObject (hBitmap);
-    }
-
-    Image::ImageType getType() const    { return Image::NativeImage; }
-
-    LowLevelGraphicsContext* createLowLevelContext()
-    {
-        return new LowLevelGraphicsSoftwareRenderer (Image (this));
-    }
-
-    Image::SharedImage* clone()
-    {
-        WindowsBitmapImage* im = new WindowsBitmapImage (format, width, height, false);
-
-        for (int i = 0; i < height; ++i)
-            memcpy (im->imageData + i * lineStride, imageData + i * lineStride, lineStride);
-
-        return im;
-    }
-
-    void blitToWindow (HWND hwnd, HDC dc, const bool transparent,
-                       const int x, const int y,
-                       const RectangleList& maskedRegion,
-                       const uint8 updateLayeredWindowAlpha) throw()
-    {
-        static HDRAWDIB hdd = 0;
-        static bool needToCreateDrawDib = true;
-
-        if (needToCreateDrawDib)
-        {
-            needToCreateDrawDib = false;
-
-            HDC dc = GetDC (0);
-            const int n = GetDeviceCaps (dc, BITSPIXEL);
-            ReleaseDC (0, dc);
-
-            // only open if we're not palettised
-            if (n > 8)
-                hdd = DrawDibOpen();
-        }
-
-        if (createPaletteIfNeeded)
-        {
-            HDC dc = GetDC (0);
-            const int n = GetDeviceCaps (dc, BITSPIXEL);
-            ReleaseDC (0, dc);
-
-            if (n <= 8)
-                palette = CreateHalftonePalette (dc);
-
-            createPaletteIfNeeded = false;
-        }
-
-        if (palette != 0)
-        {
-            SelectPalette (dc, palette, FALSE);
-            RealizePalette (dc);
-            SetStretchBltMode (dc, HALFTONE);
-        }
-
-        SetMapMode (dc, MM_TEXT);
-
-        if (transparent)
-        {
-            POINT p, pos;
-            SIZE size;
-
-            RECT windowBounds;
-            GetWindowRect (hwnd, &windowBounds);
-
-            p.x = -x;
-            p.y = -y;
-            pos.x = windowBounds.left;
-            pos.y = windowBounds.top;
-            size.cx = windowBounds.right - windowBounds.left;
-            size.cy = windowBounds.bottom - windowBounds.top;
-
-            BLENDFUNCTION bf;
-            bf.AlphaFormat = AC_SRC_ALPHA;
-            bf.BlendFlags = 0;
-            bf.BlendOp = AC_SRC_OVER;
-            bf.SourceConstantAlpha = updateLayeredWindowAlpha;
-
-            if (! maskedRegion.isEmpty())
-            {
-                for (RectangleList::Iterator i (maskedRegion); i.next();)
-                {
-                    const Rectangle<int>& r = *i.getRectangle();
-                    ExcludeClipRect (hdc, r.getX(), r.getY(), r.getRight(), r.getBottom());
-                }
-            }
-
-            updateLayeredWindow (hwnd, 0, &pos, &size, hdc, &p, 0, &bf, ULW_ALPHA);
-        }
-        else
-        {
-            int savedDC = 0;
-
-            if (! maskedRegion.isEmpty())
-            {
-                savedDC = SaveDC (dc);
-
-                for (RectangleList::Iterator i (maskedRegion); i.next();)
-                {
-                    const Rectangle<int>& r = *i.getRectangle();
-                    ExcludeClipRect (dc, r.getX(), r.getY(), r.getRight(), r.getBottom());
-                }
-            }
-
-            if (hdd == 0)
-            {
-                StretchDIBits (dc,
-                               x, y, width, height,
-                               0, 0, width, height,
-                               bitmapData, (const BITMAPINFO*) &bitmapInfo,
-                               DIB_RGB_COLORS, SRCCOPY);
-            }
-            else
-            {
-                DrawDibDraw (hdd, dc, x, y, -1, -1,
-                             (BITMAPINFOHEADER*) &bitmapInfo, bitmapData,
-                             0, 0, width, height, 0);
-            }
-
-            if (! maskedRegion.isEmpty())
-                RestoreDC (dc, savedDC);
-        }
-    }
-
-private:
-    JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (WindowsBitmapImage);
-};
-
-namespace IconConverters
-{
-    const Image createImageFromHBITMAP (HBITMAP bitmap)
-    {
-        Image im;
-
-        if (bitmap != 0)
-        {
-            BITMAP bm;
-
-            if (GetObject (bitmap, sizeof (BITMAP), &bm)
-                 && bm.bmWidth > 0 && bm.bmHeight > 0)
-            {
-                HDC tempDC = GetDC (0);
-                HDC dc = CreateCompatibleDC (tempDC);
-                ReleaseDC (0, tempDC);
-
-                SelectObject (dc, bitmap);
-
-                im = Image (Image::ARGB, bm.bmWidth, bm.bmHeight, true);
-                Image::BitmapData imageData (im, true);
-
-                for (int y = bm.bmHeight; --y >= 0;)
-                {
-                    for (int x = bm.bmWidth; --x >= 0;)
-                    {
-                        COLORREF col = GetPixel (dc, x, y);
-
-                        imageData.setPixelColour (x, y, Colour ((uint8) GetRValue (col),
-                                                                (uint8) GetGValue (col),
-                                                                (uint8) GetBValue (col)));
-                    }
-                }
-
-                DeleteDC (dc);
-            }
-        }
-
-        return im;
-    }
-
-    const Image createImageFromHICON (HICON icon)
-    {
-        ICONINFO info;
-
-        if (GetIconInfo (icon, &info))
-        {
-            Image mask (createImageFromHBITMAP (info.hbmMask));
-            Image image (createImageFromHBITMAP (info.hbmColor));
-
-            if (mask.isValid() && image.isValid())
-            {
-                for (int y = image.getHeight(); --y >= 0;)
-                {
-                    for (int x = image.getWidth(); --x >= 0;)
-                    {
-                        const float brightness = mask.getPixelAt (x, y).getBrightness();
-
-                        if (brightness > 0.0f)
-                            image.multiplyAlphaAt (x, y, 1.0f - brightness);
-                    }
-                }
-
-                return image;
-            }
-        }
-
-        return Image::null;
-    }
-
-    HICON createHICONFromImage (const Image& image, const BOOL isIcon, int hotspotX, int hotspotY)
-    {
-        WindowsBitmapImage* nativeBitmap = new WindowsBitmapImage (Image::ARGB, image.getWidth(), image.getHeight(), true);
-        Image bitmap (nativeBitmap);
-
-        {
-            Graphics g (bitmap);
-            g.drawImageAt (image, 0, 0);
-        }
-
-        HBITMAP mask = CreateBitmap (image.getWidth(), image.getHeight(), 1, 1, 0);
-
-        ICONINFO info;
-        info.fIcon = isIcon;
-        info.xHotspot = hotspotX;
-        info.yHotspot = hotspotY;
-        info.hbmMask = mask;
-        info.hbmColor = nativeBitmap->hBitmap;
-
-        HICON hi = CreateIconIndirect (&info);
-        DeleteObject (mask);
-        return hi;
-    }
-}
-
-//==============================================================================
-long improbableWindowNumber = 0xf965aa01; // also referenced by messaging.cpp
-
-
-//==============================================================================
-bool KeyPress::isKeyCurrentlyDown (const int keyCode)
-{
-    SHORT k = (SHORT) keyCode;
-
-    if ((keyCode & extendedKeyModifier) == 0
-         && (k >= (SHORT) 'a' && k <= (SHORT) 'z'))
-        k += (SHORT) 'A' - (SHORT) 'a';
-
-    const SHORT translatedValues[] = { (SHORT) ',', VK_OEM_COMMA,
-                                       (SHORT) '+', VK_OEM_PLUS,
-                                       (SHORT) '-', VK_OEM_MINUS,
-                                       (SHORT) '.', VK_OEM_PERIOD,
-                                       (SHORT) ';', VK_OEM_1,
-                                       (SHORT) ':', VK_OEM_1,
-                                       (SHORT) '/', VK_OEM_2,
-                                       (SHORT) '?', VK_OEM_2,
-                                       (SHORT) '[', VK_OEM_4,
-                                       (SHORT) ']', VK_OEM_6 };
-
-    for (int i = 0; i < numElementsInArray (translatedValues); i += 2)
-        if (k == translatedValues [i])
-            k = translatedValues [i + 1];
-
-    return (GetKeyState (k) & 0x8000) != 0;
-}
-
-//==============================================================================
-class Win32ComponentPeer  : public ComponentPeer
-{
-public:
-    enum RenderingEngineType
-    {
-        softwareRenderingEngine = 0,
-        direct2DRenderingEngine
-    };
-
-    //==============================================================================
-    Win32ComponentPeer (Component* const component,
-                        const int windowStyleFlags,
-                        HWND parentToAddTo_)
-        : ComponentPeer (component, windowStyleFlags),
-          dontRepaint (false),
-      #if JUCE_DIRECT2D
-          currentRenderingEngine (direct2DRenderingEngine),
-      #else
-          currentRenderingEngine (softwareRenderingEngine),
-      #endif
-          fullScreen (false),
-          isDragging (false),
-          isMouseOver (false),
-          hasCreatedCaret (false),
-          currentWindowIcon (0),
-          dropTarget (0),
-          updateLayeredWindowAlpha (255),
-          parentToAddTo (parentToAddTo_)
-    {
-        callFunctionIfNotLocked (&createWindowCallback, this);
-
-        setTitle (component->getName());
-
-        if ((windowStyleFlags & windowHasDropShadow) != 0
-             && Desktop::canUseSemiTransparentWindows())
-        {
-            shadower = component->getLookAndFeel().createDropShadowerForComponent (component);
-
-            if (shadower != 0)
-                shadower->setOwner (component);
-        }
-    }
-
-    ~Win32ComponentPeer()
-    {
-        setTaskBarIcon (Image());
-        shadower = 0;
-
-        // do this before the next bit to avoid messages arriving for this window
-        // before it's destroyed
-        SetWindowLongPtr (hwnd, GWLP_USERDATA, 0);
-
-        callFunctionIfNotLocked (&destroyWindowCallback, (void*) hwnd);
-
-        if (currentWindowIcon != 0)
-            DestroyIcon (currentWindowIcon);
-
-        if (dropTarget != 0)
-        {
-            dropTarget->Release();
-            dropTarget = 0;
-        }
-
-      #if JUCE_DIRECT2D
-        direct2DContext = 0;
-      #endif
-    }
-
-    //==============================================================================
-    void* getNativeHandle() const
-    {
-        return hwnd;
-    }
-
-    void setVisible (bool shouldBeVisible)
-    {
-        ShowWindow (hwnd, shouldBeVisible ? SW_SHOWNA : SW_HIDE);
-
-        if (shouldBeVisible)
-            InvalidateRect (hwnd, 0, 0);
-        else
-            lastPaintTime = 0;
-    }
-
-    void setTitle (const String& title)
-    {
-        SetWindowText (hwnd, title);
-    }
-
-    void setPosition (int x, int y)
-    {
-        offsetWithinParent (x, y);
-        SetWindowPos (hwnd, 0,
-                      x - windowBorder.getLeft(),
-                      y - windowBorder.getTop(),
-                      0, 0,
-                      SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOZORDER | SWP_NOOWNERZORDER);
-    }
-
-    void repaintNowIfTransparent()
-    {
-        if (isUsingUpdateLayeredWindow() && lastPaintTime > 0 && Time::getMillisecondCounter() > lastPaintTime + 30)
-            handlePaintMessage();
-    }
-
-    void updateBorderSize()
-    {
-        WINDOWINFO info;
-        info.cbSize = sizeof (info);
-
-        if (GetWindowInfo (hwnd, &info))
-        {
-            windowBorder = BorderSize (info.rcClient.top - info.rcWindow.top,
-                                       info.rcClient.left - info.rcWindow.left,
-                                       info.rcWindow.bottom - info.rcClient.bottom,
-                                       info.rcWindow.right - info.rcClient.right);
-        }
-
-      #if JUCE_DIRECT2D
-        if (direct2DContext != 0)
-            direct2DContext->resized();
-      #endif
-    }
-
-    void setSize (int w, int h)
-    {
-        SetWindowPos (hwnd, 0, 0, 0,
-                      w + windowBorder.getLeftAndRight(),
-                      h + windowBorder.getTopAndBottom(),
-                      SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOZORDER | SWP_NOOWNERZORDER);
-
-        updateBorderSize();
-
-        repaintNowIfTransparent();
-    }
-
-    void setBounds (int x, int y, int w, int h, bool isNowFullScreen)
-    {
-        fullScreen = isNowFullScreen;
-        offsetWithinParent (x, y);
-
-        SetWindowPos (hwnd, 0,
-                      x - windowBorder.getLeft(),
-                      y - windowBorder.getTop(),
-                      w + windowBorder.getLeftAndRight(),
-                      h + windowBorder.getTopAndBottom(),
-                      SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOOWNERZORDER);
-
-        updateBorderSize();
-
-        repaintNowIfTransparent();
-    }
-
-    const Rectangle<int> getBounds() const
-    {
-        RECT r;
-        GetWindowRect (hwnd, &r);
-
-        Rectangle<int> bounds (r.left, r.top, r.right - r.left, r.bottom - r.top);
-
-        HWND parentH = GetParent (hwnd);
-        if (parentH != 0)
-        {
-            GetWindowRect (parentH, &r);
-            bounds.translate (-r.left, -r.top);
-        }
-
-        return windowBorder.subtractedFrom (bounds);
-    }
-
-    const Point<int> getScreenPosition() const
-    {
-        RECT r;
-        GetWindowRect (hwnd, &r);
-        return Point<int> (r.left + windowBorder.getLeft(),
-                           r.top + windowBorder.getTop());
-    }
-
-    const Point<int> localToGlobal (const Point<int>& relativePosition)
-    {
-        return relativePosition + getScreenPosition();
-    }
-
-    const Point<int> globalToLocal (const Point<int>& screenPosition)
-    {
-        return screenPosition - getScreenPosition();
-    }
-
-    void setAlpha (float newAlpha)
-    {
-        const uint8 intAlpha = (uint8) jlimit (0, 255, (int) (newAlpha * 255.0f));
-
-        if (component->isOpaque())
-        {
-            if (newAlpha < 1.0f)
-            {
-                SetWindowLong (hwnd, GWL_EXSTYLE, GetWindowLong (hwnd, GWL_EXSTYLE) | WS_EX_LAYERED);
-                SetLayeredWindowAttributes (hwnd, RGB (0, 0, 0), intAlpha, LWA_ALPHA);
-            }
-            else
-            {
-                SetWindowLong (hwnd, GWL_EXSTYLE, GetWindowLong (hwnd, GWL_EXSTYLE) & ~WS_EX_LAYERED);
-                RedrawWindow (hwnd, 0, 0, RDW_ERASE | RDW_INVALIDATE | RDW_FRAME | RDW_ALLCHILDREN);
-            }
-        }
-        else
-        {
-            updateLayeredWindowAlpha = intAlpha;
-            component->repaint();
-        }
-    }
-
-    void setMinimised (bool shouldBeMinimised)
-    {
-        if (shouldBeMinimised != isMinimised())
-            ShowWindow (hwnd, shouldBeMinimised ? SW_MINIMIZE : SW_SHOWNORMAL);
-    }
-
-    bool isMinimised() const
-    {
-        WINDOWPLACEMENT wp;
-        wp.length = sizeof (WINDOWPLACEMENT);
-        GetWindowPlacement (hwnd, &wp);
-
-        return wp.showCmd == SW_SHOWMINIMIZED;
-    }
-
-    void setFullScreen (bool shouldBeFullScreen)
-    {
-        setMinimised (false);
-
-        if (fullScreen != shouldBeFullScreen)
-        {
-            fullScreen = shouldBeFullScreen;
-            const WeakReference<Component> deletionChecker (component);
-
-            if (! fullScreen)
-            {
-                const Rectangle<int> boundsCopy (lastNonFullscreenBounds);
-
-                if (hasTitleBar())
-                    ShowWindow (hwnd, SW_SHOWNORMAL);
-
-                if (! boundsCopy.isEmpty())
-                {
-                    setBounds (boundsCopy.getX(),
-                               boundsCopy.getY(),
-                               boundsCopy.getWidth(),
-                               boundsCopy.getHeight(),
-                               false);
-                }
-            }
-            else
-            {
-                if (hasTitleBar())
-                    ShowWindow (hwnd, SW_SHOWMAXIMIZED);
-                else
-                    SendMessageW (hwnd, WM_SETTINGCHANGE, 0, 0);
-            }
-
-            if (deletionChecker != 0)
-                handleMovedOrResized();
-        }
-    }
-
-    bool isFullScreen() const
-    {
-        if (! hasTitleBar())
-            return fullScreen;
-
-        WINDOWPLACEMENT wp;
-        wp.length = sizeof (wp);
-        GetWindowPlacement (hwnd, &wp);
-
-        return wp.showCmd == SW_SHOWMAXIMIZED;
-    }
-
-    bool contains (const Point<int>& position, bool trueIfInAChildWindow) const
-    {
-        if (! (isPositiveAndBelow (position.getX(), component->getWidth())
-                && isPositiveAndBelow (position.getY(), component->getHeight())))
-            return false;
-
-        RECT r;
-        GetWindowRect (hwnd, &r);
-
-        POINT p;
-        p.x = position.getX() + r.left + windowBorder.getLeft();
-        p.y = position.getY() + r.top + windowBorder.getTop();
-
-        HWND w = WindowFromPoint (p);
-        return w == hwnd || (trueIfInAChildWindow && (IsChild (hwnd, w) != 0));
-    }
-
-    const BorderSize getFrameSize() const
-    {
-        return windowBorder;
-    }
-
-    bool setAlwaysOnTop (bool alwaysOnTop)
-    {
-        const bool oldDeactivate = shouldDeactivateTitleBar;
-        shouldDeactivateTitleBar = ((styleFlags & windowIsTemporary) == 0);
-
-        SetWindowPos (hwnd, alwaysOnTop ? HWND_TOPMOST : HWND_NOTOPMOST,
-                      0, 0, 0, 0,
-                      SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOSENDCHANGING);
-
-        shouldDeactivateTitleBar = oldDeactivate;
-
-        if (shadower != 0)
-            shadower->componentBroughtToFront (*component);
-
-        return true;
-    }
-
-    void toFront (bool makeActive)
-    {
-        setMinimised (false);
-
-        const bool oldDeactivate = shouldDeactivateTitleBar;
-        shouldDeactivateTitleBar = ((styleFlags & windowIsTemporary) == 0);
-
-        callFunctionIfNotLocked (makeActive ? &toFrontCallback1 : &toFrontCallback2, hwnd);
-
-        shouldDeactivateTitleBar = oldDeactivate;
-
-        if (! makeActive)
-        {
-            // in this case a broughttofront call won't have occured, so do it now..
-            handleBroughtToFront();
-        }
-    }
-
-    void toBehind (ComponentPeer* other)
-    {
-        Win32ComponentPeer* const otherPeer = dynamic_cast <Win32ComponentPeer*> (other);
-
-        jassert (otherPeer != 0); // wrong type of window?
-
-        if (otherPeer != 0)
-        {
-            setMinimised (false);
-
-            // must be careful not to try to put a topmost window behind a normal one, or win32
-            // promotes the normal one to be topmost!
-            if (getComponent()->isAlwaysOnTop() == otherPeer->getComponent()->isAlwaysOnTop())
-                SetWindowPos (hwnd, otherPeer->hwnd, 0, 0, 0, 0,
-                              SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOSENDCHANGING);
-            else if (otherPeer->getComponent()->isAlwaysOnTop())
-                SetWindowPos (hwnd, HWND_TOP, 0, 0, 0, 0,
-                              SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOSENDCHANGING);
-        }
-    }
-
-    bool isFocused() const
-    {
-        return callFunctionIfNotLocked (&getFocusCallback, 0) == (void*) hwnd;
-    }
-
-    void grabFocus()
-    {
-        const bool oldDeactivate = shouldDeactivateTitleBar;
-        shouldDeactivateTitleBar = ((styleFlags & windowIsTemporary) == 0);
-
-        callFunctionIfNotLocked (&setFocusCallback, hwnd);
-
-        shouldDeactivateTitleBar = oldDeactivate;
-    }
-
-    void textInputRequired (const Point<int>&)
-    {
-        if (! hasCreatedCaret)
-        {
-            hasCreatedCaret = true;
-            CreateCaret (hwnd, (HBITMAP) 1, 0, 0);
-        }
-
-        ShowCaret (hwnd);
-        SetCaretPos (0, 0);
-    }
-
-    void repaint (const Rectangle<int>& area)
-    {
-        const RECT r = { area.getX(), area.getY(), area.getRight(), area.getBottom() };
-        InvalidateRect (hwnd, &r, FALSE);
-    }
-
-    void performAnyPendingRepaintsNow()
-    {
-        MSG m;
-        if (component->isVisible() && PeekMessage (&m, hwnd, WM_PAINT, WM_PAINT, PM_REMOVE))
-            DispatchMessage (&m);
-    }
-
-    //==============================================================================
-    static Win32ComponentPeer* getOwnerOfWindow (HWND h) throw()
-    {
-        if (h != 0 && GetWindowLongPtr (h, GWLP_USERDATA) == improbableWindowNumber)
-            return (Win32ComponentPeer*) (pointer_sized_int) GetWindowLongPtr (h, 8);
-
-        return 0;
-    }
-
-    //==============================================================================
-    void setTaskBarIcon (const Image& image)
-    {
-        if (image.isValid())
-        {
-            HICON hicon = IconConverters::createHICONFromImage (image, TRUE, 0, 0);
-
-            if (taskBarIcon == 0)
-            {
-                taskBarIcon = new NOTIFYICONDATA();
-                zeromem (taskBarIcon, sizeof (NOTIFYICONDATA));
-                taskBarIcon->cbSize = sizeof (NOTIFYICONDATA);
-                taskBarIcon->hWnd = (HWND) hwnd;
-                taskBarIcon->uID = (int) (pointer_sized_int) hwnd;
-                taskBarIcon->uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP;
-                taskBarIcon->uCallbackMessage = WM_TRAYNOTIFY;
-                taskBarIcon->hIcon = hicon;
-                taskBarIcon->szTip[0] = 0;
-
-                Shell_NotifyIcon (NIM_ADD, taskBarIcon);
-            }
-            else
-            {
-                HICON oldIcon = taskBarIcon->hIcon;
-
-                taskBarIcon->hIcon = hicon;
-                taskBarIcon->uFlags = NIF_ICON;
-                Shell_NotifyIcon (NIM_MODIFY, taskBarIcon);
-
-                DestroyIcon (oldIcon);
-            }
-        }
-        else if (taskBarIcon != 0)
-        {
-            taskBarIcon->uFlags = 0;
-            Shell_NotifyIcon (NIM_DELETE, taskBarIcon);
-            DestroyIcon (taskBarIcon->hIcon);
-            taskBarIcon = 0;
-        }
-    }
-
-    void setTaskBarIconToolTip (const String& toolTip) const
-    {
-        if (taskBarIcon != 0)
-        {
-            taskBarIcon->uFlags = NIF_TIP;
-            toolTip.copyToUnicode (taskBarIcon->szTip, sizeof (taskBarIcon->szTip) - 1);
-            Shell_NotifyIcon (NIM_MODIFY, taskBarIcon);
-        }
-    }
-
-    void handleTaskBarEvent (const LPARAM lParam)
-    {
-        if (component->isCurrentlyBlockedByAnotherModalComponent())
-        {
-            if (lParam == WM_LBUTTONDOWN || lParam == WM_RBUTTONDOWN
-                 || lParam == WM_LBUTTONDBLCLK || lParam == WM_LBUTTONDBLCLK)
-            {
-                Component* const current = Component::getCurrentlyModalComponent();
-
-                if (current != 0)
-                    current->inputAttemptWhenModal();
-            }
-        }
-        else
-        {
-            ModifierKeys eventMods (ModifierKeys::getCurrentModifiersRealtime());
-
-            if (lParam == WM_LBUTTONDOWN || lParam == WM_LBUTTONDBLCLK)
-                eventMods = eventMods.withFlags (ModifierKeys::leftButtonModifier);
-            else if (lParam == WM_RBUTTONDOWN || lParam == WM_RBUTTONDBLCLK)
-                eventMods = eventMods.withFlags (ModifierKeys::rightButtonModifier);
-            else if (lParam == WM_LBUTTONUP || lParam == WM_RBUTTONUP)
-                eventMods = eventMods.withoutMouseButtons();
-
-            const MouseEvent e (Desktop::getInstance().getMainMouseSource(),
-                                Point<int>(), eventMods, component, component, Time (getMouseEventTime()),
-                                Point<int>(), Time (getMouseEventTime()), 1, false);
-
-            if (lParam == WM_LBUTTONDOWN || lParam == WM_RBUTTONDOWN)
-            {
-                SetFocus (hwnd);
-                SetForegroundWindow (hwnd);
-                component->mouseDown (e);
-            }
-            else if (lParam == WM_LBUTTONUP || lParam == WM_RBUTTONUP)
-            {
-                component->mouseUp (e);
-            }
-            else if (lParam == WM_LBUTTONDBLCLK || lParam == WM_LBUTTONDBLCLK)
-            {
-                component->mouseDoubleClick (e);
-            }
-            else if (lParam == WM_MOUSEMOVE)
-            {
-                component->mouseMove (e);
-            }
-        }
-    }
-
-    //==============================================================================
-    bool isInside (HWND h) const
-    {
-        return GetAncestor (hwnd, GA_ROOT) == h;
-    }
-
-    //==============================================================================
-    static void updateKeyModifiers() throw()
-    {
-        int keyMods = 0;
-        if (GetKeyState (VK_SHIFT) & 0x8000)    keyMods |= ModifierKeys::shiftModifier;
-        if (GetKeyState (VK_CONTROL) & 0x8000)  keyMods |= ModifierKeys::ctrlModifier;
-        if (GetKeyState (VK_MENU) & 0x8000)     keyMods |= ModifierKeys::altModifier;
-        if (GetKeyState (VK_RMENU) & 0x8000)    keyMods &= ~(ModifierKeys::ctrlModifier | ModifierKeys::altModifier);
-
-        currentModifiers = currentModifiers.withOnlyMouseButtons().withFlags (keyMods);
-    }
-
-    static void updateModifiersFromWParam (const WPARAM wParam)
-    {
-        int mouseMods = 0;
-        if (wParam & MK_LBUTTON)   mouseMods |= ModifierKeys::leftButtonModifier;
-        if (wParam & MK_RBUTTON)   mouseMods |= ModifierKeys::rightButtonModifier;
-        if (wParam & MK_MBUTTON)   mouseMods |= ModifierKeys::middleButtonModifier;
-
-        currentModifiers = currentModifiers.withoutMouseButtons().withFlags (mouseMods);
-        updateKeyModifiers();
-    }
-
-    static int64 getMouseEventTime()
-    {
-        static int64 eventTimeOffset = 0;
-        static DWORD lastMessageTime = 0;
-        const DWORD thisMessageTime = GetMessageTime();
-
-        if (thisMessageTime < lastMessageTime || lastMessageTime == 0)
-        {
-            lastMessageTime = thisMessageTime;
-            eventTimeOffset = Time::currentTimeMillis() - thisMessageTime;
-        }
-
-        return eventTimeOffset + thisMessageTime;
-    }
-
-    //==============================================================================
-    bool dontRepaint;
-
-    static ModifierKeys currentModifiers;
-    static ModifierKeys modifiersAtLastCallback;
-
-private:
-    HWND hwnd, parentToAddTo;
-    ScopedPointer<DropShadower> shadower;
-    RenderingEngineType currentRenderingEngine;
-  #if JUCE_DIRECT2D
-    ScopedPointer<Direct2DLowLevelGraphicsContext> direct2DContext;
-  #endif
-    bool fullScreen, isDragging, isMouseOver, hasCreatedCaret;
-    BorderSize windowBorder;
-    HICON currentWindowIcon;
-    ScopedPointer<NOTIFYICONDATA> taskBarIcon;
-    IDropTarget* dropTarget;
-    uint8 updateLayeredWindowAlpha;
-
-    //==============================================================================
-    class TemporaryImage    : public Timer
-    {
-    public:
-        //==============================================================================
-        TemporaryImage() {}
-        ~TemporaryImage() {}
-
-        //==============================================================================
-        const Image& getImage (const bool transparent, const int w, const int h)
-        {
-            const Image::PixelFormat format = transparent ? Image::ARGB : Image::RGB;
-
-            if ((! image.isValid()) || image.getWidth() < w || image.getHeight() < h || image.getFormat() != format)
-                image = Image (new WindowsBitmapImage (format, (w + 31) & ~31, (h + 31) & ~31, false));
-
-            startTimer (3000);
-            return image;
-        }
-
-        //==============================================================================
-        void timerCallback()
-        {
-            stopTimer();
-            image = Image::null;
-        }
-
-    private:
-        Image image;
-
-        JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (TemporaryImage);
-    };
-
-    TemporaryImage offscreenImageGenerator;
-
-    //==============================================================================
-    class WindowClassHolder    : public DeletedAtShutdown
-    {
-    public:
-        WindowClassHolder()
-            : windowClassName ("JUCE_")
-        {
-            // this name has to be different for each app/dll instance because otherwise
-            // poor old Win32 can get a bit confused (even despite it not being a process-global
-            // window class).
-            windowClassName << (int) (Time::currentTimeMillis() & 0x7fffffff);
-
-            HINSTANCE moduleHandle = (HINSTANCE) PlatformUtilities::getCurrentModuleInstanceHandle();
-
-            TCHAR moduleFile [1024];
-            moduleFile[0] = 0;
-            GetModuleFileName (moduleHandle, moduleFile, 1024);
-            WORD iconNum = 0;
-
-            WNDCLASSEX wcex;
-            wcex.cbSize         = sizeof (wcex);
-            wcex.style          = CS_OWNDC;
-            wcex.lpfnWndProc    = (WNDPROC) windowProc;
-            wcex.lpszClassName  = windowClassName;
-            wcex.cbClsExtra     = 0;
-            wcex.cbWndExtra     = 32;
-            wcex.hInstance      = moduleHandle;
-            wcex.hIcon          = ExtractAssociatedIcon (moduleHandle, moduleFile, &iconNum);
-            iconNum = 1;
-            wcex.hIconSm        = ExtractAssociatedIcon (moduleHandle, moduleFile, &iconNum);
-            wcex.hCursor        = 0;
-            wcex.hbrBackground  = 0;
-            wcex.lpszMenuName   = 0;
-
-            RegisterClassEx (&wcex);
-        }
-
-        ~WindowClassHolder()
-        {
-            if (ComponentPeer::getNumPeers() == 0)
-                UnregisterClass (windowClassName, (HINSTANCE) PlatformUtilities::getCurrentModuleInstanceHandle());
-
-            clearSingletonInstance();
-        }
-
-        String windowClassName;
-
-        juce_DeclareSingleton_SingleThreaded_Minimal (WindowClassHolder);
-    };
-
-    //==============================================================================
-    static void* createWindowCallback (void* userData)
-    {
-        static_cast <Win32ComponentPeer*> (userData)->createWindow();
-        return 0;
-    }
-
-    void createWindow()
-    {
-        DWORD exstyle = WS_EX_ACCEPTFILES;
-        DWORD type = WS_CLIPSIBLINGS | WS_CLIPCHILDREN;
-
-        if (hasTitleBar())
-        {
-            type |= WS_OVERLAPPED;
-
-            if ((styleFlags & windowHasCloseButton) != 0)
-            {
-                type |= WS_SYSMENU;
-            }
-            else
-            {
-                // annoyingly, windows won't let you have a min/max button without a close button
-                jassert ((styleFlags & (windowHasMinimiseButton | windowHasMaximiseButton)) == 0);
-            }
-
-            if ((styleFlags & windowIsResizable) != 0)
-                type |= WS_THICKFRAME;
-        }
-        else if (parentToAddTo != 0)
-        {
-            type |= WS_CHILD;
-        }
-        else
-        {
-            type |= WS_POPUP | WS_SYSMENU;
-        }
-
-        if ((styleFlags & windowAppearsOnTaskbar) == 0)
-            exstyle |= WS_EX_TOOLWINDOW;
-        else
-            exstyle |= WS_EX_APPWINDOW;
-
-        if ((styleFlags & windowHasMinimiseButton) != 0)
-            type |= WS_MINIMIZEBOX;
-
-        if ((styleFlags & windowHasMaximiseButton) != 0)
-            type |= WS_MAXIMIZEBOX;
-
-        if ((styleFlags & windowIgnoresMouseClicks) != 0)
-            exstyle |= WS_EX_TRANSPARENT;
-
-        if ((styleFlags & windowIsSemiTransparent) != 0
-              && Desktop::canUseSemiTransparentWindows())
-            exstyle |= WS_EX_LAYERED;
-
-        hwnd = CreateWindowEx (exstyle, WindowClassHolder::getInstance()->windowClassName, L"", type, 0, 0, 0, 0,
-                               parentToAddTo, 0, (HINSTANCE) PlatformUtilities::getCurrentModuleInstanceHandle(), 0);
-
-      #if JUCE_DIRECT2D
-        updateDirect2DContext();
-      #endif
-
-        if (hwnd != 0)
-        {
-            SetWindowLongPtr (hwnd, 0, 0);
-            SetWindowLongPtr (hwnd, 8, (LONG_PTR) this);
-            SetWindowLongPtr (hwnd, GWLP_USERDATA, improbableWindowNumber);
-
-            if (dropTarget == 0)
-                dropTarget = new JuceDropTarget (this);
-
-            RegisterDragDrop (hwnd, dropTarget);
-
-            updateBorderSize();
-
-            // Calling this function here is (for some reason) necessary to make Windows
-            // correctly enable the menu items that we specify in the wm_initmenu message.
-            GetSystemMenu (hwnd, false);
-
-            const float alpha = component->getAlpha();
-            if (alpha < 1.0f)
-                setAlpha (alpha);
-        }
-        else
-        {
-            jassertfalse;
-        }
-    }
-
-    static void* destroyWindowCallback (void* handle)
-    {
-        RevokeDragDrop ((HWND) handle);
-        DestroyWindow ((HWND) handle);
-        return 0;
-    }
-
-    static void* toFrontCallback1 (void* h)
-    {
-        SetForegroundWindow ((HWND) h);
-        return 0;
-    }
-
-    static void* toFrontCallback2 (void* h)
-    {
-        SetWindowPos ((HWND) h, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOSENDCHANGING);
-        return 0;
-    }
-
-    static void* setFocusCallback (void* h)
-    {
-        SetFocus ((HWND) h);
-        return 0;
-    }
-
-    static void* getFocusCallback (void*)
-    {
-        return GetFocus();
-    }
-
-    void offsetWithinParent (int& x, int& y) const
-    {
-        if (isUsingUpdateLayeredWindow())
-        {
-            HWND parentHwnd = GetParent (hwnd);
-
-            if (parentHwnd != 0)
-            {
-                RECT parentRect;
-                GetWindowRect (parentHwnd, &parentRect);
-                x += parentRect.left;
-                y += parentRect.top;
-            }
-        }
-    }
-
-    bool isUsingUpdateLayeredWindow() const
-    {
-        return ! component->isOpaque();
-    }
-
-    inline bool hasTitleBar() const throw()         { return (styleFlags & windowHasTitleBar) != 0; }
-
-
-    void setIcon (const Image& newIcon)
-    {
-        HICON hicon = IconConverters::createHICONFromImage (newIcon, TRUE, 0, 0);
-
-        if (hicon != 0)
-        {
-            SendMessage (hwnd, WM_SETICON, ICON_BIG, (LPARAM) hicon);
-            SendMessage (hwnd, WM_SETICON, ICON_SMALL, (LPARAM) hicon);
-
-            if (currentWindowIcon != 0)
-                DestroyIcon (currentWindowIcon);
-
-            currentWindowIcon = hicon;
-        }
-    }
-
-    //==============================================================================
-    void handlePaintMessage()
-    {
-#if JUCE_DIRECT2D
-        if (direct2DContext != 0)
-        {
-            RECT r;
-
-            if (GetUpdateRect (hwnd, &r, false))
-            {
-                direct2DContext->start();
-                direct2DContext->clipToRectangle (Rectangle<int> (r.left, r.top, r.right - r.left, r.bottom - r.top));
-                handlePaint (*direct2DContext);
-                direct2DContext->end();
-            }
-        }
-        else
-#endif
-        {
-            HRGN rgn = CreateRectRgn (0, 0, 0, 0);
-            const int regionType = GetUpdateRgn (hwnd, rgn, false);
-
-            PAINTSTRUCT paintStruct;
-            HDC dc = BeginPaint (hwnd, &paintStruct); // Note this can immediately generate a WM_NCPAINT
-                                                      // message and become re-entrant, but that's OK
-
-            // if something in a paint handler calls, e.g. a message box, this can become reentrant and
-            // corrupt the image it's using to paint into, so do a check here.
-            static bool reentrant = false;
-            if (reentrant)
-            {
-                DeleteObject (rgn);
-                EndPaint (hwnd, &paintStruct);
-                return;
-            }
-
-            reentrant = true;
-
-            // this is the rectangle to update..
-            int x = paintStruct.rcPaint.left;
-            int y = paintStruct.rcPaint.top;
-            int w = paintStruct.rcPaint.right - x;
-            int h = paintStruct.rcPaint.bottom - y;
-
-            const bool transparent = isUsingUpdateLayeredWindow();
-
-            if (transparent)
-            {
-                // it's not possible to have a transparent window with a title bar at the moment!
-                jassert (! hasTitleBar());
-
-                RECT r;
-                GetWindowRect (hwnd, &r);
-                x = y = 0;
-                w = r.right - r.left;
-                h = r.bottom - r.top;
-            }
-
-            if (w > 0 && h > 0)
-            {
-                clearMaskedRegion();
-
-                Image offscreenImage (offscreenImageGenerator.getImage (transparent, w, h));
-
-                RectangleList contextClip;
-                const Rectangle<int> clipBounds (0, 0, w, h);
-
-                bool needToPaintAll = true;
-
-                if (regionType == COMPLEXREGION && ! transparent)
-                {
-                    HRGN clipRgn = CreateRectRgnIndirect (&paintStruct.rcPaint);
-                    CombineRgn (rgn, rgn, clipRgn, RGN_AND);
-                    DeleteObject (clipRgn);
-
-                    char rgnData [8192];
-                    const DWORD res = GetRegionData (rgn, sizeof (rgnData), (RGNDATA*) rgnData);
-
-                    if (res > 0 && res <= sizeof (rgnData))
-                    {
-                        const RGNDATAHEADER* const hdr = &(((const RGNDATA*) rgnData)->rdh);
-
-                        if (hdr->iType == RDH_RECTANGLES
-                             && hdr->rcBound.right - hdr->rcBound.left >= w
-                             && hdr->rcBound.bottom - hdr->rcBound.top >= h)
-                        {
-                            needToPaintAll = false;
-
-                            const RECT* rects = (const RECT*) (rgnData + sizeof (RGNDATAHEADER));
-                            int num = ((RGNDATA*) rgnData)->rdh.nCount;
-
-                            while (--num >= 0)
-                            {
-                                if (rects->right <= x + w && rects->bottom <= y + h)
-                                {
-                                    const int cx = jmax (x, (int) rects->left);
-                                    contextClip.addWithoutMerging (Rectangle<int> (cx - x, rects->top - y, rects->right - cx, rects->bottom - rects->top)
-                                                                       .getIntersection (clipBounds));
-                                }
-                                else
-                                {
-                                    needToPaintAll = true;
-                                    break;
-                                }
-
-                                ++rects;
-                            }
-                        }
-                    }
-                }
-
-                if (needToPaintAll)
-                {
-                    contextClip.clear();
-                    contextClip.addWithoutMerging (Rectangle<int> (w, h));
-                }
-
-                if (transparent)
-                {
-                    RectangleList::Iterator i (contextClip);
-
-                    while (i.next())
-                        offscreenImage.clear (*i.getRectangle());
-                }
-
-                // if the component's not opaque, this won't draw properly unless the platform can support this
-                jassert (Desktop::canUseSemiTransparentWindows() || component->isOpaque());
-
-                updateCurrentModifiers();
-
-                LowLevelGraphicsSoftwareRenderer context (offscreenImage, -x, -y, contextClip);
-                handlePaint (context);
-
-                if (! dontRepaint)
-                    static_cast <WindowsBitmapImage*> (offscreenImage.getSharedImage())
-                        ->blitToWindow (hwnd, dc, transparent, x, y, maskedRegion, updateLayeredWindowAlpha);
-            }
-
-            DeleteObject (rgn);
-            EndPaint (hwnd, &paintStruct);
-            reentrant = false;
-        }
-
-#ifndef JUCE_GCC  //xxx should add this fn for gcc..
-        _fpreset(); // because some graphics cards can unmask FP exceptions
-#endif
-
-        lastPaintTime = Time::getMillisecondCounter();
-    }
-
-    //==============================================================================
-    void doMouseEvent (const Point<int>& position)
-    {
-        handleMouseEvent (0, position, currentModifiers, getMouseEventTime());
-    }
-
-    const StringArray getAvailableRenderingEngines()
-    {
-        StringArray s (ComponentPeer::getAvailableRenderingEngines());
-
-#if JUCE_DIRECT2D
-        // xxx is this correct? Seems to enable it on Vista too??
-        OSVERSIONINFO info;
-        zerostruct (info);
-        info.dwOSVersionInfoSize = sizeof (OSVERSIONINFO);
-        GetVersionEx (&info);
-        if (info.dwMajorVersion >= 6)
-            s.add ("Direct2D");
-#endif
-        return s;
-    }
-
-    int getCurrentRenderingEngine() throw()
-    {
-        return currentRenderingEngine;
-    }
-
-#if JUCE_DIRECT2D
-    void updateDirect2DContext()
-    {
-        if (currentRenderingEngine != direct2DRenderingEngine)
-            direct2DContext = 0;
-        else if (direct2DContext == 0)
-            direct2DContext = new Direct2DLowLevelGraphicsContext (hwnd);
-    }
-#endif
-
-    void setCurrentRenderingEngine (int index)
-    {
-        (void) index;
-
-#if JUCE_DIRECT2D
-        currentRenderingEngine = index == 1 ? direct2DRenderingEngine : softwareRenderingEngine;
-        updateDirect2DContext();
-        repaint (component->getLocalBounds());
-#endif
-    }
-
-    void doMouseMove (const Point<int>& position)
-    {
-        if (! isMouseOver)
-        {
-            isMouseOver = true;
-            updateKeyModifiers();
-
-            TRACKMOUSEEVENT tme;
-            tme.cbSize = sizeof (tme);
-            tme.dwFlags = TME_LEAVE;
-            tme.hwndTrack = hwnd;
-            tme.dwHoverTime = 0;
-
-            if (! TrackMouseEvent (&tme))
-                jassertfalse;
-
-            Desktop::getInstance().getMainMouseSource().forceMouseCursorUpdate();
-        }
-        else if (! isDragging)
-        {
-            if (! contains (position, false))
-                return;
-        }
-
-        // (Throttling the incoming queue of mouse-events seems to still be required in XP..)
-        static uint32 lastMouseTime = 0;
-        const uint32 now = Time::getMillisecondCounter();
-        const int maxMouseMovesPerSecond = 60;
-
-        if (now > lastMouseTime + 1000 / maxMouseMovesPerSecond)
-        {
-            lastMouseTime = now;
-            doMouseEvent (position);
-        }
-    }
-
-    void doMouseDown (const Point<int>& position, const WPARAM wParam)
-    {
-        if (GetCapture() != hwnd)
-            SetCapture (hwnd);
-
-        doMouseMove (position);
-
-        updateModifiersFromWParam (wParam);
-        isDragging = true;
-
-        doMouseEvent (position);
-    }
-
-    void doMouseUp (const Point<int>& position, const WPARAM wParam)
-    {
-        updateModifiersFromWParam (wParam);
-        isDragging = false;
-
-        // release the mouse capture if the user has released all buttons
-        if ((wParam & (MK_LBUTTON | MK_RBUTTON | MK_MBUTTON)) == 0 && hwnd == GetCapture())
-            ReleaseCapture();
-
-        doMouseEvent (position);
-    }
-
-    void doCaptureChanged()
-    {
-        if (isDragging)
-            doMouseUp (getCurrentMousePos(), (WPARAM) 0);
-    }
-
-    void doMouseExit()
-    {
-        isMouseOver = false;
-        doMouseEvent (getCurrentMousePos());
-    }
-
-    void doMouseWheel (const Point<int>& position, const WPARAM wParam, const bool isVertical)
-    {
-        updateKeyModifiers();
-
-        const float amount = jlimit (-1000.0f, 1000.0f, 0.75f * (short) HIWORD (wParam));
-
-        handleMouseWheel (0, position, getMouseEventTime(),
-                          isVertical ? 0.0f : amount,
-                          isVertical ? amount : 0.0f);
-    }
-
-    //==============================================================================
-    void sendModifierKeyChangeIfNeeded()
-    {
-        if (modifiersAtLastCallback != currentModifiers)
-        {
-            modifiersAtLastCallback = currentModifiers;
-            handleModifierKeysChange();
-        }
-    }
-
-    bool doKeyUp (const WPARAM key)
-    {
-        updateKeyModifiers();
-
-        switch (key)
-        {
-            case VK_SHIFT:
-            case VK_CONTROL:
-            case VK_MENU:
-            case VK_CAPITAL:
-            case VK_LWIN:
-            case VK_RWIN:
-            case VK_APPS:
-            case VK_NUMLOCK:
-            case VK_SCROLL:
-            case VK_LSHIFT:
-            case VK_RSHIFT:
-            case VK_LCONTROL:
-            case VK_LMENU:
-            case VK_RCONTROL:
-            case VK_RMENU:
-                sendModifierKeyChangeIfNeeded();
-        }
-
-        return handleKeyUpOrDown (false)
-                || Component::getCurrentlyModalComponent() != 0;
-    }
-
-    bool doKeyDown (const WPARAM key)
-    {
-        updateKeyModifiers();
-        bool used = false;
-
-        switch (key)
-        {
-            case VK_SHIFT:
-            case VK_LSHIFT:
-            case VK_RSHIFT:
-            case VK_CONTROL:
-            case VK_LCONTROL:
-            case VK_RCONTROL:
-            case VK_MENU:
-            case VK_LMENU:
-            case VK_RMENU:
-            case VK_LWIN:
-            case VK_RWIN:
-            case VK_CAPITAL:
-            case VK_NUMLOCK:
-            case VK_SCROLL:
-            case VK_APPS:
-                sendModifierKeyChangeIfNeeded();
-                break;
-
-            case VK_LEFT:
-            case VK_RIGHT:
-            case VK_UP:
-            case VK_DOWN:
-            case VK_PRIOR:
-            case VK_NEXT:
-            case VK_HOME:
-            case VK_END:
-            case VK_DELETE:
-            case VK_INSERT:
-            case VK_F1:
-            case VK_F2:
-            case VK_F3:
-            case VK_F4:
-            case VK_F5:
-            case VK_F6:
-            case VK_F7:
-            case VK_F8:
-            case VK_F9:
-            case VK_F10:
-            case VK_F11:
-            case VK_F12:
-            case VK_F13:
-            case VK_F14:
-            case VK_F15:
-            case VK_F16:
-                used = handleKeyUpOrDown (true);
-                used = handleKeyPress (extendedKeyModifier | (int) key, 0) || used;
-                break;
-
-            case VK_ADD:
-            case VK_SUBTRACT:
-            case VK_MULTIPLY:
-            case VK_DIVIDE:
-            case VK_SEPARATOR:
-            case VK_DECIMAL:
-                used = handleKeyUpOrDown (true);
-                break;
-
-            default:
-                used = handleKeyUpOrDown (true);
-
-                {
-                    MSG msg;
-
-                    if (! PeekMessage (&msg, hwnd, WM_CHAR, WM_DEADCHAR, PM_NOREMOVE))
-                    {
-                        // if there isn't a WM_CHAR or WM_DEADCHAR message pending, we need to
-                        // manually generate the key-press event that matches this key-down.
-
-                        const UINT keyChar = MapVirtualKey (key, 2);
-                        used = handleKeyPress ((int) LOWORD (keyChar), 0) || used;
-                    }
-                }
-
-                break;
-        }
-
-        if (Component::getCurrentlyModalComponent() != 0)
-            used = true;
-
-        return used;
-    }
-
-    bool doKeyChar (int key, const LPARAM flags)
-    {
-        updateKeyModifiers();
-
-        juce_wchar textChar = (juce_wchar) key;
-
-        const int virtualScanCode = (flags >> 16) & 0xff;
-
-        if (key >= '0' && key <= '9')
-        {
-            switch (virtualScanCode)  // check for a numeric keypad scan-code
-            {
-            case 0x52:
-            case 0x4f:
-            case 0x50:
-            case 0x51:
-            case 0x4b:
-            case 0x4c:
-            case 0x4d:
-            case 0x47:
-            case 0x48:
-            case 0x49:
-                key = (key - '0') + KeyPress::numberPad0;
-                break;
-            default:
-                break;
-            }
-        }
-        else
-        {
-            // convert the scan code to an unmodified character code..
-            const UINT virtualKey = MapVirtualKey (virtualScanCode, 1);
-            UINT keyChar = MapVirtualKey (virtualKey, 2);
-
-            keyChar = LOWORD (keyChar);
-
-            if (keyChar != 0)
-                key = (int) keyChar;
-
-            // avoid sending junk text characters for some control-key combinations
-            if (textChar < ' ' && currentModifiers.testFlags (ModifierKeys::ctrlModifier | ModifierKeys::altModifier))
-                textChar = 0;
-        }
-
-        return handleKeyPress (key, textChar);
-    }
-
-    bool doAppCommand (const LPARAM lParam)
-    {
-        int key = 0;
-
-        switch (GET_APPCOMMAND_LPARAM (lParam))
-        {
-            case APPCOMMAND_MEDIA_PLAY_PAUSE:       key = KeyPress::playKey; break;
-            case APPCOMMAND_MEDIA_STOP:             key = KeyPress::stopKey; break;
-            case APPCOMMAND_MEDIA_NEXTTRACK:        key = KeyPress::fastForwardKey; break;
-            case APPCOMMAND_MEDIA_PREVIOUSTRACK:    key = KeyPress::rewindKey; break;
-            default: break;
-        }
-
-        if (key != 0)
-        {
-            updateKeyModifiers();
-
-            if (hwnd == GetActiveWindow())
-            {
-                handleKeyPress (key, 0);
-                return true;
-            }
-        }
-
-        return false;
-    }
-
-    LRESULT handleSizeConstraining (RECT* const r, const WPARAM wParam)
-    {
-        if (constrainer != 0 && (styleFlags & (windowHasTitleBar | windowIsResizable)) == (windowHasTitleBar | windowIsResizable))
-        {
-            Rectangle<int> pos (r->left, r->top, r->right - r->left, r->bottom - r->top);
-
-            constrainer->checkBounds (pos, windowBorder.addedTo (component->getBounds()),
-                                      Desktop::getInstance().getAllMonitorDisplayAreas().getBounds(),
-                                      wParam == WMSZ_TOP || wParam == WMSZ_TOPLEFT || wParam == WMSZ_TOPRIGHT,
-                                      wParam == WMSZ_LEFT || wParam == WMSZ_TOPLEFT || wParam == WMSZ_BOTTOMLEFT,
-                                      wParam == WMSZ_BOTTOM || wParam == WMSZ_BOTTOMLEFT || wParam == WMSZ_BOTTOMRIGHT,
-                                      wParam == WMSZ_RIGHT || wParam == WMSZ_TOPRIGHT || wParam == WMSZ_BOTTOMRIGHT);
-            r->left = pos.getX();
-            r->top = pos.getY();
-            r->right = pos.getRight();
-            r->bottom = pos.getBottom();
-        }
-
-        return TRUE;
-    }
-
-    LRESULT handlePositionChanging (WINDOWPOS* const wp)
-    {
-        if (constrainer != 0 && (styleFlags & (windowHasTitleBar | windowIsResizable)) == (windowHasTitleBar | windowIsResizable))
-        {
-            if ((wp->flags & (SWP_NOMOVE | SWP_NOSIZE)) != (SWP_NOMOVE | SWP_NOSIZE)
-                 && ! Component::isMouseButtonDownAnywhere())
-            {
-                Rectangle<int> pos (wp->x, wp->y, wp->cx, wp->cy);
-                const Rectangle<int> current (windowBorder.addedTo (component->getBounds()));
-
-                constrainer->checkBounds (pos, current,
-                                          Desktop::getInstance().getAllMonitorDisplayAreas().getBounds(),
-                                          pos.getY() != current.getY() && pos.getBottom() == current.getBottom(),
-                                          pos.getX() != current.getX() && pos.getRight() == current.getRight(),
-                                          pos.getY() == current.getY() && pos.getBottom() != current.getBottom(),
-                                          pos.getX() == current.getX() && pos.getRight() != current.getRight());
-                wp->x = pos.getX();
-                wp->y = pos.getY();
-                wp->cx = pos.getWidth();
-                wp->cy = pos.getHeight();
-            }
-        }
-
-        return 0;
-    }
-
-    void handleAppActivation (const WPARAM wParam)
-    {
-        modifiersAtLastCallback = -1;
-        updateKeyModifiers();
-
-        if (isMinimised())
-        {
-            component->repaint();
-            handleMovedOrResized();
-
-            if (! ComponentPeer::isValidPeer (this))
-                return;
-        }
-
-        if (LOWORD (wParam) == WA_CLICKACTIVE && component->isCurrentlyBlockedByAnotherModalComponent())
-        {
-            Component* const underMouse = component->getComponentAt (component->getMouseXYRelative());
-
-            if (underMouse != 0 && underMouse->isCurrentlyBlockedByAnotherModalComponent())
-                Component::getCurrentlyModalComponent()->inputAttemptWhenModal();
-        }
-        else
-        {
-            handleBroughtToFront();
-
-            if (component->isCurrentlyBlockedByAnotherModalComponent())
-                Component::getCurrentlyModalComponent()->toFront (true);
-        }
-    }
-
-    //==============================================================================
-    class JuceDropTarget    : public ComBaseClassHelper <IDropTarget>
-    {
-    public:
-        JuceDropTarget (Win32ComponentPeer* const owner_)
-            : owner (owner_)
-        {
-        }
-
-        HRESULT __stdcall DragEnter (IDataObject* pDataObject, DWORD /*grfKeyState*/, POINTL mousePos, DWORD* pdwEffect)
-        {
-            updateFileList (pDataObject);
-            owner->handleFileDragMove (files, owner->globalToLocal (Point<int> (mousePos.x, mousePos.y)));
-            *pdwEffect = DROPEFFECT_COPY;
-            return S_OK;
-        }
-
-        HRESULT __stdcall DragLeave()
-        {
-            owner->handleFileDragExit (files);
-            return S_OK;
-        }
-
-        HRESULT __stdcall DragOver (DWORD /*grfKeyState*/, POINTL mousePos, DWORD* pdwEffect)
-        {
-            owner->handleFileDragMove (files, owner->globalToLocal (Point<int> (mousePos.x, mousePos.y)));
-            *pdwEffect = DROPEFFECT_COPY;
-            return S_OK;
-        }
-
-        HRESULT __stdcall Drop (IDataObject* pDataObject, DWORD /*grfKeyState*/, POINTL mousePos, DWORD* pdwEffect)
-        {
-            updateFileList (pDataObject);
-            owner->handleFileDragDrop (files, owner->globalToLocal (Point<int> (mousePos.x, mousePos.y)));
-            *pdwEffect = DROPEFFECT_COPY;
-            return S_OK;
-        }
-
-    private:
-        Win32ComponentPeer* const owner;
-        StringArray files;
-
-        void updateFileList (IDataObject* const pDataObject)
-        {
-            files.clear();
-
-            FORMATETC format = { CF_HDROP, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
-            STGMEDIUM medium = { TYMED_HGLOBAL, { 0 }, 0 };
-
-            if (pDataObject->GetData (&format, &medium) == S_OK)
-            {
-                const SIZE_T totalLen = GlobalSize (medium.hGlobal);
-                const LPDROPFILES pDropFiles = (const LPDROPFILES) GlobalLock (medium.hGlobal);
-                unsigned int i = 0;
-
-                if (pDropFiles->fWide)
-                {
-                    const WCHAR* const fname = (WCHAR*) (((const char*) pDropFiles) + sizeof (DROPFILES));
-
-                    for (;;)
-                    {
-                        unsigned int len = 0;
-                        while (i + len < totalLen && fname [i + len] != 0)
-                            ++len;
-
-                        if (len == 0)
-                            break;
-
-                        files.add (String (fname + i, len));
-                        i += len + 1;
-                    }
-                }
-                else
-                {
-                    const char* const fname = ((const char*) pDropFiles) + sizeof (DROPFILES);
-
-                    for (;;)
-                    {
-                        unsigned int len = 0;
-                        while (i + len < totalLen && fname [i + len] != 0)
-                            ++len;
-
-                        if (len == 0)
-                            break;
-
-                        files.add (String (fname + i, len));
-                        i += len + 1;
-                    }
-                }
-
-                GlobalUnlock (medium.hGlobal);
-            }
-        }
-
-        JUCE_DECLARE_NON_COPYABLE (JuceDropTarget);
-    };
-
-    void doSettingChange()
-    {
-        Desktop::getInstance().refreshMonitorSizes();
-
-        if (fullScreen && ! isMinimised())
-        {
-            const Rectangle<int> r (component->getParentMonitorArea());
-
-            SetWindowPos (hwnd, 0, r.getX(), r.getY(), r.getWidth(), r.getHeight(),
-                          SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOZORDER | SWP_NOSENDCHANGING);
-        }
-    }
-
-    //==============================================================================
-public:
-    static LRESULT CALLBACK windowProc (HWND h, UINT message, WPARAM wParam, LPARAM lParam)
-    {
-        Win32ComponentPeer* const peer = getOwnerOfWindow (h);
-
-        if (peer != 0)
-        {
-            jassert (isValidPeer (peer));
-            return peer->peerWindowProc (h, message, wParam, lParam);
-        }
-
-        return DefWindowProcW (h, message, wParam, lParam);
-    }
-
-private:
-    static void* callFunctionIfNotLocked (MessageCallbackFunction* callback, void* userData)
-    {
-        if (MessageManager::getInstance()->currentThreadHasLockedMessageManager())
-            return callback (userData);
-        else
-            return MessageManager::getInstance()->callFunctionOnMessageThread (callback, userData);
-    }
-
-    static const Point<int> getPointFromLParam (LPARAM lParam) throw()
-    {
-        return Point<int> (GET_X_LPARAM (lParam), GET_Y_LPARAM (lParam));
-    }
-
-    const Point<int> getCurrentMousePos() throw()
-    {
-        RECT wr;
-        GetWindowRect (hwnd, &wr);
-        const DWORD mp = GetMessagePos();
-
-        return Point<int> (GET_X_LPARAM (mp) - wr.left - windowBorder.getLeft(),
-                           GET_Y_LPARAM (mp) - wr.top - windowBorder.getTop());
-    }
-
-    LRESULT peerWindowProc (HWND h, UINT message, WPARAM wParam, LPARAM lParam)
-    {
-        switch (message)
-        {
-            //==============================================================================
-            case WM_NCHITTEST:
-                if ((styleFlags & windowIgnoresMouseClicks) != 0)
-                    return HTTRANSPARENT;
-                else if (! hasTitleBar())
-                    return HTCLIENT;
-
-                break;
-
-            //==============================================================================
-            case WM_PAINT:
-                handlePaintMessage();
-                return 0;
-
-            case WM_NCPAINT:
-                if (wParam != 1)
-                    handlePaintMessage();
-
-                if (hasTitleBar())
-                    break;
-
-                return 0;
-
-            case WM_ERASEBKGND:
-            case WM_NCCALCSIZE:
-                if (hasTitleBar())
-                    break;
-
-                return 1;
-
-            //==============================================================================
-            case WM_MOUSEMOVE:
-                doMouseMove (getPointFromLParam (lParam));
-                return 0;
-
-            case WM_MOUSELEAVE:
-                doMouseExit();
-                return 0;
-
-            case WM_LBUTTONDOWN:
-            case WM_MBUTTONDOWN:
-            case WM_RBUTTONDOWN:
-                doMouseDown (getPointFromLParam (lParam), wParam);
-                return 0;
-
-            case WM_LBUTTONUP:
-            case WM_MBUTTONUP:
-            case WM_RBUTTONUP:
-                doMouseUp (getPointFromLParam (lParam), wParam);
-                return 0;
-
-            case WM_CAPTURECHANGED:
-                doCaptureChanged();
-                return 0;
-
-            case WM_NCMOUSEMOVE:
-                if (hasTitleBar())
-                    break;
-
-                return 0;
-
-            case 0x020A: /* WM_MOUSEWHEEL */
-            case 0x020E: /* WM_MOUSEHWHEEL */
-                doMouseWheel (getCurrentMousePos(), wParam, message == 0x020A);
-                return 0;
-
-            //==============================================================================
-            case WM_SIZING:
-                return handleSizeConstraining ((RECT*) lParam, wParam);
-
-            case WM_WINDOWPOSCHANGING:
-                return handlePositionChanging ((WINDOWPOS*) lParam);
-
-            case WM_WINDOWPOSCHANGED:
-                {
-                    const Point<int> pos (getCurrentMousePos());
-                    if (contains (pos, false))
-                        doMouseEvent (pos);
-                }
-
-                handleMovedOrResized();
-
-                if (dontRepaint)
-                    break;  // needed for non-accelerated openGL windows to draw themselves correctly..
-
-                return 0;
-
-            //==============================================================================
-            case WM_KEYDOWN:
-            case WM_SYSKEYDOWN:
-                if (doKeyDown (wParam))
-                    return 0;
-
-                break;
-
-            case WM_KEYUP:
-            case WM_SYSKEYUP:
-                if (doKeyUp (wParam))
-                    return 0;
-
-                break;
-
-            case WM_CHAR:
-                if (doKeyChar ((int) wParam, lParam))
-                    return 0;
-
-                break;
-
-            case WM_APPCOMMAND:
-                if (doAppCommand (lParam))
-                    return TRUE;
-
-                break;
-
-            //==============================================================================
-            case WM_SETFOCUS:
-                updateKeyModifiers();
-                handleFocusGain();
-                break;
-
-            case WM_KILLFOCUS:
-                if (hasCreatedCaret)
-                {
-                    hasCreatedCaret = false;
-                    DestroyCaret();
-                }
-
-                handleFocusLoss();
-                break;
-
-            case WM_ACTIVATEAPP:
-                // Windows does weird things to process priority when you swap apps,
-                // so this forces an update when the app is brought to the front
-                if (wParam != FALSE)
-                    juce_repeatLastProcessPriority();
-                else
-                    Desktop::getInstance().setKioskModeComponent (0); // turn kiosk mode off if we lose focus
-
-                juce_CheckCurrentlyFocusedTopLevelWindow();
-                modifiersAtLastCallback = -1;
-                return 0;
-
-            case WM_ACTIVATE:
-                if (LOWORD (wParam) == WA_ACTIVE || LOWORD (wParam) == WA_CLICKACTIVE)
-                {
-                    handleAppActivation (wParam);
-                    return 0;
-                }
-
-                break;
-
-            case WM_NCACTIVATE:
-                // while a temporary window is being shown, prevent Windows from deactivating the
-                // title bars of our main windows.
-                if (wParam == 0 && ! shouldDeactivateTitleBar)
-                    wParam = TRUE; // change this and let it get passed to the DefWindowProc.
-
-                break;
-
-            case WM_MOUSEACTIVATE:
-                if (! component->getMouseClickGrabsKeyboardFocus())
-                    return MA_NOACTIVATE;
-
-                break;
-
-            case WM_SHOWWINDOW:
-                if (wParam != 0)
-                    handleBroughtToFront();
-
-                break;
-
-            case WM_CLOSE:
-                if (! component->isCurrentlyBlockedByAnotherModalComponent())
-                    handleUserClosingWindow();
-
-                return 0;
-
-            case WM_QUERYENDSESSION:
-                if (JUCEApplication::getInstance() != 0)
-                {
-                    JUCEApplication::getInstance()->systemRequestedQuit();
-                    return MessageManager::getInstance()->hasStopMessageBeenSent();
-                }
-                return TRUE;
-
-            case WM_TRAYNOTIFY:
-                handleTaskBarEvent (lParam);
-                break;
-
-            case WM_SYNCPAINT:
-                return 0;
-
-            case WM_PALETTECHANGED:
-                InvalidateRect (h, 0, 0);
-                break;
-
-            case WM_DISPLAYCHANGE:
-                InvalidateRect (h, 0, 0);
-                createPaletteIfNeeded = true;
-                // intentional fall-through...
-            case WM_SETTINGCHANGE:  // note the fall-through in the previous case!
-                doSettingChange();
-                break;
-
-            case WM_INITMENU:
-                if (! hasTitleBar())
-                {
-                    if (isFullScreen())
-                    {
-                        EnableMenuItem ((HMENU) wParam, SC_RESTORE, MF_BYCOMMAND | MF_ENABLED);
-                        EnableMenuItem ((HMENU) wParam, SC_MOVE, MF_BYCOMMAND | MF_GRAYED);
-                    }
-                    else if (! isMinimised())
-                    {
-                        EnableMenuItem ((HMENU) wParam, SC_MAXIMIZE, MF_BYCOMMAND | MF_GRAYED);
-                    }
-                }
-                break;
-
-            case WM_SYSCOMMAND:
-                switch (wParam & 0xfff0)
-                {
-                case SC_CLOSE:
-                    if (sendInputAttemptWhenModalMessage())
-                        return 0;
-
-                    if (hasTitleBar())
-                    {
-                        PostMessage (h, WM_CLOSE, 0, 0);
-                        return 0;
-                    }
-                    break;
-
-                case SC_KEYMENU:
-                    // (NB mustn't call sendInputAttemptWhenModalMessage() here because of very obscure
-                    // situations that can arise if a modal loop is started from an alt-key keypress).
-                    if (hasTitleBar() && h == GetCapture())
-                        ReleaseCapture();
-
-                    break;
-
-                case SC_MAXIMIZE:
-                    if (! sendInputAttemptWhenModalMessage())
-                        setFullScreen (true);
-
-                    return 0;
-
-                case SC_MINIMIZE:
-                    if (sendInputAttemptWhenModalMessage())
-                        return 0;
-
-                    if (! hasTitleBar())
-                    {
-                        setMinimised (true);
-                        return 0;
-                    }
-                    break;
-
-                case SC_RESTORE:
-                    if (sendInputAttemptWhenModalMessage())
-                        return 0;
-
-                    if (hasTitleBar())
-                    {
-                        if (isFullScreen())
-                        {
-                            setFullScreen (false);
-                            return 0;
-                        }
-                    }
-                    else
-                    {
-                        if (isMinimised())
-                            setMinimised (false);
-                        else if (isFullScreen())
-                            setFullScreen (false);
-
-                        return 0;
-                    }
-                    break;
-                }
-
-                break;
-
-            case WM_NCLBUTTONDOWN:
-            case WM_NCRBUTTONDOWN:
-            case WM_NCMBUTTONDOWN:
-                sendInputAttemptWhenModalMessage();
-                break;
-
-            //case WM_IME_STARTCOMPOSITION;
-              //  return 0;
-
-            case WM_GETDLGCODE:
-                return DLGC_WANTALLKEYS;
-
-            default:
-                if (taskBarIcon != 0)
-                {
-                    static const DWORD taskbarCreatedMessage = RegisterWindowMessage (TEXT("TaskbarCreated"));
-
-                    if (message == taskbarCreatedMessage)
-                    {
-                        taskBarIcon->uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP;
-                        Shell_NotifyIcon (NIM_ADD, taskBarIcon);
-                    }
-                }
-
-                break;
-        }
-
-        return DefWindowProcW (h, message, wParam, lParam);
-    }
-
-    bool sendInputAttemptWhenModalMessage()
-    {
-        if (component->isCurrentlyBlockedByAnotherModalComponent())
-        {
-            Component* const current = Component::getCurrentlyModalComponent();
-
-            if (current != 0)
-                current->inputAttemptWhenModal();
-
-            return true;
-        }
-
-        return false;
-    }
-
-    JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Win32ComponentPeer);
-};
-
-ModifierKeys Win32ComponentPeer::currentModifiers;
-ModifierKeys Win32ComponentPeer::modifiersAtLastCallback;
-
-ComponentPeer* Component::createNewPeer (int styleFlags, void* nativeWindowToAttachTo)
-{
-    return new Win32ComponentPeer (this, styleFlags, (HWND) nativeWindowToAttachTo);
-}
-
-juce_ImplementSingleton_SingleThreaded (Win32ComponentPeer::WindowClassHolder);
-
-
-//==============================================================================
-void ModifierKeys::updateCurrentModifiers() throw()
-{
-    currentModifiers = Win32ComponentPeer::currentModifiers;
-}
-
-const ModifierKeys ModifierKeys::getCurrentModifiersRealtime() throw()
-{
-    Win32ComponentPeer::updateKeyModifiers();
-
-    int mouseMods = 0;
-    if ((GetKeyState (VK_LBUTTON) & 0x8000) != 0)   mouseMods |= ModifierKeys::leftButtonModifier;
-    if ((GetKeyState (VK_RBUTTON) & 0x8000) != 0)   mouseMods |= ModifierKeys::rightButtonModifier;
-    if ((GetKeyState (VK_MBUTTON) & 0x8000) != 0)   mouseMods |= ModifierKeys::middleButtonModifier;
-
-    Win32ComponentPeer::currentModifiers
-        = Win32ComponentPeer::currentModifiers.withoutMouseButtons().withFlags (mouseMods);
-
-    return Win32ComponentPeer::currentModifiers;
-}
-
-//==============================================================================
-void SystemTrayIconComponent::setIconImage (const Image& newImage)
-{
-    Win32ComponentPeer* const wp = dynamic_cast <Win32ComponentPeer*> (getPeer());
-
-    if (wp != 0)
-        wp->setTaskBarIcon (newImage);
-}
-
-void SystemTrayIconComponent::setIconTooltip (const String& tooltip)
-{
-    Win32ComponentPeer* const wp = dynamic_cast <Win32ComponentPeer*> (getPeer());
-
-    if (wp != 0)
-        wp->setTaskBarIconToolTip (tooltip);
-}
-
-//==============================================================================
-void juce_setWindowStyleBit (HWND h, const int styleType, const int feature, const bool bitIsSet) throw()
-{
-    DWORD val = GetWindowLong (h, styleType);
-
-    if (bitIsSet)
-        val |= feature;
-    else
-        val &= ~feature;
-
-    SetWindowLongPtr (h, styleType, val);
-    SetWindowPos (h, 0, 0, 0, 0, 0,
-                  SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER
-                   | SWP_NOOWNERZORDER | SWP_FRAMECHANGED | SWP_NOSENDCHANGING);
-}
-
-
-//==============================================================================
-bool Process::isForegroundProcess()
-{
-    HWND fg = GetForegroundWindow();
-
-    if (fg == 0)
-        return true;
-
-    // when running as a plugin in IE8, the browser UI runs in a different process to the plugin, so
-    // process ID isn't a reliable way to check if the foreground window belongs to us - instead, we
-    // have to see if any of our windows are children of the foreground window
-    fg = GetAncestor (fg, GA_ROOT);
-
-    for (int i = ComponentPeer::getNumPeers(); --i >= 0;)
-    {
-        Win32ComponentPeer* const wp = dynamic_cast <Win32ComponentPeer*> (ComponentPeer::getPeer (i));
-
-        if (wp != 0 && wp->isInside (fg))
-            return true;
-    }
-
-    return false;
-}
-
-//==============================================================================
-bool AlertWindow::showNativeDialogBox (const String& title,
-                                       const String& bodyText,
-                                       bool isOkCancel)
-{
-    return MessageBox (0, bodyText, title,
-                       MB_SETFOREGROUND | (isOkCancel ? MB_OKCANCEL
-                                                      : MB_OK)) == IDOK;
-}
-
-
-//==============================================================================
-void Desktop::createMouseInputSources()
-{
-    mouseSources.add (new MouseInputSource (0, true));
-}
-
-const Point<int> MouseInputSource::getCurrentMousePosition()
-{
-    POINT mousePos;
-    GetCursorPos (&mousePos);
-    return Point<int> (mousePos.x, mousePos.y);
-}
-
-void Desktop::setMousePosition (const Point<int>& newPosition)
-{
-    SetCursorPos (newPosition.getX(), newPosition.getY());
-}
-
-//==============================================================================
-Image::SharedImage* Image::SharedImage::createNativeImage (PixelFormat format, int width, int height, bool clearImage)
-{
-    return createSoftwareImage (format, width, height, clearImage);
-}
-
-//==============================================================================
-class ScreenSaverDefeater   : public Timer,
-                              public DeletedAtShutdown
-{
-public:
-    ScreenSaverDefeater()
-    {
-        startTimer (10000);
-        timerCallback();
-    }
-
-    ~ScreenSaverDefeater() {}
-
-    void timerCallback()
-    {
-        if (Process::isForegroundProcess())
-        {
-            // simulate a shift key getting pressed..
-            INPUT input[2];
-            input[0].type = INPUT_KEYBOARD;
-            input[0].ki.wVk = VK_SHIFT;
-            input[0].ki.dwFlags = 0;
-            input[0].ki.dwExtraInfo = 0;
-
-            input[1].type = INPUT_KEYBOARD;
-            input[1].ki.wVk = VK_SHIFT;
-            input[1].ki.dwFlags = KEYEVENTF_KEYUP;
-            input[1].ki.dwExtraInfo = 0;
-
-            SendInput (2, input, sizeof (INPUT));
-        }
-    }
-};
-
-static ScreenSaverDefeater* screenSaverDefeater = 0;
-
-void Desktop::setScreenSaverEnabled (const bool isEnabled)
-{
-    if (isEnabled)
-        deleteAndZero (screenSaverDefeater);
-    else if (screenSaverDefeater == 0)
-        screenSaverDefeater = new ScreenSaverDefeater();
-}
-
-bool Desktop::isScreenSaverEnabled()
-{
-    return screenSaverDefeater == 0;
-}
-
-/* (The code below is the "correct" way to disable the screen saver, but it
-    completely fails on winXP when the saver is password-protected...)
-
-static bool juce_screenSaverEnabled = true;
-
-void Desktop::setScreenSaverEnabled (const bool isEnabled) throw()
-{
-    juce_screenSaverEnabled = isEnabled;
-    SetThreadExecutionState (isEnabled ? ES_CONTINUOUS
-                                       : (ES_DISPLAY_REQUIRED | ES_CONTINUOUS));
-}
-
-bool Desktop::isScreenSaverEnabled() throw()
-{
-    return juce_screenSaverEnabled;
-}
-*/
-
-//==============================================================================
-void juce_setKioskComponent (Component* kioskModeComponent, bool enableOrDisable, bool /*allowMenusAndBars*/)
-{
-    if (enableOrDisable)
-        kioskModeComponent->setBounds (Desktop::getInstance().getMainMonitorArea (false));
-}
-
-//==============================================================================
-static BOOL CALLBACK enumMonitorsProc (HMONITOR, HDC, LPRECT r, LPARAM userInfo)
-{
-    Array <Rectangle<int> >* const monitorCoords = (Array <Rectangle<int> >*) userInfo;
-
-    monitorCoords->add (Rectangle<int> (r->left, r->top, r->right - r->left, r->bottom - r->top));
-
-    return TRUE;
-}
-
-void juce_updateMultiMonitorInfo (Array <Rectangle<int> >& monitorCoords, const bool clipToWorkArea)
-{
-    EnumDisplayMonitors (0, 0, &enumMonitorsProc, (LPARAM) &monitorCoords);
-
-    // make sure the first in the list is the main monitor
-    for (int i = 1; i < monitorCoords.size(); ++i)
-        if (monitorCoords[i].getX() == 0 && monitorCoords[i].getY() == 0)
-            monitorCoords.swap (i, 0);
-
-    if (monitorCoords.size() == 0)
-    {
-        RECT r;
-        GetWindowRect (GetDesktopWindow(), &r);
-
-        monitorCoords.add (Rectangle<int> (r.left, r.top, r.right - r.left, r.bottom - r.top));
-    }
-
-    if (clipToWorkArea)
-    {
-        // clip the main monitor to the active non-taskbar area
-        RECT r;
-        SystemParametersInfo (SPI_GETWORKAREA, 0, &r, 0);
-
-        Rectangle<int>& screen = monitorCoords.getReference (0);
-
-        screen.setPosition (jmax (screen.getX(), (int) r.left),
-                            jmax (screen.getY(), (int) r.top));
-
-        screen.setSize (jmin (screen.getRight(), (int) r.right) - screen.getX(),
-                        jmin (screen.getBottom(), (int) r.bottom) - screen.getY());
-    }
-}
-
-//==============================================================================
-const Image juce_createIconForFile (const File& file)
-{
-    Image image;
-
-    WCHAR filename [1024];
-    file.getFullPathName().copyToUnicode (filename, 1023);
-    WORD iconNum = 0;
-
-    HICON icon = ExtractAssociatedIcon ((HINSTANCE) PlatformUtilities::getCurrentModuleInstanceHandle(),
-                                        filename, &iconNum);
-
-    if (icon != 0)
-    {
-        image = IconConverters::createImageFromHICON (icon);
-        DestroyIcon (icon);
-    }
-
-    return image;
-}
-
-//==============================================================================
-void* MouseCursor::createMouseCursorFromImage (const Image& image, int hotspotX, int hotspotY)
-{
-    const int maxW = GetSystemMetrics (SM_CXCURSOR);
-    const int maxH = GetSystemMetrics (SM_CYCURSOR);
-
-    Image im (image);
-
-    if (im.getWidth() > maxW || im.getHeight() > maxH)
-    {
-        im = im.rescaled (maxW, maxH);
-
-        hotspotX = (hotspotX * maxW) / image.getWidth();
-        hotspotY = (hotspotY * maxH) / image.getHeight();
-    }
-
-    return IconConverters::createHICONFromImage (im, FALSE, hotspotX, hotspotY);
-}
-
-void MouseCursor::deleteMouseCursor (void* const cursorHandle, const bool isStandard)
-{
-    if (cursorHandle != 0 && ! isStandard)
-        DestroyCursor ((HCURSOR) cursorHandle);
-}
-
-enum
-{
-    hiddenMouseCursorHandle = 32500 // (arbitrary non-zero value to mark this type of cursor)
-};
-
-void* MouseCursor::createStandardMouseCursor (const MouseCursor::StandardCursorType type)
-{
-    LPCTSTR cursorName = IDC_ARROW;
-
-    switch (type)
-    {
-        case NormalCursor:                  break;
-        case NoCursor:                      return (void*) hiddenMouseCursorHandle;
-        case WaitCursor:                    cursorName = IDC_WAIT; break;
-        case IBeamCursor:                   cursorName = IDC_IBEAM; break;
-        case PointingHandCursor:            cursorName = MAKEINTRESOURCE(32649); break;
-        case CrosshairCursor:               cursorName = IDC_CROSS; break;
-        case CopyingCursor:                 break; // can't seem to find one of these in the win32 list..
-
-        case LeftRightResizeCursor:
-        case LeftEdgeResizeCursor:
-        case RightEdgeResizeCursor:         cursorName = IDC_SIZEWE; break;
-
-        case UpDownResizeCursor:
-        case TopEdgeResizeCursor:
-        case BottomEdgeResizeCursor:        cursorName = IDC_SIZENS; break;
-
-        case TopLeftCornerResizeCursor:
-        case BottomRightCornerResizeCursor: cursorName = IDC_SIZENWSE; break;
-
-        case TopRightCornerResizeCursor:
-        case BottomLeftCornerResizeCursor:  cursorName = IDC_SIZENESW; break;
-
-        case UpDownLeftRightResizeCursor:   cursorName = IDC_SIZEALL; break;
-
-        case DraggingHandCursor:
-        {
-            static void* dragHandCursor = 0;
-
-            if (dragHandCursor == 0)
-            {
-                static const unsigned char dragHandData[] =
-                    { 71,73,70,56,57,97,16,0,16,0,145,2,0,0,0,0,255,255,255,0,0,0,0,0,0,33,249,4,1,0,0,2,0,44,0,0,0,0,16,0,
-                      16,0,0,2,52,148,47,0,200,185,16,130,90,12,74,139,107,84,123,39,132,117,151,116,132,146,248,60,209,138,
-                      98,22,203,114,34,236,37,52,77,217,247,154,191,119,110,240,193,128,193,95,163,56,60,234,98,135,2,0,59 };
-
-                dragHandCursor = createMouseCursorFromImage (ImageFileFormat::loadFrom (dragHandData, sizeof (dragHandData)), 8, 7);
-            }
-
-            return dragHandCursor;
-        }
-
-        default:
-            jassertfalse; break;
-    }
-
-    HCURSOR cursorH = LoadCursor (0, cursorName);
-
-    if (cursorH == 0)
-        cursorH = LoadCursor (0, IDC_ARROW);
-
-    return cursorH;
-}
-
-//==============================================================================
-void MouseCursor::showInWindow (ComponentPeer*) const
-{
-    HCURSOR c = (HCURSOR) getHandle();
-
-    if (c == 0)
-        c = LoadCursor (0, IDC_ARROW);
-    else if (c == (HCURSOR) hiddenMouseCursorHandle)
-        c = 0;
-
-    SetCursor (c);
-}
-
-void MouseCursor::showInAllWindows() const
-{
-    showInWindow (0);
-}
-
-//==============================================================================
-//==============================================================================
-class JuceDropSource   : public ComBaseClassHelper <IDropSource>
-{
-public:
-    JuceDropSource() {}
-    ~JuceDropSource() {}
-
-    HRESULT __stdcall QueryContinueDrag (BOOL escapePressed, DWORD keys)
-    {
-        if (escapePressed)
-            return DRAGDROP_S_CANCEL;
-
-        if ((keys & (MK_LBUTTON | MK_RBUTTON)) == 0)
-            return DRAGDROP_S_DROP;
-
-        return S_OK;
-    }
-
-    HRESULT __stdcall GiveFeedback (DWORD)
-    {
-        return DRAGDROP_S_USEDEFAULTCURSORS;
-    }
-};
-
-
-class JuceEnumFormatEtc   : public ComBaseClassHelper <IEnumFORMATETC>
-{
-public:
-    JuceEnumFormatEtc (const FORMATETC* const format_)
-        : format (format_),
-          index (0)
-    {
-    }
-
-    ~JuceEnumFormatEtc()  {}
-
-    HRESULT __stdcall Clone (IEnumFORMATETC** result)
-    {
-        if (result == 0)
-            return E_POINTER;
-
-        JuceEnumFormatEtc* const newOne = new JuceEnumFormatEtc (format);
-        newOne->index = index;
-
-        *result = newOne;
-        return S_OK;
-    }
-
-    HRESULT __stdcall Next (ULONG celt, LPFORMATETC lpFormatEtc, ULONG* pceltFetched)
-    {
-        if (pceltFetched != 0)
-            *pceltFetched = 0;
-        else if (celt != 1)
-            return S_FALSE;
-
-        if (index == 0 && celt > 0 && lpFormatEtc != 0)
-        {
-            copyFormatEtc (lpFormatEtc [0], *format);
-            ++index;
-
-            if (pceltFetched != 0)
-                *pceltFetched = 1;
-
-            return S_OK;
-        }
-
-        return S_FALSE;
-    }
-
-    HRESULT __stdcall Skip (ULONG celt)
-    {
-        if (index + (int) celt >= 1)
-            return S_FALSE;
-
-        index += celt;
-        return S_OK;
-    }
-
-    HRESULT __stdcall Reset()
-    {
-        index = 0;
-        return S_OK;
-    }
-
-private:
-    const FORMATETC* const format;
-    int index;
-
-    static void copyFormatEtc (FORMATETC& dest, const FORMATETC& source)
-    {
-        dest = source;
-
-        if (source.ptd != 0)
-        {
-            dest.ptd = (DVTARGETDEVICE*) CoTaskMemAlloc (sizeof (DVTARGETDEVICE));
-            *(dest.ptd) = *(source.ptd);
-        }
-    }
-
-    JUCE_DECLARE_NON_COPYABLE (JuceEnumFormatEtc);
-};
-
-class JuceDataObject  : public ComBaseClassHelper <IDataObject>
-{
-public:
-    JuceDataObject (JuceDropSource* const dropSource_,
-                    const FORMATETC* const format_,
-                    const STGMEDIUM* const medium_)
-        : dropSource (dropSource_),
-          format (format_),
-          medium (medium_)
-    {
-    }
-
-    ~JuceDataObject()
-    {
-        jassert (refCount == 0);
-    }
-
-    HRESULT __stdcall GetData (FORMATETC* pFormatEtc, STGMEDIUM* pMedium)
-    {
-        if ((pFormatEtc->tymed & format->tymed) != 0
-             && pFormatEtc->cfFormat == format->cfFormat
-             && pFormatEtc->dwAspect == format->dwAspect)
-        {
-            pMedium->tymed = format->tymed;
-            pMedium->pUnkForRelease = 0;
-
-            if (format->tymed == TYMED_HGLOBAL)
-            {
-                const SIZE_T len = GlobalSize (medium->hGlobal);
-                void* const src = GlobalLock (medium->hGlobal);
-                void* const dst = GlobalAlloc (GMEM_FIXED, len);
-
-                memcpy (dst, src, len);
-
-                GlobalUnlock (medium->hGlobal);
-
-                pMedium->hGlobal = dst;
-                return S_OK;
-            }
-        }
-
-        return DV_E_FORMATETC;
-    }
-
-    HRESULT __stdcall QueryGetData (FORMATETC* f)
-    {
-        if (f == 0)
-            return E_INVALIDARG;
-
-        if (f->tymed == format->tymed
-              && f->cfFormat == format->cfFormat
-              && f->dwAspect == format->dwAspect)
-            return S_OK;
-
-        return DV_E_FORMATETC;
-    }
-
-    HRESULT __stdcall GetCanonicalFormatEtc (FORMATETC*, FORMATETC* pFormatEtcOut)
-    {
-        pFormatEtcOut->ptd = 0;
-        return E_NOTIMPL;
-    }
-
-    HRESULT __stdcall EnumFormatEtc (DWORD direction, IEnumFORMATETC** result)
-    {
-        if (result == 0)
-            return E_POINTER;
-
-        if (direction == DATADIR_GET)
-        {
-            *result = new JuceEnumFormatEtc (format);
-            return S_OK;
-        }
-
-        *result = 0;
-        return E_NOTIMPL;
-    }
-
-    HRESULT __stdcall GetDataHere (FORMATETC*, STGMEDIUM*)                  { return DATA_E_FORMATETC; }
-    HRESULT __stdcall SetData (FORMATETC*, STGMEDIUM*, BOOL)                { return E_NOTIMPL; }
-    HRESULT __stdcall DAdvise (FORMATETC*, DWORD, IAdviseSink*, DWORD*)     { return OLE_E_ADVISENOTSUPPORTED; }
-    HRESULT __stdcall DUnadvise (DWORD)                                     { return E_NOTIMPL; }
-    HRESULT __stdcall EnumDAdvise (IEnumSTATDATA**)                         { return OLE_E_ADVISENOTSUPPORTED; }
-
-private:
-    JuceDropSource* const dropSource;
-    const FORMATETC* const format;
-    const STGMEDIUM* const medium;
-
-    JUCE_DECLARE_NON_COPYABLE (JuceDataObject);
-};
-
-static HDROP createHDrop (const StringArray& fileNames)
-{
-    int totalChars = 0;
-    for (int i = fileNames.size(); --i >= 0;)
-        totalChars += fileNames[i].length() + 1;
-
-    HDROP hDrop = (HDROP) GlobalAlloc (GMEM_MOVEABLE | GMEM_ZEROINIT,
-                                       sizeof (DROPFILES) + sizeof (WCHAR) * (totalChars + 2));
-
-    if (hDrop != 0)
-    {
-        LPDROPFILES pDropFiles = (LPDROPFILES) GlobalLock (hDrop);
-        pDropFiles->pFiles = sizeof (DROPFILES);
-        pDropFiles->fWide = true;
-
-        WCHAR* fname = reinterpret_cast<WCHAR*> (addBytesToPointer (pDropFiles, sizeof (DROPFILES)));
-
-        for (int i = 0; i < fileNames.size(); ++i)
-        {
-            fileNames[i].copyToUnicode (fname, 2048);
-            fname += fileNames[i].length() + 1;
-        }
-
-        *fname = 0;
-
-        GlobalUnlock (hDrop);
-    }
-
-    return hDrop;
-}
-
-static bool performDragDrop (FORMATETC* const format, STGMEDIUM* const medium, const DWORD whatToDo)
-{
-    JuceDropSource* const source = new JuceDropSource();
-    JuceDataObject* const data = new JuceDataObject (source, format, medium);
-
-    DWORD effect;
-    const HRESULT res = DoDragDrop (data, source, whatToDo, &effect);
-
-    data->Release();
-    source->Release();
-
-    return res == DRAGDROP_S_DROP;
-}
-
-bool DragAndDropContainer::performExternalDragDropOfFiles (const StringArray& files, const bool canMove)
-{
-    FORMATETC format = { CF_HDROP, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
-    STGMEDIUM medium = { TYMED_HGLOBAL, { 0 }, 0 };
-
-    medium.hGlobal = createHDrop (files);
-
-    return performDragDrop (&format, &medium, canMove ? (DROPEFFECT_COPY | DROPEFFECT_MOVE)
-                                                      : DROPEFFECT_COPY);
-}
-
-bool DragAndDropContainer::performExternalDragDropOfText (const String& text)
-{
-    FORMATETC format = { CF_TEXT, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
-    STGMEDIUM medium = { TYMED_HGLOBAL, { 0 }, 0 };
-
-    const int numChars = text.length();
-
-    medium.hGlobal = GlobalAlloc (GMEM_MOVEABLE | GMEM_ZEROINIT, (numChars + 2) * sizeof (WCHAR));
-    WCHAR* const data = static_cast <WCHAR*> (GlobalLock (medium.hGlobal));
-
-    text.copyToUnicode (data, numChars + 1);
-    format.cfFormat = CF_UNICODETEXT;
-
-    GlobalUnlock (medium.hGlobal);
-
-    return performDragDrop (&format, &medium, DROPEFFECT_COPY | DROPEFFECT_MOVE);
-}
-
-
-#endif
+/*
+  ==============================================================================
+
+   This file is part of the JUCE library - "Jules' Utility Class Extensions"
+   Copyright 2004-10 by Raw Material Software Ltd.
+
+  ------------------------------------------------------------------------------
+
+   JUCE can be redistributed and/or modified under the terms of the GNU General
+   Public License (Version 2), as published by the Free Software Foundation.
+   A copy of the license is included in the JUCE distribution, or can be found
+   online at www.gnu.org/licenses.
+
+   JUCE 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.
+
+  ------------------------------------------------------------------------------
+
+   To release a closed-source product which uses JUCE, commercial licenses are
+   available: visit www.rawmaterialsoftware.com/juce for more information.
+
+  ==============================================================================
+*/
+
+// (This file gets included by juce_win32_NativeCode.cpp, rather than being
+// compiled on its own).
+#if JUCE_INCLUDED_FILE
+
+
+//==============================================================================
+#undef GetSystemMetrics // multimon overrides this for some reason and causes a mess..
+
+// these are in the windows SDK, but need to be repeated here for GCC..
+#ifndef GET_APPCOMMAND_LPARAM
+  #define FAPPCOMMAND_MASK                  0xF000
+  #define GET_APPCOMMAND_LPARAM(lParam)     ((short) (HIWORD (lParam) & ~FAPPCOMMAND_MASK))
+  #define APPCOMMAND_MEDIA_NEXTTRACK        11
+  #define APPCOMMAND_MEDIA_PREVIOUSTRACK    12
+  #define APPCOMMAND_MEDIA_STOP             13
+  #define APPCOMMAND_MEDIA_PLAY_PAUSE       14
+  #define WM_APPCOMMAND                     0x0319
+#endif
+
+extern void juce_repeatLastProcessPriority(); // in juce_win32_Threads.cpp
+extern void juce_CheckCurrentlyFocusedTopLevelWindow();  // in juce_TopLevelWindow.cpp
+extern bool juce_IsRunningInWine();
+
+#ifndef ULW_ALPHA
+  #define ULW_ALPHA     0x00000002
+#endif
+
+#ifndef AC_SRC_ALPHA
+  #define AC_SRC_ALPHA  0x01
+#endif
+
+static HPALETTE palette = 0;
+static bool createPaletteIfNeeded = true;
+static bool shouldDeactivateTitleBar = true;
+
+#define WM_TRAYNOTIFY WM_USER + 100
+
+using ::abs;
+
+//==============================================================================
+typedef BOOL (WINAPI* UpdateLayeredWinFunc) (HWND, HDC, POINT*, SIZE*, HDC, POINT*, COLORREF, BLENDFUNCTION*, DWORD);
+static UpdateLayeredWinFunc updateLayeredWindow = 0;
+
+bool Desktop::canUseSemiTransparentWindows() throw()
+{
+    if (updateLayeredWindow == 0)
+    {
+        if (! juce_IsRunningInWine())
+        {
+            HMODULE user32Mod = GetModuleHandle (_T("user32.dll"));
+            updateLayeredWindow = (UpdateLayeredWinFunc) GetProcAddress (user32Mod, "UpdateLayeredWindow");
+        }
+    }
+
+    return updateLayeredWindow != 0;
+}
+
+Desktop::DisplayOrientation Desktop::getCurrentOrientation() const
+{
+    return upright;
+}
+
+//==============================================================================
+const int extendedKeyModifier               = 0x10000;
+
+const int KeyPress::spaceKey                = VK_SPACE;
+const int KeyPress::returnKey               = VK_RETURN;
+const int KeyPress::escapeKey               = VK_ESCAPE;
+const int KeyPress::backspaceKey            = VK_BACK;
+const int KeyPress::deleteKey               = VK_DELETE         | extendedKeyModifier;
+const int KeyPress::insertKey               = VK_INSERT         | extendedKeyModifier;
+const int KeyPress::tabKey                  = VK_TAB;
+const int KeyPress::leftKey                 = VK_LEFT           | extendedKeyModifier;
+const int KeyPress::rightKey                = VK_RIGHT          | extendedKeyModifier;
+const int KeyPress::upKey                   = VK_UP             | extendedKeyModifier;
+const int KeyPress::downKey                 = VK_DOWN           | extendedKeyModifier;
+const int KeyPress::homeKey                 = VK_HOME           | extendedKeyModifier;
+const int KeyPress::endKey                  = VK_END            | extendedKeyModifier;
+const int KeyPress::pageUpKey               = VK_PRIOR          | extendedKeyModifier;
+const int KeyPress::pageDownKey             = VK_NEXT           | extendedKeyModifier;
+const int KeyPress::F1Key                   = VK_F1             | extendedKeyModifier;
+const int KeyPress::F2Key                   = VK_F2             | extendedKeyModifier;
+const int KeyPress::F3Key                   = VK_F3             | extendedKeyModifier;
+const int KeyPress::F4Key                   = VK_F4             | extendedKeyModifier;
+const int KeyPress::F5Key                   = VK_F5             | extendedKeyModifier;
+const int KeyPress::F6Key                   = VK_F6             | extendedKeyModifier;
+const int KeyPress::F7Key                   = VK_F7             | extendedKeyModifier;
+const int KeyPress::F8Key                   = VK_F8             | extendedKeyModifier;
+const int KeyPress::F9Key                   = VK_F9             | extendedKeyModifier;
+const int KeyPress::F10Key                  = VK_F10            | extendedKeyModifier;
+const int KeyPress::F11Key                  = VK_F11            | extendedKeyModifier;
+const int KeyPress::F12Key                  = VK_F12            | extendedKeyModifier;
+const int KeyPress::F13Key                  = VK_F13            | extendedKeyModifier;
+const int KeyPress::F14Key                  = VK_F14            | extendedKeyModifier;
+const int KeyPress::F15Key                  = VK_F15            | extendedKeyModifier;
+const int KeyPress::F16Key                  = VK_F16            | extendedKeyModifier;
+const int KeyPress::numberPad0              = VK_NUMPAD0        | extendedKeyModifier;
+const int KeyPress::numberPad1              = VK_NUMPAD1        | extendedKeyModifier;
+const int KeyPress::numberPad2              = VK_NUMPAD2        | extendedKeyModifier;
+const int KeyPress::numberPad3              = VK_NUMPAD3        | extendedKeyModifier;
+const int KeyPress::numberPad4              = VK_NUMPAD4        | extendedKeyModifier;
+const int KeyPress::numberPad5              = VK_NUMPAD5        | extendedKeyModifier;
+const int KeyPress::numberPad6              = VK_NUMPAD6        | extendedKeyModifier;
+const int KeyPress::numberPad7              = VK_NUMPAD7        | extendedKeyModifier;
+const int KeyPress::numberPad8              = VK_NUMPAD8        | extendedKeyModifier;
+const int KeyPress::numberPad9              = VK_NUMPAD9        | extendedKeyModifier;
+const int KeyPress::numberPadAdd            = VK_ADD            | extendedKeyModifier;
+const int KeyPress::numberPadSubtract       = VK_SUBTRACT       | extendedKeyModifier;
+const int KeyPress::numberPadMultiply       = VK_MULTIPLY       | extendedKeyModifier;
+const int KeyPress::numberPadDivide         = VK_DIVIDE         | extendedKeyModifier;
+const int KeyPress::numberPadSeparator      = VK_SEPARATOR      | extendedKeyModifier;
+const int KeyPress::numberPadDecimalPoint   = VK_DECIMAL        | extendedKeyModifier;
+const int KeyPress::numberPadEquals         = 0x92 /*VK_OEM_NEC_EQUAL*/  | extendedKeyModifier;
+const int KeyPress::numberPadDelete         = VK_DELETE         | extendedKeyModifier;
+const int KeyPress::playKey                 = 0x30000;
+const int KeyPress::stopKey                 = 0x30001;
+const int KeyPress::fastForwardKey          = 0x30002;
+const int KeyPress::rewindKey               = 0x30003;
+
+
+//==============================================================================
+class WindowsBitmapImage  : public Image::SharedImage
+{
+public:
+    //==============================================================================
+    HBITMAP hBitmap;
+    BITMAPV4HEADER bitmapInfo;
+    HDC hdc;
+    unsigned char* bitmapData;
+
+    //==============================================================================
+    WindowsBitmapImage (const Image::PixelFormat format_,
+                        const int w, const int h, const bool clearImage)
+        : Image::SharedImage (format_, w, h)
+    {
+        jassert (format_ == Image::RGB || format_ == Image::ARGB);
+
+        pixelStride = (format_ == Image::RGB) ? 3 : 4;
+
+        zerostruct (bitmapInfo);
+        bitmapInfo.bV4Size = sizeof (BITMAPV4HEADER);
+        bitmapInfo.bV4Width = w;
+        bitmapInfo.bV4Height = h;
+        bitmapInfo.bV4Planes = 1;
+        bitmapInfo.bV4CSType = 1;
+        bitmapInfo.bV4BitCount = (unsigned short) (pixelStride * 8);
+
+        if (format_ == Image::ARGB)
+        {
+            bitmapInfo.bV4AlphaMask        = 0xff000000;
+            bitmapInfo.bV4RedMask          = 0xff0000;
+            bitmapInfo.bV4GreenMask        = 0xff00;
+            bitmapInfo.bV4BlueMask         = 0xff;
+            bitmapInfo.bV4V4Compression    = BI_BITFIELDS;
+        }
+        else
+        {
+            bitmapInfo.bV4V4Compression    = BI_RGB;
+        }
+
+        lineStride = -((w * pixelStride + 3) & ~3);
+
+        HDC dc = GetDC (0);
+        hdc = CreateCompatibleDC (dc);
+        ReleaseDC (0, dc);
+
+        SetMapMode (hdc, MM_TEXT);
+
+        hBitmap = CreateDIBSection (hdc,
+                                    (BITMAPINFO*) &(bitmapInfo),
+                                    DIB_RGB_COLORS,
+                                    (void**) &bitmapData,
+                                    0, 0);
+
+        SelectObject (hdc, hBitmap);
+
+        if (format_ == Image::ARGB && clearImage)
+            zeromem (bitmapData, abs (h * lineStride));
+
+        imageData = bitmapData - (lineStride * (h - 1));
+    }
+
+    ~WindowsBitmapImage()
+    {
+        DeleteDC (hdc);
+        DeleteObject (hBitmap);
+    }
+
+    Image::ImageType getType() const    { return Image::NativeImage; }
+
+    LowLevelGraphicsContext* createLowLevelContext()
+    {
+        return new LowLevelGraphicsSoftwareRenderer (Image (this));
+    }
+
+    Image::SharedImage* clone()
+    {
+        WindowsBitmapImage* im = new WindowsBitmapImage (format, width, height, false);
+
+        for (int i = 0; i < height; ++i)
+            memcpy (im->imageData + i * lineStride, imageData + i * lineStride, lineStride);
+
+        return im;
+    }
+
+    void blitToWindow (HWND hwnd, HDC dc, const bool transparent,
+                       const int x, const int y,
+                       const RectangleList& maskedRegion,
+                       const uint8 updateLayeredWindowAlpha) throw()
+    {
+        static HDRAWDIB hdd = 0;
+        static bool needToCreateDrawDib = true;
+
+        if (needToCreateDrawDib)
+        {
+            needToCreateDrawDib = false;
+
+            HDC dc = GetDC (0);
+            const int n = GetDeviceCaps (dc, BITSPIXEL);
+            ReleaseDC (0, dc);
+
+            // only open if we're not palettised
+            if (n > 8)
+                hdd = DrawDibOpen();
+        }
+
+        if (createPaletteIfNeeded)
+        {
+            HDC dc = GetDC (0);
+            const int n = GetDeviceCaps (dc, BITSPIXEL);
+            ReleaseDC (0, dc);
+
+            if (n <= 8)
+                palette = CreateHalftonePalette (dc);
+
+            createPaletteIfNeeded = false;
+        }
+
+        if (palette != 0)
+        {
+            SelectPalette (dc, palette, FALSE);
+            RealizePalette (dc);
+            SetStretchBltMode (dc, HALFTONE);
+        }
+
+        SetMapMode (dc, MM_TEXT);
+
+        if (transparent)
+        {
+            POINT p, pos;
+            SIZE size;
+
+            RECT windowBounds;
+            GetWindowRect (hwnd, &windowBounds);
+
+            p.x = -x;
+            p.y = -y;
+            pos.x = windowBounds.left;
+            pos.y = windowBounds.top;
+            size.cx = windowBounds.right - windowBounds.left;
+            size.cy = windowBounds.bottom - windowBounds.top;
+
+            BLENDFUNCTION bf;
+            bf.AlphaFormat = AC_SRC_ALPHA;
+            bf.BlendFlags = 0;
+            bf.BlendOp = AC_SRC_OVER;
+            bf.SourceConstantAlpha = updateLayeredWindowAlpha;
+
+            if (! maskedRegion.isEmpty())
+            {
+                for (RectangleList::Iterator i (maskedRegion); i.next();)
+                {
+                    const Rectangle<int>& r = *i.getRectangle();
+                    ExcludeClipRect (hdc, r.getX(), r.getY(), r.getRight(), r.getBottom());
+                }
+            }
+
+            updateLayeredWindow (hwnd, 0, &pos, &size, hdc, &p, 0, &bf, ULW_ALPHA);
+        }
+        else
+        {
+            int savedDC = 0;
+
+            if (! maskedRegion.isEmpty())
+            {
+                savedDC = SaveDC (dc);
+
+                for (RectangleList::Iterator i (maskedRegion); i.next();)
+                {
+                    const Rectangle<int>& r = *i.getRectangle();
+                    ExcludeClipRect (dc, r.getX(), r.getY(), r.getRight(), r.getBottom());
+                }
+            }
+
+            if (hdd == 0)
+            {
+                StretchDIBits (dc,
+                               x, y, width, height,
+                               0, 0, width, height,
+                               bitmapData, (const BITMAPINFO*) &bitmapInfo,
+                               DIB_RGB_COLORS, SRCCOPY);
+            }
+            else
+            {
+                DrawDibDraw (hdd, dc, x, y, -1, -1,
+                             (BITMAPINFOHEADER*) &bitmapInfo, bitmapData,
+                             0, 0, width, height, 0);
+            }
+
+            if (! maskedRegion.isEmpty())
+                RestoreDC (dc, savedDC);
+        }
+    }
+
+private:
+    JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (WindowsBitmapImage);
+};
+
+namespace IconConverters
+{
+    const Image createImageFromHBITMAP (HBITMAP bitmap)
+    {
+        Image im;
+
+        if (bitmap != 0)
+        {
+            BITMAP bm;
+
+            if (GetObject (bitmap, sizeof (BITMAP), &bm)
+                 && bm.bmWidth > 0 && bm.bmHeight > 0)
+            {
+                HDC tempDC = GetDC (0);
+                HDC dc = CreateCompatibleDC (tempDC);
+                ReleaseDC (0, tempDC);
+
+                SelectObject (dc, bitmap);
+
+                im = Image (Image::ARGB, bm.bmWidth, bm.bmHeight, true);
+                Image::BitmapData imageData (im, true);
+
+                for (int y = bm.bmHeight; --y >= 0;)
+                {
+                    for (int x = bm.bmWidth; --x >= 0;)
+                    {
+                        COLORREF col = GetPixel (dc, x, y);
+
+                        imageData.setPixelColour (x, y, Colour ((uint8) GetRValue (col),
+                                                                (uint8) GetGValue (col),
+                                                                (uint8) GetBValue (col)));
+                    }
+                }
+
+                DeleteDC (dc);
+            }
+        }
+
+        return im;
+    }
+
+    const Image createImageFromHICON (HICON icon)
+    {
+        ICONINFO info;
+
+        if (GetIconInfo (icon, &info))
+        {
+            Image mask (createImageFromHBITMAP (info.hbmMask));
+            Image image (createImageFromHBITMAP (info.hbmColor));
+
+            if (mask.isValid() && image.isValid())
+            {
+                for (int y = image.getHeight(); --y >= 0;)
+                {
+                    for (int x = image.getWidth(); --x >= 0;)
+                    {
+                        const float brightness = mask.getPixelAt (x, y).getBrightness();
+
+                        if (brightness > 0.0f)
+                            image.multiplyAlphaAt (x, y, 1.0f - brightness);
+                    }
+                }
+
+                return image;
+            }
+        }
+
+        return Image::null;
+    }
+
+    HICON createHICONFromImage (const Image& image, const BOOL isIcon, int hotspotX, int hotspotY)
+    {
+        WindowsBitmapImage* nativeBitmap = new WindowsBitmapImage (Image::ARGB, image.getWidth(), image.getHeight(), true);
+        Image bitmap (nativeBitmap);
+
+        {
+            Graphics g (bitmap);
+            g.drawImageAt (image, 0, 0);
+        }
+
+        HBITMAP mask = CreateBitmap (image.getWidth(), image.getHeight(), 1, 1, 0);
+
+        ICONINFO info;
+        info.fIcon = isIcon;
+        info.xHotspot = hotspotX;
+        info.yHotspot = hotspotY;
+        info.hbmMask = mask;
+        info.hbmColor = nativeBitmap->hBitmap;
+
+        HICON hi = CreateIconIndirect (&info);
+        DeleteObject (mask);
+        return hi;
+    }
+}
+
+//==============================================================================
+long improbableWindowNumber = 0xf965aa01; // also referenced by messaging.cpp
+
+
+//==============================================================================
+bool KeyPress::isKeyCurrentlyDown (const int keyCode)
+{
+    SHORT k = (SHORT) keyCode;
+
+    if ((keyCode & extendedKeyModifier) == 0
+         && (k >= (SHORT) 'a' && k <= (SHORT) 'z'))
+        k += (SHORT) 'A' - (SHORT) 'a';
+
+    const SHORT translatedValues[] = { (SHORT) ',', VK_OEM_COMMA,
+                                       (SHORT) '+', VK_OEM_PLUS,
+                                       (SHORT) '-', VK_OEM_MINUS,
+                                       (SHORT) '.', VK_OEM_PERIOD,
+                                       (SHORT) ';', VK_OEM_1,
+                                       (SHORT) ':', VK_OEM_1,
+                                       (SHORT) '/', VK_OEM_2,
+                                       (SHORT) '?', VK_OEM_2,
+                                       (SHORT) '[', VK_OEM_4,
+                                       (SHORT) ']', VK_OEM_6 };
+
+    for (int i = 0; i < numElementsInArray (translatedValues); i += 2)
+        if (k == translatedValues [i])
+            k = translatedValues [i + 1];
+
+    return (GetKeyState (k) & 0x8000) != 0;
+}
+
+//==============================================================================
+class Win32ComponentPeer  : public ComponentPeer
+{
+public:
+    enum RenderingEngineType
+    {
+        softwareRenderingEngine = 0,
+        direct2DRenderingEngine
+    };
+
+    //==============================================================================
+    Win32ComponentPeer (Component* const component,
+                        const int windowStyleFlags,
+                        HWND parentToAddTo_)
+        : ComponentPeer (component, windowStyleFlags),
+          dontRepaint (false),
+      #if JUCE_DIRECT2D
+          currentRenderingEngine (direct2DRenderingEngine),
+      #else
+          currentRenderingEngine (softwareRenderingEngine),
+      #endif
+          fullScreen (false),
+          isDragging (false),
+          isMouseOver (false),
+          hasCreatedCaret (false),
+          currentWindowIcon (0),
+          dropTarget (0),
+          updateLayeredWindowAlpha (255),
+          parentToAddTo (parentToAddTo_)
+    {
+        callFunctionIfNotLocked (&createWindowCallback, this);
+
+        setTitle (component->getName());
+
+        if ((windowStyleFlags & windowHasDropShadow) != 0
+             && Desktop::canUseSemiTransparentWindows())
+        {
+            shadower = component->getLookAndFeel().createDropShadowerForComponent (component);
+
+            if (shadower != 0)
+                shadower->setOwner (component);
+        }
+    }
+
+    ~Win32ComponentPeer()
+    {
+        setTaskBarIcon (Image());
+        shadower = 0;
+
+        // do this before the next bit to avoid messages arriving for this window
+        // before it's destroyed
+        SetWindowLongPtr (hwnd, GWLP_USERDATA, 0);
+
+        callFunctionIfNotLocked (&destroyWindowCallback, (void*) hwnd);
+
+        if (currentWindowIcon != 0)
+            DestroyIcon (currentWindowIcon);
+
+        if (dropTarget != 0)
+        {
+            dropTarget->Release();
+            dropTarget = 0;
+        }
+
+      #if JUCE_DIRECT2D
+        direct2DContext = 0;
+      #endif
+    }
+
+    //==============================================================================
+    void* getNativeHandle() const
+    {
+        return hwnd;
+    }
+
+    void setVisible (bool shouldBeVisible)
+    {
+        ShowWindow (hwnd, shouldBeVisible ? SW_SHOWNA : SW_HIDE);
+
+        if (shouldBeVisible)
+            InvalidateRect (hwnd, 0, 0);
+        else
+            lastPaintTime = 0;
+    }
+
+    void setTitle (const String& title)
+    {
+        SetWindowText (hwnd, title);
+    }
+
+    void setPosition (int x, int y)
+    {
+        offsetWithinParent (x, y);
+        SetWindowPos (hwnd, 0,
+                      x - windowBorder.getLeft(),
+                      y - windowBorder.getTop(),
+                      0, 0,
+                      SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOZORDER | SWP_NOOWNERZORDER);
+    }
+
+    void repaintNowIfTransparent()
+    {
+        if (isUsingUpdateLayeredWindow() && lastPaintTime > 0 && Time::getMillisecondCounter() > lastPaintTime + 30)
+            handlePaintMessage();
+    }
+
+    void updateBorderSize()
+    {
+        WINDOWINFO info;
+        info.cbSize = sizeof (info);
+
+        if (GetWindowInfo (hwnd, &info))
+        {
+            windowBorder = BorderSize (info.rcClient.top - info.rcWindow.top,
+                                       info.rcClient.left - info.rcWindow.left,
+                                       info.rcWindow.bottom - info.rcClient.bottom,
+                                       info.rcWindow.right - info.rcClient.right);
+        }
+
+      #if JUCE_DIRECT2D
+        if (direct2DContext != 0)
+            direct2DContext->resized();
+      #endif
+    }
+
+    void setSize (int w, int h)
+    {
+        SetWindowPos (hwnd, 0, 0, 0,
+                      w + windowBorder.getLeftAndRight(),
+                      h + windowBorder.getTopAndBottom(),
+                      SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOZORDER | SWP_NOOWNERZORDER);
+
+        updateBorderSize();
+
+        repaintNowIfTransparent();
+    }
+
+    void setBounds (int x, int y, int w, int h, bool isNowFullScreen)
+    {
+        fullScreen = isNowFullScreen;
+        offsetWithinParent (x, y);
+
+        SetWindowPos (hwnd, 0,
+                      x - windowBorder.getLeft(),
+                      y - windowBorder.getTop(),
+                      w + windowBorder.getLeftAndRight(),
+                      h + windowBorder.getTopAndBottom(),
+                      SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOOWNERZORDER);
+
+        updateBorderSize();
+
+        repaintNowIfTransparent();
+    }
+
+    const Rectangle<int> getBounds() const
+    {
+        RECT r;
+        GetWindowRect (hwnd, &r);
+
+        Rectangle<int> bounds (r.left, r.top, r.right - r.left, r.bottom - r.top);
+
+        HWND parentH = GetParent (hwnd);
+        if (parentH != 0)
+        {
+            GetWindowRect (parentH, &r);
+            bounds.translate (-r.left, -r.top);
+        }
+
+        return windowBorder.subtractedFrom (bounds);
+    }
+
+    const Point<int> getScreenPosition() const
+    {
+        RECT r;
+        GetWindowRect (hwnd, &r);
+        return Point<int> (r.left + windowBorder.getLeft(),
+                           r.top + windowBorder.getTop());
+    }
+
+    const Point<int> localToGlobal (const Point<int>& relativePosition)
+    {
+        return relativePosition + getScreenPosition();
+    }
+
+    const Point<int> globalToLocal (const Point<int>& screenPosition)
+    {
+        return screenPosition - getScreenPosition();
+    }
+
+    void setAlpha (float newAlpha)
+    {
+        const uint8 intAlpha = (uint8) jlimit (0, 255, (int) (newAlpha * 255.0f));
+
+        if (component->isOpaque())
+        {
+            if (newAlpha < 1.0f)
+            {
+                SetWindowLong (hwnd, GWL_EXSTYLE, GetWindowLong (hwnd, GWL_EXSTYLE) | WS_EX_LAYERED);
+                SetLayeredWindowAttributes (hwnd, RGB (0, 0, 0), intAlpha, LWA_ALPHA);
+            }
+            else
+            {
+                SetWindowLong (hwnd, GWL_EXSTYLE, GetWindowLong (hwnd, GWL_EXSTYLE) & ~WS_EX_LAYERED);
+                RedrawWindow (hwnd, 0, 0, RDW_ERASE | RDW_INVALIDATE | RDW_FRAME | RDW_ALLCHILDREN);
+            }
+        }
+        else
+        {
+            updateLayeredWindowAlpha = intAlpha;
+            component->repaint();
+        }
+    }
+
+    void setMinimised (bool shouldBeMinimised)
+    {
+        if (shouldBeMinimised != isMinimised())
+            ShowWindow (hwnd, shouldBeMinimised ? SW_MINIMIZE : SW_SHOWNORMAL);
+    }
+
+    bool isMinimised() const
+    {
+        WINDOWPLACEMENT wp;
+        wp.length = sizeof (WINDOWPLACEMENT);
+        GetWindowPlacement (hwnd, &wp);
+
+        return wp.showCmd == SW_SHOWMINIMIZED;
+    }
+
+    void setFullScreen (bool shouldBeFullScreen)
+    {
+        setMinimised (false);
+
+        if (fullScreen != shouldBeFullScreen)
+        {
+            fullScreen = shouldBeFullScreen;
+            const WeakReference<Component> deletionChecker (component);
+
+            if (! fullScreen)
+            {
+                const Rectangle<int> boundsCopy (lastNonFullscreenBounds);
+
+                if (hasTitleBar())
+                    ShowWindow (hwnd, SW_SHOWNORMAL);
+
+                if (! boundsCopy.isEmpty())
+                {
+                    setBounds (boundsCopy.getX(),
+                               boundsCopy.getY(),
+                               boundsCopy.getWidth(),
+                               boundsCopy.getHeight(),
+                               false);
+                }
+            }
+            else
+            {
+                if (hasTitleBar())
+                    ShowWindow (hwnd, SW_SHOWMAXIMIZED);
+                else
+                    SendMessageW (hwnd, WM_SETTINGCHANGE, 0, 0);
+            }
+
+            if (deletionChecker != 0)
+                handleMovedOrResized();
+        }
+    }
+
+    bool isFullScreen() const
+    {
+        if (! hasTitleBar())
+            return fullScreen;
+
+        WINDOWPLACEMENT wp;
+        wp.length = sizeof (wp);
+        GetWindowPlacement (hwnd, &wp);
+
+        return wp.showCmd == SW_SHOWMAXIMIZED;
+    }
+
+    bool contains (const Point<int>& position, bool trueIfInAChildWindow) const
+    {
+        if (! (isPositiveAndBelow (position.getX(), component->getWidth())
+                && isPositiveAndBelow (position.getY(), component->getHeight())))
+            return false;
+
+        RECT r;
+        GetWindowRect (hwnd, &r);
+
+        POINT p;
+        p.x = position.getX() + r.left + windowBorder.getLeft();
+        p.y = position.getY() + r.top + windowBorder.getTop();
+
+        HWND w = WindowFromPoint (p);
+        return w == hwnd || (trueIfInAChildWindow && (IsChild (hwnd, w) != 0));
+    }
+
+    const BorderSize getFrameSize() const
+    {
+        return windowBorder;
+    }
+
+    bool setAlwaysOnTop (bool alwaysOnTop)
+    {
+        const bool oldDeactivate = shouldDeactivateTitleBar;
+        shouldDeactivateTitleBar = ((styleFlags & windowIsTemporary) == 0);
+
+        SetWindowPos (hwnd, alwaysOnTop ? HWND_TOPMOST : HWND_NOTOPMOST,
+                      0, 0, 0, 0,
+                      SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOSENDCHANGING);
+
+        shouldDeactivateTitleBar = oldDeactivate;
+
+        if (shadower != 0)
+            shadower->componentBroughtToFront (*component);
+
+        return true;
+    }
+
+    void toFront (bool makeActive)
+    {
+        setMinimised (false);
+
+        const bool oldDeactivate = shouldDeactivateTitleBar;
+        shouldDeactivateTitleBar = ((styleFlags & windowIsTemporary) == 0);
+
+        callFunctionIfNotLocked (makeActive ? &toFrontCallback1 : &toFrontCallback2, hwnd);
+
+        shouldDeactivateTitleBar = oldDeactivate;
+
+        if (! makeActive)
+        {
+            // in this case a broughttofront call won't have occured, so do it now..
+            handleBroughtToFront();
+        }
+    }
+
+    void toBehind (ComponentPeer* other)
+    {
+        Win32ComponentPeer* const otherPeer = dynamic_cast <Win32ComponentPeer*> (other);
+
+        jassert (otherPeer != 0); // wrong type of window?
+
+        if (otherPeer != 0)
+        {
+            setMinimised (false);
+
+            // must be careful not to try to put a topmost window behind a normal one, or win32
+            // promotes the normal one to be topmost!
+            if (getComponent()->isAlwaysOnTop() == otherPeer->getComponent()->isAlwaysOnTop())
+                SetWindowPos (hwnd, otherPeer->hwnd, 0, 0, 0, 0,
+                              SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOSENDCHANGING);
+            else if (otherPeer->getComponent()->isAlwaysOnTop())
+                SetWindowPos (hwnd, HWND_TOP, 0, 0, 0, 0,
+                              SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOSENDCHANGING);
+        }
+    }
+
+    bool isFocused() const
+    {
+        return callFunctionIfNotLocked (&getFocusCallback, 0) == (void*) hwnd;
+    }
+
+    void grabFocus()
+    {
+        const bool oldDeactivate = shouldDeactivateTitleBar;
+        shouldDeactivateTitleBar = ((styleFlags & windowIsTemporary) == 0);
+
+        callFunctionIfNotLocked (&setFocusCallback, hwnd);
+
+        shouldDeactivateTitleBar = oldDeactivate;
+    }
+
+    void textInputRequired (const Point<int>&)
+    {
+        if (! hasCreatedCaret)
+        {
+            hasCreatedCaret = true;
+            CreateCaret (hwnd, (HBITMAP) 1, 0, 0);
+        }
+
+        ShowCaret (hwnd);
+        SetCaretPos (0, 0);
+    }
+
+    void repaint (const Rectangle<int>& area)
+    {
+        const RECT r = { area.getX(), area.getY(), area.getRight(), area.getBottom() };
+        InvalidateRect (hwnd, &r, FALSE);
+    }
+
+    void performAnyPendingRepaintsNow()
+    {
+        MSG m;
+        if (component->isVisible() && PeekMessage (&m, hwnd, WM_PAINT, WM_PAINT, PM_REMOVE))
+            DispatchMessage (&m);
+    }
+
+    //==============================================================================
+    static Win32ComponentPeer* getOwnerOfWindow (HWND h) throw()
+    {
+        if (h != 0 && GetWindowLongPtr (h, GWLP_USERDATA) == improbableWindowNumber)
+            return (Win32ComponentPeer*) (pointer_sized_int) GetWindowLongPtr (h, 8);
+
+        return 0;
+    }
+
+    //==============================================================================
+    void setTaskBarIcon (const Image& image)
+    {
+        if (image.isValid())
+        {
+            HICON hicon = IconConverters::createHICONFromImage (image, TRUE, 0, 0);
+
+            if (taskBarIcon == 0)
+            {
+                taskBarIcon = new NOTIFYICONDATA();
+                zeromem (taskBarIcon, sizeof (NOTIFYICONDATA));
+                taskBarIcon->cbSize = sizeof (NOTIFYICONDATA);
+                taskBarIcon->hWnd = (HWND) hwnd;
+                taskBarIcon->uID = (int) (pointer_sized_int) hwnd;
+                taskBarIcon->uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP;
+                taskBarIcon->uCallbackMessage = WM_TRAYNOTIFY;
+                taskBarIcon->hIcon = hicon;
+                taskBarIcon->szTip[0] = 0;
+
+                Shell_NotifyIcon (NIM_ADD, taskBarIcon);
+            }
+            else
+            {
+                HICON oldIcon = taskBarIcon->hIcon;
+
+                taskBarIcon->hIcon = hicon;
+                taskBarIcon->uFlags = NIF_ICON;
+                Shell_NotifyIcon (NIM_MODIFY, taskBarIcon);
+
+                DestroyIcon (oldIcon);
+            }
+        }
+        else if (taskBarIcon != 0)
+        {
+            taskBarIcon->uFlags = 0;
+            Shell_NotifyIcon (NIM_DELETE, taskBarIcon);
+            DestroyIcon (taskBarIcon->hIcon);
+            taskBarIcon = 0;
+        }
+    }
+
+    void setTaskBarIconToolTip (const String& toolTip) const
+    {
+        if (taskBarIcon != 0)
+        {
+            taskBarIcon->uFlags = NIF_TIP;
+            toolTip.copyToUnicode (taskBarIcon->szTip, sizeof (taskBarIcon->szTip) - 1);
+            Shell_NotifyIcon (NIM_MODIFY, taskBarIcon);
+        }
+    }
+
+    void handleTaskBarEvent (const LPARAM lParam)
+    {
+        if (component->isCurrentlyBlockedByAnotherModalComponent())
+        {
+            if (lParam == WM_LBUTTONDOWN || lParam == WM_RBUTTONDOWN
+                 || lParam == WM_LBUTTONDBLCLK || lParam == WM_LBUTTONDBLCLK)
+            {
+                Component* const current = Component::getCurrentlyModalComponent();
+
+                if (current != 0)
+                    current->inputAttemptWhenModal();
+            }
+        }
+        else
+        {
+            ModifierKeys eventMods (ModifierKeys::getCurrentModifiersRealtime());
+
+            if (lParam == WM_LBUTTONDOWN || lParam == WM_LBUTTONDBLCLK)
+                eventMods = eventMods.withFlags (ModifierKeys::leftButtonModifier);
+            else if (lParam == WM_RBUTTONDOWN || lParam == WM_RBUTTONDBLCLK)
+                eventMods = eventMods.withFlags (ModifierKeys::rightButtonModifier);
+            else if (lParam == WM_LBUTTONUP || lParam == WM_RBUTTONUP)
+                eventMods = eventMods.withoutMouseButtons();
+
+            const MouseEvent e (Desktop::getInstance().getMainMouseSource(),
+                                Point<int>(), eventMods, component, component, Time (getMouseEventTime()),
+                                Point<int>(), Time (getMouseEventTime()), 1, false);
+
+            if (lParam == WM_LBUTTONDOWN || lParam == WM_RBUTTONDOWN)
+            {
+                SetFocus (hwnd);
+                SetForegroundWindow (hwnd);
+                component->mouseDown (e);
+            }
+            else if (lParam == WM_LBUTTONUP || lParam == WM_RBUTTONUP)
+            {
+                component->mouseUp (e);
+            }
+            else if (lParam == WM_LBUTTONDBLCLK || lParam == WM_LBUTTONDBLCLK)
+            {
+                component->mouseDoubleClick (e);
+            }
+            else if (lParam == WM_MOUSEMOVE)
+            {
+                component->mouseMove (e);
+            }
+        }
+    }
+
+    //==============================================================================
+    bool isInside (HWND h) const
+    {
+        return GetAncestor (hwnd, GA_ROOT) == h;
+    }
+
+    //==============================================================================
+    static void updateKeyModifiers() throw()
+    {
+        int keyMods = 0;
+        if (GetKeyState (VK_SHIFT) & 0x8000)    keyMods |= ModifierKeys::shiftModifier;
+        if (GetKeyState (VK_CONTROL) & 0x8000)  keyMods |= ModifierKeys::ctrlModifier;
+        if (GetKeyState (VK_MENU) & 0x8000)     keyMods |= ModifierKeys::altModifier;
+        if (GetKeyState (VK_RMENU) & 0x8000)    keyMods &= ~(ModifierKeys::ctrlModifier | ModifierKeys::altModifier);
+
+        currentModifiers = currentModifiers.withOnlyMouseButtons().withFlags (keyMods);
+    }
+
+    static void updateModifiersFromWParam (const WPARAM wParam)
+    {
+        int mouseMods = 0;
+        if (wParam & MK_LBUTTON)   mouseMods |= ModifierKeys::leftButtonModifier;
+        if (wParam & MK_RBUTTON)   mouseMods |= ModifierKeys::rightButtonModifier;
+        if (wParam & MK_MBUTTON)   mouseMods |= ModifierKeys::middleButtonModifier;
+
+        currentModifiers = currentModifiers.withoutMouseButtons().withFlags (mouseMods);
+        updateKeyModifiers();
+    }
+
+    static int64 getMouseEventTime()
+    {
+        static int64 eventTimeOffset = 0;
+        static DWORD lastMessageTime = 0;
+        const DWORD thisMessageTime = GetMessageTime();
+
+        if (thisMessageTime < lastMessageTime || lastMessageTime == 0)
+        {
+            lastMessageTime = thisMessageTime;
+            eventTimeOffset = Time::currentTimeMillis() - thisMessageTime;
+        }
+
+        return eventTimeOffset + thisMessageTime;
+    }
+
+    //==============================================================================
+    bool dontRepaint;
+
+    static ModifierKeys currentModifiers;
+    static ModifierKeys modifiersAtLastCallback;
+
+private:
+    HWND hwnd, parentToAddTo;
+    ScopedPointer<DropShadower> shadower;
+    RenderingEngineType currentRenderingEngine;
+  #if JUCE_DIRECT2D
+    ScopedPointer<Direct2DLowLevelGraphicsContext> direct2DContext;
+  #endif
+    bool fullScreen, isDragging, isMouseOver, hasCreatedCaret;
+    BorderSize windowBorder;
+    HICON currentWindowIcon;
+    ScopedPointer<NOTIFYICONDATA> taskBarIcon;
+    IDropTarget* dropTarget;
+    uint8 updateLayeredWindowAlpha;
+
+    //==============================================================================
+    class TemporaryImage    : public Timer
+    {
+    public:
+        //==============================================================================
+        TemporaryImage() {}
+        ~TemporaryImage() {}
+
+        //==============================================================================
+        const Image& getImage (const bool transparent, const int w, const int h)
+        {
+            const Image::PixelFormat format = transparent ? Image::ARGB : Image::RGB;
+
+            if ((! image.isValid()) || image.getWidth() < w || image.getHeight() < h || image.getFormat() != format)
+                image = Image (new WindowsBitmapImage (format, (w + 31) & ~31, (h + 31) & ~31, false));
+
+            startTimer (3000);
+            return image;
+        }
+
+        //==============================================================================
+        void timerCallback()
+        {
+            stopTimer();
+            image = Image::null;
+        }
+
+    private:
+        Image image;
+
+        JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (TemporaryImage);
+    };
+
+    TemporaryImage offscreenImageGenerator;
+
+    //==============================================================================
+    class WindowClassHolder    : public DeletedAtShutdown
+    {
+    public:
+        WindowClassHolder()
+            : windowClassName ("JUCE_")
+        {
+            // this name has to be different for each app/dll instance because otherwise
+            // poor old Win32 can get a bit confused (even despite it not being a process-global
+            // window class).
+            windowClassName << (int) (Time::currentTimeMillis() & 0x7fffffff);
+
+            HINSTANCE moduleHandle = (HINSTANCE) PlatformUtilities::getCurrentModuleInstanceHandle();
+
+            TCHAR moduleFile [1024];
+            moduleFile[0] = 0;
+            GetModuleFileName (moduleHandle, moduleFile, 1024);
+            WORD iconNum = 0;
+
+            WNDCLASSEX wcex;
+            wcex.cbSize         = sizeof (wcex);
+            wcex.style          = CS_OWNDC;
+            wcex.lpfnWndProc    = (WNDPROC) windowProc;
+            wcex.lpszClassName  = windowClassName;
+            wcex.cbClsExtra     = 0;
+            wcex.cbWndExtra     = 32;
+            wcex.hInstance      = moduleHandle;
+            wcex.hIcon          = ExtractAssociatedIcon (moduleHandle, moduleFile, &iconNum);
+            iconNum = 1;
+            wcex.hIconSm        = ExtractAssociatedIcon (moduleHandle, moduleFile, &iconNum);
+            wcex.hCursor        = 0;
+            wcex.hbrBackground  = 0;
+            wcex.lpszMenuName   = 0;
+
+            RegisterClassEx (&wcex);
+        }
+
+        ~WindowClassHolder()
+        {
+            if (ComponentPeer::getNumPeers() == 0)
+                UnregisterClass (windowClassName, (HINSTANCE) PlatformUtilities::getCurrentModuleInstanceHandle());
+
+            clearSingletonInstance();
+        }
+
+        String windowClassName;
+
+        juce_DeclareSingleton_SingleThreaded_Minimal (WindowClassHolder);
+    };
+
+    //==============================================================================
+    static void* createWindowCallback (void* userData)
+    {
+        static_cast <Win32ComponentPeer*> (userData)->createWindow();
+        return 0;
+    }
+
+    void createWindow()
+    {
+        DWORD exstyle = WS_EX_ACCEPTFILES;
+        DWORD type = WS_CLIPSIBLINGS | WS_CLIPCHILDREN;
+
+        if (hasTitleBar())
+        {
+            type |= WS_OVERLAPPED;
+
+            if ((styleFlags & windowHasCloseButton) != 0)
+            {
+                type |= WS_SYSMENU;
+            }
+            else
+            {
+                // annoyingly, windows won't let you have a min/max button without a close button
+                jassert ((styleFlags & (windowHasMinimiseButton | windowHasMaximiseButton)) == 0);
+            }
+
+            if ((styleFlags & windowIsResizable) != 0)
+                type |= WS_THICKFRAME;
+        }
+        else if (parentToAddTo != 0)
+        {
+            type |= WS_CHILD;
+        }
+        else
+        {
+            type |= WS_POPUP | WS_SYSMENU;
+        }
+
+        if ((styleFlags & windowAppearsOnTaskbar) == 0)
+            exstyle |= WS_EX_TOOLWINDOW;
+        else
+            exstyle |= WS_EX_APPWINDOW;
+
+        if ((styleFlags & windowHasMinimiseButton) != 0)
+            type |= WS_MINIMIZEBOX;
+
+        if ((styleFlags & windowHasMaximiseButton) != 0)
+            type |= WS_MAXIMIZEBOX;
+
+        if ((styleFlags & windowIgnoresMouseClicks) != 0)
+            exstyle |= WS_EX_TRANSPARENT;
+
+        if ((styleFlags & windowIsSemiTransparent) != 0
+              && Desktop::canUseSemiTransparentWindows())
+            exstyle |= WS_EX_LAYERED;
+
+        hwnd = CreateWindowEx (exstyle, WindowClassHolder::getInstance()->windowClassName, L"", type, 0, 0, 0, 0,
+                               parentToAddTo, 0, (HINSTANCE) PlatformUtilities::getCurrentModuleInstanceHandle(), 0);
+
+      #if JUCE_DIRECT2D
+        updateDirect2DContext();
+      #endif
+
+        if (hwnd != 0)
+        {
+            SetWindowLongPtr (hwnd, 0, 0);
+            SetWindowLongPtr (hwnd, 8, (LONG_PTR) this);
+            SetWindowLongPtr (hwnd, GWLP_USERDATA, improbableWindowNumber);
+
+            if (dropTarget == 0)
+                dropTarget = new JuceDropTarget (this);
+
+            RegisterDragDrop (hwnd, dropTarget);
+
+            updateBorderSize();
+
+            // Calling this function here is (for some reason) necessary to make Windows
+            // correctly enable the menu items that we specify in the wm_initmenu message.
+            GetSystemMenu (hwnd, false);
+
+            const float alpha = component->getAlpha();
+            if (alpha < 1.0f)
+                setAlpha (alpha);
+        }
+        else
+        {
+            jassertfalse;
+        }
+    }
+
+    static void* destroyWindowCallback (void* handle)
+    {
+        RevokeDragDrop ((HWND) handle);
+        DestroyWindow ((HWND) handle);
+        return 0;
+    }
+
+    static void* toFrontCallback1 (void* h)
+    {
+        SetForegroundWindow ((HWND) h);
+        return 0;
+    }
+
+    static void* toFrontCallback2 (void* h)
+    {
+        SetWindowPos ((HWND) h, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOSENDCHANGING);
+        return 0;
+    }
+
+    static void* setFocusCallback (void* h)
+    {
+        SetFocus ((HWND) h);
+        return 0;
+    }
+
+    static void* getFocusCallback (void*)
+    {
+        return GetFocus();
+    }
+
+    void offsetWithinParent (int& x, int& y) const
+    {
+        if (isUsingUpdateLayeredWindow())
+        {
+            HWND parentHwnd = GetParent (hwnd);
+
+            if (parentHwnd != 0)
+            {
+                RECT parentRect;
+                GetWindowRect (parentHwnd, &parentRect);
+                x += parentRect.left;
+                y += parentRect.top;
+            }
+        }
+    }
+
+    bool isUsingUpdateLayeredWindow() const
+    {
+        return ! component->isOpaque();
+    }
+
+    inline bool hasTitleBar() const throw()         { return (styleFlags & windowHasTitleBar) != 0; }
+
+
+    void setIcon (const Image& newIcon)
+    {
+        HICON hicon = IconConverters::createHICONFromImage (newIcon, TRUE, 0, 0);
+
+        if (hicon != 0)
+        {
+            SendMessage (hwnd, WM_SETICON, ICON_BIG, (LPARAM) hicon);
+            SendMessage (hwnd, WM_SETICON, ICON_SMALL, (LPARAM) hicon);
+
+            if (currentWindowIcon != 0)
+                DestroyIcon (currentWindowIcon);
+
+            currentWindowIcon = hicon;
+        }
+    }
+
+    //==============================================================================
+    void handlePaintMessage()
+    {
+#if JUCE_DIRECT2D
+        if (direct2DContext != 0)
+        {
+            RECT r;
+
+            if (GetUpdateRect (hwnd, &r, false))
+            {
+                direct2DContext->start();
+                direct2DContext->clipToRectangle (Rectangle<int> (r.left, r.top, r.right - r.left, r.bottom - r.top));
+                handlePaint (*direct2DContext);
+                direct2DContext->end();
+            }
+        }
+        else
+#endif
+        {
+            HRGN rgn = CreateRectRgn (0, 0, 0, 0);
+            const int regionType = GetUpdateRgn (hwnd, rgn, false);
+
+            PAINTSTRUCT paintStruct;
+            HDC dc = BeginPaint (hwnd, &paintStruct); // Note this can immediately generate a WM_NCPAINT
+                                                      // message and become re-entrant, but that's OK
+
+            // if something in a paint handler calls, e.g. a message box, this can become reentrant and
+            // corrupt the image it's using to paint into, so do a check here.
+            static bool reentrant = false;
+            if (reentrant)
+            {
+                DeleteObject (rgn);
+                EndPaint (hwnd, &paintStruct);
+                return;
+            }
+
+            reentrant = true;
+
+            // this is the rectangle to update..
+            int x = paintStruct.rcPaint.left;
+            int y = paintStruct.rcPaint.top;
+            int w = paintStruct.rcPaint.right - x;
+            int h = paintStruct.rcPaint.bottom - y;
+
+            const bool transparent = isUsingUpdateLayeredWindow();
+
+            if (transparent)
+            {
+                // it's not possible to have a transparent window with a title bar at the moment!
+                jassert (! hasTitleBar());
+
+                RECT r;
+                GetWindowRect (hwnd, &r);
+                x = y = 0;
+                w = r.right - r.left;
+                h = r.bottom - r.top;
+            }
+
+            if (w > 0 && h > 0)
+            {
+                clearMaskedRegion();
+
+                Image offscreenImage (offscreenImageGenerator.getImage (transparent, w, h));
+
+                RectangleList contextClip;
+                const Rectangle<int> clipBounds (0, 0, w, h);
+
+                bool needToPaintAll = true;
+
+                if (regionType == COMPLEXREGION && ! transparent)
+                {
+                    HRGN clipRgn = CreateRectRgnIndirect (&paintStruct.rcPaint);
+                    CombineRgn (rgn, rgn, clipRgn, RGN_AND);
+                    DeleteObject (clipRgn);
+
+                    char rgnData [8192];
+                    const DWORD res = GetRegionData (rgn, sizeof (rgnData), (RGNDATA*) rgnData);
+
+                    if (res > 0 && res <= sizeof (rgnData))
+                    {
+                        const RGNDATAHEADER* const hdr = &(((const RGNDATA*) rgnData)->rdh);
+
+                        if (hdr->iType == RDH_RECTANGLES
+                             && hdr->rcBound.right - hdr->rcBound.left >= w
+                             && hdr->rcBound.bottom - hdr->rcBound.top >= h)
+                        {
+                            needToPaintAll = false;
+
+                            const RECT* rects = (const RECT*) (rgnData + sizeof (RGNDATAHEADER));
+                            int num = ((RGNDATA*) rgnData)->rdh.nCount;
+
+                            while (--num >= 0)
+                            {
+                                if (rects->right <= x + w && rects->bottom <= y + h)
+                                {
+                                    const int cx = jmax (x, (int) rects->left);
+                                    contextClip.addWithoutMerging (Rectangle<int> (cx - x, rects->top - y, rects->right - cx, rects->bottom - rects->top)
+                                                                       .getIntersection (clipBounds));
+                                }
+                                else
+                                {
+                                    needToPaintAll = true;
+                                    break;
+                                }
+
+                                ++rects;
+                            }
+                        }
+                    }
+                }
+
+                if (needToPaintAll)
+                {
+                    contextClip.clear();
+                    contextClip.addWithoutMerging (Rectangle<int> (w, h));
+                }
+
+                if (transparent)
+                {
+                    RectangleList::Iterator i (contextClip);
+
+                    while (i.next())
+                        offscreenImage.clear (*i.getRectangle());
+                }
+
+                // if the component's not opaque, this won't draw properly unless the platform can support this
+                jassert (Desktop::canUseSemiTransparentWindows() || component->isOpaque());
+
+                updateCurrentModifiers();
+
+                LowLevelGraphicsSoftwareRenderer context (offscreenImage, -x, -y, contextClip);
+                handlePaint (context);
+
+                if (! dontRepaint)
+                    static_cast <WindowsBitmapImage*> (offscreenImage.getSharedImage())
+                        ->blitToWindow (hwnd, dc, transparent, x, y, maskedRegion, updateLayeredWindowAlpha);
+            }
+
+            DeleteObject (rgn);
+            EndPaint (hwnd, &paintStruct);
+            reentrant = false;
+        }
+
+#ifndef JUCE_GCC  //xxx should add this fn for gcc..
+        _fpreset(); // because some graphics cards can unmask FP exceptions
+#endif
+
+        lastPaintTime = Time::getMillisecondCounter();
+    }
+
+    //==============================================================================
+    void doMouseEvent (const Point<int>& position)
+    {
+        handleMouseEvent (0, position, currentModifiers, getMouseEventTime());
+    }
+
+    const StringArray getAvailableRenderingEngines()
+    {
+        StringArray s (ComponentPeer::getAvailableRenderingEngines());
+
+#if JUCE_DIRECT2D
+        // xxx is this correct? Seems to enable it on Vista too??
+        OSVERSIONINFO info;
+        zerostruct (info);
+        info.dwOSVersionInfoSize = sizeof (OSVERSIONINFO);
+        GetVersionEx (&info);
+        if (info.dwMajorVersion >= 6)
+            s.add ("Direct2D");
+#endif
+        return s;
+    }
+
+    int getCurrentRenderingEngine() throw()
+    {
+        return currentRenderingEngine;
+    }
+
+#if JUCE_DIRECT2D
+    void updateDirect2DContext()
+    {
+        if (currentRenderingEngine != direct2DRenderingEngine)
+            direct2DContext = 0;
+        else if (direct2DContext == 0)
+            direct2DContext = new Direct2DLowLevelGraphicsContext (hwnd);
+    }
+#endif
+
+    void setCurrentRenderingEngine (int index)
+    {
+        (void) index;
+
+#if JUCE_DIRECT2D
+        currentRenderingEngine = index == 1 ? direct2DRenderingEngine : softwareRenderingEngine;
+        updateDirect2DContext();
+        repaint (component->getLocalBounds());
+#endif
+    }
+
+    void doMouseMove (const Point<int>& position)
+    {
+        if (! isMouseOver)
+        {
+            isMouseOver = true;
+            updateKeyModifiers();
+
+            TRACKMOUSEEVENT tme;
+            tme.cbSize = sizeof (tme);
+            tme.dwFlags = TME_LEAVE;
+            tme.hwndTrack = hwnd;
+            tme.dwHoverTime = 0;
+
+            if (! TrackMouseEvent (&tme))
+                jassertfalse;
+
+            Desktop::getInstance().getMainMouseSource().forceMouseCursorUpdate();
+        }
+        else if (! isDragging)
+        {
+            if (! contains (position, false))
+                return;
+        }
+
+        // (Throttling the incoming queue of mouse-events seems to still be required in XP..)
+        static uint32 lastMouseTime = 0;
+        const uint32 now = Time::getMillisecondCounter();
+        const int maxMouseMovesPerSecond = 60;
+
+        if (now > lastMouseTime + 1000 / maxMouseMovesPerSecond)
+        {
+            lastMouseTime = now;
+            doMouseEvent (position);
+        }
+    }
+
+    void doMouseDown (const Point<int>& position, const WPARAM wParam)
+    {
+        if (GetCapture() != hwnd)
+            SetCapture (hwnd);
+
+        doMouseMove (position);
+
+        updateModifiersFromWParam (wParam);
+        isDragging = true;
+
+        doMouseEvent (position);
+    }
+
+    void doMouseUp (const Point<int>& position, const WPARAM wParam)
+    {
+        updateModifiersFromWParam (wParam);
+        isDragging = false;
+
+        // release the mouse capture if the user has released all buttons
+        if ((wParam & (MK_LBUTTON | MK_RBUTTON | MK_MBUTTON)) == 0 && hwnd == GetCapture())
+            ReleaseCapture();
+
+        doMouseEvent (position);
+    }
+
+    void doCaptureChanged()
+    {
+        if (isDragging)
+            doMouseUp (getCurrentMousePos(), (WPARAM) 0);
+    }
+
+    void doMouseExit()
+    {
+        isMouseOver = false;
+        doMouseEvent (getCurrentMousePos());
+    }
+
+    void doMouseWheel (const Point<int>& position, const WPARAM wParam, const bool isVertical)
+    {
+        updateKeyModifiers();
+
+        const float amount = jlimit (-1000.0f, 1000.0f, 0.75f * (short) HIWORD (wParam));
+
+        handleMouseWheel (0, position, getMouseEventTime(),
+                          isVertical ? 0.0f : amount,
+                          isVertical ? amount : 0.0f);
+    }
+
+    //==============================================================================
+    void sendModifierKeyChangeIfNeeded()
+    {
+        if (modifiersAtLastCallback != currentModifiers)
+        {
+            modifiersAtLastCallback = currentModifiers;
+            handleModifierKeysChange();
+        }
+    }
+
+    bool doKeyUp (const WPARAM key)
+    {
+        updateKeyModifiers();
+
+        switch (key)
+        {
+            case VK_SHIFT:
+            case VK_CONTROL:
+            case VK_MENU:
+            case VK_CAPITAL:
+            case VK_LWIN:
+            case VK_RWIN:
+            case VK_APPS:
+            case VK_NUMLOCK:
+            case VK_SCROLL:
+            case VK_LSHIFT:
+            case VK_RSHIFT:
+            case VK_LCONTROL:
+            case VK_LMENU:
+            case VK_RCONTROL:
+            case VK_RMENU:
+                sendModifierKeyChangeIfNeeded();
+        }
+
+        return handleKeyUpOrDown (false)
+                || Component::getCurrentlyModalComponent() != 0;
+    }
+
+    bool doKeyDown (const WPARAM key)
+    {
+        updateKeyModifiers();
+        bool used = false;
+
+        switch (key)
+        {
+            case VK_SHIFT:
+            case VK_LSHIFT:
+            case VK_RSHIFT:
+            case VK_CONTROL:
+            case VK_LCONTROL:
+            case VK_RCONTROL:
+            case VK_MENU:
+            case VK_LMENU:
+            case VK_RMENU:
+            case VK_LWIN:
+            case VK_RWIN:
+            case VK_CAPITAL:
+            case VK_NUMLOCK:
+            case VK_SCROLL:
+            case VK_APPS:
+                sendModifierKeyChangeIfNeeded();
+                break;
+
+            case VK_LEFT:
+            case VK_RIGHT:
+            case VK_UP:
+            case VK_DOWN:
+            case VK_PRIOR:
+            case VK_NEXT:
+            case VK_HOME:
+            case VK_END:
+            case VK_DELETE:
+            case VK_INSERT:
+            case VK_F1:
+            case VK_F2:
+            case VK_F3:
+            case VK_F4:
+            case VK_F5:
+            case VK_F6:
+            case VK_F7:
+            case VK_F8:
+            case VK_F9:
+            case VK_F10:
+            case VK_F11:
+            case VK_F12:
+            case VK_F13:
+            case VK_F14:
+            case VK_F15:
+            case VK_F16:
+                used = handleKeyUpOrDown (true);
+                used = handleKeyPress (extendedKeyModifier | (int) key, 0) || used;
+                break;
+
+            case VK_ADD:
+            case VK_SUBTRACT:
+            case VK_MULTIPLY:
+            case VK_DIVIDE:
+            case VK_SEPARATOR:
+            case VK_DECIMAL:
+                used = handleKeyUpOrDown (true);
+                break;
+
+            default:
+                used = handleKeyUpOrDown (true);
+
+                {
+                    MSG msg;
+
+                    if (! PeekMessage (&msg, hwnd, WM_CHAR, WM_DEADCHAR, PM_NOREMOVE))
+                    {
+                        // if there isn't a WM_CHAR or WM_DEADCHAR message pending, we need to
+                        // manually generate the key-press event that matches this key-down.
+
+                        const UINT keyChar = MapVirtualKey (key, 2);
+                        used = handleKeyPress ((int) LOWORD (keyChar), 0) || used;
+                    }
+                }
+
+                break;
+        }
+
+        if (Component::getCurrentlyModalComponent() != 0)
+            used = true;
+
+        return used;
+    }
+
+    bool doKeyChar (int key, const LPARAM flags)
+    {
+        updateKeyModifiers();
+
+        juce_wchar textChar = (juce_wchar) key;
+
+        const int virtualScanCode = (flags >> 16) & 0xff;
+
+        if (key >= '0' && key <= '9')
+        {
+            switch (virtualScanCode)  // check for a numeric keypad scan-code
+            {
+            case 0x52:
+            case 0x4f:
+            case 0x50:
+            case 0x51:
+            case 0x4b:
+            case 0x4c:
+            case 0x4d:
+            case 0x47:
+            case 0x48:
+            case 0x49:
+                key = (key - '0') + KeyPress::numberPad0;
+                break;
+            default:
+                break;
+            }
+        }
+        else
+        {
+            // convert the scan code to an unmodified character code..
+            const UINT virtualKey = MapVirtualKey (virtualScanCode, 1);
+            UINT keyChar = MapVirtualKey (virtualKey, 2);
+
+            keyChar = LOWORD (keyChar);
+
+            if (keyChar != 0)
+                key = (int) keyChar;
+
+            // avoid sending junk text characters for some control-key combinations
+            if (textChar < ' ' && currentModifiers.testFlags (ModifierKeys::ctrlModifier | ModifierKeys::altModifier))
+                textChar = 0;
+        }
+
+        return handleKeyPress (key, textChar);
+    }
+
+    bool doAppCommand (const LPARAM lParam)
+    {
+        int key = 0;
+
+        switch (GET_APPCOMMAND_LPARAM (lParam))
+        {
+            case APPCOMMAND_MEDIA_PLAY_PAUSE:       key = KeyPress::playKey; break;
+            case APPCOMMAND_MEDIA_STOP:             key = KeyPress::stopKey; break;
+            case APPCOMMAND_MEDIA_NEXTTRACK:        key = KeyPress::fastForwardKey; break;
+            case APPCOMMAND_MEDIA_PREVIOUSTRACK:    key = KeyPress::rewindKey; break;
+            default: break;
+        }
+
+        if (key != 0)
+        {
+            updateKeyModifiers();
+
+            if (hwnd == GetActiveWindow())
+            {
+                handleKeyPress (key, 0);
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    LRESULT handleSizeConstraining (RECT* const r, const WPARAM wParam)
+    {
+        if (constrainer != 0 && (styleFlags & (windowHasTitleBar | windowIsResizable)) == (windowHasTitleBar | windowIsResizable))
+        {
+            Rectangle<int> pos (r->left, r->top, r->right - r->left, r->bottom - r->top);
+
+            constrainer->checkBounds (pos, windowBorder.addedTo (component->getBounds()),
+                                      Desktop::getInstance().getAllMonitorDisplayAreas().getBounds(),
+                                      wParam == WMSZ_TOP || wParam == WMSZ_TOPLEFT || wParam == WMSZ_TOPRIGHT,
+                                      wParam == WMSZ_LEFT || wParam == WMSZ_TOPLEFT || wParam == WMSZ_BOTTOMLEFT,
+                                      wParam == WMSZ_BOTTOM || wParam == WMSZ_BOTTOMLEFT || wParam == WMSZ_BOTTOMRIGHT,
+                                      wParam == WMSZ_RIGHT || wParam == WMSZ_TOPRIGHT || wParam == WMSZ_BOTTOMRIGHT);
+            r->left = pos.getX();
+            r->top = pos.getY();
+            r->right = pos.getRight();
+            r->bottom = pos.getBottom();
+        }
+
+        return TRUE;
+    }
+
+    LRESULT handlePositionChanging (WINDOWPOS* const wp)
+    {
+        if (constrainer != 0 && (styleFlags & (windowHasTitleBar | windowIsResizable)) == (windowHasTitleBar | windowIsResizable))
+        {
+            if ((wp->flags & (SWP_NOMOVE | SWP_NOSIZE)) != (SWP_NOMOVE | SWP_NOSIZE)
+                 && ! Component::isMouseButtonDownAnywhere())
+            {
+                Rectangle<int> pos (wp->x, wp->y, wp->cx, wp->cy);
+                const Rectangle<int> current (windowBorder.addedTo (component->getBounds()));
+
+                constrainer->checkBounds (pos, current,
+                                          Desktop::getInstance().getAllMonitorDisplayAreas().getBounds(),
+                                          pos.getY() != current.getY() && pos.getBottom() == current.getBottom(),
+                                          pos.getX() != current.getX() && pos.getRight() == current.getRight(),
+                                          pos.getY() == current.getY() && pos.getBottom() != current.getBottom(),
+                                          pos.getX() == current.getX() && pos.getRight() != current.getRight());
+                wp->x = pos.getX();
+                wp->y = pos.getY();
+                wp->cx = pos.getWidth();
+                wp->cy = pos.getHeight();
+            }
+        }
+
+        return 0;
+    }
+
+    void handleAppActivation (const WPARAM wParam)
+    {
+        modifiersAtLastCallback = -1;
+        updateKeyModifiers();
+
+        if (isMinimised())
+        {
+            component->repaint();
+            handleMovedOrResized();
+
+            if (! ComponentPeer::isValidPeer (this))
+                return;
+        }
+
+        if (LOWORD (wParam) == WA_CLICKACTIVE && component->isCurrentlyBlockedByAnotherModalComponent())
+        {
+            Component* const underMouse = component->getComponentAt (component->getMouseXYRelative());
+
+            if (underMouse != 0 && underMouse->isCurrentlyBlockedByAnotherModalComponent())
+                Component::getCurrentlyModalComponent()->inputAttemptWhenModal();
+        }
+        else
+        {
+            handleBroughtToFront();
+
+            if (component->isCurrentlyBlockedByAnotherModalComponent())
+                Component::getCurrentlyModalComponent()->toFront (true);
+        }
+    }
+
+    //==============================================================================
+    class JuceDropTarget    : public ComBaseClassHelper <IDropTarget>
+    {
+    public:
+        JuceDropTarget (Win32ComponentPeer* const owner_)
+            : owner (owner_)
+        {
+        }
+
+        HRESULT __stdcall DragEnter (IDataObject* pDataObject, DWORD /*grfKeyState*/, POINTL mousePos, DWORD* pdwEffect)
+        {
+            updateFileList (pDataObject);
+            owner->handleFileDragMove (files, owner->globalToLocal (Point<int> (mousePos.x, mousePos.y)));
+            *pdwEffect = DROPEFFECT_COPY;
+            return S_OK;
+        }
+
+        HRESULT __stdcall DragLeave()
+        {
+            owner->handleFileDragExit (files);
+            return S_OK;
+        }
+
+        HRESULT __stdcall DragOver (DWORD /*grfKeyState*/, POINTL mousePos, DWORD* pdwEffect)
+        {
+            owner->handleFileDragMove (files, owner->globalToLocal (Point<int> (mousePos.x, mousePos.y)));
+            *pdwEffect = DROPEFFECT_COPY;
+            return S_OK;
+        }
+
+        HRESULT __stdcall Drop (IDataObject* pDataObject, DWORD /*grfKeyState*/, POINTL mousePos, DWORD* pdwEffect)
+        {
+            updateFileList (pDataObject);
+            owner->handleFileDragDrop (files, owner->globalToLocal (Point<int> (mousePos.x, mousePos.y)));
+            *pdwEffect = DROPEFFECT_COPY;
+            return S_OK;
+        }
+
+    private:
+        Win32ComponentPeer* const owner;
+        StringArray files;
+
+        void updateFileList (IDataObject* const pDataObject)
+        {
+            files.clear();
+
+            FORMATETC format = { CF_HDROP, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
+            STGMEDIUM medium = { TYMED_HGLOBAL, { 0 }, 0 };
+
+            if (pDataObject->GetData (&format, &medium) == S_OK)
+            {
+                const SIZE_T totalLen = GlobalSize (medium.hGlobal);
+                const LPDROPFILES pDropFiles = (const LPDROPFILES) GlobalLock (medium.hGlobal);
+                unsigned int i = 0;
+
+                if (pDropFiles->fWide)
+                {
+                    const WCHAR* const fname = (WCHAR*) (((const char*) pDropFiles) + sizeof (DROPFILES));
+
+                    for (;;)
+                    {
+                        unsigned int len = 0;
+                        while (i + len < totalLen && fname [i + len] != 0)
+                            ++len;
+
+                        if (len == 0)
+                            break;
+
+                        files.add (String (fname + i, len));
+                        i += len + 1;
+                    }
+                }
+                else
+                {
+                    const char* const fname = ((const char*) pDropFiles) + sizeof (DROPFILES);
+
+                    for (;;)
+                    {
+                        unsigned int len = 0;
+                        while (i + len < totalLen && fname [i + len] != 0)
+                            ++len;
+
+                        if (len == 0)
+                            break;
+
+                        files.add (String (fname + i, len));
+                        i += len + 1;
+                    }
+                }
+
+                GlobalUnlock (medium.hGlobal);
+            }
+        }
+
+        JUCE_DECLARE_NON_COPYABLE (JuceDropTarget);
+    };
+
+    void doSettingChange()
+    {
+        Desktop::getInstance().refreshMonitorSizes();
+
+        if (fullScreen && ! isMinimised())
+        {
+            const Rectangle<int> r (component->getParentMonitorArea());
+
+            SetWindowPos (hwnd, 0, r.getX(), r.getY(), r.getWidth(), r.getHeight(),
+                          SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOZORDER | SWP_NOSENDCHANGING);
+        }
+    }
+
+    //==============================================================================
+public:
+    static LRESULT CALLBACK windowProc (HWND h, UINT message, WPARAM wParam, LPARAM lParam)
+    {
+        Win32ComponentPeer* const peer = getOwnerOfWindow (h);
+
+        if (peer != 0)
+        {
+            jassert (isValidPeer (peer));
+            return peer->peerWindowProc (h, message, wParam, lParam);
+        }
+
+        return DefWindowProcW (h, message, wParam, lParam);
+    }
+
+private:
+    static void* callFunctionIfNotLocked (MessageCallbackFunction* callback, void* userData)
+    {
+        if (MessageManager::getInstance()->currentThreadHasLockedMessageManager())
+            return callback (userData);
+        else
+            return MessageManager::getInstance()->callFunctionOnMessageThread (callback, userData);
+    }
+
+    static const Point<int> getPointFromLParam (LPARAM lParam) throw()
+    {
+        return Point<int> (GET_X_LPARAM (lParam), GET_Y_LPARAM (lParam));
+    }
+
+    const Point<int> getCurrentMousePos() throw()
+    {
+        RECT wr;
+        GetWindowRect (hwnd, &wr);
+        const DWORD mp = GetMessagePos();
+
+        return Point<int> (GET_X_LPARAM (mp) - wr.left - windowBorder.getLeft(),
+                           GET_Y_LPARAM (mp) - wr.top - windowBorder.getTop());
+    }
+
+    LRESULT peerWindowProc (HWND h, UINT message, WPARAM wParam, LPARAM lParam)
+    {
+        switch (message)
+        {
+            //==============================================================================
+            case WM_NCHITTEST:
+                if ((styleFlags & windowIgnoresMouseClicks) != 0)
+                    return HTTRANSPARENT;
+                else if (! hasTitleBar())
+                    return HTCLIENT;
+
+                break;
+
+            //==============================================================================
+            case WM_PAINT:
+                handlePaintMessage();
+                return 0;
+
+            case WM_NCPAINT:
+                if (wParam != 1)
+                    handlePaintMessage();
+
+                if (hasTitleBar())
+                    break;
+
+                return 0;
+
+            case WM_ERASEBKGND:
+            case WM_NCCALCSIZE:
+                if (hasTitleBar())
+                    break;
+
+                return 1;
+
+            //==============================================================================
+            case WM_MOUSEMOVE:
+                doMouseMove (getPointFromLParam (lParam));
+                return 0;
+
+            case WM_MOUSELEAVE:
+                doMouseExit();
+                return 0;
+
+            case WM_LBUTTONDOWN:
+            case WM_MBUTTONDOWN:
+            case WM_RBUTTONDOWN:
+                doMouseDown (getPointFromLParam (lParam), wParam);
+                return 0;
+
+            case WM_LBUTTONUP:
+            case WM_MBUTTONUP:
+            case WM_RBUTTONUP:
+                doMouseUp (getPointFromLParam (lParam), wParam);
+                return 0;
+
+            case WM_CAPTURECHANGED:
+                doCaptureChanged();
+                return 0;
+
+            case WM_NCMOUSEMOVE:
+                if (hasTitleBar())
+                    break;
+
+                return 0;
+
+            case 0x020A: /* WM_MOUSEWHEEL */
+            case 0x020E: /* WM_MOUSEHWHEEL */
+                doMouseWheel (getCurrentMousePos(), wParam, message == 0x020A);
+                return 0;
+
+            //==============================================================================
+            case WM_SIZING:
+                return handleSizeConstraining ((RECT*) lParam, wParam);
+
+            case WM_WINDOWPOSCHANGING:
+                return handlePositionChanging ((WINDOWPOS*) lParam);
+
+            case WM_WINDOWPOSCHANGED:
+                {
+                    const Point<int> pos (getCurrentMousePos());
+                    if (contains (pos, false))
+                        doMouseEvent (pos);
+                }
+
+                handleMovedOrResized();
+
+                if (dontRepaint)
+                    break;  // needed for non-accelerated openGL windows to draw themselves correctly..
+
+                return 0;
+
+            //==============================================================================
+            case WM_KEYDOWN:
+            case WM_SYSKEYDOWN:
+                if (doKeyDown (wParam))
+                    return 0;
+
+                break;
+
+            case WM_KEYUP:
+            case WM_SYSKEYUP:
+                if (doKeyUp (wParam))
+                    return 0;
+
+                break;
+
+            case WM_CHAR:
+                if (doKeyChar ((int) wParam, lParam))
+                    return 0;
+
+                break;
+
+            case WM_APPCOMMAND:
+                if (doAppCommand (lParam))
+                    return TRUE;
+
+                break;
+
+            //==============================================================================
+            case WM_SETFOCUS:
+                updateKeyModifiers();
+                handleFocusGain();
+                break;
+
+            case WM_KILLFOCUS:
+                if (hasCreatedCaret)
+                {
+                    hasCreatedCaret = false;
+                    DestroyCaret();
+                }
+
+                handleFocusLoss();
+                break;
+
+            case WM_ACTIVATEAPP:
+                // Windows does weird things to process priority when you swap apps,
+                // so this forces an update when the app is brought to the front
+                if (wParam != FALSE)
+                    juce_repeatLastProcessPriority();
+                else
+                    Desktop::getInstance().setKioskModeComponent (0); // turn kiosk mode off if we lose focus
+
+                juce_CheckCurrentlyFocusedTopLevelWindow();
+                modifiersAtLastCallback = -1;
+                return 0;
+
+            case WM_ACTIVATE:
+                if (LOWORD (wParam) == WA_ACTIVE || LOWORD (wParam) == WA_CLICKACTIVE)
+                {
+                    handleAppActivation (wParam);
+                    return 0;
+                }
+
+                break;
+
+            case WM_NCACTIVATE:
+                // while a temporary window is being shown, prevent Windows from deactivating the
+                // title bars of our main windows.
+                if (wParam == 0 && ! shouldDeactivateTitleBar)
+                    wParam = TRUE; // change this and let it get passed to the DefWindowProc.
+
+                break;
+
+            case WM_MOUSEACTIVATE:
+                if (! component->getMouseClickGrabsKeyboardFocus())
+                    return MA_NOACTIVATE;
+
+                break;
+
+            case WM_SHOWWINDOW:
+                if (wParam != 0)
+                    handleBroughtToFront();
+
+                break;
+
+            case WM_CLOSE:
+                if (! component->isCurrentlyBlockedByAnotherModalComponent())
+                    handleUserClosingWindow();
+
+                return 0;
+
+            case WM_QUERYENDSESSION:
+                if (JUCEApplication::getInstance() != 0)
+                {
+                    JUCEApplication::getInstance()->systemRequestedQuit();
+                    return MessageManager::getInstance()->hasStopMessageBeenSent();
+                }
+                return TRUE;
+
+            case WM_TRAYNOTIFY:
+                handleTaskBarEvent (lParam);
+                break;
+
+            case WM_SYNCPAINT:
+                return 0;
+
+            case WM_PALETTECHANGED:
+                InvalidateRect (h, 0, 0);
+                break;
+
+            case WM_DISPLAYCHANGE:
+                InvalidateRect (h, 0, 0);
+                createPaletteIfNeeded = true;
+                // intentional fall-through...
+            case WM_SETTINGCHANGE:  // note the fall-through in the previous case!
+                doSettingChange();
+                break;
+
+            case WM_INITMENU:
+                if (! hasTitleBar())
+                {
+                    if (isFullScreen())
+                    {
+                        EnableMenuItem ((HMENU) wParam, SC_RESTORE, MF_BYCOMMAND | MF_ENABLED);
+                        EnableMenuItem ((HMENU) wParam, SC_MOVE, MF_BYCOMMAND | MF_GRAYED);
+                    }
+                    else if (! isMinimised())
+                    {
+                        EnableMenuItem ((HMENU) wParam, SC_MAXIMIZE, MF_BYCOMMAND | MF_GRAYED);
+                    }
+                }
+                break;
+
+            case WM_SYSCOMMAND:
+                switch (wParam & 0xfff0)
+                {
+                case SC_CLOSE:
+                    if (sendInputAttemptWhenModalMessage())
+                        return 0;
+
+                    if (hasTitleBar())
+                    {
+                        PostMessage (h, WM_CLOSE, 0, 0);
+                        return 0;
+                    }
+                    break;
+
+                case SC_KEYMENU:
+                    // (NB mustn't call sendInputAttemptWhenModalMessage() here because of very obscure
+                    // situations that can arise if a modal loop is started from an alt-key keypress).
+                    if (hasTitleBar() && h == GetCapture())
+                        ReleaseCapture();
+
+                    break;
+
+                case SC_MAXIMIZE:
+                    if (! sendInputAttemptWhenModalMessage())
+                        setFullScreen (true);
+
+                    return 0;
+
+                case SC_MINIMIZE:
+                    if (sendInputAttemptWhenModalMessage())
+                        return 0;
+
+                    if (! hasTitleBar())
+                    {
+                        setMinimised (true);
+                        return 0;
+                    }
+                    break;
+
+                case SC_RESTORE:
+                    if (sendInputAttemptWhenModalMessage())
+                        return 0;
+
+                    if (hasTitleBar())
+                    {
+                        if (isFullScreen())
+                        {
+                            setFullScreen (false);
+                            return 0;
+                        }
+                    }
+                    else
+                    {
+                        if (isMinimised())
+                            setMinimised (false);
+                        else if (isFullScreen())
+                            setFullScreen (false);
+
+                        return 0;
+                    }
+                    break;
+                }
+
+                break;
+
+            case WM_NCLBUTTONDOWN:
+            case WM_NCRBUTTONDOWN:
+            case WM_NCMBUTTONDOWN:
+                sendInputAttemptWhenModalMessage();
+                break;
+
+            //case WM_IME_STARTCOMPOSITION;
+              //  return 0;
+
+            case WM_GETDLGCODE:
+                return DLGC_WANTALLKEYS;
+
+            default:
+                if (taskBarIcon != 0)
+                {
+                    static const DWORD taskbarCreatedMessage = RegisterWindowMessage (TEXT("TaskbarCreated"));
+
+                    if (message == taskbarCreatedMessage)
+                    {
+                        taskBarIcon->uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP;
+                        Shell_NotifyIcon (NIM_ADD, taskBarIcon);
+                    }
+                }
+
+                break;
+        }
+
+        return DefWindowProcW (h, message, wParam, lParam);
+    }
+
+    bool sendInputAttemptWhenModalMessage()
+    {
+        if (component->isCurrentlyBlockedByAnotherModalComponent())
+        {
+            Component* const current = Component::getCurrentlyModalComponent();
+
+            if (current != 0)
+                current->inputAttemptWhenModal();
+
+            return true;
+        }
+
+        return false;
+    }
+
+    JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Win32ComponentPeer);
+};
+
+ModifierKeys Win32ComponentPeer::currentModifiers;
+ModifierKeys Win32ComponentPeer::modifiersAtLastCallback;
+
+ComponentPeer* Component::createNewPeer (int styleFlags, void* nativeWindowToAttachTo)
+{
+    return new Win32ComponentPeer (this, styleFlags, (HWND) nativeWindowToAttachTo);
+}
+
+juce_ImplementSingleton_SingleThreaded (Win32ComponentPeer::WindowClassHolder);
+
+
+//==============================================================================
+void ModifierKeys::updateCurrentModifiers() throw()
+{
+    currentModifiers = Win32ComponentPeer::currentModifiers;
+}
+
+const ModifierKeys ModifierKeys::getCurrentModifiersRealtime() throw()
+{
+    Win32ComponentPeer::updateKeyModifiers();
+
+    int mouseMods = 0;
+    if ((GetKeyState (VK_LBUTTON) & 0x8000) != 0)   mouseMods |= ModifierKeys::leftButtonModifier;
+    if ((GetKeyState (VK_RBUTTON) & 0x8000) != 0)   mouseMods |= ModifierKeys::rightButtonModifier;
+    if ((GetKeyState (VK_MBUTTON) & 0x8000) != 0)   mouseMods |= ModifierKeys::middleButtonModifier;
+
+    Win32ComponentPeer::currentModifiers
+        = Win32ComponentPeer::currentModifiers.withoutMouseButtons().withFlags (mouseMods);
+
+    return Win32ComponentPeer::currentModifiers;
+}
+
+//==============================================================================
+void SystemTrayIconComponent::setIconImage (const Image& newImage)
+{
+    Win32ComponentPeer* const wp = dynamic_cast <Win32ComponentPeer*> (getPeer());
+
+    if (wp != 0)
+        wp->setTaskBarIcon (newImage);
+}
+
+void SystemTrayIconComponent::setIconTooltip (const String& tooltip)
+{
+    Win32ComponentPeer* const wp = dynamic_cast <Win32ComponentPeer*> (getPeer());
+
+    if (wp != 0)
+        wp->setTaskBarIconToolTip (tooltip);
+}
+
+//==============================================================================
+void juce_setWindowStyleBit (HWND h, const int styleType, const int feature, const bool bitIsSet) throw()
+{
+    DWORD val = GetWindowLong (h, styleType);
+
+    if (bitIsSet)
+        val |= feature;
+    else
+        val &= ~feature;
+
+    SetWindowLongPtr (h, styleType, val);
+    SetWindowPos (h, 0, 0, 0, 0, 0,
+                  SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER
+                   | SWP_NOOWNERZORDER | SWP_FRAMECHANGED | SWP_NOSENDCHANGING);
+}
+
+
+//==============================================================================
+bool Process::isForegroundProcess()
+{
+    HWND fg = GetForegroundWindow();
+
+    if (fg == 0)
+        return true;
+
+    // when running as a plugin in IE8, the browser UI runs in a different process to the plugin, so
+    // process ID isn't a reliable way to check if the foreground window belongs to us - instead, we
+    // have to see if any of our windows are children of the foreground window
+    fg = GetAncestor (fg, GA_ROOT);
+
+    for (int i = ComponentPeer::getNumPeers(); --i >= 0;)
+    {
+        Win32ComponentPeer* const wp = dynamic_cast <Win32ComponentPeer*> (ComponentPeer::getPeer (i));
+
+        if (wp != 0 && wp->isInside (fg))
+            return true;
+    }
+
+    return false;
+}
+
+//==============================================================================
+bool AlertWindow::showNativeDialogBox (const String& title,
+                                       const String& bodyText,
+                                       bool isOkCancel)
+{
+    return MessageBox (0, bodyText, title,
+                       MB_SETFOREGROUND | (isOkCancel ? MB_OKCANCEL
+                                                      : MB_OK)) == IDOK;
+}
+
+
+//==============================================================================
+void Desktop::createMouseInputSources()
+{
+    mouseSources.add (new MouseInputSource (0, true));
+}
+
+const Point<int> MouseInputSource::getCurrentMousePosition()
+{
+    POINT mousePos;
+    GetCursorPos (&mousePos);
+    return Point<int> (mousePos.x, mousePos.y);
+}
+
+void Desktop::setMousePosition (const Point<int>& newPosition)
+{
+    SetCursorPos (newPosition.getX(), newPosition.getY());
+}
+
+//==============================================================================
+Image::SharedImage* Image::SharedImage::createNativeImage (PixelFormat format, int width, int height, bool clearImage)
+{
+    return createSoftwareImage (format, width, height, clearImage);
+}
+
+//==============================================================================
+class ScreenSaverDefeater   : public Timer,
+                              public DeletedAtShutdown
+{
+public:
+    ScreenSaverDefeater()
+    {
+        startTimer (10000);
+        timerCallback();
+    }
+
+    ~ScreenSaverDefeater() {}
+
+    void timerCallback()
+    {
+        if (Process::isForegroundProcess())
+        {
+            // simulate a shift key getting pressed..
+            INPUT input[2];
+            input[0].type = INPUT_KEYBOARD;
+            input[0].ki.wVk = VK_SHIFT;
+            input[0].ki.dwFlags = 0;
+            input[0].ki.dwExtraInfo = 0;
+
+            input[1].type = INPUT_KEYBOARD;
+            input[1].ki.wVk = VK_SHIFT;
+            input[1].ki.dwFlags = KEYEVENTF_KEYUP;
+            input[1].ki.dwExtraInfo = 0;
+
+            SendInput (2, input, sizeof (INPUT));
+        }
+    }
+};
+
+static ScreenSaverDefeater* screenSaverDefeater = 0;
+
+void Desktop::setScreenSaverEnabled (const bool isEnabled)
+{
+    if (isEnabled)
+        deleteAndZero (screenSaverDefeater);
+    else if (screenSaverDefeater == 0)
+        screenSaverDefeater = new ScreenSaverDefeater();
+}
+
+bool Desktop::isScreenSaverEnabled()
+{
+    return screenSaverDefeater == 0;
+}
+
+/* (The code below is the "correct" way to disable the screen saver, but it
+    completely fails on winXP when the saver is password-protected...)
+
+static bool juce_screenSaverEnabled = true;
+
+void Desktop::setScreenSaverEnabled (const bool isEnabled) throw()
+{
+    juce_screenSaverEnabled = isEnabled;
+    SetThreadExecutionState (isEnabled ? ES_CONTINUOUS
+                                       : (ES_DISPLAY_REQUIRED | ES_CONTINUOUS));
+}
+
+bool Desktop::isScreenSaverEnabled() throw()
+{
+    return juce_screenSaverEnabled;
+}
+*/
+
+//==============================================================================
+void juce_setKioskComponent (Component* kioskModeComponent, bool enableOrDisable, bool /*allowMenusAndBars*/)
+{
+    if (enableOrDisable)
+        kioskModeComponent->setBounds (Desktop::getInstance().getMainMonitorArea (false));
+}
+
+//==============================================================================
+static BOOL CALLBACK enumMonitorsProc (HMONITOR, HDC, LPRECT r, LPARAM userInfo)
+{
+    Array <Rectangle<int> >* const monitorCoords = (Array <Rectangle<int> >*) userInfo;
+
+    monitorCoords->add (Rectangle<int> (r->left, r->top, r->right - r->left, r->bottom - r->top));
+
+    return TRUE;
+}
+
+void juce_updateMultiMonitorInfo (Array <Rectangle<int> >& monitorCoords, const bool clipToWorkArea)
+{
+    EnumDisplayMonitors (0, 0, &enumMonitorsProc, (LPARAM) &monitorCoords);
+
+    // make sure the first in the list is the main monitor
+    for (int i = 1; i < monitorCoords.size(); ++i)
+        if (monitorCoords[i].getX() == 0 && monitorCoords[i].getY() == 0)
+            monitorCoords.swap (i, 0);
+
+    if (monitorCoords.size() == 0)
+    {
+        RECT r;
+        GetWindowRect (GetDesktopWindow(), &r);
+
+        monitorCoords.add (Rectangle<int> (r.left, r.top, r.right - r.left, r.bottom - r.top));
+    }
+
+    if (clipToWorkArea)
+    {
+        // clip the main monitor to the active non-taskbar area
+        RECT r;
+        SystemParametersInfo (SPI_GETWORKAREA, 0, &r, 0);
+
+        Rectangle<int>& screen = monitorCoords.getReference (0);
+
+        screen.setPosition (jmax (screen.getX(), (int) r.left),
+                            jmax (screen.getY(), (int) r.top));
+
+        screen.setSize (jmin (screen.getRight(), (int) r.right) - screen.getX(),
+                        jmin (screen.getBottom(), (int) r.bottom) - screen.getY());
+    }
+}
+
+//==============================================================================
+const Image juce_createIconForFile (const File& file)
+{
+    Image image;
+
+    WCHAR filename [1024];
+    file.getFullPathName().copyToUnicode (filename, 1023);
+    WORD iconNum = 0;
+
+    HICON icon = ExtractAssociatedIcon ((HINSTANCE) PlatformUtilities::getCurrentModuleInstanceHandle(),
+                                        filename, &iconNum);
+
+    if (icon != 0)
+    {
+        image = IconConverters::createImageFromHICON (icon);
+        DestroyIcon (icon);
+    }
+
+    return image;
+}
+
+//==============================================================================
+void* MouseCursor::createMouseCursorFromImage (const Image& image, int hotspotX, int hotspotY)
+{
+    const int maxW = GetSystemMetrics (SM_CXCURSOR);
+    const int maxH = GetSystemMetrics (SM_CYCURSOR);
+
+    Image im (image);
+
+    if (im.getWidth() > maxW || im.getHeight() > maxH)
+    {
+        im = im.rescaled (maxW, maxH);
+
+        hotspotX = (hotspotX * maxW) / image.getWidth();
+        hotspotY = (hotspotY * maxH) / image.getHeight();
+    }
+
+    return IconConverters::createHICONFromImage (im, FALSE, hotspotX, hotspotY);
+}
+
+void MouseCursor::deleteMouseCursor (void* const cursorHandle, const bool isStandard)
+{
+    if (cursorHandle != 0 && ! isStandard)
+        DestroyCursor ((HCURSOR) cursorHandle);
+}
+
+enum
+{
+    hiddenMouseCursorHandle = 32500 // (arbitrary non-zero value to mark this type of cursor)
+};
+
+void* MouseCursor::createStandardMouseCursor (const MouseCursor::StandardCursorType type)
+{
+    LPCTSTR cursorName = IDC_ARROW;
+
+    switch (type)
+    {
+        case NormalCursor:                  break;
+        case NoCursor:                      return (void*) hiddenMouseCursorHandle;
+        case WaitCursor:                    cursorName = IDC_WAIT; break;
+        case IBeamCursor:                   cursorName = IDC_IBEAM; break;
+        case PointingHandCursor:            cursorName = MAKEINTRESOURCE(32649); break;
+        case CrosshairCursor:               cursorName = IDC_CROSS; break;
+        case CopyingCursor:                 break; // can't seem to find one of these in the win32 list..
+
+        case LeftRightResizeCursor:
+        case LeftEdgeResizeCursor:
+        case RightEdgeResizeCursor:         cursorName = IDC_SIZEWE; break;
+
+        case UpDownResizeCursor:
+        case TopEdgeResizeCursor:
+        case BottomEdgeResizeCursor:        cursorName = IDC_SIZENS; break;
+
+        case TopLeftCornerResizeCursor:
+        case BottomRightCornerResizeCursor: cursorName = IDC_SIZENWSE; break;
+
+        case TopRightCornerResizeCursor:
+        case BottomLeftCornerResizeCursor:  cursorName = IDC_SIZENESW; break;
+
+        case UpDownLeftRightResizeCursor:   cursorName = IDC_SIZEALL; break;
+
+        case DraggingHandCursor:
+        {
+            static void* dragHandCursor = 0;
+
+            if (dragHandCursor == 0)
+            {
+                static const unsigned char dragHandData[] =
+                    { 71,73,70,56,57,97,16,0,16,0,145,2,0,0,0,0,255,255,255,0,0,0,0,0,0,33,249,4,1,0,0,2,0,44,0,0,0,0,16,0,
+                      16,0,0,2,52,148,47,0,200,185,16,130,90,12,74,139,107,84,123,39,132,117,151,116,132,146,248,60,209,138,
+                      98,22,203,114,34,236,37,52,77,217,247,154,191,119,110,240,193,128,193,95,163,56,60,234,98,135,2,0,59 };
+
+                dragHandCursor = createMouseCursorFromImage (ImageFileFormat::loadFrom (dragHandData, sizeof (dragHandData)), 8, 7);
+            }
+
+            return dragHandCursor;
+        }
+
+        default:
+			//jassertfalse; // SO. This causes crashes in Debug mode in Windows. Removing it doesn't seem to make much difference.
+             break;
+			 
+    }
+
+    HCURSOR cursorH = LoadCursor (0, cursorName);
+
+    if (cursorH == 0)
+        cursorH = LoadCursor (0, IDC_ARROW);
+
+    return cursorH;
+}
+
+//==============================================================================
+void MouseCursor::showInWindow (ComponentPeer*) const
+{
+    HCURSOR c = (HCURSOR) getHandle();
+
+    if (c == 0)
+        c = LoadCursor (0, IDC_ARROW);
+    else if (c == (HCURSOR) hiddenMouseCursorHandle)
+        c = 0;
+
+    SetCursor (c);
+}
+
+void MouseCursor::showInAllWindows() const
+{
+    showInWindow (0);
+}
+
+//==============================================================================
+//==============================================================================
+class JuceDropSource   : public ComBaseClassHelper <IDropSource>
+{
+public:
+    JuceDropSource() {}
+    ~JuceDropSource() {}
+
+    HRESULT __stdcall QueryContinueDrag (BOOL escapePressed, DWORD keys)
+    {
+        if (escapePressed)
+            return DRAGDROP_S_CANCEL;
+
+        if ((keys & (MK_LBUTTON | MK_RBUTTON)) == 0)
+            return DRAGDROP_S_DROP;
+
+        return S_OK;
+    }
+
+    HRESULT __stdcall GiveFeedback (DWORD)
+    {
+        return DRAGDROP_S_USEDEFAULTCURSORS;
+    }
+};
+
+
+class JuceEnumFormatEtc   : public ComBaseClassHelper <IEnumFORMATETC>
+{
+public:
+    JuceEnumFormatEtc (const FORMATETC* const format_)
+        : format (format_),
+          index (0)
+    {
+    }
+
+    ~JuceEnumFormatEtc()  {}
+
+    HRESULT __stdcall Clone (IEnumFORMATETC** result)
+    {
+        if (result == 0)
+            return E_POINTER;
+
+        JuceEnumFormatEtc* const newOne = new JuceEnumFormatEtc (format);
+        newOne->index = index;
+
+        *result = newOne;
+        return S_OK;
+    }
+
+    HRESULT __stdcall Next (ULONG celt, LPFORMATETC lpFormatEtc, ULONG* pceltFetched)
+    {
+        if (pceltFetched != 0)
+            *pceltFetched = 0;
+        else if (celt != 1)
+            return S_FALSE;
+
+        if (index == 0 && celt > 0 && lpFormatEtc != 0)
+        {
+            copyFormatEtc (lpFormatEtc [0], *format);
+            ++index;
+
+            if (pceltFetched != 0)
+                *pceltFetched = 1;
+
+            return S_OK;
+        }
+
+        return S_FALSE;
+    }
+
+    HRESULT __stdcall Skip (ULONG celt)
+    {
+        if (index + (int) celt >= 1)
+            return S_FALSE;
+
+        index += celt;
+        return S_OK;
+    }
+
+    HRESULT __stdcall Reset()
+    {
+        index = 0;
+        return S_OK;
+    }
+
+private:
+    const FORMATETC* const format;
+    int index;
+
+    static void copyFormatEtc (FORMATETC& dest, const FORMATETC& source)
+    {
+        dest = source;
+
+        if (source.ptd != 0)
+        {
+            dest.ptd = (DVTARGETDEVICE*) CoTaskMemAlloc (sizeof (DVTARGETDEVICE));
+            *(dest.ptd) = *(source.ptd);
+        }
+    }
+
+    JUCE_DECLARE_NON_COPYABLE (JuceEnumFormatEtc);
+};
+
+class JuceDataObject  : public ComBaseClassHelper <IDataObject>
+{
+public:
+    JuceDataObject (JuceDropSource* const dropSource_,
+                    const FORMATETC* const format_,
+                    const STGMEDIUM* const medium_)
+        : dropSource (dropSource_),
+          format (format_),
+          medium (medium_)
+    {
+    }
+
+    ~JuceDataObject()
+    {
+        jassert (refCount == 0);
+    }
+
+    HRESULT __stdcall GetData (FORMATETC* pFormatEtc, STGMEDIUM* pMedium)
+    {
+        if ((pFormatEtc->tymed & format->tymed) != 0
+             && pFormatEtc->cfFormat == format->cfFormat
+             && pFormatEtc->dwAspect == format->dwAspect)
+        {
+            pMedium->tymed = format->tymed;
+            pMedium->pUnkForRelease = 0;
+
+            if (format->tymed == TYMED_HGLOBAL)
+            {
+                const SIZE_T len = GlobalSize (medium->hGlobal);
+                void* const src = GlobalLock (medium->hGlobal);
+                void* const dst = GlobalAlloc (GMEM_FIXED, len);
+
+                memcpy (dst, src, len);
+
+                GlobalUnlock (medium->hGlobal);
+
+                pMedium->hGlobal = dst;
+                return S_OK;
+            }
+        }
+
+        return DV_E_FORMATETC;
+    }
+
+    HRESULT __stdcall QueryGetData (FORMATETC* f)
+    {
+        if (f == 0)
+            return E_INVALIDARG;
+
+        if (f->tymed == format->tymed
+              && f->cfFormat == format->cfFormat
+              && f->dwAspect == format->dwAspect)
+            return S_OK;
+
+        return DV_E_FORMATETC;
+    }
+
+    HRESULT __stdcall GetCanonicalFormatEtc (FORMATETC*, FORMATETC* pFormatEtcOut)
+    {
+        pFormatEtcOut->ptd = 0;
+        return E_NOTIMPL;
+    }
+
+    HRESULT __stdcall EnumFormatEtc (DWORD direction, IEnumFORMATETC** result)
+    {
+        if (result == 0)
+            return E_POINTER;
+
+        if (direction == DATADIR_GET)
+        {
+            *result = new JuceEnumFormatEtc (format);
+            return S_OK;
+        }
+
+        *result = 0;
+        return E_NOTIMPL;
+    }
+
+    HRESULT __stdcall GetDataHere (FORMATETC*, STGMEDIUM*)                  { return DATA_E_FORMATETC; }
+    HRESULT __stdcall SetData (FORMATETC*, STGMEDIUM*, BOOL)                { return E_NOTIMPL; }
+    HRESULT __stdcall DAdvise (FORMATETC*, DWORD, IAdviseSink*, DWORD*)     { return OLE_E_ADVISENOTSUPPORTED; }
+    HRESULT __stdcall DUnadvise (DWORD)                                     { return E_NOTIMPL; }
+    HRESULT __stdcall EnumDAdvise (IEnumSTATDATA**)                         { return OLE_E_ADVISENOTSUPPORTED; }
+
+private:
+    JuceDropSource* const dropSource;
+    const FORMATETC* const format;
+    const STGMEDIUM* const medium;
+
+    JUCE_DECLARE_NON_COPYABLE (JuceDataObject);
+};
+
+static HDROP createHDrop (const StringArray& fileNames)
+{
+    int totalChars = 0;
+    for (int i = fileNames.size(); --i >= 0;)
+        totalChars += fileNames[i].length() + 1;
+
+    HDROP hDrop = (HDROP) GlobalAlloc (GMEM_MOVEABLE | GMEM_ZEROINIT,
+                                       sizeof (DROPFILES) + sizeof (WCHAR) * (totalChars + 2));
+
+    if (hDrop != 0)
+    {
+        LPDROPFILES pDropFiles = (LPDROPFILES) GlobalLock (hDrop);
+        pDropFiles->pFiles = sizeof (DROPFILES);
+        pDropFiles->fWide = true;
+
+        WCHAR* fname = reinterpret_cast<WCHAR*> (addBytesToPointer (pDropFiles, sizeof (DROPFILES)));
+
+        for (int i = 0; i < fileNames.size(); ++i)
+        {
+            fileNames[i].copyToUnicode (fname, 2048);
+            fname += fileNames[i].length() + 1;
+        }
+
+        *fname = 0;
+
+        GlobalUnlock (hDrop);
+    }
+
+    return hDrop;
+}
+
+static bool performDragDrop (FORMATETC* const format, STGMEDIUM* const medium, const DWORD whatToDo)
+{
+    JuceDropSource* const source = new JuceDropSource();
+    JuceDataObject* const data = new JuceDataObject (source, format, medium);
+
+    DWORD effect;
+    const HRESULT res = DoDragDrop (data, source, whatToDo, &effect);
+
+    data->Release();
+    source->Release();
+
+    return res == DRAGDROP_S_DROP;
+}
+
+bool DragAndDropContainer::performExternalDragDropOfFiles (const StringArray& files, const bool canMove)
+{
+    FORMATETC format = { CF_HDROP, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
+    STGMEDIUM medium = { TYMED_HGLOBAL, { 0 }, 0 };
+
+    medium.hGlobal = createHDrop (files);
+
+    return performDragDrop (&format, &medium, canMove ? (DROPEFFECT_COPY | DROPEFFECT_MOVE)
+                                                      : DROPEFFECT_COPY);
+}
+
+bool DragAndDropContainer::performExternalDragDropOfText (const String& text)
+{
+    FORMATETC format = { CF_TEXT, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
+    STGMEDIUM medium = { TYMED_HGLOBAL, { 0 }, 0 };
+
+    const int numChars = text.length();
+
+    medium.hGlobal = GlobalAlloc (GMEM_MOVEABLE | GMEM_ZEROINIT, (numChars + 2) * sizeof (WCHAR));
+    WCHAR* const data = static_cast <WCHAR*> (GlobalLock (medium.hGlobal));
+
+    text.copyToUnicode (data, numChars + 1);
+    format.cfFormat = CF_UNICODETEXT;
+
+    GlobalUnlock (medium.hGlobal);
+
+    return performDragDrop (&format, &medium, DROPEFFECT_COPY | DROPEFFECT_MOVE);
+}
+
+
+#endif
diff --git a/Source/Processors/RecordNode.cpp b/Source/Processors/RecordNode.cpp
index 1fab01b233c72e1bae7c09ea6c96b8191bb875e1..b7e8483a6cda0958be291a80c955baa396143019 100755
--- a/Source/Processors/RecordNode.cpp
+++ b/Source/Processors/RecordNode.cpp
@@ -1,424 +1,421 @@
-/*
-    ------------------------------------------------------------------
-
-    This file is part of the Open Ephys GUI
-    Copyright (C) 2012 Open Ephys
-
-    ------------------------------------------------------------------
-
-    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 3 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, see <http://www.gnu.org/licenses/>.
-
-*/
-
-#include "RecordNode.h"
-#include "ProcessorGraph.h"
-
-RecordNode::RecordNode()
-	: GenericProcessor("Record Node"), isRecording(false), isProcessing(false),
-		timestamp(0), signalFilesShouldClose(false)
-{
-
-	
-//	newDataFolder = true; // defaults to creating a new data folder on startup
-	continuousDataIntegerBuffer = new int16[10000];
-	continuousDataFloatBuffer = new float[10000];
-	signalFilesShouldClose = false;
-
-}
-
-
-RecordNode::~RecordNode() {
-
-}
-
-void RecordNode::setChannel(int id, int chan)
-{
-
-	std::cout << "Record node setting channel." << std::endl;
-
-	for (int i = 0; i < continuousChannels.size(); i++)
-	{
-
-		if (continuousChannels[i].nodeId == id &&
-			continuousChannels[i].chan == chan)
-		{
-			std::cout << "Found channel " << i << std::endl;
-			setCurrentChannel(i);
-			break;
-		}
-
-	}
-}
-
-void RecordNode::setChannelStatus(int chan, bool status)
-{
-
-	std::cout << "Setting channel status!" << std::endl;
-	setCurrentChannel(chan);
-
-	if (status)
-		setParameter(2, 1.0f);
-	else
-		setParameter(2, 0.0f);
-
-}
-
-// void RecordNode::enableCurrentChannel(bool state)
-// {
-// 	continuousChannels[nextAvailableChannel].isRecording = state;
-// }
-
-void RecordNode::resetConnections()
-{
-	//std::cout << "Resetting connections" << std::endl;
-	nextAvailableChannel = 0;
-	wasConnected = false;
-
-	continuousChannels.clear();
-	eventChannels.clear();
-}
-
-void RecordNode::filenameComponentChanged(FilenameComponent* fnc)
-{
-
-	std::cout << "Got a new file" << std::endl;
-	dataDirectory = fnc->getCurrentFile();
-	std::cout << "File name: " << dataDirectory.getFullPathName();
-	if (dataDirectory.isDirectory())
-		std::cout << " is a directory." << std::endl;
-	else
-		std::cout << " is NOT a directory." << std::endl;
-
-	createNewDirectory();
-
-}
-
-
-void RecordNode::addInputChannel(GenericProcessor* sourceNode, int chan)
-{
-
-	if (chan != getProcessorGraph()->midiChannelIndex)
-	{
-        
-        setPlayConfigDetails(getNextChannel(false)+1,0,44100.0,128);
-        
-		Channel newChannel;
-
-		std::cout << "Record node adding channel." << std::endl;
-
-		newChannel.nodeId = sourceNode->getNodeId();
-		newChannel.chan = chan;
-		newChannel.name = sourceNode->getOutputChannelName(chan);
-		newChannel.isRecording = sourceNode->recordStatus(chan);
-
-		String filename = rootFolder.getFullPathName();
-		filename += "/";
-		filename += newChannel.nodeId;
-		filename += "_";
-		filename += newChannel.name;
-		filename += ".continuous";
-
-		newChannel.filename = filename;
-		newChannel.file = 0; 
-
-		if (newChannel.isRecording)
-			std::cout << "  This channel will be recorded." << std::endl;
-		else 
-			std::cout << "  This channel will NOT be recorded." << std::endl;
-	
-		std::cout << "adding channel " << getNextChannel(false) << std::endl;
-
-		std::pair<int, Channel> newPair (getNextChannel(false), newChannel);
-
-		//std::cout << "adding channel " << getNextChannel(false) << std::endl;
-
-		continuousChannels.insert(newPair);
-
-		
-	} else {
-
-		std::map<int, Channel> eventChans;
-
-		int ID = sourceNode->getNodeId();
-
-		for (int n = 0; n < sourceNode->settings.eventChannelIds.size(); n++)
-		{
-
-			Channel newChannel;
-
-			newChannel.nodeId = ID;
-			newChannel.chan = sourceNode->settings.eventChannelIds[n];
-			newChannel.name = sourceNode->settings.eventChannelNames[n];
-			newChannel.isRecording = true;
-			newChannel.file = 0;
-
-			std::pair<int, Channel> newPair (newChannel.chan, newChannel);
-
-			eventChans.insert(newPair);
-
-		}
-
-		std::pair<int, std::map<int, Channel> > newPair (ID, eventChans);
-
-		eventChannels.insert(newPair);
-
-	}
-
-}
-
-void RecordNode::createNewDirectory()
-{
-	std::cout << "Creating new directory." << std::endl;
-
-	Time calendar = Time::getCurrentTime();
-
-	Array<int> t;
-	t.add(calendar.getYear()-2000);
-	t.add(calendar.getMonth()+1); // January = 0
-	t.add(calendar.getDayOfMonth());
-	t.add(calendar.getHours());
-	t.add(calendar.getMinutes());
-	t.add(calendar.getSeconds());
-
-	String filename = "";
-	
-	for (int n = 0; n < t.size(); n++)
-	{
-		if (t[n] < 10)
-			filename += "0";
-
-		filename += t[n];
-
-		if (n == 2)
-			filename += "_";
-		else if (n < 5)
-			filename += "-";
-	}
-
-	rootFolder = File(dataDirectory.getFullPathName() + File::separator + filename);
-
-}
-
-
-void RecordNode::setParameter (int parameterIndex, float newValue)
-{
-
-	// 0 = stop recording
-	// 1 = start recording
-	// 2 = toggle individual channel (0.0f = OFF, anything else = ON)
-
- 	if (parameterIndex == 1) {
-
-		isRecording = true;
-		std::cout << "START RECORDING." << std::endl;
-
- 		if (!rootFolder.exists())
- 			rootFolder.createDirectory();
-
-		// create / open necessary files
-		for (int i = 0; i < continuousChannels.size(); i++)
-		{
-			if (continuousChannels[i].isRecording)
-			{
-				std::cout << "OPENING FILE: " << continuousChannels[i].filename << std::endl;
-
-				File f = File(continuousChannels[i].filename);
-				bool fileExists = false;
-
-				if (f.exists())
-				{
-					fileExists = true;
-				}
-
-
-				continuousChannels[i].file = fopen(continuousChannels[i].filename.toUTF8(), "a");
-
-				if (!fileExists)
-				{
-					// create header (needs more details, obviously)
-					String header = "THIS IS A HEADER.";
-					fwrite(header.toUTF8(), 1, header.getNumBytesAsUTF8(), continuousChannels[i].file);
-				}
-
-			}
-		}
- 		
-
- 	} else if (parameterIndex == 0) {
-
-		
-		std::cout << "STOP RECORDING." << std::endl;
-
-		if (isRecording) {
-			// close necessary files
-
-			signalFilesShouldClose = true;
-
-			
-		}
-
-		isRecording = false;
-
- 		
- 	} else if (parameterIndex == 2) {
-
-		if (isProcessing) {
-
-			std::cout << "Toggling channel " << currentChannel << std::endl;
-
-	 		if (newValue == 0.0f) {
-	 			continuousChannels[currentChannel].isRecording = false;
-
-	 			if (isRecording) {
-	 				std::cout << "CLOSING FILE: " << continuousChannels[currentChannel].filename << std::endl;
-	 				fclose(continuousChannels[currentChannel].file);
-	 			}
-
-	 		}
-	 		else {
-	 			continuousChannels[currentChannel].isRecording = true;
-
-	 			if (isRecording) {
-	 				std::cout << "OPENING FILE: " << continuousChannels[currentChannel].filename << std::endl;
-	 				continuousChannels[currentChannel].file = 
-	 					fopen(continuousChannels[currentChannel].filename.toUTF8(), "a");
-	 			}
-	 		}
-		}
- 	}
-}
-
-void RecordNode::closeAllFiles()
-{
-
-	for (int i = 0; i < continuousChannels.size(); i++)
-	{
-		if (continuousChannels[i].isRecording)
-		{
-			std::cout << "CLOSING FILE: " << continuousChannels[i].filename << std::endl;
-			fclose(continuousChannels[i].file);
-		}
-	}
-}
-
-bool RecordNode::enable()
-{
-	isProcessing = true;
-	return true;
-}
-
-
-bool RecordNode::disable() 
-{	
-	// close files if necessary
-	setParameter(0, 10.0f);
-
-	isProcessing = false;
-
-	return true;
-}
-
-float RecordNode::getFreeSpace()
-{
-	return 1.0f - float(dataDirectory.getBytesFreeOnVolume())/float(dataDirectory.getVolumeTotalSize());
-}
-
-void RecordNode::writeContinuousBuffer(float* data, int nSamples, int channel)
-{
-
-	// scale the data appropriately -- currently just getting it into the right
-	// range; actually need to take into account the gain of each channel
-	for (int n = 0; n < nSamples; n++)
-	{
-		*(continuousDataFloatBuffer+n) = *(data+n) / 10000.0f; 
-	}
-
-	// find file and write samples to disk
-
-	AudioDataConverters::convertFloatToInt16BE(continuousDataFloatBuffer, continuousDataIntegerBuffer, nSamples);
-
-	//int16 samps = nSamples;
-
-	fwrite(&timestamp,							// ptr
-			   8,   							// size of each element
-			   1, 		  						// count 
-			   continuousChannels[channel].file);   // ptr to FILE object
-
-	fwrite(&nSamples,								// ptr
-			   sizeof(nSamples),   				// size of each element
-			   1, 		  						// count 
-			   continuousChannels[channel].file);   // ptr to FILE object
-
-	int n = fwrite(continuousDataIntegerBuffer,		// ptr
-			   2,			     					// size of each element
-			   nSamples, 		  					// count 
-			   continuousChannels[channel].file);   // ptr to FILE object
-	// n must equal "count", otherwise there was an error
-}
- 
-void RecordNode::writeEventBuffer(MidiMessage& event, int node, int channel)
-{
-	// find file and write samples to disk
-
-}
-
-void RecordNode::process(AudioSampleBuffer &buffer, 
-                            MidiBuffer &midiMessages,
-                            int& nSamples)
-{
-
-	//std::cout << "Record node processing block." << std::endl;
-	//std::cout << "Num channels: " << buffer.getNumChannels() << std::endl;
-
-
-	if (isRecording) {
-
-		timestamp = timer.getHighResolutionTicks();
-
-		// WHY IS THIS AFFECTING THE LFP DISPLAY?
-		//buffer.applyGain(0, nSamples, 5.2438f);
-
-		// cycle through events -- extract the samples per channel
-		// NOT YET IMPLEMENTED
-
-		// cycle through buffer channels
-		for (int i = 0; i < buffer.getNumChannels(); i++)
-		{
-
-			if (continuousChannels[i].isRecording)
-			{
-				// write buffer to disk!
-				writeContinuousBuffer(buffer.getSampleData(i),
-									  nSamples,
-									  i);
-				
-				//std::cout << "Record channel " << i << std::endl;
-			}
-				
-
-		}
-
-		return;
-
-	}
-
-	// this is intended to prevent parameter changes from closing files
-	// before recording stops
-	if (signalFilesShouldClose)
-	{
-		closeAllFiles();
-		signalFilesShouldClose = false;
-	}
-
-}
+/*
+    ------------------------------------------------------------------
+
+    This file is part of the Open Ephys GUI
+    Copyright (C) 2012 Open Ephys
+
+    ------------------------------------------------------------------
+
+    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 3 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, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#include "RecordNode.h"
+#include "ProcessorGraph.h"
+
+RecordNode::RecordNode()
+	: GenericProcessor("Record Node"), isRecording(false), isProcessing(false),
+		timestamp(0), signalFilesShouldClose(false)
+{
+
+	
+	continuousDataIntegerBuffer = new int16[10000];
+	continuousDataFloatBuffer = new float[10000];
+	signalFilesShouldClose = false;
+
+	settings.numInputs = 128;
+	settings.numOutputs = 0;
+
+	// 128 inputs, 0 outputs
+	setPlayConfigDetails(getNumInputs(),getNumOutputs(),44100.0,128);
+
+}
+
+
+RecordNode::~RecordNode() {
+
+}
+
+void RecordNode::setChannel(int id, int chan)
+{
+
+	std::cout << "Record node setting channel." << std::endl;
+
+	for (int i = 0; i < continuousChannels.size(); i++)
+	{
+
+		if (continuousChannels[i].nodeId == id &&
+			continuousChannels[i].chan == chan)
+		{
+			std::cout << "Found channel " << i << std::endl;
+			setCurrentChannel(i);
+			break;
+		}
+
+	}
+}
+
+void RecordNode::setChannelStatus(int chan, bool status)
+{
+
+	std::cout << "Setting channel status!" << std::endl;
+	setCurrentChannel(chan);
+
+	if (status)
+		setParameter(2, 1.0f);
+	else
+		setParameter(2, 0.0f);
+
+}
+
+// void RecordNode::enableCurrentChannel(bool state)
+// {
+// 	continuousChannels[nextAvailableChannel].isRecording = state;
+// }
+
+void RecordNode::resetConnections()
+{
+	//std::cout << "Resetting connections" << std::endl;
+	nextAvailableChannel = 0;
+	wasConnected = false;
+
+	continuousChannels.clear();
+	eventChannels.clear();
+}
+
+void RecordNode::filenameComponentChanged(FilenameComponent* fnc)
+{
+
+	std::cout << "Got a new file" << std::endl;
+	dataDirectory = fnc->getCurrentFile();
+	std::cout << "File name: " << dataDirectory.getFullPathName();
+	if (dataDirectory.isDirectory())
+		std::cout << " is a directory." << std::endl;
+	else
+		std::cout << " is NOT a directory." << std::endl;
+
+	createNewDirectory();
+
+}
+
+
+void RecordNode::addInputChannel(GenericProcessor* sourceNode, int chan)
+{
+
+	if (chan != getProcessorGraph()->midiChannelIndex)
+	{
+        
+        setPlayConfigDetails(getNextChannel(false)+1,0,44100.0,128);
+        
+		Channel newChannel;
+
+		std::cout << "Record node adding channel." << std::endl;
+
+		newChannel.nodeId = sourceNode->getNodeId();
+		newChannel.chan = chan;
+		newChannel.name = sourceNode->getOutputChannelName(chan);
+		newChannel.isRecording = sourceNode->recordStatus(chan);
+
+		String filename = rootFolder.getFullPathName();
+		filename += "/";
+		filename += newChannel.nodeId;
+		filename += "_";
+		filename += newChannel.name;
+		filename += ".continuous";
+
+		newChannel.filename = filename;
+		newChannel.file = 0; 
+
+		if (newChannel.isRecording)
+			std::cout << "  This channel will be recorded." << std::endl;
+		else 
+			std::cout << "  This channel will NOT be recorded." << std::endl;
+	
+		std::cout << "adding channel " << getNextChannel(false) << std::endl;
+
+		std::pair<int, Channel> newPair (getNextChannel(false), newChannel);
+
+		//std::cout << "adding channel " << getNextChannel(false) << std::endl;
+
+		continuousChannels.insert(newPair);
+
+		
+	} else {
+
+		std::map<int, Channel> eventChans;
+
+		int ID = sourceNode->getNodeId();
+
+		for (int n = 0; n < sourceNode->settings.eventChannelIds.size(); n++)
+		{
+
+			Channel newChannel;
+
+			newChannel.nodeId = ID;
+			newChannel.chan = sourceNode->settings.eventChannelIds[n];
+			newChannel.name = sourceNode->settings.eventChannelNames[n];
+			newChannel.isRecording = true;
+			newChannel.file = 0;
+
+			std::pair<int, Channel> newPair (newChannel.chan, newChannel);
+
+			eventChans.insert(newPair);
+
+		}
+
+		std::pair<int, std::map<int, Channel> > newPair (ID, eventChans);
+
+		eventChannels.insert(newPair);
+
+	}
+
+}
+
+void RecordNode::createNewDirectory()
+{
+	std::cout << "Creating new directory." << std::endl;
+
+	Time calendar = Time::getCurrentTime();
+
+	Array<int> t;
+	t.add(calendar.getYear()-2000);
+	t.add(calendar.getMonth()+1); // January = 0
+	t.add(calendar.getDayOfMonth());
+	t.add(calendar.getHours());
+	t.add(calendar.getMinutes());
+	t.add(calendar.getSeconds());
+
+	String filename = "";
+	
+	for (int n = 0; n < t.size(); n++)
+	{
+		if (t[n] < 10)
+			filename += "0";
+
+		filename += t[n];
+
+		if (n == 2)
+			filename += "_";
+		else if (n < 5)
+			filename += "-";
+	}
+
+	rootFolder = File(dataDirectory.getFullPathName() + File::separator + filename);
+
+}
+
+
+void RecordNode::setParameter (int parameterIndex, float newValue)
+{
+
+	// 0 = stop recording
+	// 1 = start recording
+	// 2 = toggle individual channel (0.0f = OFF, anything else = ON)
+
+ 	if (parameterIndex == 1) {
+
+		isRecording = true;
+		std::cout << "START RECORDING." << std::endl;
+
+ 		if (!rootFolder.exists())
+ 			rootFolder.createDirectory();
+
+		// create / open necessary files
+		for (int i = 0; i < continuousChannels.size(); i++)
+		{
+			if (continuousChannels[i].isRecording)
+			{
+				std::cout << "OPENING FILE: " << continuousChannels[i].filename << std::endl;
+
+				File f = File(continuousChannels[i].filename);
+
+				continuousChannels[i].file = fopen(continuousChannels[i].filename.toUTF8(), "a+b");
+
+				if (!f.exists())
+				{
+					// create header (needs more details, obviously)
+					String header = "THIS IS A HEADER.";
+					fwrite(header.toUTF8(), 1, header.getNumBytesAsUTF8(), continuousChannels[i].file);
+				}
+
+			}
+		}
+ 		
+
+ 	} else if (parameterIndex == 0) {
+
+		
+		std::cout << "STOP RECORDING." << std::endl;
+
+		if (isRecording) {
+			// close necessary files
+
+			signalFilesShouldClose = true;
+			
+		}
+
+		isRecording = false;
+
+ 		
+ 	} else if (parameterIndex == 2) {
+
+		if (isProcessing) {
+
+			std::cout << "Toggling channel " << currentChannel << std::endl;
+
+	 		if (newValue == 0.0f) {
+	 			continuousChannels[currentChannel].isRecording = false;
+
+	 			if (isRecording) {
+	 				std::cout << "CLOSING FILE: " << continuousChannels[currentChannel].filename << std::endl;
+	 				fclose(continuousChannels[currentChannel].file);
+	 			}
+
+	 		}
+	 		else {
+	 			continuousChannels[currentChannel].isRecording = true;
+
+	 			if (isRecording) {
+	 				std::cout << "OPENING FILE: " << continuousChannels[currentChannel].filename << std::endl;
+	 				continuousChannels[currentChannel].file = 
+	 					fopen(continuousChannels[currentChannel].filename.toUTF8(), "a+b");
+	 			}
+	 		}
+		}
+ 	}
+}
+
+void RecordNode::closeAllFiles()
+{
+
+	for (int i = 0; i < continuousChannels.size(); i++)
+	{
+		if (continuousChannels[i].isRecording)
+		{
+			std::cout << "CLOSING FILE: " << continuousChannels[i].filename << std::endl;
+			fclose(continuousChannels[i].file);
+		}
+	}
+}
+
+bool RecordNode::enable()
+{
+	isProcessing = true;
+	return true;
+}
+
+
+bool RecordNode::disable() 
+{	
+	// close files if necessary
+	setParameter(0, 10.0f);
+
+	isProcessing = false;
+
+	return true;
+}
+
+float RecordNode::getFreeSpace()
+{
+	return 1.0f - float(dataDirectory.getBytesFreeOnVolume())/float(dataDirectory.getVolumeTotalSize());
+}
+
+void RecordNode::writeContinuousBuffer(float* data, int nSamples, int channel)
+{
+
+	// scale the data appropriately -- currently just getting it into the right
+	// range; actually need to take into account the gain of each channel
+	for (int n = 0; n < nSamples; n++)
+	{
+		*(continuousDataFloatBuffer+n) = *(data+n) / 10000.0f; 
+	}
+
+	// find file and write samples to disk
+
+	AudioDataConverters::convertFloatToInt16BE(continuousDataFloatBuffer, continuousDataIntegerBuffer, nSamples);
+
+	//int16 samps = nSamples;
+
+	fwrite(&timestamp,							// ptr
+			   8,   							// size of each element
+			   1, 		  						// count 
+			   continuousChannels[channel].file);   // ptr to FILE object
+
+	fwrite(&nSamples,								// ptr
+			   sizeof(nSamples),   				// size of each element
+			   1, 		  						// count 
+			   continuousChannels[channel].file);   // ptr to FILE object
+
+	int n = fwrite(continuousDataIntegerBuffer,		// ptr
+			   2,			     					// size of each element
+			   nSamples, 		  					// count 
+			   continuousChannels[channel].file);   // ptr to FILE object
+	// n must equal "count", otherwise there was an error
+}
+ 
+void RecordNode::writeEventBuffer(MidiMessage& event, int node, int channel)
+{
+	// find file and write samples to disk
+
+}
+
+void RecordNode::process(AudioSampleBuffer &buffer, 
+                            MidiBuffer &midiMessages,
+                            int& nSamples)
+{
+
+	//std::cout << "Record node processing block." << std::endl;
+	//std::cout << "Num channels: " << buffer.getNumChannels() << std::endl;
+
+
+	if (isRecording) {
+
+		timestamp = timer.getHighResolutionTicks();
+
+		// WHY IS THIS AFFECTING THE LFP DISPLAY?
+		//buffer.applyGain(0, nSamples, 5.2438f);
+
+		// cycle through events -- extract the samples per channel
+		// NOT YET IMPLEMENTED
+
+		// cycle through buffer channels
+		for (int i = 0; i < buffer.getNumChannels(); i++)
+		{
+
+			if (continuousChannels[i].isRecording)
+			{
+				// write buffer to disk!
+				writeContinuousBuffer(buffer.getSampleData(i),
+									  nSamples,
+									  i);
+				
+				//std::cout << "Record channel " << i << std::endl;
+			}
+				
+
+		}
+
+		return;
+
+	}
+
+	// this is intended to prevent parameter changes from closing files
+	// before recording stops
+	if (signalFilesShouldClose)
+	{
+		closeAllFiles();
+		signalFilesShouldClose = false;
+	}
+
+}
diff --git a/Source/Processors/RecordNode.h b/Source/Processors/RecordNode.h
index d6af23e3da4d4c3d97e8275a7d4be6d64b997099..0aee3a23dec4c40b14f1343ff91da79aac391da3 100755
--- a/Source/Processors/RecordNode.h
+++ b/Source/Processors/RecordNode.h
@@ -119,11 +119,6 @@ private:
   */
   File rootFolder;
 
-  /** Determines whether a new rootFolder is created when recording
-      begins. 
-  */
-  bool newDataFolder;
-
   /** Holds data that has been converted from float to int16 before
       saving. 
   */
diff --git a/Source/Processors/SourceNode.cpp b/Source/Processors/SourceNode.cpp
index aea3f600052952f200d053a7524bb1cae6f44106..f4b6ca6c395fa331d0cf9b86cff9c33f9a6a9950 100755
--- a/Source/Processors/SourceNode.cpp
+++ b/Source/Processors/SourceNode.cpp
@@ -315,8 +315,6 @@ void SourceNode::process(AudioSampleBuffer &buffer,
 	 	}
 	 }
 
-	 
-
 }