diff --git a/ColumnMode/ColumnMode.rc b/ColumnMode/ColumnMode.rc index 1e1674e..cd66676 100644 --- a/ColumnMode/ColumnMode.rc +++ b/ColumnMode/ColumnMode.rc @@ -1,266 +1,268 @@ -// Microsoft Visual C++ generated resource script. -// -#include "resource.h" - -#define APSTUDIO_READONLY_SYMBOLS -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 2 resource. -// -#ifndef APSTUDIO_INVOKED -#include "targetver.h" -#endif -#define APSTUDIO_HIDDEN_SYMBOLS -#include "windows.h" -#undef APSTUDIO_HIDDEN_SYMBOLS - -///////////////////////////////////////////////////////////////////////////// -#undef APSTUDIO_READONLY_SYMBOLS - -///////////////////////////////////////////////////////////////////////////// -// English (United States) resources - -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) -LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US -#pragma code_page(1252) - -///////////////////////////////////////////////////////////////////////////// -// -// Icon -// - -// Icon with lowest ID value placed first to ensure application icon -// remains consistent on all systems. -IDI_COLUMNMODE ICON "ColumnMode.ico" - -IDI_SMALL ICON "small.ico" - - -///////////////////////////////////////////////////////////////////////////// -// -// Menu -// - -IDC_COLUMNMODE MENU -BEGIN - POPUP "&File" - BEGIN - MENUITEM "New\tCtrl+N", ID_FILE_NEW - MENUITEM "Open\tCtrl+O", ID_FILE_OPEN - MENUITEM "Save\tCtrl+S", ID_FILE_SAVE - MENUITEM "Save As\tCtrl+Shift+S", ID_FILE_SAVEAS - MENUITEM "Refresh\tF5", ID_FILE_REFRESH - MENUITEM "Properties...", ID_FILE_PROPERTIES - MENUITEM SEPARATOR - MENUITEM "Print...\tCtrl+P", ID_FILE_PRINT - MENUITEM SEPARATOR - MENUITEM "E&xit", IDM_EXIT - END - POPUP "Edit" - BEGIN - MENUITEM "Undo\tCtrl+Z", ID_EDIT_UNDO, INACTIVE - MENUITEM SEPARATOR - MENUITEM "Cut\tCtrl+X", ID_EDIT_CUT - MENUITEM "Copy\tCtrl+C", ID_EDIT_COPY - MENUITEM "Paste\tCtrl+V", ID_EDIT_PASTE - MENUITEM "Delete\tDel", ID_EDIT_DELETE - MENUITEM "Find\tCtrl+F", ID_EDIT_FIND - END - POPUP "Options" - BEGIN - MENUITEM "Diagram Mode", ID_OPTIONS_DIAGRAMMODE, CHECKED - MENUITEM "Text Mode", ID_OPTIONS_TEXTMODE - POPUP "Themes" - BEGIN - MENUITEM "Create New Theme", ID_THEMES_CREATENEWTHEME - MENUITEM "Rescan", ID_THEMES_RESCAN - MENUITEM SEPARATOR - END - END - POPUP "Plugins" - BEGIN - MENUITEM "Rescan", ID_PLUGINS_RESCAN - MENUITEM SEPARATOR - END - POPUP "&Help" - BEGIN - MENUITEM "&About ...", IDM_ABOUT - END -END - - -///////////////////////////////////////////////////////////////////////////// -// -// Accelerator -// - -IDC_COLUMNMODE ACCELERATORS -BEGIN - "C", ID_EDIT_COPY, VIRTKEY, CONTROL, NOINVERT - "X", ID_EDIT_CUT, VIRTKEY, CONTROL, NOINVERT - VK_DELETE, ID_EDIT_DELETE, VIRTKEY, CONTROL, NOINVERT - "F", ID_EDIT_FIND, VIRTKEY, CONTROL, NOINVERT - "V", ID_EDIT_PASTE, VIRTKEY, CONTROL, NOINVERT - "Z", ID_EDIT_UNDO, VIRTKEY, CONTROL, NOINVERT - "N", ID_FILE_NEW, VIRTKEY, CONTROL, NOINVERT - "O", ID_FILE_OPEN, VIRTKEY, CONTROL, NOINVERT - "P", ID_FILE_PRINT, VIRTKEY, CONTROL, NOINVERT - VK_F5, ID_FILE_REFRESH, VIRTKEY, NOINVERT - "S", ID_FILE_SAVE, VIRTKEY, CONTROL, NOINVERT - "S", ID_FILE_SAVEAS, VIRTKEY, SHIFT, CONTROL, NOINVERT - "/", IDM_ABOUT, ASCII, ALT, NOINVERT -END - - -///////////////////////////////////////////////////////////////////////////// -// -// Dialog -// - -IDD_ABOUTBOX DIALOGEX 0, 0, 170, 62 -STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "About ColumnMode" -FONT 8, "MS Shell Dlg", 0, 0, 0x1 -BEGIN - ICON IDR_MAINFRAME,IDC_STATIC,14,14,21,20 - LTEXT "ColumnMode, Version 1.0",IDC_STATIC,42,14,114,8,SS_NOPREFIX - LTEXT "Copyright (C) 2019",IDC_STATIC,42,26,114,8 - DEFPUSHBUTTON "OK",IDOK,113,41,50,14,WS_GROUP -END - -IDD_DOCUMENTPROPERTIES DIALOGEX 0, 0, 179, 78 -STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Document Properties" -FONT 8, "MS Shell Dlg", 400, 0, 0x1 -BEGIN - DEFPUSHBUTTON "OK",IDOK,64,56,50,14 - PUSHBUTTON "Cancel",IDCANCEL,122,56,50,14 - LTEXT "Line Count:",IDC_STATIC,7,9,38,8 - EDITTEXT IDC_LINECOUNT_EDITBOX,66,7,55,14,ES_AUTOHSCROLL - LTEXT "Column Count:",IDC_STATIC,7,30,48,8 - EDITTEXT IDC_COLUMNCOUNT_EDITBOX,66,27,55,14,ES_AUTOHSCROLL -END - -IDD_FIND_DIALOG DIALOGEX 0, 0, 179, 53 -STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Find" -FONT 8, "MS Shell Dlg", 400, 0, 0x1 -BEGIN - PUSHBUTTON "Next",ID_NEXT,64,28,50,14 - PUSHBUTTON "Previous",ID_PREVIOUS,122,28,50,14 - LTEXT "Search Text:",-1,7,9,45,8 - EDITTEXT IDC_FIND_EDITBOX,66,7,106,14,ES_AUTOHSCROLL -END - -IDD_THEMENAMEQUERY DIALOGEX 0, 0, 179, 53 -STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Create New Theme" -FONT 8, "MS Shell Dlg", 400, 0, 0x1 -BEGIN - PUSHBUTTON "OK",IDOK,64,28,50,14 - PUSHBUTTON "CANCEL",IDCANCEL,122,28,50,14 - LTEXT "Theme Name:",-1,7,9,45,8 - EDITTEXT IDC_THEMENAME_EDITBOX,66,7,106,14,ES_AUTOHSCROLL -END - - -///////////////////////////////////////////////////////////////////////////// -// -// DESIGNINFO -// - -#ifdef APSTUDIO_INVOKED -GUIDELINES DESIGNINFO -BEGIN - IDD_ABOUTBOX, DIALOG - BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 163 - TOPMARGIN, 7 - BOTTOMMARGIN, 55 - END - - IDD_DOCUMENTPROPERTIES, DIALOG - BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 172 - TOPMARGIN, 7 - BOTTOMMARGIN, 71 - END - - IDD_FIND_DIALOG, DIALOG - BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 172 - TOPMARGIN, 7 - BOTTOMMARGIN, 46 - END - - IDD_THEMENAMEQUERY, DIALOG - BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 172 - TOPMARGIN, 7 - BOTTOMMARGIN, 46 - END -END -#endif // APSTUDIO_INVOKED - - -#ifdef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// TEXTINCLUDE -// - -1 TEXTINCLUDE -BEGIN - "resource.h\0" -END - -2 TEXTINCLUDE -BEGIN - "#ifndef APSTUDIO_INVOKED\r\n" - "#include ""targetver.h""\r\n" - "#endif\r\n" - "#define APSTUDIO_HIDDEN_SYMBOLS\r\n" - "#include ""windows.h""\r\n" - "#undef APSTUDIO_HIDDEN_SYMBOLS\r\n" - "\0" -END - -3 TEXTINCLUDE -BEGIN - "\r\n" - "\0" -END - -#endif // APSTUDIO_INVOKED - - -///////////////////////////////////////////////////////////////////////////// -// -// String Table -// - -STRINGTABLE -BEGIN - IDS_APP_TITLE "ColumnMode" - IDC_COLUMNMODE "COLUMNMODE" -END - -#endif // English (United States) resources -///////////////////////////////////////////////////////////////////////////// - - - -#ifndef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 3 resource. -// - - -///////////////////////////////////////////////////////////////////////////// -#endif // not APSTUDIO_INVOKED - +// Microsoft Visual C++ generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#ifndef APSTUDIO_INVOKED +#include "targetver.h" +#endif +#define APSTUDIO_HIDDEN_SYMBOLS +#include "windows.h" +#undef APSTUDIO_HIDDEN_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// English (United States) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#pragma code_page(1252) + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +IDI_COLUMNMODE ICON "ColumnMode.ico" + +IDI_SMALL ICON "small.ico" + + +///////////////////////////////////////////////////////////////////////////// +// +// Menu +// + +IDC_COLUMNMODE MENU +BEGIN + POPUP "&File" + BEGIN + MENUITEM "New\tCtrl+N", ID_FILE_NEW + MENUITEM "Open\tCtrl+O", ID_FILE_OPEN + MENUITEM "Save\tCtrl+S", ID_FILE_SAVE + MENUITEM "Save As\tCtrl+Shift+S", ID_FILE_SAVEAS + MENUITEM "Refresh\tF5", ID_FILE_REFRESH + MENUITEM "Properties...", ID_FILE_PROPERTIES + MENUITEM SEPARATOR + MENUITEM "Print...\tCtrl+P", ID_FILE_PRINT + MENUITEM SEPARATOR + MENUITEM "E&xit", IDM_EXIT + END + POPUP "Edit" + BEGIN + MENUITEM "Undo\tCtrl+Z", ID_EDIT_UNDO, INACTIVE + MENUITEM SEPARATOR + MENUITEM "Cut\tCtrl+X", ID_EDIT_CUT + MENUITEM "Copy\tCtrl+C", ID_EDIT_COPY + MENUITEM "Paste\tCtrl+V", ID_EDIT_PASTE + MENUITEM "Delete\tDel", ID_EDIT_DELETE + MENUITEM "Find\tCtrl+F", ID_EDIT_FIND + END + POPUP "Options" + BEGIN + MENUITEM "Diagram Mode", ID_OPTIONS_DIAGRAMMODE, CHECKED + MENUITEM "Text Mode", ID_OPTIONS_TEXTMODE + MENUITEM SEPARATOR + POPUP "Themes" + BEGIN + MENUITEM "Create New Theme", ID_THEMES_CREATENEWTHEME + MENUITEM "Edit a Theme", ID_THEMES_EDIT + MENUITEM "Rescan", ID_THEMES_RESCAN + MENUITEM SEPARATOR + END + END + POPUP "Plugins" + BEGIN + MENUITEM "Rescan", ID_PLUGINS_RESCAN + MENUITEM SEPARATOR + END + POPUP "&Help" + BEGIN + MENUITEM "&About ...", IDM_ABOUT + END +END + + +///////////////////////////////////////////////////////////////////////////// +// +// Accelerator +// + +IDC_COLUMNMODE ACCELERATORS +BEGIN + "C", ID_EDIT_COPY, VIRTKEY, CONTROL, NOINVERT + "X", ID_EDIT_CUT, VIRTKEY, CONTROL, NOINVERT + VK_DELETE, ID_EDIT_DELETE, VIRTKEY, CONTROL, NOINVERT + "F", ID_EDIT_FIND, VIRTKEY, CONTROL, NOINVERT + "V", ID_EDIT_PASTE, VIRTKEY, CONTROL, NOINVERT + "Z", ID_EDIT_UNDO, VIRTKEY, CONTROL, NOINVERT + "N", ID_FILE_NEW, VIRTKEY, CONTROL, NOINVERT + "O", ID_FILE_OPEN, VIRTKEY, CONTROL, NOINVERT + "P", ID_FILE_PRINT, VIRTKEY, CONTROL, NOINVERT + VK_F5, ID_FILE_REFRESH, VIRTKEY, NOINVERT + "S", ID_FILE_SAVE, VIRTKEY, CONTROL, NOINVERT + "S", ID_FILE_SAVEAS, VIRTKEY, SHIFT, CONTROL, NOINVERT + "/", IDM_ABOUT, ASCII, ALT, NOINVERT +END + + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_ABOUTBOX DIALOGEX 0, 0, 170, 62 +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "About ColumnMode" +FONT 8, "MS Shell Dlg", 0, 0, 0x1 +BEGIN + ICON IDR_MAINFRAME,IDC_STATIC,14,14,21,20 + LTEXT "ColumnMode, Version 1.0",IDC_STATIC,42,14,114,8,SS_NOPREFIX + LTEXT "Copyright (C) 2019",IDC_STATIC,42,26,114,8 + DEFPUSHBUTTON "OK",IDOK,113,41,50,14,WS_GROUP +END + +IDD_DOCUMENTPROPERTIES DIALOGEX 0, 0, 179, 78 +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Document Properties" +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + DEFPUSHBUTTON "OK",IDOK,64,56,50,14 + PUSHBUTTON "Cancel",IDCANCEL,122,56,50,14 + LTEXT "Line Count:",IDC_STATIC,7,9,38,8 + EDITTEXT IDC_LINECOUNT_EDITBOX,66,7,55,14,ES_AUTOHSCROLL + LTEXT "Column Count:",IDC_STATIC,7,30,48,8 + EDITTEXT IDC_COLUMNCOUNT_EDITBOX,66,27,55,14,ES_AUTOHSCROLL +END + +IDD_FIND_DIALOG DIALOGEX 0, 0, 179, 53 +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Find" +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + PUSHBUTTON "Next",ID_NEXT,64,28,50,14 + PUSHBUTTON "Previous",ID_PREVIOUS,122,28,50,14 + LTEXT "Search Text:",-1,7,9,45,8 + EDITTEXT IDC_FIND_EDITBOX,66,7,106,14,ES_AUTOHSCROLL +END + +IDD_THEMENAMEQUERY DIALOGEX 0, 0, 179, 53 +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Create New Theme" +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + PUSHBUTTON "OK",IDOK,64,28,50,14 + PUSHBUTTON "CANCEL",IDCANCEL,122,28,50,14 + LTEXT "Theme Name:",-1,7,9,45,8 + EDITTEXT IDC_THEMENAME_EDITBOX,66,7,106,14,ES_AUTOHSCROLL +END + + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO +BEGIN + IDD_ABOUTBOX, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 163 + TOPMARGIN, 7 + BOTTOMMARGIN, 55 + END + + IDD_DOCUMENTPROPERTIES, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 172 + TOPMARGIN, 7 + BOTTOMMARGIN, 71 + END + + IDD_FIND_DIALOG, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 172 + TOPMARGIN, 7 + BOTTOMMARGIN, 46 + END + + IDD_THEMENAMEQUERY, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 172 + TOPMARGIN, 7 + BOTTOMMARGIN, 46 + END +END +#endif // APSTUDIO_INVOKED + + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE +BEGIN + "#ifndef APSTUDIO_INVOKED\r\n" + "#include ""targetver.h""\r\n" + "#endif\r\n" + "#define APSTUDIO_HIDDEN_SYMBOLS\r\n" + "#include ""windows.h""\r\n" + "#undef APSTUDIO_HIDDEN_SYMBOLS\r\n" + "\0" +END + +3 TEXTINCLUDE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// String Table +// + +STRINGTABLE +BEGIN + IDS_APP_TITLE "ColumnMode" + IDC_COLUMNMODE "COLUMNMODE" +END + +#endif // English (United States) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/ColumnMode/ColumnMode.vcxproj b/ColumnMode/ColumnMode.vcxproj index 4f3131e..cb15e28 100644 --- a/ColumnMode/ColumnMode.vcxproj +++ b/ColumnMode/ColumnMode.vcxproj @@ -23,33 +23,33 @@ {6546B3A0-08BA-43DD-A450-B2DE1262820A} Win32Proj ColumnMode - 10.0.17134.0 + 10.0 ColumnMode Application true - v141 + v143 Unicode Application false - v141 + v143 true Unicode Application true - v141 + v143 Unicode Application false - v141 + v143 true Unicode @@ -143,6 +143,7 @@ true NDEBUG;_WINDOWS;%(PreprocessorDefinitions) true + stdcpp17 Windows diff --git a/ColumnMode/ColumnModePluginApi.h b/ColumnMode/ColumnModePluginApi.h index fa0c838..635eb26 100644 --- a/ColumnMode/ColumnModePluginApi.h +++ b/ColumnMode/ColumnModePluginApi.h @@ -4,7 +4,7 @@ namespace ColumnMode { - constexpr UINT c_ColumnModePluginApiVersion = 1; + constexpr UINT c_ColumnModePluginApiVersion = 2; #pragma region ColumnModeCallbacks @@ -32,6 +32,7 @@ namespace ColumnMode typedef HRESULT(APIENTRY* PFN_PF_ONOPEN)(HANDLE, LPCWSTR); typedef HRESULT(APIENTRY* PFN_PF_ONSAVE)(HANDLE, LPCWSTR); typedef HRESULT(APIENTRY* PFN_PF_ONSAVEAS)(HANDLE, LPCWSTR); + typedef HRESULT(APIENTRY* PFN_PF_ONTYPINGCOMPLETE)(HANDLE, const size_t numChars, const WCHAR* pAllText); //Plugin Life cycle typedef HRESULT(APIENTRY* PFN_PF_ONLOADCOMPLETED)(HANDLE); //Called after OpenColumnModePlugin @@ -45,10 +46,19 @@ namespace ColumnMode PFN_PF_ONLOADCOMPLETED pfnOnLoadCompleted; PFN_PF_ONSHUTDOWN pfnOnShutdown; + + // API version >= 2 + PFN_PF_ONTYPINGCOMPLETE pfnOnTypingComplete; }; #pragma endregion + struct PluginDependency + { + UINT length; // number of WCHARs in pName + WCHAR* pName; + }; + struct OpenPluginArgs { _In_ UINT apiVersion; @@ -58,6 +68,20 @@ namespace ColumnMode }; } +/* +Safe to not export if your plugin doesn't have run-time dll dependencies. +Called in the following pattern: +1. pCount is a valid pointer to any UINT and pDependencies is nullptr. - Plugin should set pCount to the number of dependencies. +2. pCount is a valid pointer, pDependencies is a valid pointer, each dependency's pName is nullptr. - Plugin should validate pCount is the right size, then populate the length fields of each dependency struct. +3. pCount is a valid pointer, pDependencies is a valid pointer, each dependency's pName is a valid pointer - Plugin should validate pCount, then foreach dependency: validate the length and then write the dependency name to the buffer (including extension). + +Return value from each step should be S_OK if everything is valid and fields are being written as expected. If pCount or a length value is wrong, return E_INVALIDARG. Else, return E_FAIL. + +Note that depenency dlls should be in the same directory as your plugin: %APPDATA%/ColumnMode/Plugins/your_plugin_name/ +*/ +extern "C" HRESULT WINAPI QueryColumnModePluginDependencies(_Inout_ UINT* pCount, _Inout_opt_count_(*pCount) ColumnMode::PluginDependency* pDependencies); +typedef HRESULT(WINAPI* PFN_QUERYCOLUMNMODEPLUGINDEPENDENCIES)(_Inout_ UINT* pCount, _Inout_opt_count_(*pCount) ColumnMode::PluginDependency* pDependencies); +// Required export extern "C" HRESULT WINAPI OpenColumnModePlugin(_Inout_ ColumnMode::OpenPluginArgs* args); typedef HRESULT(WINAPI* PFN_OPENCOLUMNMODEPLUGIN)(_Inout_ ColumnMode::OpenPluginArgs* args); \ No newline at end of file diff --git a/ColumnMode/Main.cpp b/ColumnMode/Main.cpp index f1db5c4..f4be5a1 100644 --- a/ColumnMode/Main.cpp +++ b/ColumnMode/Main.cpp @@ -114,7 +114,7 @@ void MyRegisterClass(HINSTANCE hInstance) } { // Document window - WNDCLASSEXW wcex; + WNDCLASSEXW wcex {}; wcex.cbSize = sizeof(WNDCLASSEX); @@ -316,6 +316,9 @@ LRESULT CALLBACK TopLevelWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM case ID_THEMES_CREATENEWTHEME: OnCreateTheme(hWnd, hInst); break; + case ID_THEMES_EDIT: + OnEditTheme(hWnd, hInst); + break; case ID_FILE_REFRESH: OnRefresh(g_windowHandles); break; diff --git a/ColumnMode/PluginManager.cpp b/ColumnMode/PluginManager.cpp index 61daaff..0c39e12 100644 --- a/ColumnMode/PluginManager.cpp +++ b/ColumnMode/PluginManager.cpp @@ -59,25 +59,124 @@ HRESULT ColumnMode::PluginManager::ScanForPlugins() return S_OK; } +HRESULT LoadLibraryHelper(std::filesystem::path path, HMODULE& out_pluginModule) +{ + DWORD flags = LOAD_LIBRARY_SEARCH_DEFAULT_DIRS | LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR; + out_pluginModule = LoadLibraryEx(path.c_str(), NULL, flags); + if (out_pluginModule == NULL) + { + DWORD err = GetLastError(); + WCHAR buff[1024]; + std::swprintf(buff, 1024, _T("Plugin not found or DLL failed to load.\nError code: %d\nPath: %s"), err, path.c_str()); + MessageBox(NULL, buff, L"Error loading plugin DLL", MB_OK | MB_ICONERROR); + + return E_INVALIDARG; + } + return S_OK; +} + +HRESULT LoadPluginDependenciesHelper(PFN_QUERYCOLUMNMODEPLUGINDEPENDENCIES pfnQueryDeps, std::filesystem::path pluginDir, HMODULE pluginModule) +{ + UINT numDeps = 0; + std::wstring pluginName = pluginDir.filename(); //plugin name is the last part of the pluginDir + + //query num dependencies and create dependency list + HRESULT hr = pfnQueryDeps(&numDeps, nullptr); + if(FAILED(hr)) + { + MessageBoxHelper_FormattedBody(MB_ICONERROR | MB_OK, L"Failed to get dependencies", L"%s returned failure code %d when calling QueryColumnModePluginDependencies (1st call).", pluginName, hr); + return hr; + } + ColumnMode::PluginDependency defaultInit{ 0, nullptr }; + std::vector deps = std::vector(numDeps, defaultInit); + + // query sizes of dependency names and allocate space + hr = pfnQueryDeps(&numDeps, deps.data()); + if (FAILED(hr)) + { + MessageBoxHelper_FormattedBody(MB_ICONERROR | MB_OK, L"Failed to get dependencies", L"%s returned failure code %d when calling QueryColumnModePluginDependencies (2nd call).", pluginName, hr); + return hr; + } + for (auto depIt = deps.begin(); depIt != deps.end(); depIt++) + { + depIt->pName = (WCHAR*)malloc((depIt->length +1) * sizeof(WCHAR)); //add one extra char of padding so that we can ensure null-terminated + if (depIt->pName == nullptr) + { + hr = E_OUTOFMEMORY; + goto cleanup_and_exit; + } + } + + // query dependency names + hr = pfnQueryDeps(&numDeps, deps.data()); + if (FAILED(hr)) + { + MessageBoxHelper_FormattedBody(MB_ICONERROR | MB_OK, L"Failed to get dependencies", L"%s returned failure code %d when calling QueryColumnModePluginDependencies (3rd call).", pluginName, hr); + goto cleanup_and_exit; + } + + //Now we need to free the plugin library in case it has a load time library that does weird checks for runtime dependencies in dllmain (looking at you dxcompiler.dll) + FreeLibrary(pluginModule); + //Finally load the requested libraries + for (auto depIt = deps.begin(); depIt != deps.end(); depIt++) + { + depIt->pName[depIt->length] = L'\0'; //ensure null-terminated + std::filesystem::path depFullPath = pluginDir / depIt->pName; + HMODULE hm; + if (FAILED(LoadLibraryHelper(depFullPath, hm))) + { + hr = E_FAIL; + goto cleanup_and_exit; + //maybe unload dlls? + } + } + + cleanup_and_exit: + // free allocated strings + for (auto depIt = deps.begin(); depIt != deps.end(); depIt++) + { + if (depIt->pName != nullptr) + { + free(depIt->pName); + depIt->pName = nullptr; + } + } + return hr; +} + HRESULT ColumnMode::PluginManager::LoadPlugin(LPCWSTR pluginName) { std::filesystem::path path(m_modulesRootPath); - path.append(pluginName) //Plugins should be in a folder of the plugin name - .append(pluginName) //Plugin is a DLL file of the plugin name + path.append(pluginName) //Plugins should be in a folder of the plugin name + .append(pluginName) //Plugin is a DLL file of the plugin name .replace_extension(L".dll"); - HMODULE pluginModule = LoadLibrary(path.c_str()); - if (pluginModule == NULL) + + + HMODULE pluginModule; + BAIL_ON_FAIL_HR(LoadLibraryHelper(path, pluginModule)); + + PFN_QUERYCOLUMNMODEPLUGINDEPENDENCIES pfnQueryDeps = + reinterpret_cast(GetProcAddress(pluginModule, "QueryColumnModePluginDependencies")); + + if (pfnQueryDeps != nullptr) { - MessageBox(NULL, path.c_str(), L"Plugin Not Found", MB_OK | MB_ICONERROR); - return E_INVALIDARG; + BAIL_ON_FAIL_HR(LoadPluginDependenciesHelper(pfnQueryDeps, m_modulesRootPath / pluginName, pluginModule)); } + BAIL_ON_FAIL_HR(LoadLibraryHelper(path, pluginModule)); PFN_OPENCOLUMNMODEPLUGIN pfnOpenPlugin = reinterpret_cast(GetProcAddress(pluginModule, "OpenColumnModePlugin")); - PluginFunctions pluginFuncs = { 0 }; - OpenPluginArgs args; + if (pfnOpenPlugin == nullptr) + { + MessageBoxHelper_FormattedBody(MB_ICONERROR | MB_OK, L"Failed to open plugin", L"%s doesn't export the OpenColumnModePlugin function.", pluginName); + return E_FAIL; + } + + PluginFunctions pluginFuncs{}; + ZeroMemory(&pluginFuncs, sizeof(pluginFuncs)); + OpenPluginArgs args{}; args.apiVersion = c_ColumnModePluginApiVersion; args.hPlugin = NULL; args.pPluginFuncs = &pluginFuncs; diff --git a/ColumnMode/PluginManagerFunctions.inl b/ColumnMode/PluginManagerFunctions.inl index e593507..e86bf2c 100644 --- a/ColumnMode/PluginManagerFunctions.inl +++ b/ColumnMode/PluginManagerFunctions.inl @@ -21,6 +21,7 @@ DECLARE_PLUGINMANAGER_FUNCTION_CALL_ALL(OnOpen, (LPCWSTR)) DECLARE_PLUGINMANAGER_FUNCTION_CALL_ALL(OnSave, (LPCWSTR)) DECLARE_PLUGINMANAGER_FUNCTION_CALL_ALL(OnSaveAs, (LPCWSTR)) +DECLARE_PLUGINMANAGER_FUNCTION_CALL_ALL(OnTypingComplete, (const size_t, const WCHAR*)) #undef DECLARE_PLUGINMANAGER_FUNCTION_CALL_ALL @@ -39,6 +40,7 @@ DECLARE_PLUGINMANAGER_FUNCTION_CALL_ALL(OnSaveAs, (LPCWSTR)) DEFINE_PLUGINMANAGER_FUNCTION_CALL_ALL(OnOpen, (LPCWSTR fileName), (p.m_hPlugin, fileName)) DEFINE_PLUGINMANAGER_FUNCTION_CALL_ALL(OnSave, (LPCWSTR fileName), (p.m_hPlugin, fileName)) DEFINE_PLUGINMANAGER_FUNCTION_CALL_ALL(OnSaveAs, (LPCWSTR fileName), (p.m_hPlugin, fileName)) +DEFINE_PLUGINMANAGER_FUNCTION_CALL_ALL(OnTypingComplete, (const size_t numChars, const WCHAR* pAllText), (p.m_hPlugin, numChars, pAllText)) #undef DEFINE_PLUGINMANAGER_FUNCTION_CALL_ALL diff --git a/ColumnMode/Program.cpp b/ColumnMode/Program.cpp index ff17fa4..0c487c8 100644 --- a/ColumnMode/Program.cpp +++ b/ColumnMode/Program.cpp @@ -1,4 +1,6 @@ #include "stdafx.h" +#include + #include "Program.h" #include "Resource.h" #include "Verify.h" @@ -110,6 +112,7 @@ class Status int m_caretRow; int m_caretColumn; Mode m_mode; + std::optional m_warning; void RefreshStatusBar(HWND statusBarLabelHwnd) { @@ -118,6 +121,11 @@ class Status label << L"Row: " << (m_caretRow + 1) << " Col: " << (m_caretColumn + 1); label << L" Mode: " << (m_mode == Mode::TextMode ? L"Text" : L"Diagram"); + if (m_warning.has_value()) + { + label << L" WARNING: " << m_warning.value(); + } + Static_SetText(statusBarLabelHwnd, label.str().c_str()); } @@ -147,6 +155,21 @@ class Status return m_mode; } + void SetWarning(std::wstring str, HWND statusBarLabelHwnd) + { + m_warning = str; + RefreshStatusBar(statusBarLabelHwnd); + } + + void ClearWarning(std::wstring str, HWND statusBarLabelHwnd) + { + if (m_warning.has_value() && m_warning.value() == str) + { + m_warning.reset(); + } + RefreshStatusBar(statusBarLabelHwnd); + } + } g_status; bool g_isDragging; @@ -169,6 +192,7 @@ DWRITE_HIT_TEST_METRICS g_caretMetrics; int g_caretBlinkState; int g_updatesSinceLastEdit; +bool g_editMadeSinceLastConfirmationOfEdits = false; const int g_numUpdatesWithoutEditBeforeConfirmingEdits = 50; std::wstring g_allText; @@ -733,7 +757,7 @@ void InitGraphics(WindowHandles windowHandles) g_isTrackingLeaveClientArea = false; g_hasTextSelectionRectangle = false; g_caretBlinkState = 0; - g_updatesSinceLastEdit = 0; + g_updatesSinceLastEdit = g_numUpdatesWithoutEditBeforeConfirmingEdits+1; //init to more than the confirmation value so we don't prematurely confirm g_isShiftDown = false; g_hasUnsavedChanges = false; g_needsDeviceRecreation = false; @@ -1590,12 +1614,11 @@ void OnKeyDown(WindowHandles windowHandles, WPARAM wParam) return; g_caretBlinkState = 0; - g_updatesSinceLastEdit = 0; CheckModifierKeys(); // modifiers could be pressed when a message went to a different handler if (g_keyOutput[wParam].Valid) { DisableTextSelectionRectangle(windowHandles); - + g_updatesSinceLastEdit = 0; // only register newly typed characters for calling ConfirmEdits wchar_t chr = g_isShiftDown ? g_keyOutput[wParam].Uppercase : g_keyOutput[wParam].Lowercase; if (g_status.GetMode() == Mode::DiagramMode) @@ -1892,6 +1915,7 @@ void ConfirmEdits() { g_themeManager.LoadThemeFromText(g_allText, g_theme); } + g_pluginManager.PF_OnTypingComplete_ALL(g_allText.length(), g_allText.c_str()); } void Update() @@ -1993,6 +2017,17 @@ void OpenImpl(WindowHandles windowHandles, LPCWSTR fileName) EnableMenuItem(windowHandles, ID_FILE_REFRESH); EnableMenuItem(windowHandles, ID_FILE_SAVE); g_pluginManager.PF_OnOpen_ALL(fileName); + + std::filesystem::path path = fileName; + if (path.extension() == L".cmt") + { + if (!g_themeManager.LoadTheme(path.filename(), g_theme, false)) + { + WCHAR buff[256]; + std::swprintf(buff, 256, L"There was an error loading the theme.\nWhen you have fixed the issue, CTRL+S and then select it as the active theme from Options > Themes > %s.", path.filename().replace_extension(L"").c_str()); + MessageBox(NULL, buff, fileName, MB_OK); + } + } } void OnOpen(WindowHandles windowHandles) @@ -2031,12 +2066,6 @@ void OnOpen(WindowHandles windowHandles) if (!!GetOpenFileName(&ofn)) { OpenImpl(windowHandles, ofn.lpstrFile); - std::filesystem::path path = ofn.lpstrFile; - if (path.extension() == L".cmt") { - if (!g_themeManager.LoadTheme(path.filename(), g_theme, false)) { - MessageBox(NULL, L"There was an error loading the theme.", ofn.lpstrFile, MB_OK); - } - } } } @@ -2940,6 +2969,37 @@ void OnCreateTheme(HWND hwnd, HINSTANCE hInst) DialogBox(hInst, MAKEINTRESOURCE(IDD_THEMENAMEQUERY), hwnd, ThemeNameQueryCallback); } +void OnEditTheme(HWND hwnd, HINSTANCE hInst) +{ + std::filesystem::path currentThemePath = g_themeManager.GetThemeFilepath(g_theme); + + OPENFILENAME ofn; // common dialog box structure + wchar_t szFile[MAX_PATH]; + + ZeroMemory(&ofn, sizeof(ofn)); + ofn.lStructSize = sizeof(ofn); + ofn.hwndOwner = g_windowManager.GetWindowHandles().TopLevel; + ofn.lpstrFile = szFile; + + // Set lpstrFile[0] to '\0' so that GetOpenFileName does not + // use the contents of szFile to initialize itself. + ofn.lpstrFile[0] = L'\0'; + ofn.nMaxFile = sizeof(szFile); + ofn.lpstrFilter = L"*.cmt\0"; + ofn.nFilterIndex = 1; + ofn.lpstrFileTitle = NULL; + ofn.nMaxFileTitle = 0; + ofn.lpstrInitialDir = currentThemePath.parent_path().c_str(); + ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST; + + // Display the Open dialog box. + + if (!!GetOpenFileName(&ofn)) + { + OpenImpl(g_windowManager.GetWindowHandles(), ofn.lpstrFile); + } +} + bool OnMaybeDynamicMenuItemSelected(WindowHandles windowHandles, int id) { static_assert(ColumnMode::ThemeManager::THEME_MENU_ITEM_START_INDEX > ColumnMode::PluginManager::PLUGIN_MENU_ITEM_START_INDEX); @@ -3004,7 +3064,17 @@ bool OnMaybeThemeSelected(WindowHandles windowHandles, int id) int size = GetMenuString(themesMenu, id, buff, 64, MF_BYCOMMAND); if (size > 0 && g_theme.GetName().compare(buff) != 0) { - g_themeManager.LoadTheme(buff, g_theme); + if (!g_themeManager.LoadTheme(buff, g_theme)) + { + int dialogResult = MessageBox(NULL, L"There was an error loading the theme.\nOpen it for editing and try to fix the issue?", buff, MB_ICONERROR | MB_YESNO); + if (dialogResult == IDYES) + { + ColumnMode::Theme temp{}; + temp.SetName(buff); + std::wstring path = g_themeManager.GetThemeFilepath(temp); + OpenImpl(g_windowManager.GetWindowHandles(), path.c_str()); + } + } OnThemesRescan(windowHandles, true); // Handle the check marking-ing in probably the worst way } return true; @@ -3306,4 +3376,14 @@ std::wstring& GetAllText() ColumnMode::FindTool& GetFindTool() { return g_findTool; +} + +void SetWarningMessage(std::wstring str) +{ + g_status.SetWarning(str, g_windowManager.GetWindowHandles().StatusBarLabel); +} + +void ClearWarningMssage(std::wstring str) +{ + g_status.ClearWarning(str, g_windowManager.GetWindowHandles().StatusBarLabel); } \ No newline at end of file diff --git a/ColumnMode/Program.h b/ColumnMode/Program.h index 3c6ab50..20576ef 100644 --- a/ColumnMode/Program.h +++ b/ColumnMode/Program.h @@ -43,6 +43,7 @@ void OnPrint(WindowHandles windowHandles); void OnPluginRescan(WindowHandles windowHandles, bool skipRescan=false); void OnThemesRescan(WindowHandles windowHandles, bool skipRescan = false); void OnCreateTheme(HWND hwnd, HINSTANCE hInst); +void OnEditTheme(HWND hwnd, HINSTANCE hInst); bool OnMaybeDynamicMenuItemSelected(WindowHandles windowHandles, int id); void OnDiagramMode(WindowHandles windowHandles); void OnTextMode(WindowHandles windowHandles); @@ -83,4 +84,6 @@ enum class ScrollToStyle }; void ScrollTo(UINT index, ScrollToStyle scrollStyle = ScrollToStyle::CENTER); -ColumnMode::FindTool& GetFindTool(); \ No newline at end of file +ColumnMode::FindTool& GetFindTool(); +void SetWarningMessage(std::wstring str); +void ClearWarningMssage(std::wstring str); \ No newline at end of file diff --git a/ColumnMode/Resource.h b/ColumnMode/Resource.h index 2c18743..72c29ce 100644 Binary files a/ColumnMode/Resource.h and b/ColumnMode/Resource.h differ diff --git a/ColumnMode/Theme.cpp b/ColumnMode/Theme.cpp index 7cc1c02..d8756cd 100644 --- a/ColumnMode/Theme.cpp +++ b/ColumnMode/Theme.cpp @@ -1,5 +1,7 @@ #include "stdafx.h" #include "../External/json.hpp" + +#include "Program.h" #include "Theme.h" #include "Verify.h" #include "utf8Conversion.h" @@ -185,10 +187,18 @@ bool ColumnMode::ThemeManager::LoadThemeFromText(std::wstring jsonString, Theme& { json data = json::parse(jsonString); out = data; + themeTextInvalidOnLastLoadFromText = false; + ClearWarningMssage(L"Theme JSON invalid!"); return true; } catch (...) { + if (!themeTextInvalidOnLastLoadFromText) + { + MessageBox(NULL, L"Your latest change broke the theme.\nEnsure that your JSON is well formatted and color values are valid floats.", L"Error parsing Theme", MB_ICONERROR | MB_OK); + } + themeTextInvalidOnLastLoadFromText = true; + SetWarningMessage(L"Theme JSON invalid!"); return false; } return false; diff --git a/ColumnMode/Theme.h b/ColumnMode/Theme.h index 9ed6505..e9bc2a7 100644 --- a/ColumnMode/Theme.h +++ b/ColumnMode/Theme.h @@ -78,6 +78,7 @@ namespace ColumnMode private: std::filesystem::path m_themesRootPath; std::vector m_availableThemes; + bool themeTextInvalidOnLastLoadFromText = false; public: static const int THEME_MENU_ITEM_START_INDEX = 5000;//chosen arbitrarily. hopefully the resource generator doesn't conflict diff --git a/ColumnMode/Verify.h b/ColumnMode/Verify.h index 1c896d8..474776c 100644 --- a/ColumnMode/Verify.h +++ b/ColumnMode/Verify.h @@ -6,6 +6,8 @@ void inline VerifyHR(HRESULT hr) __debugbreak(); } +#define BAIL_ON_FAIL_HR(hrFunc) {HRESULT hr = hrFunc; if(FAILED(hr)) { return hr;}} + void inline VerifyBool(BOOL b) { if (!b) diff --git a/ColumnMode/stdafx.h b/ColumnMode/stdafx.h index 344b9ac..2f18b10 100644 Binary files a/ColumnMode/stdafx.h and b/ColumnMode/stdafx.h differ diff --git a/Images/themes_UI_annotation.png b/Images/themes_UI_annotation.png new file mode 100644 index 0000000..f496aac Binary files /dev/null and b/Images/themes_UI_annotation.png differ diff --git a/Manual/Themes.md b/Manual/Themes.md new file mode 100644 index 0000000..7f5b0a8 --- /dev/null +++ b/Manual/Themes.md @@ -0,0 +1,29 @@ +# Themes +Themes allow you to style ColumnMode's color pallet to suit your taste / usage. +You can find the Themes installed on your system at `%APPDATA%/ColumnMode/Themes` (extension is `.cmt`). +`.cmt` files are a JSON format pairing colors to theme Ids. +Opening a `.cmt` file in ColumnMode will allow you to preview your changes in realtime (though some fields are not used by the editor when viewing `.cmt` files. Eventually this may be addressed by a more full-featured theme editor). + +You can create a new Theme by going to Options > Themes > Create New Theme. +Your new theme will be based on the default theme: ColumnModeClassic. + +## Theme Ids +You can think of a theme as a pallet of colors that can be picked from by the Column Mode editor for different uses. + +### `UI_`* Theme Ids +![Annotated UI elements](../Images/themes_UI_annotation.png) + +1. `UI_BACKGROUND`: The empty region of the window that can't be edited. +1. `UI_PAPER`: The region available for editing. +1. `UI_PAPER_BORDER` +1. `UI_MARGIN` +1. `UI_CURRENT_LINE_HIGHLIGHT`: A color that should be different from `UI_PAPER` to indicate the line bing edited. +1. `UI_CARET`: The flashing indicator for the character you are about to edit. +1. `UI_DRAG_RECT`: The solid line that shows the exact selection rectangle you are dragging out. +1. `UI_SELECTION`: The shaded region of your selection. +1. `UI_SELECTION_BORDER`: The "marching ants" on the ourside of the effective selection rectangle. + +### `TEXT_`* Theme Ids +Most of these aren't used yet. +For now just edit `TEXT_DEFAULT` to set the color of the text. +Other `TEXT_`* colors will be used in the future when plugins are able to handle text colorization. \ No newline at end of file diff --git a/README.md b/README.md index ee2fd2a..7dd36ea 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,8 @@ ColumnMode is a lightweight, column-based text editor. * Supports copying and pasting * Supports undo * Supports print +* Supports extension via plugins +* Supports [Themes](Manual/Themes.md) to change the look and feel ![Example image](https://raw.githubusercontent.com/clandrew/ColumnMode/master/Images/CutPaste.gif "Example image") ![Example image](https://raw.githubusercontent.com/clandrew/ColumnMode/master/Images/Undo.gif "Example image") diff --git a/SamplePlugin/SamplePlugin.vcxproj b/SamplePlugin/SamplePlugin.vcxproj index 7c332dd..65fb020 100644 --- a/SamplePlugin/SamplePlugin.vcxproj +++ b/SamplePlugin/SamplePlugin.vcxproj @@ -1,178 +1,178 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - Debug - x64 - - - Release - x64 - - - - 16.0 - Win32Proj - {c544b2fb-d327-4011-87b4-f184470bc716} - SamplePlugin - 10.0 - - - - DynamicLibrary - true - v142 - Unicode - - - DynamicLibrary - false - v142 - true - Unicode - - - DynamicLibrary - true - v142 - Unicode - - - DynamicLibrary - false - v142 - true - Unicode - - - - - - - - - - - - - - - - - - - - - true - - - false - - - true - - - false - - - - Level3 - true - WIN32;_DEBUG;SAMPLEPLUGIN_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - true - Use - pch.h - - - Windows - true - false - SamplePlugin.def - - - - - Level3 - true - true - true - WIN32;NDEBUG;SAMPLEPLUGIN_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - true - Use - pch.h - - - Windows - true - true - true - false - SamplePlugin.def - - - - - Level3 - true - _DEBUG;SAMPLEPLUGIN_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - true - Use - pch.h - - - Windows - true - false - SamplePlugin.def - - - - - Level3 - true - true - true - NDEBUG;SAMPLEPLUGIN_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - true - Use - pch.h - - - Windows - true - true - true - false - SamplePlugin.def - - - - - - - - - - - - Create - Create - Create - Create - - - - - - - - + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 16.0 + Win32Proj + {c544b2fb-d327-4011-87b4-f184470bc716} + SamplePlugin + 10.0 + + + + DynamicLibrary + true + v143 + Unicode + + + DynamicLibrary + false + v143 + true + Unicode + + + DynamicLibrary + true + v143 + Unicode + + + DynamicLibrary + false + v143 + true + Unicode + + + + + + + + + + + + + + + + + + + + + true + + + false + + + true + + + false + + + + Level3 + true + WIN32;_DEBUG;SAMPLEPLUGIN_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + true + Use + pch.h + + + Windows + true + false + SamplePlugin.def + + + + + Level3 + true + true + true + WIN32;NDEBUG;SAMPLEPLUGIN_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + true + Use + pch.h + + + Windows + true + true + true + false + SamplePlugin.def + + + + + Level3 + true + _DEBUG;SAMPLEPLUGIN_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + true + Use + pch.h + + + Windows + true + false + SamplePlugin.def + + + + + Level3 + true + true + true + NDEBUG;SAMPLEPLUGIN_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + true + Use + pch.h + + + Windows + true + true + true + false + SamplePlugin.def + + + + + + + + + + + + Create + Create + Create + Create + + + + + + + + \ No newline at end of file