├── .gitattributes ├── .gitignore ├── ClipBoardPlus.sln ├── ClipBoardPlus ├── AboutDlg.cpp ├── AboutDlg.h ├── ClipBoardPlus.cpp ├── ClipBoardPlus.h ├── ClipBoardPlus.rc ├── ClipBoardPlus.vcxproj ├── ClipBoardPlus.vcxproj.filters ├── ClipBoardPlusDlg.cpp ├── ClipBoardPlusDlg.h ├── ClipButton.cpp ├── ClipButton.h ├── ClipEditorDlg.cpp ├── ClipEditorDlg.h ├── NetHelper.cpp ├── NetHelper.h ├── Reminder.cpp ├── Reminder.h ├── ReminderDlg.cpp ├── ReminderDlg.h ├── Resource.h ├── SysHelper.cpp ├── SysHelper.h ├── res │ ├── Clip01.bmp │ ├── Clip02.bmp │ ├── ClipBoardPlus.ico │ ├── ClipBoardPlus.rc2 │ ├── OormiLogo.bmp │ └── rem.wav ├── stdafx.cpp ├── stdafx.h └── targetver.h ├── LICENSE.txt ├── cbphelp ├── help110.html ├── help110bk.html ├── images │ ├── ClipBoardPlus170p.png │ ├── OormiLogo.png │ ├── popupmenu.png │ ├── promohelp.jpg │ ├── ss.png │ ├── ssnotes.png │ ├── ssrem.png │ ├── ssremack.png │ └── ssremui.png ├── main.css └── updatecbp.txt └── readme.md /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | 47 | ############################################################################### 48 | # diff behavior for common document formats 49 | # 50 | # Convert binary document formats to text before diffing them. This feature 51 | # is only available from the command line. Turn it on by uncommenting the 52 | # entries below. 53 | ############################################################################### 54 | #*.doc diff=astextplain 55 | #*.DOC diff=astextplain 56 | #*.docx diff=astextplain 57 | #*.DOCX diff=astextplain 58 | #*.dot diff=astextplain 59 | #*.DOT diff=astextplain 60 | #*.pdf diff=astextplain 61 | #*.PDF diff=astextplain 62 | #*.rtf diff=astextplain 63 | #*.RTF diff=astextplain 64 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | 4 | # User-specific files 5 | *.suo 6 | *.user 7 | *.userosscache 8 | *.sln.docstates 9 | 10 | # User-specific files (MonoDevelop/Xamarin Studio) 11 | *.userprefs 12 | 13 | # Build results 14 | [Dd]ebug/ 15 | [Dd]ebugPublic/ 16 | [Rr]elease/ 17 | [Rr]eleases/ 18 | [Xx]64/ 19 | [Xx]86/ 20 | [Bb]uild/ 21 | bld/ 22 | [Bb]in/ 23 | [Oo]bj/ 24 | 25 | # Visual Studio 2015 cache/options directory 26 | .vs/ 27 | # Uncomment if you have tasks that create the project's static files in wwwroot 28 | #wwwroot/ 29 | 30 | # MSTest test Results 31 | [Tt]est[Rr]esult*/ 32 | [Bb]uild[Ll]og.* 33 | 34 | # NUNIT 35 | *.VisualState.xml 36 | TestResult.xml 37 | 38 | # Build Results of an ATL Project 39 | [Dd]ebugPS/ 40 | [Rr]eleasePS/ 41 | dlldata.c 42 | 43 | # DNX 44 | project.lock.json 45 | artifacts/ 46 | 47 | *_i.c 48 | *_p.c 49 | *_i.h 50 | *.ilk 51 | *.meta 52 | *.obj 53 | *.pch 54 | *.pdb 55 | *.pgc 56 | *.pgd 57 | *.rsp 58 | *.sbr 59 | *.tlb 60 | *.tli 61 | *.tlh 62 | *.tmp 63 | *.tmp_proj 64 | *.log 65 | *.vspscc 66 | *.vssscc 67 | .builds 68 | *.pidb 69 | *.svclog 70 | *.scc 71 | 72 | # Chutzpah Test files 73 | _Chutzpah* 74 | 75 | # Visual C++ cache files 76 | ipch/ 77 | *.aps 78 | *.ncb 79 | *.opendb 80 | *.opensdf 81 | *.sdf 82 | *.cachefile 83 | *.VC.db 84 | 85 | # Visual Studio profiler 86 | *.psess 87 | *.vsp 88 | *.vspx 89 | *.sap 90 | 91 | # TFS 2012 Local Workspace 92 | $tf/ 93 | 94 | # Guidance Automation Toolkit 95 | *.gpState 96 | 97 | # ReSharper is a .NET coding add-in 98 | _ReSharper*/ 99 | *.[Rr]e[Ss]harper 100 | *.DotSettings.user 101 | 102 | # JustCode is a .NET coding add-in 103 | .JustCode 104 | 105 | # TeamCity is a build add-in 106 | _TeamCity* 107 | 108 | # DotCover is a Code Coverage Tool 109 | *.dotCover 110 | 111 | # NCrunch 112 | _NCrunch_* 113 | .*crunch*.local.xml 114 | nCrunchTemp_* 115 | 116 | # MightyMoose 117 | *.mm.* 118 | AutoTest.Net/ 119 | 120 | # Web workbench (sass) 121 | .sass-cache/ 122 | 123 | # Installshield output folder 124 | [Ee]xpress/ 125 | 126 | # DocProject is a documentation generator add-in 127 | DocProject/buildhelp/ 128 | DocProject/Help/*.HxT 129 | DocProject/Help/*.HxC 130 | DocProject/Help/*.hhc 131 | DocProject/Help/*.hhk 132 | DocProject/Help/*.hhp 133 | DocProject/Help/Html2 134 | DocProject/Help/html 135 | 136 | # Click-Once directory 137 | publish/ 138 | 139 | # Publish Web Output 140 | *.[Pp]ublish.xml 141 | *.azurePubxml 142 | 143 | # TODO: Un-comment the next line if you do not want to checkin 144 | # your web deploy settings because they may include unencrypted 145 | # passwords 146 | #*.pubxml 147 | *.publishproj 148 | 149 | # NuGet Packages 150 | *.nupkg 151 | # The packages folder can be ignored because of Package Restore 152 | **/packages/* 153 | # except build/, which is used as an MSBuild target. 154 | !**/packages/build/ 155 | # Uncomment if necessary however generally it will be regenerated when needed 156 | #!**/packages/repositories.config 157 | # NuGet v3's project.json files produces more ignoreable files 158 | *.nuget.props 159 | *.nuget.targets 160 | 161 | # Microsoft Azure Build Output 162 | csx/ 163 | *.build.csdef 164 | 165 | # Microsoft Azure Emulator 166 | ecf/ 167 | rcf/ 168 | 169 | # Microsoft Azure ApplicationInsights config file 170 | ApplicationInsights.config 171 | 172 | # Windows Store app package directory 173 | AppPackages/ 174 | BundleArtifacts/ 175 | 176 | # Visual Studio cache files 177 | # files ending in .cache can be ignored 178 | *.[Cc]ache 179 | # but keep track of directories ending in .cache 180 | !*.[Cc]ache/ 181 | 182 | # Others 183 | ClientBin/ 184 | [Ss]tyle[Cc]op.* 185 | ~$* 186 | *~ 187 | *.dbmdl 188 | *.dbproj.schemaview 189 | *.pfx 190 | *.publishsettings 191 | node_modules/ 192 | orleans.codegen.cs 193 | 194 | # RIA/Silverlight projects 195 | Generated_Code/ 196 | 197 | # Backup & report files from converting an old project file 198 | # to a newer Visual Studio version. Backup files are not needed, 199 | # because we have git ;-) 200 | _UpgradeReport_Files/ 201 | Backup*/ 202 | UpgradeLog*.XML 203 | UpgradeLog*.htm 204 | 205 | # SQL Server files 206 | *.mdf 207 | *.ldf 208 | 209 | # Business Intelligence projects 210 | *.rdl.data 211 | *.bim.layout 212 | *.bim_*.settings 213 | 214 | # Microsoft Fakes 215 | FakesAssemblies/ 216 | 217 | # GhostDoc plugin setting file 218 | *.GhostDoc.xml 219 | 220 | # Node.js Tools for Visual Studio 221 | .ntvs_analysis.dat 222 | 223 | # Visual Studio 6 build log 224 | *.plg 225 | 226 | # Visual Studio 6 workspace options file 227 | *.opt 228 | 229 | # Visual Studio LightSwitch build output 230 | **/*.HTMLClient/GeneratedArtifacts 231 | **/*.DesktopClient/GeneratedArtifacts 232 | **/*.DesktopClient/ModelManifest.xml 233 | **/*.Server/GeneratedArtifacts 234 | **/*.Server/ModelManifest.xml 235 | _Pvt_Extensions 236 | 237 | # LightSwitch generated files 238 | GeneratedArtifacts/ 239 | ModelManifest.xml 240 | 241 | # Paket dependency manager 242 | .paket/paket.exe 243 | 244 | # FAKE - F# Make 245 | .fake/ 246 | /ClipBoardPlus/Graphics 247 | /ClipboardPlus-master.zip 248 | /updatepredicted.txt 249 | -------------------------------------------------------------------------------- /ClipBoardPlus.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.25123.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ClipBoardPlus", "ClipBoardPlus\ClipBoardPlus.vcxproj", "{9F5E0B13-385B-42D0-BD7A-B70124D14616}" 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 | {9F5E0B13-385B-42D0-BD7A-B70124D14616}.Debug|Win32.ActiveCfg = Debug|Win32 17 | {9F5E0B13-385B-42D0-BD7A-B70124D14616}.Debug|x64.ActiveCfg = Debug|x64 18 | {9F5E0B13-385B-42D0-BD7A-B70124D14616}.Debug|x64.Build.0 = Debug|x64 19 | {9F5E0B13-385B-42D0-BD7A-B70124D14616}.Debug|x86.ActiveCfg = Debug|Win32 20 | {9F5E0B13-385B-42D0-BD7A-B70124D14616}.Debug|x86.Build.0 = Debug|Win32 21 | {9F5E0B13-385B-42D0-BD7A-B70124D14616}.Release|x64.ActiveCfg = Release|x64 22 | {9F5E0B13-385B-42D0-BD7A-B70124D14616}.Release|x64.Build.0 = Release|x64 23 | {9F5E0B13-385B-42D0-BD7A-B70124D14616}.Release|x86.ActiveCfg = Release|Win32 24 | {9F5E0B13-385B-42D0-BD7A-B70124D14616}.Release|x86.Build.0 = Release|Win32 25 | EndGlobalSection 26 | GlobalSection(SolutionProperties) = preSolution 27 | HideSolutionNode = FALSE 28 | EndGlobalSection 29 | EndGlobal 30 | -------------------------------------------------------------------------------- /ClipBoardPlus/AboutDlg.cpp: -------------------------------------------------------------------------------- 1 | // AboutDlg.cpp : implementation file 2 | // 3 | 4 | #include "stdafx.h" 5 | #include "ClipBoardPlus.h" 6 | #include "AboutDlg.h" 7 | #include "afxdialogex.h" 8 | 9 | 10 | // CAboutDlg dialog 11 | 12 | IMPLEMENT_DYNAMIC(CAboutDlg, CDialogEx) 13 | 14 | CAboutDlg::CAboutDlg(CWnd* pParent /*=NULL*/) 15 | : CDialogEx(IDD_ABOUTBOX, pParent) 16 | { 17 | 18 | } 19 | 20 | CAboutDlg::~CAboutDlg() 21 | { 22 | } 23 | 24 | void CAboutDlg::DoDataExchange(CDataExchange* pDX) 25 | { 26 | CDialogEx::DoDataExchange(pDX); 27 | } 28 | 29 | 30 | BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx) 31 | END_MESSAGE_MAP() 32 | 33 | 34 | // CAboutDlg message handlers 35 | -------------------------------------------------------------------------------- /ClipBoardPlus/AboutDlg.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | 4 | // CAboutDlg dialog 5 | 6 | class CAboutDlg : public CDialogEx 7 | { 8 | DECLARE_DYNAMIC(CAboutDlg) 9 | 10 | public: 11 | CAboutDlg(CWnd* pParent = NULL); // standard constructor 12 | virtual ~CAboutDlg(); 13 | 14 | // Dialog Data 15 | #ifdef AFX_DESIGN_TIME 16 | enum { IDD = IDD_ABOUTBOX }; 17 | #endif 18 | 19 | protected: 20 | virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support 21 | 22 | DECLARE_MESSAGE_MAP() 23 | }; 24 | -------------------------------------------------------------------------------- /ClipBoardPlus/ClipBoardPlus.cpp: -------------------------------------------------------------------------------- 1 | 2 | // ClipBoardPlus.cpp : Defines the class behaviors for the application. 3 | // 4 | 5 | #include "stdafx.h" 6 | #include "ClipBoardPlus.h" 7 | #include "ClipBoardPlusDlg.h" 8 | 9 | #ifdef _DEBUG 10 | #define new DEBUG_NEW 11 | #endif 12 | 13 | 14 | // CClipBoardPlusApp 15 | 16 | BEGIN_MESSAGE_MAP(CClipBoardPlusApp, CWinApp) 17 | ON_COMMAND(ID_HELP, &CWinApp::OnHelp) 18 | END_MESSAGE_MAP() 19 | 20 | 21 | // CClipBoardPlusApp construction 22 | 23 | CClipBoardPlusApp::CClipBoardPlusApp() 24 | { 25 | // support Restart Manager 26 | m_dwRestartManagerSupportFlags = AFX_RESTART_MANAGER_SUPPORT_RESTART; 27 | 28 | // TODO: add construction code here, 29 | // Place all significant initialization in InitInstance 30 | } 31 | 32 | 33 | // The one and only CClipBoardPlusApp object 34 | 35 | CClipBoardPlusApp theApp; 36 | 37 | 38 | // CClipBoardPlusApp initialization 39 | 40 | BOOL CClipBoardPlusApp::InitInstance() 41 | { 42 | // InitCommonControlsEx() is required on Windows XP if an application 43 | // manifest specifies use of ComCtl32.dll version 6 or later to enable 44 | // visual styles. Otherwise, any window creation will fail. 45 | INITCOMMONCONTROLSEX InitCtrls; 46 | InitCtrls.dwSize = sizeof(InitCtrls); 47 | // Set this to include all the common control classes you want to use 48 | // in your application. 49 | InitCtrls.dwICC = ICC_WIN95_CLASSES; 50 | InitCommonControlsEx(&InitCtrls); 51 | 52 | CWinApp::InitInstance(); 53 | 54 | 55 | // Create the shell manager, in case the dialog contains 56 | // any shell tree view or shell list view controls. 57 | CShellManager *pShellManager = new CShellManager; 58 | 59 | // Activate "Windows Native" visual manager for enabling themes in MFC controls 60 | CMFCVisualManager::SetDefaultManager(RUNTIME_CLASS(CMFCVisualManagerWindows)); 61 | 62 | // Standard initialization 63 | // If you are not using these features and wish to reduce the size 64 | // of your final executable, you should remove from the following 65 | // the specific initialization routines you do not need 66 | // Change the registry key under which our settings are stored 67 | // TODO: You should modify this string to be something appropriate 68 | // such as the name of your company or organization 69 | SetRegistryKey(_T("Oormi Creations")); 70 | 71 | CClipBoardPlusDlg dlg; 72 | m_pMainWnd = &dlg; 73 | INT_PTR nResponse = dlg.DoModal(); 74 | if (nResponse == IDOK) 75 | { 76 | // TODO: Place code here to handle when the dialog is 77 | // dismissed with OK 78 | } 79 | else if (nResponse == IDCANCEL) 80 | { 81 | // TODO: Place code here to handle when the dialog is 82 | // dismissed with Cancel 83 | } 84 | else if (nResponse == -1) 85 | { 86 | TRACE(traceAppMsg, 0, "Warning: dialog creation failed, so application is terminating unexpectedly.\n"); 87 | TRACE(traceAppMsg, 0, "Warning: if you are using MFC controls on the dialog, you cannot #define _AFX_NO_MFC_CONTROLS_IN_DIALOGS.\n"); 88 | } 89 | 90 | // Delete the shell manager created above. 91 | if (pShellManager != NULL) 92 | { 93 | delete pShellManager; 94 | } 95 | 96 | // Since the dialog has been closed, return FALSE so that we exit the 97 | // application, rather than start the application's message pump. 98 | return FALSE; 99 | } 100 | 101 | -------------------------------------------------------------------------------- /ClipBoardPlus/ClipBoardPlus.h: -------------------------------------------------------------------------------- 1 | 2 | // ClipBoardPlus.h : main header file for the PROJECT_NAME application 3 | // 4 | 5 | #pragma once 6 | 7 | #ifndef __AFXWIN_H__ 8 | #error "include 'stdafx.h' before including this file for PCH" 9 | #endif 10 | 11 | #include "resource.h" // main symbols 12 | 13 | 14 | // CClipBoardPlusApp: 15 | // See ClipBoardPlus.cpp for the implementation of this class 16 | // 17 | 18 | class CClipBoardPlusApp : public CWinApp 19 | { 20 | public: 21 | CClipBoardPlusApp(); 22 | 23 | // Overrides 24 | public: 25 | virtual BOOL InitInstance(); 26 | 27 | // Implementation 28 | 29 | DECLARE_MESSAGE_MAP() 30 | }; 31 | 32 | extern CClipBoardPlusApp theApp; -------------------------------------------------------------------------------- /ClipBoardPlus/ClipBoardPlus.rc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oormicreations/ClipboardPlus/5c12e91e287ad68d15f2af375b6a56b9bef22026/ClipBoardPlus/ClipBoardPlus.rc -------------------------------------------------------------------------------- /ClipBoardPlus/ClipBoardPlus.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | {9F5E0B13-385B-42D0-BD7A-B70124D14616} 23 | ClipBoardPlus 24 | 8.1 25 | MFCProj 26 | 27 | 28 | 29 | Application 30 | true 31 | v140 32 | Unicode 33 | Static 34 | 35 | 36 | Application 37 | false 38 | v140 39 | true 40 | Unicode 41 | Static 42 | 43 | 44 | Application 45 | true 46 | v140 47 | Unicode 48 | Static 49 | 50 | 51 | Application 52 | false 53 | v140 54 | true 55 | Unicode 56 | Static 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | true 78 | $(IncludePath) 79 | 80 | 81 | true 82 | 83 | 84 | false 85 | $(IncludePath) 86 | $(LibraryPath) 87 | 88 | 89 | false 90 | 91 | 92 | 93 | Use 94 | Level3 95 | Disabled 96 | WIN32;_WINDOWS;_DEBUG;%(PreprocessorDefinitions) 97 | %(AdditionalIncludeDirectories) 98 | 99 | 100 | Windows 101 | wininet.lib;winmm.lib 102 | %(AdditionalLibraryDirectories) 103 | 104 | 105 | false 106 | true 107 | _DEBUG;%(PreprocessorDefinitions) 108 | 109 | 110 | 0x0409 111 | _DEBUG;%(PreprocessorDefinitions) 112 | $(IntDir);%(AdditionalIncludeDirectories) 113 | 114 | 115 | 116 | 117 | Use 118 | Level3 119 | Disabled 120 | _WINDOWS;_DEBUG;%(PreprocessorDefinitions) 121 | 122 | 123 | Windows 124 | 125 | 126 | false 127 | true 128 | _DEBUG;%(PreprocessorDefinitions) 129 | 130 | 131 | 0x0409 132 | _DEBUG;%(PreprocessorDefinitions) 133 | $(IntDir);%(AdditionalIncludeDirectories) 134 | 135 | 136 | 137 | 138 | Level3 139 | Use 140 | MaxSpeed 141 | true 142 | true 143 | WIN32;_WINDOWS;NDEBUG;%(PreprocessorDefinitions) 144 | %(AdditionalIncludeDirectories) 145 | 146 | 147 | Windows 148 | true 149 | true 150 | wininet.lib;winmm.lib 151 | %(AdditionalLibraryDirectories) 152 | 153 | 154 | false 155 | true 156 | NDEBUG;%(PreprocessorDefinitions) 157 | 158 | 159 | 0x0409 160 | NDEBUG;%(PreprocessorDefinitions) 161 | $(IntDir);%(AdditionalIncludeDirectories) 162 | 163 | 164 | 165 | 166 | Level3 167 | Use 168 | MaxSpeed 169 | true 170 | true 171 | _WINDOWS;NDEBUG;%(PreprocessorDefinitions) 172 | 173 | 174 | Windows 175 | true 176 | true 177 | 178 | 179 | false 180 | true 181 | NDEBUG;%(PreprocessorDefinitions) 182 | 183 | 184 | 0x0409 185 | NDEBUG;%(PreprocessorDefinitions) 186 | $(IntDir);%(AdditionalIncludeDirectories) 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | Create 214 | Create 215 | Create 216 | Create 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | -------------------------------------------------------------------------------- /ClipBoardPlus/ClipBoardPlus.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Header Files 20 | 21 | 22 | Header Files 23 | 24 | 25 | Header Files 26 | 27 | 28 | Header Files 29 | 30 | 31 | Header Files 32 | 33 | 34 | Header Files 35 | 36 | 37 | Header Files 38 | 39 | 40 | Header Files 41 | 42 | 43 | Header Files 44 | 45 | 46 | Header Files 47 | 48 | 49 | Header Files 50 | 51 | 52 | Header Files 53 | 54 | 55 | 56 | 57 | Source Files 58 | 59 | 60 | Source Files 61 | 62 | 63 | Source Files 64 | 65 | 66 | Source Files 67 | 68 | 69 | Source Files 70 | 71 | 72 | Source Files 73 | 74 | 75 | Source Files 76 | 77 | 78 | Source Files 79 | 80 | 81 | Source Files 82 | 83 | 84 | Source Files 85 | 86 | 87 | 88 | 89 | Resource Files 90 | 91 | 92 | 93 | 94 | Resource Files 95 | 96 | 97 | 98 | 99 | Resource Files 100 | 101 | 102 | Resource Files 103 | 104 | 105 | Resource Files 106 | 107 | 108 | Resource Files 109 | 110 | 111 | -------------------------------------------------------------------------------- /ClipBoardPlus/ClipBoardPlusDlg.cpp: -------------------------------------------------------------------------------- 1 |  2 | // ClipBoardPlusDlg.cpp : implementation file 3 | // 4 | 5 | #include "stdafx.h" 6 | #include "ClipBoardPlus.h" 7 | #include "ClipBoardPlusDlg.h" 8 | #include "afxdialogex.h" 9 | #include "AboutDlg.h" 10 | 11 | #ifdef _DEBUG 12 | #define new DEBUG_NEW 13 | #endif 14 | 15 | 16 | // CClipBoardPlusDlg dialog 17 | 18 | 19 | CClipBoardPlusDlg::CClipBoardPlusDlg(CWnd* pParent /*=NULL*/) 20 | : CDialogEx(IDD_CLIPBOARDPLUS_DIALOG, pParent) 21 | { 22 | m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); 23 | m_EdDlg = NULL; 24 | } 25 | 26 | void CClipBoardPlusDlg::DoDataExchange(CDataExchange* pDX) 27 | { 28 | CDialogEx::DoDataExchange(pDX); 29 | DDX_Control(pDX, IDC_BUTTON1, m_ClipButton[0]); 30 | DDX_Control(pDX, IDC_BUTTON2, m_ClipButton[1]); 31 | DDX_Control(pDX, IDC_BUTTON3, m_ClipButton[2]); 32 | DDX_Control(pDX, IDC_BUTTON4, m_ClipButton[3]); 33 | DDX_Control(pDX, IDC_BUTTON5, m_ClipButton[4]); 34 | } 35 | 36 | BEGIN_MESSAGE_MAP(CClipBoardPlusDlg, CDialogEx) 37 | ON_WM_PAINT() 38 | ON_WM_QUERYDRAGICON() 39 | ON_BN_CLICKED(IDC_BUTTON1, &CClipBoardPlusDlg::OnBnClickedButton1) 40 | ON_BN_CLICKED(IDC_BUTTON2, &CClipBoardPlusDlg::OnBnClickedButton2) 41 | ON_WM_DESTROY() 42 | ON_BN_CLICKED(IDOK, &CClipBoardPlusDlg::OnBnClickedOk) 43 | ON_WM_CLIPBOARDUPDATE() 44 | ON_BN_CLICKED(IDC_BUTTON3, &CClipBoardPlusDlg::OnBnClickedButton3) 45 | ON_BN_CLICKED(IDC_BUTTON4, &CClipBoardPlusDlg::OnBnClickedButton4) 46 | ON_BN_CLICKED(IDC_BUTTON5, &CClipBoardPlusDlg::OnBnClickedButton5) 47 | ON_WM_CONTEXTMENU() 48 | ON_COMMAND(ID_MENU_EXIT, &CClipBoardPlusDlg::OnMenuExit) 49 | ON_COMMAND(ID_MENU_CLEAR, &CClipBoardPlusDlg::OnMenuClear) 50 | ON_COMMAND(ID_MENU_CLEARALL, &CClipBoardPlusDlg::OnMenuClearall) 51 | ON_COMMAND(ID_MENU_PASSWORDMODE, &CClipBoardPlusDlg::OnMenuPasswordmode) 52 | ON_COMMAND(ID_MENU_CLEARCLIPBOARD, &CClipBoardPlusDlg::OnMenuClearclipboard) 53 | ON_COMMAND(ID_MENU_SAVE, &CClipBoardPlusDlg::OnMenuSave) 54 | ON_COMMAND(ID_MENU_SAVEALL, &CClipBoardPlusDlg::OnMenuSaveall) 55 | ON_COMMAND(ID_MENU_HELP, &CClipBoardPlusDlg::OnMenuHelp) 56 | ON_MESSAGE(WM_TRAY_MESSAGE, OnTrayNotify) 57 | ON_COMMAND(ID_MENU_MINIMIZETO, &CClipBoardPlusDlg::OnMenuMinimizeto) 58 | ON_COMMAND(ID_TRAY_RESTORE, &CClipBoardPlusDlg::OnTrayRestore) 59 | ON_COMMAND(ID_TRAY_EXIT, &CClipBoardPlusDlg::OnTrayExit) 60 | ON_WM_SHOWWINDOW() 61 | ON_COMMAND(ID_MENU_CHECKFORUPDATES, &CClipBoardPlusDlg::OnMenuCheckforupdates) 62 | ON_COMMAND(ID_MENU_ABOUT, &CClipBoardPlusDlg::OnMenuAbout) 63 | ON_COMMAND(ID_MENU_EDIT, &CClipBoardPlusDlg::OnMenuEdit) 64 | ON_COMMAND(ID_MENU_OPENLINK, &CClipBoardPlusDlg::OnMenuOpenlink) 65 | ON_COMMAND(ID_MENU_GETMOREFREEAPPS, &CClipBoardPlusDlg::OnMenuGetmorefreeapps) 66 | ON_COMMAND(ID_MENU_ADD, &CClipBoardPlusDlg::OnMenuAdd) 67 | ON_COMMAND(ID_MENU_STICKYNOTES, &CClipBoardPlusDlg::OnMenuStickynotes) 68 | ON_MESSAGE(WM_CBP_RESTORE, RestoreHandler) 69 | ON_COMMAND(ID_MENU_REMAINONTOP, &CClipBoardPlusDlg::OnMenuRemainontop) 70 | ON_COMMAND(ID_MENU_REMINDERS, &CClipBoardPlusDlg::OnMenuReminders) 71 | ON_WM_TIMER() 72 | ON_COMMAND(ID_SAVE_DELETEAUTOSAVEDCLIPS, &CClipBoardPlusDlg::OnSaveDeleteautosavedclips) 73 | END_MESSAGE_MAP() 74 | 75 | 76 | // CClipBoardPlusDlg message handlers 77 | LRESULT CClipBoardPlusDlg::RestoreHandler(WPARAM wp, LPARAM lp) 78 | { 79 | MaximizeFromTray(); 80 | return 0; 81 | } 82 | 83 | BOOL CClipBoardPlusDlg::OnInitDialog() 84 | { 85 | CDialogEx::OnInitDialog(); 86 | 87 | // Set the icon for this dialog. The framework does this automatically 88 | // when the application's main window is not a dialog 89 | SetIcon(m_hIcon, TRUE); // Set big icon 90 | SetIcon(m_hIcon, FALSE); // Set small icon 91 | 92 | // TODO: Add extra initialization here 93 | if (!AddClipboardFormatListener(this->GetSafeHwnd())) 94 | { 95 | AfxMessageBox(_T("AddClipboardFormatListener failed!")); 96 | } 97 | 98 | m_CBPVersionMaj = 1; 99 | m_CBPVersionMin = 3; 100 | 101 | m_PasswordMode = TRUE; 102 | m_IsClipBoardPlusEvent = FALSE; 103 | m_TopmostMode = FALSE; 104 | m_RightClickedButton = -1; 105 | 106 | m_MenuPopup.LoadMenu(IDR_MENU_CBP); 107 | 108 | SetupMinimizeToTray(); 109 | InitClips(); 110 | GetClip(); //get already present contents 111 | 112 | InitReminders(); 113 | 114 | m_NetHelper.ReportUsage(_T("ClipboardPlus"), m_CBPVersionMaj*10 + m_CBPVersionMin); 115 | 116 | 117 | 118 | return TRUE; // return TRUE unless you set the focus to a control 119 | } 120 | 121 | // If you add a minimize button to your dialog, you will need the code below 122 | // to draw the icon. For MFC applications using the document/view model, 123 | // this is automatically done for you by the framework. 124 | 125 | void CClipBoardPlusDlg::OnPaint() 126 | { 127 | if (IsIconic()) 128 | { 129 | CPaintDC dc(this); // device context for painting 130 | 131 | SendMessage(WM_ICONERASEBKGND, reinterpret_cast(dc.GetSafeHdc()), 0); 132 | 133 | // Center icon in client rectangle 134 | int cxIcon = GetSystemMetrics(SM_CXICON); 135 | int cyIcon = GetSystemMetrics(SM_CYICON); 136 | CRect rect; 137 | GetClientRect(&rect); 138 | int x = (rect.Width() - cxIcon + 1) / 2; 139 | int y = (rect.Height() - cyIcon + 1) / 2; 140 | 141 | // Draw the icon 142 | dc.DrawIcon(x, y, m_hIcon); 143 | } 144 | else 145 | { 146 | CDialogEx::OnPaint(); 147 | } 148 | } 149 | 150 | // The system calls this function to obtain the cursor to display while the user drags 151 | // the minimized window. 152 | HCURSOR CClipBoardPlusDlg::OnQueryDragIcon() 153 | { 154 | return static_cast(m_hIcon); 155 | } 156 | 157 | void CClipBoardPlusDlg::InitClips() 158 | { 159 | for (int i = 0; i < MAXCLIPS; i++) 160 | { 161 | m_ClipButton[i].SetSkin(IDB_BITMAP_CLIP_COLD, IDB_BITMAP_CLIP_COLD, RGB(60, 60, 60)); 162 | m_Clips[i] = _T(""); 163 | } 164 | 165 | LoadFromBackup(); 166 | } 167 | 168 | void CClipBoardPlusDlg::ClearClip(int nclip) 169 | { 170 | m_Clips[nclip] = _T(""); 171 | m_ClipButton[nclip].SetText(_T("")); 172 | } 173 | 174 | void CClipBoardPlusDlg::MaskClips() 175 | { 176 | for (int i = 0; i < MAXCLIPS; i++) 177 | { 178 | if (IsPassword(m_Clips[i]) && m_PasswordMode) 179 | { 180 | m_ClipButton[i].SetText(_T("* * * * * * * *")); 181 | } 182 | else m_ClipButton[i].SetText(m_Clips[i]); 183 | } 184 | 185 | } 186 | 187 | void CClipBoardPlusDlg::GetClip() 188 | { 189 | CString tmpClip; 190 | CString newClip = GetClipboardText(); 191 | 192 | if (m_Clips[0] == newClip) 193 | { 194 | return; 195 | } 196 | 197 | if (!m_Clips[0].IsEmpty()) 198 | { 199 | for (int i = MAXCLIPS - 1; i > 0; i--) 200 | { 201 | tmpClip = m_Clips[i - 1]; 202 | m_Clips[i] = tmpClip; 203 | m_ClipButton[i].SetText(m_Clips[i]); 204 | } 205 | } 206 | 207 | m_Clips[0] = newClip; 208 | m_ClipButton[0].SetText(m_Clips[0]); 209 | m_ClipButton[0].SetSkin(IDB_BITMAP_CLIP_HOT, IDB_BITMAP_CLIP_HOT, RGB(30, 30, 30)); 210 | 211 | MaskClips(); 212 | 213 | SaveToBackup();//persistant loading 214 | } 215 | 216 | 217 | void CClipBoardPlusDlg::ScrollClips(int nclip) 218 | { 219 | CString tmpClip; 220 | CString hotClip = m_Clips[nclip]; 221 | 222 | for (int i = nclip; i > 0; i--) 223 | { 224 | tmpClip = m_Clips[i - 1]; 225 | m_Clips[i] = tmpClip; 226 | m_ClipButton[i].SetText(m_Clips[i]); 227 | } 228 | 229 | m_Clips[0] = hotClip; 230 | m_ClipButton[0].SetText(m_Clips[0]); 231 | m_ClipButton[0].SetSkin(IDB_BITMAP_CLIP_HOT, IDB_BITMAP_CLIP_HOT, RGB(30, 30, 30)); 232 | 233 | MaskClips(); 234 | 235 | } 236 | 237 | 238 | CString CClipBoardPlusDlg::GetClipboardText() 239 | { 240 | // Try opening the clipboard 241 | if (!OpenClipboard()) 242 | { 243 | //AfxMessageBox(_T("")); 244 | //MS Word or Excel will cause problems by locking up the clipbroad many times. 245 | //So return last clip in case of failure. 246 | return m_Clips[0]; 247 | } 248 | 249 | // Get handle of clipboard object for unicode text 250 | HANDLE hData = GetClipboardData(CF_UNICODETEXT); 251 | if (hData == nullptr) 252 | { 253 | //AfxMessageBox(_T("")); 254 | CloseClipboard(); 255 | return m_Clips[0]; 256 | } 257 | 258 | // Lock the handle to get the actual text pointer 259 | TCHAR * pszText = static_cast(GlobalLock(hData)); 260 | if (pszText == nullptr) 261 | { 262 | //AfxMessageBox(_T("")); 263 | // Release the lock 264 | GlobalUnlock(hData); 265 | 266 | // Release the clipboard 267 | CloseClipboard(); 268 | 269 | return m_Clips[0]; 270 | } 271 | 272 | // Save text in a string class instance 273 | CString text(pszText); 274 | 275 | // Release the lock 276 | GlobalUnlock(hData); 277 | 278 | // Release the clipboard 279 | CloseClipboard(); 280 | 281 | return text; 282 | } 283 | 284 | 285 | BOOL CClipBoardPlusDlg::SetClipboardText(CString text) 286 | { 287 | //if(text.IsEmpty()) return FALSE; 288 | 289 | m_IsClipBoardPlusEvent = TRUE; 290 | 291 | // Try opening the clipboard 292 | if (!OpenClipboard()) 293 | { 294 | return FALSE; 295 | } 296 | 297 | LPTSTR lptstrCopy; 298 | HGLOBAL hglbCopy; 299 | int iSize = (text.GetLength() + 1) * sizeof(TCHAR); 300 | 301 | hglbCopy = GlobalAlloc(GMEM_MOVEABLE, iSize); 302 | if (hglbCopy == NULL) 303 | { 304 | CloseClipboard(); 305 | return FALSE; 306 | } 307 | 308 | // Lock the handle and copy the text to the buffer. 309 | lptstrCopy = (LPTSTR)GlobalLock(hglbCopy); 310 | ZeroMemory(lptstrCopy, iSize); // adds null character also 311 | memcpy(lptstrCopy, text.GetBuffer(), text.GetLength() * sizeof(TCHAR)); 312 | 313 | //lptstrCopy[iSize] = /*(TCHAR)*/0; // null character 314 | GlobalUnlock(hglbCopy); 315 | 316 | EmptyClipboard(); 317 | HANDLE hData = SetClipboardData(CF_UNICODETEXT, hglbCopy); 318 | if (hData == nullptr) 319 | { 320 | CloseClipboard(); 321 | return FALSE; 322 | } 323 | 324 | // Release the clipboard 325 | CloseClipboard(); 326 | 327 | return TRUE; 328 | } 329 | 330 | void CClipBoardPlusDlg::OnDestroy() 331 | { 332 | if (!m_bMinimized) //store window position only if not minimized to tray 333 | { 334 | WINDOWPLACEMENT wp; 335 | GetWindowPlacement(&wp); 336 | AfxGetApp()->WriteProfileBinary(_T("ClipboardPlus"), _T("WP"), (LPBYTE)&wp, sizeof(wp)); 337 | } 338 | 339 | KillTimer(m_uRemTimer); 340 | 341 | CDialogEx::OnDestroy(); 342 | 343 | if (m_bMinimized) 344 | { 345 | Shell_NotifyIcon(NIM_DELETE, &m_TrayData); 346 | } 347 | 348 | // Unload the menu resources 349 | m_MenuTray.DestroyMenu(); 350 | m_MenuPopup.DestroyMenu(); 351 | } 352 | 353 | 354 | void CClipBoardPlusDlg::OnBnClickedOk() 355 | { 356 | if (!RemoveClipboardFormatListener(this->GetSafeHwnd())) 357 | { 358 | AfxMessageBox(_T("RemoveClipboardFormatListener failed!")); 359 | } 360 | 361 | CDialogEx::OnOK(); 362 | } 363 | 364 | 365 | void CClipBoardPlusDlg::OnClipboardUpdate() 366 | { 367 | // This feature requires Windows Vista or greater. 368 | // The symbol _WIN32_WINNT must be >= 0x0600. 369 | 370 | if(!m_IsClipBoardPlusEvent) GetClip(); 371 | m_IsClipBoardPlusEvent = FALSE; 372 | 373 | CDialogEx::OnClipboardUpdate(); 374 | } 375 | 376 | 377 | void CClipBoardPlusDlg::OnBnClickedButton1() 378 | { 379 | 380 | } 381 | 382 | void CClipBoardPlusDlg::OnBnClickedButton2() 383 | { 384 | SetClipboardText(m_Clips[1]); 385 | ScrollClips(1); 386 | } 387 | 388 | void CClipBoardPlusDlg::OnBnClickedButton3() 389 | { 390 | SetClipboardText(m_Clips[2]); 391 | ScrollClips(2); 392 | } 393 | 394 | 395 | void CClipBoardPlusDlg::OnBnClickedButton4() 396 | { 397 | SetClipboardText(m_Clips[3]); 398 | ScrollClips(3); 399 | } 400 | 401 | 402 | void CClipBoardPlusDlg::OnBnClickedButton5() 403 | { 404 | SetClipboardText(m_Clips[4]); 405 | ScrollClips(4); 406 | } 407 | 408 | 409 | void CClipBoardPlusDlg::OnContextMenu(CWnd* /*pWnd*/, CPoint point) 410 | { 411 | CMenu *pSubMenu = m_MenuPopup.GetSubMenu(0); 412 | ASSERT(pSubMenu); 413 | pSubMenu->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, point.x, point.y, this); 414 | 415 | m_RightClickedButton = -1; 416 | CRect brect; 417 | for (int i = 0; i < MAXCLIPS; i++) 418 | { 419 | m_ClipButton[i].GetWindowRect(&brect); 420 | if (brect.PtInRect(point)) 421 | { 422 | m_RightClickedButton = i; 423 | break; 424 | } 425 | } 426 | 427 | //TRACE("b=%d\n", m_RightClickedButton); 428 | } 429 | 430 | 431 | void CClipBoardPlusDlg::OnMenuExit() 432 | { 433 | OnBnClickedOk(); 434 | } 435 | 436 | 437 | void CClipBoardPlusDlg::OnMenuClear() 438 | { 439 | if (m_RightClickedButton >= 0) 440 | { 441 | ClearClip(m_RightClickedButton); 442 | SaveToBackup(); 443 | } 444 | } 445 | 446 | 447 | void CClipBoardPlusDlg::OnMenuClearall() 448 | { 449 | for (int i = 0; i < MAXCLIPS; i++) 450 | { 451 | ClearClip(i); 452 | } 453 | SaveToBackup(); 454 | } 455 | 456 | 457 | void CClipBoardPlusDlg::OnMenuPasswordmode() 458 | { 459 | m_PasswordMode = !m_PasswordMode; 460 | m_MenuPopup.CheckMenuItem(ID_MENU_PASSWORDMODE, (MF_CHECKED * (UINT)m_PasswordMode) | MF_BYCOMMAND); 461 | 462 | MaskClips(); 463 | } 464 | 465 | BOOL CClipBoardPlusDlg::IsPassword(CString clip) 466 | { 467 | if (clip.IsEmpty()) return FALSE; 468 | 469 | //should not be more than one word 470 | if (clip.Find(' ') >= 0) return FALSE; 471 | 472 | //should not be too long, like a link etc 473 | if (clip.GetLength() > MIN_PASSWORD_SZ) return FALSE; 474 | 475 | TCHAR nums[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 476 | L'०', L'१', L'२', L'३', L'४', L'५', L'६', L'७', L'८', L'९'}; //L'x' is necessary 477 | 478 | TCHAR spl[] = { '~', '`', '!', '@', '#', '$', '%', '^', '&', '*', 479 | '(', ')', '-', '_', '+', '=', '|', '\\', '{', '[', '}', ']', 480 | ':', ';', '\"', '\'', '<', ',', '>', '.', '?', '/'}; //32 481 | 482 | BOOL hasnum = FALSE; 483 | BOOL hasspl = FALSE; 484 | 485 | for (int i = 0; i < 20; i++) 486 | { 487 | if (clip.Find(nums[i]) >= 0) 488 | { 489 | hasnum = TRUE; 490 | break; 491 | } 492 | } 493 | 494 | for (int i = 0; i < 32; i++) 495 | { 496 | if (clip.Find(spl[i]) >= 0) 497 | { 498 | hasspl = TRUE; 499 | break; 500 | } 501 | } 502 | 503 | return hasnum && hasspl; 504 | 505 | } 506 | 507 | 508 | 509 | 510 | void CClipBoardPlusDlg::OnMenuClearclipboard() 511 | { 512 | ////EmptyClipboard causes problems 513 | //if (OpenClipboard()) 514 | //{ 515 | // EmptyClipboard(); 516 | // CloseClipboard(); 517 | //} 518 | 519 | m_Clips[0] = _T(""); 520 | m_ClipButton[0].SetText(m_Clips[0]); 521 | SetClipboardText(m_Clips[0]); 522 | 523 | } 524 | 525 | 526 | void CClipBoardPlusDlg::OnMenuSave() 527 | { 528 | if (m_RightClickedButton >= 0) SaveClips(m_Clips[m_RightClickedButton]); 529 | } 530 | 531 | 532 | void CClipBoardPlusDlg::OnMenuSaveall() 533 | { 534 | CString str; 535 | for (int i = 0; i < MAXCLIPS; i++) 536 | { 537 | str = str + "\r\n-------------------------------------------------------------------------------\r\n" + m_Clips[i]; 538 | } 539 | SaveClips(str); 540 | } 541 | 542 | void CClipBoardPlusDlg::SaveClips(CString str) 543 | { 544 | CString fname = CTime::GetCurrentTime().Format("Clips-%Y%m%d-%H%M%S.txt"); 545 | 546 | CSysHelper shelp; 547 | CString idir = shelp.GetUserDocumentPath(CBP_USER_FOLDER); 548 | 549 | CFileDialog ResFileOpenDialog(false, _T("txt"), fname, 550 | OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, _T("Text Files (*.txt)|*.txt|All Files (*.*)|*.*||")); 551 | ResFileOpenDialog.m_ofn.lpstrInitialDir = idir; 552 | 553 | INT_PTR res = ResFileOpenDialog.DoModal(); 554 | 555 | if (res == IDOK) 556 | { 557 | fname = ResFileOpenDialog.GetPathName(); 558 | CFile txtfile; 559 | BOOL res = txtfile.Open(fname, CFile::modeCreate | CFile::modeWrite); 560 | if (!res) 561 | { 562 | AfxMessageBox(_T("Error : Failed to create the file")); 563 | return; 564 | } 565 | txtfile.Write(str, str.GetLength()*sizeof(TCHAR)); 566 | txtfile.Close(); 567 | } 568 | 569 | } 570 | 571 | void CClipBoardPlusDlg::OnMenuHelp() 572 | { 573 | ShellExecute(NULL, _T("open"), _T("https://oormi.in/software/cbp/help110.html"), NULL, NULL, SW_SHOWNORMAL); 574 | } 575 | 576 | afx_msg LRESULT CClipBoardPlusDlg::OnTrayNotify(WPARAM wParam, LPARAM lParam) 577 | { 578 | UINT uID; 579 | UINT uMsg; 580 | CPoint pt; 581 | 582 | uID = (UINT)wParam; 583 | uMsg = (UINT)lParam; 584 | 585 | if (uID != 1) 586 | { 587 | return 0; 588 | } 589 | 590 | switch (uMsg) 591 | { 592 | case WM_LBUTTONDOWN: 593 | GetCursorPos(&pt); 594 | ClientToScreen(&pt); 595 | OnTrayLButtonDown(pt); 596 | break; 597 | 598 | case WM_RBUTTONDOWN: 599 | 600 | case WM_CONTEXTMENU: 601 | GetCursorPos(&pt); 602 | OnTrayRButtonDown(pt); 603 | break; 604 | 605 | } 606 | 607 | return 0; 608 | } 609 | 610 | void CClipBoardPlusDlg::OnTrayLButtonDown(CPoint pt) 611 | { 612 | MaximizeFromTray(); 613 | } 614 | 615 | void CClipBoardPlusDlg::OnTrayRButtonDown(CPoint pt) 616 | { 617 | m_MenuTray.GetSubMenu(0)->TrackPopupMenu(TPM_BOTTOMALIGN | TPM_LEFTBUTTON | TPM_RIGHTBUTTON, pt.x, pt.y, this); 618 | } 619 | 620 | 621 | void CClipBoardPlusDlg::OnMenuMinimizeto() 622 | { 623 | MinimizeToTray(); 624 | } 625 | 626 | void CClipBoardPlusDlg::SetupMinimizeToTray() 627 | { 628 | m_TrayData.cbSize = sizeof(NOTIFYICONDATA); 629 | m_TrayData.hWnd = this->m_hWnd; 630 | m_TrayData.uID = 1; 631 | m_TrayData.uCallbackMessage = WM_TRAY_MESSAGE; 632 | m_TrayData.hIcon = this->m_hIcon; 633 | 634 | wcscpy_s(m_TrayData.szTip, _T("Clipboard Plus")); 635 | m_TrayData.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP; 636 | 637 | BOOL bSuccess = m_MenuTray.LoadMenu(IDR_MENU_TRAY); 638 | if (!(bSuccess)) 639 | { 640 | MessageBox(_T("Unabled to load menu"), _T("Error")); 641 | } 642 | 643 | m_bMinimized = FALSE; 644 | } 645 | 646 | void CClipBoardPlusDlg::MinimizeToTray() 647 | { 648 | BOOL bSuccess = Shell_NotifyIcon(NIM_ADD, &m_TrayData); 649 | if (!(bSuccess)) 650 | { 651 | MessageBox(_T("Unable to set tray icon"), _T("Error")); 652 | } 653 | 654 | this->ShowWindow(SW_MINIMIZE); 655 | this->ShowWindow(SW_HIDE); 656 | 657 | m_bMinimized = TRUE; 658 | } 659 | 660 | void CClipBoardPlusDlg::MaximizeFromTray() 661 | { 662 | this->ShowWindow(SW_SHOW); 663 | this->ShowWindow(SW_RESTORE); 664 | 665 | Shell_NotifyIcon(NIM_DELETE, &m_TrayData); 666 | 667 | m_bMinimized = FALSE; 668 | 669 | SendMessage(WM_SYSCOMMAND, SC_RESTORE, 0); // restore the minimize window 670 | SetForegroundWindow(); 671 | SetActiveWindow(); 672 | SetWindowPos(0, 0, 0, 0, 0, SWP_SHOWWINDOW | SWP_NOMOVE | SWP_NOSIZE); 673 | RedrawWindow(0, 0, RDW_FRAME | RDW_INVALIDATE | RDW_ALLCHILDREN); 674 | 675 | } 676 | 677 | void CClipBoardPlusDlg::OnTrayRestore() 678 | { 679 | MaximizeFromTray(); 680 | } 681 | 682 | 683 | void CClipBoardPlusDlg::OnTrayExit() 684 | { 685 | OnBnClickedOk(); 686 | } 687 | 688 | 689 | void CClipBoardPlusDlg::OnShowWindow(BOOL bShow, UINT nStatus) 690 | { 691 | CDialogEx::OnShowWindow(bShow, nStatus); 692 | 693 | static bool bOnce = true; 694 | 695 | if (bShow && !IsWindowVisible() && bOnce) 696 | { 697 | bOnce = false; 698 | 699 | WINDOWPLACEMENT *lwp; 700 | UINT nl; 701 | 702 | if (AfxGetApp()->GetProfileBinary(_T("ClipboardPlus"), _T("WP"), (LPBYTE*)&lwp, &nl)) 703 | { 704 | SetWindowPlacement(lwp); 705 | delete[] lwp; 706 | } 707 | } 708 | } 709 | 710 | 711 | void CClipBoardPlusDlg::OnMenuAbout() 712 | { 713 | CAboutDlg aboutDlg; 714 | aboutDlg.DoModal(); 715 | } 716 | 717 | void CClipBoardPlusDlg::OnMenuCheckforupdates() 718 | { 719 | m_NetHelper.Checkforupdates(m_CBPVersionMaj, m_CBPVersionMin, 720 | _T("https://oormi.in/software/cbp/updatecbp.txt"), 721 | _T(" https://github.com/oormicreations/ClipboardPlus/releases"), _T("Clipboard Plus App")); 722 | 723 | } 724 | 725 | 726 | 727 | void CClipBoardPlusDlg::OnMenuEdit() 728 | { 729 | if ((m_RightClickedButton >= 0) && (!m_Clips[m_RightClickedButton].IsEmpty())) 730 | { 731 | DisplayNotesDlg(FALSE, m_Clips[m_RightClickedButton]); 732 | SaveToBackup(); 733 | } 734 | } 735 | 736 | 737 | void CClipBoardPlusDlg::OnMenuOpenlink() 738 | { 739 | if (m_RightClickedButton >= 0) 740 | { 741 | if (m_Clips[m_RightClickedButton].Find(_T("http")) >= 0) 742 | { 743 | ShellExecute(NULL, _T("open"), m_Clips[m_RightClickedButton], NULL, NULL, SW_SHOWNORMAL); 744 | } 745 | } 746 | } 747 | 748 | 749 | void CClipBoardPlusDlg::OnMenuGetmorefreeapps() 750 | { 751 | ShellExecute(NULL, _T("open"), _T("https://github.com/oormicreations?tab=repositories"), NULL, NULL, SW_SHOWNORMAL); 752 | } 753 | 754 | 755 | void CClipBoardPlusDlg::OnMenuAdd() 756 | { 757 | if (!m_Clips[m_RightClickedButton].IsEmpty()) 758 | { 759 | DisplayNotesDlg(TRUE, m_Clips[m_RightClickedButton]); 760 | } 761 | } 762 | 763 | 764 | void CClipBoardPlusDlg::OnMenuStickynotes() 765 | { 766 | DisplayNotesDlg(TRUE, _T("")); 767 | } 768 | 769 | 770 | void CClipBoardPlusDlg::DisplayNotesDlg(BOOL isnotes, CString add) 771 | { 772 | if (m_EdDlg == NULL) 773 | { 774 | m_EdDlg = new CClipEditorDlg(this);; 775 | m_EdDlg->m_AddThis = _T(""); 776 | m_EdDlg->m_IsStickyNote = isnotes; 777 | m_EdDlg->m_VerStr.Format(_T("CBP Sticky Clips Ver %d.%d←"), m_CBPVersionMaj, m_CBPVersionMin); 778 | m_EdDlg->Create(IDD_DIALOG_EDIT, this); 779 | } 780 | 781 | m_EdDlg->m_AddThis = _T(""); 782 | m_EdDlg->m_IsStickyNote = isnotes; 783 | 784 | if (isnotes) 785 | { 786 | m_EdDlg->m_AddThis = add; 787 | m_EdDlg->ShowNotesButtons(SW_SHOW); 788 | m_EdDlg->SetWindowText(_T("Sticky Clips")); 789 | m_EdDlg->ReadStickyNotes(); 790 | } 791 | else 792 | { 793 | m_EdDlg->ShowNotesButtons(SW_HIDE); 794 | m_EdDlg->SetWindowText(_T("Edit Clip")); 795 | m_EdDlg->m_ClipEd.SetWindowText(add); 796 | } 797 | 798 | 799 | //if (!m_EdDlg->AnimateWindow(400, AW_SLIDE | AW_VER_POSITIVE)) 800 | //{ 801 | m_EdDlg->ShowWindow(SW_SHOWNORMAL); 802 | //} 803 | 804 | } 805 | 806 | void CClipBoardPlusDlg::OnMenuRemainontop() 807 | { 808 | m_TopmostMode = !m_TopmostMode; 809 | m_MenuPopup.CheckMenuItem(ID_MENU_REMAINONTOP, (MF_CHECKED * (UINT)m_TopmostMode) | MF_BYCOMMAND); 810 | 811 | if(m_TopmostMode) SetWindowPos(&wndTopMost, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); 812 | else SetWindowPos(&wndNoTopMost, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); 813 | } 814 | 815 | void CClipBoardPlusDlg::SaveToBackup() 816 | { 817 | CString sClips; 818 | sClips.Format(_T("CBP Ver %d.%d"), m_CBPVersionMaj, m_CBPVersionMin); 819 | 820 | for (int i = 0; i < MAXCLIPS; i++) 821 | { 822 | if(!m_Clips[i].IsEmpty()) sClips = sClips + _T("←") + m_Clips[i]; 823 | } 824 | 825 | CSysHelper SysHelper; 826 | SysHelper.SaveString(SysHelper.GetAppFileName(CBP_BACKUP_FILE), sClips); 827 | } 828 | 829 | void CClipBoardPlusDlg::LoadFromBackup() 830 | { 831 | CSysHelper SysHelper; 832 | 833 | SysHelper.m_FileName = SysHelper.GetAppFileName(CBP_BACKUP_FILE); 834 | 835 | if (!SysHelper.m_FileName.IsEmpty()) 836 | { 837 | CString sClips = SysHelper.ReadStringFromFile(SysHelper.m_FileName, FALSE); 838 | 839 | if (!sClips.IsEmpty()) 840 | { 841 | if (ParseClips(sClips)) 842 | { 843 | for (int i = 0; i < MAXCLIPS; i++) 844 | { 845 | m_ClipButton[i].SetText(m_Clips[i]); 846 | } 847 | 848 | m_ClipButton[0].SetSkin(IDB_BITMAP_CLIP_HOT, IDB_BITMAP_CLIP_HOT, RGB(30, 30, 30)); 849 | 850 | MaskClips(); 851 | return; 852 | } 853 | } 854 | } 855 | 856 | } 857 | 858 | BOOL CClipBoardPlusDlg::ParseClips(CString clips) 859 | { 860 | int iCount = 0; 861 | int iStart = 0; 862 | CString token; 863 | CString separator = _T("←"); 864 | token = clips.Tokenize(separator, iStart); 865 | 866 | CString sVer; 867 | sVer.Format(_T("CBP Ver %d.%d←"), m_CBPVersionMaj, m_CBPVersionMin); 868 | 869 | token = token + separator; 870 | if (token.Compare(sVer)) 871 | { 872 | //no issues for 1.3, bypass check 873 | //AfxMessageBox(_T("The backup file has some problems.")); 874 | //return FALSE; 875 | } 876 | 877 | while (iStart >= 0) 878 | { 879 | m_Clips[iCount] = clips.Tokenize(separator, iStart); 880 | iCount++; 881 | if (iCount >= MAXCLIPS)break; 882 | } 883 | iCount--; 884 | 885 | if (iCount<1)return FALSE; 886 | return TRUE; 887 | } 888 | 889 | 890 | void CClipBoardPlusDlg::OnMenuReminders() 891 | { 892 | m_RemDlg.DoModal(); 893 | } 894 | 895 | void CClipBoardPlusDlg::InitReminders() 896 | { 897 | m_RemDlg.m_sVer.Format(_T("CBP Ver %d.%d←"), m_CBPVersionMaj, m_CBPVersionMin); 898 | m_RemDlg.LoadReminders(); 899 | m_uRemTimer = SetTimer(WM_TIMER + 1001, 30000, NULL); 900 | } 901 | 902 | void CClipBoardPlusDlg::OnTimer(UINT_PTR nIDEvent) 903 | { 904 | if (nIDEvent == m_uRemTimer) 905 | { 906 | CTime curTime = CTime::GetCurrentTime(); 907 | for (UINT t = 0; t < m_RemDlg.m_uRemCount; t++) 908 | { 909 | if (m_RemDlg.m_rReminders[t].m_sStatus == _T("Expired")) continue; 910 | if (m_RemDlg.m_rReminders[t].m_sStatus == _T("Deleted")) continue; 911 | if (m_RemDlg.m_rReminders[t].m_tRemTime == 0) continue; 912 | if (m_RemDlg.m_rReminders[t].m_tRemTime <= curTime) 913 | { 914 | SendMessage(WM_CBP_RESTORE, 0, 0); 915 | 916 | CSysHelper sysHelper; 917 | CString remalertfile = sysHelper.GetAppFileName(CBP_ALERT_FILE); 918 | if (!remalertfile.IsEmpty()) PlaySound(remalertfile, NULL, SND_FILENAME); 919 | MessageBox(m_RemDlg.m_rReminders[t].GetNotificationStr(), _T("ClipBoard Plus Reminder"), MB_ICONINFORMATION); 920 | 921 | m_RemDlg.m_rReminders[t].m_sStatus = _T("Expired"); 922 | m_RemDlg.SaveReminders(); 923 | } 924 | } 925 | } 926 | 927 | CDialogEx::OnTimer(nIDEvent); 928 | } 929 | 930 | 931 | void CClipBoardPlusDlg::OnSaveDeleteautosavedclips() 932 | { 933 | CSysHelper SysHelper; 934 | SysHelper.SaveString(SysHelper.GetAppFileName(CBP_BACKUP_FILE), _T("")); 935 | 936 | } 937 | -------------------------------------------------------------------------------- /ClipBoardPlus/ClipBoardPlusDlg.h: -------------------------------------------------------------------------------- 1 | 2 | // ClipBoardPlusDlg.h : header file 3 | // 4 | 5 | #pragma once 6 | #include "ClipButton.h" 7 | #include "NetHelper.h" 8 | #include "ClipEditorDlg.h" 9 | #include "SysHelper.h" 10 | #include "ReminderDlg.h" 11 | #include "mmsystem.h" 12 | 13 | 14 | #define MAXCLIPS 5 15 | #define WM_TRAY_MESSAGE (WM_USER + 1) 16 | #define MIN_PASSWORD_SZ 16 17 | 18 | // CClipBoardPlusDlg dialog 19 | class CClipBoardPlusDlg : public CDialogEx 20 | { 21 | // Construction 22 | public: 23 | CClipBoardPlusDlg(CWnd* pParent = NULL); // standard constructor 24 | 25 | // Dialog Data 26 | CString m_Clips[MAXCLIPS]; 27 | CClipButton m_ClipButton[MAXCLIPS]; 28 | BOOL m_PasswordMode, m_TopmostMode; 29 | BOOL m_IsClipBoardPlusEvent; 30 | int m_RightClickedButton; 31 | CMenu m_MenuPopup, m_MenuTray; 32 | NOTIFYICONDATA m_TrayData; 33 | BOOL m_bMinimized; 34 | int m_CBPVersionMaj, m_CBPVersionMin; 35 | CNetHelper m_NetHelper; 36 | CClipEditorDlg *m_EdDlg; 37 | CReminderDlg m_RemDlg; 38 | UINT m_uRemTimer; 39 | 40 | 41 | void InitClips(); 42 | void GetClip(); 43 | CString GetClipboardText(); 44 | BOOL SetClipboardText(CString text); 45 | void ScrollClips(int nclip); 46 | void ClearClip(int nclip); 47 | BOOL IsPassword(CString clip); 48 | void MaskClips(); 49 | void SaveClips(CString str); 50 | void OnTrayLButtonDown(CPoint pt); 51 | void OnTrayRButtonDown(CPoint pt); 52 | void SetupMinimizeToTray(); 53 | void MinimizeToTray(); 54 | void MaximizeFromTray(); 55 | void DisplayNotesDlg(BOOL isnotes, CString add); 56 | 57 | void SaveToBackup(); 58 | void LoadFromBackup(); 59 | BOOL ParseClips(CString notes); 60 | 61 | void InitReminders(); 62 | 63 | #ifdef AFX_DESIGN_TIME 64 | enum { IDD = IDD_CLIPBOARDPLUS_DIALOG }; 65 | #endif 66 | 67 | protected: 68 | virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support 69 | 70 | 71 | // Implementation 72 | protected: 73 | HICON m_hIcon; 74 | 75 | // Generated message map functions 76 | virtual BOOL OnInitDialog(); 77 | afx_msg void OnPaint(); 78 | afx_msg HCURSOR OnQueryDragIcon(); 79 | afx_msg LRESULT OnTrayNotify(WPARAM wParam, LPARAM lParam); 80 | 81 | DECLARE_MESSAGE_MAP() 82 | public: 83 | afx_msg void OnBnClickedButton1(); 84 | afx_msg void OnBnClickedButton2(); 85 | afx_msg void OnDestroy(); 86 | afx_msg void OnBnClickedOk(); 87 | afx_msg void OnClipboardUpdate(); 88 | afx_msg void OnBnClickedButton3(); 89 | afx_msg void OnBnClickedButton4(); 90 | afx_msg void OnBnClickedButton5(); 91 | afx_msg void OnContextMenu(CWnd* /*pWnd*/, CPoint /*point*/); 92 | afx_msg void OnMenuExit(); 93 | afx_msg void OnMenuClear(); 94 | afx_msg void OnMenuClearall(); 95 | afx_msg void OnMenuPasswordmode(); 96 | afx_msg void OnMenuClearclipboard(); 97 | afx_msg void OnMenuSave(); 98 | afx_msg void OnMenuSaveall(); 99 | afx_msg void OnMenuHelp(); 100 | afx_msg void OnMenuMinimizeto(); 101 | afx_msg void OnTrayRestore(); 102 | afx_msg void OnTrayExit(); 103 | afx_msg void OnShowWindow(BOOL bShow, UINT nStatus); 104 | afx_msg void OnMenuCheckforupdates(); 105 | afx_msg void OnMenuAbout(); 106 | afx_msg void OnMenuEdit(); 107 | afx_msg void OnMenuOpenlink(); 108 | afx_msg void OnMenuGetmorefreeapps(); 109 | afx_msg void OnMenuAdd(); 110 | afx_msg void OnMenuStickynotes(); 111 | afx_msg LRESULT RestoreHandler(WPARAM wp, LPARAM lp); 112 | 113 | afx_msg void OnMenuRemainontop(); 114 | afx_msg void OnMenuReminders(); 115 | afx_msg void OnTimer(UINT_PTR nIDEvent); 116 | afx_msg void OnSaveDeleteautosavedclips(); 117 | }; 118 | -------------------------------------------------------------------------------- /ClipBoardPlus/ClipButton.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "ClipButton.h" 3 | #include "resource.h" // main symbols 4 | 5 | 6 | CClipButton::CClipButton() 7 | { 8 | m_IsHot = FALSE; 9 | } 10 | 11 | 12 | CClipButton::~CClipButton() 13 | { 14 | } 15 | 16 | BEGIN_MESSAGE_MAP(CClipButton, CButton) 17 | ON_WM_ERASEBKGND() 18 | ON_WM_KILLFOCUS() 19 | ON_WM_DESTROY() 20 | ON_WM_MOUSEHOVER() 21 | ON_WM_MOUSEMOVE() 22 | ON_WM_MOUSELEAVE() 23 | END_MESSAGE_MAP() 24 | 25 | 26 | BOOL CClipButton::OnEraseBkgnd(CDC* pDC) 27 | { 28 | return TRUE; 29 | //return CButton::OnEraseBkgnd(pDC); 30 | } 31 | 32 | 33 | void CClipButton::OnKillFocus(CWnd* pNewWnd) 34 | { 35 | CButton::OnKillFocus(pNewWnd); 36 | 37 | this->Invalidate(); 38 | } 39 | 40 | 41 | void CClipButton::SetSkin(UINT uiNormal, UINT uiDisabled, COLORREF clrTextColor) 42 | { 43 | m_NormalBitmapDC.DeleteObject(); 44 | m_DisabledBitmapDC.DeleteObject(); 45 | 46 | if (uiNormal > 0) 47 | { 48 | m_NormalBitmapDC.LoadBitmap(uiNormal); 49 | } 50 | if (uiDisabled > 0) 51 | { 52 | m_DisabledBitmapDC.LoadBitmap(uiDisabled); 53 | } 54 | 55 | m_TextColor = clrTextColor; 56 | } 57 | 58 | void CClipButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) 59 | { 60 | ASSERT(lpDrawItemStruct); 61 | 62 | CDC btnDC; 63 | btnDC.Attach(lpDrawItemStruct->hDC); 64 | 65 | BITMAP bmpStruct; 66 | 67 | CRect btnRect; 68 | GetClientRect(&btnRect); 69 | 70 | CDC *bmpDC = new CDC(); 71 | bmpDC->CreateCompatibleDC(&btnDC); 72 | bmpDC->SelectObject(m_NormalBitmapDC); 73 | m_NormalBitmapDC.GetBitmap(&bmpStruct); 74 | 75 | const int padding = 0; 76 | btnDC.StretchBlt(padding, padding, btnRect.Width() - (2 * padding), btnRect.Height() - (2 * padding), 77 | bmpDC, 0, 0, bmpStruct.bmWidth, bmpStruct.bmHeight, SRCCOPY); 78 | 79 | CRect textRect; 80 | textRect = lpDrawItemStruct->rcItem; 81 | textRect.left = textRect.left + 10; 82 | 83 | int oldMode = btnDC.SetBkMode(TRANSPARENT); 84 | COLORREF oldColor = btnDC.SetTextColor(m_TextColor); 85 | 86 | CSize sz; 87 | sz = btnDC.GetTextExtent(m_BtnText); 88 | 89 | BOOL bNoOfLines = FALSE; 90 | UINT uiDrawTextFormat = DT_LEFT | DT_VCENTER | DT_SINGLELINE; 91 | 92 | int iOffset = btnDC.DrawText(m_BtnText, textRect, uiDrawTextFormat); 93 | 94 | btnDC.DeleteDC(); 95 | bmpDC->DeleteDC(); 96 | delete bmpDC; 97 | 98 | } 99 | 100 | 101 | void CClipButton::OnDestroy() 102 | { 103 | CButton::OnDestroy(); 104 | 105 | m_NormalBitmapDC.DeleteObject(); 106 | m_DisabledBitmapDC.DeleteObject(); 107 | } 108 | 109 | void CClipButton::SetText(CString btext) 110 | { 111 | btext.Replace(_T("\r\n"), _T(" ")); 112 | 113 | int iLength = btext.GetLength(); 114 | if (iLength > 45) 115 | { 116 | btext.Truncate(45); 117 | btext = btext + _T(" ..."); 118 | } 119 | 120 | m_BtnText = btext; 121 | this->Invalidate(); 122 | 123 | } 124 | 125 | void CClipButton::OnMouseHover(UINT nFlags, CPoint point) 126 | { 127 | SetSkin(IDB_BITMAP_CLIP_HOT, IDB_BITMAP_CLIP_HOT, RGB(30, 30, 30)); 128 | Invalidate(); 129 | 130 | CButton::OnMouseHover(nFlags, point); 131 | } 132 | 133 | 134 | void CClipButton::OnMouseMove(UINT nFlags, CPoint point) 135 | { 136 | if (!m_IsHot) 137 | { 138 | TRACKMOUSEEVENT tme; 139 | tme.cbSize = sizeof(TRACKMOUSEEVENT); 140 | tme.dwFlags = TME_HOVER | TME_LEAVE; 141 | tme.dwHoverTime = 100; 142 | tme.hwndTrack = this->GetSafeHwnd(); 143 | TrackMouseEvent(&tme); 144 | m_IsHot = TRUE; 145 | //TRACE("track\n"); 146 | } 147 | CButton::OnMouseMove(nFlags, point); 148 | } 149 | 150 | 151 | void CClipButton::OnMouseLeave() 152 | { 153 | if (m_IsHot) 154 | { 155 | SetSkin(IDB_BITMAP_CLIP_COLD, IDB_BITMAP_CLIP_COLD, RGB(60, 60, 60)); 156 | Invalidate(); 157 | m_IsHot = FALSE; 158 | } 159 | 160 | CButton::OnMouseLeave(); 161 | } 162 | -------------------------------------------------------------------------------- /ClipBoardPlus/ClipButton.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "afxwin.h" 3 | class CClipButton : 4 | public CButton 5 | { 6 | public: 7 | CClipButton(); 8 | ~CClipButton(); 9 | 10 | CBitmap m_NormalBitmapDC; 11 | CBitmap m_DisabledBitmapDC; 12 | COLORREF m_TextColor; 13 | CString m_BtnText; 14 | BOOL m_IsHot; 15 | 16 | void SetSkin(UINT uiNormal, UINT uiDisabled, COLORREF clrTextColor); 17 | void SetText(CString btext); 18 | virtual void DrawItem(LPDRAWITEMSTRUCT /*lpDrawItemStruct*/); 19 | 20 | DECLARE_MESSAGE_MAP() 21 | afx_msg BOOL OnEraseBkgnd(CDC* pDC); 22 | afx_msg void OnKillFocus(CWnd* pNewWnd); 23 | afx_msg void OnDestroy(); 24 | afx_msg void OnMouseHover(UINT nFlags, CPoint point); 25 | afx_msg void OnMouseMove(UINT nFlags, CPoint point); 26 | afx_msg void OnMouseLeave(); 27 | }; 28 | 29 | -------------------------------------------------------------------------------- /ClipBoardPlus/ClipEditorDlg.cpp: -------------------------------------------------------------------------------- 1 | // ClipEditorDlg.cpp : implementation file 2 | // 3 | 4 | #include "stdafx.h" 5 | #include "ClipBoardPlus.h" 6 | #include "ClipEditorDlg.h" 7 | #include "afxdialogex.h" 8 | #include 9 | #include "mmsystem.h" 10 | 11 | // CClipEditorDlg dialog 12 | 13 | IMPLEMENT_DYNAMIC(CClipEditorDlg, CDialog) 14 | 15 | CClipEditorDlg::CClipEditorDlg(CWnd* pParent /*=NULL*/) 16 | : CDialog(IDD_DIALOG_EDIT, pParent) 17 | { 18 | m_BkBrush = 0; 19 | m_EdFont = NULL; 20 | m_RemCount = 0; 21 | 22 | for (int i = 0; i < MAX_REMINDERS; i++) m_Timer[i] = 0; 23 | } 24 | 25 | CClipEditorDlg::~CClipEditorDlg() 26 | { 27 | } 28 | 29 | void CClipEditorDlg::DoDataExchange(CDataExchange* pDX) 30 | { 31 | CDialog::DoDataExchange(pDX); 32 | DDX_Control(pDX, IDC_EDIT_CLIP, m_ClipEd); 33 | DDX_Control(pDX, IDC_SLIDER_BROWSE, m_SliderBrowse); 34 | } 35 | 36 | 37 | BEGIN_MESSAGE_MAP(CClipEditorDlg, CDialog) 38 | ON_BN_CLICKED(IDOK, &CClipEditorDlg::OnBnClickedOk) 39 | ON_BN_CLICKED(IDC_ADDNOTE, &CClipEditorDlg::OnBnClickedAddnote) 40 | ON_BN_CLICKED(IDC_PRENOTE, &CClipEditorDlg::OnBnClickedPrenote) 41 | ON_BN_CLICKED(IDC_NEXTNOTE, &CClipEditorDlg::OnBnClickedNextnote) 42 | ON_BN_CLICKED(IDC_DELNOTE, &CClipEditorDlg::OnBnClickedDelnote) 43 | ON_BN_CLICKED(IDCANCEL, &CClipEditorDlg::OnBnClickedCancel) 44 | ON_WM_CTLCOLOR() 45 | ON_WM_DESTROY() 46 | ON_WM_PAINT() 47 | ON_BN_CLICKED(IDC_COPYNOTE, &CClipEditorDlg::OnBnClickedCopynote) 48 | ON_EN_CHANGE(IDC_EDIT_CLIP, &CClipEditorDlg::OnEnChangeEditClip) 49 | ON_WM_TIMER() 50 | ON_WM_VSCROLL() 51 | ON_EN_KILLFOCUS(IDC_EDIT_CLIP, &CClipEditorDlg::OnEnKillfocusEditClip) 52 | END_MESSAGE_MAP() 53 | 54 | 55 | // CClipEditorDlg message handlers 56 | 57 | 58 | BOOL CClipEditorDlg::OnInitDialog() 59 | { 60 | CDialog::OnInitDialog(); 61 | 62 | // TODO: Add extra initialization here 63 | CWnd *pwnd = GetParent(); 64 | CRect wrect; 65 | pwnd->GetWindowRect(&wrect); 66 | int ht = wrect.Height(); 67 | wrect.top = wrect.top + ht; 68 | wrect.bottom = wrect.bottom + ht; 69 | MoveWindow(wrect); 70 | 71 | //GetDlgItem(IDC_EDIT_NOTECOUNT)->MoveWindow(14, 0, wrect.Width()/2, 14); 72 | //GetDlgItem(IDC_EDIT_NOTEINFO)->MoveWindow(wrect.Width() / 2, 0, wrect.Width()-14, 14); 73 | 74 | SetNotesFont(); 75 | m_HasChanged = FALSE; 76 | 77 | m_SliderBrowse.SetRange(0, 100); 78 | 79 | SetToolTips(); 80 | 81 | return TRUE; // return TRUE unless you set the focus to a control 82 | // EXCEPTION: OCX Property Pages should return FALSE 83 | } 84 | 85 | void CClipEditorDlg::ShowNotesButtons(int show) 86 | { 87 | GetDlgItem(IDC_ADDNOTE)->ShowWindow(show); 88 | GetDlgItem(IDC_DELNOTE)->ShowWindow(show); 89 | //GetDlgItem(IDC_PRENOTE)->ShowWindow(show); 90 | //GetDlgItem(IDC_NEXTNOTE)->ShowWindow(show); 91 | GetDlgItem(IDC_COPYNOTE)->ShowWindow(show); 92 | GetDlgItem(IDCANCEL)->ShowWindow(!show); 93 | m_SliderBrowse.ShowWindow(show); 94 | } 95 | 96 | void CClipEditorDlg::SetNotesFont() 97 | { 98 | CString fontname = _T("Georgia"); 99 | int fontsz = 16; 100 | if (!m_SysHelper.IsFontInstalled(fontname)) 101 | { 102 | fontname = _T("Courier New"); 103 | fontsz = 16; 104 | } 105 | 106 | m_EdFont = new CFont; 107 | m_EdFont->CreateFontW(fontsz, 0, 0, 0, FW_NORMAL, 0, 0, 0, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH, fontname); 108 | 109 | m_ClipEd.SetFont(m_EdFont); 110 | } 111 | 112 | void CClipEditorDlg::OnBnClickedOk() 113 | { 114 | if (!m_IsStickyNote) 115 | { 116 | m_ClipEd.GetWindowText(m_ClipText); 117 | m_SysHelper.SetClipboardText(m_ClipText); 118 | } 119 | else 120 | { 121 | //ShowChangedNotice(); 122 | if (m_HasChanged) 123 | { 124 | if (m_NoteCount > 0) 125 | { 126 | CString notes = m_VerStr; 127 | for (int n = 0; n < m_NoteCount; n++) 128 | { 129 | if (!m_Notes[n].IsEmpty()) notes = notes + m_Notes[n] + _T("←"); 130 | } 131 | 132 | m_SysHelper.SaveString(m_SysHelper.m_FileName, notes); 133 | } 134 | } 135 | 136 | } 137 | 138 | CDialog::OnOK(); 139 | } 140 | 141 | void CClipEditorDlg::ShowChangedNotice() 142 | { 143 | if (m_HasChanged) 144 | { 145 | int res = AfxMessageBox(_T("Do you wish to save the edited clip?"), MB_YESNO); 146 | if (res == IDYES) 147 | { 148 | OnBnClickedAddnote(); 149 | } 150 | else m_HasChanged = FALSE; 151 | } 152 | } 153 | 154 | BOOL CClipEditorDlg::ReadStickyNotes() 155 | { 156 | m_DispNote = 0; 157 | m_NoteCount = 0; 158 | 159 | m_SysHelper.m_FileName = m_SysHelper.GetAppFileName(CBP_SNOTES_FILE); 160 | 161 | if (!m_SysHelper.m_FileName.IsEmpty()) 162 | { 163 | BOOL res = m_SysHelper.CreateFileAndInit(m_SysHelper.m_FileName, m_VerStr); 164 | 165 | if (res) 166 | { 167 | CString notes = m_SysHelper.ReadStringFromFile(m_SysHelper.m_FileName); 168 | 169 | if (!notes.IsEmpty()) 170 | { 171 | if (ParseNotes(notes)) 172 | { 173 | m_DispNote = m_NoteCount - 1; 174 | DisplayNote(); 175 | } 176 | else 177 | { 178 | m_ClipEd.SetWindowText(_T("How does it work?\r\n\r\n\ 179 | C : Copy Clip\r\n+ : New Clip\r\n- : Delete Clip\r\n✓ : Save and Close\r\nSlider: Browse\ 180 | \r\nset reminder 11:30 call someone\r\nset reminder 2h 15m go jogging and drop trash\r\nPress add + button to set a reminder as above")); 181 | } 182 | 183 | m_SliderBrowse.SetRange(1, m_NoteCount); 184 | m_SliderBrowse.SetPos(m_NoteCount); 185 | 186 | if (!m_AddThis.IsEmpty()) 187 | { 188 | m_ClipEd.SetWindowText(m_AddThis); 189 | OnBnClickedAddnote(); 190 | } 191 | 192 | return TRUE; 193 | } 194 | 195 | 196 | 197 | } 198 | } 199 | 200 | return FALSE; 201 | } 202 | 203 | BOOL CClipEditorDlg::ParseNotes(CString notes) 204 | { 205 | m_NoteCount = 0; 206 | int start = 0; 207 | CString token; 208 | CString separator = _T("←"); 209 | token = notes.Tokenize(separator, start); 210 | 211 | token = token + separator; 212 | 213 | //Disable ver check for this ver 214 | //if (token.Compare(m_VerStr)) 215 | //{ 216 | // AfxMessageBox(_T("The sticky clips file has some problems.")); 217 | // return FALSE; 218 | //} 219 | 220 | while (start >= 0) 221 | { 222 | m_Notes[m_NoteCount] = notes.Tokenize(separator, start); 223 | m_NoteCount++; 224 | if (m_NoteCount > MAX_NOTES)break; 225 | } 226 | m_NoteCount--; 227 | 228 | if(m_NoteCount<1)return FALSE; 229 | return TRUE; 230 | } 231 | 232 | 233 | void CClipEditorDlg::OnBnClickedAddnote() 234 | { 235 | if (m_NoteCount >= MAX_NOTES) 236 | { 237 | AfxMessageBox(_T("You have too many notes. Delete some to make room.")); 238 | return; 239 | } 240 | 241 | CString note, str; 242 | if (m_IsStickyNote) 243 | { 244 | note = m_AddThis; 245 | m_ClipEd.SetWindowText(note); 246 | m_HasChanged = TRUE; 247 | } 248 | else m_ClipEd.SetWindowText(_T("")); 249 | 250 | 251 | CString time = CTime::GetCurrentTime().Format("%Y-%m-%d %H:%M:%S"); 252 | 253 | m_Notes[m_NoteCount] = note + _T("⧖") + time; 254 | m_NoteCount++; 255 | m_DispNote = m_NoteCount - 1; 256 | 257 | m_SliderBrowse.SetRange(1, m_NoteCount); 258 | m_SliderBrowse.SetPos(m_NoteCount); 259 | 260 | DisplayNote(); 261 | } 262 | 263 | 264 | void CClipEditorDlg::OnBnClickedPrenote() 265 | { 266 | ShowChangedNotice(); 267 | 268 | if (m_DispNote > 0) 269 | { 270 | m_DispNote--; 271 | m_ClipEd.SetWindowText(m_Notes[m_DispNote]); 272 | DisplayNote(); 273 | } 274 | } 275 | 276 | 277 | void CClipEditorDlg::OnBnClickedNextnote() 278 | { 279 | ShowChangedNotice(); 280 | 281 | if (m_DispNote < m_NoteCount - 1) 282 | { 283 | m_DispNote++; 284 | m_ClipEd.SetWindowText(m_Notes[m_DispNote]); 285 | DisplayNote(); 286 | } 287 | } 288 | 289 | 290 | void CClipEditorDlg::OnBnClickedDelnote() 291 | { 292 | if (m_NoteCount < 1)return; 293 | 294 | m_Notes[m_DispNote] = _T("Deleted"); 295 | 296 | CString notes = m_VerStr; 297 | for (int n = 0; n < m_NoteCount; n++) 298 | { 299 | if(m_Notes[n] != _T("Deleted")) notes = notes + m_Notes[n] + _T("←"); 300 | } 301 | 302 | m_SysHelper.SaveString(m_SysHelper.m_FileName, notes); 303 | 304 | for (int n = m_DispNote; n < m_NoteCount-1; n++) 305 | { 306 | m_Notes[n] = m_Notes[n+1]; 307 | } 308 | 309 | m_NoteCount--; 310 | 311 | if (m_NoteCount < m_DispNote + 1) 312 | { 313 | m_DispNote = m_NoteCount - 1; 314 | } 315 | 316 | if (m_NoteCount < 1) 317 | { 318 | m_NoteCount = 0; 319 | m_Notes[m_NoteCount] = _T(""); 320 | m_DispNote = 0; 321 | } 322 | 323 | m_SliderBrowse.SetRange(1, m_NoteCount); 324 | 325 | DisplayNote(); 326 | } 327 | 328 | 329 | void CClipEditorDlg::OnBnClickedCancel() 330 | { 331 | if (m_IsStickyNote) 332 | { 333 | m_ClipEd.SetWindowText(_T("")); 334 | SetDlgItemText(IDC_EDIT_NOTEINFO, _T("")); 335 | SetDlgItemText(IDC_EDIT_NOTECOUNT, _T("")); 336 | } 337 | else 338 | { 339 | CDialog::OnCancel(); 340 | } 341 | } 342 | 343 | 344 | HBRUSH CClipEditorDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) 345 | { 346 | HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor); 347 | 348 | // TODO: Change any attributes of the DC here 349 | int id = pWnd->GetDlgCtrlID(); 350 | 351 | if ((id == IDC_EDIT_CLIP))// || (id == IDC_EDIT_NOTECOUNT) || (id == IDC_EDIT_NOTEINFO)) 352 | { 353 | COLORREF bkc = RGB(255, 255, 220); 354 | pDC->SetTextColor(RGB(0, 0, 170)); 355 | pDC->SetBkColor(bkc); 356 | 357 | if (!m_BkBrush) m_BkBrush = CreateSolidBrush(bkc); 358 | hbr = m_BkBrush; 359 | } 360 | 361 | // TODO: Return a different brush if the default is not desired 362 | return hbr; 363 | } 364 | 365 | 366 | void CClipEditorDlg::OnDestroy() 367 | { 368 | CDialog::OnDestroy(); 369 | 370 | if (m_BkBrush != NULL) 371 | { 372 | DeleteObject(m_BkBrush); 373 | m_BkBrush = NULL; 374 | } 375 | 376 | if(m_EdFont!=NULL) delete m_EdFont; 377 | if (m_ToolTip) delete m_ToolTip; 378 | 379 | //its modeless so delete manually 380 | delete this; 381 | } 382 | 383 | 384 | void CClipEditorDlg::DisplayNote() 385 | { 386 | CString str; 387 | if (m_NoteCount > 0) 388 | { 389 | str.Format(_T("%03d | %03d"), m_DispNote + 1, m_NoteCount); 390 | } 391 | SetDlgItemText(IDC_EDIT_NOTECOUNT, str); 392 | 393 | int pos = m_Notes[m_DispNote].Find(_T("⧖")); 394 | str = m_Notes[m_DispNote].Right(m_Notes[m_DispNote].GetLength() - pos - 1); 395 | SetDlgItemText(IDC_EDIT_NOTEINFO, str); 396 | 397 | str = m_Notes[m_DispNote].Left(pos); 398 | SetDlgItemText(IDC_EDIT_CLIP, str); 399 | } 400 | 401 | 402 | 403 | void CClipEditorDlg::OnPaint() 404 | { 405 | CPaintDC dc(this); // device context for painting 406 | // TODO: Add your message handler code here 407 | // Do not call CDialog::OnPaint() for painting messages 408 | 409 | //CRect rect; 410 | //GetClientRect(&rect); 411 | //dc.FillSolidRect(rect, RGB(255, 255, 190)); 412 | } 413 | 414 | 415 | void CClipEditorDlg::OnBnClickedCopynote() 416 | { 417 | CString str; 418 | GetDlgItemText(IDC_EDIT_CLIP, str); 419 | m_SysHelper.SetClipboardText(str); 420 | } 421 | 422 | 423 | void CClipEditorDlg::OnEnChangeEditClip() 424 | { 425 | // TODO: If this is a RICHEDIT control, the control will not 426 | // send this notification unless you override the CDialog::OnInitDialog() 427 | // function and call CRichEditCtrl().SetEventMask() 428 | // with the ENM_CHANGE flag ORed into the mask. 429 | 430 | // TODO: Add your control notification handler code here 431 | m_HasChanged = TRUE; 432 | } 433 | 434 | void CClipEditorDlg::Process(CString note) 435 | { 436 | CString str, hr, min; 437 | BOOL isduration = FALSE; 438 | int pos = 0; 439 | 440 | ////test 441 | //note = _T("Set reminder 12:52 x:yz"); 442 | //note = _T("Set reminder 2h 12m abch xyzm "); 443 | pos = note.Find(_T("⧖")); 444 | note = note.Left(pos); 445 | 446 | note.MakeLower(); 447 | note.Replace(_T("\r\n"), _T(" ")); 448 | note.Replace(_T(" "), _T(" ")); 449 | note.Trim(); 450 | 451 | str = _T("set reminder"); 452 | pos = note.Find(str); 453 | if (pos == 0) 454 | { 455 | note.Replace(str, _T("")); 456 | 457 | pos = note.Find(_T(":")); 458 | if ((pos > 0) && (pos < 5)) 459 | { 460 | hr = note.Left(pos); 461 | note.Replace(hr, _T("")); 462 | hr.Trim(); 463 | 464 | pos = note.Find(_T(" ")); 465 | if ((pos > 0) && (pos < 4)) 466 | { 467 | min = note.Left(pos); 468 | note.Replace(min, _T("")); 469 | min.Trim(); 470 | min.Trim(':'); 471 | } 472 | 473 | note.Trim(); 474 | } 475 | else 476 | { 477 | pos = note.Find(_T("h ")); 478 | if ((pos > 0) && (pos < 5)) 479 | { 480 | hr = note.Left(pos); 481 | note.Replace(hr + _T("h "), _T("")); 482 | hr.Trim(); 483 | } 484 | 485 | pos = note.Find(_T("m ")); 486 | if ((pos > 0) && (pos < 4)) 487 | { 488 | min = note.Left(pos); 489 | note.Replace(min + _T("m "), _T("")); 490 | min.Trim(); 491 | } 492 | 493 | isduration = TRUE; 494 | } 495 | 496 | int h = _ttoi(hr); 497 | int m = _ttoi(min); 498 | long duration = 0; 499 | 500 | CTime time = CTime::GetCurrentTime(); 501 | int h1 = time.GetHour(); 502 | int m1 = time.GetMinute(); 503 | int totalmin = h1 * 60 + m1; 504 | int remmin = h * 60 + m; 505 | 506 | if (isduration) duration = (h * 60 + m); 507 | else 508 | { 509 | if ((h > 23) || (m > 59)) 510 | { 511 | AfxMessageBox(_T("Hour/min are out of range (23,59)"), MB_ICONERROR); 512 | return; 513 | } 514 | 515 | 516 | if (remmin > totalmin) 517 | { 518 | duration = (remmin - totalmin); 519 | } 520 | else 521 | { 522 | AfxMessageBox(_T("Error: Reminder is in past."), MB_ICONERROR); 523 | return; 524 | } 525 | } 526 | 527 | if (duration < 1) 528 | { 529 | AfxMessageBox(_T("Error: Time duration was not found."), MB_ICONERROR); 530 | return; 531 | } 532 | else 533 | { 534 | if (isduration) 535 | { 536 | h = h + h1; 537 | if (h > 23) 538 | { 539 | h = h - 24; 540 | } 541 | m = m + m1; 542 | if (m > 59) 543 | { 544 | h++; 545 | m = m - 60; 546 | } 547 | } 548 | 549 | int h3 = duration / 60; 550 | int m3 = duration % 60; 551 | 552 | if (m_RemCount >= MAX_REMINDERS) 553 | { 554 | m_RemCount = 0; 555 | } 556 | 557 | m_RemText[m_RemCount] = note; 558 | if (m_RemText[m_RemCount].GetLength()>150) m_RemText[m_RemCount].Truncate(150); 559 | 560 | str.Format(_T("Reminder set for\r\n\r\n%s ...\r\n\r\nAt time %02d:%02d. Due in %d hours %d minutes"), m_RemText[m_RemCount], h, m, h3, m3); 561 | } 562 | //str.Format(_T("Reminder set for\n%s\non %d:%d\n%d"), note, h, m, duration); 563 | 564 | KillTimer(m_Timer[m_RemCount]); 565 | m_Timer[m_RemCount] = SetTimer(WM_USER + m_RemCount + 1, duration * 60000, NULL); 566 | m_RemCount++; 567 | 568 | AfxMessageBox(str, MB_ICONINFORMATION); 569 | 570 | } 571 | 572 | //else m_RemText.Empty(); 573 | 574 | 575 | } 576 | 577 | void CClipEditorDlg::OnTimer(UINT_PTR nIDEvent) 578 | { 579 | 580 | if ((nIDEvent < WM_USER + m_RemCount + 1) && (nIDEvent > WM_USER)) 581 | { 582 | UINT nrem = nIDEvent - WM_USER - 1; 583 | 584 | KillTimer(m_Timer[nrem]); 585 | CString remalertfile = m_SysHelper.GetAppFileName(CBP_ALERT_FILE); 586 | if (!remalertfile.IsEmpty()) PlaySound(remalertfile, NULL, SND_FILENAME); 587 | 588 | CWnd *parent = GetParent(); 589 | if (parent) parent->SendMessage(WM_CBP_RESTORE, 0, 0); 590 | 591 | MessageBox(m_RemText[nrem] + _T(" ...\r\n\r\n(Check the sticky clip for more.)"), _T("ClipBoard Plus Reminder"), MB_ICONINFORMATION); 592 | m_RemText[nrem].Empty(); 593 | 594 | } 595 | 596 | CDialog::OnTimer(nIDEvent); 597 | } 598 | 599 | 600 | 601 | 602 | void CClipEditorDlg::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) 603 | { 604 | // TODO: Add your message handler code here and/or call default 605 | 606 | if (pScrollBar == (CScrollBar*)&m_SliderBrowse) 607 | { 608 | //if ((nSBCode == SB_THUMBPOSITION) || (nSBCode == SB_THUMBTRACK)) 609 | //if (nSBCode != SB_ENDSCROLL) 610 | //{ 611 | m_DispNote = m_SliderBrowse.GetPos() - 1; //nPos - 1; 612 | if (m_DispNote < 0) m_DispNote = 0; 613 | if (m_DispNote >= MAX_NOTES)m_DispNote = MAX_NOTES - 1; 614 | if (m_DispNote >= m_NoteCount)m_DispNote = m_NoteCount - 1; 615 | DisplayNote(); 616 | //} 617 | } 618 | 619 | CDialog::OnVScroll(nSBCode, nPos, pScrollBar); 620 | } 621 | 622 | 623 | void CClipEditorDlg::SetToolTips() 624 | { 625 | m_ToolTip = new CToolTipCtrl(); 626 | m_ToolTip->Create(this); 627 | 628 | int buttonids[] = { IDCANCEL, IDC_COPYNOTE, IDC_ADDNOTE, IDC_DELNOTE, IDOK, IDC_SLIDER_BROWSE }; 629 | CString tips[] = { _T("Cancel"), _T("Copy Clip"), _T("Add New Clip"), _T("Delete Clip"), _T("Save and Close"), _T("Browse") }; 630 | int nbuttons = 6; 631 | 632 | for (int i = 0; i < nbuttons; i++) 633 | { 634 | CWnd* pWnd = GetDlgItem(buttonids[i]); 635 | m_ToolTip->AddTool(pWnd, tips[i]); 636 | } 637 | 638 | m_ToolTip->Activate(TRUE); 639 | } 640 | 641 | BOOL CClipEditorDlg::PreTranslateMessage(MSG* pMsg) 642 | { 643 | if (m_ToolTip != NULL) 644 | { 645 | m_ToolTip->RelayEvent(pMsg); 646 | } 647 | 648 | return CDialog::PreTranslateMessage(pMsg); 649 | } 650 | 651 | 652 | void CClipEditorDlg::OnEnKillfocusEditClip() 653 | { 654 | if (m_HasChanged) 655 | { 656 | CString note; 657 | m_ClipEd.GetWindowText(note); 658 | if (!note.IsEmpty()) 659 | { 660 | CString time = CTime::GetCurrentTime().Format("%Y-%m-%d %H:%M:%S"); 661 | m_Notes[m_DispNote] = note + _T("⧖") + time; 662 | Process(m_Notes[m_DispNote]); 663 | } 664 | 665 | } 666 | } 667 | -------------------------------------------------------------------------------- /ClipBoardPlus/ClipEditorDlg.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "afxwin.h" 3 | #include "SysHelper.h" 4 | #include "afxcmn.h" 5 | 6 | #define MAX_NOTES 300 7 | #define MAX_REMINDERS 20 8 | 9 | // CClipEditorDlg dialog 10 | 11 | class CClipEditorDlg : public CDialog 12 | { 13 | DECLARE_DYNAMIC(CClipEditorDlg) 14 | 15 | public: 16 | CClipEditorDlg(CWnd* pParent = NULL); // standard constructor 17 | virtual ~CClipEditorDlg(); 18 | 19 | // Dialog Data 20 | #ifdef AFX_DESIGN_TIME 21 | enum { IDD = IDD_DIALOG_EDIT }; 22 | #endif 23 | 24 | protected: 25 | virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support 26 | 27 | DECLARE_MESSAGE_MAP() 28 | public: 29 | CSysHelper m_SysHelper; 30 | BOOL m_IsStickyNote; 31 | CEdit m_ClipEd; 32 | CString m_ClipText; 33 | int m_NoteCount, m_DispNote; 34 | CString m_Notes[MAX_NOTES]; 35 | CString m_VerStr; 36 | HBRUSH m_BkBrush; 37 | CString m_AddThis; 38 | CFont *m_EdFont; 39 | BOOL m_HasChanged; 40 | UINT m_Timer[MAX_REMINDERS]; 41 | UINT m_RemCount; 42 | CString m_RemText[MAX_REMINDERS]; 43 | CSliderCtrl m_SliderBrowse; 44 | CToolTipCtrl* m_ToolTip; 45 | 46 | 47 | BOOL ReadStickyNotes(); 48 | BOOL ParseNotes(CString notes); 49 | void SetNotesFont(); 50 | void DisplayNote(); 51 | void ShowNotesButtons(int show); 52 | void ShowChangedNotice(); 53 | void Process(CString note); 54 | void SetToolTips(); 55 | 56 | virtual BOOL OnInitDialog(); 57 | afx_msg void OnBnClickedOk(); 58 | afx_msg void OnBnClickedAddnote(); 59 | afx_msg void OnBnClickedPrenote(); 60 | afx_msg void OnBnClickedNextnote(); 61 | afx_msg void OnBnClickedDelnote(); 62 | afx_msg void OnBnClickedCancel(); 63 | afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor); 64 | afx_msg void OnDestroy(); 65 | afx_msg void OnPaint(); 66 | afx_msg void OnBnClickedCopynote(); 67 | afx_msg void OnEnChangeEditClip(); 68 | afx_msg void OnTimer(UINT_PTR nIDEvent); 69 | afx_msg void OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar); 70 | virtual BOOL PreTranslateMessage(MSG* pMsg); 71 | afx_msg void OnEnKillfocusEditClip(); 72 | }; 73 | -------------------------------------------------------------------------------- /ClipBoardPlus/NetHelper.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "NetHelper.h" 3 | 4 | 5 | CNetHelper::CNetHelper() 6 | { 7 | } 8 | 9 | 10 | CNetHelper::~CNetHelper() 11 | { 12 | } 13 | 14 | 15 | 16 | UINT UsageProc(LPVOID param) 17 | { 18 | int ver = *(int*)param; 19 | 20 | //static CHAR frmdata[] = ("appinstall=cbp_install&ver=1.0.0"); 21 | static CHAR frmdata[30]; 22 | sprintf_s(frmdata, "appinstall=cbp_install&ver=%d", ver); 23 | frmdata[29] = 0; 24 | 25 | static TCHAR hdrs[] = (_T("Content-Type: application/x-www-form-urlencoded")); 26 | LPCTSTR accept[2] = { _T("*/*"), NULL }; 27 | 28 | HINTERNET hInternet = InternetOpen(_T("Oormi Usage"), INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0); 29 | 30 | HINTERNET hSession = InternetConnect(hInternet, _T("oormi.in"), INTERNET_DEFAULT_HTTPS_PORT, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 1); 31 | 32 | HINTERNET hReq = HttpOpenRequest(hSession, _T("POST"), _T("software/selftalkmsg/selftalkstat01.php"), NULL, NULL, accept, INTERNET_FLAG_SECURE, 1); 33 | 34 | //not working with unicode version 35 | //BOOL res = HttpSendRequest(hReq, _T("Content-Type: application/x-www-form-urlencoded"), _tcslen(hdrs), _T("appinstall=install&ver=1.0.0"), _tcslen(frmdata)); 36 | BOOL res = HttpSendRequestA(hReq, ("Content-Type: application/x-www-form-urlencoded"), _tcslen(hdrs), frmdata, strlen(frmdata)); 37 | 38 | InternetCloseHandle(hReq); 39 | InternetCloseHandle(hSession); 40 | InternetCloseHandle(hInternet); 41 | return 0; 42 | } 43 | 44 | void CNetHelper::ReportUsage(CString regSection, int ver) 45 | { 46 | unsigned char *c;// = new char; 47 | UINT i; 48 | 49 | if (!AfxGetApp()->GetProfileBinary(regSection, _T("VERSION"), (LPBYTE*)&c, &i)) 50 | { 51 | AfxBeginThread(UsageProc, (LPVOID)&ver/*UsageProc receives this as param */, THREAD_PRIORITY_NORMAL); 52 | AfxGetApp()->WriteProfileBinary(regSection, _T("VERSION"), (LPBYTE)&ver, sizeof(ver)); 53 | } 54 | 55 | //char x = c[0]; 56 | delete [] c; 57 | c = NULL; 58 | } 59 | 60 | CString CNetHelper::Fetch(CString url, CString useragent) 61 | { 62 | CString content = _T(""); 63 | DWORD flags; 64 | BOOL connected = InternetGetConnectedState(&flags, NULL); 65 | if (!connected) 66 | { 67 | return content; 68 | } 69 | 70 | HINTERNET hInet = InternetOpen(useragent, INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, NULL); 71 | HINTERNET hUrl = InternetOpenUrl(hInet, url, NULL, -1L, 72 | INTERNET_FLAG_RELOAD | INTERNET_FLAG_PRAGMA_NOCACHE | 73 | INTERNET_FLAG_NO_CACHE_WRITE | WININET_API_FLAG_ASYNC, NULL); 74 | 75 | if (hUrl) 76 | { 77 | CHAR szBuffer[1024] = { 0 }; 78 | 79 | DWORD dwRead; 80 | while (InternetReadFile(hUrl, szBuffer, sizeof(szBuffer) - 1, &dwRead) == TRUE) 81 | { 82 | if (dwRead > 0) 83 | { 84 | szBuffer[dwRead] = 0; 85 | CString tstr(CA2CT(szBuffer, CP_UTF8)); 86 | content += tstr; 87 | } 88 | else break; 89 | } 90 | } 91 | 92 | InternetCloseHandle(hUrl); 93 | InternetCloseHandle(hInet); 94 | 95 | return content; 96 | } 97 | 98 | 99 | void CNetHelper::Checkforupdates(int appVerMaj, int appVerMin, CString updateFile, CString downloadUrl, CString userAgent) 100 | { 101 | CString content = Fetch(updateFile, userAgent); 102 | 103 | if (!content.IsEmpty()) 104 | { 105 | CString ver1, ver2, durl; 106 | 107 | AfxExtractSubString(ver1, content, 0, '|'); //major ver num 108 | AfxExtractSubString(ver2, content, 1, '|'); //minor ver num 109 | AfxExtractSubString(durl, content, 2, '|'); //downlaod url 110 | 111 | int oldver = appVerMaj * 10 + appVerMin; 112 | int newver = _ttoi(ver1) * 10 + _ttoi(ver2); 113 | 114 | if (newver > oldver) 115 | { 116 | int res = AfxMessageBox(_T("A new version of Clipboard Plus is available for download. Would you like to download it now?"), MB_YESNO); 117 | if (res == IDYES) 118 | { 119 | ShellExecute(NULL, _T("open"), durl, NULL, NULL, SW_SHOWNORMAL); 120 | } 121 | else 122 | { 123 | AfxMessageBox(_T("Clipboard Plus can be updated from ") + downloadUrl); 124 | } 125 | } 126 | else 127 | { 128 | AfxMessageBox(_T("Your version of Clipboard Plus is up to date!")); 129 | } 130 | } 131 | 132 | else 133 | { 134 | AfxMessageBox(_T("Failed to connect to the internet!")); 135 | } 136 | } 137 | 138 | -------------------------------------------------------------------------------- /ClipBoardPlus/NetHelper.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "wininet.h" 3 | 4 | class CNetHelper 5 | { 6 | public: 7 | CNetHelper(); 8 | ~CNetHelper(); 9 | 10 | void Checkforupdates(int appVerMaj, int appVerMin, CString updateFile, CString downloadUrl, CString userAgent); 11 | CString Fetch(CString url, CString useragent); 12 | void ReportUsage(CString regSection, int ver); 13 | }; 14 | 15 | -------------------------------------------------------------------------------- /ClipBoardPlus/Reminder.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "Reminder.h" 3 | 4 | 5 | CReminder::CReminder() 6 | { 7 | } 8 | 9 | 10 | CReminder::~CReminder() 11 | { 12 | } 13 | 14 | void CReminder::SetRemDateTime(CString sToken) 15 | { 16 | int iStart = 0, iCount = 0; 17 | CString token; 18 | CString separator = _T("|"); 19 | CTime curTime = CTime::GetCurrentTime(); 20 | 21 | while (iStart >= 0) 22 | { 23 | token = sToken.Tokenize(separator, iStart); 24 | token.Trim(); 25 | if (!token.IsEmpty()) 26 | { 27 | if (iCount == 0) m_tRemTime = _tcstoui64(token, NULL, 10); 28 | if (iCount == 1) 29 | { 30 | m_sStatus = token; 31 | if (m_tRemTime <= curTime) 32 | { 33 | if (m_sStatus == _T("Active")) 34 | { 35 | m_sStatus = _T("Missed"); 36 | } 37 | } 38 | 39 | } 40 | if (iCount == 2) m_sRemDesc = token; 41 | iCount++; 42 | } 43 | 44 | if (iCount >= 3)break; 45 | } 46 | 47 | m_sDispStr = m_tRemTime.Format(_T("%Y-%m-%d | %H:%M | ")) + m_sStatus + m_sRemDesc; 48 | 49 | } 50 | 51 | CString CReminder::GetNotificationStr() 52 | { 53 | return (m_tRemTime.Format(_T("%Y-%m-%d | %H:%M | ")) + m_sStatus + _T(" |\r\n\r\n") + m_sRemDesc); 54 | } -------------------------------------------------------------------------------- /ClipBoardPlus/Reminder.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "SysHelper.h" 4 | 5 | #define MAX_REMINDERS_NEW 200 6 | 7 | class CReminder 8 | { 9 | public: 10 | CReminder(); 11 | ~CReminder(); 12 | 13 | CString m_sStatus; 14 | CString m_sRemDesc; 15 | CString m_sDispStr; 16 | CTime m_tRemTime; 17 | 18 | void SetRemDateTime(CString sToken); 19 | CString GetNotificationStr(); 20 | 21 | }; 22 | 23 | -------------------------------------------------------------------------------- /ClipBoardPlus/ReminderDlg.cpp: -------------------------------------------------------------------------------- 1 | // ReminderDlg.cpp : implementation file 2 | // 3 | 4 | #include "stdafx.h" 5 | #include "ClipBoardPlus.h" 6 | #include "ReminderDlg.h" 7 | #include "afxdialogex.h" 8 | 9 | 10 | // CReminderDlg dialog 11 | 12 | IMPLEMENT_DYNAMIC(CReminderDlg, CDialogEx) 13 | 14 | CReminderDlg::CReminderDlg(CWnd* pParent /*=NULL*/) 15 | : CDialogEx(IDD_DIALOG_REM, pParent) 16 | { 17 | m_uRemCount = 0; 18 | 19 | } 20 | 21 | CReminderDlg::~CReminderDlg() 22 | { 23 | } 24 | 25 | void CReminderDlg::DoDataExchange(CDataExchange* pDX) 26 | { 27 | CDialogEx::DoDataExchange(pDX); 28 | DDX_Control(pDX, IDC_DATETIMEPICKER1, m_dtDate); 29 | DDX_Control(pDX, IDC_DATETIMEPICKER2, m_dtTime); 30 | DDX_Control(pDX, IDC_LIST_REM, m_lbRemList); 31 | } 32 | 33 | 34 | BEGIN_MESSAGE_MAP(CReminderDlg, CDialogEx) 35 | ON_BN_CLICKED(IDC_BUTTON_SETREM, &CReminderDlg::OnBnClickedButtonSetrem) 36 | ON_NOTIFY(DTN_DATETIMECHANGE, IDC_DATETIMEPICKER1, &CReminderDlg::OnDtnDatetimechangeDatetimepicker1) 37 | ON_NOTIFY(DTN_DATETIMECHANGE, IDC_DATETIMEPICKER2, &CReminderDlg::OnDtnDatetimechangeDatetimepicker2) 38 | ON_BN_CLICKED(IDC_BUTTON_DELREM, &CReminderDlg::OnBnClickedButtonDelrem) 39 | ON_LBN_SELCHANGE(IDC_LIST_REM, &CReminderDlg::OnLbnSelchangeListRem) 40 | ON_WM_DESTROY() 41 | END_MESSAGE_MAP() 42 | 43 | 44 | // CReminderDlg message handlers 45 | 46 | BOOL CReminderDlg::OnInitDialog() 47 | { 48 | CDialogEx::OnInitDialog(); 49 | 50 | // TODO: Add extra initialization here 51 | m_dtDate.SetFormat(_T("yyyy-MM-dd")); 52 | m_dtTime.SetFormat(_T("HH:mm")); 53 | 54 | CTime start = CTime::GetCurrentTime(); 55 | CTime end = CTime(start.GetYear() + 10, 12, 31, start.GetHour(), start.GetMinute(), 0); 56 | m_dtDate.SetRange(&start, &end); 57 | m_dtTime.SetRange(&start, &end); 58 | 59 | SetList(); 60 | 61 | return TRUE; // return TRUE unless you set the focus to a control 62 | // EXCEPTION: OCX Property Pages should return FALSE 63 | } 64 | 65 | 66 | void CReminderDlg::OnBnClickedButtonSetrem() 67 | { 68 | UINT rCount = 0; 69 | if (m_uRemCount < MAX_REMINDERS_NEW - 1) 70 | { 71 | rCount = m_uRemCount; 72 | m_uRemCount++; 73 | } 74 | else //overwrite expired one 75 | { 76 | for (int t = 0; t < MAX_REMINDERS_NEW; t++) 77 | { 78 | if (m_rReminders[t].m_sStatus == _T("Expired")) 79 | { 80 | rCount = t; 81 | break; 82 | } 83 | } 84 | } 85 | 86 | if ((rCount < 1) && (m_uRemCount >= MAX_REMINDERS_NEW)) 87 | { 88 | UINT res = AfxMessageBox(_T("Maximum limit for reminders has been reached. Please free up some space by deleting old reminders.\r\nClick Yes to proceed anyway. No to cancel"), MB_YESNO); 89 | if (res == IDNO) return; 90 | } 91 | 92 | GetDlgItemText(IDC_EDIT_REMTEXT, m_rReminders[rCount].m_sRemDesc); 93 | if (m_rReminders[rCount].m_sRemDesc.IsEmpty()) 94 | { 95 | AfxMessageBox(_T("Please enter a description or to do text.")); 96 | return; 97 | } 98 | 99 | CTime dt1, dt2; 100 | m_dtDate.GetTime(dt1); 101 | m_dtTime.GetTime(dt2); 102 | 103 | m_rReminders[rCount].m_tRemTime = CTime(dt1.GetYear(), dt1.GetMonth(), dt1.GetDay(), dt2.GetHour(), dt2.GetMinute(), 0); 104 | m_rReminders[rCount].m_sDispStr = m_rReminders[rCount].m_tRemTime.Format(_T("%Y-%m-%d | %H:%M | ")) + m_rReminders[rCount].m_sRemDesc; 105 | m_rReminders[rCount].m_sStatus = _T("Active"); 106 | 107 | m_lbRemList.AddString(m_rReminders[rCount].GetNotificationStr()); 108 | } 109 | 110 | 111 | void CReminderDlg::OnDtnDatetimechangeDatetimepicker1(NMHDR *pNMHDR, LRESULT *pResult) 112 | { 113 | LPNMDATETIMECHANGE pDTChange = reinterpret_cast(pNMHDR); 114 | // TODO: Add your control notification handler code here 115 | //GetDlgItemText(IDC_DATETIMEPICKER1, m_sDate); 116 | *pResult = 0; 117 | } 118 | 119 | 120 | void CReminderDlg::OnDtnDatetimechangeDatetimepicker2(NMHDR *pNMHDR, LRESULT *pResult) 121 | { 122 | LPNMDATETIMECHANGE pDTChange = reinterpret_cast(pNMHDR); 123 | // TODO: Add your control notification handler code here 124 | //GetDlgItemText(IDC_DATETIMEPICKER2, m_sTime); 125 | *pResult = 0; 126 | } 127 | 128 | 129 | void CReminderDlg::OnBnClickedButtonDelrem() 130 | { 131 | int iID = m_lbRemList.GetCurSel(); 132 | m_lbRemList.DeleteString(iID); 133 | m_rReminders[iID].m_sStatus = _T("Deleted"); 134 | } 135 | 136 | 137 | void CReminderDlg::OnLbnSelchangeListRem() 138 | { 139 | CString str; 140 | int iID = m_lbRemList.GetCurSel(); 141 | 142 | if (iID < 0) return; 143 | 144 | m_lbRemList.GetText(iID, str); 145 | SetDlgItemText(IDC_EDIT_REMTEXT, str); 146 | 147 | //below will fail for expired reminders because setrange has set a minimum 148 | //m_dtDate.SetTime(&m_rReminders[iID].m_tRemTime); 149 | //m_dtTime.SetTime(&m_rReminders[iID].m_tRemTime); 150 | } 151 | 152 | void CReminderDlg::SetList() 153 | { 154 | for (UINT i = 0; i < m_uRemCount; i++) 155 | { 156 | if (m_rReminders[i].m_sStatus != _T("Deleted")) 157 | { 158 | m_lbRemList.AddString(m_rReminders[i].GetNotificationStr()); 159 | } 160 | } 161 | } 162 | 163 | BOOL CReminderDlg::LoadReminders() 164 | { 165 | CSysHelper SysHelper; 166 | SysHelper.m_FileName = SysHelper.GetAppFileName(CBP_REM_FILE); 167 | 168 | if (!SysHelper.m_FileName.IsEmpty()) 169 | { 170 | CString sRems = SysHelper.ReadStringFromFile(SysHelper.m_FileName, FALSE); 171 | 172 | if (!sRems.IsEmpty()) 173 | { 174 | return ParseRems(sRems); 175 | } 176 | } 177 | return 0; 178 | } 179 | 180 | BOOL CReminderDlg::ParseRems(CString sRems) 181 | { 182 | int iCount = 0; 183 | int iStart = 0; 184 | CString token; 185 | CString separator = _T("←"); 186 | token = sRems.Tokenize(separator, iStart); 187 | 188 | token = token + separator; 189 | if (token.Compare(m_sVer)) 190 | { 191 | AfxMessageBox(_T("The reminders file has some problems.")); 192 | return FALSE; 193 | } 194 | 195 | while (iStart >= 0) 196 | { 197 | token = sRems.Tokenize(separator, iStart); 198 | token.Trim(); 199 | if (!token.IsEmpty()) 200 | { 201 | m_rReminders[iCount].SetRemDateTime(token); 202 | iCount++; 203 | } 204 | 205 | if (iCount >= MAX_REMINDERS_NEW)break; 206 | } 207 | 208 | m_uRemCount = iCount; 209 | 210 | if (iCount<1)return FALSE; 211 | return TRUE; 212 | } 213 | 214 | BOOL CReminderDlg::SaveReminders() 215 | { 216 | CString str; 217 | CString sRems = m_sVer; 218 | 219 | if (m_uRemCount >= MAX_REMINDERS_NEW) m_uRemCount = MAX_REMINDERS_NEW; 220 | 221 | for (UINT i = 0; i < m_uRemCount; i++) 222 | { 223 | if (m_rReminders[i].m_sStatus != _T("Deleted")) 224 | { 225 | LONGLONG t = m_rReminders[i].m_tRemTime.GetTime(); 226 | str.Format(_T("%I64d|%s|%s"), t, m_rReminders[i].m_sStatus, m_rReminders[i].m_sRemDesc); 227 | sRems = sRems + _T("\r\n") + str + _T("←"); 228 | } 229 | } 230 | 231 | CSysHelper SysHelper; 232 | return SysHelper.SaveString(SysHelper.GetAppFileName(CBP_REM_FILE), sRems); 233 | } 234 | 235 | void CReminderDlg::OnDestroy() 236 | { 237 | CDialogEx::OnDestroy(); 238 | SaveReminders(); 239 | } 240 | -------------------------------------------------------------------------------- /ClipBoardPlus/ReminderDlg.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "afxdtctl.h" 3 | #include "Reminder.h" 4 | 5 | 6 | 7 | // CReminderDlg dialog 8 | 9 | class CReminderDlg : public CDialogEx 10 | { 11 | DECLARE_DYNAMIC(CReminderDlg) 12 | 13 | public: 14 | CReminderDlg(CWnd* pParent = NULL); // standard constructor 15 | virtual ~CReminderDlg(); 16 | 17 | CString m_sVer; 18 | CDateTimeCtrl m_dtDate; 19 | CDateTimeCtrl m_dtTime; 20 | CListBox m_lbRemList; 21 | 22 | virtual BOOL OnInitDialog(); 23 | BOOL LoadReminders(); 24 | BOOL SaveReminders(); 25 | BOOL ParseRems(CString sRems); 26 | void SetList(); 27 | 28 | CReminder m_rReminders[MAX_REMINDERS_NEW]; 29 | UINT m_uRemCount; 30 | 31 | // Dialog Data 32 | #ifdef AFX_DESIGN_TIME 33 | enum { IDD = IDD_DIALOG_REM }; 34 | #endif 35 | 36 | protected: 37 | virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support 38 | 39 | DECLARE_MESSAGE_MAP() 40 | public: 41 | afx_msg void OnBnClickedButtonSetrem(); 42 | afx_msg void OnDtnDatetimechangeDatetimepicker1(NMHDR *pNMHDR, LRESULT *pResult); 43 | afx_msg void OnDtnDatetimechangeDatetimepicker2(NMHDR *pNMHDR, LRESULT *pResult); 44 | afx_msg void OnBnClickedButtonDelrem(); 45 | afx_msg void OnLbnSelchangeListRem(); 46 | afx_msg void OnDestroy(); 47 | }; 48 | -------------------------------------------------------------------------------- /ClipBoardPlus/Resource.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oormicreations/ClipboardPlus/5c12e91e287ad68d15f2af375b6a56b9bef22026/ClipBoardPlus/Resource.h -------------------------------------------------------------------------------- /ClipBoardPlus/SysHelper.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "SysHelper.h" 3 | 4 | 5 | CSysHelper::CSysHelper() 6 | { 7 | } 8 | 9 | 10 | CSysHelper::~CSysHelper() 11 | { 12 | } 13 | 14 | 15 | CString CSysHelper::GetClipboardText() 16 | { 17 | // Try opening the clipboard 18 | if (!OpenClipboard(0)) 19 | { 20 | //AfxMessageBox(_T("")); 21 | //MS Word or Excel will cause problems by locking up the clipbroad many times. 22 | //So return last clip in case of failure. 23 | return _T(""); 24 | } 25 | 26 | // Get handle of clipboard object for unicode text 27 | HANDLE hData = GetClipboardData(CF_UNICODETEXT); 28 | if (hData == nullptr) 29 | { 30 | //AfxMessageBox(_T("")); 31 | CloseClipboard(); 32 | return _T(""); 33 | } 34 | 35 | // Lock the handle to get the actual text pointer 36 | TCHAR * pszText = static_cast(GlobalLock(hData)); 37 | if (pszText == nullptr) 38 | { 39 | //AfxMessageBox(_T("")); 40 | // Release the lock 41 | GlobalUnlock(hData); 42 | 43 | // Release the clipboard 44 | CloseClipboard(); 45 | 46 | return _T(""); 47 | } 48 | 49 | // Save text in a string class instance 50 | CString text(pszText); 51 | 52 | // Release the lock 53 | GlobalUnlock(hData); 54 | 55 | // Release the clipboard 56 | CloseClipboard(); 57 | 58 | return text; 59 | } 60 | 61 | 62 | BOOL CSysHelper::SetClipboardText(CString text) 63 | { 64 | // Try opening the clipboard 65 | if (!OpenClipboard(0)) 66 | { 67 | return FALSE; 68 | } 69 | 70 | LPTSTR lptstrCopy; 71 | HGLOBAL hglbCopy; 72 | int iSize = (text.GetLength() + 1) * sizeof(TCHAR); 73 | 74 | hglbCopy = GlobalAlloc(GMEM_MOVEABLE, iSize); 75 | if (hglbCopy == NULL) 76 | { 77 | CloseClipboard(); 78 | return FALSE; 79 | } 80 | 81 | // Lock the handle and copy the text to the buffer. 82 | lptstrCopy = (LPTSTR)GlobalLock(hglbCopy); 83 | ZeroMemory(lptstrCopy, iSize); // adds null character also 84 | memcpy(lptstrCopy, text.GetBuffer(), text.GetLength() * sizeof(TCHAR)); 85 | 86 | //lptstrCopy[iSize] = /*(TCHAR)*/0; // null character 87 | GlobalUnlock(hglbCopy); 88 | 89 | EmptyClipboard(); 90 | HANDLE hData = SetClipboardData(CF_UNICODETEXT, hglbCopy); 91 | if (hData == nullptr) 92 | { 93 | CloseClipboard(); 94 | return FALSE; 95 | } 96 | 97 | // Release the clipboard 98 | CloseClipboard(); 99 | 100 | return TRUE; 101 | } 102 | 103 | CString CSysHelper::ReadStringFromFile(CString filename, BOOL prompt) 104 | { 105 | CFile file; 106 | if (!file.Open(filename, CFile::modeRead)) 107 | { 108 | if (prompt) AfxMessageBox(_T("Failed to open the file: ") + filename, MB_ICONERROR); 109 | return _T(""); 110 | } 111 | 112 | UINT len = (UINT)file.GetLength(); 113 | char * buf = new char[len + 1]; 114 | 115 | file.Read(buf, len); 116 | file.Close(); 117 | 118 | buf[len] = 0; 119 | 120 | 121 | CString uni; 122 | int cc = 0; 123 | // get length (cc) of the new widechar excluding the \0 terminator first 124 | if ((cc = MultiByteToWideChar(CP_UTF8, 0, buf, -1, NULL, 0) - 1) > 0) 125 | { 126 | // convert 127 | wchar_t *buf1 = uni.GetBuffer(cc); 128 | if (buf1) MultiByteToWideChar(CP_UTF8, 0, buf, -1, buf1, cc); 129 | uni.ReleaseBuffer(); 130 | } 131 | 132 | delete[] buf; 133 | return uni; 134 | } 135 | 136 | CString CSysHelper::GetFileContent() 137 | { 138 | CFileDialog DataFileOpenDialog(true, _T("rtf"), _T(""), OFN_HIDEREADONLY, _T("Rich text Files (*.rtf)|*.rtf|Text Files (*.txt)|*.txt|All Files (*.*)|*.*||")); 139 | DataFileOpenDialog.m_ofn.lpstrTitle = _T("Load an RTF or Text File ..."); 140 | //DataFileOpenDialog.m_ofn.lpstrInitialDir = GetUserDocumentPath(PREDICTED_FOLDER); 141 | INT_PTR res = DataFileOpenDialog.DoModal(); 142 | if (res == IDCANCEL) return _T(""); 143 | m_FileName = DataFileOpenDialog.GetPathName(); 144 | if (m_FileName.IsEmpty()) return _T(""); 145 | m_FileExt = DataFileOpenDialog.GetFileExt(); 146 | 147 | m_FileTitle = DataFileOpenDialog.GetFileTitle(); 148 | if (m_FileTitle.GetLength() > 10) 149 | { 150 | m_FileTitle.Truncate(10); 151 | m_FileTitle = m_FileTitle + _T("..."); 152 | } 153 | 154 | return ReadStringFromFile(m_FileName); 155 | } 156 | 157 | BOOL CSysHelper::GetSaveFileNameType() 158 | { 159 | CFileDialog DataFileOpenDialog(false, _T("rtf"), _T(""), OFN_HIDEREADONLY, _T("Rich text Files (*.rtf)|*.rtf|Text Files (*.txt)|*.txt|All Files (*.*)|*.*||")); 160 | DataFileOpenDialog.m_ofn.lpstrTitle = _T("Save an RTF or Text File ..."); 161 | //DataFileOpenDialog.m_ofn.lpstrInitialDir = GetUserDocumentPath(PREDICTED_FOLDER); 162 | 163 | INT_PTR res = DataFileOpenDialog.DoModal(); 164 | if (res == IDCANCEL) return FALSE; 165 | m_FileName = DataFileOpenDialog.GetPathName(); 166 | if (m_FileName.IsEmpty()) return FALSE; 167 | m_FileExt = DataFileOpenDialog.GetFileExt(); 168 | 169 | m_FileTitle = DataFileOpenDialog.GetFileTitle(); 170 | if (m_FileTitle.GetLength() > 10) 171 | { 172 | m_FileTitle.Truncate(10); 173 | m_FileTitle = m_FileTitle + _T("..."); 174 | } 175 | 176 | return TRUE; 177 | } 178 | 179 | BOOL CSysHelper::SetFileContent(CString content) 180 | { 181 | if (m_FileName.IsEmpty()) 182 | { 183 | GetSaveFileNameType(); 184 | } 185 | 186 | if(!SaveString(m_FileName, content)) m_FileName = _T(""); 187 | 188 | return TRUE; 189 | 190 | } 191 | 192 | BOOL CSysHelper::SaveString(CString filename, CString content) 193 | { 194 | if (filename.IsEmpty()) return FALSE; 195 | 196 | CFile file; 197 | BOOL res1 = file.Open(filename, CFile::modeWrite|CFile::modeCreate); 198 | if (!res1) 199 | { 200 | AfxMessageBox(_T("Error : Failed to save the file")); 201 | return FALSE; 202 | } 203 | 204 | UINT len = (UINT)content.GetLength() * sizeof(TCHAR); 205 | char * outputString = (char*)malloc(len+1); 206 | ZeroMemory(outputString, len+1); 207 | 208 | len = WideCharToMultiByte(CP_UTF8, NULL, content, -1, outputString, len, NULL, NULL); 209 | 210 | file.Write(outputString, ::strlen(outputString)); 211 | file.Close(); 212 | free(outputString); 213 | 214 | return TRUE; 215 | 216 | } 217 | 218 | 219 | BOOL CSysHelper::SaveStringAppend(CString filename, CString content) 220 | { 221 | if (filename.IsEmpty()) return FALSE; 222 | 223 | CFile file; 224 | BOOL res1 = file.Open(filename, CFile::modeWrite); 225 | if (!res1) 226 | { 227 | AfxMessageBox(_T("Error : Failed to append the file")); 228 | return FALSE; 229 | } 230 | 231 | UINT len = (UINT)content.GetLength() * sizeof(TCHAR); 232 | char * outputString = (char*)malloc(len + 1); 233 | ZeroMemory(outputString, len + 1); 234 | 235 | len = WideCharToMultiByte(CP_UTF8, NULL, content, -1, outputString, len, NULL, NULL); 236 | 237 | file.SeekToEnd(); 238 | file.Write(outputString, ::strlen(outputString)); 239 | file.Close(); 240 | free(outputString); 241 | 242 | return TRUE; 243 | 244 | } 245 | 246 | 247 | CString CSysHelper::GetAppFileName(UINT type) 248 | { 249 | CString path = GetUserDocumentPath(CBP_USER_FOLDER); 250 | 251 | if (!path.IsEmpty()) 252 | { 253 | CString fname; 254 | if (type == CBP_SNOTES_FILE) fname = _T("\\CBP_StickyClips.txt"); 255 | if (type == CBP_ALERT_FILE) fname = _T("\\rem.wav"); 256 | if (type == CBP_BACKUP_FILE) fname = _T("\\CBP_Backup.txt"); 257 | if (type == CBP_REM_FILE) fname = _T("\\CBP_Reminders.txt"); 258 | if (fname.IsEmpty()) return _T(""); 259 | 260 | path = path + fname; 261 | return path; 262 | } 263 | 264 | return _T(""); 265 | } 266 | 267 | CString CSysHelper::GetUserDocumentPath(UINT type) 268 | { 269 | TCHAR my_documents[MAX_PATH]; 270 | for (int i = 0; i < MAX_PATH; i++)my_documents[i] = 0; 271 | 272 | HRESULT result = SHGetFolderPath(NULL, CSIDL_PERSONAL, NULL, SHGFP_TYPE_CURRENT, my_documents); 273 | 274 | if (result != S_OK) 275 | { 276 | return _T(""); 277 | } 278 | else 279 | { 280 | CString str; 281 | str.SetString(my_documents); 282 | 283 | if (type == CBP_USER_FOLDER) 284 | { 285 | str = str + _T("\\Oormi Creations\\Clipboard Plus"); 286 | } 287 | 288 | if (GetFileAttributes(str) == INVALID_FILE_ATTRIBUTES) 289 | { 290 | //path doesn't exist, attempt creation 291 | if (SHCreateDirectoryEx(NULL, str, NULL) == ERROR_SUCCESS) 292 | { 293 | return str; 294 | } 295 | else 296 | { 297 | return _T(""); 298 | } 299 | } 300 | 301 | //path is valid 302 | return str; 303 | } 304 | 305 | } 306 | 307 | BOOL CSysHelper::CreateFileAndInit(CString filename, CString content) 308 | { 309 | if (INVALID_FILE_ATTRIBUTES == GetFileAttributes(filename) && GetLastError() == ERROR_FILE_NOT_FOUND) 310 | { 311 | SaveString(filename, content); 312 | return TRUE; 313 | } 314 | else return TRUE; 315 | 316 | return FALSE; 317 | } 318 | 319 | static int CALLBACK EnumFontFamExProc(ENUMLOGFONTEX* /*lpelfe*/, NEWTEXTMETRICEX* /*lpntme*/, int /*FontType*/, LPARAM lParam) 320 | { 321 | LPARAM* l = (LPARAM*)lParam; 322 | *l = TRUE; 323 | return TRUE; 324 | } 325 | 326 | bool CSysHelper::IsFontInstalled(LPCTSTR lpszFont) 327 | { 328 | // Get the screen DC 329 | CDC dc; 330 | if (!dc.CreateCompatibleDC(NULL)) 331 | { 332 | return false; 333 | } 334 | LOGFONT lf = { 0 }; 335 | // Any character set will do 336 | lf.lfCharSet = DEFAULT_CHARSET; 337 | // Set the facename to check for 338 | _tcscpy_s(lf.lfFaceName, lpszFont); 339 | LPARAM lParam = 0; 340 | // Enumerate fonts 341 | ::EnumFontFamiliesEx(dc.GetSafeHdc(), &lf, (FONTENUMPROC)EnumFontFamExProc, (LPARAM)&lParam, 0); 342 | return lParam ? true : false; 343 | } 344 | 345 | void CSysHelper::SelectMultipleFiles(CString * files, int maxfiles) 346 | { 347 | CFileDialog DataFileOpenDialog(true, _T("rtf"), _T(""), OFN_ALLOWMULTISELECT, _T("Text Files (*.txt)|*.txt|All Files (*.*)|*.*||")); 348 | DataFileOpenDialog.m_ofn.lpstrTitle = _T("Select Files ..."); 349 | //DataFileOpenDialog.m_ofn.lpstrInitialDir = GetUserDocumentPath(PREDICTED_FOLDER); 350 | 351 | int nLnBuff = maxfiles*256; 352 | TCHAR* pBuffFileSelect = new TCHAR[nLnBuff]; 353 | 354 | memset(pBuffFileSelect, 0, nLnBuff * sizeof(TCHAR)); 355 | 356 | DataFileOpenDialog.m_ofn.lpstrFile = pBuffFileSelect; 357 | DataFileOpenDialog.m_ofn.nMaxFile = nLnBuff; 358 | 359 | INT_PTR res = DataFileOpenDialog.DoModal(); 360 | if (res == IDOK) 361 | { 362 | 363 | int f = 0; 364 | POSITION pos(DataFileOpenDialog.GetStartPosition()); 365 | while (pos) 366 | { 367 | CString filename = DataFileOpenDialog.GetNextPathName(pos); 368 | 369 | files[f] = filename; 370 | f++; 371 | if (f >= maxfiles) break; 372 | } 373 | } 374 | 375 | delete[] pBuffFileSelect; 376 | } 377 | -------------------------------------------------------------------------------- /ClipBoardPlus/SysHelper.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #define CBP_USER_FOLDER 1 3 | #define CBP_SNOTES_FILE 1 4 | #define CBP_ALERT_FILE 2 5 | #define CBP_BACKUP_FILE 3 6 | #define CBP_REM_FILE 4 7 | 8 | #define TWIPS_PER_PT 20 9 | #define WM_CBP_RESTORE WM_USER + 100 10 | 11 | class CSysHelper 12 | { 13 | public: 14 | CSysHelper(); 15 | ~CSysHelper(); 16 | 17 | CString m_FileName, m_FileTitle, m_FileExt; 18 | 19 | CString GetClipboardText(); 20 | BOOL SetClipboardText(CString text); 21 | CString GetFileContent(); 22 | BOOL SetFileContent(CString content); 23 | BOOL SaveString(CString filename, CString content); 24 | BOOL SaveStringAppend(CString filename, CString content); 25 | CString GetAppFileName(UINT type); 26 | CString GetUserDocumentPath(UINT type); 27 | BOOL CreateFileAndInit(CString filename, CString content); 28 | CString ReadStringFromFile(CString filename, BOOL prompt = TRUE); 29 | bool IsFontInstalled(LPCTSTR lpszFont); 30 | void SelectMultipleFiles(CString * files, int maxfiles); 31 | BOOL GetSaveFileNameType(); 32 | }; 33 | 34 | -------------------------------------------------------------------------------- /ClipBoardPlus/res/Clip01.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oormicreations/ClipboardPlus/5c12e91e287ad68d15f2af375b6a56b9bef22026/ClipBoardPlus/res/Clip01.bmp -------------------------------------------------------------------------------- /ClipBoardPlus/res/Clip02.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oormicreations/ClipboardPlus/5c12e91e287ad68d15f2af375b6a56b9bef22026/ClipBoardPlus/res/Clip02.bmp -------------------------------------------------------------------------------- /ClipBoardPlus/res/ClipBoardPlus.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oormicreations/ClipboardPlus/5c12e91e287ad68d15f2af375b6a56b9bef22026/ClipBoardPlus/res/ClipBoardPlus.ico -------------------------------------------------------------------------------- /ClipBoardPlus/res/ClipBoardPlus.rc2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oormicreations/ClipboardPlus/5c12e91e287ad68d15f2af375b6a56b9bef22026/ClipBoardPlus/res/ClipBoardPlus.rc2 -------------------------------------------------------------------------------- /ClipBoardPlus/res/OormiLogo.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oormicreations/ClipboardPlus/5c12e91e287ad68d15f2af375b6a56b9bef22026/ClipBoardPlus/res/OormiLogo.bmp -------------------------------------------------------------------------------- /ClipBoardPlus/res/rem.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oormicreations/ClipboardPlus/5c12e91e287ad68d15f2af375b6a56b9bef22026/ClipBoardPlus/res/rem.wav -------------------------------------------------------------------------------- /ClipBoardPlus/stdafx.cpp: -------------------------------------------------------------------------------- 1 | 2 | // stdafx.cpp : source file that includes just the standard includes 3 | // ClipBoardPlus.pch will be the pre-compiled header 4 | // stdafx.obj will contain the pre-compiled type information 5 | 6 | #include "stdafx.h" 7 | 8 | 9 | -------------------------------------------------------------------------------- /ClipBoardPlus/stdafx.h: -------------------------------------------------------------------------------- 1 | 2 | // stdafx.h : include file for standard system include files, 3 | // or project specific include files that are used frequently, 4 | // but are changed infrequently 5 | 6 | #pragma once 7 | 8 | #ifndef VC_EXTRALEAN 9 | #define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers 10 | #endif 11 | 12 | #include "targetver.h" 13 | 14 | #define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS // some CString constructors will be explicit 15 | 16 | // turns off MFC's hiding of some common and often safely ignored warning messages 17 | #define _AFX_ALL_WARNINGS 18 | 19 | #include // MFC core and standard components 20 | #include // MFC extensions 21 | 22 | 23 | 24 | 25 | 26 | #ifndef _AFX_NO_OLE_SUPPORT 27 | #include // MFC support for Internet Explorer 4 Common Controls 28 | #endif 29 | #ifndef _AFX_NO_AFXCMN_SUPPORT 30 | #include // MFC support for Windows Common Controls 31 | #endif // _AFX_NO_AFXCMN_SUPPORT 32 | 33 | #include // MFC support for ribbons and control bars 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | #ifdef _UNICODE 44 | #if defined _M_IX86 45 | #pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='x86' publicKeyToken='6595b64144ccf1df' language='*'\"") 46 | #elif defined _M_X64 47 | #pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='amd64' publicKeyToken='6595b64144ccf1df' language='*'\"") 48 | #else 49 | #pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"") 50 | #endif 51 | #endif 52 | 53 | 54 | -------------------------------------------------------------------------------- /ClipBoardPlus/targetver.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // Including SDKDDKVer.h defines the highest available Windows platform. 4 | 5 | // If you wish to build your application for a previous Windows platform, include WinSDKVer.h and 6 | // set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h. 7 | 8 | #include 9 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) Oormi Creations and Contributors 4 | 5 | All rights reserved. 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a copy 8 | of this software and associated documentation files (the "Software"), to deal 9 | in the Software without restriction, including without limitation the rights 10 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | copies of the Software, and to permit persons to whom the Software is 12 | furnished to do so, subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included in all 15 | copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | SOFTWARE. -------------------------------------------------------------------------------- /cbphelp/help110.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | ClipBoard Plus Help 8 | 9 | 10 | 11 | 12 | 13 |
14 | 15 |
16 | 17 | 20 | 21 |
ClipBoard Plus
22 | 23 |
Help Document
24 | 25 |
26 | 27 | 28 | 62 | 63 |
64 |

Contents

65 | Introduction
66 | Installation
67 | System Requirements
68 | Usage
69 | Sticky clips and notes
70 | Reminders
71 | 72 |


73 | 74 |
75 | screenshot 76 |
77 | 78 |
79 |

Introduction

80 |

Clipboard Plus is a Windows utility to view and manage the 81 | Windows clipboard.

82 |

It maintains and can display up to five copied items or 83 | clips. Clips are arranged from newest to oldest.

84 |

Clicking on a clip loads it back into the clipboard and it is 85 | ready for pasting into another application. It also now 86 | becomes the latest clip, and other clips scroll down.

87 |

It has a built in Sticky Note tool in which the clips can be stored, 88 | notes can be added and reminders can be set.

89 |

The stored clips persist between reboots.

90 |

To explore more features and functions of this utility, right 91 | click on it.

92 |

This tiny but useful utility is completely free and open 93 | sourced. For more such amazing free apps please visit the 94 | links on the left.

95 | 96 |

The source code of this application is available for anyone 97 | to improve, fork, contribute or for use in your own 98 | application, without any restrictions.

99 | 100 |
101 |

Installation

102 |

Download the latest Windows Installer from: GitHub

105 |

Unzip the downloaded file and run setup.exe.

106 |

Follow the instructions. Run the program from start menu or 107 | by double clicking Clipboard Plus desktop icon.

108 |

Please read the License before installing and using this 111 | software.

112 |
113 |

Note: The installer will optionally add a shortcut to the 114 | startup folder of Windows, so that Clipboard Plus starts 115 | automatically when you start Windows. This is enabled by 116 | default. You can remove the shortcut from the startup folder if needed.

117 |
118 |

 

119 | 120 |
121 |

System Requirements

122 |

123 |

Minimum requirements:

124 |

Microsoft Windows 7 to 10

125 |

Single core CPU

126 |

1 GB RAM

127 |

5 MB of free space on hard disk

128 |

A monitor with at least 800 x 600 resolution.

129 | 130 |
131 |

Usage

132 |

Copy content as usual from any window using Control-C or 133 | Control-X or context menu. The clip will appear in the 134 | Clipboard Plus list. Copy more to add to the list. Click on 135 | any entry in the list to load it in the Windows Clipboard. 136 | Paste it anywhere you like. Whenever you copy something, the 137 | top most clip will be updated and the old clips scroll down.

138 | 139 | 140 | 141 |
142 |

Note: Only text clips are supported.

143 |
144 |
145 |
146 |

Note: The last clip will be lost when a new clip is 147 | updated.

148 |
149 |

 

150 |

Right Click on the main window to bring up the Pop Up Menu.

151 | 152 | pop up menu 153 | 154 |

Clear|Clear This Clip: Clear individual clips by right 155 | clicking on the clip, and click Clear.

156 |

Clear|Clear All: Clear all clips.

157 |

Clear|Clear Clipboard: Clear current content of 158 | the clipboard without affecting rest of the clips.

159 |
160 |

Note: You cannot undo Clear commands.

161 |
162 |

 

163 |

Save|Save: Save individual clip as a text file by 164 | right clicking on the clip and click Save.

165 |

Save|Save All: Save all the clips as a text 166 | file.

167 |

Save|Delete Autosaved Clips: Does that.

168 | 169 |

Sticky Clips|View Sticky Clips: Opens the saved clips (See below for details).

170 |

Sticky Clips|Add to Sticky Clips: This will add the clip on 171 | which you right clicked to the Sticky Clips. If you wish to use 172 | a clip often or want to save it for later, you can do so here. 173 | Note that as you copy other things, the clip will disappear from 174 | the main list, but it will be there in the Sticky Clips.

175 | 176 |

Reminders: Opens reminders window (See below for details).

177 | 178 |

Edit Clip: Edit the clip in the edit box 179 | that pops up. Click tick mark button to close. The edited clip 180 | is loaded into the clipboard.

181 |

Open link: If the clip is a link, it will be opened 182 | in your default browser.

183 |

Password Mode: Enable or disable password 184 | mode. When enabled, it masks the copied passwords.

185 |
186 |

Note: A password must have combination of letters, numbers 187 | and special characters to be detected as a password.

188 |

A clip with spaces or with length greater than 16 189 | characters is not considered as a password.

190 |

This feature is language dependent. Currently only English 191 | and Hindi is supported. It cannot recognize Arabic 192 | passwords, for example.

193 |
194 |

 

195 |
196 |

Warning: The hidden 197 | password is not really secure. Anyone can unhide it or load 198 | it up in the clipboard. This feature simply ensures that a 199 | casual onlooker is not able to see it.

200 |

Clear the clip as soon as it is used.

201 |
202 | 203 | 204 |
205 | 206 |

Window|Minimize to tray: The main window is 207 | hidden and can be restored from the tray icon.

208 |

Window|Remain on top: Clipboad Plus remains on top of all 209 | windows when you check this option. Uncheck it to cancel always on top mode.

210 | 211 |

Help And More|Help: Access this help online.

212 |

Help And More|About: Information about Clipboard Plus.

213 |

Help And More|Check for updates: If updates are available 214 | the user is prompted to update and the download website is 215 | opened in the browser.

216 |

Help And More|Get more free apps: Opens the Oormi 217 | Creations GitHub repository where you can find more awesome, 218 | free and open source apps like this one.

219 |

Exit: Closes Clipboard Plus.

220 | 221 |


222 |

Sticky Clips and notes

223 | You can type in 224 | notes, reminders, text, clips etc and save them for later use. 225 | Here is what the buttons do:
226 |
227 | C : Copy
228 | + : New note
229 | - : Delete note
230 | ✓ : Save and Close
231 | Slider: Browse the sticky notes and clips 232 |

233 | sticky clips screen shot 234 | 235 |
236 |
237 |

Note: Sticky clips can save up to 300 clips. The clips are 238 | saved as delimited text file. If you wish to have more 239 | clips, just rename the CBP_StickyClips.txt file, 240 | which can be found in:

241 |

(My) Documents\Oormi Creations\Clipboard Plus

242 |

You can also delete it to quickly clear all saved clips.

243 |
244 | 245 |


246 | 247 |

Reminders

248 | 249 |

Clipboard Plus has a neat feature to remind you for something important. 250 | Right click to open the reminder window. Set a date and time and click set reminder. 251 | You are done!

252 | 253 | reminder screen shot
254 | 255 |

You can delete old reminders by selecting them. The set reminders persist between shut downs 256 | or closing/opening of Clipboard Plus. In case Clipboard Plus 257 | is closed or the PC is sleeping or is off at the time of reminder, the reminder is 258 | sounded as soon as it is up again.

259 |


260 | 261 | 262 | 263 |
264 | Setting reminders via sticky clips (Versions 1.2 and below) 265 | 266 | Setting reminders via sticky clips (Versions 1.2 and below) 267 |
Click to Show/hide 268 |
269 |
270 | 271 | The old way of setting reminders via sticky clips window is still supported. 272 | Although you may not need it now. 273 | Just type in your note and prefix it with the set reminder 274 | command and time. For example:
275 |
276 | set reminder 11:30 call someone
277 | set reminder 2h 15m go jogging and drop trash
278 |
set reminder 20m Skype meeting with client
279 |
280 |
Press Tick (✓) button to set a reminder as above.
281 |
282 | You should see an ack message showing some details. This is also 283 | saved as a sticky clip for later use. The reminder is a one 284 | time reminder, it won't keep repeating.
285 |
286 | rem ack screen shot
287 |
288 | 289 | As you must have noticed, there are two ways to specify the 290 | time. Either as HH:MM, in which case the reminder sounds exactly 291 | at that time, or as a duration as xxh yym, in which case the 292 | reminder sounds exactly after that duration.
293 |
294 |
295 |

Note: Its a bit sensitive about syntax. So do not add words 296 | between set reminder and time or do not use words instead of 297 | numbers while mentioning time. Do not use AM or PM. It works in 24 hr format.

298 |

You cannot set a reminder for next day or next week. 299 | However, when you use the duration, it may cross over to the 300 | next day.

301 |
302 |   303 |
304 |

Warning: This is not a 305 | Windows scheduler event or OS level alarm. If you exit 306 | ClipBoard Plus, you will never get reminded. Closing and 307 | restarting ClipBoard Plus has the same effect. Reminders are 308 | timer based, they are not retained (As for version 1.1.0).

309 |

You can set up to 20 reminders. The 21st reminder will overwrite the first and so on.

310 |
311 |
312 |
313 |

Note: The reminder appears as a message box. If your text 314 | is too long, it gets truncated. But you can view the full 315 | text in sticky clips.

316 |

If you are not happy with the voice that announces the 317 | reminder, you can replace it with your own jingle or sound 318 | by replacing the rem.wav file found in this 319 | location:

320 |

(My) Documents\Oormi Creations\Clipboard Plus

321 |
322 |

323 |
324 |
325 | 326 | 327 | 328 | 329 | 330 | 331 |
332 | 333 | 343 | 344 | 345 | 346 | 347 | -------------------------------------------------------------------------------- /cbphelp/help110bk.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Clipboard Plus Help 8 | 9 | 11 | 12 | 13 |
14 |
15 | 18 |
Clipboard 19 | Plus
20 |
Help Document
21 |
22 |
23 | 24 | 25 | 26 | 46 | 47 | 48 | 51 | 52 | 53 | 54 | 55 | 56 | 61 | 62 | 63 | 72 | 73 | 74 |
27 | 45 |
49 |

 

50 |
oormi
57 |

By Oormi Creations

58 |

September 2018

59 |

 

60 |
64 |

For queries, support, bug reports, feature requests etc, 65 | please Email us:

66 |

oormicreations@gmail.com

67 |
68 |

Note: Support is minimal and there are no guarantees of any 69 | kind. The software is being provided as is.

70 |
71 |
75 |
76 |
77 | 78 | 79 | 80 | 95 | 103 | 104 | 105 | 126 | 128 | 129 | 130 | 190 | 198 | 199 | 200 | 212 | 215 | 216 | 217 | 276 | 286 | 287 | 288 | 307 | 313 | 314 | 315 |
81 |

Introduction

82 |

Clipboard Plus is a Windows utility to view and manage the 83 | Windows clipboard.

84 |

It maintains and can display up to five copied items or 85 | clips. Clips are arranged from newest to oldest.

86 |

Clicking on a clip loads it back into the clipboard and it is 87 | ready for pasting into another application. It also now 88 | becomes the latest clip, and other clips scroll down.

89 |

To explore more features and functions of this utility, right 90 | click on it.

91 |

This tiny but useful utility is completely free and open 92 | sourced. For more such amazing free apps please visit the 93 | links on the left.

94 |
96 |

101 |
102 |
106 |

Installation

107 |

Download the Windows Installer from: GitHub

110 |

Unzip the downloaded file and run setup.exe.

111 |

Follow the instructions. Run the program from start menu or 112 | by double clicking Clipboard Plus desktop icon.

113 |
114 |

Note: The installer will optionally add a shortcut to the 115 | startup folder of Windows, so that Clipboard Plus starts 116 | automatically when you start Windows. This is enabled by 117 | default. Disabled the auto startup by unchecking the related 118 | checkbox on the last screen of the installer.

119 |
120 |

 

121 |

Please read the License before installing and using this 124 | software.

125 |

127 |
131 |

Usage

132 |

Copy content as usual from any window using Control-C or 133 | Control-X or context menu. The clip will appear in the 134 | Clipboard Plus list. Copy more to add to the list. Click on 135 | any entry in the list to load it in the Windows Clipboard. 136 | Paste it anywhere you like. Whenever you copy something, the 137 | top most clip will be updated and the old clips scroll down.

138 |
139 |

Note: Only text clips are supported.

140 |
141 |

 

142 |
143 |

Note: The last clip will be lost when a new clip is 144 | updated.

145 |
146 |

 

147 |

Right Click on the main window to bring up the Pop Up Menu.

148 |

Clear: Clear individual clips by right 149 | clicking on the clip, and click Clear.

150 |

Clear All: Clear all clips.

151 |

Clear Clipboard: Clear current content of 152 | the clipboard without affecting rest of the clips.

153 |
154 |

Note: You cannot undo Clear commands.

155 |
156 |

 

157 |

Save: Save individual clip as a text file by 158 | right clicking on the clip and click Save.

159 |

Save All: Save all the clips as a text 160 | file.

161 |

Edit Clip: Edit the clip in the edit box 162 | that pops up. Click tick mark button to close. The edited clip 163 | is loaded into the clipboard.

164 |

Open link: If the clip is a link, it will be opened 165 | in your default browser.

166 |

Password Mode: Enable or disable password 167 | mode. When enabled, it masks the copied passwords.

168 |
169 |

Note: A password must have combination of letters, numbers 170 | and special characters to be detected as a password.

171 |

A clip with spaces or with length greater than 16 172 | characters is not considered as a password.

173 |

This feature is language dependent. Currently only English 174 | and Hindi is supported. It cannot recognize Arabic 175 | passwords, for example.

176 |
177 |

 

178 |
179 |

Warning: The hidden 180 | password is not really secure. Anyone can unhide it or load 181 | it up in the clipboard. This feature simply ensures that a 182 | casual onlooker is not able to see it.

183 |

Clear the clip as soon as it is used.

184 |
185 | 186 |


187 |

188 |
189 |
screen shot
191 |
192 |
193 |
194 |
195 |
196 |
197 | pop up menu
View Sticky Clips: Opens the Sticky Clips 201 | window just below the ClipBoard Plus window. You can type in 202 | notes, reminders, text, clips etc and save them for later use. 203 | Here is what the buttons do:
204 |
205 | ✕ : Clear
206 | C : Copy
207 | + : Save note
208 | ← : Next note
209 | → : Previous note
210 | - : Delete note
211 | ✓ : Close
sticky clips screen shot
It has a neat feature to remind you for something important. 218 | Just type in your note and prefix it with the set reminder 219 | command and time. For example:
220 |
221 | set reminder 11:30 call someone
222 | set reminder 2h 15m go jogging and drop trash
223 |
set reminder 20m Skype meeting with client
224 |
225 |
Press Add (+) button to set a reminder as above.
226 |
227 | You should see an ack message showing some details. This is also 228 | saved as a sticky clip for later use. The reminder is a one 229 | time reminder, it won't keep repeating.
230 |
231 | As you must have noticed, there are two ways to specify the 232 | time. Either as HH:MM, in which case the reminder sounds exactly 233 | at that time, or as a duration as xxh yym, in which case the 234 | reminder sounds exactly after that duration.
235 |
236 |
237 |

Note: Its a bit sensitive about syntax. So do not add words 238 | between set reminder and time or do not use words instead of 239 | numbers while mentioning time. Do not use AM or PM. It works in 24 hr format.

240 |

You cannot set a reminder for next day or next week. 241 | However, when you use the duration, it may cross over to the 242 | next day.

243 |
244 |   245 |
246 |

Warning: This is not a 247 | Windows scheduler event or OS level alarm. If you exit 248 | ClipBoard Plus, you will never get reminded. Closing and 249 | restarting ClipBoard Plus has the same effect. Reminders are 250 | timer based, they are not retained (As for version 1.1.0).

251 |

You can set up to 20 reminders. The 21st reminder will overwrite the first and so on.

252 |
253 | 254 |


255 |

256 |
257 |

Note: The reminder appears as a message box. If your text 258 | is too long, it gets truncated. But you can view the full 259 | text in sticky clips.

260 |

If you are not happy with the voice that announces the 261 | reminder, you can replace it with your own jingle or sound 262 | by replacing the rem.wav file found in this 263 | location:

264 |

My Documents\Oormi Creations\Clipboard Plus

265 |
266 |   267 |
268 |

Note: Sticky clips can save up to 300 clips. The clips are 269 | saved as delimited text file. If you wish to have more 270 | clips, just rename the CBP_StickyClips.txt file, 271 | which can be found in:

272 |

My Documents\Oormi Creations\Clipboard Plus

273 |

You can also delete it to quickly clear all saved clips.

274 |
275 |  
rem screen shot
279 |
280 |
281 | rem ack screen shot
284 |
285 |

289 | Add to Sticky Clips: This will add the clip on 290 | which you right clicked to the Sticky Clips. If you wish to use 291 | a clip often or want to save it for later, you can do so here. 292 | Note that as you copy other things, the clip will disappear from 293 | the main list, but it will be there in the Sticky Clips.
294 |
295 |

Minimize to tray: The main window is 296 | hidden and can be restored from the tray icon.

297 |

Help: Access this help online.

298 |

About: Information about Clipboard Plus.

299 |

Check for updates: If updates are available 300 | the user is prompted to update and the download website is 301 | opened in the browser.

302 |

Get more free apps: Opens the Oormi 303 | Creations GitHub repository where you can find more awesome, 304 | free and open source apps like this one.

305 |

Exit: Closes Clipboard Plus.

306 |

308 |
309 |
310 |
311 |
312 |
316 |
317 |
318 | 328 |
329 | 330 | 331 | -------------------------------------------------------------------------------- /cbphelp/images/ClipBoardPlus170p.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oormicreations/ClipboardPlus/5c12e91e287ad68d15f2af375b6a56b9bef22026/cbphelp/images/ClipBoardPlus170p.png -------------------------------------------------------------------------------- /cbphelp/images/OormiLogo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oormicreations/ClipboardPlus/5c12e91e287ad68d15f2af375b6a56b9bef22026/cbphelp/images/OormiLogo.png -------------------------------------------------------------------------------- /cbphelp/images/popupmenu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oormicreations/ClipboardPlus/5c12e91e287ad68d15f2af375b6a56b9bef22026/cbphelp/images/popupmenu.png -------------------------------------------------------------------------------- /cbphelp/images/promohelp.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oormicreations/ClipboardPlus/5c12e91e287ad68d15f2af375b6a56b9bef22026/cbphelp/images/promohelp.jpg -------------------------------------------------------------------------------- /cbphelp/images/ss.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oormicreations/ClipboardPlus/5c12e91e287ad68d15f2af375b6a56b9bef22026/cbphelp/images/ss.png -------------------------------------------------------------------------------- /cbphelp/images/ssnotes.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oormicreations/ClipboardPlus/5c12e91e287ad68d15f2af375b6a56b9bef22026/cbphelp/images/ssnotes.png -------------------------------------------------------------------------------- /cbphelp/images/ssrem.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oormicreations/ClipboardPlus/5c12e91e287ad68d15f2af375b6a56b9bef22026/cbphelp/images/ssrem.png -------------------------------------------------------------------------------- /cbphelp/images/ssremack.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oormicreations/ClipboardPlus/5c12e91e287ad68d15f2af375b6a56b9bef22026/cbphelp/images/ssremack.png -------------------------------------------------------------------------------- /cbphelp/images/ssremui.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oormicreations/ClipboardPlus/5c12e91e287ad68d15f2af375b6a56b9bef22026/cbphelp/images/ssremui.png -------------------------------------------------------------------------------- /cbphelp/main.css: -------------------------------------------------------------------------------- 1 | @charset "utf-8"; 2 | body { 3 | font: 110%/1.4 Garamond, Georgia, "Times New Roman", Times, serif, sans-serif; 4 | background-color: #F9F9F9; 5 | margin: 0; 6 | padding: 0; 7 | color: #000; 8 | } 9 | /* ~~ Element/tag selectors ~~ */ 10 | ul, ol, dl { /* Due to variations between browsers, it's best practices to zero padding and margin on lists. For consistency, you can either specify the amounts you want here, or on the list items (LI, DT, DD) they contain. Remember that what you do here will cascade to the .nav list unless you write a more specific selector. */ 11 | padding: 0; 12 | margin: 0; 13 | } 14 | h1, h2, h3, h4, h5, h6, p { 15 | margin-top: 0; /* removing the top margin gets around an issue where margins can escape from their containing div. The remaining bottom margin will hold it away from any elements that follow. */ 16 | padding-right: 15px; 17 | padding-left: 15px; /* adding the padding to the sides of the elements within the divs, instead of the divs themselves, gets rid of any box model math. A nested div with side padding can also be used as an alternate method. */ 18 | } 19 | a img { /* this selector removes the default blue border displayed in some browsers around an image when it is surrounded by a link */ 20 | border: none; 21 | } 22 | /* ~~ Styling for your site's links must remain in this order - including the group of selectors that create the hover effect. ~~ */ 23 | a:link { 24 | color: #414958; 25 | text-decoration: underline; /* unless you style your links to look extremely unique, it's best to provide underlines for quick visual identification */ 26 | } 27 | a:visited { 28 | color: #4E5869; 29 | text-decoration: underline; 30 | } 31 | a:hover, a:active, a:focus { /* this group of selectors will give a keyboard navigator the same hover experience as the person using a mouse. */ 32 | text-decoration: none; 33 | } 34 | 35 | .container { 36 | width: 80%; 37 | background-color: #FFF; 38 | margin: 0 auto; /* the auto value on the sides, coupled with the width, centers the layout. It is not needed if you set the .container's width to 100%. */ 39 | } 40 | 41 | .header { 42 | height:170px; 43 | background: #E8E8E8; 44 | background: -webkit-linear-gradient(#E8E8E8, #ffffff); 45 | background: -moz-linear-gradient(#E8E8E8, #ffffff); 46 | background: linear-gradient(#E8E8E8, #ffffff); 47 | border-bottom: 2px dotted #888; 48 | border-top: 2px dotted #888; 49 | 50 | } 51 | 52 | .b2blogo { 53 | float:left; 54 | padding-left: 20px; 55 | } 56 | 57 | .b2btitle { 58 | float:right; 59 | font-size: 42px; 60 | padding-right: 60px; 61 | padding-top:40px; 62 | } 63 | 64 | .b2bsubtitle { 65 | clear:right; 66 | float:right; 67 | font-size: 24px; 68 | padding-right: 60px; 69 | } 70 | 71 | .sidebar { 72 | clear:both; 73 | float: left; 74 | width: 20%; 75 | min-width: 180px; 76 | height: auto; 77 | background: #E8E8E8; 78 | background: -webkit-linear-gradient(#E8E8E8, #ffffff); 79 | background: -moz-linear-gradient(#E8E8E8, #ffffff); 80 | background: linear-gradient(#E8E8E8, #ffffff); 81 | bottom: 0px; 82 | word-wrap:break-word; 83 | } 84 | 85 | .content { 86 | float:right; 87 | width:75%; 88 | /* background: #E8E8E0;*/ 89 | } 90 | 91 | ul.nav { 92 | background: #E8E8E8; 93 | background: -webkit-linear-gradient(#E8E8E8, #ffffff); 94 | background: -moz-linear-gradient(#E8E8E8, #ffffff); 95 | background: linear-gradient(#E8E8E8, #ffffff); 96 | list-style: none; /* this removes the list marker */ 97 | /* [disabled]border-top: 2px dotted #888;*/ /* this creates the top border for the links - all others are placed using a bottom border on the LI */ 98 | margin-bottom: 15px; /* this creates the space between the navigation on the content below */ 99 | } 100 | 101 | ul.nav li { 102 | border-bottom: 2px dotted #888; 103 | } 104 | 105 | ul.nav a, ul.nav a:visited { /* grouping these selectors makes sure that your links retain their button look even after being visited */ 106 | padding: 5px 5px 5px 5px; 107 | display: block; /* this gives the link block properties causing it to fill the whole LI containing it. This causes the entire area to react to a mouse click. */ 108 | text-decoration: none; 109 | color: #000; 110 | } 111 | 112 | ul.nav a:hover, ul.nav a:active, ul.nav a:focus { /* this changes the background and text color for both mouse and keyboard navigators */ 113 | background-color: #bbb; 114 | color: #414141; 115 | } 116 | 117 | .footer { 118 | padding: 10px 0; 119 | background: #E8E8E8; 120 | background: -webkit-linear-gradient(#E8E8E8, #ffffff); 121 | background: -moz-linear-gradient(#E8E8E8, #ffffff); 122 | background: linear-gradient(#E8E8E8, #ffffff); 123 | position: relative;/* this gives IE6 hasLayout to properly clear */ 124 | clear: both; 125 | text-align: center; 126 | padding-top: 20px; 127 | border-top: 2px dotted #888; 128 | border-bottom: 2px dotted #888; 129 | } 130 | 131 | .noticebox { 132 | background-color: #DDDDD9; 133 | text-align: left; 134 | display: block; 135 | padding-left: 15px; 136 | padding-right: 15px; 137 | padding-bottom: 5px; 138 | padding-top: 15px; 139 | border-radius: 7px; 140 | width: 70%; 141 | } 142 | 143 | 144 | 145 | 146 | .FAQ { 147 | vertical-align: top; 148 | height: auto; 149 | } 150 | 151 | .list { 152 | display:none; 153 | height:auto; 154 | margin:0; 155 | float: left; 156 | } 157 | 158 | .show { 159 | display: none; 160 | } 161 | 162 | .hide:target + .show { 163 | display: inline; 164 | } 165 | .hide:target { 166 | display: none; 167 | } 168 | .hide:target ~ .list { 169 | display:inline; 170 | } 171 | 172 | /*style the (+) and (-) */ 173 | .hide, .show { 174 | width: 80%; 175 | height: 30px; 176 | border-radius: 3px; 177 | background: #DDDDD9; 178 | margin-right: 0; 179 | float: left; 180 | margin-bottom: 15px; 181 | padding-left: 15px; 182 | 183 | } 184 | 185 | .hide:hover, .show:hover { 186 | text-decoration: none; 187 | box-shadow: 0 0 4px #222 inset; 188 | margin-bottom: 15px; 189 | } 190 | 191 | .list p { 192 | height:auto; 193 | margin:0; 194 | } 195 | .question { 196 | float: left; 197 | height: auto; 198 | width: 90%; 199 | line-height: 20px; 200 | padding-left: 20px; 201 | margin-bottom: 25px; 202 | 203 | } -------------------------------------------------------------------------------- /cbphelp/updatecbp.txt: -------------------------------------------------------------------------------- 1 | 1|3|https://github.com/oormicreations/ClipboardPlus/releases -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # ClipBoard Plus Project Overview 2 | 3 | ![Promo](https://oormi.in/software/cbp/images/promohelp.jpg) 4 | 5 | 6 | **Clipboard Plus** is a free and open sourced windows application for viewing and managing a clipboard with multiple clips. 7 | 8 | It maintains and can display up to five copied items or clips. Clips are arranged from newest to oldest. 9 | 10 | Clicking on a clip loads it back into the clipboard and it is ready for pasting into another application. It also now becomes the latest clip, and other clips scroll down. 11 | 12 | To explore more features and functions of this utility, right click on it. 13 | 14 | It has a built in Sticky Note tool in which the clips can be stored, notes can be added and reminders can be set. 15 | 16 | It also has a feature to set reminders. 17 | 18 | This tiny but useful utility is completely free and open sourced. 19 | 20 | --- 21 | 22 | **Usage and Help** 23 | 24 | https://oormi.in/software/cbp/help110.html 25 | 26 | --- 27 | 28 | **Intro Video** 29 | 30 | https://www.youtube.com/watch?v=PSwx6liKgnA 31 | 32 | --- 33 | 34 | **Download link** 35 | 36 | https://github.com/oormicreations/ClipboardPlus/releases 37 | 38 | [![Github All Releases](https://img.shields.io/github/downloads/oormicreations/ClipboardPlus/total.svg)]() 39 | 40 | --- 41 | 42 | **Features:** 43 | 44 | * Stores multiple clips as you copy. 45 | * Stores up to 5 text clips. 46 | * Clicking on any of the preview clip loads it on to the clipboard. 47 | * Clear specific clips or clear all. 48 | * Save specific clips or save all as text file. 49 | * Open URLs directly from Clipboard Plus. 50 | * Edit clips 51 | * Hides copied passwords automatically. 52 | 53 | * Built in Sticky Clips. 54 | * Send clips to Sticky Clips. 55 | * Set reminders. 56 | 57 | * Remembers window position. 58 | * Can be minimized to the tray. 59 | * Minimal UI. 60 | 61 | * Supported on MS Windows 7 to 10. 62 | * IDE MS VS 2015, C++, MFC 63 | 64 | --- 65 | 66 | **What is new in version 1.3** 67 | 68 | * GUI for reminders 69 | * Bug fixes 70 | * Better right click menu 71 | * Can delete auto saved (persistant) clips if needed 72 | 73 | --- 74 | 75 | **What is new in version 1.2** 76 | 77 | * Always on top option 78 | * Persistant clips (Saves and displays clips even after PC is turned off and on) 79 | * Browse slider to quickly go to any Sticky clip or Note 80 | * Cleaner UI 81 | * Code improvements 82 | * Bug fix: Changing the clip in Sticky clips will not add a new Sticky clip 83 | 84 | 85 | --- 86 | 87 | A FOSS Project by Oormi Creations 88 | 89 | http://oormi.in 90 | 91 | oormicreations@gmail.com 92 | 93 | 94 | ![logo](https://oormi.in/software/cbp/images/OormiLogo.png) --------------------------------------------------------------------------------