commit 7e2001bc4d9b4fca65b2ffcc7201d549fb35213c Author: Paddy Xu Date: Wed Apr 12 17:58:52 2017 +0300 WIP diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..7910f21 --- /dev/null +++ b/.gitignore @@ -0,0 +1,290 @@ +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. +## +## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore + +# User-specific files +*.suo +*.user +*.userosscache +*.sln.docstates + +# User-specific files (MonoDevelop/Xamarin Studio) +*.userprefs + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +bld/ +[Bb]in/ +[Oo]bj/ +[Ll]og/ + +# Visual Studio 2015 cache/options directory +.vs/ +# Uncomment if you have tasks that create the project's static files in wwwroot +#wwwroot/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +# NUNIT +*.VisualState.xml +TestResult.xml + +# Build Results of an ATL Project +[Dd]ebugPS/ +[Rr]eleasePS/ +dlldata.c + +# .NET Core +project.lock.json +project.fragment.lock.json +artifacts/ +**/Properties/launchSettings.json + +*_i.c +*_p.c +*_i.h +*.ilk +*.meta +*.obj +*.pch +*.pdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*.log +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc + +# Chutzpah Test files +_Chutzpah* + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opendb +*.opensdf +*.sdf +*.cachefile +*.VC.db +*.VC.VC.opendb + +# Visual Studio profiler +*.psess +*.vsp +*.vspx +*.sap + +# TFS 2012 Local Workspace +$tf/ + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper +*.DotSettings.user + +# JustCode is a .NET coding add-in +.JustCode + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# Visual Studio code coverage results +*.coverage +*.coveragexml + +# NCrunch +_NCrunch_* +.*crunch*.local.xml +nCrunchTemp_* + +# MightyMoose +*.mm.* +AutoTest.Net/ + +# Web workbench (sass) +.sass-cache/ + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.[Pp]ublish.xml +*.azurePubxml +# TODO: Comment the next line if you want to checkin your web deploy settings +# but database connection strings (with potential passwords) will be unencrypted +*.pubxml +*.publishproj + +# Microsoft Azure Web App publish settings. Comment the next line if you want to +# checkin your Azure Web App publish settings, but sensitive information contained +# in these scripts will be unencrypted +PublishScripts/ + +# NuGet Packages +*.nupkg +# The packages folder can be ignored because of Package Restore +**/packages/* +# except build/, which is used as an MSBuild target. +!**/packages/build/ +# Uncomment if necessary however generally it will be regenerated when needed +#!**/packages/repositories.config +# NuGet v3's project.json files produces more ignorable files +*.nuget.props +*.nuget.targets + +# Microsoft Azure Build Output +csx/ +*.build.csdef + +# Microsoft Azure Emulator +ecf/ +rcf/ + +# Windows Store app package directories and files +AppPackages/ +BundleArtifacts/ +Package.StoreAssociation.xml +_pkginfo.txt + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!*.[Cc]ache/ + +# Others +ClientBin/ +~$* +*~ +*.dbmdl +*.dbproj.schemaview +*.jfm +*.pfx +*.publishsettings +orleans.codegen.cs + +# Since there are multiple workflows, uncomment next line to ignore bower_components +# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) +#bower_components/ + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file +# to a newer Visual Studio version. Backup files are not needed, +# because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm + +# SQL Server files +*.mdf +*.ldf +*.ndf + +# Business Intelligence projects +*.rdl.data +*.bim.layout +*.bim_*.settings + +# Microsoft Fakes +FakesAssemblies/ + +# GhostDoc plugin setting file +*.GhostDoc.xml + +# Node.js Tools for Visual Studio +.ntvs_analysis.dat +node_modules/ + +# Typescript v1 declaration files +typings/ + +# Visual Studio 6 build log +*.plg + +# Visual Studio 6 workspace options file +*.opt + +# Visual Studio 6 auto-generated workspace file (contains which files were open etc.) +*.vbw + +# Visual Studio LightSwitch build output +**/*.HTMLClient/GeneratedArtifacts +**/*.DesktopClient/GeneratedArtifacts +**/*.DesktopClient/ModelManifest.xml +**/*.Server/GeneratedArtifacts +**/*.Server/ModelManifest.xml +_Pvt_Extensions + +# Paket dependency manager +.paket/paket.exe +paket-files/ + +# FAKE - F# Make +.fake/ + +# JetBrains Rider +.idea/ +*.sln.iml + +# CodeRush +.cr/ + +# Python Tools for Visual Studio (PTVS) +__pycache__/ +*.pyc + +# Cake - Uncomment if you are using it +# tools/** +# !tools/packages.config + +# Telerik's JustMock configuration file +*.jmconfig + +# BizTalk build output +*.btp.cs +*.btm.cs +*.odx.cs +*.xsd.cs + +/QuickLook.Plugin.PDFViewer/MoonPdfLib diff --git a/QuickLook.Native.Shell32/QuickLook.Native.Shell32.cpp b/QuickLook.Native.Shell32/QuickLook.Native.Shell32.cpp new file mode 100644 index 0000000..c5fffa8 --- /dev/null +++ b/QuickLook.Native.Shell32/QuickLook.Native.Shell32.cpp @@ -0,0 +1,21 @@ +// dllmain.cpp : Defines the entry point for the DLL application. +#include "stdafx.h" + +#include "Shell32.h" + +#define EXPORT extern "C" __declspec(dllexport) + +EXPORT void SaveCurrentSelection() +{ + Shell32::SaveCurrentSelection(); +} + +EXPORT int GetCurrentSelectionCount() +{ + return Shell32::GetCurrentSelectionCount(); +} + +EXPORT void GetCurrentSelectionBuffer(PWCHAR buffer) +{ + Shell32::GetCurrentSelectionBuffer(buffer); +} diff --git a/QuickLook.Native.Shell32/QuickLook.Native.Shell32.h b/QuickLook.Native.Shell32/QuickLook.Native.Shell32.h new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/QuickLook.Native.Shell32/QuickLook.Native.Shell32.h @@ -0,0 +1 @@ + diff --git a/QuickLook.Native.Shell32/QuickLook.Native.Shell32.vcxproj b/QuickLook.Native.Shell32/QuickLook.Native.Shell32.vcxproj new file mode 100644 index 0000000..52e1db8 --- /dev/null +++ b/QuickLook.Native.Shell32/QuickLook.Native.Shell32.vcxproj @@ -0,0 +1,109 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + 15.0 + {D31EE321-C2B0-4984-B749-736F7DE509F1} + Win32Proj + QuickLookShell32Helper + 10.0.15063.0 + QuickLook.Native.Shell32 + + + + DynamicLibrary + true + v141 + Unicode + + + DynamicLibrary + false + v141 + true + Unicode + + + + + + + + + + + + + + + true + $(SolutionDir)Build\$(Configuration)\ + + + false + $(SolutionDir)Build\$(Configuration)\ + + + + Use + Level3 + Disabled + WIN32;_DEBUG;_WINDOWS;_USRDLL;QUICKLOOKSHELL32HELPER_EXPORTS;%(PreprocessorDefinitions) + + + Windows + + + + + Level3 + Use + Full + true + true + WIN32;NDEBUG;_WINDOWS;_USRDLL;QUICKLOOKSHELL32HELPER_EXPORTS;%(PreprocessorDefinitions) + Speed + + + Windows + true + true + + + + + + + + + + + + + false + + + false + + + + + + + Create + Create + + + + + + \ No newline at end of file diff --git a/QuickLook.Native.Shell32/QuickLook.Shell32Helper.vcxproj.filters b/QuickLook.Native.Shell32/QuickLook.Shell32Helper.vcxproj.filters new file mode 100644 index 0000000..4a95b94 --- /dev/null +++ b/QuickLook.Native.Shell32/QuickLook.Shell32Helper.vcxproj.filters @@ -0,0 +1,45 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + + + + Header Files + + + Header Files + + + Header Files + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + \ No newline at end of file diff --git a/QuickLook.Native.Shell32/Shell32.cpp b/QuickLook.Native.Shell32/Shell32.cpp new file mode 100644 index 0000000..3e69893 --- /dev/null +++ b/QuickLook.Native.Shell32/Shell32.cpp @@ -0,0 +1,220 @@ +#include "stdafx.h" + +#include "Shell32.h" + +using namespace std; + +vector Shell32::vector_items; + +void Shell32::SaveCurrentSelection() +{ + vector_items.clear(); + + switch (GetFocusedWindowType()) + { + case EXPLORER: + SaveSelectedFromExplorer(); + break; + case DESKTOP: + SaveSelectedFromDesktop(); + break; + default: + break; + } +} + +UINT Shell32::GetCurrentSelectionCount() +{ + return vector_items.size(); +} + +void Shell32::GetCurrentSelectionBuffer(PWCHAR buffer) +{ + PWCHAR pos = buffer; + + for (vector::iterator it = vector_items.begin(); it < vector_items.end(); ++it) + { + int l = it->length(); + wcscpy_s(pos, l + 1, it->c_str()); + + pos += l; + + // overwrite NULL + wcscpy_s(pos++, 2, L"|"); + } + + // remove last "|" + wcscpy_s(pos - 1, 1, L""); +} + +void Shell32::SaveSelectedFromExplorer() { + CoInitialize(nullptr); + + CComPtr psw; + HRESULT ret=psw.CoCreateInstance(CLSID_ShellWindows); + + auto hwndFGW = GetForegroundWindow(); + + auto fFound = FALSE; + + for (int i = 0; !fFound; i++) { + VARIANT vi; + V_VT(&vi) = VT_I4; + V_I4(&vi) = i; + + CComPtr pdisp; + // ReSharper disable once CppSomeObjectMembersMightNotBeInitialized + if (SUCCEEDED(psw->Item(vi, &pdisp))) + { + CComPtr pwba; + if (SUCCEEDED(pdisp->QueryInterface(IID_IWebBrowserApp, reinterpret_cast(&pwba)))) { + HWND hwndWBA; + if (SUCCEEDED(pwba->get_HWND(reinterpret_cast(&hwndWBA))) && hwndWBA == hwndFGW) { + fFound = TRUE; + + CComPtr ppdisp; + if (SUCCEEDED(pwba->get_Document(&ppdisp))) { + CComPtr pshvd; + if (SUCCEEDED(ppdisp->QueryInterface(IID_IShellFolderViewDual2, reinterpret_cast(&pshvd)))) + { + CComPtr pfis; + if (SUCCEEDED(pshvd->SelectedItems(&pfis))) + { + LONG pCount = 0L; + pfis->get_Count(&pCount); + + for (int ii = 0; ii < pCount; ii++) + { + VARIANT vii; + V_VT(&vii) = VT_I4; + V_I4(&vii) = ii; + + CComPtr pfi; + // ReSharper disable once CppSomeObjectMembersMightNotBeInitialized + if (SUCCEEDED(pfis->Item(vii, &pfi))) + { + CComBSTR pbs = SysAllocStringLen(L"", MAX_PATH); + pfi->get_Path(&pbs); + + wstring ws = wstring(pbs); + ws.shrink_to_fit(); + + vector_items.push_back(ws); + } + } + } + } + } + } + } + } + } +} + +CComQIPtr Shell32::AttachDesktopShellWindow() +{ + CoInitialize(nullptr); + + CComPtr psw; + CComQIPtr pdispOut; + + if (SUCCEEDED(psw.CoCreateInstance(CLSID_ShellWindows))) + { + VARIANT pvarLoc = { VT_EMPTY }; + long phwnd; + psw->FindWindowSW(&pvarLoc, &pvarLoc, SWC_DESKTOP, &phwnd, SWFO_NEEDDISPATCH, reinterpret_cast(&pdispOut)); + } + return pdispOut; +} + +void Shell32::SaveSelectedFromDesktop() +{ + auto pWebBrowser2 = AttachDesktopShellWindow(); + + if (!pWebBrowser2) + return; + + CComQIPtr psp(pWebBrowser2); + CComPtr psb; + CComPtr psv; + CComPtr pfv; + CComPtr ppf2; + + if (!psp) return; + + if (SUCCEEDED(psp->QueryService(SID_STopLevelBrowser, IID_IShellBrowser, reinterpret_cast(&psb)))) + { + if (SUCCEEDED(psb->QueryActiveShellView(&psv))) + { + if (SUCCEEDED(psv->QueryInterface(IID_IFolderView, reinterpret_cast(&pfv)))) + { + if (SUCCEEDED(pfv->GetFolder(IID_IPersistFolder2, reinterpret_cast(&ppf2)))) + { + LPITEMIDLIST pidlFolder; + if (SUCCEEDED(ppf2->GetCurFolder(&pidlFolder))) + { + CComPtr dao; + if (SUCCEEDED(psv->GetItemObject(SVGIO_SELECTION, IID_IDataObject, reinterpret_cast(&dao)))) + vectorFromDataObject(dao); + } + CoTaskMemFree(pidlFolder); + } + } + } + } +} + +void Shell32::vectorFromDataObject(CComPtr dao) { + FORMATETC formatetc; + STGMEDIUM medium; + + formatetc.cfFormat = CF_HDROP; + formatetc.ptd = nullptr; + formatetc.dwAspect = DVASPECT_CONTENT; + formatetc.lindex = -1; + formatetc.tymed = TYMED_HGLOBAL; + + medium.tymed = TYMED_HGLOBAL; + + if (SUCCEEDED(dao->GetData(&formatetc, &medium))) + { + int n = DragQueryFile(HDROP(medium.hGlobal), 0xFFFFFFFF, nullptr, 0); + + for (int i = 0; i < n; i++) + { + WCHAR buffer[MAX_PATH]; + DragQueryFile(HDROP(medium.hGlobal), i, buffer, MAX_PATH - 1); + + wstring ws = wstring(buffer); + ws.shrink_to_fit(); + + vector_items.push_back(ws); + } + } +} + +Shell32::FocusedWindowType Shell32::GetFocusedWindowType() +{ + auto type = INVALID; + + auto hwndfg = GetForegroundWindow(); + + auto classBuffer = new WCHAR[MAX_PATH]; + if (SUCCEEDED(GetClassName(hwndfg, classBuffer, MAX_PATH))) + { + if (wcscmp(classBuffer, L"WorkerW") == 0 || wcscmp(classBuffer, L"Progman") == 0) + { + if (FindWindowEx(hwndfg, nullptr, L"SHELLDLL_DefView", nullptr) != nullptr) + { + type = DESKTOP; + } + } + else if (wcscmp(classBuffer, L"ExploreWClass") == 0 || wcscmp(classBuffer, L"CabinetWClass") == 0) + { + type = EXPLORER; + } + } + delete[] classBuffer; + + return type; +} diff --git a/QuickLook.Native.Shell32/Shell32.h b/QuickLook.Native.Shell32/Shell32.h new file mode 100644 index 0000000..a278016 --- /dev/null +++ b/QuickLook.Native.Shell32/Shell32.h @@ -0,0 +1,29 @@ +#pragma once + +#include "stdafx.h" + +class Shell32 +{ +public: + static void SaveCurrentSelection(); + static UINT GetCurrentSelectionCount(); + static void GetCurrentSelectionBuffer(PWCHAR buffer); + +private: + enum FocusedWindowType + { + INVALID, + DESKTOP, + EXPLORER, + }; + + static std::vector vector_items; + + static void SaveSelectedFromDesktop(); + static void SaveSelectedFromExplorer(); + + static FocusedWindowType GetFocusedWindowType(); + static CComQIPtr AttachDesktopShellWindow(); + static void vectorFromDataObject(CComPtr dao); +}; + diff --git a/QuickLook.Native.Shell32/dllmain.cpp b/QuickLook.Native.Shell32/dllmain.cpp new file mode 100644 index 0000000..78d8d49 --- /dev/null +++ b/QuickLook.Native.Shell32/dllmain.cpp @@ -0,0 +1,18 @@ +// dllmain.cpp : Defines the entry point for the DLL application. +#include "stdafx.h" +#include "Shell32.h" + +BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) +{ + switch (ul_reason_for_call) + { + case DLL_PROCESS_ATTACH: + case DLL_THREAD_ATTACH: + case DLL_THREAD_DETACH: + case DLL_PROCESS_DETACH: + default: + break; + } + return TRUE; +} + diff --git a/QuickLook.Native.Shell32/stdafx.cpp b/QuickLook.Native.Shell32/stdafx.cpp new file mode 100644 index 0000000..2c536e2 --- /dev/null +++ b/QuickLook.Native.Shell32/stdafx.cpp @@ -0,0 +1,8 @@ +// stdafx.cpp : source file that includes just the standard includes +// QuickLook.Shell32Helper.pch will be the pre-compiled header +// stdafx.obj will contain the pre-compiled type information + +#include "stdafx.h" + +// TODO: reference any additional headers you need in STDAFX.H +// and not in this file diff --git a/QuickLook.Native.Shell32/stdafx.h b/QuickLook.Native.Shell32/stdafx.h new file mode 100644 index 0000000..d32e163 --- /dev/null +++ b/QuickLook.Native.Shell32/stdafx.h @@ -0,0 +1,23 @@ +// stdafx.h : include file for standard system include files, +// or project specific include files that are used frequently, but +// are changed infrequently +// + +#pragma once + +#include "targetver.h" + +#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers +// Windows Header Files: +#include + + + +// TODO: reference additional headers your program requires here +#include +#include +#include +#include +#include +#include +#include diff --git a/QuickLook.Native.Shell32/targetver.h b/QuickLook.Native.Shell32/targetver.h new file mode 100644 index 0000000..87c0086 --- /dev/null +++ b/QuickLook.Native.Shell32/targetver.h @@ -0,0 +1,8 @@ +#pragma once + +// Including SDKDDKVer.h defines the highest available Windows platform. + +// If you wish to build your application for a previous Windows platform, include WinSDKVer.h and +// set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h. + +#include diff --git a/QuickLook.Plugin.PDFViewer/Class1.cs b/QuickLook.Plugin.PDFViewer/Class1.cs new file mode 100644 index 0000000..0223c6e --- /dev/null +++ b/QuickLook.Plugin.PDFViewer/Class1.cs @@ -0,0 +1,52 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Media; +using System.Windows.Threading; +using MoonPdfLib; + +namespace QuickLook.Plugin.PDFViewer +{ + public class Class1:IViewer + { + public bool CanView(string path, byte[] sample) + { + if (String.IsNullOrEmpty(path)) + return false; + + if (Path.GetExtension(path).ToLower() == ".pdf") + return true; + + if (Encoding.ASCII.GetString(sample.Take(4).ToArray()) == "%PDF") + return true; + + return false; + } + + public void View(string path, ViewContentContainer container) + { + MoonPdfPanel pdfPanel = new MoonPdfPanel + { + ViewType = ViewType.SinglePage, + PageRowDisplay = PageRowDisplayType.ContinuousPageRows, + PageMargin = new System.Windows.Thickness(0, 2, 4, 2), + Background = new SolidColorBrush(Colors.LightGray) + }; + + container.SetContent(pdfPanel); + + Task.Delay(200).ContinueWith(t => container.Dispatcher.Invoke(() => pdfPanel.OpenFile(path))); + + Task.Delay(400).ContinueWith(t => container.Dispatcher.Invoke(() => pdfPanel.ZoomToWidth())); + } + + public void Close() + { + return; + } + } +} diff --git a/QuickLook.Plugin.PDFViewer/Properties/AssemblyInfo.cs b/QuickLook.Plugin.PDFViewer/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..c979bc0 --- /dev/null +++ b/QuickLook.Plugin.PDFViewer/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("QuickLook.Plugin.PDFViewer")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("QuickLook.Plugin.PDFViewer")] +[assembly: AssemblyCopyright("Copyright © 2017")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("a82ac69c-edf5-4f0d-8cbd-8e5e3c06e64d")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/QuickLook.Plugin.PDFViewer/QuickLook.Plugin.PDFViewer.csproj b/QuickLook.Plugin.PDFViewer/QuickLook.Plugin.PDFViewer.csproj new file mode 100644 index 0000000..c8d6d66 --- /dev/null +++ b/QuickLook.Plugin.PDFViewer/QuickLook.Plugin.PDFViewer.csproj @@ -0,0 +1,73 @@ + + + + + Debug + AnyCPU + {A82AC69C-EDF5-4F0D-8CBD-8E5E3C06E64D} + Library + Properties + QuickLook.Plugin.PDFViewer + QuickLook.Plugin.PDFViewer + v4.5.2 + 512 + + + true + full + false + ..\Build\Debug\Plugins\PDFViewer\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + ..\Build\Release\Plugins\PDFViewer\ + TRACE + prompt + 4 + + + + ..\packages\MoonPdfLib-x86.0.3.0\lib\MoonPdfLib.dll + + + ..\packages\MoonPdfLib-x86.0.3.0\lib\MouseKeyboardActivityMonitor.dll + + + + + + + + + + + + + + + + + + + + + {8b4a9ce5-67b5-4a94-81cb-3771f688fdeb} + QuickLook + False + + + + + + + + + Always + + + + \ No newline at end of file diff --git a/QuickLook.Plugin.PDFViewer/QuickLook.Plugin.PDFViewer.csproj.DotSettings b/QuickLook.Plugin.PDFViewer/QuickLook.Plugin.PDFViewer.csproj.DotSettings new file mode 100644 index 0000000..b0c88b5 --- /dev/null +++ b/QuickLook.Plugin.PDFViewer/QuickLook.Plugin.PDFViewer.csproj.DotSettings @@ -0,0 +1,2 @@ + + True \ No newline at end of file diff --git a/QuickLook.Plugin.PDFViewer/libmupdf.dll b/QuickLook.Plugin.PDFViewer/libmupdf.dll new file mode 100644 index 0000000..e28ff73 Binary files /dev/null and b/QuickLook.Plugin.PDFViewer/libmupdf.dll differ diff --git a/QuickLook.Plugin.PDFViewer/packages.config b/QuickLook.Plugin.PDFViewer/packages.config new file mode 100644 index 0000000..2bc521b --- /dev/null +++ b/QuickLook.Plugin.PDFViewer/packages.config @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/QuickLook.sln b/QuickLook.sln new file mode 100644 index 0000000..3de82d4 --- /dev/null +++ b/QuickLook.sln @@ -0,0 +1,63 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.26403.3 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "QuickLook", "QuickLook\QuickLook.csproj", "{8B4A9CE5-67B5-4A94-81CB-3771F688FDEB}" + ProjectSection(ProjectDependencies) = postProject + {D31EE321-C2B0-4984-B749-736F7DE509F1} = {D31EE321-C2B0-4984-B749-736F7DE509F1} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "QuickLook.Native.Shell32", "QuickLook.Native.Shell32\QuickLook.Native.Shell32.vcxproj", "{D31EE321-C2B0-4984-B749-736F7DE509F1}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "QuickLook.Plugin.PDFViewer", "QuickLook.Plugin.PDFViewer\QuickLook.Plugin.PDFViewer.csproj", "{A82AC69C-EDF5-4F0D-8CBD-8E5E3C06E64D}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|Any CPU = Release|Any CPU + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {8B4A9CE5-67B5-4A94-81CB-3771F688FDEB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {8B4A9CE5-67B5-4A94-81CB-3771F688FDEB}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8B4A9CE5-67B5-4A94-81CB-3771F688FDEB}.Debug|x64.ActiveCfg = Debug|Any CPU + {8B4A9CE5-67B5-4A94-81CB-3771F688FDEB}.Debug|x64.Build.0 = Debug|Any CPU + {8B4A9CE5-67B5-4A94-81CB-3771F688FDEB}.Debug|x86.ActiveCfg = Debug|Any CPU + {8B4A9CE5-67B5-4A94-81CB-3771F688FDEB}.Debug|x86.Build.0 = Debug|Any CPU + {8B4A9CE5-67B5-4A94-81CB-3771F688FDEB}.Release|Any CPU.ActiveCfg = Release|Any CPU + {8B4A9CE5-67B5-4A94-81CB-3771F688FDEB}.Release|Any CPU.Build.0 = Release|Any CPU + {8B4A9CE5-67B5-4A94-81CB-3771F688FDEB}.Release|x64.ActiveCfg = Release|Any CPU + {8B4A9CE5-67B5-4A94-81CB-3771F688FDEB}.Release|x64.Build.0 = Release|Any CPU + {8B4A9CE5-67B5-4A94-81CB-3771F688FDEB}.Release|x86.ActiveCfg = Release|Any CPU + {8B4A9CE5-67B5-4A94-81CB-3771F688FDEB}.Release|x86.Build.0 = Release|Any CPU + {D31EE321-C2B0-4984-B749-736F7DE509F1}.Debug|Any CPU.ActiveCfg = Debug|Win32 + {D31EE321-C2B0-4984-B749-736F7DE509F1}.Debug|Any CPU.Build.0 = Debug|Win32 + {D31EE321-C2B0-4984-B749-736F7DE509F1}.Debug|x64.ActiveCfg = Debug|Win32 + {D31EE321-C2B0-4984-B749-736F7DE509F1}.Debug|x86.ActiveCfg = Debug|Win32 + {D31EE321-C2B0-4984-B749-736F7DE509F1}.Debug|x86.Build.0 = Debug|Win32 + {D31EE321-C2B0-4984-B749-736F7DE509F1}.Release|Any CPU.ActiveCfg = Release|Win32 + {D31EE321-C2B0-4984-B749-736F7DE509F1}.Release|Any CPU.Build.0 = Release|Win32 + {D31EE321-C2B0-4984-B749-736F7DE509F1}.Release|x64.ActiveCfg = Release|Win32 + {D31EE321-C2B0-4984-B749-736F7DE509F1}.Release|x86.ActiveCfg = Release|Win32 + {D31EE321-C2B0-4984-B749-736F7DE509F1}.Release|x86.Build.0 = Release|Win32 + {A82AC69C-EDF5-4F0D-8CBD-8E5E3C06E64D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A82AC69C-EDF5-4F0D-8CBD-8E5E3C06E64D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A82AC69C-EDF5-4F0D-8CBD-8E5E3C06E64D}.Debug|x64.ActiveCfg = Debug|Any CPU + {A82AC69C-EDF5-4F0D-8CBD-8E5E3C06E64D}.Debug|x64.Build.0 = Debug|Any CPU + {A82AC69C-EDF5-4F0D-8CBD-8E5E3C06E64D}.Debug|x86.ActiveCfg = Debug|Any CPU + {A82AC69C-EDF5-4F0D-8CBD-8E5E3C06E64D}.Debug|x86.Build.0 = Debug|Any CPU + {A82AC69C-EDF5-4F0D-8CBD-8E5E3C06E64D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A82AC69C-EDF5-4F0D-8CBD-8E5E3C06E64D}.Release|Any CPU.Build.0 = Release|Any CPU + {A82AC69C-EDF5-4F0D-8CBD-8E5E3C06E64D}.Release|x64.ActiveCfg = Release|Any CPU + {A82AC69C-EDF5-4F0D-8CBD-8E5E3C06E64D}.Release|x64.Build.0 = Release|Any CPU + {A82AC69C-EDF5-4F0D-8CBD-8E5E3C06E64D}.Release|x86.ActiveCfg = Release|Any CPU + {A82AC69C-EDF5-4F0D-8CBD-8E5E3C06E64D}.Release|x86.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/QuickLook.sln.DotSettings b/QuickLook.sln.DotSettings new file mode 100644 index 0000000..0b7d2d1 --- /dev/null +++ b/QuickLook.sln.DotSettings @@ -0,0 +1,23 @@ + + True + Default: Reformat Code + 0 + 0 + 0 + True + False + False + C:\Users\Paddy\AppData\Local\JetBrains\Transient\ReSharperPlatformVs15\v08_4c97e4a7\SolutionCaches + True + True + True + 04/11/2017 18:22:55 + VS + anonymous + True + [19,13](1024,768) + CSharpBlankLinesPage + -941,-110 + True + False + True \ No newline at end of file diff --git a/QuickLook/App.config b/QuickLook/App.config new file mode 100644 index 0000000..88fa402 --- /dev/null +++ b/QuickLook/App.config @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/QuickLook/App.xaml b/QuickLook/App.xaml new file mode 100644 index 0000000..8f0f19e --- /dev/null +++ b/QuickLook/App.xaml @@ -0,0 +1,9 @@ + + + + + diff --git a/QuickLook/App.xaml.cs b/QuickLook/App.xaml.cs new file mode 100644 index 0000000..7708ba2 --- /dev/null +++ b/QuickLook/App.xaml.cs @@ -0,0 +1,29 @@ +using System; +using System.Collections.Generic; +using System.Configuration; +using System.Data; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Threading.Tasks; +using System.Windows; +using QuickLook.Plugin; +using QuickLook.Utilities; + +namespace QuickLook +{ + /// + /// Interaction logic for App.xaml + /// + public partial class App : Application + { + public static string AppPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); + + private void Application_Startup(object sender, StartupEventArgs e) + { + PluginManager.GetInstance(); + + BackgroundListener.GetInstance(); + } + } +} diff --git a/QuickLook/BackgroundListener.cs b/QuickLook/BackgroundListener.cs new file mode 100644 index 0000000..e1eb04a --- /dev/null +++ b/QuickLook/BackgroundListener.cs @@ -0,0 +1,60 @@ +using System.Text; +using System.Threading; +using System.Windows.Forms; +using QuickLook.Utilities; + +namespace QuickLook +{ + internal class BackgroundListener + { + private static BackgroundListener _instance; + + private GlobalKeyboardHook _hook; + + protected BackgroundListener() + { + InstallHook(HotkeyEventHandler); + } + + private void HotkeyEventHandler(object sender, KeyEventArgs e) + { + string[] paths; + + // communicate with COM in a separate thread + var tCom = new Thread(() => paths = GetCurrentSelection()); + + tCom.Start(); + tCom.Join(); + + var mw = new MainWindow(); + mw.Show(); + } + + private void InstallHook(KeyEventHandler handler) + { + _hook = GlobalKeyboardHook.GetInstance(); + + _hook.HookedKeys.Add(Keys.Space); + + _hook.KeyUp += handler; + } + + private string[] GetCurrentSelection() + { + NativeMethods.QuickLook.SaveCurrentSelection(); + + var n = NativeMethods.QuickLook.GetCurrentSelectionCount(); + + var sb = new StringBuilder(n * 261); // MAX_PATH + NULL = 261 + + NativeMethods.QuickLook.GetCurrentSelectionBuffer(sb); + + return sb.Length == 0 ? new string[0] : sb.ToString().Split('|'); + } + + internal static BackgroundListener GetInstance() + { + return _instance ?? (_instance = new BackgroundListener()); + } + } +} \ No newline at end of file diff --git a/QuickLook/ExtensionMethods/DispatcherExtensions.cs b/QuickLook/ExtensionMethods/DispatcherExtensions.cs new file mode 100644 index 0000000..0b990bf --- /dev/null +++ b/QuickLook/ExtensionMethods/DispatcherExtensions.cs @@ -0,0 +1,30 @@ +using System; +using System.Threading.Tasks; +using System.Windows.Threading; + +namespace QuickLook.ExtensionMethods +{ + internal static class DispatcherExtensions + { + public static void Delay(this Dispatcher disp, int delayMs, + Action action, object parm = null) + { + Task.Delay(delayMs).ContinueWith(t => { disp.Invoke(action, parm); }); + } + + public static void DelayWithPriority(this Dispatcher disp, int delayMs, + Action action, object parm = null, + DispatcherPriority priority = DispatcherPriority.ApplicationIdle) + { + Task.Delay(delayMs).ContinueWith(t => { disp.BeginInvoke(action, priority, parm); }); + } + + public static async Task DelayAsync(this Dispatcher disp, int delayMs, + Action action, object parm = null, + DispatcherPriority priority = DispatcherPriority.ApplicationIdle) + { + await Task.Delay(delayMs); + await disp.BeginInvoke(action, priority, parm); + } + } +} \ No newline at end of file diff --git a/QuickLook/MainWindow.xaml b/QuickLook/MainWindow.xaml new file mode 100644 index 0000000..0f774de --- /dev/null +++ b/QuickLook/MainWindow.xaml @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + +