Skip to content

Commit adcfbef

Browse files
committed
Add project files.
1 parent 92fa347 commit adcfbef

10 files changed

+456
-0
lines changed

SimpleSave.sln

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
2+
Microsoft Visual Studio Solution File, Format Version 12.00
3+
# Visual Studio Version 17
4+
VisualStudioVersion = 17.12.35527.113 d17.12
5+
MinimumVisualStudioVersion = 10.0.40219.1
6+
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SimpleSave", "SimpleSave\SimpleSave.vcxproj", "{2C67543B-438E-4AF4-BD4C-AE37A55D7DD4}"
7+
EndProject
8+
Global
9+
GlobalSection(SolutionConfigurationPlatforms) = preSolution
10+
Debug|x64 = Debug|x64
11+
Debug|x86 = Debug|x86
12+
Release|x64 = Release|x64
13+
Release|x86 = Release|x86
14+
EndGlobalSection
15+
GlobalSection(ProjectConfigurationPlatforms) = postSolution
16+
{2C67543B-438E-4AF4-BD4C-AE37A55D7DD4}.Debug|x64.ActiveCfg = Debug|x64
17+
{2C67543B-438E-4AF4-BD4C-AE37A55D7DD4}.Debug|x64.Build.0 = Debug|x64
18+
{2C67543B-438E-4AF4-BD4C-AE37A55D7DD4}.Debug|x86.ActiveCfg = Debug|Win32
19+
{2C67543B-438E-4AF4-BD4C-AE37A55D7DD4}.Debug|x86.Build.0 = Debug|Win32
20+
{2C67543B-438E-4AF4-BD4C-AE37A55D7DD4}.Release|x64.ActiveCfg = Release|x64
21+
{2C67543B-438E-4AF4-BD4C-AE37A55D7DD4}.Release|x64.Build.0 = Release|x64
22+
{2C67543B-438E-4AF4-BD4C-AE37A55D7DD4}.Release|x86.ActiveCfg = Release|Win32
23+
{2C67543B-438E-4AF4-BD4C-AE37A55D7DD4}.Release|x86.Build.0 = Release|Win32
24+
EndGlobalSection
25+
GlobalSection(SolutionProperties) = preSolution
26+
HideSolutionNode = FALSE
27+
EndGlobalSection
28+
EndGlobal

SimpleSave/Resource.h

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
//{{NO_DEPENDENCIES}}
2+
// Microsoft Visual C++ generated include file.
3+
// Used by SimpleSave.rc
4+
5+
#define IDS_APP_TITLE 103
6+
7+
#define IDR_MAINFRAME 128
8+
#define IDD_SIMPLESAVE_DIALOG 102
9+
#define IDD_ABOUTBOX 103
10+
#define IDM_ABOUT 104
11+
#define IDM_EXIT 105
12+
#define IDI_SIMPLESAVE 107
13+
#define IDI_SMALL 108
14+
#define IDC_SIMPLESAVE 109
15+
#define IDC_MYICON 2
16+
#ifndef IDC_STATIC
17+
#define IDC_STATIC -1
18+
#endif
19+
// Next default values for new objects
20+
//
21+
#ifdef APSTUDIO_INVOKED
22+
#ifndef APSTUDIO_READONLY_SYMBOLS
23+
24+
#define _APS_NO_MFC 130
25+
#define _APS_NEXT_RESOURCE_VALUE 129
26+
#define _APS_NEXT_COMMAND_VALUE 32771
27+
#define _APS_NEXT_CONTROL_VALUE 1000
28+
#define _APS_NEXT_SYMED_VALUE 110
29+
#endif
30+
#endif

SimpleSave/SimpleSave.cpp

+159
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
// RaoufiTech on github, still in development will add more functionality later on. hope u enjoy this.
2+
3+
#include <windows.h>
4+
#include <shlobj.h>
5+
#include <gdiplus.h>
6+
#include <iostream>
7+
#include <string>
8+
#include <ctime>
9+
#include <vector>
10+
#include <thread>
11+
#include <atomic>
12+
13+
//#pragma comment(lib, "gdiplus.lib") uncomment this if you don't link with gdiplus during building, I am linking so I can remove this.
14+
15+
using namespace Gdiplus;
16+
17+
std::atomic<bool> running(true);
18+
19+
std::wstring getCurrentTimeAsWString() {
20+
time_t now = time(0);
21+
struct tm tstruct;
22+
wchar_t buf[80];
23+
localtime_s(&tstruct, &now);
24+
wcsftime(buf, sizeof(buf) / sizeof(wchar_t), L"%H-%M-%S", &tstruct);
25+
return std::wstring(buf);
26+
}
27+
28+
std::wstring getDownloadPath() {
29+
PWSTR path = nullptr;
30+
if (SHGetKnownFolderPath(FOLDERID_Downloads, 0, NULL, &path) == S_OK) {
31+
std::wstring downloadPath = std::wstring(path) + L"\\ClipBoardImages";
32+
CoTaskMemFree(path);
33+
return downloadPath;
34+
}
35+
return L"";
36+
}
37+
38+
void saveBitmapAsImage(HBITMAP hBitmap, const std::wstring& filename, const CLSID& format) {
39+
Bitmap bitmap(hBitmap, NULL);
40+
bitmap.Save(filename.c_str(), &format, NULL);
41+
}
42+
43+
void createFolderIfNotExists(const std::wstring& path) {
44+
SHCreateDirectoryExW(NULL, path.c_str(), NULL);
45+
}
46+
47+
bool addToStartup() {
48+
wchar_t exePath[MAX_PATH];
49+
GetModuleFileNameW(NULL, exePath, MAX_PATH);
50+
51+
HKEY hKey;
52+
if (RegOpenKeyW(HKEY_CURRENT_USER, L"Software\\Microsoft\\Windows\\CurrentVersion\\Run", &hKey) == ERROR_SUCCESS) {
53+
RegSetValueExW(hKey, L"ClipboardImageSaver", 0, REG_SZ, (BYTE*)exePath, (DWORD)(wcslen(exePath) + 1) * sizeof(wchar_t));
54+
RegCloseKey(hKey);
55+
return true;
56+
}
57+
return false;
58+
}
59+
60+
std::string hashBitmap(HBITMAP hBitmap) {
61+
BITMAP bmp;
62+
GetObject(hBitmap, sizeof(BITMAP), &bmp);
63+
64+
int bufferSize = bmp.bmWidthBytes * bmp.bmHeight;
65+
std::vector<BYTE> buffer(bufferSize);
66+
67+
HDC hdc = GetDC(NULL);
68+
GetBitmapBits(hBitmap, bufferSize, buffer.data());
69+
ReleaseDC(NULL, hdc);
70+
71+
// Simple hash of pixels so that we dont save the same image every second
72+
std::hash<std::string> hasher;
73+
return std::to_string(hasher(std::string(buffer.begin(), buffer.end())));
74+
}
75+
76+
void monitorClipboard() {
77+
std::wstring downloadPath = getDownloadPath();
78+
createFolderIfNotExists(downloadPath);
79+
80+
GdiplusStartupInput gdiplusStartupInput;
81+
ULONG_PTR gdiplusToken;
82+
GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
83+
84+
CLSID pngClsid;
85+
HRESULT hr = CLSIDFromString(L"{557CF406-1A04-11D3-9A73-0000F81EF32E}", &pngClsid);
86+
if (FAILED(hr)) {
87+
MessageBoxW(NULL, L"Failed to retrieve CLSID for PNG format!", L"Error", MB_ICONERROR);
88+
running = false;
89+
return;
90+
}
91+
92+
std::string lastImageHash;
93+
94+
while (running) {
95+
if (OpenClipboard(NULL)) {
96+
if (IsClipboardFormatAvailable(CF_BITMAP)) {
97+
HBITMAP hBitmap = (HBITMAP)GetClipboardData(CF_BITMAP);
98+
if (hBitmap) {
99+
std::string currentHash = hashBitmap(hBitmap);
100+
if (currentHash != lastImageHash) {
101+
std::wstring filename = downloadPath + L"\\" + getCurrentTimeAsWString() + L".png";
102+
saveBitmapAsImage(hBitmap, filename, pngClsid);
103+
lastImageHash = currentHash;
104+
}
105+
}
106+
}
107+
CloseClipboard();
108+
}
109+
Sleep(1000);
110+
}
111+
112+
GdiplusShutdown(gdiplusToken);
113+
}
114+
115+
void listenForHotkey() {
116+
if (!RegisterHotKey(NULL, 1, MOD_CONTROL | MOD_ALT, 0x53)) { // CTRL+ALT+S shuts down the app until you rerun the .exe again.
117+
if (GetLastError() == ERROR_HOTKEY_ALREADY_REGISTERED) {
118+
MessageBoxW(NULL, L"Hotkey already registered by another instance of EasySave or another application.", L"Info", MB_ICONINFORMATION);
119+
}
120+
return;
121+
}
122+
123+
MSG msg = { 0 };
124+
while (GetMessage(&msg, NULL, 0, 0)) {
125+
if (msg.message == WM_HOTKEY) {
126+
running = false;
127+
break;
128+
}
129+
}
130+
131+
UnregisterHotKey(NULL, 1);
132+
}
133+
134+
int WINAPI WinMain(
135+
_In_ HINSTANCE hInstance,
136+
_In_opt_ HINSTANCE hPrevInstance,
137+
_In_ LPSTR lpCmdLine,
138+
_In_ int nCmdShow)
139+
{
140+
HANDLE mutex = CreateMutex(NULL, TRUE, L"EasySaveMutex");
141+
if (GetLastError() == ERROR_ALREADY_EXISTS) {
142+
MessageBoxW(NULL, L"Another instance of EasySave is already running.", L"Error", MB_ICONERROR);
143+
return 1;
144+
}
145+
146+
FreeConsole();
147+
if (!addToStartup()) {
148+
MessageBoxW(NULL, L"Failed to add to startup!", L"Error", MB_ICONERROR);
149+
return 1;
150+
}
151+
152+
std::thread hotkeyThread(listenForHotkey);
153+
monitorClipboard();
154+
155+
hotkeyThread.join();
156+
157+
ReleaseMutex(mutex);
158+
return 0;
159+
}

SimpleSave/SimpleSave.h

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
#pragma once
2+
3+
#include "resource.h"

SimpleSave/SimpleSave.rc

3.26 KB
Binary file not shown.

SimpleSave/SimpleSave.vcxproj

+150
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
3+
<ItemGroup Label="ProjectConfigurations">
4+
<ProjectConfiguration Include="Debug|Win32">
5+
<Configuration>Debug</Configuration>
6+
<Platform>Win32</Platform>
7+
</ProjectConfiguration>
8+
<ProjectConfiguration Include="Release|Win32">
9+
<Configuration>Release</Configuration>
10+
<Platform>Win32</Platform>
11+
</ProjectConfiguration>
12+
<ProjectConfiguration Include="Debug|x64">
13+
<Configuration>Debug</Configuration>
14+
<Platform>x64</Platform>
15+
</ProjectConfiguration>
16+
<ProjectConfiguration Include="Release|x64">
17+
<Configuration>Release</Configuration>
18+
<Platform>x64</Platform>
19+
</ProjectConfiguration>
20+
</ItemGroup>
21+
<PropertyGroup Label="Globals">
22+
<VCProjectVersion>17.0</VCProjectVersion>
23+
<Keyword>Win32Proj</Keyword>
24+
<ProjectGuid>{2c67543b-438e-4af4-bd4c-ae37a55d7dd4}</ProjectGuid>
25+
<RootNamespace>SimpleSave</RootNamespace>
26+
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
27+
</PropertyGroup>
28+
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
29+
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
30+
<ConfigurationType>Application</ConfigurationType>
31+
<UseDebugLibraries>true</UseDebugLibraries>
32+
<PlatformToolset>v143</PlatformToolset>
33+
<CharacterSet>Unicode</CharacterSet>
34+
</PropertyGroup>
35+
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
36+
<ConfigurationType>Application</ConfigurationType>
37+
<UseDebugLibraries>false</UseDebugLibraries>
38+
<PlatformToolset>v143</PlatformToolset>
39+
<WholeProgramOptimization>true</WholeProgramOptimization>
40+
<CharacterSet>Unicode</CharacterSet>
41+
</PropertyGroup>
42+
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
43+
<ConfigurationType>Application</ConfigurationType>
44+
<UseDebugLibraries>true</UseDebugLibraries>
45+
<PlatformToolset>v143</PlatformToolset>
46+
<CharacterSet>Unicode</CharacterSet>
47+
</PropertyGroup>
48+
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
49+
<ConfigurationType>Application</ConfigurationType>
50+
<UseDebugLibraries>false</UseDebugLibraries>
51+
<PlatformToolset>v143</PlatformToolset>
52+
<WholeProgramOptimization>true</WholeProgramOptimization>
53+
<CharacterSet>Unicode</CharacterSet>
54+
</PropertyGroup>
55+
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
56+
<ImportGroup Label="ExtensionSettings">
57+
</ImportGroup>
58+
<ImportGroup Label="Shared">
59+
</ImportGroup>
60+
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
61+
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
62+
</ImportGroup>
63+
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
64+
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
65+
</ImportGroup>
66+
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
67+
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
68+
</ImportGroup>
69+
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
70+
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
71+
</ImportGroup>
72+
<PropertyGroup Label="UserMacros" />
73+
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
74+
<ClCompile>
75+
<WarningLevel>Level3</WarningLevel>
76+
<SDLCheck>true</SDLCheck>
77+
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
78+
<ConformanceMode>true</ConformanceMode>
79+
</ClCompile>
80+
<Link>
81+
<SubSystem>Windows</SubSystem>
82+
<GenerateDebugInformation>true</GenerateDebugInformation>
83+
</Link>
84+
</ItemDefinitionGroup>
85+
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
86+
<ClCompile>
87+
<WarningLevel>Level3</WarningLevel>
88+
<FunctionLevelLinking>true</FunctionLevelLinking>
89+
<IntrinsicFunctions>true</IntrinsicFunctions>
90+
<SDLCheck>true</SDLCheck>
91+
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
92+
<ConformanceMode>true</ConformanceMode>
93+
</ClCompile>
94+
<Link>
95+
<SubSystem>Windows</SubSystem>
96+
<EnableCOMDATFolding>true</EnableCOMDATFolding>
97+
<OptimizeReferences>true</OptimizeReferences>
98+
<GenerateDebugInformation>true</GenerateDebugInformation>
99+
</Link>
100+
</ItemDefinitionGroup>
101+
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
102+
<ClCompile>
103+
<WarningLevel>Level3</WarningLevel>
104+
<SDLCheck>true</SDLCheck>
105+
<PreprocessorDefinitions>_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
106+
<ConformanceMode>true</ConformanceMode>
107+
</ClCompile>
108+
<Link>
109+
<SubSystem>Windows</SubSystem>
110+
<GenerateDebugInformation>true</GenerateDebugInformation>
111+
<AdditionalDependencies>gdiplus.lib;%(AdditionalDependencies)</AdditionalDependencies>
112+
</Link>
113+
</ItemDefinitionGroup>
114+
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
115+
<ClCompile>
116+
<WarningLevel>Level3</WarningLevel>
117+
<FunctionLevelLinking>true</FunctionLevelLinking>
118+
<IntrinsicFunctions>true</IntrinsicFunctions>
119+
<SDLCheck>true</SDLCheck>
120+
<PreprocessorDefinitions>NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
121+
<ConformanceMode>true</ConformanceMode>
122+
</ClCompile>
123+
<Link>
124+
<SubSystem>Windows</SubSystem>
125+
<EnableCOMDATFolding>true</EnableCOMDATFolding>
126+
<OptimizeReferences>true</OptimizeReferences>
127+
<GenerateDebugInformation>true</GenerateDebugInformation>
128+
<AdditionalDependencies>gdiplus.lib;%(AdditionalDependencies)</AdditionalDependencies>
129+
</Link>
130+
</ItemDefinitionGroup>
131+
<ItemGroup>
132+
<ClInclude Include="framework.h" />
133+
<ClInclude Include="Resource.h" />
134+
<ClInclude Include="resource1.h" />
135+
<ClInclude Include="SimpleSave.h" />
136+
<ClInclude Include="targetver.h" />
137+
</ItemGroup>
138+
<ItemGroup>
139+
<ClCompile Include="SimpleSave.cpp" />
140+
</ItemGroup>
141+
<ItemGroup>
142+
<ResourceCompile Include="SimpleSave.rc" />
143+
</ItemGroup>
144+
<ItemGroup>
145+
<Image Include="..\..\..\..\Downloads\CLIPDOWNLOAD.ico" />
146+
</ItemGroup>
147+
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
148+
<ImportGroup Label="ExtensionTargets">
149+
</ImportGroup>
150+
</Project>

0 commit comments

Comments
 (0)