├── .gitignore ├── LICENSE ├── Makefile ├── README.md ├── abpack.pl ├── resource.h ├── scite.bmp ├── wscitecm-remove.reg ├── wscitecm.cpp ├── wscitecm.def ├── wscitecm.h ├── wscitecm.manifest └── wscitecm.rc /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled Object files 2 | *.slo 3 | *.lo 4 | *.o 5 | *.obj 6 | 7 | # Compiled Dynamic libraries 8 | *.so 9 | *.dylib 10 | *.dll 11 | 12 | # Compiled Static libraries 13 | *.lai 14 | *.la 15 | *.a 16 | *.lib 17 | 18 | # Executables 19 | *.exe 20 | *.out 21 | *.app 22 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2000-2014 Andre Burgaud (http://www.burgaud.com) 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | TARGETOS = BOTH 2 | !include 3 | 4 | lflags = /NODEFAULTLIB /INCREMENTAL:NO /RELEASE /NOLOGO 5 | dlllflags = $(lflags) -entry:_DllMainCRTStartup$(DLLENTRY) -dll 6 | 7 | all: wscitecm.dll 8 | 9 | wscitecm.dll: wscitecm.obj wscitecm.res 10 | $(implib) -machine:$(CPU) -def:wscitecm.def $** -out:wscitecm.lib 11 | $(link) $(dlllflags) -base:0x1C000000 -out:$*.dll $** $(olelibsdll) shell32.lib msvcrt.lib wscitecm.lib comctl32.lib wscitecm.exp 12 | mt -manifest $*.manifest -outputresource:$*.dll;2 13 | 14 | .cpp.obj: 15 | $(cc) $(cflags) $(cvarsdll) $*.cpp 16 | 17 | wscitecm.res: wscitecm.rc 18 | $(rc) $(rcflags) $(rcvars) wscitecm.rc 19 | 20 | clean: 21 | -1 del wscitecm.dll wscitecm.lib wscitecm.dll.manifest wscitecm.obj wscitecm.exp wscitecm.res 22 | 23 | zip: 24 | -1 del *.zip 25 | perl abpack.pl -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | wscitecm 2 | ======== 3 | 4 | SciTE Context Menu Extension 5 | 6 | 7 | Description 8 | ----------- 9 | Context Menu Extension for SciTE (Win32) 10 | Version: 1.4.0 11 | Date: 12/06/2008 12 | OS: Windows 13 | Main file: wscitecm.dll 14 | 15 | Overview 16 | -------- 17 | `wscitecm.dll` is a companion to Scintilla Text Editor (SiTE) on Windows (32-bit and 64-bit). Installing wscitecm.dll creates a new command **Edit with SciTE** in the context menu of Windows Explorer. You can quickly open one or several selected files in Windows Explorer: right click on the selection and click on the command **Edit with SciTE**. For a friendly installation, I recommend to use the [SciTE setup provided by Bruce Dodson](http://gisdeveloper.tripod.com/scite.html) or [Troy Simpson's implemention of SciTEInstaller](http://opensource.ebswift.com/SciTEInstaller/). 18 | 19 | The manual build and installation is described in the following sections. 20 | 21 | For additional information and to download the binaries, visit [http://www.burgaud.com/scite-context-menu/](http://www.burgaud.com/scite-context-menu/). 22 | 23 | Uninstallation 24 | -------------- 25 | **To uninstall a version prior to 1.2** 26 | 27 | - Double click on the file `wscitecm-remove.reg`. This will clean-up the old registry keys. This script was provided by Bruce Dodson. 28 | 29 | **To uninstall any version newer than 1.2** 30 | 31 | - In SciTE directory installation, type the command `regsvr32 /u wscitecm.dll`. 32 | 33 | Installation 34 | ------------ 35 | 1. Copy `wscitecm.dll` in SciTE directory. Refer to the paragraph unload the dll if you have the error: **Access is denied** 36 | 1. In SciTE directory installation, type the command `regsvr32 wscitecm.dll`. This will register the dll. 37 | 38 | If everything goes well, you should have **Edit with SciTE** when you right click on selected file(s) in Windows Explorer. 39 | 40 | Unload the dll 41 | -------------- 42 | If you try to delete or override the dll file and you get the error **Access is denied**, the library is already loaded. There are several options to workaround this issue: 43 | 44 | **Solution 1** 45 | 46 | - Close all the Windows Explorer instances open on your desktop and copy wsctecm.dll using the command line (Example: "C:/>cp wscitecm.dll "). 47 | 48 | **Solution 2** 49 | 50 | - Reboot the computer and delete or override wscitecm.dll (with the command line) before starting Windows Explorer and using the context menu (right-click). 51 | 52 | **Solution 3** 53 | 54 | - Open a command line window 55 | - Type CTRL+ALT+DEL to display the Windows Task Manager, display the Process tab and "kill" the explorer.exe process. 56 | - If Windows Exlorer does not restart automatically, start it manually from the command line window (c:/>explorer). 57 | - Delete or override wscitecm.dll before using the context menu (Example: "C:/>cp wscitecm.dll "). 58 | 59 | Build 60 | ----- 61 | Until version 1.2.1, wscitecm was built with Visual C++ 6.0. Version 1.3.0 (32-bit and 64-bit) was built with Visual Studio 2005. A Makefile is provided with the sources: in the source directory, type "nmake". Ensure that all the environment variables and paths are set correctly. To do so, use the command file "VCVARS32.BAT" available in the bin directory of Visual C++ installation. 62 | 63 | History 64 | ------- 65 | **Version 1.4.0 (12/06/2008)** 66 | 67 | - Fixed an issue with the manifest file introduced with VS 2005 compilation 68 | - Modified the GUID to avoid conflict with Notepad++ reusing wscitecm code with the same GUID 69 | 70 | **Version 1.3.0 (05/26/2008)** 71 | 72 | - Support for Vista 64-bit 73 | - Build with Visual Studio 2005 74 | - Fixed warnings related to string functions 75 | 76 | **Version 1.2.1 (01/21/2003)** 77 | 78 | - Released under MIT license and packaged with the source code 79 | 80 | **Version 1.2** 81 | 82 | - Registration and unregistration of the Shell Extension included in the code 83 | - SciTE icon displayed in the context menu 84 | 85 | **Version 1.x** 86 | 87 | - Initial version 88 | 89 | License 90 | ------- 91 | See LICENSE file. 92 | -------------------------------------------------------------------------------- /abpack.pl: -------------------------------------------------------------------------------- 1 | #--------------------------------------------------------------------------- 2 | # See LICSENSE 3 | #--------------------------------------------------------------------------- 4 | # abpack.pl: Generates binaries and sources archives 5 | #--------------------------------------------------------------------------- 6 | 7 | require "ctime.pl"; 8 | use Archive::Zip qw( :ERROR_CODES :CONSTANTS ); 9 | 10 | my $author_name = "Andre Burgaud"; 11 | my $author_email = "andre\@burgaud.com"; 12 | my $author_web = "www.burgaud.com"; 13 | 14 | my $project_title = "Context Menu Extension for SciTE"; 15 | my $project_name = "wscitecm"; 16 | my $project_extension = "140"; 17 | my $project_version = "1.4.0"; 18 | my $project_date = "12/06/2008"; 19 | 20 | my $note_line = "================================\n"; 21 | 22 | my @list_bin = qw( 23 | readme.txt 24 | license.txt 25 | wscitecm-remove.reg 26 | wscitecm.dll 27 | wscitecm64.dll 28 | ); 29 | 30 | my @list_src = qw( 31 | readme.txt 32 | license.txt 33 | wscitecm-remove.reg 34 | wscitecm.cpp 35 | wscitecm.h 36 | wscitecm.rc 37 | wscitecm.def 38 | resource.h 39 | scite.bmp 40 | Makefile 41 | abpack.pl 42 | ); 43 | 44 | # Binaries Package 45 | my $note_bin = create_note("Binary Files"); 46 | my $zip_bin = Archive::Zip->new(); 47 | print "Creating binary package...\n"; 48 | create_zip("$project_name$project_extension.zip", $zip_bin, $note_bin, @list_bin); 49 | 50 | # Sources Package 51 | my $note_src = create_note("Source Files"); 52 | my $zip_src = Archive::Zip->new(); 53 | print "Creating source package...\n"; 54 | create_zip("$project_name$project_extension" . "_src.zip", $zip_src, $note_src, @list_src); 55 | 56 | # Functions 57 | sub create_zip(zip_name, comment, zip, list) { 58 | my ($zip_name, $zip, $comment, @list) = @_; 59 | for (@list) { 60 | print "Zipping $_...\n"; 61 | $member = $zip->addFile($_); 62 | } 63 | $member->desiredCompressionLevel(9); 64 | $zip->zipfileComment($comment); 65 | die "Write error" if $zip->writeToFileNamed($zip_name) != AZ_OK; 66 | } 67 | 68 | sub create_note() { 69 | my ($type) = @_; 70 | my $note = ""; 71 | $note .= $note_line; 72 | $note .= "$project_title\n"; 73 | $note .= $note_line; 74 | $note .= "$type\n"; 75 | $note .= "Version: $project_version $project_date\n"; 76 | $note .= "Author: $author_name <$author_email>\n"; 77 | $date=&ctime(time); 78 | $note .= "$date"; 79 | return $note; 80 | } -------------------------------------------------------------------------------- /resource.h: -------------------------------------------------------------------------------- 1 | //{{NO_DEPENDENCIES}} 2 | // Microsoft Developer Studio generated include file. 3 | // Used by wscitecm.rc 4 | // 5 | 6 | #define IDI_SCITE 101 7 | #define IDB_SCITE 102 8 | 9 | // Next default values for new objects 10 | // 11 | #ifdef APSTUDIO_INVOKED 12 | #ifndef APSTUDIO_READONLY_SYMBOLS 13 | #define _APS_NEXT_RESOURCE_VALUE 104 14 | #define _APS_NEXT_COMMAND_VALUE 40001 15 | #define _APS_NEXT_CONTROL_VALUE 1000 16 | #define _APS_NEXT_SYMED_VALUE 101 17 | #endif 18 | #endif 19 | -------------------------------------------------------------------------------- /scite.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/andreburgaud/wscitecm/462b79b56cde8300cf71d6228fdc09136e62af86/scite.bmp -------------------------------------------------------------------------------- /wscitecm-remove.reg: -------------------------------------------------------------------------------- 1 | REGEDIT4 2 | 3 | [-HKEY_CLASSES_ROOT\CLSID\{120b94b5-2e6a-4f13-94d0-414bcb64fa0f}] 4 | [-HKEY_CLASSES_ROOT\*\shellex\ContextMenuHandlers\SciTE] 5 | [-HKEY_CURRENT_USER\Software\SciTE] 6 | -------------------------------------------------------------------------------- /wscitecm.cpp: -------------------------------------------------------------------------------- 1 | //--------------------------------------------------------------------------- 2 | // See LICENSE 3 | //--------------------------------------------------------------------------- 4 | 5 | //--------------------------------------------------------------------------- 6 | // wscitecm.cpp 7 | // Defines the entry point for the DLL application. 8 | //--------------------------------------------------------------------------- 9 | 10 | #ifndef STRICT 11 | #define STRICT 12 | #endif 13 | 14 | #define INC_OLE2 15 | 16 | #include 17 | #include 18 | #include 19 | 20 | #define GUID_SIZE 128 21 | #define MAX_FILES 10 22 | #define MAX_CMDSTR (MAX_PATH * MAX_FILES) 23 | #define ResultFromShort(i) ResultFromScode(MAKE_SCODE(SEVERITY_SUCCESS, 0, (USHORT)(i))) 24 | 25 | #pragma data_seg(".text") 26 | #define INITGUID 27 | #include 28 | #include 29 | #include "resource.h" 30 | #include "wscitecm.h" 31 | #pragma data_seg() 32 | 33 | //--------------------------------------------------------------------------- 34 | // Global variables 35 | //--------------------------------------------------------------------------- 36 | UINT _cRef = 0; // COM Reference count. 37 | HINSTANCE _hModule = NULL; // DLL Module. 38 | 39 | typedef struct{ 40 | HKEY hRootKey; 41 | LPTSTR szSubKey; 42 | LPTSTR lpszValueName; 43 | LPTSTR szData; 44 | } DOREGSTRUCT, *LPDOREGSTRUCT; 45 | 46 | char szSciTEName[] = "SciTE.exe"; 47 | char szShellExtensionTitle[] = "SciTE"; 48 | 49 | BOOL RegisterServer(CLSID, LPTSTR); 50 | BOOL UnregisterServer(CLSID, LPTSTR); 51 | void MsgBox(LPTSTR); 52 | void MsgBoxDebug(LPTSTR); 53 | void MsgBoxError(LPTSTR); 54 | 55 | //--------------------------------------------------------------------------- 56 | // DllMain 57 | //--------------------------------------------------------------------------- 58 | extern "C" int APIENTRY 59 | DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved) { 60 | if (dwReason == DLL_PROCESS_ATTACH) { 61 | _hModule = hInstance; 62 | } 63 | return 1; 64 | } 65 | 66 | //--------------------------------------------------------------------------- 67 | // DllCanUnloadNow 68 | //--------------------------------------------------------------------------- 69 | STDAPI DllCanUnloadNow(void) { 70 | return (_cRef == 0 ? S_OK : S_FALSE); 71 | } 72 | 73 | //--------------------------------------------------------------------------- 74 | // DllGetClassObject 75 | //--------------------------------------------------------------------------- 76 | STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppvOut) { 77 | *ppvOut = NULL; 78 | if (IsEqualIID(rclsid, CLSID_ShellExtension)) { 79 | CShellExtClassFactory *pcf = new CShellExtClassFactory; 80 | return pcf->QueryInterface(riid, ppvOut); 81 | } 82 | return CLASS_E_CLASSNOTAVAILABLE; 83 | } 84 | 85 | //--------------------------------------------------------------------------- 86 | // DllRegisterServer 87 | //--------------------------------------------------------------------------- 88 | STDAPI DllRegisterServer() { 89 | return (RegisterServer(CLSID_ShellExtension, szShellExtensionTitle) ? S_OK : E_FAIL); 90 | } 91 | 92 | //--------------------------------------------------------------------------- 93 | // DllUnregisterServer 94 | //--------------------------------------------------------------------------- 95 | STDAPI DllUnregisterServer(void) { 96 | return (UnregisterServer(CLSID_ShellExtension, szShellExtensionTitle) ? S_OK : E_FAIL); 97 | } 98 | 99 | //--------------------------------------------------------------------------- 100 | // CheckSciTE 101 | //--------------------------------------------------------------------------- 102 | BOOL CheckSciTE() { 103 | TCHAR szModuleFullName[MAX_PATH]; 104 | TCHAR szExeFullName[MAX_PATH]; 105 | int nLenPath = 0; 106 | TCHAR* pDest; 107 | LPTSTR *lpFilePart = NULL; 108 | 109 | GetModuleFileName(_hModule, szModuleFullName, MAX_PATH); 110 | pDest = strrchr(szModuleFullName, '\\' ); 111 | pDest++; 112 | pDest[0] = 0; 113 | 114 | DWORD dw = SearchPath(szModuleFullName, szShellExtensionTitle, ".exe", MAX_PATH, szExeFullName, lpFilePart); 115 | 116 | return (dw ? TRUE : FALSE); 117 | } 118 | 119 | //--------------------------------------------------------------------------- 120 | // RegisterServer 121 | //--------------------------------------------------------------------------- 122 | BOOL RegisterServer(CLSID clsid, LPTSTR lpszTitle) { 123 | int i; 124 | HKEY hKey; 125 | LRESULT lResult; 126 | DWORD dwDisp; 127 | TCHAR szSubKey[MAX_PATH]; 128 | TCHAR szCLSID[MAX_PATH]; 129 | TCHAR szModule[MAX_PATH]; 130 | LPWSTR pwsz; 131 | 132 | if (!CheckSciTE()) { 133 | MsgBoxError("To register the SciTE context menu extension,\r\ninstall wscitecm.dll in the same directory than SciTE.exe."); 134 | return FALSE; 135 | } 136 | 137 | StringFromIID(clsid, &pwsz); 138 | if(pwsz) { 139 | #ifdef UNICODE 140 | lstrcpy(szCLSID, pwsz); 141 | #else 142 | WideCharToMultiByte(CP_ACP, 0, pwsz, -1, szCLSID, ARRAYSIZE(szCLSID), NULL, NULL); 143 | #endif 144 | //free the string 145 | LPMALLOC pMalloc; 146 | CoGetMalloc(1, &pMalloc); 147 | pMalloc->Free(pwsz); 148 | pMalloc->Release(); 149 | } 150 | 151 | //get this app's path and file name 152 | GetModuleFileName(_hModule, szModule, MAX_PATH); 153 | 154 | DOREGSTRUCT ClsidEntries[] = { 155 | HKEY_CLASSES_ROOT, TEXT("CLSID\\%s"), NULL, lpszTitle, 156 | HKEY_CLASSES_ROOT, TEXT("CLSID\\%s\\InprocServer32"), NULL, szModule, 157 | HKEY_CLASSES_ROOT, TEXT("CLSID\\%s\\InprocServer32"), TEXT("ThreadingModel"), TEXT("Apartment"), 158 | HKEY_CLASSES_ROOT, TEXT("*\\shellex\\ContextMenuHandlers\\SciTE"), NULL, szCLSID, 159 | NULL, NULL, NULL, NULL 160 | }; 161 | 162 | // Register the CLSID entries 163 | for(i = 0; ClsidEntries[i].hRootKey; i++) { 164 | // Create the sub key string - for this case, insert the file extension 165 | wsprintf(szSubKey, ClsidEntries[i].szSubKey, szCLSID); 166 | lResult = RegCreateKeyEx(ClsidEntries[i].hRootKey, szSubKey, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hKey, &dwDisp); 167 | if(NOERROR == lResult) { 168 | TCHAR szData[MAX_PATH]; 169 | // If necessary, create the value string 170 | wsprintf(szData, ClsidEntries[i].szData, szModule); 171 | lResult = RegSetValueEx(hKey, ClsidEntries[i].lpszValueName, 0, REG_SZ, (LPBYTE)szData, (lstrlen(szData) + 1) * sizeof(TCHAR)); 172 | RegCloseKey(hKey); 173 | } 174 | else 175 | return FALSE; 176 | } 177 | return TRUE; 178 | } 179 | 180 | //--------------------------------------------------------------------------- 181 | // UnregisterServer 182 | //--------------------------------------------------------------------------- 183 | BOOL UnregisterServer(CLSID clsid, LPTSTR lpszTitle) { 184 | TCHAR szCLSID[GUID_SIZE + 1]; 185 | TCHAR szCLSIDKey[GUID_SIZE + 32]; 186 | TCHAR szKeyTemp[MAX_PATH + GUID_SIZE]; 187 | LPWSTR pwsz; 188 | 189 | StringFromIID(clsid, &pwsz); 190 | if(pwsz) { 191 | #ifdef UNICODE 192 | lstrcpy(szCLSID, pwsz); 193 | #else 194 | WideCharToMultiByte(CP_ACP, 0, pwsz, -1, szCLSID, ARRAYSIZE(szCLSID), NULL, NULL); 195 | #endif 196 | //free the string 197 | LPMALLOC pMalloc; 198 | CoGetMalloc(1, &pMalloc); 199 | pMalloc->Free(pwsz); 200 | pMalloc->Release(); 201 | } 202 | 203 | lstrcpy(szCLSIDKey, TEXT("CLSID\\")); 204 | lstrcat(szCLSIDKey, szCLSID); 205 | 206 | wsprintf(szKeyTemp, TEXT("*\\shellex\\ContextMenuHandlers\\%s"), lpszTitle); 207 | RegDeleteKey(HKEY_CLASSES_ROOT, szKeyTemp); 208 | 209 | wsprintf(szKeyTemp, TEXT("%s\\%s"), szCLSIDKey, TEXT("InprocServer32")); 210 | RegDeleteKey(HKEY_CLASSES_ROOT, szKeyTemp); 211 | RegDeleteKey(HKEY_CLASSES_ROOT, szCLSIDKey); 212 | 213 | return TRUE; 214 | } 215 | 216 | //--------------------------------------------------------------------------- 217 | // MsgBoxDebug 218 | //--------------------------------------------------------------------------- 219 | void MsgBoxDebug(LPTSTR lpszMsg) { 220 | MessageBox(NULL, 221 | lpszMsg, 222 | "DEBUG", 223 | MB_OK); 224 | } 225 | 226 | //--------------------------------------------------------------------------- 227 | // MsgBox 228 | //--------------------------------------------------------------------------- 229 | void MsgBox(LPTSTR lpszMsg) { 230 | MessageBox(NULL, 231 | lpszMsg, 232 | "SciTE Extension", 233 | MB_OK); 234 | } 235 | 236 | //--------------------------------------------------------------------------- 237 | // MsgBoxError 238 | //--------------------------------------------------------------------------- 239 | void MsgBoxError(LPTSTR lpszMsg) { 240 | MessageBox(NULL, 241 | lpszMsg, 242 | "SciTE Extension", 243 | MB_OK | MB_ICONSTOP); 244 | } 245 | 246 | //--------------------------------------------------------------------------- 247 | // CShellExtClassFactory 248 | //--------------------------------------------------------------------------- 249 | CShellExtClassFactory::CShellExtClassFactory() { 250 | m_cRef = 0L; 251 | _cRef++; 252 | } 253 | 254 | CShellExtClassFactory::~CShellExtClassFactory() { 255 | _cRef--; 256 | } 257 | 258 | STDMETHODIMP CShellExtClassFactory::QueryInterface(REFIID riid, LPVOID FAR *ppv) { 259 | *ppv = NULL; 260 | if (IsEqualIID(riid, IID_IUnknown) || IsEqualIID(riid, IID_IClassFactory)) { 261 | *ppv = (LPCLASSFACTORY)this; 262 | AddRef(); 263 | return NOERROR; 264 | } 265 | return E_NOINTERFACE; 266 | } 267 | 268 | STDMETHODIMP_(ULONG) CShellExtClassFactory::AddRef() { 269 | return ++m_cRef; 270 | } 271 | 272 | STDMETHODIMP_(ULONG) CShellExtClassFactory::Release() 273 | { 274 | if (--m_cRef) 275 | return m_cRef; 276 | delete this; 277 | return 0L; 278 | } 279 | 280 | STDMETHODIMP CShellExtClassFactory::CreateInstance(LPUNKNOWN pUnkOuter, REFIID riid, LPVOID *ppvObj) { 281 | *ppvObj = NULL; 282 | if (pUnkOuter) 283 | return CLASS_E_NOAGGREGATION; 284 | LPCSHELLEXT pShellExt = new CShellExt(); 285 | if (NULL == pShellExt) 286 | return E_OUTOFMEMORY; 287 | return pShellExt->QueryInterface(riid, ppvObj); 288 | } 289 | 290 | STDMETHODIMP CShellExtClassFactory::LockServer(BOOL fLock) { 291 | return NOERROR; 292 | } 293 | 294 | //--------------------------------------------------------------------------- 295 | // CShellExt 296 | //--------------------------------------------------------------------------- 297 | CShellExt::CShellExt() { 298 | m_cRef = 0L; 299 | m_pDataObj = NULL; 300 | _cRef++; 301 | m_hSciteBmp = LoadBitmap(_hModule, MAKEINTRESOURCE(IDB_SCITE)); 302 | HRESULT hr; 303 | hr = SHGetMalloc(&m_pAlloc); 304 | if (FAILED(hr)) 305 | m_pAlloc = NULL; 306 | } 307 | 308 | CShellExt::~CShellExt() { 309 | if (m_pDataObj) 310 | m_pDataObj->Release(); 311 | _cRef--; 312 | m_pAlloc->Release(); 313 | } 314 | 315 | STDMETHODIMP CShellExt::QueryInterface(REFIID riid, LPVOID FAR *ppv) { 316 | *ppv = NULL; 317 | if (IsEqualIID(riid, IID_IShellExtInit) || IsEqualIID(riid, IID_IUnknown)) { 318 | *ppv = (LPSHELLEXTINIT)this; 319 | } 320 | else if (IsEqualIID(riid, IID_IContextMenu)) { 321 | *ppv = (LPCONTEXTMENU)this; 322 | } 323 | if (*ppv) { 324 | AddRef(); 325 | return NOERROR; 326 | } 327 | return E_NOINTERFACE; 328 | } 329 | 330 | STDMETHODIMP_(ULONG) CShellExt::AddRef() { 331 | return ++m_cRef; 332 | } 333 | 334 | STDMETHODIMP_(ULONG) CShellExt::Release() { 335 | if (--m_cRef) 336 | return m_cRef; 337 | delete this; 338 | return 0L; 339 | } 340 | 341 | STDMETHODIMP CShellExt::Initialize(LPCITEMIDLIST pIDFolder, LPDATAOBJECT pDataObj, HKEY hRegKey) { 342 | HRESULT hres = 0; 343 | if (m_pDataObj) 344 | m_pDataObj->Release(); 345 | if (pDataObj) { 346 | m_pDataObj = pDataObj; 347 | pDataObj->AddRef(); 348 | } 349 | return NOERROR; 350 | } 351 | 352 | STDMETHODIMP CShellExt::QueryContextMenu(HMENU hMenu, UINT indexMenu, UINT idCmdFirst, UINT idCmdLast, UINT uFlags) { 353 | UINT idCmd = idCmdFirst; 354 | BOOL bAppendItems=TRUE; 355 | char szItemSciTE[]="Edit with &SciTE"; 356 | 357 | FORMATETC fmte = { 358 | CF_HDROP, 359 | (DVTARGETDEVICE FAR *)NULL, 360 | DVASPECT_CONTENT, 361 | -1, 362 | TYMED_HGLOBAL 363 | }; 364 | 365 | HRESULT hres = m_pDataObj->GetData(&fmte, &m_stgMedium); 366 | 367 | if (SUCCEEDED(hres)) { 368 | if (m_stgMedium.hGlobal) 369 | m_cbFiles = DragQueryFile((HDROP)m_stgMedium.hGlobal, (UINT)-1, 0, 0); 370 | } 371 | 372 | UINT nIndex = indexMenu++; 373 | InsertMenu(hMenu, nIndex, MF_STRING|MF_BYPOSITION, idCmd++, szItemSciTE); 374 | 375 | if (m_hSciteBmp) { 376 | SetMenuItemBitmaps (hMenu, nIndex, MF_BYPOSITION, m_hSciteBmp, m_hSciteBmp); 377 | } 378 | 379 | return ResultFromShort(idCmd-idCmdFirst); 380 | } 381 | 382 | STDMETHODIMP CShellExt::InvokeCommand(LPCMINVOKECOMMANDINFO lpcmi) { 383 | HRESULT hr = E_INVALIDARG; 384 | 385 | if (!HIWORD(lpcmi->lpVerb)) { 386 | UINT idCmd = LOWORD(lpcmi->lpVerb); 387 | switch(idCmd) { 388 | case 0: 389 | hr = InvokeSciTE(lpcmi->hwnd, lpcmi->lpDirectory, lpcmi->lpVerb, lpcmi->lpParameters, lpcmi->nShow); 390 | break; 391 | } 392 | } 393 | return hr; 394 | } 395 | 396 | STDMETHODIMP CShellExt::GetCommandString(UINT_PTR idCmd, UINT uFlags, UINT FAR *reserved, LPSTR pszName, UINT cchMax) { 397 | if (uFlags == GCS_HELPTEXT && cchMax > 35) 398 | lstrcpy(pszName, "Edits the selected file(s) with SciTE"); 399 | return NOERROR; 400 | } 401 | 402 | static void getSciTEName(char *name) { 403 | TCHAR szModuleFullName[MAX_PATH]; 404 | int nLenPath = 0; 405 | TCHAR* pDest; 406 | 407 | name[0] = 0; 408 | GetModuleFileName(_hModule, szModuleFullName, MAX_PATH); 409 | pDest = strrchr(szModuleFullName, '\\' ); 410 | pDest++; 411 | pDest[0] = 0; 412 | strcpy_s(name, MAX_PATH, szModuleFullName); 413 | strcat_s(name, MAX_PATH, szSciTEName); 414 | 415 | if (name[0] == 0) 416 | strcpy_s(name, MAX_PATH, szSciTEName); 417 | } 418 | 419 | STDMETHODIMP CShellExt::InvokeSciTE(HWND hParent, LPCSTR pszWorkingDir, LPCSTR pszCmd, LPCSTR pszParam, int iShowCmd) { 420 | TCHAR szFileUserClickedOn[MAX_PATH]; 421 | LPTSTR pszCommand; 422 | UINT nSizeCommand; 423 | UINT i; 424 | 425 | FORMATETC fmte = { 426 | CF_HDROP, 427 | (DVTARGETDEVICE FAR *)NULL, 428 | DVASPECT_CONTENT, 429 | -1, 430 | TYMED_HGLOBAL 431 | }; 432 | 433 | nSizeCommand = MAX_PATH * (m_cbFiles + 1) * sizeof(TCHAR); 434 | pszCommand = (LPTSTR)m_pAlloc->Alloc(nSizeCommand); 435 | 436 | if (pszCommand) 437 | getSciTEName(pszCommand); 438 | else { 439 | MsgBoxError("Insufficient memory available."); 440 | return E_FAIL; 441 | } 442 | 443 | for (i = 0; i < m_cbFiles; i++) { 444 | DragQueryFile((HDROP)m_stgMedium.hGlobal, i, szFileUserClickedOn, MAX_PATH); 445 | strcat_s(pszCommand, nSizeCommand, " \""); 446 | strcat_s(pszCommand, nSizeCommand, szFileUserClickedOn); 447 | strcat_s(pszCommand, nSizeCommand, "\""); 448 | } 449 | 450 | STARTUPINFO si; 451 | PROCESS_INFORMATION pi; 452 | ZeroMemory(&si, sizeof(si)); 453 | si.cb = sizeof(si); 454 | si.dwFlags = STARTF_USESHOWWINDOW; 455 | si.wShowWindow = SW_RESTORE; 456 | if (!CreateProcess (NULL, pszCommand, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)) { 457 | MessageBox(hParent, 458 | "Error creating process: wscitecm.dll needs to be in the same directory as SciTE.exe", 459 | "SciTE Extension", 460 | MB_OK); 461 | } 462 | 463 | m_pAlloc->Free(pszCommand); 464 | return NOERROR; 465 | } -------------------------------------------------------------------------------- /wscitecm.def: -------------------------------------------------------------------------------- 1 | ;wscitecm.def : Declares the module parameters for the DLL. 2 | 3 | LIBRARY wscitecm 4 | ;DESCRIPTION 'SciTE Shell Extension' 5 | 6 | EXPORTS 7 | DllCanUnloadNow PRIVATE 8 | DllGetClassObject PRIVATE 9 | DllRegisterServer PRIVATE 10 | DllUnregisterServer PRIVATE 11 | -------------------------------------------------------------------------------- /wscitecm.h: -------------------------------------------------------------------------------- 1 | //--------------------------------------------------------------------------- 2 | // See LICENSE 3 | //--------------------------------------------------------------------------- 4 | 5 | //--------------------------------------------------------------------------- 6 | // wscitecm.h 7 | //--------------------------------------------------------------------------- 8 | 9 | // Old GUID 10 | // {120b94b5-2e6a-4f13-94d0-414bcb64fa0f} 11 | //DEFINE_GUID(CLSID_ShellExtension, 0x120b94b5, 0x2e6a, 0x4f13, 0x94, 0xd0, 0x41, 0x4b, 0xcb, 0x64, 0xfa, 0x0f); 12 | 13 | // New GUID since version 1.3.1 14 | // Created to avoid conflict with Notpad++ reusing this code with the GUID above 15 | // {C4ACBD3E-6114-4618-904C-B206ABA9DEB0} 16 | DEFINE_GUID(CLSID_ShellExtension, 17 | 0xc4acbd3e, 0x6114, 0x4618, 0x90, 0x4c, 0xb2, 0x6, 0xab, 0xa9, 0xde, 0xb0); 18 | 19 | class CShellExtClassFactory : public IClassFactory { 20 | protected: 21 | ULONG m_cRef; 22 | 23 | public: 24 | CShellExtClassFactory(); 25 | ~CShellExtClassFactory(); 26 | 27 | STDMETHODIMP QueryInterface(REFIID, LPVOID FAR *); 28 | STDMETHODIMP_(ULONG) AddRef(); 29 | STDMETHODIMP_(ULONG) Release(); 30 | STDMETHODIMP CreateInstance(LPUNKNOWN, REFIID, LPVOID FAR *); 31 | STDMETHODIMP LockServer(BOOL); 32 | }; 33 | typedef CShellExtClassFactory *LPCSHELLEXTCLASSFACTORY; 34 | 35 | class CShellExt : public IContextMenu, IShellExtInit { 36 | public: 37 | protected: 38 | ULONG m_cRef; 39 | UINT m_cbFiles; 40 | STGMEDIUM m_stgMedium; 41 | LPDATAOBJECT m_pDataObj; 42 | HBITMAP m_hSciteBmp; 43 | LPMALLOC m_pAlloc; 44 | TCHAR m_szDllDir [MAX_PATH]; 45 | 46 | STDMETHODIMP InvokeSciTE(HWND hParent, 47 | LPCSTR pszWorkingDir, 48 | LPCSTR pszCmd, 49 | LPCSTR pszParam, 50 | int iShowCmd); 51 | 52 | public: 53 | CShellExt(); 54 | ~CShellExt(); 55 | 56 | STDMETHODIMP QueryInterface(REFIID, LPVOID FAR *); 57 | STDMETHODIMP_(ULONG) AddRef(); 58 | STDMETHODIMP_(ULONG) Release(); 59 | 60 | STDMETHODIMP QueryContextMenu(HMENU hMenu, 61 | UINT indexMenu, 62 | UINT idCmdFirst, 63 | UINT idCmdLast, 64 | UINT uFlags); 65 | 66 | STDMETHODIMP InvokeCommand(LPCMINVOKECOMMANDINFO lpcmi); 67 | 68 | STDMETHODIMP GetCommandString(UINT_PTR idCmd, 69 | UINT uFlags, 70 | UINT FAR *reserved, 71 | LPSTR pszName, 72 | UINT cchMax); 73 | 74 | STDMETHODIMP Initialize(LPCITEMIDLIST pIDFolder, 75 | LPDATAOBJECT pDataObj, 76 | HKEY hKeyID); 77 | }; 78 | 79 | typedef CShellExt *LPCSHELLEXT; 80 | -------------------------------------------------------------------------------- /wscitecm.manifest: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /wscitecm.rc: -------------------------------------------------------------------------------- 1 | //Microsoft Developer Studio generated resource script. 2 | #include "resource.h" 3 | 4 | #define APSTUDIO_READONLY_SYMBOLS 5 | ///////////////////////////////////////////////////////////////////////////// 6 | // 7 | // Generated from the TEXTINCLUDE 2 resource. 8 | // 9 | #include "afxres.h" 10 | 11 | ///////////////////////////////////////////////////////////////////////////// 12 | #undef APSTUDIO_READONLY_SYMBOLS 13 | 14 | ///////////////////////////////////////////////////////////////////////////// 15 | // English (U.S.) resources 16 | 17 | #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) 18 | #ifdef _WIN32 19 | LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US 20 | #pragma code_page(1252) 21 | #endif //_WIN32 22 | 23 | #ifndef _MAC 24 | ///////////////////////////////////////////////////////////////////////////// 25 | // 26 | // Version 27 | // 28 | 29 | VS_VERSION_INFO VERSIONINFO 30 | FILEVERSION 1,4,0,0 31 | PRODUCTVERSION 1,4,0,0 32 | FILEFLAGSMASK 0x3fL 33 | #ifdef _DEBUG 34 | FILEFLAGS 0x3L 35 | #else 36 | FILEFLAGS 0x2L 37 | #endif 38 | FILEOS 0x4L 39 | FILETYPE 0x2L 40 | FILESUBTYPE 0x0L 41 | BEGIN 42 | BLOCK "StringFileInfo" 43 | BEGIN 44 | BLOCK "040904b0" 45 | BEGIN 46 | VALUE "Comments", "\0" 47 | VALUE "CompanyName", "Burgaud.com\0" 48 | VALUE "FileDescription", "Context Menu Handler for SciTE\0" 49 | VALUE "FileVersion", "1.4.0\0" 50 | VALUE "InternalName", "wscitecm\0" 51 | VALUE "LegalCopyright", "Copyright (c) 2000-2008 Andre Burgaud\0" 52 | VALUE "LegalTrademarks", "\0" 53 | VALUE "OriginalFilename", "wscitecm.dll\0" 54 | VALUE "PrivateBuild", "\0" 55 | VALUE "ProductName", "wscitecm\0" 56 | VALUE "ProductVersion", "1.4.0\0" 57 | VALUE "SpecialBuild", "\0" 58 | END 59 | END 60 | BLOCK "VarFileInfo" 61 | BEGIN 62 | VALUE "Translation", 0x409, 1200 63 | END 64 | END 65 | #endif // _MAC 66 | 67 | #ifdef APSTUDIO_INVOKED 68 | ///////////////////////////////////////////////////////////////////////////// 69 | // 70 | // TEXTINCLUDE 71 | // 72 | 73 | 1 TEXTINCLUDE DISCARDABLE 74 | BEGIN 75 | "resource.h\0" 76 | END 77 | 78 | 2 TEXTINCLUDE DISCARDABLE 79 | BEGIN 80 | "#include ""afxres.h""\r\n" 81 | "\0" 82 | END 83 | 84 | 3 TEXTINCLUDE DISCARDABLE 85 | BEGIN 86 | "\r\n" 87 | "\0" 88 | END 89 | #endif // APSTUDIO_INVOKED 90 | 91 | ///////////////////////////////////////////////////////////////////////////// 92 | // 93 | // Bitmap 94 | // 95 | 96 | IDB_SCITE BITMAP DISCARDABLE "scite.bmp" 97 | #endif // English (U.S.) resources 98 | ///////////////////////////////////////////////////////////////////////////// 99 | 100 | #ifndef APSTUDIO_INVOKED 101 | ///////////////////////////////////////////////////////////////////////////// 102 | // 103 | // Generated from the TEXTINCLUDE 3 resource. 104 | // 105 | 106 | ///////////////////////////////////////////////////////////////////////////// 107 | #endif // not APSTUDIO_INVOKED 108 | --------------------------------------------------------------------------------