Subversion Repositories filter_foundry

Rev

Rev 469 | Rev 471 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

  1. /*
  2.         This file is part of "Filter Foundry", a filter plugin for Adobe Photoshop
  3.         Copyright (C) 2003-2009 Toby Thain, toby@telegraphics.com.au
  4.         Copyright (C) 2018-2021 Daniel Marschall, ViaThinkSoft
  5.  
  6.         This program is free software; you can redistribute it and/or modify
  7.         it under the terms of the GNU General Public License as published by
  8.         the Free Software Foundation; either version 2 of the License, or
  9.         (at your option) any later version.
  10.  
  11.         This program is distributed in the hope that it will be useful,
  12.         but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.         MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.         GNU General Public License for more details.
  15.  
  16.         You should have received a copy of the GNU General Public License
  17.         along with this program; if not, write to the Free Software
  18.         Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  19. */
  20.  
  21. #include "ff.h"
  22. #include "slider_win.h"
  23.  
  24. // More information about the PLUGIN.DLL sliders:
  25. // https://misc.daniel-marschall.de/projects/filter_factory/sliders.html
  26.  
  27. // PLUGIN.DLL Sliders: This method will register the "slider" class used in dialogs.
  28. typedef BOOL(__cdecl* f_RegisterSlider)(HINSTANCE hInstanceDll, DWORD* MessageID);
  29. BOOL RegisterSlider(HINSTANCE hInstanceDll, DWORD* MessageID) {
  30.         f_RegisterSlider fRegisterSlider;
  31.         HMODULE hPlugin;
  32.         BOOL res;
  33.  
  34.         hPlugin = LoadLibrary(TEXT("PLUGIN.DLL"));
  35.         if (!hPlugin) return false;
  36.         fRegisterSlider = (f_RegisterSlider)(void*)GetProcAddress(hPlugin, "RegisterSlider");
  37.         res = (fRegisterSlider != 0) ? fRegisterSlider(hInstanceDll, MessageID) : false;
  38.         FreeLibrary(hPlugin);
  39.         return res;
  40. }
  41.  
  42. // PLUGIN.DLL Sliders: This method will unregister the "slider" class used in dialogs.
  43. typedef BOOL(__cdecl* f_UnregisterSlider)(HINSTANCE hInstanceDll);
  44. BOOL UnregisterSlider(HINSTANCE hInstanceDll) {
  45.         f_UnregisterSlider fUnregisterSlider;
  46.         HMODULE hPlugin;
  47.         BOOL res;
  48.  
  49.         hPlugin = LoadLibrary(TEXT("PLUGIN.DLL"));
  50.         if (!hPlugin) return false;
  51.         fUnregisterSlider = (f_UnregisterSlider)(void*)GetProcAddress(hPlugin, "UnRegisterSlider");
  52.         res = (fUnregisterSlider != 0) ? fUnregisterSlider(hInstanceDll) : false;
  53.         FreeLibrary(hPlugin);
  54.         return res;
  55. }
  56.  
  57. // PLUGIN.DLL Sliders: Set slider range (min/max)
  58. typedef int(__cdecl* f_SetSliderRange)(HWND hWnd, int nMin, int nMax);
  59. int SetSliderRange(HWND hWnd, int nMin, int nMax) {
  60.         f_SetSliderRange fSetSliderRange;
  61.         HMODULE hPlugin;
  62.         int res;
  63.  
  64.         hPlugin = LoadLibrary(TEXT("PLUGIN.DLL"));
  65.         if (!hPlugin) return 0;
  66.         fSetSliderRange = (f_SetSliderRange)(void*)GetProcAddress(hPlugin, "SetSliderRange");
  67.         res = (fSetSliderRange != 0) ? fSetSliderRange(hWnd, nMin, nMax) : 0;
  68.         FreeLibrary(hPlugin);
  69.         return res;
  70. }
  71.  
  72. // PLUGIN.DLL Sliders : Sets slider position
  73. typedef int(__cdecl* f_SetSliderPos)(HWND hWnd, int nPos, BOOL bRepaint);
  74. int SetSliderPos(HWND hWnd, int nPos, BOOL bRepaint) {
  75.         f_SetSliderPos fSetSliderPos;
  76.         HMODULE hPlugin;
  77.         int res;
  78.  
  79.         hPlugin = LoadLibrary(TEXT("PLUGIN.DLL"));
  80.         if (!hPlugin) return 0;
  81.         fSetSliderPos = (f_SetSliderPos)(void*)GetProcAddress(hPlugin, "SetSliderPos");
  82.         res = (fSetSliderPos != 0) ? fSetSliderPos(hWnd, nPos, bRepaint) : 0;
  83.         FreeLibrary(hPlugin);
  84.         return res;
  85. }
  86.  
  87. // PLUGIN.DLL Sliders : Get slider position
  88. typedef int(__cdecl* f_GetSliderPos)(HWND hWnd, BOOL bPixelPosition);
  89. int GetSliderPos(HWND hWnd, BOOL bPixelPosition) {
  90.         f_GetSliderPos fGetSliderPos;
  91.         HMODULE hPlugin;
  92.         int res;
  93.  
  94.         hPlugin = LoadLibrary(TEXT("PLUGIN.DLL"));
  95.         if (!hPlugin) return 0;
  96.         fGetSliderPos = (f_GetSliderPos)(void*)GetProcAddress(hPlugin, "GetSliderPos");
  97.         res = (fGetSliderPos != 0) ? fGetSliderPos(hWnd, bPixelPosition) : 0;
  98.         FreeLibrary(hPlugin);
  99.         return res;
  100. }
  101.  
  102. LRESULT CALLBACK DummyWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
  103.         return DefWindowProc(hwnd, uMsg, wParam, lParam);
  104. }
  105.  
  106. void Win32sFixSuperclassing(HWND hDlg, int destItem, int sourceItem) {
  107.         // Win32s (Win3.11) compatibility fix: Since GetClassInfo(WC_BUTTON) and GetClassInfo(WC_STATIC) won't work,
  108.         // we had replaced the WndProc by a dummy. Now, we find out the real Button and Static WndProcs and give them
  109.         // to our classes, making them the intended superclasses. Messages which have been sent in between were lost,
  110.         // though...
  111.  
  112.         WNDPROC wndProc;
  113. #ifdef _WIN64
  114.         wndProc = (WNDPROC)GetWindowLongPtr(GetDlgItem(hDlg, destItem), GWLP_WNDPROC);
  115.         if (wndProc == DummyWndProc) {
  116.                 wndProc = (WNDPROC)GetWindowLongPtr(GetDlgItem(hDlg, sourceItem), GWLP_WNDPROC);
  117.                 SetWindowLongPtr(GetDlgItem(hDlg, destItem), GWLP_WNDPROC, (LONG_PTR)wndProc);
  118.         }
  119. #else
  120.         wndProc = (WNDPROC)GetWindowLongPtr(GetDlgItem(hDlg, destItem), GWL_WNDPROC);
  121.         if (wndProc == DummyWndProc) {
  122.                 wndProc = (WNDPROC)GetWindowLongPtr(GetDlgItem(hDlg, sourceItem), GWL_WNDPROC);
  123.                 SetWindowLongPtr(GetDlgItem(hDlg, destItem), GWL_WNDPROC, (LONG_PTR)wndProc);
  124.         }
  125. #endif
  126. }
  127.  
  128. Boolean MakeSimpleSubclass(LPCTSTR targetClass, LPCTSTR sourceClass) {
  129.         WNDCLASS clx;
  130.  
  131.         if (GetClassInfo(hDllInstance, sourceClass, &clx) != 0) {
  132.                 clx.lpszClassName = targetClass;
  133.                 if (RegisterClass(&clx) == 0) {
  134.                         TCHAR s[0x300];
  135.                         xstrcpy(s, (TCHAR*)TEXT("RegisterClass failed: "));
  136.                         FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), 0, s + xstrlen(s), 0x300 - (DWORD)xstrlen(s), NULL);
  137.                         dbg(&s[0]);
  138.                         return false;
  139.                 }
  140.                 else {
  141.                         return true;
  142.                 }
  143.         }
  144.         else {
  145.                 if ((xstrcmp(sourceClass, WC_BUTTON) == 0) || (xstrcmp(sourceClass, WC_STATIC) == 0)) {
  146.                         // GetClassInfo(WC_STATIC) and GetClassInfo(WC_BUTTON) fail on Win32s (Windows 3.11)
  147.                         // So we create a fake-class now. It will be replaced with the real Button/Static WndProc later!
  148.                         clx.style = 0;
  149.                         clx.lpfnWndProc = DummyWndProc;
  150.                         clx.cbClsExtra = 0;
  151.                         clx.cbWndExtra = 0;
  152.                         clx.hInstance = hDllInstance;
  153.                         clx.hIcon = 0;
  154.                         clx.hCursor = 0;
  155.                         clx.hbrBackground = 0;
  156.                         clx.lpszMenuName = 0;
  157.                         clx.lpszClassName = targetClass;
  158.  
  159.                         if (RegisterClass(&clx) == 0) {
  160.                                 TCHAR s[0x300];
  161.                                 xstrcpy(s, (TCHAR*)TEXT("RegisterClass failed: "));
  162.                                 FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), 0, s + xstrlen(s), 0x300 - (DWORD)xstrlen(s), NULL);
  163.                                 dbg(&s[0]);
  164.                                 return false;
  165.                         }
  166.                         else {
  167.                                 return true;
  168.                         }
  169.                 }
  170.                 else {
  171.                         simplealert((TCHAR*)TEXT("GetClassInfo failed"));
  172.                 }
  173.                 return false;
  174.         }
  175. }
  176.  
  177. void Slider_Uninit_PluginDll() {
  178. #ifndef use_plugin_dll_sliders
  179.         return;
  180. #else
  181.         if (gdata->pluginDllSliderInitialized) {
  182.                 if (UnregisterSlider(hDllInstance)) {
  183.                         gdata->pluginDllSliderInitialized = false;
  184.                 } else {
  185.                         simplealert(TEXT("UnRegisterSlider failed"));
  186.                 }
  187.         }
  188. #endif
  189.  
  190. }
  191.  
  192. Boolean Slider_Init_PluginDll(LPCTSTR targetClass) {
  193.  
  194. #ifndef use_plugin_dll_sliders
  195.         return false;
  196. #else
  197.         if (RegisterSlider(hDllInstance, &gdata->pluginDllSliderMessageId)) {
  198.                 gdata->pluginDllSliderInitialized = true;
  199.         } else {
  200.                 // This can happen if PLUGIN.DLL is not existing
  201.                 // It will also happen if a previous uninitialization failed (or was forgotten)
  202.                 return false; // Fall back to Windows sliders
  203.         }
  204.  
  205.         // Make "FoundrySlider" a subclass of "slider" then
  206.         return MakeSimpleSubclass(targetClass, TEXT("slider"));
  207. #endif
  208.  
  209. }
  210.  
  211. typedef void(__stdcall* f_InitCommonControls)();
  212. typedef BOOL(__stdcall* f_InitCommonControlsEx)(const INITCOMMONCONTROLSEX* picce);
  213. Boolean Slider_Init_MsTrackbar(LPCTSTR targetClass) {
  214.         f_InitCommonControls fInitCommonControls;
  215.         f_InitCommonControlsEx fInitCommonControlsEx;
  216.         HMODULE libComctl32;
  217.  
  218.         // Make sure that Comctl32 is loaded
  219.         libComctl32 = LoadLibrary(TEXT("Comctl32.dll"));
  220.         if (libComctl32) {
  221.                 fInitCommonControlsEx = (f_InitCommonControlsEx)(void*)GetProcAddress(libComctl32, "InitCommonControlsEx");
  222.                 if (fInitCommonControlsEx != 0) {
  223.                         INITCOMMONCONTROLSEX icce;
  224.                         icce.dwSize = sizeof(INITCOMMONCONTROLSEX);
  225.                         icce.dwICC = ICC_BAR_CLASSES;
  226.                         fInitCommonControlsEx(&icce);
  227.                 }
  228.                 else {
  229.                         fInitCommonControls = (f_InitCommonControls)(void*)GetProcAddress(libComctl32, "InitCommonControls");
  230.                         if (fInitCommonControls != 0) {
  231.                                 fInitCommonControls();
  232.                         }
  233.                 }
  234.                 // There seems to be a bug in Windows NT 3.11 (if PLUGIN.DLL does not exist):
  235.                 // If we call FreeLibrary, and then open Filter Foundry again,
  236.                 // then you get an error message "BRUSHES" cannot initialize Comctl32.dll ...
  237.                 // I am not sure if it is OK to do a FreeLibrary after you have called InitCommonControls.
  238.                 // Isn't that a contradiction?
  239.                 //FreeLibrary(libComctl32);
  240.         }
  241.  
  242.         // Make "FoundrySlider" a subclass of "msctls_trackbar32" then
  243.         return MakeSimpleSubclass(targetClass, TEXT("msctls_trackbar32"));
  244. }
  245.  
  246. Boolean Slider_Init_None(LPCTSTR targetClass) {
  247.         // Make "FoundrySlider" a subclass of "STATIC" (making it invisible)
  248.         return MakeSimpleSubclass(targetClass, WC_STATIC);
  249. }
  250.