Merge ImageResizer into master (#1469)

* Import Image Resizer for Windows

* getting code analysis and stylecop hooked in

* upgrading to 4.7.2

* adding copyright

* getting stuff to work

headers and trailing commas

adding braces

updated encoder

* Revert "getting stuff to work"

This reverts commit 5310866120.

* update to .net 4.7.2

* access modifier

* zero errors

* Fixed unit tests not running issue

* Fixed ImageResizer.Test stylecop warning

* Formatted ShellExtensions project with clang-format

* Fixed annotation warnings

* Suppressed 6031 and 26812 warnings for specific lines

* Shifting ImageResizer projects to PowerToys solution (#1054)

* Shifted ImageResizer projects to PowerToys solution: Builds, all tests pass, ImageResizer C# project works independently

* Deleted extra files

* Deleted nuget config file and fixed code analysis paths

* Convert ImageResizer to a PowerToy (#1073)

* Updated vcxproj file with common project references and cpp version flags

* Added module template code to dllmain and updated headers for successful build

* Removed unnecessary include

* Added dll to runner and add fixes to show up in PT Settings

* Added settings file

* Added support for enabling/disabling based on PowerRename codebase

* Fixed missing braces

* Fixed call_custom_action

* Add ImageResizer to msi installer (dev/imageResizer) (#1094)

* Updated vcxproj file with common project references and cpp version flags

* Added module template code to dllmain and updated headers for successful build

* Removed unnecessary include

* Added dll to runner and add fixes to show up in PT Settings

* Added settings file

* Added support for enabling/disabling based on PowerRename codebase

* Fixed solution file configurations

* Removed Any CPU from ImageResizer csprojs

* Renamed registry writing and removed build time registry addition

* Added ImageResizer installation details to msi

* Fixed comment on conditions to close explorer.exe

* Sync dev/imageResizer with master (#1105)

* tweaking language

* adjusting elevated permission verbiage to match Windows

* npm audit fix to update stuff

* slight bump for fabric ui

* Remove unwanted files (#1037)

Add temp build files to gitignore

* Ensure previous search and replace texts are evaluated and updated in the UI at startup (#1043)

Ensure stored settings get evaluated after initial enumeration

There was a bug where the list view was not getting updated with the results of the search and replace on launch when we are using a stored search or replace text from a previous session.

* adding fancy zone opacity setting, enhancement #631 (#1008)

* adding fancy zone opacity setting, enhancement #631

* applying zone opacity setting to all zones during zone selection

* changing opacity setting to percentage

* runner: show message box when restarting with different elevation fails (#1061)

Also make the message box appear on top of the settings window.

* Fix misaligned display of zones in layout priview and grid editor (#1010)

Fix misaligned display of zones in layout preview and grid editor

* MSIX: Extract MSIX building functionality from msix_reinstall.ps1 to a separate script (#1068)

* MSIX: label PowerToys as Preview (#1090)

* MSIX: Code sign msixbundle (#1093)

* Update to MSIX README.md (#1095)

* Update README.md

few adjustments

* Update README.md

* Update README.md

* adding in privacy statement, removing About in dialog (#1087)

* adding in privacy statement, removing About in dialog

* added Preview

* Revert "Fix misaligned display of zones in layout priview and grid editor (#1010)" (#1097)

This reverts commit d03690cffd.

* Fix reversed order of zones in layout (#1071)

* Shifted three functions to common (#1101)

Co-authored-by: Clint Rutkas <clint@rutkas.com>
Co-authored-by: Enrico Giordani <enricogior@users.noreply.github.com>
Co-authored-by: Chris Davis <chrisdavis@outlook.com>
Co-authored-by: Yosef Durr <yodurr@microsoft.com>
Co-authored-by: Bartosz Sosnowski <bzoz@users.noreply.github.com>
Co-authored-by: vldmr11080 <57061786+vldmr11080@users.noreply.github.com>
Co-authored-by: yuyoyuppe <yuyoyuppe@users.noreply.github.com>

* Revert "Sync dev/imageResizer with master (#1105)"

This reverts commit db7f15541f.

* Added icon to Resize pictures context menu entry (dev/imageResizer) (#1113)

* Updated vcxproj file with common project references and cpp version flags

* Added module template code to dllmain and updated headers for successful build

* Removed unnecessary include

* Added dll to runner and add fixes to show up in PT Settings

* Added settings file

* Added support for enabling/disabling based on PowerRename codebase

* Fixed solution file configurations

* Removed Any CPU from ImageResizer csprojs

* Renamed registry writing and removed build time registry addition

* Added ImageResizer installation details to msi

* Shifted to MII, TODO: Fix position

* Incorporated ImageResizer Icon in context menu entry

* Fixed typo

* Merged with dev/imageResizer

* Renamed Advanced Options to Settings and removed About tab (dev/imageResizer) (#1123)

* Removed about tab, renamed advanced opt to settings, changed assembly info

* Restored Resource designer file

* Reverted changes on AssemblyInfo

* MSI: Fix ImageResizer menu item position (dev/imageResizer) (#1114)

* Updated vcxproj file with common project references and cpp version flags

* Added module template code to dllmain and updated headers for successful build

* Removed unnecessary include

* Added dll to runner and add fixes to show up in PT Settings

* Added settings file

* Added support for enabling/disabling based on PowerRename codebase

* Fixed solution file configurations

* Removed Any CPU from ImageResizer csprojs

* Renamed registry writing and removed build time registry addition

* Added ImageResizer installation details to msi

* Shifted to MII, TODO: Fix position

* Incorporated ImageResizer Icon in context menu entry

* Changed registry entries to SystemFileAssociations and added index changes in InsertMenuItem

* Fixed extra newline

* Fixed merge conflict

* Refactor ImageResizer code base naming to match PowerRename (#1121)

* Created empty README file

* Renamed dll project

* Removed ShellExtensions references in src

* Fixed ImageResizerUI assembly name and added changes to MSI

* added the helper functions

* localized dllmain powerrename

* localized powerRenameExt

* localized the settings file

* built the proj

* Modified resourceIDs for strings in the table

* added common as a reference project

* Removed get_res_string_wchar and used the get_resource_string() function instead which returns a wstring typecast into wchar*

* Added new lines to the end of the file

* Removed string resources from the settings.cpp file

* rebuilt project PowerRename

* moved app name to constructor to init only once

* updated formatting of common.cpp

* reverting formatting of files

* Removed some IDs from resource file. Changed SHIFT to Shift

* Localizing C# Project of FancyZones (FancyZonesEditor) (#199) (#1122)

* removed hardcoded strings from CanvasEditorWindow.xaml

* removed hardcoded strings from GridEditorWindow.xaml

* loc

* Localized MainWindow

* reverting MainWindow.xaml as it is not rendering the window as expected

* Changed the resource settings from internal to public

* the culture is set based on the culture of the system UI set in the system settings

* Removed the french resource files used for testing

* Localized canvasWindow and mainwindow

* Removed setting the UI culture explicitly as it would be implicitly set to the culture of system UI

* Removed redundant header file

* Localize the Shortcut guide PowerToy (#199) (#1126)

* Localized shortcut_guide.cpp

* localized overlay_window.cpp

* formatting changes

* Localize overlay window

* removed the README link from the set of localized resources

* Typo: changed upper to lower

* Localize C++ Projects of FancyZones (#1130)

* localized dllmain.cpp  of fancyzones project

* localized FancyZones.cpp

* format fancyzones.rc file

* Moved SuperFancyZones back to being a string instead of having it in the resource file as it is the window class name

* reverted changes for window name

* Formatted fancyzones rc file

* Align zone dimensions from layout preview with those from grid editor (#1115)

* MSIX: add a dedicated .rc for UWPUI which joins both UI and DLL .rc's (#1139)

* Runner: fix restarting with same elevation (#1133)

* MSIX: reinstall script uses bundle instead of .msi to be able to reinstall in all cases

* Telemetry: add WebView init failure errors

* Settings: initialize COM security to allow communication between elevated Settings and WebView

* Common: implement on_scope_exit helper and typed_storage

* Changes for #1140 and #569 (#1152)

* MSIX build instructions adjustmnet (#1170)

* MSIX: hide the "Run at Startup" option if running as packaged

* MSIX: update identity name and publisher (#1176)

* Runner: fix startup task state setting for MSIX (#1181)

* Add ImageResizer to MSIX installer and make the code MSIX-compatible (#1219)

* Removed ImageResizer.exe location registry key

* Added working resize pictures to MSIX context menu without icon

* Fixed missing icon on MSIX build

* Added comments

* Changed to single context handler entry

* Made changes as per PR comments

* Localize ImageResizer (#1261)

* Removed hardcoded strings

* Added resource dlls to MSIX installer

* Save ImageResizer settings in JSON format (#1258)

* Combined settings files

* Added JSON settings functionality in PowerToys format with thread safety

* Reverting changes to csproj file

* Removed settings.settings and designer file and added target sdk tools to fix warning

* Added NewtonSoft Json package

* Added 3 tests

* Added propertychanged test

* Removed unused libraries

* Removed additional allocation statements in test

* Added comments on test

* Added one-time setup code

* Added Newtonsoft.Json.dll to MSI and MSIX installer

* Fixed copyright header

* Fixed folder location in MSIX

* Renamed jsonMutex to _jsonMutex

* Fixed line endings

* Created private setup functions and added Arrange, Act, Assert comments

* Created private setup functions and added Arrange, Act, Assert comments

* Suppressed copyright warning on AppFixture and enabled treat warnings as errors

* Added comments on Reload/AppFixture and added constructor andispose

* Added telemetry to ImageResizer Shell Extension code (dev/imageResizer) (#1272)

* Added telemetry to C++ ImageResizerExt

* Added Register and unregister calls

* Changed default enable setting

* Set startup location to center of the screen (ImageResizer) (#1452)

* Added ImageResizer resources.dlls to the MSI installer (#1448)

* Implemented fix for foreground issue for ImageResizer (#1434)

* Fixed conflict in installer README.md file

* Fixed conflict in bundle.js

* Auto-generate AssemblyInfo in ImageResizer (#1467)

* Updated assembly info

* Added auto-generation of AssemblyInfo.cs

* Fixed minor issues

* Remove the  License file since Notice.md have been added

* Fix errors due to resolving merge conflicts

Co-authored-by: Brice Lambson <brice@bricelam.net>
Co-authored-by: Clint Rutkas <clint@rutkas.com>
Co-authored-by: Arjun Balgovind <arbalgov@microsoft.com>
Co-authored-by: Enrico Giordani <enricogior@users.noreply.github.com>
Co-authored-by: Chris Davis <chrisdavis@outlook.com>
Co-authored-by: Yosef Durr <yodurr@microsoft.com>
Co-authored-by: Bartosz Sosnowski <bzoz@users.noreply.github.com>
Co-authored-by: vldmr11080 <57061786+vldmr11080@users.noreply.github.com>
Co-authored-by: yuyoyuppe <yuyoyuppe@users.noreply.github.com>
Co-authored-by: Alekhya Kommuru <alkommur@microsoft.com>
Co-authored-by: Alekhya <reddykalekhya@gmail.com>
Co-authored-by: yuyoyuppe <a.yuyoyuppe@gmail.com>
Co-authored-by: Udit Singh <udsing@microsoft.com>
This commit is contained in:
Arjun Balgovind
2020-03-12 12:02:34 -04:00
committed by GitHub
parent 7f12288b2c
commit d84cc370c9
114 changed files with 13436 additions and 10 deletions

View File

@@ -0,0 +1,407 @@
// ContextMenuHandler.cpp : Implementation of CContextMenuHandler
#include "stdafx.h"
#include "ContextMenuHandler.h"
#include "HDropIterator.h"
#include "Settings.h"
#include "common/icon_helpers.h"
#include "trace.h"
extern HINSTANCE g_hInst_imageResizer;
CContextMenuHandler::CContextMenuHandler()
{
m_pidlFolder = NULL;
m_pdtobj = NULL;
app_name = GET_RESOURCE_STRING(IDS_RESIZE_PICTURES);
}
CContextMenuHandler::~CContextMenuHandler()
{
Uninitialize();
}
void CContextMenuHandler::Uninitialize()
{
CoTaskMemFree((LPVOID)m_pidlFolder);
m_pidlFolder = NULL;
if (m_pdtobj)
{
m_pdtobj->Release();
m_pdtobj = NULL;
}
}
HRESULT CContextMenuHandler::Initialize(_In_opt_ PCIDLIST_ABSOLUTE pidlFolder, _In_opt_ IDataObject* pdtobj, _In_opt_ HKEY hkeyProgID)
{
Uninitialize();
if (!CSettings::GetEnabled())
{
return E_FAIL;
}
if (pidlFolder)
{
m_pidlFolder = ILClone(pidlFolder);
}
if (pdtobj)
{
m_pdtobj = pdtobj;
m_pdtobj->AddRef();
}
return S_OK;
}
HRESULT CContextMenuHandler::QueryContextMenu(_In_ HMENU hmenu, UINT indexMenu, UINT idCmdFirst, UINT idCmdLast, UINT uFlags)
{
if (uFlags & CMF_DEFAULTONLY)
{
return S_OK;
}
if (!CSettings::GetEnabled())
{
return E_FAIL;
}
// NB: We just check the first item. We could iterate through more if the first one doesn't meet the criteria
HDropIterator i(m_pdtobj);
i.First();
// Suppressing C26812 warning as the issue is in the shtypes.h library
#pragma warning(suppress : 26812)
PERCEIVED type;
PERCEIVEDFLAG flag;
LPTSTR pszPath = i.CurrentItem();
LPTSTR pszExt = PathFindExtension(pszPath);
// TODO: Instead, detect whether there's a WIC codec installed that can handle this file
AssocGetPerceivedType(pszExt, &type, &flag, NULL);
free(pszPath);
bool dragDropFlag = false;
// If selected file is an image...
if (type == PERCEIVED_TYPE_IMAGE)
{
HRESULT hr = E_UNEXPECTED;
wchar_t strResizePictures[64] = { 0 };
// If handling drag-and-drop...
if (m_pidlFolder)
{
// Suppressing C6031 warning since return value is not required.
#pragma warning(suppress : 6031)
// Load 'Resize pictures here' string
LoadString(g_hInst_imageResizer, IDS_RESIZE_PICTURES_HERE, strResizePictures, ARRAYSIZE(strResizePictures));
dragDropFlag = true;
}
else
{
// Suppressing C6031 warning since return value is not required.
#pragma warning(suppress : 6031)
// Load 'Resize pictures' string
LoadString(g_hInst_imageResizer, IDS_RESIZE_PICTURES, strResizePictures, ARRAYSIZE(strResizePictures));
}
MENUITEMINFO mii;
mii.cbSize = sizeof(MENUITEMINFO);
mii.fMask = MIIM_STRING | MIIM_FTYPE | MIIM_ID | MIIM_STATE;
mii.wID = idCmdFirst + ID_RESIZE_PICTURES;
mii.fType = MFT_STRING;
mii.dwTypeData = (PWSTR)strResizePictures;
mii.fState = MFS_ENABLED;
HICON hIcon = (HICON)LoadImage(g_hInst_imageResizer, MAKEINTRESOURCE(IDI_RESIZE_PICTURES), IMAGE_ICON, 16, 16, 0);
if (hIcon)
{
mii.fMask |= MIIM_BITMAP;
if (m_hbmpIcon == NULL)
{
m_hbmpIcon = CreateBitmapFromIcon(hIcon);
}
mii.hbmpItem = m_hbmpIcon;
DestroyIcon(hIcon);
}
if (dragDropFlag)
{
// Insert the menu entry at indexMenu+1 since the first entry should be "Copy here"
indexMenu++;
}
else
{
// indexMenu gets the first possible menu item index based on the location of the shellex registry key.
// If the registry entry is under SystemFileAssociations for the image formats, ShellImagePreview (in Windows by default) will be at indexMenu=0
// Shell ImagePreview consists of 4 menu items, a separator, Rotate right, Rotate left, and another separator
// Check if the entry at indexMenu is a separator, insert the new menu item at indexMenu+1 if true
MENUITEMINFO miiExisting;
miiExisting.dwTypeData = NULL;
miiExisting.fMask = MIIM_TYPE;
miiExisting.cbSize = sizeof(MENUITEMINFO);
GetMenuItemInfo(hmenu, indexMenu, TRUE, &miiExisting);
if (miiExisting.fType == MFT_SEPARATOR)
{
indexMenu++;
}
}
if (!InsertMenuItem(hmenu, indexMenu, TRUE, &mii))
{
hr = HRESULT_FROM_WIN32(GetLastError());
}
else
{
hr = MAKE_HRESULT(SEVERITY_SUCCESS, FACILITY_NULL, 1);
}
return hr;
}
return S_OK;
}
HRESULT CContextMenuHandler::GetCommandString(UINT_PTR idCmd, UINT uType, _In_ UINT* pReserved, LPSTR pszName, UINT cchMax)
{
if (idCmd == ID_RESIZE_PICTURES)
{
if (uType == GCS_VERBW)
{
wcscpy_s((LPWSTR)pszName, cchMax, RESIZE_PICTURES_VERBW);
}
}
else
{
return E_INVALIDARG;
}
return S_OK;
}
HRESULT CContextMenuHandler::InvokeCommand(_In_ CMINVOKECOMMANDINFO* pici)
{
BOOL fUnicode = FALSE;
Trace::Invoked();
HRESULT hr = E_FAIL;
if (pici->cbSize == sizeof(CMINVOKECOMMANDINFOEX) && pici->fMask & CMIC_MASK_UNICODE)
{
fUnicode = TRUE;
}
if (!fUnicode && HIWORD(pici->lpVerb))
{
}
else if (fUnicode && HIWORD(((CMINVOKECOMMANDINFOEX*)pici)->lpVerbW))
{
if (wcscmp(((CMINVOKECOMMANDINFOEX*)pici)->lpVerbW, RESIZE_PICTURES_VERBW) == 0)
{
hr = ResizePictures(pici, nullptr);
}
}
else if (LOWORD(pici->lpVerb) == ID_RESIZE_PICTURES)
{
hr = ResizePictures(pici, nullptr);
}
Trace::InvokedRet(hr);
return hr;
}
// This function is used for both MSI and MSIX. If pici is null and psiItemArray is not null then this is called by Invoke(MSIX). If pici is not null and psiItemArray is null then this is called by InvokeCommand(MSI).
HRESULT CContextMenuHandler::ResizePictures(CMINVOKECOMMANDINFO* pici, IShellItemArray* psiItemArray)
{
// Set the application path based on the location of the dll
std::wstring path = get_module_folderpath(g_hInst_imageResizer);
path = path + L"\\ImageResizer.exe";
LPTSTR lpApplicationName = (LPTSTR)path.c_str();
// Create an anonymous pipe to stream filenames
SECURITY_ATTRIBUTES sa;
HANDLE hReadPipe;
HANDLE hWritePipe;
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
sa.lpSecurityDescriptor = NULL;
sa.bInheritHandle = TRUE;
HRESULT hr = E_FAIL;
if (!CreatePipe(&hReadPipe, &hWritePipe, &sa, 0))
{
Trace::InvokedRet(hr);
return hr;
}
if (!SetHandleInformation(hWritePipe, HANDLE_FLAG_INHERIT, 0))
{
Trace::InvokedRet(hr);
return hr;
}
CAtlFile writePipe(hWritePipe);
CString commandLine;
commandLine.Format(_T("\"%s\""), lpApplicationName);
// Set the output directory
if (m_pidlFolder)
{
TCHAR szFolder[MAX_PATH];
SHGetPathFromIDList(m_pidlFolder, szFolder);
commandLine.AppendFormat(_T(" /d \"%s\""), szFolder);
}
int nSize = commandLine.GetLength() + 1;
LPTSTR lpszCommandLine = new TCHAR[nSize];
_tcscpy_s(lpszCommandLine, nSize, commandLine);
STARTUPINFO startupInfo;
ZeroMemory(&startupInfo, sizeof(STARTUPINFO));
startupInfo.cb = sizeof(STARTUPINFO);
startupInfo.hStdInput = hReadPipe;
startupInfo.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
if (pici)
{
startupInfo.wShowWindow = pici->nShow;
}
else
{
startupInfo.wShowWindow = SW_SHOWNORMAL;
}
PROCESS_INFORMATION processInformation;
// Start the resizer
CreateProcess(
NULL,
lpszCommandLine,
NULL,
NULL,
TRUE,
0,
NULL,
NULL,
&startupInfo,
&processInformation);
delete[] lpszCommandLine;
if (!CloseHandle(processInformation.hProcess))
{
Trace::InvokedRet(hr);
return hr;
}
if (!CloseHandle(processInformation.hThread))
{
Trace::InvokedRet(hr);
return hr;
}
// psiItemArray is NULL if called from InvokeCommand. This part is used for the MSI installer. It is not NULL if it is called from Invoke (MSIX).
if (!psiItemArray)
{
// Stream the input files
HDropIterator i(m_pdtobj);
for (i.First(); !i.IsDone(); i.Next())
{
CString fileName(i.CurrentItem());
fileName.Append(_T("\r\n"));
writePipe.Write(fileName, fileName.GetLength() * sizeof(TCHAR));
}
}
else
{
//m_pdtobj will be NULL when invoked from the MSIX build as Initialize is never called (IShellExtInit functions aren't called in case of MSIX).
DWORD fileCount = 0;
// Gets the list of files currently selected using the IShellItemArray
psiItemArray->GetCount(&fileCount);
// Iterate over the list of files
for (DWORD i = 0; i < fileCount; i++)
{
IShellItem* shellItem;
psiItemArray->GetItemAt(i, &shellItem);
LPWSTR itemName;
// Retrieves the entire file system path of the file from its shell item
shellItem->GetDisplayName(SIGDN_FILESYSPATH, &itemName);
CString fileName(itemName);
fileName.Append(_T("\r\n"));
// Write the file path into the input stream for image resizer
writePipe.Write(fileName, fileName.GetLength() * sizeof(TCHAR));
}
}
writePipe.Close();
hr = S_OK;
Trace::InvokedRet(hr);
return hr;
}
HRESULT __stdcall CContextMenuHandler::GetTitle(IShellItemArray* /*psiItemArray*/, LPWSTR* ppszName)
{
return SHStrDup(app_name.c_str(), ppszName);
}
HRESULT __stdcall CContextMenuHandler::GetIcon(IShellItemArray* /*psiItemArray*/, LPWSTR* ppszIcon)
{
// Since ImageResizer is registered as a COM SurrogateServer the current module filename would be dllhost.exe. To get the icon we need the path of ImageResizerExt.dll, which can be obtained by passing the HINSTANCE of the dll
std::wstring iconResourcePath = get_module_filename(g_hInst_imageResizer);
iconResourcePath += L",-";
iconResourcePath += std::to_wstring(IDI_RESIZE_PICTURES);
return SHStrDup(iconResourcePath.c_str(), ppszIcon);
}
HRESULT __stdcall CContextMenuHandler::GetToolTip(IShellItemArray* /*psiItemArray*/, LPWSTR* ppszInfotip)
{
*ppszInfotip = nullptr;
return E_NOTIMPL;
}
HRESULT __stdcall CContextMenuHandler::GetCanonicalName(GUID* pguidCommandName)
{
*pguidCommandName = __uuidof(this);
return S_OK;
}
HRESULT __stdcall CContextMenuHandler::GetState(IShellItemArray* psiItemArray, BOOL fOkToBeSlow, EXPCMDSTATE* pCmdState)
{
if (!CSettings::GetEnabled())
{
*pCmdState = ECS_HIDDEN;
return S_OK;
}
// Hide if the file is not an image
*pCmdState = ECS_HIDDEN;
// Suppressing C26812 warning as the issue is in the shtypes.h library
#pragma warning(suppress : 26812)
PERCEIVED type;
PERCEIVEDFLAG flag;
IShellItem* shellItem;
//Check extension of first item in the list (the item which is right-clicked on)
psiItemArray->GetItemAt(0, &shellItem);
LPTSTR pszPath;
// Retrieves the entire file system path of the file from its shell item
shellItem->GetDisplayName(SIGDN_FILESYSPATH, &pszPath);
LPTSTR pszExt = PathFindExtension(pszPath);
// TODO: Instead, detect whether there's a WIC codec installed that can handle this file
AssocGetPerceivedType(pszExt, &type, &flag, NULL);
free(pszPath);
// If selected file is an image...
if (type == PERCEIVED_TYPE_IMAGE)
{
*pCmdState = ECS_ENABLED;
}
return S_OK;
}
HRESULT __stdcall CContextMenuHandler::GetFlags(EXPCMDFLAGS* pFlags)
{
*pFlags = ECF_DEFAULT;
return S_OK;
}
HRESULT __stdcall CContextMenuHandler::EnumSubCommands(IEnumExplorerCommand** ppEnum)
{
*ppEnum = nullptr;
return E_NOTIMPL;
}
// psiItemArray contains the list of files that have been selected when the context menu entry is invoked
HRESULT __stdcall CContextMenuHandler::Invoke(IShellItemArray* psiItemArray, IBindCtx* /*pbc*/)
{
Trace::Invoked();
HRESULT hr = ResizePictures(nullptr, psiItemArray);
Trace::InvokedRet(hr);
return hr;
}

View File

@@ -0,0 +1,57 @@
#pragma once
#define ID_RESIZE_PICTURES 0
#define RESIZE_PICTURES_VERBW L"resize"
#include "stdafx.h"
#include "resource.h"
#include "ImageResizerExt_i.h"
#if defined(_WIN32_WCE) && !defined(_CE_DCOM) && !defined(_CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA)
#error "Single-threaded COM objects are not properly supported on Windows CE platform, such as the Windows Mobile platforms that do not include full DCOM support. Define _CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA to force ATL to support creating single-thread COM object's and allow use of it's single-threaded COM object implementations. The threading model in your rgs file was set to 'Free' as that is the only threading model supported in non DCOM Windows CE platforms."
#endif
using namespace ATL;
class ATL_NO_VTABLE __declspec(uuid("51B4D7E5-7568-4234-B4BB-47FB3C016A69")) CContextMenuHandler :
public CComObjectRootEx<CComSingleThreadModel>,
public CComCoClass<CContextMenuHandler, &CLSID_ContextMenuHandler>,
public IShellExtInit,
public IContextMenu,
public IExplorerCommand
{
BEGIN_COM_MAP(CContextMenuHandler)
COM_INTERFACE_ENTRY(IShellExtInit)
COM_INTERFACE_ENTRY(IContextMenu)
COM_INTERFACE_ENTRY(IExplorerCommand)
END_COM_MAP()
DECLARE_REGISTRY_RESOURCEID(IDR_CONTEXTMENUHANDLER)
DECLARE_NOT_AGGREGATABLE(CContextMenuHandler)
public:
CContextMenuHandler();
~CContextMenuHandler();
HRESULT STDMETHODCALLTYPE Initialize(_In_opt_ PCIDLIST_ABSOLUTE pidlFolder, _In_opt_ IDataObject* pdtobj, _In_opt_ HKEY hkeyProgID);
HRESULT STDMETHODCALLTYPE QueryContextMenu(_In_ HMENU hmenu, UINT indexMenu, UINT idCmdFirst, UINT idCmdLast, UINT uFlags);
HRESULT STDMETHODCALLTYPE GetCommandString(UINT_PTR idCmd, UINT uType, _In_ UINT* pReserved, LPSTR pszName, UINT cchMax);
HRESULT STDMETHODCALLTYPE InvokeCommand(_In_ CMINVOKECOMMANDINFO* pici);
// Inherited via IExplorerCommand
virtual HRESULT __stdcall GetTitle(IShellItemArray* psiItemArray, LPWSTR* ppszName) override;
virtual HRESULT __stdcall GetIcon(IShellItemArray* psiItemArray, LPWSTR* ppszIcon) override;
virtual HRESULT __stdcall GetToolTip(IShellItemArray* psiItemArray, LPWSTR* ppszInfotip) override;
virtual HRESULT __stdcall GetCanonicalName(GUID* pguidCommandName) override;
virtual HRESULT __stdcall GetState(IShellItemArray* psiItemArray, BOOL fOkToBeSlow, EXPCMDSTATE* pCmdState) override;
virtual HRESULT __stdcall Invoke(IShellItemArray* psiItemArray, IBindCtx* pbc) override;
virtual HRESULT __stdcall GetFlags(EXPCMDFLAGS* pFlags) override;
virtual HRESULT __stdcall EnumSubCommands(IEnumExplorerCommand** ppEnum) override;
private:
void Uninitialize();
HRESULT ResizePictures(CMINVOKECOMMANDINFO* pici, IShellItemArray* psiItemArray);
PCIDLIST_ABSOLUTE m_pidlFolder;
IDataObject* m_pdtobj;
HBITMAP m_hbmpIcon = nullptr;
std::wstring app_name;
};
OBJECT_ENTRY_AUTO(__uuidof(ContextMenuHandler), CContextMenuHandler)

View File

@@ -0,0 +1,3 @@
HKCR
{
}

View File

@@ -0,0 +1,49 @@
#include "StdAfx.h"
#include "HDropIterator.h"
HDropIterator::HDropIterator(IDataObject* pdtobj)
{
_current = 0;
FORMATETC formatetc = {
CF_HDROP,
NULL,
DVASPECT_CONTENT,
-1,
TYMED_HGLOBAL
};
pdtobj->GetData(&formatetc, &m_medium);
_listCount = DragQueryFile((HDROP)m_medium.hGlobal, 0xFFFFFFFF, NULL, 0);
}
HDropIterator::~HDropIterator()
{
ReleaseStgMedium(&m_medium);
}
void HDropIterator::First()
{
_current = 0;
}
void HDropIterator::Next()
{
_current++;
}
bool HDropIterator::IsDone() const
{
return _current >= _listCount;
}
LPTSTR HDropIterator::CurrentItem() const
{
UINT cch = DragQueryFile((HDROP)m_medium.hGlobal, _current, NULL, 0) + 1;
LPTSTR pszPath = (LPTSTR)malloc(sizeof(TCHAR) * cch);
DragQueryFile((HDROP)m_medium.hGlobal, _current, pszPath, cch);
return pszPath;
}

View File

@@ -0,0 +1,17 @@
#pragma once
class HDropIterator
{
public:
HDropIterator(IDataObject *pDataObject);
~HDropIterator();
void First();
void Next();
bool IsDone() const;
LPTSTR CurrentItem() const;
private:
UINT _listCount;
STGMEDIUM m_medium;
UINT _current;
};

View File

@@ -0,0 +1,54 @@
#include "stdafx.h"
#include "resource.h"
#include "ImageResizerExt_i.h"
#include "dllmain.h"
__control_entrypoint(DllExport) STDAPI DllCanUnloadNow()
{
return _AtlModule.DllCanUnloadNow();
}
_Check_return_ STDAPI DllGetClassObject(_In_ REFCLSID rclsid, _In_ REFIID riid, _Outptr_ LPVOID* ppv)
{
return _AtlModule.DllGetClassObject(rclsid, riid, ppv);
}
STDAPI DllRegisterServer()
{
return _AtlModule.DllRegisterServer();
}
STDAPI DllUnregisterServer()
{
return _AtlModule.DllUnregisterServer();
}
STDAPI DllInstall(BOOL bInstall, _In_opt_ LPCWSTR pszCmdLine)
{
HRESULT hr = E_FAIL;
static const wchar_t szUserSwitch[] = L"user";
if (pszCmdLine != NULL)
{
if (_wcsnicmp(pszCmdLine, szUserSwitch, _countof(szUserSwitch)) == 0)
{
ATL::AtlSetPerUserRegistration(true);
}
}
if (bInstall)
{
hr = DllRegisterServer();
if (FAILED(hr))
{
DllUnregisterServer();
}
}
else
{
hr = DllUnregisterServer();
}
return hr;
}

View File

@@ -0,0 +1,8 @@
LIBRARY
EXPORTS
DllCanUnloadNow PRIVATE
DllGetClassObject PRIVATE
DllRegisterServer PRIVATE
DllUnregisterServer PRIVATE
DllInstall PRIVATE

View File

@@ -0,0 +1,15 @@
import "shobjidl.idl";
[
uuid(09082E28-A5CA-47A7-8571-A2236C411E91),
version(3.1)
]
library ImageResizerExtLib
{
[uuid(51B4D7E5-7568-4234-B4BB-47FB3C016A69)]
coclass ContextMenuHandler
{
[default] interface IShellExtInit;
interface IContextMenu;
};
};

Binary file not shown.

View File

@@ -0,0 +1,3 @@
HKCR
{
}

View File

@@ -0,0 +1,311 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="15.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>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{0B43679E-EDFA-4DA0-AD30-F4628B308B1B}</ProjectGuid>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
<Keyword>AtlProj</Keyword>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<UseOfAtl>Static</UseOfAtl>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<UseOfAtl>Static</UseOfAtl>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<UseOfAtl>Static</UseOfAtl>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<UseOfAtl>Static</UseOfAtl>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<IgnoreImportLibrary>true</IgnoreImportLibrary>
<LinkIncremental>true</LinkIncremental>
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\modules\</OutDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<IgnoreImportLibrary>true</IgnoreImportLibrary>
<LinkIncremental>true</LinkIncremental>
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\modules\</OutDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<IgnoreImportLibrary>true</IgnoreImportLibrary>
<LinkIncremental>false</LinkIncremental>
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\modules\</OutDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<IgnoreImportLibrary>true</IgnoreImportLibrary>
<LinkIncremental>false</LinkIncremental>
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\modules\</OutDir>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_WINDOWS;_DEBUG;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<AdditionalIncludeDirectories>..\..\..\common\inc;..\..\..\common\Telemetry;..\..\;..\..\..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<LanguageStandard>stdcpplatest</LanguageStandard>
</ClCompile>
<Midl>
<MkTypLibCompatible>false</MkTypLibCompatible>
<TargetEnvironment>Win32</TargetEnvironment>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<HeaderFileName>ImageResizerExt_i.h</HeaderFileName>
<InterfaceIdentifierFileName>ImageResizerExt_i.c</InterfaceIdentifierFileName>
<ProxyFileName>ImageResizerExt_p.c</ProxyFileName>
<GenerateStublessProxies>true</GenerateStublessProxies>
<TypeLibraryName>$(IntDir)ImageResizerExt.tlb</TypeLibraryName>
<DllDataFileName />
<ValidateAllParameters>true</ValidateAllParameters>
</Midl>
<ResourceCompile>
<Culture>0x0409</Culture>
<AdditionalIncludeDirectories>$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ResourceCompile>
<Link>
<SubSystem>Windows</SubSystem>
<ModuleDefinitionFile>.\ImageResizerExt.def</ModuleDefinitionFile>
<GenerateDebugInformation>true</GenerateDebugInformation>
<RegisterOutput>true</RegisterOutput>
<PerUserRedirection>true</PerUserRedirection>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>_WINDOWS;_DEBUG;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<AdditionalIncludeDirectories>..\..\..\common\inc;..\..\..\common\Telemetry;..\..\;..\..\..\;..\..\..\..\deps\cpprestsdk\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<LanguageStandard>stdcpplatest</LanguageStandard>
</ClCompile>
<Midl>
<MkTypLibCompatible>false</MkTypLibCompatible>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<HeaderFileName>ImageResizerExt_i.h</HeaderFileName>
<InterfaceIdentifierFileName>ImageResizerExt_i.c</InterfaceIdentifierFileName>
<ProxyFileName>ImageResizerExt_p.c</ProxyFileName>
<GenerateStublessProxies>true</GenerateStublessProxies>
<TypeLibraryName>$(IntDir)ImageResizerExt.tlb</TypeLibraryName>
<DllDataFileName />
<ValidateAllParameters>true</ValidateAllParameters>
</Midl>
<ResourceCompile>
<Culture>0x0409</Culture>
<AdditionalIncludeDirectories>$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ResourceCompile>
<Link>
<SubSystem>Windows</SubSystem>
<ModuleDefinitionFile>.\ImageResizerExt.def</ModuleDefinitionFile>
<GenerateDebugInformation>true</GenerateDebugInformation>
<RegisterOutput>true</RegisterOutput>
<PerUserRedirection>true</PerUserRedirection>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<PreprocessorDefinitions>WIN32;_WINDOWS;NDEBUG;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<AdditionalIncludeDirectories>..\..\..\common\inc;..\..\..\common\Telemetry;..\..\;..\..\..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<LanguageStandard>stdcpplatest</LanguageStandard>
</ClCompile>
<Midl>
<MkTypLibCompatible>false</MkTypLibCompatible>
<TargetEnvironment>Win32</TargetEnvironment>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<HeaderFileName>ImageResizerExt_i.h</HeaderFileName>
<InterfaceIdentifierFileName>ImageResizerExt_i.c</InterfaceIdentifierFileName>
<ProxyFileName>ImageResizerExt_p.c</ProxyFileName>
<GenerateStublessProxies>true</GenerateStublessProxies>
<TypeLibraryName>$(IntDir)ImageResizerExt.tlb</TypeLibraryName>
<DllDataFileName />
<ValidateAllParameters>true</ValidateAllParameters>
</Midl>
<ResourceCompile>
<Culture>0x0409</Culture>
<AdditionalIncludeDirectories>$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ResourceCompile>
<Link>
<SubSystem>Windows</SubSystem>
<ModuleDefinitionFile>.\ImageResizerExt.def</ModuleDefinitionFile>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<RegisterOutput>true</RegisterOutput>
<PerUserRedirection>true</PerUserRedirection>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<PreprocessorDefinitions>_WINDOWS;NDEBUG;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<AdditionalIncludeDirectories>..\..\..\common\inc;..\..\..\common\Telemetry;..\..\;..\..\..\;..\..\..\..\deps\cpprestsdk\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<LanguageStandard>stdcpplatest</LanguageStandard>
</ClCompile>
<Midl>
<MkTypLibCompatible>false</MkTypLibCompatible>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<HeaderFileName>ImageResizerExt_i.h</HeaderFileName>
<InterfaceIdentifierFileName>ImageResizerExt_i.c</InterfaceIdentifierFileName>
<ProxyFileName>ImageResizerExt_p.c</ProxyFileName>
<GenerateStublessProxies>true</GenerateStublessProxies>
<TypeLibraryName>$(IntDir)ImageResizerExt.tlb</TypeLibraryName>
<DllDataFileName />
<ValidateAllParameters>true</ValidateAllParameters>
</Midl>
<ResourceCompile>
<Culture>0x0409</Culture>
<AdditionalIncludeDirectories>$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ResourceCompile>
<Link>
<SubSystem>Windows</SubSystem>
<ModuleDefinitionFile>.\ImageResizerExt.def</ModuleDefinitionFile>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<RegisterOutput>true</RegisterOutput>
<PerUserRedirection>true</PerUserRedirection>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="ContextMenuHandler.cpp" />
<ClCompile Include="HDropIterator.cpp" />
<ClCompile Include="dllmain.cpp">
<CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</CompileAsManaged>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
</PrecompiledHeader>
<CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</CompileAsManaged>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
</PrecompiledHeader>
<CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</CompileAsManaged>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
</PrecompiledHeader>
<CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</CompileAsManaged>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
</PrecompiledHeader>
</ClCompile>
<ClCompile Include="ImageResizerExt.cpp" />
<ClCompile Include="ImageResizerExt_i.c">
<CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</CompileAsManaged>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
</PrecompiledHeader>
<CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</CompileAsManaged>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
</PrecompiledHeader>
<CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</CompileAsManaged>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
</PrecompiledHeader>
<CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</CompileAsManaged>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
</PrecompiledHeader>
</ClCompile>
<ClCompile Include="Settings.cpp" />
<ClCompile Include="stdafx.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
</ClCompile>
<ClCompile Include="trace.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="ContextMenuHandler.h" />
<ClInclude Include="HDropIterator.h" />
<ClInclude Include="dllmain.h" />
<ClInclude Include="Settings.h" />
<ClInclude Include="Resource.h" />
<ClInclude Include="ImageResizerExt_i.h" />
<ClInclude Include="stdafx.h" />
<ClInclude Include="targetver.h" />
<ClInclude Include="trace.h" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="ImageResizerExt.rc" />
</ItemGroup>
<ItemGroup>
<None Include="ContextMenuHandler.rgs" />
<None Include="ImageResizerExt.def" />
<None Include="ImageResizerExt.rgs" />
</ItemGroup>
<ItemGroup>
<Midl Include="ImageResizerExt.idl" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\common\common.vcxproj">
<Project>{74485049-c722-400f-abe5-86ac52d929b3}</Project>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<Image Include="..\ui\Resources\ImageResizer.ico" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@@ -0,0 +1,102 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
<Filter Include="Generated Files">
<UniqueIdentifier>{87bc9b81-f7fa-45d9-87cc-c99e55473868}</UniqueIdentifier>
<SourceControlFiles>False</SourceControlFiles>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="stdafx.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="ImageResizerExt.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="dllmain.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="ImageResizerExt_i.c">
<Filter>Generated Files</Filter>
</ClCompile>
<ClCompile Include="ContextMenuHandler.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="HDropIterator.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Settings.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="trace.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClInclude Include="trace.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClInclude Include="stdafx.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="targetver.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Resource.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="dllmain.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ImageResizerExt_i.h">
<Filter>Generated Files</Filter>
</ClInclude>
<ClInclude Include="ContextMenuHandler.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="HDropIterator.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Settings.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="ImageResizerExt.rc">
<Filter>Resource Files</Filter>
</ResourceCompile>
</ItemGroup>
<ItemGroup>
<None Include="ImageResizerExt.rgs">
<Filter>Resource Files</Filter>
</None>
<None Include="ImageResizerExt.def">
<Filter>Source Files</Filter>
</None>
<None Include="ContextMenuHandler.rgs">
<Filter>Resource Files</Filter>
</None>
</ItemGroup>
<ItemGroup>
<Midl Include="ImageResizerExt.idl">
<Filter>Source Files</Filter>
</Midl>
</ItemGroup>
<ItemGroup>
<Image Include="..\ui\Resources\ImageResizer.ico">
<Filter>Resource Files</Filter>
</Image>
</ItemGroup>
</Project>

View File

@@ -0,0 +1,66 @@
#include "stdafx.h"
#include <commctrl.h>
#include "Settings.h"
const wchar_t c_rootRegPath[] = L"Software\\Microsoft\\ImageResizer";
const wchar_t c_enabled[] = L"Enabled";
const bool c_enabledDefault = true;
bool CSettings::GetEnabled()
{
return GetRegBoolValue(c_enabled, c_enabledDefault);
}
bool CSettings::SetEnabled(_In_ bool enabled)
{
return SetRegBoolValue(c_enabled, enabled);
}
bool CSettings::SetRegBoolValue(_In_ PCWSTR valueName, _In_ bool value)
{
DWORD dwValue = value ? 1 : 0;
return SetRegDWORDValue(valueName, dwValue);
}
bool CSettings::GetRegBoolValue(_In_ PCWSTR valueName, _In_ bool defaultValue)
{
DWORD value = GetRegDWORDValue(valueName, (defaultValue == 0) ? false : true);
return (value == 0) ? false : true;
}
bool CSettings::SetRegDWORDValue(_In_ PCWSTR valueName, _In_ DWORD value)
{
return (SUCCEEDED(HRESULT_FROM_WIN32(SHSetValue(HKEY_CURRENT_USER, c_rootRegPath, valueName, REG_DWORD, &value, sizeof(value)))));
}
DWORD CSettings::GetRegDWORDValue(_In_ PCWSTR valueName, _In_ DWORD defaultValue)
{
DWORD retVal = defaultValue;
DWORD type = REG_DWORD;
DWORD dwEnabled = 0;
DWORD cb = sizeof(dwEnabled);
if (SHGetValue(HKEY_CURRENT_USER, c_rootRegPath, valueName, &type, &dwEnabled, &cb) == ERROR_SUCCESS)
{
retVal = dwEnabled;
}
return retVal;
}
bool CSettings::SetRegStringValue(_In_ PCWSTR valueName, _In_ PCWSTR value)
{
ULONG cb = (DWORD)((wcslen(value) + 1) * sizeof(*value));
return (SUCCEEDED(HRESULT_FROM_WIN32(SHSetValue(HKEY_CURRENT_USER, c_rootRegPath, valueName, REG_SZ, (const BYTE*)value, cb))));
}
bool CSettings::GetRegStringValue(_In_ PCWSTR valueName, __out_ecount(cchBuf) PWSTR value, DWORD cchBuf)
{
if (cchBuf > 0)
{
value[0] = L'\0';
}
DWORD type = REG_SZ;
ULONG cb = cchBuf * sizeof(*value);
return (SUCCEEDED(HRESULT_FROM_WIN32(SHGetValue(HKEY_CURRENT_USER, c_rootRegPath, valueName, &type, value, &cb) == ERROR_SUCCESS)));
}

View File

@@ -0,0 +1,16 @@
#pragma once
class CSettings
{
public:
static bool GetEnabled();
static bool SetEnabled(_In_ bool enabled);
private:
static bool GetRegBoolValue(_In_ PCWSTR valueName, _In_ bool defaultValue);
static bool SetRegBoolValue(_In_ PCWSTR valueName, _In_ bool value);
static bool SetRegDWORDValue(_In_ PCWSTR valueName, _In_ DWORD value);
static DWORD GetRegDWORDValue(_In_ PCWSTR valueName, _In_ DWORD defaultValue);
static bool SetRegStringValue(_In_ PCWSTR valueName, _In_ PCWSTR value);
static bool GetRegStringValue(_In_ PCWSTR valueName, __out_ecount(cchBuf) PWSTR value, DWORD cchBuf);
};

View File

@@ -0,0 +1,117 @@
#include "stdafx.h"
#include "resource.h"
#include "ImageResizerExt_i.h"
#include "dllmain.h"
#include <interface/powertoy_module_interface.h>
#include <common/settings_objects.h>
#include "Settings.h"
#include "trace.h"
#include <common/common.h>
CImageResizerExtModule _AtlModule;
HINSTANCE g_hInst_imageResizer = 0;
extern "C" BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
{
switch (dwReason)
{
case DLL_PROCESS_ATTACH:
g_hInst_imageResizer = hInstance;
Trace::RegisterProvider();
break;
case DLL_PROCESS_DETACH:
Trace::UnregisterProvider();
break;
}
return _AtlModule.DllMain(dwReason, lpReserved);
}
class ImageResizerModule : public PowertoyModuleIface
{
private:
// Enabled by default
bool m_enabled = true;
std::wstring app_name;
public:
// Constructor
ImageResizerModule()
{
app_name = GET_RESOURCE_STRING(IDS_IMAGERESIZER);
};
// Destroy the powertoy and free memory
virtual void destroy() override
{
delete this;
}
// Return the display name of the powertoy, this will be cached by the runner
virtual const wchar_t* get_name() override
{
return app_name.c_str();
}
// Return array of the names of all events that this powertoy listens for, with
// nullptr as the last element of the array. Nullptr can also be retured for empty
// list.
virtual const wchar_t** get_events() override
{
static const wchar_t* events[] = { nullptr };
return events;
}
// Return JSON with the configuration options.
virtual bool get_config(wchar_t* buffer, int* buffer_size) override
{
HINSTANCE hinstance = reinterpret_cast<HINSTANCE>(&__ImageBase);
// Create a Settings object.
PowerToysSettings::Settings settings(hinstance, get_name());
settings.set_description(GET_RESOURCE_STRING(IDS_SETTINGS_DESCRIPTION));
return settings.serialize_to_buffer(buffer, buffer_size);
}
// Signal from the Settings editor to call a custom action.
// This can be used to spawn more complex editors.
virtual void call_custom_action(const wchar_t* action) override {}
// Called by the runner to pass the updated settings values as a serialized JSON.
virtual void set_config(const wchar_t* config) override {}
// Enable the powertoy
virtual void enable()
{
m_enabled = true;
CSettings::SetEnabled(m_enabled);
Trace::EnableImageResizer(m_enabled);
}
// Disable the powertoy
virtual void disable()
{
m_enabled = false;
CSettings::SetEnabled(m_enabled);
Trace::EnableImageResizer(m_enabled);
}
// Returns if the powertoys is enabled
virtual bool is_enabled() override
{
return m_enabled;
}
// Handle incoming event, data is event-specific
virtual intptr_t signal_event(const wchar_t* name, intptr_t data) override
{
return 0;
}
virtual void register_system_menu_helper(PowertoySystemMenuIface* helper) override {}
virtual void signal_system_menu_action(const wchar_t* name) override {}
};
extern "C" __declspec(dllexport) PowertoyModuleIface* __cdecl powertoy_create()
{
return new ImageResizerModule();
}

View File

@@ -0,0 +1,8 @@
class CImageResizerExtModule : public ATL::CAtlDllModuleT<CImageResizerExtModule>
{
public:
DECLARE_LIBID(LIBID_ImageResizerExtLib)
DECLARE_REGISTRY_APPID_RESOURCEID(IDR_IMAGERESIZEREXT, "{0C866E7B-65CB-4E7D-B1DD-D014F000E8D8}")
};
extern class CImageResizerExtModule _AtlModule;

View File

@@ -0,0 +1,22 @@
//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ generated include file.
// Used by ImageResizerExt.rc
//
#define IDS_RESIZE_PICTURES 100
#define IDS_RESIZE_PICTURES_HERE 101
#define IDR_IMAGERESIZEREXT 102
#define IDR_CONTEXTMENUHANDLER 104
#define IDI_RESIZE_PICTURES 105
#define IDS_IMAGERESIZER 106
#define IDS_SETTINGS_DESCRIPTION 107
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 201
#define _APS_NEXT_COMMAND_VALUE 32768
#define _APS_NEXT_CONTROL_VALUE 201
#define _APS_NEXT_SYMED_VALUE 103
#endif
#endif

View File

@@ -0,0 +1,2 @@
#include "stdafx.h"
#pragma comment(lib, "windowsapp")

View File

@@ -0,0 +1,23 @@
#pragma once
#ifndef STRICT
#define STRICT
#endif
#define _ATL_APARTMENT_THREADED
#define _ATL_NO_AUTOMATIC_NAMESPACE
#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS
#define ATL_NO_ASSERT_ON_DESTROY_NONEXISTENT_WINDOW
#include "targetver.h"
#include "resource.h"
#include <winrt/base.h>
#include <atlbase.h>
#include <atlcom.h>
#include <atlfile.h>
#include <atlstr.h>
#include <windows.h>
#include <ShlObj.h>
#include <ProjectTelemetry.h>

View File

@@ -0,0 +1,4 @@
#pragma once
#include <winsdkver.h>
#include <SDKDDKVer.h>

View File

@@ -0,0 +1,49 @@
#include "stdafx.h"
#include "trace.h"
TRACELOGGING_DEFINE_PROVIDER(
g_hProvider,
"Microsoft.PowerToys",
// {38e8889b-9731-53f5-e901-e8a7c1753074}
(0x38e8889b, 0x9731, 0x53f5, 0xe9, 0x01, 0xe8, 0xa7, 0xc1, 0x75, 0x30, 0x74),
TraceLoggingOptionProjectTelemetry());
void Trace::RegisterProvider() noexcept
{
TraceLoggingRegister(g_hProvider);
}
void Trace::UnregisterProvider() noexcept
{
TraceLoggingUnregister(g_hProvider);
}
void Trace::EnableImageResizer(_In_ bool enabled) noexcept
{
TraceLoggingWrite(
g_hProvider,
"ImageResizer_EnableImageResizer",
ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance),
TraceLoggingKeyword(PROJECT_KEYWORD_MEASURE),
TraceLoggingBoolean(enabled, "Enabled"));
}
void Trace::Invoked() noexcept
{
TraceLoggingWrite(
g_hProvider,
"ImageResizer_Invoked",
ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance),
TraceLoggingKeyword(PROJECT_KEYWORD_MEASURE));
}
void Trace::InvokedRet(_In_ HRESULT hr) noexcept
{
TraceLoggingWrite(
g_hProvider,
"ImageResizer_InvokedRet",
ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance),
TraceLoggingHResult(hr),
TraceLoggingKeyword(PROJECT_KEYWORD_MEASURE));
}

View File

@@ -0,0 +1,11 @@
#pragma once
class Trace
{
public:
static void RegisterProvider() noexcept;
static void UnregisterProvider() noexcept;
static void EnableImageResizer(_In_ bool enabled) noexcept;
static void Invoked() noexcept;
static void InvokedRet(_In_ HRESULT hr) noexcept;
};